Chromium Code Reviews| Index: athena/common/drag_handle.cc |
| diff --git a/athena/common/drag_handle.cc b/athena/common/drag_handle.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..f48dd234a7b1b7a5d9a95552570449898efe3658 |
| --- /dev/null |
| +++ b/athena/common/drag_handle.cc |
| @@ -0,0 +1,175 @@ |
| +// Copyright 2014 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 "athena/common/drag_handle.h" |
| + |
| +#include "ui/views/background.h" |
| +#include "ui/views/layout/box_layout.h" |
| +#include "ui/views/view.h" |
| +#include "ui/views/widget/widget.h" |
| + |
| +namespace athena { |
| +namespace { |
| + |
| +const SkColor kDragHandleColorNormal = SK_ColorGRAY; |
| +const SkColor kDragHandleColorHot = SK_ColorWHITE; |
| + |
| +class DragHandleView : public views::View { |
| + public: |
| + explicit DragHandleView(DragHandle::ScrollDirection scroll_direction, |
| + DragHandle::ScrollDelegate* delegate, |
| + int preferred_width, |
| + int preferred_height); |
| + virtual ~DragHandleView(); |
| + |
| + private: |
| + enum State { |
| + DEFAULT, |
| + SCROLLING, |
| + }; |
| + |
| + void SetColor(SkColor color); |
| + |
| + void SetState(State state); |
| + |
| + // views::View: |
| + virtual gfx::Size GetPreferredSize() const OVERRIDE; |
| + virtual void OnMouseEntered(const ui::MouseEvent& event) OVERRIDE; |
| + virtual void OnMouseExited(const ui::MouseEvent& event) OVERRIDE; |
| + virtual void OnGestureEvent(ui::GestureEvent* event) OVERRIDE; |
| + |
| + State state_; |
| + DragHandle::ScrollDelegate* delegate_; |
| + DragHandle::ScrollDirection scroll_direction_; |
| + SkColor color_; |
| + float scroll_start_location_; |
| + const int preferred_width_; |
| + const int preferred_height_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(DragHandleView); |
| +}; |
| + |
| +DragHandleView::DragHandleView(DragHandle::ScrollDirection scroll_direction, |
| + DragHandle::ScrollDelegate* delegate, |
| + int preferred_width, |
| + int preferred_height) |
| + : state_(DEFAULT), |
| + delegate_(delegate), |
| + scroll_direction_(scroll_direction), |
| + color_(SK_ColorTRANSPARENT), |
| + preferred_width_(preferred_width), |
| + preferred_height_(preferred_height) { |
| + SetColor(kDragHandleColorNormal); |
| +} |
| + |
| +DragHandleView::~DragHandleView() { |
| +} |
| + |
| +void DragHandleView::SetColor(SkColor color) { |
| + if (color_ == color) |
| + return; |
| + color_ = color; |
| + set_background(views::Background::CreateSolidBackground(color_)); |
| + SchedulePaint(); |
| +} |
| + |
| +void DragHandleView::SetState(State state) { |
| + if (state_ == state) |
| + return; |
| + state_ = state; |
| + if (state == DEFAULT) |
| + scroll_start_location_ = 0; |
| +} |
| + |
| +// views::View: |
| +gfx::Size DragHandleView::GetPreferredSize() const { |
| + return gfx::Size(preferred_width_, preferred_height_); |
| +} |
| + |
| +void DragHandleView::OnMouseEntered(const ui::MouseEvent& event) { |
| + SetColor(kDragHandleColorHot); |
| +} |
| + |
| +void DragHandleView::OnMouseExited(const ui::MouseEvent& event) { |
| + SetColor(kDragHandleColorNormal); |
| +} |
| + |
| +void DragHandleView::OnGestureEvent(ui::GestureEvent* event) { |
| + SkColor change_color = SK_ColorTRANSPARENT; |
| + if (event->type() == ui::ET_GESTURE_BEGIN && |
| + event->details().touch_points() == 1) { |
| + change_color = kDragHandleColorHot; |
| + } else if (event->type() == ui::ET_GESTURE_END && |
| + event->details().touch_points() == 1) { |
| + change_color = kDragHandleColorNormal; |
| + } |
| + if (change_color != SK_ColorTRANSPARENT) { |
| + SetColor(change_color); |
| + event->SetHandled(); |
| + return; |
| + } |
| + |
| + if (event->type() == ui::ET_GESTURE_SCROLL_BEGIN) { |
| + if (!delegate_->HandleCanScroll() || state_ != DEFAULT) |
| + return; |
| + float delta; |
| + if (scroll_direction_ == DragHandle::VERTICAL) { |
| + delta = event->details().scroll_y_hint(); |
| + scroll_start_location_ = event->root_location().y(); |
| + } else { |
| + delta = event->details().scroll_x_hint(); |
| + scroll_start_location_ = event->root_location().x(); |
| + } |
| + delegate_->HandleScrollBegin(delta); |
| + SetState(SCROLLING); |
| + event->SetHandled(); |
| + } else if (event->type() == ui::ET_GESTURE_SCROLL_END) { |
| + if (state_ != SCROLLING) |
| + return; |
| + delegate_->HandleScrollEnd(); |
| + SetColor(kDragHandleColorNormal); |
| + SetState(DEFAULT); |
| + event->SetHandled(); |
| + } else if (event->type() == ui::ET_SCROLL_FLING_START) { |
| + if (state_ != SCROLLING) |
| + return; |
| + delegate_->HandleScrollEnd(); |
|
sadrul
2014/09/12 04:30:36
Do we not want to take the velocity into considera
mfomitchev
2014/09/12 20:49:07
That sounds like a good idea. I was thinking of do
|
| + SetColor(kDragHandleColorNormal); |
| + SetState(DEFAULT); |
| + event->SetHandled(); |
| + } else if (event->type() == ui::ET_GESTURE_SCROLL_UPDATE) { |
| + if (state_ != SCROLLING) |
| + return; |
| + float delta = scroll_direction_ == DragHandle::VERTICAL |
| + ? event->root_location().y() - scroll_start_location_ |
| + : event->root_location().x() - scroll_start_location_; |
| + delegate_->HandleScrollUpdate(delta); |
| + event->SetHandled(); |
| + } |
| +} |
| + |
| +} // namespace |
| + |
| +views::View* CreateDragHandleView(DragHandle::ScrollDirection scroll_direction, |
| + DragHandle::ScrollDelegate* delegate, |
| + int preferred_width, |
| + int preferred_height, |
| + int margin) { |
| + views::View* content_view = new views::View; |
| + content_view->set_background( |
| + views::Background::CreateSolidBackground(SK_ColorBLACK)); |
| + views::BoxLayout* layout = |
| + new views::BoxLayout(views::BoxLayout::kHorizontal, margin, margin, 0); |
| + layout->set_main_axis_alignment(views::BoxLayout::MAIN_AXIS_ALIGNMENT_CENTER); |
| + layout->set_cross_axis_alignment( |
| + views::BoxLayout::CROSS_AXIS_ALIGNMENT_CENTER); |
| + content_view->SetLayoutManager(layout); |
| + |
| + views::View* view = new DragHandleView( |
| + scroll_direction, delegate, preferred_width, preferred_height); |
| + content_view->AddChildView(view); |
| + return content_view; |
| +} |
| + |
| +} // namespace athena |