Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1219)

Unified Diff: chrome/browser/ui/touch/frame/touch_browser_frame_view.cc

Issue 7273073: Animated Rotation (Closed) Base URL: http://git.chromium.org/git/chromium.git@trunk
Patch Set: Use new minimal sensor API Created 9 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/ui/touch/frame/touch_browser_frame_view.cc
diff --git a/chrome/browser/ui/touch/frame/touch_browser_frame_view.cc b/chrome/browser/ui/touch/frame/touch_browser_frame_view.cc
index b1ae5b4e448f79eb5900b069d3b4ab81d56e0130..d771ed8df53550bedd967658bad8f013004a7a1c 100644
--- a/chrome/browser/ui/touch/frame/touch_browser_frame_view.cc
+++ b/chrome/browser/ui/touch/frame/touch_browser_frame_view.cc
@@ -4,6 +4,7 @@
#include "chrome/browser/ui/touch/frame/touch_browser_frame_view.h"
+#include "base/debug/trace_event.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/renderer_host/render_widget_host_view_views.h"
#include "chrome/browser/tabs/tab_strip_model.h"
@@ -20,7 +21,7 @@
#include "content/common/content_notification_types.h"
#include "content/common/notification_service.h"
#include "content/common/view_messages.h"
-#include "ui/base/animation/slide_animation.h"
+#include "ui/gfx/interpolated_transform.h"
#include "ui/gfx/rect.h"
#include "ui/gfx/transform.h"
#include "views/controls/button/image_button.h"
@@ -48,6 +49,141 @@ bool TabContentsHasFocus(const TabContents* contents) {
} // namespace
+////////////////////////////////////////////////////////////////////////////////
+// Animation
+
+class TouchBrowserFrameRotation : public ui::AnimationDelegate {
sadrul 2011/07/15 15:25:48 This probably should be in the anonymous namespace
+ public:
+ static void Perform(views::View* root,
+ sensors::ScreenOrientation::Side oldUp,
+ sensors::ScreenOrientation::Side newUp) {
+ new TouchBrowserFrameRotation(root, oldUp, newUp);
+ }
+
+ private:
+ TouchBrowserFrameRotation(views::View* root,
+ sensors::ScreenOrientation::Side old_up,
+ sensors::ScreenOrientation::Side new_up)
+ : root_(root),
sadrul 2011/07/15 15:25:48 4-space indent
+ old_up_(old_up),
+ new_up_(new_up) {
+ animation_.reset(new ui::SlideAnimation(this));
+ animation_->SetTweenType(ui::Tween::LINEAR);
+ animation_->SetSlideDuration(1000);
+ Start();
+ }
+
+ virtual void AnimationProgressed(const ui::Animation* anim) OVERRIDE {
+ if (!interpolated_transform_.get())
+ return;
+
+ float t = static_cast<float>(anim->GetCurrentValue());
+ root_->SetTransform(interpolated_transform_->Interpolate(t));
+ root_->ScheduleComposite();
+ }
+
+ virtual void AnimationEnded(const ui::Animation* anim) OVERRIDE {
+ TRACE_EVENT_END0("RotateAnimation", "Start rotating");
+ // TODO(vollick) massage matrix so that entries sufficiently close
+ // to 0, 1, or -1 are clamped to these values. The idea is to fight
+ // accumulated numeric error due to successive rotations.
+ ui::Transform xform = root_->GetTransform();
+ gfx::Point origin;
+ xform.TransformPoint(origin);
+ ui::Transform translation;
+ translation.SetTranslate(new_origin_.x() - origin.x(),
+ new_origin_.y() - origin.y());
+ xform.ConcatTransform(translation);
+ root_->SetTransform(xform);
+ root_->SetBounds(0, 0, new_size_.width(), new_size_.height());
+ root_->SetPaintingEnabled(true);
+ root_->SchedulePaint();
+ delete this;
+ }
+
+ int SideToDegrees(sensors::ScreenOrientation::Side side) {
+ switch (side) {
+ case sensors::ScreenOrientation::RIGHT: return 90;
sadrul 2011/07/15 15:25:48 indentations!
+ case sensors::ScreenOrientation::LEFT: return -90;
+ case sensors::ScreenOrientation::BOTTOM: return 180;
+ default: return 0;
+ }
+ }
+
+ int NormalizeAngle(int degrees) {
+ while (degrees <= -180) degrees += 360;
+ while (degrees > 180) degrees -= 360;
+ return degrees;
+ }
+
+ void Start() {
+ TRACE_EVENT_BEGIN0("RotateAnimation", "Start rotating");
+ root_->SetPaintingEnabled(false);
+ int degrees = SideToDegrees(new_up_) - SideToDegrees(old_up_);
+ degrees = NormalizeAngle(degrees);
+
+ // No rotation required.
+ if (degrees == 0)
+ return;
+
+ gfx::Point old_pivot;
+ gfx::Point new_pivot;
+
+ switch (degrees) {
+ case 90:
sadrul 2011/07/15 15:25:48 ditto
+ new_origin_ = old_pivot = gfx::Point(root_->width(), 0);
+ new_pivot.SetPoint(root_->width(), root_->height());
+ new_size_.SetSize(root_->height(), root_->width());
+ break;
+ case -90:
+ new_origin_ = new_pivot = gfx::Point(0, root_->height());
+ new_size_.SetSize(root_->height(), root_->width());
+ break;
+ case 180:
+ new_pivot = old_pivot = gfx::Point(root_->width() / 2,
+ root_->height() / 2);
+ new_origin_.SetPoint(root_->width(), root_->height());
+ new_size_.SetSize(root_->width(), root_->height());
+ break;
+ }
+
+ // Convert points to world space.
+ const ui::Transform& xform = root_->GetTransform();
+ xform.TransformPoint(old_pivot);
+ xform.TransformPoint(new_pivot);
+ xform.TransformPoint(new_origin_);
+
+ scoped_ptr<ui::InterpolatedTransform> rotation(
+ new ui::InterpolatedTransformAboutPivot(
+ old_pivot,
+ new ui::InterpolatedRotation(0, degrees)));
+
+ scoped_ptr<ui::InterpolatedTransform> translation(
+ new ui::InterpolatedTranslation(
+ gfx::Point(0, 0),
+ gfx::Point(new_pivot.x() - old_pivot.x(),
+ new_pivot.y() - old_pivot.y())));
+
+ interpolated_transform_.reset(
+ new ui::InterpolatedConstantTransform(xform));
+
+ rotation->SetChild(translation.release());
+ interpolated_transform_->SetChild(rotation.release());
+
+ animation_->Show();
+ }
+
+ views::View* root_;
+ scoped_ptr<ui::SlideAnimation> animation_;
+ scoped_ptr<ui::InterpolatedTransform> interpolated_transform_;
+ sensors::ScreenOrientation::Side old_up_;
+ sensors::ScreenOrientation::Side new_up_;
+ gfx::Size new_size_;
+ gfx::Point new_origin_;
+
+ DISALLOW_COPY_AND_ASSIGN(TouchBrowserFrameRotation);
+};
+
// static
const char TouchBrowserFrameView::kViewClassName[] =
"browser/ui/touch/frame/TouchBrowserFrameView";
@@ -61,7 +197,8 @@ TouchBrowserFrameView::TouchBrowserFrameView(BrowserFrame* frame,
keyboard_showing_(false),
keyboard_height_(kDefaultKeyboardHeight),
focus_listener_added_(false),
- keyboard_(NULL) {
+ keyboard_(NULL),
+ up_(sensors::ScreenOrientation::TOP) {
registrar_.Add(this,
content::NOTIFICATION_NAV_ENTRY_COMMITTED,
NotificationService::AllSources());
@@ -92,10 +229,13 @@ TouchBrowserFrameView::TouchBrowserFrameView(BrowserFrame* frame,
chromeos::input_method::InputMethodManager::GetInstance();
manager->AddVirtualKeyboardObserver(this);
#endif
+
+ sensors::Provider::GetInstance()->AddListener(this);
}
TouchBrowserFrameView::~TouchBrowserFrameView() {
browser_view()->browser()->tabstrip_model()->RemoveObserver(this);
+ sensors::Provider::GetInstance()->RemoveListener(this);
}
std::string TouchBrowserFrameView::GetClassName() const {
@@ -361,6 +501,15 @@ void TouchBrowserFrameView::AnimationEnded(const ui::Animation* animation) {
SchedulePaint();
}
+void TouchBrowserFrameView::OnScreenOrientationChange(
+ const sensors::ScreenOrientation& change) {
+
+ views::Widget* widget = GetWidget();
sadrul 2011/07/15 15:25:48 Please try this with --views-desktop and see if th
+ views::View* root = widget->GetRootView();
+ TouchBrowserFrameRotation::Perform(root, up_, change.upward);
+ up_ = change.upward;
+}
+
#if defined(OS_CHROMEOS)
void TouchBrowserFrameView::VirtualKeyboardChanged(
chromeos::input_method::InputMethodManager* manager,

Powered by Google App Engine
This is Rietveld 408576698