summaryrefslogtreecommitdiffstats
path: root/views
diff options
context:
space:
mode:
Diffstat (limited to 'views')
-rw-r--r--views/animator.cc151
-rw-r--r--views/animator.h110
-rw-r--r--views/views.gyp2
-rw-r--r--views/widget/widget.h6
-rw-r--r--views/widget/widget_gtk.cc5
-rw-r--r--views/widget/widget_gtk.h2
-rw-r--r--views/widget/widget_win.cc8
-rw-r--r--views/widget/widget_win.h6
8 files changed, 289 insertions, 1 deletions
diff --git a/views/animator.cc b/views/animator.cc
new file mode 100644
index 0000000..2b2a7db
--- /dev/null
+++ b/views/animator.cc
@@ -0,0 +1,151 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved. Use of this
+// source code is governed by a BSD-style license that can be found in the
+// LICENSE file.
+
+#include "views/animator.h"
+
+#include <algorithm>
+
+#include "app/slide_animation.h"
+#include "views/view.h"
+
+namespace views {
+
+////////////////////////////////////////////////////////////////////////////////
+// Animator, public:
+
+Animator::Animator(View* host)
+ : host_(host),
+ delegate_(NULL),
+ direction_(ANIMATE_NONE) {
+ InitAnimation();
+}
+
+Animator::Animator(View* host, AnimatorDelegate* delegate)
+ : host_(host),
+ animation_(NULL),
+ delegate_(delegate),
+ direction_(ANIMATE_NONE) {
+ InitAnimation();
+}
+
+Animator::~Animator() {
+ // Explicitly NULL the delegate so we don't call back through to the delegate
+ // when the animation is stopped. The Animator is designed to be owned by a
+ // View and at this point the View is dust.
+ delegate_ = NULL;
+ animation_->Stop();
+}
+
+bool Animator::IsAnimating() const {
+ return animation_->IsAnimating();
+}
+
+void Animator::AnimateToBounds(const gfx::Rect& bounds, int direction) {
+ direction_ = direction;
+ start_bounds_ = host_->bounds();
+ target_bounds_ = bounds;
+
+ // Stop any running animation before we have a chance to return.
+ animation_->Stop();
+
+ if (bounds == host_->bounds())
+ return;
+
+ if (direction_ == ANIMATE_NONE) {
+ host_->SetBounds(bounds);
+ return;
+ }
+
+ if (direction_ & ANIMATE_X) {
+ if (direction_ & ANIMATE_CLAMP)
+ start_bounds_.set_x(GetClampedX());
+ } else {
+ start_bounds_.set_x(target_bounds_.x());
+ }
+
+ if (direction_ & ANIMATE_Y) {
+ if (direction_ & ANIMATE_CLAMP)
+ start_bounds_.set_y(GetClampedY());
+ } else {
+ start_bounds_.set_y(target_bounds_.y());
+ }
+
+ if (!(direction_ & ANIMATE_WIDTH))
+ start_bounds_.set_width(target_bounds_.width());
+ if (!(direction_ & ANIMATE_HEIGHT))
+ start_bounds_.set_height(target_bounds_.height());
+
+ // Make sure the host view has the start bounds to avoid a flicker.
+ host_->SetBounds(start_bounds_);
+
+ // Start the animation from the beginning.
+ animation_->Reset(0.0);
+ animation_->Show();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Animator, AnimationDelegate:
+
+void Animator::AnimationEnded(const Animation* animation) {
+ // |delegate_| could be NULL if we're called back from the destructor.
+ if (delegate_)
+ delegate_->AnimationCompletedForHost(host_);
+}
+
+void Animator::AnimationProgressed(const Animation* animation) {
+ int delta_x = target_bounds_.x() - start_bounds_.x();
+ int delta_y = target_bounds_.y() - start_bounds_.y();
+ int delta_width = target_bounds_.width() - start_bounds_.width();
+ int delta_height = target_bounds_.height() - start_bounds_.height();
+
+ // The current frame's position and size is the animation's progress percent
+ // multiplied by the delta between the start and target position/size...
+ double cv = animation_->GetCurrentValue();
+ int frame_x = start_bounds_.x() + static_cast<int>(delta_x * cv);
+ int frame_y = start_bounds_.y() + static_cast<int>(delta_y * cv);
+ // ... except for clamped positions, which remain clamped at the right/bottom
+ // edge of the previous view in the layout flow.
+ if (direction_ & ANIMATE_CLAMP && direction_ & ANIMATE_X)
+ frame_x = GetClampedX();
+ if (direction_ & ANIMATE_CLAMP && direction_ & ANIMATE_Y)
+ frame_y = GetClampedY();
+ int frame_width = start_bounds_.width() + static_cast<int>(delta_width * cv);
+ int frame_height =
+ start_bounds_.height() + static_cast<int>(delta_height * cv);
+ host_->SetBounds(frame_x, frame_y, frame_width, frame_height);
+ host_->GetParent()->SchedulePaint();
+}
+
+void Animator::AnimationCanceled(const Animation* animation) {
+ AnimationEnded(animation);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Animator, private:
+
+void Animator::InitAnimation() {
+ animation_.reset(new SlideAnimation(this));
+ animation_->SetSlideDuration(150);
+ animation_->SetTweenType(SlideAnimation::EASE_OUT);
+}
+
+int Animator::GetClampedX() const {
+ if (delegate_ && direction_ & ANIMATE_CLAMP && direction_ & ANIMATE_X) {
+ View* previous_view = delegate_->GetClampedView(host_);
+ if (previous_view)
+ return previous_view->bounds().right();
+ }
+ return host_->x();
+}
+
+int Animator::GetClampedY() const {
+ if (delegate_ && direction_ & ANIMATE_CLAMP && direction_ & ANIMATE_Y) {
+ View* previous_view = delegate_->GetClampedView(host_);
+ if (previous_view)
+ return previous_view->bounds().bottom();
+ }
+ return host_->y();
+}
+
+} // namespace views
diff --git a/views/animator.h b/views/animator.h
new file mode 100644
index 0000000..2719fd6
--- /dev/null
+++ b/views/animator.h
@@ -0,0 +1,110 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved. Use of this
+// source code is governed by a BSD-style license that can be found in the
+// LICENSE file.
+
+#ifndef VIEWS_ANIMATOR_H_
+#define VIEWS_ANIMATOR_H_
+
+#include <xutility>
+
+#include "app/animation.h"
+#include "base/gfx/rect.h"
+#include "base/ref_counted.h"
+#include "base/scoped_ptr.h"
+
+class SlideAnimation;
+
+////////////////////////////////////////////////////////////////////////////////
+// ALERT!
+//
+// This API is preliminary and subject to change. Talk to beng before using it!
+//
+
+namespace views {
+
+class View;
+
+class AnimatorDelegate {
+ public:
+ // Returns the view in the visual layout whose trailing edge the view that
+ // hosts an animator should be clamped to during animations, when
+ // ANIMATE_CLAMP is specified in combination with ANIMATE_X or ANIMATE_Y.
+ virtual View* GetClampedView(View* host) = 0;
+
+ // Notifies the delegate that the active animation running for |host| has
+ // completed.
+ virtual void AnimationCompletedForHost(View* host) = 0;
+};
+
+// An animator is an object that can animate actions on a host view. Once
+// created, an Animator is typically owned by its host view.
+class Animator : public AnimationDelegate {
+ public:
+ enum BoundsChangeFlags {
+ ANIMATE_NONE = 0x0, // Don't animate anything... o_O
+ ANIMATE_X = 0x1, // Animate the host view's x position
+ ANIMATE_Y = 0x2, // Animate the host view's y position
+ ANIMATE_WIDTH = 0x4, // Animate the host view's width
+ ANIMATE_HEIGHT = 0x8, // Animate the host view's height
+ ANIMATE_CLAMP = 0x10 // Clamp the host view's x or y position to the
+ // trailing edge of the view returned by
+ // AnimatorDelegate::GetClampedView.
+ };
+
+ // Creates the animator for the specified host view. Optionally an
+ // AnimationContext can be provided to animate multiple views from a single
+ // animation.
+ explicit Animator(View* host);
+ Animator(View* host, AnimatorDelegate* delegate);
+ virtual ~Animator();
+
+ // Returns true if the animator is currently animating.
+ bool IsAnimating() const;
+
+ // Moves/sizes the host view to the specified bounds. |direction| is a
+ // combination of the above flags indicating what aspects of the bounds should
+ // be animated.
+ void AnimateToBounds(const gfx::Rect& bounds, int direction);
+ void AnimateToBounds(int x, int y, int width, int height, int direction) {
+ AnimateToBounds(gfx::Rect(x, y, std::max(0, width), std::max(0, height)),
+ direction);
+ }
+
+ // Overridden from AnimationDelegate:
+ virtual void AnimationEnded(const Animation* animation);
+ virtual void AnimationProgressed(const Animation* animation);
+ virtual void AnimationCanceled(const Animation* animation);
+
+ private:
+ void InitAnimation();
+
+ // Get the current X/Y position of the host view, clamped to the right edge of
+ // the previous view in the visual layout, if applicable (See
+ // AnimatorDelegate for more info).
+ int GetClampedX() const;
+ int GetClampedY() const;
+
+ // The view that this animator is attached to.
+ View* host_;
+
+ // Start and end bounds for the animation.
+ gfx::Rect start_bounds_;
+ gfx::Rect target_bounds_;
+
+ // The animation used by this animator.
+ scoped_ptr<SlideAnimation> animation_;
+
+ // A delegate object that provides information about surrounding views.
+ // Will be NULL during this class' destructor.
+ AnimatorDelegate* delegate_;
+
+ // Some combination of BoundsChangeFlags indicating the type of bounds change
+ // the host view is subject to.
+ int direction_;
+
+ DISALLOW_COPY_AND_ASSIGN(Animator);
+};
+
+} // namespace views
+
+#endif // #ifndef VIEWS_ANIMATOR_H_
diff --git a/views/views.gyp b/views/views.gyp
index abb790f..4504f99 100644
--- a/views/views.gyp
+++ b/views/views.gyp
@@ -58,6 +58,8 @@
'accessibility/view_accessibility.h',
'accessibility/view_accessibility_wrapper.cc',
'accessibility/view_accessibility_wrapper.h',
+ 'animator.cc',
+ 'animator.h',
'background.cc',
'background.h',
'border.cc',
diff --git a/views/widget/widget.h b/views/widget/widget.h
index 9c4c5ef..0566b0b 100644
--- a/views/widget/widget.h
+++ b/views/widget/widget.h
@@ -20,6 +20,7 @@ class Accelerator;
class FocusManager;
class RootView;
class TooltipManager;
+class View;
class Window;
////////////////////////////////////////////////////////////////////////////////
@@ -96,6 +97,11 @@ class Widget {
return NULL;
}
+ // Starts a drag operation for the specified view. |point| is a position in
+ // |view| coordinates that the drag was initiated from.
+ virtual void GenerateMousePressedForView(View* view,
+ const gfx::Point& point) = 0;
+
// Returns the accelerator given a command id. Returns false if there is
// no accelerator associated with a given id, which is a common condition.
virtual bool GetAccelerator(int cmd_id,
diff --git a/views/widget/widget_gtk.cc b/views/widget/widget_gtk.cc
index 3bec281..c4ea3b5 100644
--- a/views/widget/widget_gtk.cc
+++ b/views/widget/widget_gtk.cc
@@ -368,6 +368,11 @@ bool WidgetGtk::IsActive() const {
return gtk_window_is_active(GTK_WINDOW(widget_));
}
+void WidgetGtk::GenerateMousePressedForView(View* view,
+ const gfx::Point& point) {
+ NOTIMPLEMENTED();
+}
+
TooltipManager* WidgetGtk::GetTooltipManager() {
return tooltip_manager_.get();
}
diff --git a/views/widget/widget_gtk.h b/views/widget/widget_gtk.h
index 58d8895..28cf8be 100644
--- a/views/widget/widget_gtk.h
+++ b/views/widget/widget_gtk.h
@@ -92,6 +92,8 @@ class WidgetGtk : public Widget, public MessageLoopForUI::Observer {
virtual Widget* GetRootWidget() const;
virtual bool IsVisible() const;
virtual bool IsActive() const;
+ virtual void GenerateMousePressedForView(View* view,
+ const gfx::Point& point);
virtual TooltipManager* GetTooltipManager();
virtual bool GetAccelerator(int cmd_id, Accelerator* accelerator);
virtual Window* GetWindow();
diff --git a/views/widget/widget_win.cc b/views/widget/widget_win.cc
index 8d39991..ed58ae9 100644
--- a/views/widget/widget_win.cc
+++ b/views/widget/widget_win.cc
@@ -392,6 +392,14 @@ bool WidgetWin::IsActive() const {
return win_util::IsWindowActive(GetNativeView());
}
+void WidgetWin::GenerateMousePressedForView(View* view,
+ const gfx::Point& point) {
+ gfx::Point point_in_widget(point);
+ View::ConvertPointToWidget(view, &point_in_widget);
+ root_view_->SetMouseHandler(view);
+ ProcessMousePressed(point_in_widget.ToPOINT(), MK_LBUTTON, false, false);
+}
+
TooltipManager* WidgetWin::GetTooltipManager() {
return tooltip_manager_.get();
}
diff --git a/views/widget/widget_win.h b/views/widget/widget_win.h
index 33c247e..d3665d2 100644
--- a/views/widget/widget_win.h
+++ b/views/widget/widget_win.h
@@ -159,6 +159,7 @@ class WidgetWin : public Widget,
MSG_WM_ENDSESSION(OnEndSession)
MSG_WM_ENTERSIZEMOVE(OnEnterSizeMove)
MSG_WM_EXITMENULOOP(OnExitMenuLoop)
+ MSG_WM_EXITSIZEMOVE(OnExitSizeMove)
MSG_WM_GETMINMAXINFO(OnGetMinMaxInfo)
MSG_WM_HSCROLL(OnHScroll)
MSG_WM_INITMENU(OnInitMenu)
@@ -225,6 +226,8 @@ class WidgetWin : public Widget,
virtual Widget* GetRootWidget() const;
virtual bool IsVisible() const;
virtual bool IsActive() const;
+ virtual void GenerateMousePressedForView(View* view,
+ const gfx::Point& point);
virtual TooltipManager* GetTooltipManager();
virtual ThemeProvider* GetThemeProvider() const;
virtual Window* GetWindow();
@@ -371,10 +374,11 @@ class WidgetWin : public Widget,
}
virtual void OnEndSession(BOOL ending, UINT logoff) { SetMsgHandled(FALSE); }
virtual void OnEnterSizeMove() { SetMsgHandled(FALSE); }
+ virtual LRESULT OnEraseBkgnd(HDC dc);
virtual void OnExitMenuLoop(BOOL is_track_popup_menu) {
SetMsgHandled(FALSE);
}
- virtual LRESULT OnEraseBkgnd(HDC dc);
+ virtual void OnExitSizeMove() { SetMsgHandled(FALSE); }
virtual LRESULT OnGetObject(UINT uMsg, WPARAM w_param, LPARAM l_param);
virtual void OnGetMinMaxInfo(MINMAXINFO* minmax_info) {
SetMsgHandled(FALSE);