blob: a33d5be51bb1c679e9bc6ec44ffa3b47587986c5 [file] [log] [blame]
[email protected]8af4c1992010-02-04 21:38:071// Copyright (c) 2010 The Chromium Authors. All rights reserved.
license.botbf09a502008-08-24 00:55:552// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
initial.commit09911bf2008-07-26 23:55:294
[email protected]2362e4f2009-05-08 00:34:055#include "views/view.h"
initial.commit09911bf2008-07-26 23:55:296
7#include <algorithm>
[email protected]1eb89e82008-08-15 12:27:038#ifndef NDEBUG
initial.commit09911bf2008-07-26 23:55:299#include <iostream>
[email protected]1eb89e82008-08-15 12:27:0310#endif
initial.commit09911bf2008-07-26 23:55:2911
[email protected]37126212009-05-06 02:23:3112#include "app/drag_drop_types.h"
initial.commit09911bf2008-07-26 23:55:2913#include "base/logging.h"
14#include "base/message_loop.h"
[email protected]82739cf2008-09-16 00:37:5615#include "base/scoped_handle.h"
[email protected]d55194ca2010-03-11 18:25:4516#include "base/utf_string_conversions.h"
[email protected]74db48eb2010-06-25 16:33:2317#include "gfx/canvas_skia.h"
[email protected]5c7293a2010-03-17 06:40:5718#include "gfx/path.h"
[email protected]d5282e72009-05-13 13:16:5219#include "third_party/skia/include/core/SkShader.h"
[email protected]2362e4f2009-05-08 00:34:0520#include "views/background.h"
21#include "views/layout_manager.h"
[email protected]3ee83f2c2009-05-10 05:58:4022#include "views/views_delegate.h"
[email protected]2362e4f2009-05-08 00:34:0523#include "views/widget/root_view.h"
[email protected]319d4ae2009-05-28 19:09:4524#include "views/widget/tooltip_manager.h"
[email protected]2362e4f2009-05-08 00:34:0525#include "views/widget/widget.h"
26#include "views/window/window.h"
[email protected]031e4d32009-12-29 01:13:2327
[email protected]6ff244f2009-01-20 20:38:0828#if defined(OS_WIN)
[email protected]5fe15722010-10-22 00:03:2229#include "views/accessibility/view_accessibility.h"
[email protected]6ff244f2009-01-20 20:38:0830#endif
[email protected]031e4d32009-12-29 01:13:2331#if defined(OS_LINUX)
32#include "app/scoped_handle_gtk.h"
33#endif
initial.commit09911bf2008-07-26 23:55:2934
[email protected]c2dacc92008-10-16 23:51:3835namespace views {
initial.commit09911bf2008-07-26 23:55:2936
37// static
[email protected]3ee83f2c2009-05-10 05:58:4038ViewsDelegate* ViewsDelegate::views_delegate = NULL;
39
40// static
[email protected]2362e4f2009-05-08 00:34:0541char View::kViewClassName[] = "views/View";
initial.commit09911bf2008-07-26 23:55:2942
[email protected]8af4c1992010-02-04 21:38:0743// static
44const int View::kShowFolderDropMenuDelay = 400;
45
initial.commit09911bf2008-07-26 23:55:2946/////////////////////////////////////////////////////////////////////////////
47//
48// View - constructors, destructors, initialization
49//
50/////////////////////////////////////////////////////////////////////////////
51
52View::View()
53 : id_(0),
54 group_(-1),
[email protected]6ff244f2009-01-20 20:38:0855 enabled_(true),
56 focusable_(false),
[email protected]83548a42010-06-18 13:53:3757 accessibility_focusable_(false),
[email protected]4f3dc372009-02-24 00:10:2958 bounds_(0, 0, 0, 0),
[email protected]9ea053e2010-07-15 08:19:0559 needs_layout_(true),
initial.commit09911bf2008-07-26 23:55:2960 parent_(NULL),
initial.commit09911bf2008-07-26 23:55:2961 is_visible_(true),
initial.commit09911bf2008-07-26 23:55:2962 is_parent_owned_(true),
63 notify_when_visible_bounds_in_root_changes_(false),
64 registered_for_visible_bounds_notification_(false),
[email protected]bda9556c2010-01-07 00:55:1665 accelerator_registration_delayed_(false),
initial.commit09911bf2008-07-26 23:55:2966 next_focusable_view_(NULL),
67 previous_focusable_view_(NULL),
[email protected]bda9556c2010-01-07 00:55:1668 accelerator_focus_manager_(NULL),
[email protected]71421c3f2009-06-06 00:41:4469 registered_accelerator_count_(0),
initial.commit09911bf2008-07-26 23:55:2970 context_menu_controller_(NULL),
71 drag_controller_(NULL),
initial.commit09911bf2008-07-26 23:55:2972 flip_canvas_on_paint_for_rtl_ui_(false) {
73}
74
75View::~View() {
[email protected]8c57de22010-03-12 21:06:0476 if (parent_)
77 parent_->RemoveChildView(this);
78
initial.commit09911bf2008-07-26 23:55:2979 int c = static_cast<int>(child_views_.size());
80 while (--c >= 0) {
[email protected]8c57de22010-03-12 21:06:0481 child_views_[c]->SetParent(NULL);
initial.commit09911bf2008-07-26 23:55:2982 if (child_views_[c]->IsParentOwned())
83 delete child_views_[c];
initial.commit09911bf2008-07-26 23:55:2984 }
[email protected]a64f33902009-10-10 05:41:2385
86#if defined(OS_WIN)
[email protected]5fe15722010-10-22 00:03:2287 if (view_accessibility_.get())
88 view_accessibility_->set_view(NULL);
[email protected]a64f33902009-10-10 05:41:2389#endif
initial.commit09911bf2008-07-26 23:55:2990}
91
92/////////////////////////////////////////////////////////////////////////////
93//
94// View - sizing
95//
96/////////////////////////////////////////////////////////////////////////////
97
[email protected]0d8ea702008-10-14 17:03:0798gfx::Rect View::GetBounds(PositionMirroringSettings settings) const {
99 gfx::Rect bounds(bounds_);
initial.commit09911bf2008-07-26 23:55:29100
101 // If the parent uses an RTL UI layout and if we are asked to transform the
102 // bounds to their mirrored position if necessary, then we should shift the
103 // rectangle appropriately.
[email protected]0d8ea702008-10-14 17:03:07104 if (settings == APPLY_MIRRORING_TRANSFORMATION)
105 bounds.set_x(MirroredX());
[email protected]4f3dc372009-02-24 00:10:29106
[email protected]0d8ea702008-10-14 17:03:07107 return bounds;
initial.commit09911bf2008-07-26 23:55:29108}
109
[email protected]6f3bb6c2008-09-17 22:25:33110// y(), width() and height() are agnostic to the RTL UI layout of the
111// parent view. x(), on the other hand, is not.
initial.commit09911bf2008-07-26 23:55:29112int View::GetX(PositionMirroringSettings settings) const {
[email protected]80f8b9f2008-10-16 18:17:47113 return settings == IGNORE_MIRRORING_TRANSFORMATION ? x() : MirroredX();
initial.commit09911bf2008-07-26 23:55:29114}
115
[email protected]80f8b9f2008-10-16 18:17:47116void View::SetBounds(const gfx::Rect& bounds) {
[email protected]de8d613d2010-10-25 22:30:10117 if (bounds == bounds_) {
118 if (needs_layout_) {
119 needs_layout_ = false;
120 Layout();
121 }
initial.commit09911bf2008-07-26 23:55:29122 return;
[email protected]de8d613d2010-10-25 22:30:10123 }
initial.commit09911bf2008-07-26 23:55:29124
[email protected]80f8b9f2008-10-16 18:17:47125 gfx::Rect prev = bounds_;
initial.commit09911bf2008-07-26 23:55:29126 bounds_ = bounds;
[email protected]b97c8a22010-02-05 19:36:43127 bool size_changed = prev.size() != bounds_.size();
128 bool position_changed = prev.origin() != bounds_.origin();
initial.commit09911bf2008-07-26 23:55:29129
[email protected]b97c8a22010-02-05 19:36:43130 if (size_changed || position_changed) {
131 DidChangeBounds(prev, bounds_);
132
133 RootView* root = GetRootView();
134 if (root)
initial.commit09911bf2008-07-26 23:55:29135 root->ViewBoundsChanged(this, size_changed, position_changed);
136 }
137}
138
[email protected]80f8b9f2008-10-16 18:17:47139gfx::Rect View::GetLocalBounds(bool include_border) const {
[email protected]9a3f0ac22008-11-14 03:24:02140 if (include_border || !border_.get())
[email protected]80f8b9f2008-10-16 18:17:47141 return gfx::Rect(0, 0, width(), height());
initial.commit09911bf2008-07-26 23:55:29142
[email protected]80f8b9f2008-10-16 18:17:47143 gfx::Insets insets;
144 border_->GetInsets(&insets);
145 return gfx::Rect(insets.left(), insets.top(),
[email protected]4a8d3272009-03-10 19:15:08146 std::max(0, width() - insets.width()),
147 std::max(0, height() - insets.height()));
initial.commit09911bf2008-07-26 23:55:29148}
149
[email protected]0a1d36b22008-10-17 19:33:09150gfx::Point View::GetPosition() const {
151 return gfx::Point(GetX(APPLY_MIRRORING_TRANSFORMATION), y());
initial.commit09911bf2008-07-26 23:55:29152}
153
[email protected]154f8bc2008-10-15 18:02:30154gfx::Size View::GetPreferredSize() {
155 if (layout_manager_.get())
156 return layout_manager_->GetPreferredSize(this);
157 return gfx::Size();
initial.commit09911bf2008-07-26 23:55:29158}
159
[email protected]a1360162009-11-30 21:19:07160int View::GetBaseline() {
161 return -1;
162}
163
initial.commit09911bf2008-07-26 23:55:29164void View::SizeToPreferredSize() {
[email protected]154f8bc2008-10-15 18:02:30165 gfx::Size prefsize = GetPreferredSize();
166 if ((prefsize.width() != width()) || (prefsize.height() != height()))
167 SetBounds(x(), y(), prefsize.width(), prefsize.height());
initial.commit09911bf2008-07-26 23:55:29168}
169
[email protected]7ccc52b72009-05-08 21:09:11170void View::PreferredSizeChanged() {
[email protected]9ea053e2010-07-15 08:19:05171 InvalidateLayout();
[email protected]7ccc52b72009-05-08 21:09:11172 if (parent_)
173 parent_->ChildPreferredSizeChanged(this);
174}
175
[email protected]154f8bc2008-10-15 18:02:30176gfx::Size View::GetMinimumSize() {
177 return GetPreferredSize();
initial.commit09911bf2008-07-26 23:55:29178}
179
180int View::GetHeightForWidth(int w) {
181 if (layout_manager_.get())
182 return layout_manager_->GetPreferredHeightForWidth(this, w);
[email protected]154f8bc2008-10-15 18:02:30183 return GetPreferredSize().height();
initial.commit09911bf2008-07-26 23:55:29184}
185
[email protected]80f8b9f2008-10-16 18:17:47186void View::DidChangeBounds(const gfx::Rect& previous,
187 const gfx::Rect& current) {
[email protected]9ea053e2010-07-15 08:19:05188 needs_layout_ = false;
[email protected]80f8b9f2008-10-16 18:17:47189 Layout();
initial.commit09911bf2008-07-26 23:55:29190}
191
[email protected]e9adf0702010-03-08 23:34:07192void View::ScrollRectToVisible(const gfx::Rect& rect) {
initial.commit09911bf2008-07-26 23:55:29193 View* parent = GetParent();
194
195 // We must take RTL UI mirroring into account when adjusting the position of
196 // the region.
[email protected]e9adf0702010-03-08 23:34:07197 if (parent) {
198 gfx::Rect scroll_rect(rect);
199 scroll_rect.Offset(GetX(APPLY_MIRRORING_TRANSFORMATION), y());
200 parent->ScrollRectToVisible(scroll_rect);
201 }
initial.commit09911bf2008-07-26 23:55:29202}
203
204/////////////////////////////////////////////////////////////////////////////
205//
206// View - layout
207//
208/////////////////////////////////////////////////////////////////////////////
209
210void View::Layout() {
[email protected]9ea053e2010-07-15 08:19:05211 needs_layout_ = false;
212
[email protected]f8617192010-07-05 07:57:10213 // If we have a layout manager, let it handle the layout for us.
initial.commit09911bf2008-07-26 23:55:29214 if (layout_manager_.get()) {
215 layout_manager_->Layout(this);
216 SchedulePaint();
217 }
218
[email protected]9ea053e2010-07-15 08:19:05219 // Make sure to propagate the Layout() call to any children that haven't
220 // received it yet through the layout manager and need to be laid out. This
221 // is needed for the case when the child requires a layout but its bounds
222 // weren't changed by the layout manager. If there is no layout manager, we
223 // just propagate the Layout() call down the hierarchy, so whoever receives
224 // the call can take appropriate action.
[email protected]09fe9492009-11-07 02:23:06225 for (int i = 0, count = GetChildViewCount(); i < count; ++i) {
initial.commit09911bf2008-07-26 23:55:29226 View* child = GetChildViewAt(i);
[email protected]9ea053e2010-07-15 08:19:05227 if (child->needs_layout_ || !layout_manager_.get()) {
228 child->needs_layout_ = false;
229 child->Layout();
230 }
initial.commit09911bf2008-07-26 23:55:29231 }
232}
233
[email protected]9ea053e2010-07-15 08:19:05234void View::InvalidateLayout() {
[email protected]de8d613d2010-10-25 22:30:10235 // Always invalidate up. This is needed to handle the case of us already being
236 // valid, but not our parent.
[email protected]9ea053e2010-07-15 08:19:05237 needs_layout_ = true;
238 if (parent_)
239 parent_->InvalidateLayout();
240}
241
initial.commit09911bf2008-07-26 23:55:29242LayoutManager* View::GetLayoutManager() const {
243 return layout_manager_.get();
244}
245
246void View::SetLayoutManager(LayoutManager* layout_manager) {
[email protected]09fe9492009-11-07 02:23:06247 if (layout_manager_.get())
initial.commit09911bf2008-07-26 23:55:29248 layout_manager_->Uninstalled(this);
[email protected]09fe9492009-11-07 02:23:06249
initial.commit09911bf2008-07-26 23:55:29250 layout_manager_.reset(layout_manager);
[email protected]09fe9492009-11-07 02:23:06251 if (layout_manager_.get())
initial.commit09911bf2008-07-26 23:55:29252 layout_manager_->Installed(this);
initial.commit09911bf2008-07-26 23:55:29253}
254
255////////////////////////////////////////////////////////////////////////////////
256//
257// View - Right-to-left UI layout
258//
259////////////////////////////////////////////////////////////////////////////////
260
[email protected]c3bca422010-02-19 23:29:02261int View::MirroredX() const {
initial.commit09911bf2008-07-26 23:55:29262 View* parent = GetParent();
[email protected]aaa71da52010-02-19 21:39:24263 return parent ? parent->MirroredLeftPointForRect(bounds_) : x();
initial.commit09911bf2008-07-26 23:55:29264}
265
266int View::MirroredLeftPointForRect(const gfx::Rect& bounds) const {
[email protected]c2f4bdb72010-05-10 23:15:21267 return base::i18n::IsRTL() ?
[email protected]aaa71da52010-02-19 21:39:24268 (width() - bounds.x() - bounds.width()) : bounds.x();
initial.commit09911bf2008-07-26 23:55:29269}
270
271////////////////////////////////////////////////////////////////////////////////
272//
273// View - states
274//
275////////////////////////////////////////////////////////////////////////////////
276
277bool View::IsEnabled() const {
278 return enabled_;
279}
280
281void View::SetEnabled(bool state) {
282 if (enabled_ != state) {
283 enabled_ = state;
284 SchedulePaint();
285 }
286}
287
initial.commit09911bf2008-07-26 23:55:29288void View::SetFocusable(bool focusable) {
289 focusable_ = focusable;
290}
291
[email protected]59461d22010-07-21 15:41:09292bool View::IsFocusableInRootView() const {
293 return IsFocusable() && IsVisibleInRootView();
294}
295
296bool View::IsAccessibilityFocusableInRootView() const {
[email protected]1aa36552010-07-14 08:21:25297 return (focusable_ || accessibility_focusable_) && IsEnabled() &&
298 IsVisibleInRootView();
[email protected]83548a42010-06-18 13:53:37299}
300
[email protected]82166b62009-06-30 18:48:00301FocusManager* View::GetFocusManager() {
302 Widget* widget = GetWidget();
303 return widget ? widget->GetFocusManager() : NULL;
304}
305
initial.commit09911bf2008-07-26 23:55:29306bool View::HasFocus() {
initial.commit09911bf2008-07-26 23:55:29307 FocusManager* focus_manager = GetFocusManager();
308 if (focus_manager)
309 return focus_manager->GetFocusedView() == this;
310 return false;
311}
312
[email protected]5c9e97a2009-09-09 23:48:30313void View::Focus() {
[email protected]7f14e1f2009-10-01 15:57:26314 // By default, we clear the native focus. This ensures that no visible native
315 // view as the focus and that we still receive keyboard inputs.
[email protected]5c9e97a2009-09-09 23:48:30316 FocusManager* focus_manager = GetFocusManager();
317 if (focus_manager)
[email protected]7f14e1f2009-10-01 15:57:26318 focus_manager->ClearNativeFocus();
[email protected]6a054ffa2010-08-06 07:07:18319
320 // Notify assistive technologies of the focus change.
321 NotifyAccessibilityEvent(AccessibilityTypes::EVENT_FOCUS);
322}
323
324void View::NotifyAccessibilityEvent(AccessibilityTypes::Event event_type) {
325 NotifyAccessibilityEvent(event_type, true);
[email protected]5c9e97a2009-09-09 23:48:30326}
327
initial.commit09911bf2008-07-26 23:55:29328void View::SetHotTracked(bool flag) {
329}
330
331/////////////////////////////////////////////////////////////////////////////
332//
333// View - painting
334//
335/////////////////////////////////////////////////////////////////////////////
336
[email protected]0a1d36b22008-10-17 19:33:09337void View::SchedulePaint(const gfx::Rect& r, bool urgent) {
338 if (!IsVisible())
initial.commit09911bf2008-07-26 23:55:29339 return;
initial.commit09911bf2008-07-26 23:55:29340
341 if (parent_) {
342 // Translate the requested paint rect to the parent's coordinate system
343 // then pass this notification up to the parent.
[email protected]0a1d36b22008-10-17 19:33:09344 gfx::Rect paint_rect = r;
345 paint_rect.Offset(GetPosition());
initial.commit09911bf2008-07-26 23:55:29346 parent_->SchedulePaint(paint_rect, urgent);
347 }
348}
349
350void View::SchedulePaint() {
[email protected]0a1d36b22008-10-17 19:33:09351 SchedulePaint(GetLocalBounds(true), false);
initial.commit09911bf2008-07-26 23:55:29352}
353
[email protected]82522512009-05-15 07:37:29354void View::Paint(gfx::Canvas* canvas) {
initial.commit09911bf2008-07-26 23:55:29355 PaintBackground(canvas);
356 PaintFocusBorder(canvas);
357 PaintBorder(canvas);
358}
359
[email protected]82522512009-05-15 07:37:29360void View::PaintBackground(gfx::Canvas* canvas) {
[email protected]9a3f0ac22008-11-14 03:24:02361 if (background_.get())
initial.commit09911bf2008-07-26 23:55:29362 background_->Paint(canvas, this);
363}
364
[email protected]82522512009-05-15 07:37:29365void View::PaintBorder(gfx::Canvas* canvas) {
[email protected]9a3f0ac22008-11-14 03:24:02366 if (border_.get())
initial.commit09911bf2008-07-26 23:55:29367 border_->Paint(*this, canvas);
368}
369
[email protected]82522512009-05-15 07:37:29370void View::PaintFocusBorder(gfx::Canvas* canvas) {
[email protected]59461d22010-07-21 15:41:09371 if (HasFocus() && (IsFocusable() || IsAccessibilityFocusableInRootView()))
[email protected]6f3bb6c2008-09-17 22:25:33372 canvas->DrawFocusRect(0, 0, width(), height());
initial.commit09911bf2008-07-26 23:55:29373}
374
[email protected]82522512009-05-15 07:37:29375void View::PaintChildren(gfx::Canvas* canvas) {
[email protected]09fe9492009-11-07 02:23:06376 for (int i = 0, count = GetChildViewCount(); i < count; ++i) {
initial.commit09911bf2008-07-26 23:55:29377 View* child = GetChildViewAt(i);
378 if (!child) {
379 NOTREACHED() << "Should not have a NULL child View for index in bounds";
380 continue;
381 }
382 child->ProcessPaint(canvas);
383 }
384}
385
[email protected]82522512009-05-15 07:37:29386void View::ProcessPaint(gfx::Canvas* canvas) {
[email protected]09fe9492009-11-07 02:23:06387 if (!IsVisible())
initial.commit09911bf2008-07-26 23:55:29388 return;
initial.commit09911bf2008-07-26 23:55:29389
390 // We're going to modify the canvas, save it's state first.
[email protected]bd026802010-06-29 22:08:44391 canvas->Save();
initial.commit09911bf2008-07-26 23:55:29392
393 // Paint this View and its children, setting the clip rect to the bounds
394 // of this View and translating the origin to the local bounds' top left
395 // point.
396 //
397 // Note that the X (or left) position we pass to ClipRectInt takes into
398 // consideration whether or not the view uses a right-to-left layout so that
399 // we paint our view in its mirrored position if need be.
[email protected]80f8b9f2008-10-16 18:17:47400 if (canvas->ClipRectInt(MirroredX(), y(), width(), height())) {
initial.commit09911bf2008-07-26 23:55:29401 // Non-empty clip, translate the graphics such that 0,0 corresponds to
402 // where this view is located (related to its parent).
[email protected]80f8b9f2008-10-16 18:17:47403 canvas->TranslateInt(MirroredX(), y());
initial.commit09911bf2008-07-26 23:55:29404
initial.commit09911bf2008-07-26 23:55:29405 // If the View we are about to paint requested the canvas to be flipped, we
406 // should change the transform appropriately.
[email protected]abffeda2010-08-13 22:35:50407 canvas->Save();
408 if (FlipCanvasOnPaintForRTLUI()) {
[email protected]6f3bb6c2008-09-17 22:25:33409 canvas->TranslateInt(width(), 0);
initial.commit09911bf2008-07-26 23:55:29410 canvas->ScaleInt(-1, 1);
initial.commit09911bf2008-07-26 23:55:29411 }
412
413 Paint(canvas);
414
415 // We must undo the canvas mirroring once the View is done painting so that
416 // we don't pass the canvas with the mirrored transform to Views that
417 // didn't request the canvas to be flipped.
[email protected]bd026802010-06-29 22:08:44418 canvas->Restore();
[email protected]abffeda2010-08-13 22:35:50419
initial.commit09911bf2008-07-26 23:55:29420 PaintChildren(canvas);
421 }
422
423 // Restore the canvas's original transform.
[email protected]bd026802010-06-29 22:08:44424 canvas->Restore();
initial.commit09911bf2008-07-26 23:55:29425}
426
427void View::PaintNow() {
[email protected]09fe9492009-11-07 02:23:06428 if (!IsVisible())
initial.commit09911bf2008-07-26 23:55:29429 return;
initial.commit09911bf2008-07-26 23:55:29430
431 View* view = GetParent();
432 if (view)
433 view->PaintNow();
434}
435
initial.commit09911bf2008-07-26 23:55:29436gfx::Insets View::GetInsets() const {
initial.commit09911bf2008-07-26 23:55:29437 gfx::Insets insets;
[email protected]9a3f0ac22008-11-14 03:24:02438 if (border_.get())
439 border_->GetInsets(&insets);
initial.commit09911bf2008-07-26 23:55:29440 return insets;
441}
442
[email protected]e9adf0702010-03-08 23:34:07443gfx::NativeCursor View::GetCursorForPoint(Event::EventType event_type,
444 const gfx::Point& p) {
[email protected]9abf8dd62009-06-04 06:40:42445 return NULL;
446}
447
[email protected]a52ca4672009-06-05 05:41:09448bool View::HitTest(const gfx::Point& l) const {
[email protected]d7fc97942009-11-20 22:07:11449 if (l.x() >= 0 && l.x() < width() && l.y() >= 0 && l.y() < height()) {
[email protected]a52ca4672009-06-05 05:41:09450 if (HasHitTestMask()) {
451 gfx::Path mask;
452 GetHitTestMask(&mask);
[email protected]a3406972009-11-04 05:05:48453 ScopedRegion rgn(mask.CreateNativeRegion());
454 // TODO: can this use SkRegion's contains instead?
[email protected]a52ca4672009-06-05 05:41:09455#if defined(OS_WIN)
[email protected]a52ca4672009-06-05 05:41:09456 return !!PtInRegion(rgn, l.x(), l.y());
[email protected]10a6e77b2009-12-31 01:03:52457#elif defined(TOOLKIT_USES_GTK)
[email protected]a3406972009-11-04 05:05:48458 return gdk_region_point_in(rgn.Get(), l.x(), l.y());
[email protected]a52ca4672009-06-05 05:41:09459#endif
460 }
461 // No mask, but inside our bounds.
462 return true;
463 }
464 // Outside our bounds.
465 return false;
466}
467
initial.commit09911bf2008-07-26 23:55:29468void View::SetContextMenuController(ContextMenuController* menu_controller) {
469 context_menu_controller_ = menu_controller;
470}
471
[email protected]e9adf0702010-03-08 23:34:07472void View::ShowContextMenu(const gfx::Point& p, bool is_mouse_gesture) {
[email protected]042811c2008-10-31 21:31:34473 if (!context_menu_controller_)
474 return;
475
[email protected]e9adf0702010-03-08 23:34:07476 context_menu_controller_->ShowContextMenu(this, p, is_mouse_gesture);
[email protected]042811c2008-10-31 21:31:34477}
478
initial.commit09911bf2008-07-26 23:55:29479/////////////////////////////////////////////////////////////////////////////
480//
481// View - tree
482//
483/////////////////////////////////////////////////////////////////////////////
484
485bool View::ProcessMousePressed(const MouseEvent& e, DragInfo* drag_info) {
[email protected]83548a42010-06-18 13:53:37486 const bool enabled = IsEnabled();
[email protected]e9adf0702010-03-08 23:34:07487 int drag_operations =
488 (enabled && e.IsOnlyLeftMouseButton() && HitTest(e.location())) ?
489 GetDragOperations(e.location()) : 0;
490 ContextMenuController* context_menu_controller = e.IsRightMouseButton() ?
491 context_menu_controller_ : 0;
initial.commit09911bf2008-07-26 23:55:29492
493 const bool result = OnMousePressed(e);
494 // WARNING: we may have been deleted, don't use any View variables;
495
496 if (!enabled)
497 return result;
498
499 if (drag_operations != DragDropTypes::DRAG_NONE) {
[email protected]e9adf0702010-03-08 23:34:07500 drag_info->PossibleDrag(e.location());
initial.commit09911bf2008-07-26 23:55:29501 return true;
502 }
503 return !!context_menu_controller || result;
504}
505
506bool View::ProcessMouseDragged(const MouseEvent& e, DragInfo* drag_info) {
507 // Copy the field, that way if we're deleted after drag and drop no harm is
508 // done.
509 ContextMenuController* context_menu_controller = context_menu_controller_;
510 const bool possible_drag = drag_info->possible_drag;
[email protected]e9adf0702010-03-08 23:34:07511 if (possible_drag && ExceededDragThreshold(drag_info->start_pt.x() - e.x(),
512 drag_info->start_pt.y() - e.y())) {
[email protected]b5f94de2009-12-04 07:59:00513 if (!drag_controller_ ||
[email protected]e9adf0702010-03-08 23:34:07514 drag_controller_->CanStartDrag(this, drag_info->start_pt, e.location()))
515 DoDrag(e, drag_info->start_pt);
initial.commit09911bf2008-07-26 23:55:29516 } else {
517 if (OnMouseDragged(e))
518 return true;
519 // Fall through to return value based on context menu controller.
520 }
521 // WARNING: we may have been deleted.
522 return (context_menu_controller != NULL) || possible_drag;
523}
524
525void View::ProcessMouseReleased(const MouseEvent& e, bool canceled) {
526 if (!canceled && context_menu_controller_ && e.IsOnlyRightMouseButton()) {
527 // Assume that if there is a context menu controller we won't be deleted
528 // from mouse released.
[email protected]96b667d2008-10-14 20:58:44529 gfx::Point location(e.location());
initial.commit09911bf2008-07-26 23:55:29530 OnMouseReleased(e, canceled);
[email protected]464fdb32009-03-19 20:25:44531 if (HitTest(location)) {
532 ConvertPointToScreen(this, &location);
[email protected]e9adf0702010-03-08 23:34:07533 ShowContextMenu(location, true);
[email protected]464fdb32009-03-19 20:25:44534 }
initial.commit09911bf2008-07-26 23:55:29535 } else {
536 OnMouseReleased(e, canceled);
537 }
538 // WARNING: we may have been deleted.
539}
540
[email protected]ad84c8f2010-09-08 14:06:10541#if defined(TOUCH_UI)
542bool View::ProcessTouchEvent(const TouchEvent& e) {
543 // TODO(rjkroege): Implement a grab scheme similar to as
544 // as is found in MousePressed.
545 const bool result = OnTouchEvent(e);
546 return result;
547}
548#endif
549
initial.commit09911bf2008-07-26 23:55:29550void View::AddChildView(View* v) {
[email protected]0d52b2302009-05-11 23:50:55551 AddChildView(static_cast<int>(child_views_.size()), v);
initial.commit09911bf2008-07-26 23:55:29552}
553
554void View::AddChildView(int index, View* v) {
[email protected]0b2fa2b2009-12-01 01:06:12555 CHECK(v != this) << "You cannot add a view as its own child";
556
initial.commit09911bf2008-07-26 23:55:29557 // Remove the view from its current parent if any.
558 if (v->GetParent())
559 v->GetParent()->RemoveChildView(v);
560
[email protected]0d52b2302009-05-11 23:50:55561 // Sets the prev/next focus views.
562 InitFocusSiblings(v, index);
initial.commit09911bf2008-07-26 23:55:29563
564 // Let's insert the view.
565 child_views_.insert(child_views_.begin() + index, v);
566 v->SetParent(this);
567
[email protected]09fe9492009-11-07 02:23:06568 for (View* p = this; p; p = p->GetParent())
initial.commit09911bf2008-07-26 23:55:29569 p->ViewHierarchyChangedImpl(false, true, this, v);
[email protected]09fe9492009-11-07 02:23:06570
initial.commit09911bf2008-07-26 23:55:29571 v->PropagateAddNotifications(this, v);
572 UpdateTooltip();
573 RootView* root = GetRootView();
574 if (root)
[email protected]9fc4f202010-07-07 15:38:19575 RegisterChildrenForVisibleBoundsNotification(root, v);
initial.commit09911bf2008-07-26 23:55:29576
577 if (layout_manager_.get())
578 layout_manager_->ViewAdded(this, v);
579}
580
581View* View::GetChildViewAt(int index) const {
582 return index < GetChildViewCount() ? child_views_[index] : NULL;
583}
584
585int View::GetChildViewCount() const {
586 return static_cast<int>(child_views_.size());
587}
588
[email protected]3a9c26f2010-03-12 21:04:39589bool View::HasChildView(View* a_view) {
590 return find(child_views_.begin(),
591 child_views_.end(),
592 a_view) != child_views_.end();
593}
594
initial.commit09911bf2008-07-26 23:55:29595void View::RemoveChildView(View* a_view) {
596 DoRemoveChildView(a_view, true, true, false);
597}
598
599void View::RemoveAllChildViews(bool delete_views) {
600 ViewList::iterator iter;
601 while ((iter = child_views_.begin()) != child_views_.end()) {
602 DoRemoveChildView(*iter, false, false, delete_views);
603 }
604 UpdateTooltip();
605}
606
[email protected]e9adf0702010-03-08 23:34:07607void View::DoDrag(const MouseEvent& e, const gfx::Point& press_pt) {
608 int drag_operations = GetDragOperations(press_pt);
[email protected]4768c65b2009-08-28 21:42:59609 if (drag_operations == DragDropTypes::DRAG_NONE)
610 return;
611
612 OSExchangeData data;
[email protected]e9adf0702010-03-08 23:34:07613 WriteDragData(press_pt, &data);
[email protected]4768c65b2009-08-28 21:42:59614
615 // Message the RootView to do the drag and drop. That way if we're removed
616 // the RootView can detect it and avoid calling us back.
617 RootView* root_view = GetRootView();
618 root_view->StartDragForViewFromMouseEvent(this, data, drag_operations);
619}
620
initial.commit09911bf2008-07-26 23:55:29621void View::DoRemoveChildView(View* a_view,
622 bool update_focus_cycle,
623 bool update_tool_tip,
624 bool delete_removed_view) {
625#ifndef NDEBUG
626 DCHECK(!IsProcessingPaint()) << "Should not be removing a child view " <<
627 "during a paint, this will seriously " <<
628 "mess things up!";
629#endif
630 DCHECK(a_view);
631 const ViewList::iterator i = find(child_views_.begin(),
632 child_views_.end(),
633 a_view);
634 if (i != child_views_.end()) {
[email protected]0d52b2302009-05-11 23:50:55635 if (update_focus_cycle) {
initial.commit09911bf2008-07-26 23:55:29636 // Let's remove the view from the focus traversal.
637 View* next_focusable = a_view->next_focusable_view_;
638 View* prev_focusable = a_view->previous_focusable_view_;
639 if (prev_focusable)
640 prev_focusable->next_focusable_view_ = next_focusable;
641 if (next_focusable)
642 next_focusable->previous_focusable_view_ = prev_focusable;
643 }
644
645 RootView* root = GetRootView();
646 if (root)
[email protected]9fc4f202010-07-07 15:38:19647 UnregisterChildrenForVisibleBoundsNotification(root, a_view);
initial.commit09911bf2008-07-26 23:55:29648 a_view->PropagateRemoveNotifications(this);
649 a_view->SetParent(NULL);
650
651 if (delete_removed_view && a_view->IsParentOwned())
652 delete a_view;
653
654 child_views_.erase(i);
655 }
656
657 if (update_tool_tip)
658 UpdateTooltip();
659
660 if (layout_manager_.get())
661 layout_manager_->ViewRemoved(this, a_view);
662}
663
664void View::PropagateRemoveNotifications(View* parent) {
[email protected]09fe9492009-11-07 02:23:06665 for (int i = 0, count = GetChildViewCount(); i < count; ++i)
initial.commit09911bf2008-07-26 23:55:29666 GetChildViewAt(i)->PropagateRemoveNotifications(parent);
initial.commit09911bf2008-07-26 23:55:29667
[email protected]09fe9492009-11-07 02:23:06668 for (View* v = this; v; v = v->GetParent())
669 v->ViewHierarchyChangedImpl(true, false, parent, this);
initial.commit09911bf2008-07-26 23:55:29670}
671
672void View::PropagateAddNotifications(View* parent, View* child) {
[email protected]09fe9492009-11-07 02:23:06673 for (int i = 0, count = GetChildViewCount(); i < count; ++i)
initial.commit09911bf2008-07-26 23:55:29674 GetChildViewAt(i)->PropagateAddNotifications(parent, child);
initial.commit09911bf2008-07-26 23:55:29675 ViewHierarchyChangedImpl(true, true, parent, child);
676}
677
[email protected]59461d22010-07-21 15:41:09678bool View::IsFocusable() const {
679 return focusable_ && IsEnabled() && IsVisible();
680}
681
[email protected]8b9a8f12010-07-27 01:39:13682void View::PropagateThemeChanged() {
[email protected]b2b718012010-03-25 15:09:06683 for (int i = GetChildViewCount() - 1; i >= 0; --i)
[email protected]8b9a8f12010-07-27 01:39:13684 GetChildViewAt(i)->PropagateThemeChanged();
685 OnThemeChanged();
[email protected]32670b02009-03-03 00:28:00686}
687
[email protected]8b9a8f12010-07-27 01:39:13688void View::PropagateLocaleChanged() {
[email protected]b2b718012010-03-25 15:09:06689 for (int i = GetChildViewCount() - 1; i >= 0; --i)
[email protected]8b9a8f12010-07-27 01:39:13690 GetChildViewAt(i)->PropagateLocaleChanged();
691 OnLocaleChanged();
[email protected]b2b718012010-03-25 15:09:06692}
693
initial.commit09911bf2008-07-26 23:55:29694#ifndef NDEBUG
695bool View::IsProcessingPaint() const {
696 return GetParent() && GetParent()->IsProcessingPaint();
697}
698#endif
699
[email protected]f704ee72008-11-10 21:31:59700gfx::Point View::GetKeyboardContextMenuLocation() {
701 gfx::Rect vis_bounds = GetVisibleBounds();
702 gfx::Point screen_point(vis_bounds.x() + vis_bounds.width() / 2,
703 vis_bounds.y() + vis_bounds.height() / 2);
704 ConvertPointToScreen(this, &screen_point);
705 return screen_point;
706}
707
[email protected]82739cf2008-09-16 00:37:56708bool View::HasHitTestMask() const {
709 return false;
710}
711
712void View::GetHitTestMask(gfx::Path* mask) const {
713 DCHECK(mask);
714}
715
[email protected]bb515ed2009-01-15 00:53:43716void View::ViewHierarchyChanged(bool is_add,
717 View* parent,
718 View* child) {
initial.commit09911bf2008-07-26 23:55:29719}
720
721void View::ViewHierarchyChangedImpl(bool register_accelerators,
[email protected]bb515ed2009-01-15 00:53:43722 bool is_add,
723 View* parent,
724 View* child) {
initial.commit09911bf2008-07-26 23:55:29725 if (register_accelerators) {
726 if (is_add) {
727 // If you get this registration, you are part of a subtree that has been
728 // added to the view hierarchy.
[email protected]bda9556c2010-01-07 00:55:16729 if (GetFocusManager()) {
730 RegisterPendingAccelerators();
731 } else {
732 // Delay accelerator registration until visible as we do not have
733 // focus manager until then.
734 accelerator_registration_delayed_ = true;
735 }
initial.commit09911bf2008-07-26 23:55:29736 } else {
737 if (child == this)
[email protected]fa1cf0b82010-01-15 21:49:44738 UnregisterAccelerators(true);
initial.commit09911bf2008-07-26 23:55:29739 }
740 }
741
742 ViewHierarchyChanged(is_add, parent, child);
[email protected]9ea053e2010-07-15 08:19:05743 parent->needs_layout_ = true;
initial.commit09911bf2008-07-26 23:55:29744}
745
746void View::PropagateVisibilityNotifications(View* start, bool is_visible) {
[email protected]09fe9492009-11-07 02:23:06747 for (int i = 0, count = GetChildViewCount(); i < count; ++i)
initial.commit09911bf2008-07-26 23:55:29748 GetChildViewAt(i)->PropagateVisibilityNotifications(start, is_visible);
initial.commit09911bf2008-07-26 23:55:29749 VisibilityChanged(start, is_visible);
750}
751
752void View::VisibilityChanged(View* starting_from, bool is_visible) {
753}
754
[email protected]bda9556c2010-01-07 00:55:16755void View::PropagateNativeViewHierarchyChanged(bool attached,
756 gfx::NativeView native_view,
757 RootView* root_view) {
758 for (int i = 0, count = GetChildViewCount(); i < count; ++i)
759 GetChildViewAt(i)->PropagateNativeViewHierarchyChanged(attached,
760 native_view,
761 root_view);
762 NativeViewHierarchyChanged(attached, native_view, root_view);
763}
764
765void View::NativeViewHierarchyChanged(bool attached,
766 gfx::NativeView native_view,
767 RootView* root_view) {
768 FocusManager* focus_manager = GetFocusManager();
769 if (!accelerator_registration_delayed_ &&
770 accelerator_focus_manager_ &&
771 accelerator_focus_manager_ != focus_manager) {
772 UnregisterAccelerators(true);
773 accelerator_registration_delayed_ = true;
774 }
775 if (accelerator_registration_delayed_ && attached) {
776 if (focus_manager) {
777 RegisterPendingAccelerators();
778 accelerator_registration_delayed_ = false;
779 }
780 }
781}
782
initial.commit09911bf2008-07-26 23:55:29783void View::SetNotifyWhenVisibleBoundsInRootChanges(bool value) {
784 if (notify_when_visible_bounds_in_root_changes_ == value)
785 return;
786 notify_when_visible_bounds_in_root_changes_ = value;
787 RootView* root = GetRootView();
788 if (root) {
789 if (value)
790 root->RegisterViewForVisibleBoundsNotification(this);
791 else
792 root->UnregisterViewForVisibleBoundsNotification(this);
793 }
794}
795
796bool View::GetNotifyWhenVisibleBoundsInRootChanges() {
797 return notify_when_visible_bounds_in_root_changes_;
798}
799
[email protected]0d52b2302009-05-11 23:50:55800View* View::GetViewForPoint(const gfx::Point& point) {
initial.commit09911bf2008-07-26 23:55:29801 // Walk the child Views recursively looking for the View that most
802 // tightly encloses the specified point.
[email protected]09fe9492009-11-07 02:23:06803 for (int i = GetChildViewCount() - 1; i >= 0; --i) {
initial.commit09911bf2008-07-26 23:55:29804 View* child = GetChildViewAt(i);
[email protected]82739cf2008-09-16 00:37:56805 if (!child->IsVisible())
initial.commit09911bf2008-07-26 23:55:29806 continue;
[email protected]82739cf2008-09-16 00:37:56807
[email protected]96b667d2008-10-14 20:58:44808 gfx::Point point_in_child_coords(point);
[email protected]82739cf2008-09-16 00:37:56809 View::ConvertPointToView(this, child, &point_in_child_coords);
[email protected]613b8062008-10-14 23:45:09810 if (child->HitTest(point_in_child_coords))
[email protected]0d52b2302009-05-11 23:50:55811 return child->GetViewForPoint(point_in_child_coords);
initial.commit09911bf2008-07-26 23:55:29812 }
813 return this;
814}
815
[email protected]a0dde122008-11-21 20:51:20816Widget* View::GetWidget() const {
817 // The root view holds a reference to this view hierarchy's Widget.
818 return parent_ ? parent_->GetWidget() : NULL;
initial.commit09911bf2008-07-26 23:55:29819}
820
[email protected]cd8c47902009-04-30 20:55:35821Window* View::GetWindow() const {
822 Widget* widget = GetWidget();
823 return widget ? widget->GetWindow() : NULL;
824}
825
[email protected]2db27be2010-02-10 22:46:47826bool View::ContainsNativeView(gfx::NativeView native_view) const {
827 for (int i = 0, count = GetChildViewCount(); i < count; ++i) {
828 if (GetChildViewAt(i)->ContainsNativeView(native_view))
829 return true;
830 }
831 return false;
832}
833
initial.commit09911bf2008-07-26 23:55:29834// Get the containing RootView
835RootView* View::GetRootView() {
[email protected]a0dde122008-11-21 20:51:20836 Widget* widget = GetWidget();
837 return widget ? widget->GetRootView() : NULL;
initial.commit09911bf2008-07-26 23:55:29838}
839
840View* View::GetViewByID(int id) const {
841 if (id == id_)
842 return const_cast<View*>(this);
843
[email protected]09fe9492009-11-07 02:23:06844 for (int i = 0, count = GetChildViewCount(); i < count; ++i) {
initial.commit09911bf2008-07-26 23:55:29845 View* child = GetChildViewAt(i);
846 View* view = child->GetViewByID(id);
847 if (view)
848 return view;
849 }
850 return NULL;
851}
852
853void View::GetViewsWithGroup(int group_id, std::vector<View*>* out) {
854 if (group_ == group_id)
855 out->push_back(this);
856
[email protected]09fe9492009-11-07 02:23:06857 for (int i = 0, count = GetChildViewCount(); i < count; ++i)
initial.commit09911bf2008-07-26 23:55:29858 GetChildViewAt(i)->GetViewsWithGroup(group_id, out);
859}
860
861View* View::GetSelectedViewForGroup(int group_id) {
862 std::vector<View*> views;
863 GetRootView()->GetViewsWithGroup(group_id, &views);
864 if (views.size() > 0)
865 return views[0];
866 else
867 return NULL;
868}
869
870void View::SetID(int id) {
871 id_ = id;
872}
873
874int View::GetID() const {
875 return id_;
876}
877
878void View::SetGroup(int gid) {
[email protected]96f960d2009-09-14 18:45:30879 // Don't change the group id once it's set.
880 DCHECK(group_ == -1 || group_ == gid);
initial.commit09911bf2008-07-26 23:55:29881 group_ = gid;
882}
883
884int View::GetGroup() const {
885 return group_;
886}
887
888void View::SetParent(View* parent) {
[email protected]09fe9492009-11-07 02:23:06889 if (parent != parent_)
initial.commit09911bf2008-07-26 23:55:29890 parent_ = parent;
initial.commit09911bf2008-07-26 23:55:29891}
892
893bool View::IsParentOf(View* v) const {
894 DCHECK(v);
895 View* parent = v->GetParent();
896 while (parent) {
897 if (this == parent)
898 return true;
899 parent = parent->GetParent();
900 }
901 return false;
902}
903
[email protected]5e26d9d42010-05-13 22:11:03904int View::GetChildIndex(const View* v) const {
[email protected]09fe9492009-11-07 02:23:06905 for (int i = 0, count = GetChildViewCount(); i < count; i++) {
initial.commit09911bf2008-07-26 23:55:29906 if (v == GetChildViewAt(i))
907 return i;
908 }
909 return -1;
910}
911
912///////////////////////////////////////////////////////////////////////////////
913//
914// View - focus
915//
916///////////////////////////////////////////////////////////////////////////////
917
918View* View::GetNextFocusableView() {
919 return next_focusable_view_;
920}
921
922View* View::GetPreviousFocusableView() {
923 return previous_focusable_view_;
924}
925
926void View::SetNextFocusableView(View* view) {
927 view->previous_focusable_view_ = this;
928 next_focusable_view_ = view;
929}
930
931void View::InitFocusSiblings(View* v, int index) {
932 int child_count = static_cast<int>(child_views_.size());
933
934 if (child_count == 0) {
935 v->next_focusable_view_ = NULL;
936 v->previous_focusable_view_ = NULL;
937 } else {
938 if (index == child_count) {
939 // We are inserting at the end, but the end of the child list may not be
940 // the last focusable element. Let's try to find an element with no next
941 // focusable element to link to.
942 View* last_focusable_view = NULL;
943 for (std::vector<View*>::iterator iter = child_views_.begin();
944 iter != child_views_.end(); ++iter) {
945 if (!(*iter)->next_focusable_view_) {
946 last_focusable_view = *iter;
947 break;
948 }
949 }
950 if (last_focusable_view == NULL) {
951 // Hum... there is a cycle in the focus list. Let's just insert ourself
952 // after the last child.
953 View* prev = child_views_[index - 1];
954 v->previous_focusable_view_ = prev;
955 v->next_focusable_view_ = prev->next_focusable_view_;
956 prev->next_focusable_view_->previous_focusable_view_ = v;
957 prev->next_focusable_view_ = v;
958 } else {
959 last_focusable_view->next_focusable_view_ = v;
960 v->next_focusable_view_ = NULL;
961 v->previous_focusable_view_ = last_focusable_view;
962 }
963 } else {
964 View* prev = child_views_[index]->GetPreviousFocusableView();
965 v->previous_focusable_view_ = prev;
966 v->next_focusable_view_ = child_views_[index];
967 if (prev)
968 prev->next_focusable_view_ = v;
969 child_views_[index]->previous_focusable_view_ = v;
970 }
971 }
972}
973
974#ifndef NDEBUG
975void View::PrintViewHierarchy() {
976 PrintViewHierarchyImp(0);
977}
978
979void View::PrintViewHierarchyImp(int indent) {
980 std::wostringstream buf;
981 int ind = indent;
982 while (ind-- > 0)
983 buf << L' ';
984 buf << UTF8ToWide(GetClassName());
985 buf << L' ';
986 buf << GetID();
987 buf << L' ';
[email protected]80f8b9f2008-10-16 18:17:47988 buf << bounds_.x() << L"," << bounds_.y() << L",";
989 buf << bounds_.right() << L"," << bounds_.bottom();
initial.commit09911bf2008-07-26 23:55:29990 buf << L' ';
991 buf << this;
992
[email protected]b4d13c62010-10-20 00:11:40993 VLOG(1) << buf.str();
initial.commit09911bf2008-07-26 23:55:29994 std::cout << buf.str() << std::endl;
995
[email protected]09fe9492009-11-07 02:23:06996 for (int i = 0, count = GetChildViewCount(); i < count; ++i)
initial.commit09911bf2008-07-26 23:55:29997 GetChildViewAt(i)->PrintViewHierarchyImp(indent + 2);
initial.commit09911bf2008-07-26 23:55:29998}
999
1000
1001void View::PrintFocusHierarchy() {
1002 PrintFocusHierarchyImp(0);
1003}
1004
1005void View::PrintFocusHierarchyImp(int indent) {
1006 std::wostringstream buf;
1007 int ind = indent;
1008 while (ind-- > 0)
1009 buf << L' ';
1010 buf << UTF8ToWide(GetClassName());
1011 buf << L' ';
1012 buf << GetID();
1013 buf << L' ';
1014 buf << GetClassName().c_str();
1015 buf << L' ';
1016 buf << this;
1017
[email protected]b4d13c62010-10-20 00:11:401018 VLOG(1) << buf.str();
initial.commit09911bf2008-07-26 23:55:291019 std::cout << buf.str() << std::endl;
1020
1021 if (GetChildViewCount() > 0)
1022 GetChildViewAt(0)->PrintFocusHierarchyImp(indent + 2);
1023
1024 View* v = GetNextFocusableView();
1025 if (v)
1026 v->PrintFocusHierarchyImp(indent);
1027}
1028#endif
1029
1030////////////////////////////////////////////////////////////////////////////////
1031//
1032// View - accelerators
1033//
1034////////////////////////////////////////////////////////////////////////////////
1035
1036void View::AddAccelerator(const Accelerator& accelerator) {
1037 if (!accelerators_.get())
1038 accelerators_.reset(new std::vector<Accelerator>());
[email protected]71421c3f2009-06-06 00:41:441039
1040 std::vector<Accelerator>::iterator iter =
1041 std::find(accelerators_->begin(), accelerators_->end(), accelerator);
1042 DCHECK(iter == accelerators_->end())
1043 << "Registering the same accelerator multiple times";
1044
initial.commit09911bf2008-07-26 23:55:291045 accelerators_->push_back(accelerator);
[email protected]71421c3f2009-06-06 00:41:441046 RegisterPendingAccelerators();
initial.commit09911bf2008-07-26 23:55:291047}
1048
[email protected]e8e0f362008-11-08 01:13:251049void View::RemoveAccelerator(const Accelerator& accelerator) {
1050 std::vector<Accelerator>::iterator iter;
1051 if (!accelerators_.get() ||
1052 ((iter = std::find(accelerators_->begin(), accelerators_->end(),
1053 accelerator)) == accelerators_->end())) {
1054 NOTREACHED() << "Removing non-existing accelerator";
1055 return;
1056 }
1057
[email protected]4bd23f32009-06-08 20:59:191058 size_t index = iter - accelerators_->begin();
[email protected]e8e0f362008-11-08 01:13:251059 accelerators_->erase(iter);
[email protected]71421c3f2009-06-06 00:41:441060 if (index >= registered_accelerator_count_) {
1061 // The accelerator is not registered to FocusManager.
1062 return;
1063 }
1064 --registered_accelerator_count_;
1065
[email protected]e8e0f362008-11-08 01:13:251066 RootView* root_view = GetRootView();
1067 if (!root_view) {
1068 // We are not part of a view hierarchy, so there is nothing to do as we
1069 // removed ourselves from accelerators_, we won't be registered when added
1070 // to one.
1071 return;
1072 }
1073
[email protected]bda9556c2010-01-07 00:55:161074 // If accelerator_focus_manager_ is NULL then we did not registered
1075 // accelerators so there is nothing to unregister.
1076 if (accelerator_focus_manager_) {
1077 accelerator_focus_manager_->UnregisterAccelerator(accelerator, this);
[email protected]e8e0f362008-11-08 01:13:251078 }
1079}
1080
initial.commit09911bf2008-07-26 23:55:291081void View::ResetAccelerators() {
[email protected]71421c3f2009-06-06 00:41:441082 if (accelerators_.get())
[email protected]bda9556c2010-01-07 00:55:161083 UnregisterAccelerators(false);
initial.commit09911bf2008-07-26 23:55:291084}
1085
[email protected]71421c3f2009-06-06 00:41:441086void View::RegisterPendingAccelerators() {
1087 if (!accelerators_.get() ||
1088 registered_accelerator_count_ == accelerators_->size()) {
1089 // No accelerators are waiting for registration.
initial.commit09911bf2008-07-26 23:55:291090 return;
[email protected]71421c3f2009-06-06 00:41:441091 }
initial.commit09911bf2008-07-26 23:55:291092
1093 RootView* root_view = GetRootView();
1094 if (!root_view) {
1095 // We are not yet part of a view hierarchy, we'll register ourselves once
1096 // added to one.
1097 return;
1098 }
[email protected]f3735c5d2009-03-19 17:26:231099
[email protected]bda9556c2010-01-07 00:55:161100 accelerator_focus_manager_ = GetFocusManager();
1101 if (!accelerator_focus_manager_) {
initial.commit09911bf2008-07-26 23:55:291102 // Some crash reports seem to show that we may get cases where we have no
1103 // focus manager (see bug #1291225). This should never be the case, just
1104 // making sure we don't crash.
[email protected]f8dce002009-09-10 21:07:041105
1106 // TODO(jcampan): This fails for a view under WidgetGtk with TYPE_CHILD.
1107 // (see http://crbug.com/21335) reenable NOTREACHED assertion and
1108 // verify accelerators works as expected.
1109#if defined(OS_WIN)
initial.commit09911bf2008-07-26 23:55:291110 NOTREACHED();
[email protected]f8dce002009-09-10 21:07:041111#endif
initial.commit09911bf2008-07-26 23:55:291112 return;
1113 }
[email protected]71421c3f2009-06-06 00:41:441114 std::vector<Accelerator>::const_iterator iter;
1115 for (iter = accelerators_->begin() + registered_accelerator_count_;
initial.commit09911bf2008-07-26 23:55:291116 iter != accelerators_->end(); ++iter) {
[email protected]bda9556c2010-01-07 00:55:161117 accelerator_focus_manager_->RegisterAccelerator(*iter, this);
initial.commit09911bf2008-07-26 23:55:291118 }
[email protected]71421c3f2009-06-06 00:41:441119 registered_accelerator_count_ = accelerators_->size();
initial.commit09911bf2008-07-26 23:55:291120}
1121
[email protected]bda9556c2010-01-07 00:55:161122void View::UnregisterAccelerators(bool leave_data_intact) {
initial.commit09911bf2008-07-26 23:55:291123 if (!accelerators_.get())
1124 return;
1125
1126 RootView* root_view = GetRootView();
1127 if (root_view) {
[email protected]bda9556c2010-01-07 00:55:161128 if (accelerator_focus_manager_) {
initial.commit09911bf2008-07-26 23:55:291129 // We may not have a FocusManager if the window containing us is being
1130 // closed, in which case the FocusManager is being deleted so there is
1131 // nothing to unregister.
[email protected]bda9556c2010-01-07 00:55:161132 accelerator_focus_manager_->UnregisterAccelerators(this);
1133 accelerator_focus_manager_ = NULL;
initial.commit09911bf2008-07-26 23:55:291134 }
[email protected]bda9556c2010-01-07 00:55:161135 if (!leave_data_intact) {
1136 accelerators_->clear();
1137 accelerators_.reset();
1138 }
[email protected]71421c3f2009-06-06 00:41:441139 registered_accelerator_count_ = 0;
initial.commit09911bf2008-07-26 23:55:291140 }
1141}
1142
[email protected]e9adf0702010-03-08 23:34:071143int View::GetDragOperations(const gfx::Point& press_pt) {
1144 return drag_controller_ ?
1145 drag_controller_->GetDragOperations(this, press_pt) :
1146 DragDropTypes::DRAG_NONE;
initial.commit09911bf2008-07-26 23:55:291147}
1148
[email protected]e9adf0702010-03-08 23:34:071149void View::WriteDragData(const gfx::Point& press_pt, OSExchangeData* data) {
initial.commit09911bf2008-07-26 23:55:291150 DCHECK(drag_controller_);
[email protected]e9adf0702010-03-08 23:34:071151 drag_controller_->WriteDragData(this, press_pt, data);
initial.commit09911bf2008-07-26 23:55:291152}
1153
1154void View::OnDragDone() {
1155}
1156
1157bool View::InDrag() {
1158 RootView* root_view = GetRootView();
1159 return root_view ? (root_view->GetDragView() == this) : false;
1160}
1161
[email protected]d5c81012010-04-03 00:56:121162bool View::GetAccessibleName(std::wstring* name) {
1163 DCHECK(name);
1164
1165 if (accessible_name_.empty())
1166 return false;
1167 *name = accessible_name_;
1168 return true;
1169}
1170
[email protected]4c671e12010-09-28 19:30:231171AccessibilityTypes::Role View::GetAccessibleRole() {
1172 return AccessibilityTypes::ROLE_CLIENT;
[email protected]b82a0492010-05-27 23:00:031173}
1174
[email protected]d5c81012010-04-03 00:56:121175void View::SetAccessibleName(const std::wstring& name) {
1176 accessible_name_ = name;
1177}
1178
initial.commit09911bf2008-07-26 23:55:291179// static
[email protected]bb515ed2009-01-15 00:53:431180void View::ConvertPointToView(const View* src,
1181 const View* dst,
1182 gfx::Point* point) {
initial.commit09911bf2008-07-26 23:55:291183 ConvertPointToView(src, dst, point, true);
1184}
1185
1186// static
[email protected]bb515ed2009-01-15 00:53:431187void View::ConvertPointToView(const View* src,
1188 const View* dst,
1189 gfx::Point* point,
initial.commit09911bf2008-07-26 23:55:291190 bool try_other_direction) {
1191 // src can be NULL
1192 DCHECK(dst);
1193 DCHECK(point);
1194
[email protected]bb515ed2009-01-15 00:53:431195 const View* v;
initial.commit09911bf2008-07-26 23:55:291196 gfx::Point offset;
1197
1198 for (v = dst; v && v != src; v = v->GetParent()) {
1199 offset.SetPoint(offset.x() + v->GetX(APPLY_MIRRORING_TRANSFORMATION),
[email protected]6f3bb6c2008-09-17 22:25:331200 offset.y() + v->y());
initial.commit09911bf2008-07-26 23:55:291201 }
1202
1203 // The source was not found. The caller wants a conversion
1204 // from a view to a transitive parent.
1205 if (src && v == NULL && try_other_direction) {
1206 gfx::Point p;
1207 // note: try_other_direction is force to FALSE so we don't
1208 // end up in an infinite recursion should both src and dst
1209 // are not parented.
1210 ConvertPointToView(dst, src, &p, false);
1211 // since the src and dst are inverted, p should also be negated
1212 point->SetPoint(point->x() - p.x(), point->y() - p.y());
1213 } else {
1214 point->SetPoint(point->x() - offset.x(), point->y() - offset.y());
1215
1216 // If src is NULL, sp is in the screen coordinate system
1217 if (src == NULL) {
[email protected]a0dde122008-11-21 20:51:201218 Widget* widget = dst->GetWidget();
1219 if (widget) {
[email protected]3b680a82008-12-17 02:03:231220 gfx::Rect b;
[email protected]a0dde122008-11-21 20:51:201221 widget->GetBounds(&b, false);
[email protected]3b680a82008-12-17 02:03:231222 point->SetPoint(point->x() - b.x(), point->y() - b.y());
initial.commit09911bf2008-07-26 23:55:291223 }
1224 }
1225 }
1226}
1227
1228// static
[email protected]2fb6d462009-02-13 18:40:101229void View::ConvertPointToWidget(const View* src, gfx::Point* p) {
initial.commit09911bf2008-07-26 23:55:291230 DCHECK(src);
1231 DCHECK(p);
[email protected]96b667d2008-10-14 20:58:441232
[email protected]96b667d2008-10-14 20:58:441233 gfx::Point offset;
[email protected]2fb6d462009-02-13 18:40:101234 for (const View* v = src; v; v = v->GetParent()) {
[email protected]96b667d2008-10-14 20:58:441235 offset.set_x(offset.x() + v->GetX(APPLY_MIRRORING_TRANSFORMATION));
1236 offset.set_y(offset.y() + v->y());
initial.commit09911bf2008-07-26 23:55:291237 }
[email protected]96b667d2008-10-14 20:58:441238 p->SetPoint(p->x() + offset.x(), p->y() + offset.y());
initial.commit09911bf2008-07-26 23:55:291239}
1240
1241// static
[email protected]2fb6d462009-02-13 18:40:101242void View::ConvertPointFromWidget(const View* dest, gfx::Point* p) {
[email protected]96b667d2008-10-14 20:58:441243 gfx::Point t;
[email protected]2fb6d462009-02-13 18:40:101244 ConvertPointToWidget(dest, &t);
[email protected]96b667d2008-10-14 20:58:441245 p->SetPoint(p->x() - t.x(), p->y() - t.y());
initial.commit09911bf2008-07-26 23:55:291246}
1247
1248// static
[email protected]2fb6d462009-02-13 18:40:101249void View::ConvertPointToScreen(const View* src, gfx::Point* p) {
initial.commit09911bf2008-07-26 23:55:291250 DCHECK(src);
1251 DCHECK(p);
1252
[email protected]96b667d2008-10-14 20:58:441253 // If the view is not connected to a tree, there's nothing we can do.
[email protected]a0dde122008-11-21 20:51:201254 Widget* widget = src->GetWidget();
1255 if (widget) {
1256 ConvertPointToWidget(src, p);
[email protected]3b680a82008-12-17 02:03:231257 gfx::Rect r;
[email protected]a0dde122008-11-21 20:51:201258 widget->GetBounds(&r, false);
[email protected]3b680a82008-12-17 02:03:231259 p->SetPoint(p->x() + r.x(), p->y() + r.y());
initial.commit09911bf2008-07-26 23:55:291260 }
1261}
1262
[email protected]a0949a42010-08-23 16:03:051263gfx::Rect View::GetScreenBounds() const {
1264 gfx::Point origin;
1265 View::ConvertPointToScreen(this, &origin);
1266 return gfx::Rect(origin, size());
1267}
1268
initial.commit09911bf2008-07-26 23:55:291269/////////////////////////////////////////////////////////////////////////////
1270//
1271// View - event handlers
1272//
1273/////////////////////////////////////////////////////////////////////////////
1274
1275bool View::OnMousePressed(const MouseEvent& e) {
1276 return false;
1277}
1278
1279bool View::OnMouseDragged(const MouseEvent& e) {
1280 return false;
1281}
1282
1283void View::OnMouseReleased(const MouseEvent& e, bool canceled) {
1284}
1285
1286void View::OnMouseMoved(const MouseEvent& e) {
1287}
1288
1289void View::OnMouseEntered(const MouseEvent& e) {
1290}
1291
1292void View::OnMouseExited(const MouseEvent& e) {
1293}
1294
[email protected]ad84c8f2010-09-08 14:06:101295#if defined(TOUCH_UI)
1296bool View::OnTouchEvent(const TouchEvent& event) {
[email protected]b4d13c62010-10-20 00:11:401297 DVLOG(1) << "visited the OnTouchEvent";
[email protected]ad84c8f2010-09-08 14:06:101298 return false;
1299}
1300#endif
1301
initial.commit09911bf2008-07-26 23:55:291302void View::SetMouseHandler(View *new_mouse_handler) {
1303 // It is valid for new_mouse_handler to be NULL
[email protected]09fe9492009-11-07 02:23:061304 if (parent_)
initial.commit09911bf2008-07-26 23:55:291305 parent_->SetMouseHandler(new_mouse_handler);
initial.commit09911bf2008-07-26 23:55:291306}
1307
1308void View::SetVisible(bool flag) {
1309 if (flag != is_visible_) {
1310 // If the tab is currently visible, schedule paint to
1311 // refresh parent
[email protected]09fe9492009-11-07 02:23:061312 if (IsVisible())
initial.commit09911bf2008-07-26 23:55:291313 SchedulePaint();
initial.commit09911bf2008-07-26 23:55:291314
1315 is_visible_ = flag;
1316
1317 // This notifies all subviews recursively.
1318 PropagateVisibilityNotifications(this, flag);
1319
1320 // If we are newly visible, schedule paint.
[email protected]09fe9492009-11-07 02:23:061321 if (IsVisible())
initial.commit09911bf2008-07-26 23:55:291322 SchedulePaint();
initial.commit09911bf2008-07-26 23:55:291323 }
1324}
1325
1326bool View::IsVisibleInRootView() const {
1327 View* parent = GetParent();
1328 if (IsVisible() && parent)
1329 return parent->IsVisibleInRootView();
1330 else
1331 return false;
1332}
1333
initial.commit09911bf2008-07-26 23:55:291334/////////////////////////////////////////////////////////////////////////////
1335//
1336// View - keyboard and focus
1337//
1338/////////////////////////////////////////////////////////////////////////////
1339
1340void View::RequestFocus() {
1341 RootView* rv = GetRootView();
[email protected]59461d22010-07-21 15:41:091342 if (rv && IsFocusableInRootView())
initial.commit09911bf2008-07-26 23:55:291343 rv->FocusView(this);
initial.commit09911bf2008-07-26 23:55:291344}
1345
1346void View::WillGainFocus() {
1347}
1348
1349void View::DidGainFocus() {
1350}
1351
1352void View::WillLoseFocus() {
1353}
1354
1355bool View::OnKeyPressed(const KeyEvent& e) {
1356 return false;
1357}
1358
1359bool View::OnKeyReleased(const KeyEvent& e) {
1360 return false;
1361}
1362
1363bool View::OnMouseWheel(const MouseWheelEvent& e) {
1364 return false;
1365}
1366
1367void View::SetDragController(DragController* drag_controller) {
[email protected]09fe9492009-11-07 02:23:061368 drag_controller_ = drag_controller;
initial.commit09911bf2008-07-26 23:55:291369}
1370
1371DragController* View::GetDragController() {
1372 return drag_controller_;
1373}
1374
[email protected]134c47b92009-08-19 03:33:441375bool View::GetDropFormats(
1376 int* formats,
1377 std::set<OSExchangeData::CustomFormat>* custom_formats) {
1378 return false;
1379}
1380
1381bool View::AreDropTypesRequired() {
1382 return false;
1383}
1384
initial.commit09911bf2008-07-26 23:55:291385bool View::CanDrop(const OSExchangeData& data) {
[email protected]134c47b92009-08-19 03:33:441386 // TODO(sky): when I finish up migration, this should default to true.
initial.commit09911bf2008-07-26 23:55:291387 return false;
1388}
1389
1390void View::OnDragEntered(const DropTargetEvent& event) {
1391}
1392
1393int View::OnDragUpdated(const DropTargetEvent& event) {
1394 return DragDropTypes::DRAG_NONE;
1395}
1396
1397void View::OnDragExited() {
1398}
1399
1400int View::OnPerformDrop(const DropTargetEvent& event) {
1401 return DragDropTypes::DRAG_NONE;
1402}
1403
initial.commit09911bf2008-07-26 23:55:291404// static
1405bool View::ExceededDragThreshold(int delta_x, int delta_y) {
1406 return (abs(delta_x) > GetHorizontalDragThreshold() ||
1407 abs(delta_y) > GetVerticalDragThreshold());
1408}
1409
initial.commit09911bf2008-07-26 23:55:291410// Tooltips -----------------------------------------------------------------
[email protected]e9adf0702010-03-08 23:34:071411bool View::GetTooltipText(const gfx::Point& p, std::wstring* tooltip) {
initial.commit09911bf2008-07-26 23:55:291412 return false;
1413}
1414
[email protected]e9adf0702010-03-08 23:34:071415bool View::GetTooltipTextOrigin(const gfx::Point& p, gfx::Point* loc) {
initial.commit09911bf2008-07-26 23:55:291416 return false;
1417}
1418
1419void View::TooltipTextChanged() {
[email protected]a0dde122008-11-21 20:51:201420 Widget* widget = GetWidget();
1421 if (widget && widget->GetTooltipManager())
1422 widget->GetTooltipManager()->TooltipTextChanged(this);
initial.commit09911bf2008-07-26 23:55:291423}
1424
1425void View::UpdateTooltip() {
[email protected]a0dde122008-11-21 20:51:201426 Widget* widget = GetWidget();
1427 if (widget && widget->GetTooltipManager())
1428 widget->GetTooltipManager()->UpdateTooltip();
initial.commit09911bf2008-07-26 23:55:291429}
1430
initial.commit09911bf2008-07-26 23:55:291431std::string View::GetClassName() const {
1432 return kViewClassName;
1433}
1434
[email protected]5c2b98b2009-03-09 20:55:541435View* View::GetAncestorWithClassName(const std::string& name) {
1436 for (View* view = this; view; view = view->GetParent()) {
1437 if (view->GetClassName() == name)
1438 return view;
1439 }
1440 return NULL;
1441}
1442
initial.commit09911bf2008-07-26 23:55:291443gfx::Rect View::GetVisibleBounds() {
[email protected]b6296fd2009-02-13 17:34:161444 if (!IsVisibleInRootView())
1445 return gfx::Rect();
[email protected]6f3bb6c2008-09-17 22:25:331446 gfx::Rect vis_bounds(0, 0, width(), height());
initial.commit09911bf2008-07-26 23:55:291447 gfx::Rect ancestor_bounds;
1448 View* view = this;
1449 int root_x = 0;
1450 int root_y = 0;
initial.commit09911bf2008-07-26 23:55:291451 while (view != NULL && !vis_bounds.IsEmpty()) {
1452 root_x += view->GetX(APPLY_MIRRORING_TRANSFORMATION);
[email protected]6f3bb6c2008-09-17 22:25:331453 root_y += view->y();
1454 vis_bounds.Offset(view->GetX(APPLY_MIRRORING_TRANSFORMATION), view->y());
initial.commit09911bf2008-07-26 23:55:291455 View* ancestor = view->GetParent();
1456 if (ancestor != NULL) {
[email protected]6f3bb6c2008-09-17 22:25:331457 ancestor_bounds.SetRect(0, 0, ancestor->width(),
1458 ancestor->height());
initial.commit09911bf2008-07-26 23:55:291459 vis_bounds = vis_bounds.Intersect(ancestor_bounds);
[email protected]a0dde122008-11-21 20:51:201460 } else if (!view->GetWidget()) {
1461 // If the view has no Widget, we're not visible. Return an empty rect.
initial.commit09911bf2008-07-26 23:55:291462 return gfx::Rect();
1463 }
1464 view = ancestor;
1465 }
1466 if (vis_bounds.IsEmpty())
1467 return vis_bounds;
1468 // Convert back to this views coordinate system.
1469 vis_bounds.Offset(-root_x, -root_y);
1470 return vis_bounds;
1471}
1472
1473int View::GetPageScrollIncrement(ScrollView* scroll_view,
1474 bool is_horizontal, bool is_positive) {
1475 return 0;
1476}
1477
1478int View::GetLineScrollIncrement(ScrollView* scroll_view,
1479 bool is_horizontal, bool is_positive) {
1480 return 0;
1481}
1482
[email protected]45da6c72009-10-28 20:45:421483ThemeProvider* View::GetThemeProvider() const {
[email protected]4a190632009-05-09 01:07:421484 Widget* widget = GetWidget();
1485 return widget ? widget->GetThemeProvider() : NULL;
1486}
1487
initial.commit09911bf2008-07-26 23:55:291488// static
[email protected]9fc4f202010-07-07 15:38:191489void View::RegisterChildrenForVisibleBoundsNotification(
1490 RootView* root, View* view) {
initial.commit09911bf2008-07-26 23:55:291491 DCHECK(root && view);
1492 if (view->GetNotifyWhenVisibleBoundsInRootChanges())
1493 root->RegisterViewForVisibleBoundsNotification(view);
1494 for (int i = 0; i < view->GetChildViewCount(); ++i)
[email protected]9fc4f202010-07-07 15:38:191495 RegisterChildrenForVisibleBoundsNotification(root, view->GetChildViewAt(i));
initial.commit09911bf2008-07-26 23:55:291496}
1497
1498// static
[email protected]9fc4f202010-07-07 15:38:191499void View::UnregisterChildrenForVisibleBoundsNotification(
initial.commit09911bf2008-07-26 23:55:291500 RootView* root, View* view) {
1501 DCHECK(root && view);
1502 if (view->GetNotifyWhenVisibleBoundsInRootChanges())
1503 root->UnregisterViewForVisibleBoundsNotification(view);
1504 for (int i = 0; i < view->GetChildViewCount(); ++i)
[email protected]9fc4f202010-07-07 15:38:191505 UnregisterChildrenForVisibleBoundsNotification(root,
1506 view->GetChildViewAt(i));
initial.commit09911bf2008-07-26 23:55:291507}
1508
1509void View::AddDescendantToNotify(View* view) {
1510 DCHECK(view);
1511 if (!descendants_to_notify_.get())
1512 descendants_to_notify_.reset(new ViewList());
1513 descendants_to_notify_->push_back(view);
1514}
1515
1516void View::RemoveDescendantToNotify(View* view) {
1517 DCHECK(view && descendants_to_notify_.get());
1518 ViewList::iterator i = find(descendants_to_notify_->begin(),
1519 descendants_to_notify_->end(),
1520 view);
1521 DCHECK(i != descendants_to_notify_->end());
1522 descendants_to_notify_->erase(i);
1523 if (descendants_to_notify_->empty())
1524 descendants_to_notify_.reset();
1525}
1526
initial.commit09911bf2008-07-26 23:55:291527// DropInfo --------------------------------------------------------------------
1528
1529void View::DragInfo::Reset() {
1530 possible_drag = false;
[email protected]e9adf0702010-03-08 23:34:071531 start_pt = gfx::Point();
initial.commit09911bf2008-07-26 23:55:291532}
1533
[email protected]e9adf0702010-03-08 23:34:071534void View::DragInfo::PossibleDrag(const gfx::Point& p) {
initial.commit09911bf2008-07-26 23:55:291535 possible_drag = true;
[email protected]e9adf0702010-03-08 23:34:071536 start_pt = p;
initial.commit09911bf2008-07-26 23:55:291537}
1538
1539} // namespace