Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "ui/touch_selection/touch_handle_drawable_aura.h" | |
| 6 | |
| 7 #include "ui/aura/window.h" | |
| 8 #include "ui/aura/window_targeter.h" | |
| 9 #include "ui/base/cursor/cursor.h" | |
| 10 #include "ui/base/hit_test.h" | |
| 11 #include "ui/base/resource/resource_bundle.h" | |
| 12 #include "ui/events/event.h" | |
| 13 #include "ui/gfx/canvas.h" | |
| 14 #include "ui/gfx/geometry/rect_conversions.h" | |
| 15 #include "ui/resources/grit/ui_resources.h" | |
| 16 | |
| 17 namespace ui { | |
| 18 namespace { | |
| 19 | |
| 20 // The distance by which a handle image is offset from the focal point (i.e. | |
| 21 // text baseline) downwards. | |
| 22 const int kSelectionHandleVerticalVisualOffset = 2; | |
| 23 | |
| 24 // The padding around the selection handle image can be used to extend the | |
| 25 // handle window so that touch events near the selection handle image are | |
| 26 // targeted to the selection handle window. | |
| 27 const int kSelectionHandlePadding = 0; | |
| 28 | |
| 29 gfx::Image* GetCenterHandleImage() { | |
| 30 static gfx::Image* handle_image = nullptr; | |
| 31 if (!handle_image) { | |
| 32 handle_image = &ui::ResourceBundle::GetSharedInstance().GetImageNamed( | |
|
jdduke (slow)
2015/01/28 16:35:32
How expensive are these calls? If they're relative
mohsen
2015/02/22 23:23:09
Yeah, apparently ResourceBundle has its own cachin
| |
| 33 IDR_TEXT_SELECTION_HANDLE_CENTER); | |
| 34 } | |
| 35 return handle_image; | |
| 36 } | |
| 37 | |
| 38 gfx::Image* GetLeftHandleImage() { | |
| 39 static gfx::Image* handle_image = nullptr; | |
| 40 if (!handle_image) { | |
| 41 handle_image = &ui::ResourceBundle::GetSharedInstance().GetImageNamed( | |
| 42 IDR_TEXT_SELECTION_HANDLE_LEFT); | |
| 43 } | |
| 44 return handle_image; | |
| 45 } | |
| 46 | |
| 47 gfx::Image* GetRightHandleImage() { | |
| 48 static gfx::Image* handle_image = nullptr; | |
| 49 if (!handle_image) { | |
| 50 handle_image = &ui::ResourceBundle::GetSharedInstance().GetImageNamed( | |
| 51 IDR_TEXT_SELECTION_HANDLE_RIGHT); | |
| 52 } | |
| 53 return handle_image; | |
| 54 } | |
| 55 | |
| 56 // Return the appropriate handle image based on the bound's type | |
| 57 gfx::Image* GetHandleImage(ui::TouchHandleOrientation orientation) { | |
| 58 switch(orientation) { | |
| 59 case ui::TOUCH_HANDLE_LEFT: | |
| 60 return GetLeftHandleImage(); | |
| 61 case ui::TOUCH_HANDLE_CENTER: | |
| 62 return GetCenterHandleImage(); | |
| 63 case ui::TOUCH_HANDLE_RIGHT: | |
| 64 return GetRightHandleImage(); | |
| 65 default: | |
| 66 NOTREACHED() << "Invalid touch handle bound type."; | |
| 67 return nullptr; | |
| 68 }; | |
| 69 } | |
| 70 | |
| 71 class TouchHandleDrawableAuraTargeter : public aura::WindowTargeter { | |
| 72 protected: | |
| 73 bool EventLocationInsideBounds(ui::EventTarget* target, | |
| 74 const LocatedEvent& event) const override; | |
| 75 }; | |
| 76 | |
| 77 bool TouchHandleDrawableAuraTargeter::EventLocationInsideBounds( | |
| 78 EventTarget* target, | |
| 79 const LocatedEvent& event) const { | |
| 80 return false; | |
| 81 } | |
| 82 | |
| 83 } | |
| 84 | |
| 85 // static | |
| 86 gfx::Size TouchHandleDrawableAura::GetMaxHandleImageSize() { | |
| 87 gfx::Rect center_rect = gfx::Rect(GetCenterHandleImage()->Size()); | |
| 88 gfx::Rect left_rect = gfx::Rect(GetLeftHandleImage()->Size()); | |
| 89 gfx::Rect right_rect = gfx::Rect(GetRightHandleImage()->Size()); | |
| 90 gfx::Rect union_rect = center_rect; | |
| 91 union_rect.Union(left_rect); | |
| 92 union_rect.Union(right_rect); | |
| 93 return union_rect.size(); | |
| 94 } | |
| 95 | |
| 96 TouchHandleDrawableAura::TouchHandleDrawableAura(aura::Window* parent) | |
| 97 : window_(new aura::Window(this)), | |
| 98 enabled_(false), | |
| 99 alpha_(0), | |
| 100 orientation_(TOUCH_HANDLE_ORIENTATION_UNDEFINED) { | |
| 101 SetSelfDestroy(false); | |
| 102 SetImageOffset(gfx::Vector2d(kSelectionHandlePadding, | |
| 103 kSelectionHandlePadding)); | |
| 104 SetBackgroundColor(SK_ColorTRANSPARENT); | |
| 105 window_->SetTransparent(true); | |
| 106 window_->Init(aura::WINDOW_LAYER_TEXTURED); | |
| 107 window_->set_owned_by_parent(false); | |
| 108 window_->SetEventTargeter( | |
| 109 scoped_ptr<EventTargeter>(new TouchHandleDrawableAuraTargeter)); | |
| 110 parent->AddChild(window_.get()); | |
| 111 } | |
| 112 | |
| 113 TouchHandleDrawableAura::~TouchHandleDrawableAura() { | |
| 114 } | |
| 115 | |
| 116 void TouchHandleDrawableAura::UpdateBounds() { | |
| 117 gfx::RectF new_bounds = relative_bounds_; | |
| 118 new_bounds.Offset(focal_position_.x(), focal_position_.y()); | |
| 119 window_->SetBounds(gfx::ToNearestRect(new_bounds)); | |
| 120 } | |
| 121 | |
| 122 void TouchHandleDrawableAura::SetEnabled(bool enabled) { | |
| 123 if (enabled == enabled_) | |
| 124 return; | |
| 125 | |
| 126 enabled_ = enabled; | |
| 127 bool visible = alpha_ > 0; // XXX: float comparison | |
| 128 if (enabled_ && visible) | |
| 129 window_->Show(); | |
| 130 else | |
| 131 window_->Hide(); | |
| 132 } | |
| 133 | |
| 134 void TouchHandleDrawableAura::SetOrientation( | |
| 135 TouchHandleOrientation orientation) { | |
| 136 if (orientation_ == orientation) | |
| 137 return; | |
| 138 orientation_ = orientation; | |
| 139 gfx::Image* image = GetHandleImage(orientation); | |
| 140 SetImage(*image); | |
| 141 | |
| 142 // Calculate the relative bounds. | |
| 143 gfx::Size image_size = image->Size(); | |
| 144 int window_width = image_size.width() + 2 * kSelectionHandlePadding; | |
| 145 int window_height = image_size.height() + 2 * kSelectionHandlePadding; | |
| 146 // Due to the shape of the handle images, the window is aligned differently to | |
| 147 // the selection bound depending on the orientation. | |
| 148 int window_left = 0; | |
| 149 switch (orientation) { | |
| 150 case ui::TOUCH_HANDLE_LEFT: | |
| 151 window_left = -image_size.width() - kSelectionHandlePadding; | |
| 152 break; | |
| 153 case ui::TOUCH_HANDLE_RIGHT: | |
| 154 window_left = -kSelectionHandlePadding; | |
| 155 break; | |
| 156 case ui::TOUCH_HANDLE_CENTER: | |
| 157 window_left = -window_width / 2; | |
| 158 break; | |
| 159 default: | |
| 160 NOTREACHED() << "Undefined handle orientation."; | |
| 161 break; | |
| 162 }; | |
| 163 relative_bounds_ = gfx::RectF( | |
| 164 window_left, | |
| 165 kSelectionHandleVerticalVisualOffset - kSelectionHandlePadding, | |
| 166 window_width, | |
| 167 window_height); | |
| 168 UpdateBounds(); | |
| 169 } | |
| 170 | |
| 171 void TouchHandleDrawableAura::SetAlpha(float alpha) { | |
| 172 if (alpha == alpha_) // XXX: float comparison | |
| 173 return; | |
| 174 | |
| 175 alpha_ = alpha; | |
| 176 window_->layer()->SetOpacity(alpha_); | |
| 177 bool visible = alpha_ > 0; // XXX: float comparison | |
| 178 if (enabled_ && visible) | |
| 179 window_->Show(); | |
| 180 else | |
| 181 window_->Hide(); | |
| 182 } | |
| 183 | |
| 184 void TouchHandleDrawableAura::SetFocus(const gfx::PointF& position) { | |
| 185 focal_position_ = position; | |
| 186 UpdateBounds(); | |
| 187 } | |
| 188 | |
| 189 gfx::RectF TouchHandleDrawableAura::GetVisibleBounds() const { | |
| 190 gfx::RectF r(window_->bounds()); | |
| 191 r.Inset(kSelectionHandlePadding, | |
| 192 kSelectionHandlePadding + kSelectionHandleVerticalVisualOffset, | |
| 193 kSelectionHandlePadding, | |
| 194 kSelectionHandlePadding); | |
| 195 return r; | |
| 196 } | |
| 197 | |
| 198 } // namespace ui | |
| OLD | NEW |