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

Side by Side Diff: chrome/browser/ui/gtk/tabs/tab_gtk.cc

Issue 6933037: Multi-tab selection for Linux. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fixing clang errors Created 9 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « chrome/browser/ui/gtk/tabs/tab_gtk.h ('k') | chrome/browser/ui/gtk/tabs/tab_renderer_gtk.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/ui/gtk/tabs/tab_gtk.h" 5 #include "chrome/browser/ui/gtk/tabs/tab_gtk.h"
6 6
7 #include <gdk/gdkkeysyms.h> 7 #include <gdk/gdkkeysyms.h>
8 8
9 #include "base/memory/singleton.h" 9 #include "base/memory/singleton.h"
10 #include "base/utf_string_conversions.h" 10 #include "base/utf_string_conversions.h"
11 #include "chrome/app/chrome_command_ids.h" 11 #include "chrome/app/chrome_command_ids.h"
12 #include "chrome/browser/ui/gtk/accelerators_gtk.h" 12 #include "chrome/browser/ui/gtk/accelerators_gtk.h"
13 #include "chrome/browser/ui/gtk/menu_gtk.h" 13 #include "chrome/browser/ui/gtk/menu_gtk.h"
14 #include "chrome/browser/ui/gtk/tabs/tab_strip_menu_controller.h"
14 #include "chrome/browser/ui/tabs/tab_menu_model.h" 15 #include "chrome/browser/ui/tabs/tab_menu_model.h"
15 #include "grit/generated_resources.h" 16 #include "grit/generated_resources.h"
16 #include "grit/theme_resources.h" 17 #include "grit/theme_resources.h"
17 #include "ui/base/dragdrop/gtk_dnd_util.h" 18 #include "ui/base/dragdrop/gtk_dnd_util.h"
18 #include "ui/base/models/accelerator_gtk.h" 19 #include "ui/base/models/accelerator_gtk.h"
19 #include "ui/gfx/path.h" 20 #include "ui/gfx/path.h"
20 21
21 namespace { 22 namespace {
22 23
23 // Returns the width of the title for the current font, in pixels. 24 // Returns the width of the title for the current font, in pixels.
24 int GetTitleWidth(gfx::Font* font, string16 title) { 25 int GetTitleWidth(gfx::Font* font, string16 title) {
25 DCHECK(font); 26 DCHECK(font);
26 if (title.empty()) 27 if (title.empty())
27 return 0; 28 return 0;
28 29
29 return font->GetStringWidth(title); 30 return font->GetStringWidth(title);
30 } 31 }
31 32
32 } // namespace 33 } // namespace
33 34
34 class TabGtk::ContextMenuController : public ui::SimpleMenuModel::Delegate,
35 public MenuGtk::Delegate {
36 public:
37 explicit ContextMenuController(TabGtk* tab)
38 : tab_(tab),
39 model_(this, tab->delegate()->IsTabPinned(tab)) {
40 menu_.reset(new MenuGtk(this, &model_));
41 }
42
43 virtual ~ContextMenuController() {}
44
45 void RunMenu(const gfx::Point& point, guint32 event_time) {
46 menu_->PopupAsContext(point, event_time);
47 }
48
49 void Cancel() {
50 tab_ = NULL;
51 menu_->Cancel();
52 }
53
54 private:
55 // Overridden from ui::SimpleMenuModel::Delegate:
56 virtual bool IsCommandIdChecked(int command_id) const {
57 return false;
58 }
59 virtual bool IsCommandIdEnabled(int command_id) const {
60 return tab_ && tab_->delegate()->IsCommandEnabledForTab(
61 static_cast<TabStripModel::ContextMenuCommand>(command_id),
62 tab_);
63 }
64 virtual bool GetAcceleratorForCommandId(
65 int command_id,
66 ui::Accelerator* accelerator) {
67 int browser_command;
68 if (!TabStripModel::ContextMenuCommandToBrowserCommand(command_id,
69 &browser_command))
70 return false;
71 const ui::AcceleratorGtk* accelerator_gtk =
72 AcceleratorsGtk::GetInstance()->GetPrimaryAcceleratorForCommand(
73 browser_command);
74 if (accelerator_gtk)
75 *accelerator = *accelerator_gtk;
76 return !!accelerator_gtk;
77 }
78
79 virtual void ExecuteCommand(int command_id) {
80 if (!tab_)
81 return;
82 tab_->delegate()->ExecuteCommandForTab(
83 static_cast<TabStripModel::ContextMenuCommand>(command_id), tab_);
84 }
85
86 GtkWidget* GetImageForCommandId(int command_id) const {
87 int browser_cmd_id;
88 return TabStripModel::ContextMenuCommandToBrowserCommand(command_id,
89 &browser_cmd_id) ?
90 MenuGtk::Delegate::GetDefaultImageForCommandId(browser_cmd_id) :
91 NULL;
92 }
93
94 // The context menu.
95 scoped_ptr<MenuGtk> menu_;
96
97 // The Tab the context menu was brought up for. Set to NULL when the menu
98 // is canceled.
99 TabGtk* tab_;
100
101 // The model.
102 TabMenuModel model_;
103
104 DISALLOW_COPY_AND_ASSIGN(ContextMenuController);
105 };
106
107 class TabGtk::TabGtkObserverHelper { 35 class TabGtk::TabGtkObserverHelper {
108 public: 36 public:
109 explicit TabGtkObserverHelper(TabGtk* tab) 37 explicit TabGtkObserverHelper(TabGtk* tab)
110 : tab_(tab) { 38 : tab_(tab) {
111 MessageLoopForUI::current()->AddObserver(tab_); 39 MessageLoopForUI::current()->AddObserver(tab_);
112 } 40 }
113 41
114 ~TabGtkObserverHelper() { 42 ~TabGtkObserverHelper() {
115 MessageLoopForUI::current()->RemoveObserver(tab_); 43 MessageLoopForUI::current()->RemoveObserver(tab_);
116 } 44 }
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
169 } 97 }
170 } 98 }
171 99
172 gboolean TabGtk::OnButtonPressEvent(GtkWidget* widget, GdkEventButton* event) { 100 gboolean TabGtk::OnButtonPressEvent(GtkWidget* widget, GdkEventButton* event) {
173 // Every button press ensures either a button-release-event or a drag-fail 101 // Every button press ensures either a button-release-event or a drag-fail
174 // signal for |widget|. 102 // signal for |widget|.
175 if (event->button == 1 && event->type == GDK_BUTTON_PRESS) { 103 if (event->button == 1 && event->type == GDK_BUTTON_PRESS) {
176 // Store whether or not we were selected just now... we only want to be 104 // Store whether or not we were selected just now... we only want to be
177 // able to drag foreground tabs, so we don't start dragging the tab if 105 // able to drag foreground tabs, so we don't start dragging the tab if
178 // it was in the background. 106 // it was in the background.
179 bool just_selected = !IsSelected(); 107 if (!IsActive()) {
180 if (just_selected) { 108 if (event->state & GDK_CONTROL_MASK)
181 delegate_->SelectTab(this); 109 delegate_->ToggleTabSelection(this);
110 else if (event->state & GDK_SHIFT_MASK)
111 delegate_->ExtendTabSelection(this);
112 else
113 delegate_->ActivateTab(this);
182 } 114 }
183
184 // Hook into the message loop to handle dragging. 115 // Hook into the message loop to handle dragging.
185 observer_.reset(new TabGtkObserverHelper(this)); 116 observer_.reset(new TabGtkObserverHelper(this));
186 117
187 // Store the button press event, used to initiate a drag. 118 // Store the button press event, used to initiate a drag.
188 last_mouse_down_ = gdk_event_copy(reinterpret_cast<GdkEvent*>(event)); 119 last_mouse_down_ = gdk_event_copy(reinterpret_cast<GdkEvent*>(event));
189 } else if (event->button == 3) { 120 } else if (event->button == 3) {
190 // Only show the context menu if the left mouse button isn't down (i.e., 121 // Only show the context menu if the left mouse button isn't down (i.e.,
191 // the user might want to drag instead). 122 // the user might want to drag instead).
192 if (!last_mouse_down_) { 123 if (!last_mouse_down_) {
193 menu_controller_.reset(new ContextMenuController(this)); 124 menu_controller_.reset(delegate()->GetTabStripMenuControllerForTab(this));
194 menu_controller_->RunMenu(gfx::Point(event->x_root, event->y_root), 125 menu_controller_->RunMenu(gfx::Point(event->x_root, event->y_root),
195 event->time); 126 event->time);
196 } 127 }
197 } 128 }
198 129
199 return TRUE; 130 return TRUE;
200 } 131 }
201 132
202 gboolean TabGtk::OnButtonReleaseEvent(GtkWidget* widget, 133 gboolean TabGtk::OnButtonReleaseEvent(GtkWidget* widget,
203 GdkEventButton* event) { 134 GdkEventButton* event) {
204 if (event->button == 1) { 135 if (event->button == 1) {
136 if (IsActive() && !(event->state & (GDK_SHIFT_MASK | GDK_CONTROL_MASK))) {
137 delegate_->ActivateTab(this);
138 }
205 observer_.reset(); 139 observer_.reset();
206 140
207 if (last_mouse_down_) { 141 if (last_mouse_down_) {
208 gdk_event_free(last_mouse_down_); 142 gdk_event_free(last_mouse_down_);
209 last_mouse_down_ = NULL; 143 last_mouse_down_ = NULL;
210 } 144 }
211 } 145 }
212 146
213 // Middle mouse up means close the tab, but only if the mouse is over it 147 // Middle mouse up means close the tab, but only if the mouse is over it
214 // (like a button). 148 // (like a button).
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
286 static_cast<gint>(new_x), static_cast<gint>(new_y))) { 220 static_cast<gint>(new_x), static_cast<gint>(new_y))) {
287 StartDragging(gfx::Point( 221 StartDragging(gfx::Point(
288 static_cast<int>(last_mouse_down_->button.x), 222 static_cast<int>(last_mouse_down_->button.x),
289 static_cast<int>(last_mouse_down_->button.y))); 223 static_cast<int>(last_mouse_down_->button.y)));
290 } 224 }
291 } 225 }
292 226
293 /////////////////////////////////////////////////////////////////////////////// 227 ///////////////////////////////////////////////////////////////////////////////
294 // TabGtk, TabRendererGtk overrides: 228 // TabGtk, TabRendererGtk overrides:
295 229
230 bool TabGtk::IsActive() const {
231 return delegate_->IsTabActive(this);
232 }
233
296 bool TabGtk::IsSelected() const { 234 bool TabGtk::IsSelected() const {
297 return delegate_->IsTabSelected(this); 235 return delegate_->IsTabSelected(this);
298 } 236 }
299 237
300 bool TabGtk::IsVisible() const { 238 bool TabGtk::IsVisible() const {
301 return GTK_WIDGET_FLAGS(event_box_) & GTK_VISIBLE; 239 return GTK_WIDGET_FLAGS(event_box_) & GTK_VISIBLE;
302 } 240 }
303 241
304 void TabGtk::SetVisible(bool visible) const { 242 void TabGtk::SetVisible(bool visible) const {
305 if (visible) { 243 if (visible) {
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
387 gdk_event_free(last_mouse_down_); 325 gdk_event_free(last_mouse_down_);
388 last_mouse_down_ = NULL; 326 last_mouse_down_ = NULL;
389 } 327 }
390 328
391 // Notify the drag helper that we're done with any potential drag operations. 329 // Notify the drag helper that we're done with any potential drag operations.
392 // Clean up the drag helper, which is re-created on the next mouse press. 330 // Clean up the drag helper, which is re-created on the next mouse press.
393 delegate_->EndDrag(canceled); 331 delegate_->EndDrag(canceled);
394 332
395 observer_.reset(); 333 observer_.reset();
396 } 334 }
OLDNEW
« no previous file with comments | « chrome/browser/ui/gtk/tabs/tab_gtk.h ('k') | chrome/browser/ui/gtk/tabs/tab_renderer_gtk.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698