summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ui/base/touch/touch_editing_controller.cc12
-rw-r--r--ui/base/touch/touch_editing_controller.h41
-rw-r--r--ui/base/ui_base_switches.cc3
-rw-r--r--ui/base/ui_base_switches.h1
-rw-r--r--ui/views/controls/textfield/native_textfield_views.cc49
-rw-r--r--ui/views/controls/textfield/native_textfield_views.h5
-rw-r--r--ui/views/touchui/touch_editing_menu.cc150
-rw-r--r--ui/views/touchui/touch_editing_menu.h74
-rw-r--r--ui/views/touchui/touch_selection_controller_impl.cc371
-rw-r--r--ui/views/touchui/touch_selection_controller_impl.h40
-rw-r--r--ui/views/views.gyp5
-rw-r--r--ui/views/views_delegate.cc16
-rw-r--r--ui/views/views_delegate.h2
13 files changed, 285 insertions, 484 deletions
diff --git a/ui/base/touch/touch_editing_controller.cc b/ui/base/touch/touch_editing_controller.cc
index 1b84ed9..8afb740 100644
--- a/ui/base/touch/touch_editing_controller.cc
+++ b/ui/base/touch/touch_editing_controller.cc
@@ -6,21 +6,9 @@
namespace ui {
-namespace {
-TouchSelectionControllerFactory* g_shared_instance = NULL;
-} // namespace
-
TouchSelectionController* TouchSelectionController::create(
TouchEditable* client_view) {
- if (g_shared_instance)
- return g_shared_instance->create(client_view);
return NULL;
}
-// static
-void TouchSelectionControllerFactory::SetInstance(
- TouchSelectionControllerFactory* instance) {
- g_shared_instance = instance;
-}
-
} // namespace ui
diff --git a/ui/base/touch/touch_editing_controller.h b/ui/base/touch/touch_editing_controller.h
index e7985ce..999c2ad 100644
--- a/ui/base/touch/touch_editing_controller.h
+++ b/ui/base/touch/touch_editing_controller.h
@@ -20,17 +20,6 @@ class UI_EXPORT TouchEditable : public ui::SimpleMenuModel::Delegate {
// end of selection. Visually, |start| may lie after |end|.
virtual void SelectRect(const gfx::Point& start, const gfx::Point& end) = 0;
- // Gets the end points of the current selection. The end points p1 and p2 must
- // be the cursor rect for the start and end of selection:
- // ____________________________________
- // | textfield with |selected text| |
- // ------------------------------------
- // ^p1 ^p2
- //
- // p1 should be the logical start and p2 the logical end of selection. Hence,
- // visually, p1 could be to the right of p2 in the figure above.
- virtual void GetSelectionEndPoints(gfx::Rect* p1, gfx::Rect* p2) = 0;
-
// Gets the bounds of the client view in parent's coordinates.
virtual const gfx::Rect& GetBounds() = 0;
@@ -41,13 +30,6 @@ class UI_EXPORT TouchEditable : public ui::SimpleMenuModel::Delegate {
virtual void ConvertPointToScreen(gfx::Point* point) = 0;
virtual void ConvertPointFromScreen(gfx::Point* point) = 0;
- // Returns true if the editable draws its own handles (hence, the
- // TouchSelectionController need not draw handles).
- virtual bool DrawsHandles() = 0;
-
- // Tells the editable to open context menu.
- virtual void OpenContextMenu(const gfx::Point anchor) = 0;
-
protected:
virtual ~TouchEditable() {}
};
@@ -62,18 +44,19 @@ class UI_EXPORT TouchSelectionController {
static TouchSelectionController* create(
TouchEditable* client_view);
- // Notifies the controller that the selection has changed.
- virtual void SelectionChanged() = 0;
-};
-
-class UI_EXPORT TouchSelectionControllerFactory {
- public:
- static void SetInstance(TouchSelectionControllerFactory* instance);
-
- virtual TouchSelectionController* create(TouchEditable* client_view) = 0;
+ // Notification that the text selection in TouchEditable has
+ // changed. p1 and p2 are lower corners of the start and end of selection:
+ // ____________________________________
+ // | textfield with |selected text| |
+ // ------------------------------------
+ // ^p1 ^p2
+ //
+ // p1 is always the start and p2 is always the end of selection. Hence,
+ // p1 could be to the right of p2 in the figure above.
+ virtual void SelectionChanged(const gfx::Point& p1, const gfx::Point& p2) = 0;
- protected:
- virtual ~TouchSelectionControllerFactory() {}
+ // Notification that the TouchEditable has lost focus.
+ virtual void ClientViewLostFocus() = 0;
};
} // namespace views
diff --git a/ui/base/ui_base_switches.cc b/ui/base/ui_base_switches.cc
index b4fdabf..e647ac3 100644
--- a/ui/base/ui_base_switches.cc
+++ b/ui/base/ui_base_switches.cc
@@ -20,9 +20,6 @@ const char kEnableNewDialogStyle[] = "enable-new-dialog-style";
const char kEnableTouchDragDrop[] = "enable-touch-drag-drop";
-// Enables controls that support touch base text editing.
-const char kEnableTouchEditing[] = "enable-touch-editing";
-
// Enables the Views textfield on Windows.
const char kEnableViewsTextfield[] = "enable-views-textfield";
diff --git a/ui/base/ui_base_switches.h b/ui/base/ui_base_switches.h
index b21e2b1..14bdebc 100644
--- a/ui/base/ui_base_switches.h
+++ b/ui/base/ui_base_switches.h
@@ -17,7 +17,6 @@ UI_EXPORT extern const char kDisableTouchAdjustment[];
UI_EXPORT extern const char kEnableBezelTouch[];
UI_EXPORT extern const char kEnableNewDialogStyle[];
UI_EXPORT extern const char kEnableTouchDragDrop[];
-UI_EXPORT extern const char kEnableTouchEditing[];
UI_EXPORT extern const char kEnableViewsTextfield[];
UI_EXPORT extern const char kForceDeviceScaleFactor[];
UI_EXPORT extern const char kHighlightMissingScaledResources[];
diff --git a/ui/views/controls/textfield/native_textfield_views.cc b/ui/views/controls/textfield/native_textfield_views.cc
index 16b908f..d9c4348 100644
--- a/ui/views/controls/textfield/native_textfield_views.cc
+++ b/ui/views/controls/textfield/native_textfield_views.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 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.
@@ -69,7 +69,8 @@ NativeTextfieldViews::NativeTextfieldViews(Textfield* parent)
initiating_drag_(false),
ALLOW_THIS_IN_INITIALIZER_LIST(cursor_timer_(this)),
aggregated_clicks_(0),
- touch_selection_controller_(NULL) {
+ ALLOW_THIS_IN_INITIALIZER_LIST(touch_selection_controller_(
+ ui::TouchSelectionController::create(this))) {
set_border(text_border_);
#if defined(OS_CHROMEOS)
@@ -103,7 +104,6 @@ bool NativeTextfieldViews::OnMousePressed(const ui::MouseEvent& event) {
}
OnAfterUserAction();
- touch_selection_controller_.reset();
return true;
}
@@ -169,12 +169,6 @@ void NativeTextfieldViews::OnGestureEvent(ui::GestureEvent* event) {
OnAfterUserAction();
event->SetHandled();
return;
- case ui::ET_GESTURE_TAP:
- touch_selection_controller_.reset(
- ui::TouchSelectionController::create(this));
- if (touch_selection_controller_.get())
- touch_selection_controller_->SelectionChanged();
- break;
default:
break;
}
@@ -317,16 +311,6 @@ void NativeTextfieldViews::SelectRect(const gfx::Point& start,
OnAfterUserAction();
}
-void NativeTextfieldViews::GetSelectionEndPoints(gfx::Rect* p1,
- gfx::Rect* p2) {
- gfx::RenderText* render_text = GetRenderText();
- const gfx::SelectionModel& sel = render_text->selection_model();
- gfx::SelectionModel start_sel =
- render_text->GetSelectionModelForSelectionStart();
- *p1 = render_text->GetCursorBounds(start_sel, true);
- *p2 = render_text->GetCursorBounds(sel, true);
-}
-
const gfx::Rect& NativeTextfieldViews::GetBounds() {
return bounds();
}
@@ -343,15 +327,6 @@ void NativeTextfieldViews::ConvertPointFromScreen(gfx::Point* point) {
View::ConvertPointFromScreen(this, point);
}
-bool NativeTextfieldViews::DrawsHandles() {
- return false;
-}
-
-void NativeTextfieldViews::OpenContextMenu(const gfx::Point anchor) {
- touch_selection_controller_.reset();
- ShowContextMenu(anchor, false);
-}
-
gfx::NativeCursor NativeTextfieldViews::GetCursor(const ui::MouseEvent& event) {
bool in_selection = GetRenderText()->IsPointInSelection(event.location());
bool drag_event = event.type() == ui::ET_MOUSE_DRAGGED;
@@ -600,7 +575,6 @@ bool NativeTextfieldViews::HandleKeyPressed(const ui::KeyEvent& e) {
bool handled = false;
if (controller)
handled = controller->HandleKeyEvent(textfield_, e);
- touch_selection_controller_.reset();
return handled || HandleKeyEvent(e);
}
@@ -630,7 +604,8 @@ void NativeTextfieldViews::HandleBlur() {
RepaintCursor();
}
- touch_selection_controller_.reset();
+ if (touch_selection_controller_.get())
+ touch_selection_controller_->ClientViewLostFocus();
ClearSelection();
}
@@ -699,7 +674,6 @@ string16 NativeTextfieldViews::GetLabelForCommandId(int command_id) const {
}
void NativeTextfieldViews::ExecuteCommand(int command_id) {
- touch_selection_controller_.reset();
if (!IsCommandIdEnabled(command_id))
return;
@@ -1215,8 +1189,17 @@ void NativeTextfieldViews::OnCaretBoundsChanged() {
textfield_->GetInputMethod()->OnCaretBoundsChanged(textfield_);
// Notify selection controller
- if (touch_selection_controller_.get())
- touch_selection_controller_->SelectionChanged();
+ if (!touch_selection_controller_.get())
+ return;
+ gfx::RenderText* render_text = GetRenderText();
+ const gfx::SelectionModel& sel = render_text->selection_model();
+ gfx::SelectionModel start_sel =
+ render_text->GetSelectionModelForSelectionStart();
+ gfx::Rect start_cursor = render_text->GetCursorBounds(start_sel, true);
+ gfx::Rect end_cursor = render_text->GetCursorBounds(sel, true);
+ gfx::Point start(start_cursor.x(), start_cursor.bottom() - 1);
+ gfx::Point end(end_cursor.x(), end_cursor.bottom() - 1);
+ touch_selection_controller_->SelectionChanged(start, end);
}
void NativeTextfieldViews::OnBeforeUserAction() {
diff --git a/ui/views/controls/textfield/native_textfield_views.h b/ui/views/controls/textfield/native_textfield_views.h
index 70aa16e..166d9bb 100644
--- a/ui/views/controls/textfield/native_textfield_views.h
+++ b/ui/views/controls/textfield/native_textfield_views.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 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.
@@ -80,13 +80,10 @@ class VIEWS_EXPORT NativeTextfieldViews : public View,
// ui::TouchEditable overrides:
virtual void SelectRect(const gfx::Point& start,
const gfx::Point& end) OVERRIDE;
- virtual void GetSelectionEndPoints(gfx::Rect* p1, gfx::Rect* p2) OVERRIDE;
virtual const gfx::Rect& GetBounds() OVERRIDE;
virtual gfx::NativeView GetNativeView() OVERRIDE;
virtual void ConvertPointToScreen(gfx::Point* point) OVERRIDE;
virtual void ConvertPointFromScreen(gfx::Point* point) OVERRIDE;
- virtual bool DrawsHandles() OVERRIDE;
- virtual void OpenContextMenu(const gfx::Point anchor) OVERRIDE;
// ContextMenuController overrides:
virtual void ShowContextMenuForView(View* source,
diff --git a/ui/views/touchui/touch_editing_menu.cc b/ui/views/touchui/touch_editing_menu.cc
deleted file mode 100644
index ed1dae9..0000000
--- a/ui/views/touchui/touch_editing_menu.cc
+++ /dev/null
@@ -1,150 +0,0 @@
-// Copyright (c) 2013 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 "ui/views/touchui/touch_editing_menu.h"
-
-#include "base/utf_string_conversions.h"
-#include "grit/ui_strings.h"
-#include "ui/base/l10n/l10n_util.h"
-#include "ui/base/resource/resource_bundle.h"
-#include "ui/gfx/canvas.h"
-#include "ui/gfx/insets.h"
-#include "ui/gfx/text_utils.h"
-#include "ui/views/bubble/bubble_border.h"
-#include "ui/views/bubble/bubble_frame_view.h"
-#include "ui/views/controls/button/custom_button.h"
-#include "ui/views/controls/button/label_button.h"
-#include "ui/views/layout/box_layout.h"
-#include "ui/views/widget/widget.h"
-
-namespace {
-
-const int kMenuCommands[] = {IDS_APP_CUT,
- IDS_APP_COPY,
- IDS_APP_PASTE,
- IDS_APP_DELETE,
- IDS_APP_SELECT_ALL};
-const int kSpacingBetweenButtons = 0;
-const int kButtonSeparatorColor = SkColorSetARGB(13, 0, 0, 0);
-const int kMenuButtonBorderThickness = 5;
-const SkColor kMenuButtonColorNormal = SkColorSetARGB(102, 255, 255, 255);
-const SkColor kMenuButtonColorHover = SkColorSetARGB(13, 0, 0, 0);
-
-const char* kEllipsesButtonText = "...";
-const int kEllipsesButtonTag = -1;
-} // namespace
-
-namespace views {
-
-class TouchEditingMenuButtonBackground : public Background {
- public:
- TouchEditingMenuButtonBackground() {}
-
- virtual void Paint(gfx::Canvas* canvas, View* view) const OVERRIDE {
- CustomButton::ButtonState state = static_cast<CustomButton*>(view)->state();
- SkColor background_color = (state == CustomButton::STATE_NORMAL)?
- kMenuButtonColorNormal : kMenuButtonColorHover;
- int w = view->width();
- int h = view->height();
- canvas->FillRect(gfx::Rect(1, 0, w, h), background_color);
- }
-
- private:
- DISALLOW_COPY_AND_ASSIGN(TouchEditingMenuButtonBackground);
-};
-
-TouchEditingMenuView::TouchEditingMenuView(
- TouchEditingMenuController* controller,
- gfx::Point anchor_point,
- gfx::NativeView context)
- : BubbleDelegateView(NULL, views::BubbleBorder::BOTTOM_CENTER),
- controller_(controller) {
- set_anchor_point(anchor_point);
- set_shadow(views::BubbleBorder::SMALL_SHADOW);
- set_parent_window(context);
- set_margins(gfx::Insets());
- set_use_focusless(true);
- set_adjust_if_offscreen(true);
-
- SetLayoutManager(new BoxLayout(BoxLayout::kHorizontal, 0, 0,
- kSpacingBetweenButtons));
- CreateButtons();
- views::BubbleDelegateView::CreateBubble(this);
- GetBubbleFrameView()->set_background(NULL);
- Show();
-}
-
-TouchEditingMenuView::~TouchEditingMenuView() {
-}
-
-void TouchEditingMenuView::Close() {
- if (GetWidget()) {
- controller_ = NULL;
- GetWidget()->Close();
- }
-}
-
-void TouchEditingMenuView::WindowClosing() {
- views::BubbleDelegateView::WindowClosing();
- if (controller_)
- controller_->OnMenuClosed(this);
-}
-
-void TouchEditingMenuView::ButtonPressed(Button* sender,
- const ui::Event& event) {
- if (controller_) {
- if (sender->tag() != kEllipsesButtonTag)
- controller_->ExecuteCommand(sender->tag());
- else
- controller_->OpenContextMenu();
- }
-}
-
-void TouchEditingMenuView::OnPaint(gfx::Canvas* canvas) {
- BubbleDelegateView::OnPaint(canvas);
-
- // Draw separator bars.
- int x = 0;
- for (int i = 0; i < child_count() - 1; ++i) {
- View* child = child_at(i);
- x += child->width();
- canvas->FillRect(gfx::Rect(x, 0, 1, child->height()),
- kButtonSeparatorColor);
- }
-}
-
-void TouchEditingMenuView::CreateButtons() {
- RemoveAllChildViews(true);
- for (size_t i = 0; i < arraysize(kMenuCommands); i++) {
- int command_id = kMenuCommands[i];
- if (controller_ && controller_->IsCommandIdEnabled(command_id)) {
- Button* button = CreateButton(l10n_util::GetStringUTF16(command_id),
- command_id);
- AddChildView(button);
- }
- }
-
- // Finally, add ellipses button.
- AddChildView(CreateButton(
- UTF8ToUTF16(kEllipsesButtonText), kEllipsesButtonTag));
- Layout();
-}
-
-Button* TouchEditingMenuView::CreateButton(const string16& title, int tag) {
- LabelButton* button = new LabelButton(this, gfx::RemoveAcceleratorChar(
- title, '&', NULL, NULL));
- button->set_focusable(true);
- button->set_request_focus_on_press(false);
- button->set_background(new TouchEditingMenuButtonBackground);
- button->set_border(Border::CreateEmptyBorder(kMenuButtonBorderThickness,
- kMenuButtonBorderThickness,
- kMenuButtonBorderThickness,
- kMenuButtonBorderThickness));
- button->SetFont(ui::ResourceBundle::GetSharedInstance().GetFont(
- ui::ResourceBundle::SmallFont));
- button->set_tag(tag);
- return button;
-}
-
-} // namespace views
diff --git a/ui/views/touchui/touch_editing_menu.h b/ui/views/touchui/touch_editing_menu.h
deleted file mode 100644
index 86d4892..0000000
--- a/ui/views/touchui/touch_editing_menu.h
+++ /dev/null
@@ -1,74 +0,0 @@
-// Copyright (c) 2013 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 UI_VIEWS_TOUCHUI_TOUCH_EDITING_MENU_H_
-#define UI_VIEWS_TOUCHUI_TOUCH_EDITING_MENU_H_
-
-#include "ui/gfx/point.h"
-#include "ui/views/bubble/bubble_delegate.h"
-#include "ui/views/controls/button/button.h"
-#include "ui/views/views_export.h"
-
-namespace gfx {
-class Canvas;
-}
-
-namespace views {
-class TouchEditingMenuView;
-class Widget;
-
-class VIEWS_EXPORT TouchEditingMenuController {
- public:
- // Checks if the specified menu command is supported.
- virtual bool IsCommandIdEnabled(int command_id) const = 0;
-
- // Send a context menu command to the controller.
- virtual void ExecuteCommand(int command_id) = 0;
-
- // Tell the controller that user has selected the context menu button.
- virtual void OpenContextMenu() = 0;
-
- // Called when the menu is closed.
- virtual void OnMenuClosed(TouchEditingMenuView* menu) = 0;
-
- protected:
- virtual ~TouchEditingMenuController() {}
-};
-
-// A View that displays the touch context menu.
-class VIEWS_EXPORT TouchEditingMenuView : public BubbleDelegateView,
- public ButtonListener {
- public:
- TouchEditingMenuView(TouchEditingMenuController* controller,
- gfx::Point anchor_point,
- gfx::NativeView context);
- virtual ~TouchEditingMenuView();
-
- void Close();
-
- private:
- // views::WidgetDelegate overrides:
- void WindowClosing() OVERRIDE;
-
- // Overridden from ButtonListener.
- void ButtonPressed(Button* sender, const ui::Event& event) OVERRIDE;
-
- // Overridden from BubbleDelegateView.
- void OnPaint(gfx::Canvas* canvas) OVERRIDE;
-
- // Queries the |controller_| for what elements to show in the menu and sizes
- // the menu appropriately.
- void CreateButtons();
-
- // Helper method to create a single button.
- Button* CreateButton(const string16& title, int tag);
-
- TouchEditingMenuController* controller_;
-
- DISALLOW_COPY_AND_ASSIGN(TouchEditingMenuView);
-};
-
-} // namespace views
-
-#endif // UI_VIEWS_TOUCHUI_TOUCH_SELECTION_CONTROLLER_IMPL_H_
diff --git a/ui/views/touchui/touch_selection_controller_impl.cc b/ui/views/touchui/touch_selection_controller_impl.cc
index a0ca742..5956373 100644
--- a/ui/views/touchui/touch_selection_controller_impl.cc
+++ b/ui/views/touchui/touch_selection_controller_impl.cc
@@ -1,32 +1,52 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 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 "ui/views/touchui/touch_selection_controller_impl.h"
-#include "base/command_line.h"
#include "base/time.h"
+#include "base/utf_string_conversions.h"
#include "grit/ui_strings.h"
-#include "ui/base/ui_base_switches.h"
+#include "third_party/skia/include/effects/SkGradientShader.h"
+#include "ui/base/l10n/l10n_util.h"
+#include "ui/base/resource/resource_bundle.h"
#include "ui/gfx/canvas.h"
#include "ui/gfx/rect.h"
#include "ui/gfx/screen.h"
#include "ui/gfx/size.h"
+#include "ui/gfx/text_utils.h"
+#include "ui/gfx/transform.h"
+#include "ui/views/background.h"
+#include "ui/views/controls/button/button.h"
+#include "ui/views/controls/button/custom_button.h"
+#include "ui/views/controls/button/text_button.h"
+#include "ui/views/controls/label.h"
+#include "ui/views/controls/menu/menu_config.h"
+#include "ui/views/layout/box_layout.h"
#include "ui/views/widget/widget.h"
namespace {
// Constants defining the visual attributes of selection handles
const int kSelectionHandleRadius = 10;
+const int kSelectionHandleCursorHeight = 10;
const int kSelectionHandleAlpha = 0x7F;
const SkColor kSelectionHandleColor =
- SkColorSetA(SK_ColorBLACK, kSelectionHandleAlpha);
+ SkColorSetA(SK_ColorBLUE, kSelectionHandleAlpha);
// The minimum selection size to trigger selection controller.
const int kMinSelectionSize = 4;
+const int kContextMenuCommands[] = {IDS_APP_CUT,
+ IDS_APP_COPY,
+// TODO(varunjain): PASTE is acting funny due to some gtk clipboard issue.
+// Uncomment the following when that is fixed.
+// IDS_APP_PASTE,
+ IDS_APP_DELETE,
+ IDS_APP_SELECT_ALL};
+const int kContextMenuPadding = 2;
const int kContextMenuTimoutMs = 1000;
-const int kContextMenuVerticalOffset = 5;
+const int kContextMenuVerticalOffset = 25;
// Convenience struct to represent a circle shape.
struct Circle {
@@ -36,13 +56,12 @@ struct Circle {
};
// Creates a widget to host SelectionHandleView.
-views::Widget* CreateTouchSelectionPopupWidget(gfx::NativeView context) {
+views::Widget* CreateTouchSelectionPopupWidget() {
views::Widget* widget = new views::Widget;
views::Widget::InitParams params(views::Widget::InitParams::TYPE_POPUP);
params.can_activate = false;
params.transparent = true;
params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
- params.context = context;
widget->Init(params);
return widget;
}
@@ -71,11 +90,9 @@ namespace views {
// A View that displays the text selection handle.
class TouchSelectionControllerImpl::SelectionHandleView : public View {
public:
- explicit SelectionHandleView(TouchSelectionControllerImpl* controller,
- gfx::NativeView context)
- : controller_(controller),
- cursor_height_(0) {
- widget_.reset(CreateTouchSelectionPopupWidget(context));
+ explicit SelectionHandleView(TouchSelectionControllerImpl* controller)
+ : controller_(controller) {
+ widget_.reset(CreateTouchSelectionPopupWidget());
widget_->SetContentsView(this);
widget_->SetAlwaysOnTop(true);
@@ -88,30 +105,30 @@ class TouchSelectionControllerImpl::SelectionHandleView : public View {
virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE {
Circle circle = {kSelectionHandleRadius, gfx::Point(kSelectionHandleRadius,
- kSelectionHandleRadius + cursor_height_),
+ kSelectionHandleRadius + kSelectionHandleCursorHeight),
kSelectionHandleColor};
PaintCircle(circle, canvas);
canvas->DrawLine(gfx::Point(kSelectionHandleRadius, 0),
- gfx::Point(kSelectionHandleRadius, cursor_height_),
+ gfx::Point(kSelectionHandleRadius, kSelectionHandleCursorHeight),
kSelectionHandleColor);
}
- virtual void OnGestureEvent(ui::GestureEvent* event) OVERRIDE {
- event->SetHandled();
- switch (event->type()) {
- case ui::ET_GESTURE_SCROLL_BEGIN:
- controller_->dragging_handle_ = this;
- break;
- case ui::ET_GESTURE_SCROLL_UPDATE:
- controller_->SelectionHandleDragged(event->location());
- break;
- case ui::ET_GESTURE_SCROLL_END:
- case ui::ET_GESTURE_END:
- controller_->dragging_handle_ = NULL;
- break;
- default:
- break;
- }
+ virtual bool OnMousePressed(const ui::MouseEvent& event) OVERRIDE {
+ controller_->dragging_handle_ = this;
+ return true;
+ }
+
+ virtual bool OnMouseDragged(const ui::MouseEvent& event) OVERRIDE {
+ controller_->SelectionHandleDragged(event.location());
+ return true;
+ }
+
+ virtual void OnMouseReleased(const ui::MouseEvent& event) OVERRIDE {
+ controller_->dragging_handle_ = NULL;
+ }
+
+ virtual void OnMouseCaptureLost() OVERRIDE {
+ controller_->dragging_handle_ = NULL;
}
virtual void SetVisible(bool visible) OVERRIDE {
@@ -127,18 +144,13 @@ class TouchSelectionControllerImpl::SelectionHandleView : public View {
virtual gfx::Size GetPreferredSize() OVERRIDE {
return gfx::Size(2 * kSelectionHandleRadius,
- 2 * kSelectionHandleRadius + cursor_height_);
- }
-
- bool IsWidgetVisible() const {
- return widget_->IsVisible();
+ 2 * kSelectionHandleRadius + kSelectionHandleCursorHeight);
}
- void SetSelectionRectInScreen(const gfx::Rect& rect) {
- cursor_height_ = rect.height();
- gfx::Rect widget_bounds(rect.x() - kSelectionHandleRadius, rect.y(),
+ void SetScreenPosition(const gfx::Point& position) {
+ gfx::Rect widget_bounds(position.x() - kSelectionHandleRadius, position.y(),
2 * kSelectionHandleRadius,
- 2 * kSelectionHandleRadius + cursor_height_);
+ 2 * kSelectionHandleRadius + kSelectionHandleCursorHeight);
widget_->SetBounds(widget_bounds);
}
@@ -149,65 +161,194 @@ class TouchSelectionControllerImpl::SelectionHandleView : public View {
private:
scoped_ptr<Widget> widget_;
TouchSelectionControllerImpl* controller_;
- int cursor_height_;
DISALLOW_COPY_AND_ASSIGN(SelectionHandleView);
};
+class ContextMenuButtonBackground : public Background {
+ public:
+ ContextMenuButtonBackground() {}
+
+ virtual void Paint(gfx::Canvas* canvas, View* view) const OVERRIDE {
+ CustomButton::ButtonState state = static_cast<CustomButton*>(view)->state();
+ SkColor background_color, border_color;
+ if (state == CustomButton::STATE_NORMAL) {
+ background_color = SkColorSetARGB(102, 255, 255, 255);
+ border_color = SkColorSetARGB(36, 0, 0, 0);
+ } else {
+ background_color = SkColorSetARGB(13, 0, 0, 0);
+ border_color = SkColorSetARGB(72, 0, 0, 0);
+ }
+ int w = view->width();
+ int h = view->height();
+ canvas->FillRect(gfx::Rect(1, 1, w - 2, h - 2), background_color);
+ canvas->FillRect(gfx::Rect(2, 0, w - 4, 1), border_color);
+ canvas->FillRect(gfx::Rect(1, 1, 1, 1), border_color);
+ canvas->FillRect(gfx::Rect(0, 2, 1, h - 4), border_color);
+ canvas->FillRect(gfx::Rect(1, h - 2, 1, 1), border_color);
+ canvas->FillRect(gfx::Rect(2, h - 1, w - 4, 1), border_color);
+ canvas->FillRect(gfx::Rect(w - 2, 1, 1, 1), border_color);
+ canvas->FillRect(gfx::Rect(w - 1, 2, 1, h - 4), border_color);
+ canvas->FillRect(gfx::Rect(w - 2, h - 2, 1, 1), border_color);
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(ContextMenuButtonBackground);
+};
+
+// A View that displays the touch context menu.
+class TouchSelectionControllerImpl::TouchContextMenuView
+ : public ButtonListener,
+ public View {
+ public:
+ explicit TouchContextMenuView(TouchSelectionControllerImpl* controller)
+ : controller_(controller) {
+ widget_.reset(CreateTouchSelectionPopupWidget());
+ widget_->SetContentsView(this);
+ widget_->SetAlwaysOnTop(true);
+
+ // We are owned by the TouchSelectionController.
+ set_owned_by_client();
+ SetLayoutManager(new BoxLayout(BoxLayout::kHorizontal, kContextMenuPadding,
+ kContextMenuPadding, kContextMenuPadding));
+ }
+
+ virtual ~TouchContextMenuView() {
+ }
+
+ virtual void SetVisible(bool visible) OVERRIDE {
+ // We simply show/hide the container widget.
+ if (visible != widget_->IsVisible()) {
+ if (visible)
+ widget_->Show();
+ else
+ widget_->Hide();
+ }
+ View::SetVisible(visible);
+ }
+
+ void SetScreenPosition(const gfx::Point& position) {
+ RefreshButtonsAndSetWidgetPosition(position);
+ }
+
+ gfx::Point GetScreenPosition() {
+ return widget_->GetClientAreaBoundsInScreen().origin();
+ }
+
+ void OnPaintBackground(gfx::Canvas* canvas) OVERRIDE {
+ // TODO(varunjain): the following color scheme is copied from
+ // menu_scroll_view_container.cc. Figure out how to consolidate the two
+ // pieces of code.
+#if defined(OS_CHROMEOS)
+ static const SkColor kGradientColors[2] = {
+ SK_ColorWHITE,
+ SkColorSetRGB(0xF0, 0xF0, 0xF0)
+ };
+
+ static const SkScalar kGradientPoints[2] = {
+ SkIntToScalar(0),
+ SkIntToScalar(1)
+ };
+
+ SkPoint points[2];
+ points[0].iset(0, 0);
+ points[1].iset(0, height());
+
+ skia::RefPtr<SkShader> shader = skia::AdoptRef(
+ SkGradientShader::CreateLinear(
+ points, kGradientColors, kGradientPoints,
+ arraysize(kGradientPoints),
+ SkShader::kRepeat_TileMode));
+ DCHECK(shader);
+
+ SkPaint paint;
+ paint.setShader(shader.get());
+
+ paint.setStyle(SkPaint::kFill_Style);
+ paint.setXfermodeMode(SkXfermode::kSrc_Mode);
+
+ canvas->DrawRect(GetLocalBounds(), paint);
+#else
+ canvas->DrawColor(SkColorSetRGB(210, 225, 246),
+ SkXfermode::kSrc_Mode);
+#endif
+ }
+
+ // Overridden from ButtonListener:
+ virtual void ButtonPressed(Button* sender, const ui::Event& event) OVERRIDE {
+ controller_->ExecuteCommand(sender->tag());
+ }
+
+ private:
+ // Queries the client view for what elements to show in the menu and sizes
+ // the menu appropriately.
+ void RefreshButtonsAndSetWidgetPosition(const gfx::Point& position) {
+ RemoveAllChildViews(true);
+ int total_width = 0;
+ int height = 0;
+ for (size_t i = 0; i < arraysize(kContextMenuCommands); i++) {
+ int command_id = kContextMenuCommands[i];
+ if (controller_->IsCommandIdEnabled(command_id)) {
+ TextButton* button = new TextButton(this, gfx::RemoveAcceleratorChar(
+ l10n_util::GetStringUTF16(command_id), '&', NULL, NULL));
+ button->set_focusable(true);
+ button->set_request_focus_on_press(false);
+ button->SetEnabledColor(MenuConfig::instance().text_color);
+ button->set_background(new ContextMenuButtonBackground());
+ button->set_alignment(TextButton::ALIGN_CENTER);
+ button->SetFont(ui::ResourceBundle::GetSharedInstance().GetFont(
+ ui::ResourceBundle::LargeFont));
+ button->set_tag(command_id);
+ AddChildView(button);
+ gfx::Size button_size = button->GetPreferredSize();
+ total_width += button_size.width() + kContextMenuPadding;
+ if (height < button_size.height())
+ height = button_size.height();
+ }
+ }
+ gfx::Rect widget_bounds(position.x() - total_width / 2,
+ position.y() - height,
+ total_width,
+ height);
+ gfx::Rect monitor_bounds = gfx::Screen::GetNativeScreen()->
+ GetDisplayNearestPoint(position).bounds();
+ widget_->SetBounds(widget_bounds.AdjustToFit(monitor_bounds));
+ Layout();
+ }
+
+ scoped_ptr<Widget> widget_;
+ TouchSelectionControllerImpl* controller_;
+
+ DISALLOW_COPY_AND_ASSIGN(TouchContextMenuView);
+};
+
TouchSelectionControllerImpl::TouchSelectionControllerImpl(
ui::TouchEditable* client_view)
: client_view_(client_view),
- client_widget_(NULL),
- selection_handle_1_(new SelectionHandleView(this,
- client_view->GetNativeView())),
- selection_handle_2_(new SelectionHandleView(this,
- client_view->GetNativeView())),
- context_menu_(NULL),
+ selection_handle_1_(new SelectionHandleView(this)),
+ selection_handle_2_(new SelectionHandleView(this)),
+ context_menu_(new TouchContextMenuView(this)),
dragging_handle_(NULL) {
- client_widget_ = Widget::GetWidgetForNativeView(
- client_view_->GetNativeView());
- client_widget_->AddObserver(this);
}
TouchSelectionControllerImpl::~TouchSelectionControllerImpl() {
- HideContextMenu();
- if (client_widget_)
- client_widget_->RemoveObserver(this);
}
-void TouchSelectionControllerImpl::SelectionChanged() {
- gfx::Rect r1, r2;
- client_view_->GetSelectionEndPoints(&r1, &r2);
- gfx::Point screen_pos_1(r1.origin());
+void TouchSelectionControllerImpl::SelectionChanged(const gfx::Point& p1,
+ const gfx::Point& p2) {
+ gfx::Point screen_pos_1(p1);
client_view_->ConvertPointToScreen(&screen_pos_1);
- gfx::Point screen_pos_2(r2.origin());
+ gfx::Point screen_pos_2(p2);
client_view_->ConvertPointToScreen(&screen_pos_2);
- gfx::Rect screen_rect_1(screen_pos_1, r1.size());
- gfx::Rect screen_rect_2(screen_pos_2, r2.size());
- if (client_view_->DrawsHandles()) {
- UpdateContextMenu(r1.origin(), r2.origin());
- return;
- }
if (dragging_handle_) {
// We need to reposition only the selection handle that is being dragged.
// The other handle stays the same. Also, the selection handle being dragged
// will always be at the end of selection, while the other handle will be at
// the start.
- dragging_handle_->SetSelectionRectInScreen(screen_rect_2);
-
- // The non-dragging-handle might have recently become visible.
- SelectionHandleView* non_dragging_handle =
- dragging_handle_ == selection_handle_1_.get()?
- selection_handle_2_.get() : selection_handle_1_.get();
- if (client_view_->GetBounds().Contains(r1.origin())) {
- non_dragging_handle->SetSelectionRectInScreen(screen_rect_1);
- non_dragging_handle->SetVisible(true);
- } else {
- non_dragging_handle->SetVisible(false);
- }
+ dragging_handle_->SetScreenPosition(screen_pos_2);
} else {
- UpdateContextMenu(r1.origin(), r2.origin());
+ UpdateContextMenu(p1, p2);
// Check if there is any selection at all.
if (IsEmptySelection(screen_pos_2, screen_pos_1)) {
@@ -216,15 +357,15 @@ void TouchSelectionControllerImpl::SelectionChanged() {
return;
}
- if (client_view_->GetBounds().Contains(r1.origin())) {
- selection_handle_1_->SetSelectionRectInScreen(screen_rect_1);
+ if (client_view_->GetBounds().Contains(p1)) {
+ selection_handle_1_->SetScreenPosition(screen_pos_1);
selection_handle_1_->SetVisible(true);
} else {
selection_handle_1_->SetVisible(false);
}
- if (client_view_->GetBounds().Contains(r2.origin())) {
- selection_handle_2_->SetSelectionRectInScreen(screen_rect_2);
+ if (client_view_->GetBounds().Contains(p2)) {
+ selection_handle_2_->SetScreenPosition(screen_pos_2);
selection_handle_2_->SetVisible(true);
} else {
selection_handle_2_->SetVisible(false);
@@ -232,6 +373,12 @@ void TouchSelectionControllerImpl::SelectionChanged() {
}
}
+void TouchSelectionControllerImpl::ClientViewLostFocus() {
+ selection_handle_1_->SetVisible(false);
+ selection_handle_2_->SetVisible(false);
+ HideContextMenu();
+}
+
void TouchSelectionControllerImpl::SelectionHandleDragged(
const gfx::Point& drag_pos) {
// We do not want to show the context menu while dragging.
@@ -276,44 +423,21 @@ void TouchSelectionControllerImpl::ExecuteCommand(int command_id) {
client_view_->ExecuteCommand(command_id);
}
-void TouchSelectionControllerImpl::OpenContextMenu() {
- gfx::Point anchor = context_menu_->anchor_point();
- HideContextMenu();
- client_view_->OpenContextMenu(anchor);
-}
-
-void TouchSelectionControllerImpl::OnMenuClosed(TouchEditingMenuView* menu) {
- if (menu == context_menu_)
- context_menu_ = NULL;
-}
-
-void TouchSelectionControllerImpl::OnWidgetClosing(Widget* widget) {
- DCHECK_EQ(client_widget_, widget);
- client_widget_ = NULL;
-}
-
-void TouchSelectionControllerImpl::OnWidgetBoundsChanged(
- Widget* widget,
- const gfx::Rect& new_bounds) {
- DCHECK_EQ(client_widget_, widget);
- HideContextMenu();
- SelectionChanged();
-}
-
void TouchSelectionControllerImpl::ContextMenuTimerFired() {
// Get selection end points in client_view's space.
- gfx::Rect r1, r2;
- client_view_->GetSelectionEndPoints(&r1, &r2);
+ gfx::Point p1(kSelectionHandleRadius, 0);
+ ConvertPointToClientView(selection_handle_1_.get(), &p1);
+ gfx::Point p2(kSelectionHandleRadius, 0);
+ ConvertPointToClientView(selection_handle_2_.get(), &p2);
// if selection is completely inside the view, we display the context menu
// in the middle of the end points on the top. Else, we show the menu on the
// top border of the view in the center.
gfx::Point menu_pos;
gfx::Rect client_bounds = client_view_->GetBounds();
- if (client_bounds.Contains(r1.origin()) &&
- client_bounds.Contains(r2.origin())) {
- menu_pos.set_x((r1.origin().x() + r2.origin().x()) / 2);
- menu_pos.set_y(std::min(r1.y(), r2.y()) - kContextMenuVerticalOffset);
+ if (client_bounds.Contains(p1) && client_bounds.Contains(p2)) {
+ menu_pos.set_x((p1.x() + p2.x()) / 2);
+ menu_pos.set_y(std::min(p1.y(), p2.y()) - kContextMenuVerticalOffset);
} else {
menu_pos.set_x(client_bounds.x() + client_bounds.width() / 2);
menu_pos.set_y(client_bounds.y());
@@ -321,9 +445,8 @@ void TouchSelectionControllerImpl::ContextMenuTimerFired() {
client_view_->ConvertPointToScreen(&menu_pos);
- DCHECK(!context_menu_);
- context_menu_ = new TouchEditingMenuView(this, menu_pos,
- client_view_->GetNativeView());
+ context_menu_->SetScreenPosition(menu_pos);
+ context_menu_->SetVisible(true);
}
void TouchSelectionControllerImpl::UpdateContextMenu(const gfx::Point& p1,
@@ -342,9 +465,7 @@ void TouchSelectionControllerImpl::UpdateContextMenu(const gfx::Point& p1,
}
void TouchSelectionControllerImpl::HideContextMenu() {
- if (context_menu_)
- context_menu_->Close();
- context_menu_ = NULL;
+ context_menu_->SetVisible(false);
context_menu_timer_.Stop();
}
@@ -364,17 +485,13 @@ bool TouchSelectionControllerImpl::IsSelectionHandle2Visible() {
return selection_handle_2_->visible();
}
-ViewsTouchSelectionControllerFactory::ViewsTouchSelectionControllerFactory() {
-}
+} // namespace views
-ui::TouchSelectionController* ViewsTouchSelectionControllerFactory::create(
- ui::TouchEditable* client_view) {
-#if defined(OS_CHROMEOS)
- if (CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableTouchEditing))
- return new views::TouchSelectionControllerImpl(client_view);
-#endif
- return NULL;
+namespace ui {
+
+TouchSelectionController* TouchSelectionController::create(
+ TouchEditable* client_view) {
+ return new views::TouchSelectionControllerImpl(client_view);
}
-} // namespace views
+} // namespace ui
diff --git a/ui/views/touchui/touch_selection_controller_impl.h b/ui/views/touchui/touch_selection_controller_impl.h
index 04579fe..5d042e7 100644
--- a/ui/views/touchui/touch_selection_controller_impl.h
+++ b/ui/views/touchui/touch_selection_controller_impl.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -8,7 +8,6 @@
#include "base/timer.h"
#include "ui/base/touch/touch_editing_controller.h"
#include "ui/gfx/point.h"
-#include "ui/views/touchui/touch_editing_menu.h"
#include "ui/views/view.h"
#include "ui/views/views_export.h"
@@ -17,9 +16,7 @@ namespace views {
// Touch specific implementation of TouchSelectionController. Responsible for
// displaying selection handles and menu elements relevant in a touch interface.
class VIEWS_EXPORT TouchSelectionControllerImpl
- : public ui::TouchSelectionController,
- public TouchEditingMenuController,
- public WidgetObserver {
+ : public ui::TouchSelectionController {
public:
// Use TextSelectionController::create().
explicit TouchSelectionControllerImpl(
@@ -28,11 +25,15 @@ class VIEWS_EXPORT TouchSelectionControllerImpl
virtual ~TouchSelectionControllerImpl();
// TextSelectionController.
- virtual void SelectionChanged() OVERRIDE;
+ virtual void SelectionChanged(const gfx::Point& p1,
+ const gfx::Point& p2) OVERRIDE;
+
+ virtual void ClientViewLostFocus() OVERRIDE;
private:
friend class TouchSelectionControllerImplTest;
class SelectionHandleView;
+ class TouchContextMenuView;
// Callback to inform the client view that the selection handle has been
// dragged, hence selection may need to be updated.
@@ -42,18 +43,11 @@ class VIEWS_EXPORT TouchSelectionControllerImpl
// system to that of the client view.
void ConvertPointToClientView(SelectionHandleView* source, gfx::Point* point);
- // Overridden from TouchEditingMenuController.
- bool IsCommandIdEnabled(int command_id) const OVERRIDE;
- void ExecuteCommand(int command_id) OVERRIDE;
- void OpenContextMenu() OVERRIDE;
- void OnMenuClosed(TouchEditingMenuView* menu) OVERRIDE;
+ // Checks if the client view supports a context menu command.
+ bool IsCommandIdEnabled(int command_id) const;
- // Overridden from WidgetObserver. We will observe the widget backing the
- // |client_view_| so that when its moved/resized, we can update the selection
- // handles appropriately.
- void OnWidgetClosing(Widget* widget) OVERRIDE;
- void OnWidgetBoundsChanged(Widget* widget,
- const gfx::Rect& new_bounds) OVERRIDE;
+ // Sends a context menu command to the client view.
+ void ExecuteCommand(int command_id);
// Time to show context menu.
void ContextMenuTimerFired();
@@ -71,10 +65,9 @@ class VIEWS_EXPORT TouchSelectionControllerImpl
bool IsSelectionHandle2Visible();
ui::TouchEditable* client_view_;
- Widget* client_widget_;
scoped_ptr<SelectionHandleView> selection_handle_1_;
scoped_ptr<SelectionHandleView> selection_handle_2_;
- TouchEditingMenuView* context_menu_;
+ scoped_ptr<TouchContextMenuView> context_menu_;
// Timer to trigger |context_menu| (|context_menu| is not shown if the
// selection handles are being updated. It appears only when the handles are
@@ -87,15 +80,6 @@ class VIEWS_EXPORT TouchSelectionControllerImpl
DISALLOW_COPY_AND_ASSIGN(TouchSelectionControllerImpl);
};
-class VIEWS_EXPORT ViewsTouchSelectionControllerFactory
- : public ui::TouchSelectionControllerFactory {
- public:
- ViewsTouchSelectionControllerFactory();
-
- // Overridden from ui::TouchSelectionControllerFactory.
- ui::TouchSelectionController* create(ui::TouchEditable* client_view) OVERRIDE;
-};
-
} // namespace views
#endif // UI_UI_VIEWS_TOUCHUI_TOUCH_SELECTION_CONTROLLER_IMPL_H_
diff --git a/ui/views/views.gyp b/ui/views/views.gyp
index f74b094..abd8943 100644
--- a/ui/views/views.gyp
+++ b/ui/views/views.gyp
@@ -309,10 +309,6 @@
'repeat_controller.h',
'round_rect_painter.cc',
'round_rect_painter.h',
- 'touchui/touch_editing_menu.cc',
- 'touchui/touch_editing_menu.h',
- 'touchui/touch_selection_controller_impl.cc',
- 'touchui/touch_selection_controller_impl.h',
'view.cc',
'view.h',
'view_constants.cc',
@@ -325,7 +321,6 @@
'view_text_utils.cc',
'view_text_utils.h',
'view_win.cc',
- 'views_delegate.cc',
'views_delegate.h',
'widget/aero_tooltip_manager.cc',
'widget/aero_tooltip_manager.h',
diff --git a/ui/views/views_delegate.cc b/ui/views/views_delegate.cc
deleted file mode 100644
index cf51e24..0000000
--- a/ui/views/views_delegate.cc
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright (c) 2013 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 "ui/views/views_delegate.h"
-
-#include "ui/views/touchui/touch_selection_controller_impl.h"
-
-namespace views {
-
-ViewsDelegate::ViewsDelegate() {
- ui::TouchSelectionControllerFactory::SetInstance(
- new views::ViewsTouchSelectionControllerFactory);
-}
-
-} // namespace views
diff --git a/ui/views/views_delegate.h b/ui/views/views_delegate.h
index b569da9..105bab0 100644
--- a/ui/views/views_delegate.h
+++ b/ui/views/views_delegate.h
@@ -49,8 +49,6 @@ class VIEWS_EXPORT ViewsDelegate {
// The active ViewsDelegate used by the views system.
static ViewsDelegate* views_delegate;
- ViewsDelegate();
-
virtual ~ViewsDelegate() {}
// Saves the position, size and "show" state for the window with the