diff options
author | ben@chromium.org <ben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-07-07 18:44:31 +0000 |
---|---|---|
committer | ben@chromium.org <ben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-07-07 18:44:31 +0000 |
commit | 7c0560f904487819f2c408c87899d1ccfa91c1fe (patch) | |
tree | da949466cd6dd09f5ce575b206a65b6ba0e1a2f9 /views | |
parent | 93a2c7241cddc33af51cdc3daea03e414f544ec8 (diff) | |
download | chromium_src-7c0560f904487819f2c408c87899d1ccfa91c1fe.zip chromium_src-7c0560f904487819f2c408c87899d1ccfa91c1fe.tar.gz chromium_src-7c0560f904487819f2c408c87899d1ccfa91c1fe.tar.bz2 |
Basics of a new TabStrip.It's very, very rough, but I wanted to check it in so I don't have to keep typing svn pset as I pass patches back and forth between machines.Behind a command line flag --enable-tabtastic2.I'm trying to split the TabContents specific stuff off of the TabStrip so it's more generic (and more easily mocked for unit testing of various layout conditions). Hence TabStrip vs. BrowserTabStrip. TabStrip may move into views/ once this process is complete.Animator is a utility that can be associated with a View that (at this point) animates that View's bounds from wherever it is now to somewhere else. The TabStrip uses this to do animations for individual Tabs that are independent of each other - a limitation of the old TabStrip is that only one animation is ever active at a time so its animations are a little jumpy compared to other products.Also, detached tab dragging shows the live contents, with all animations/video/etc.Like I said, this is really rough, but I didn't want it to grow any bigger. I will write up a design doc later.http://crbug.com/9032TEST=TBD... will finally be doing some for TabStrip layout!
Review URL: http://codereview.chromium.org/42490
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@20053 0039d316-1c4b-4281-b951-d872f2087c98
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); |