diff options
Diffstat (limited to 'views')
-rw-r--r-- | views/animator.cc | 151 | ||||
-rw-r--r-- | views/animator.h | 110 | ||||
-rw-r--r-- | views/views.gyp | 2 | ||||
-rw-r--r-- | views/widget/widget.h | 6 | ||||
-rw-r--r-- | views/widget/widget_gtk.cc | 5 | ||||
-rw-r--r-- | views/widget/widget_gtk.h | 2 | ||||
-rw-r--r-- | views/widget/widget_win.cc | 8 | ||||
-rw-r--r-- | views/widget/widget_win.h | 6 |
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); |