OLD | NEW |
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 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/gtk/tabs/tab_gtk.h" | 5 #include "chrome/browser/gtk/tabs/tab_gtk.h" |
6 | 6 |
7 #include "app/gfx/path.h" | 7 #include "app/gfx/path.h" |
8 #include "app/l10n_util.h" | 8 #include "app/l10n_util.h" |
9 #include "app/resource_bundle.h" | 9 #include "app/resource_bundle.h" |
10 #include "chrome/browser/gtk/custom_button.h" | 10 #include "chrome/browser/gtk/custom_button.h" |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
93 | 93 |
94 DISALLOW_COPY_AND_ASSIGN(ContextMenuController); | 94 DISALLOW_COPY_AND_ASSIGN(ContextMenuController); |
95 }; | 95 }; |
96 | 96 |
97 /////////////////////////////////////////////////////////////////////////////// | 97 /////////////////////////////////////////////////////////////////////////////// |
98 // TabGtk, public: | 98 // TabGtk, public: |
99 | 99 |
100 TabGtk::TabGtk(TabDelegate* delegate) | 100 TabGtk::TabGtk(TabDelegate* delegate) |
101 : TabRendererGtk(), | 101 : TabRendererGtk(), |
102 delegate_(delegate), | 102 delegate_(delegate), |
103 closing_(false) { | 103 closing_(false), |
| 104 dragging_(false) { |
104 event_box_.Own(gtk_event_box_new()); | 105 event_box_.Own(gtk_event_box_new()); |
105 gtk_event_box_set_visible_window(GTK_EVENT_BOX(event_box_.get()), FALSE); | 106 gtk_event_box_set_visible_window(GTK_EVENT_BOX(event_box_.get()), FALSE); |
106 gtk_drag_source_set(event_box_.get(), GDK_BUTTON1_MASK, | 107 gtk_drag_source_set(event_box_.get(), GDK_BUTTON1_MASK, |
107 target_table, G_N_ELEMENTS(target_table), | 108 target_table, G_N_ELEMENTS(target_table), |
108 GDK_ACTION_MOVE); | 109 GDK_ACTION_MOVE); |
109 gtk_drag_dest_set(event_box_.get(), GTK_DEST_DEFAULT_DROP, | |
110 target_table, G_N_ELEMENTS(target_table), | |
111 GDK_ACTION_MOVE); | |
112 gtk_drag_dest_set_track_motion(event_box_.get(), true); | |
113 g_signal_connect(G_OBJECT(event_box_.get()), "button-press-event", | 110 g_signal_connect(G_OBJECT(event_box_.get()), "button-press-event", |
114 G_CALLBACK(OnMousePress), this); | 111 G_CALLBACK(OnMousePress), this); |
115 g_signal_connect(G_OBJECT(event_box_.get()), "button-release-event", | 112 g_signal_connect(G_OBJECT(event_box_.get()), "button-release-event", |
116 G_CALLBACK(OnMouseRelease), this); | 113 G_CALLBACK(OnMouseRelease), this); |
117 g_signal_connect(G_OBJECT(event_box_.get()), "enter-notify-event", | 114 g_signal_connect(G_OBJECT(event_box_.get()), "enter-notify-event", |
118 G_CALLBACK(OnEnterNotify), this); | 115 G_CALLBACK(OnEnterNotify), this); |
119 g_signal_connect(G_OBJECT(event_box_.get()), "leave-notify-event", | 116 g_signal_connect(G_OBJECT(event_box_.get()), "leave-notify-event", |
120 G_CALLBACK(OnLeaveNotify), this); | 117 G_CALLBACK(OnLeaveNotify), this); |
121 g_signal_connect_after(G_OBJECT(event_box_.get()), "drag-begin", | 118 g_signal_connect_after(G_OBJECT(event_box_.get()), "drag-begin", |
122 G_CALLBACK(&OnDragBegin), this); | 119 G_CALLBACK(OnDragBegin), this); |
123 g_signal_connect_after(G_OBJECT(event_box_.get()), "drag-end", | 120 g_signal_connect_after(G_OBJECT(event_box_.get()), "drag-end", |
124 G_CALLBACK(&OnDragEnd), this); | 121 G_CALLBACK(OnDragEnd), this); |
125 g_signal_connect_after(G_OBJECT(event_box_.get()), "drag-failed", | 122 g_signal_connect_after(G_OBJECT(event_box_.get()), "drag-failed", |
126 G_CALLBACK(&OnDragFailed), this); | 123 G_CALLBACK(OnDragFailed), this); |
127 g_signal_connect_after(G_OBJECT(event_box_.get()), "drag-motion", | |
128 G_CALLBACK(&OnDragMotion), this); | |
129 gtk_widget_add_events(event_box_.get(), | 124 gtk_widget_add_events(event_box_.get(), |
130 GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | | 125 GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | |
131 GDK_LEAVE_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK); | 126 GDK_LEAVE_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK); |
132 gtk_container_add(GTK_CONTAINER(event_box_.get()), TabRendererGtk::widget()); | 127 gtk_container_add(GTK_CONTAINER(event_box_.get()), TabRendererGtk::widget()); |
133 gtk_widget_show_all(event_box_.get()); | 128 gtk_widget_show_all(event_box_.get()); |
134 | 129 |
135 close_button_.reset(MakeCloseButton()); | 130 close_button_.reset(MakeCloseButton()); |
136 } | 131 } |
137 | 132 |
138 TabGtk::~TabGtk() { | 133 TabGtk::~TabGtk() { |
139 if (menu_controller_.get()) { | 134 if (menu_controller_.get()) { |
140 // The menu is showing. Close the menu. | 135 // The menu is showing. Close the menu. |
141 menu_controller_->Cancel(); | 136 menu_controller_->Cancel(); |
142 | 137 |
143 // Invoke this so that we hide the highlight. | 138 // Invoke this so that we hide the highlight. |
144 ContextMenuClosed(); | 139 ContextMenuClosed(); |
145 } | 140 } |
146 | 141 |
147 event_box_.Destroy(); | 142 event_box_.Destroy(); |
148 } | 143 } |
149 | 144 |
150 // static | 145 // static |
| 146 void TabGtk::GdkEventHandler(GdkEvent* event, void* data) { |
| 147 TabGtk* tab = static_cast<TabGtk*>(data); |
| 148 |
| 149 if (event->type == GDK_MOTION_NOTIFY && tab->dragging_) { |
| 150 tab->delegate_->ContinueDrag(NULL); |
| 151 } |
| 152 |
| 153 gtk_main_do_event(event); |
| 154 } |
| 155 |
| 156 // static |
151 gboolean TabGtk::OnMousePress(GtkWidget* widget, GdkEventButton* event, | 157 gboolean TabGtk::OnMousePress(GtkWidget* widget, GdkEventButton* event, |
152 TabGtk* tab) { | 158 TabGtk* tab) { |
153 if (event->button == 1) { | 159 if (event->button == 1) { |
154 // Store whether or not we were selected just now... we only want to be | 160 // Store whether or not we were selected just now... we only want to be |
155 // able to drag foreground tabs, so we don't start dragging the tab if | 161 // able to drag foreground tabs, so we don't start dragging the tab if |
156 // it was in the background. | 162 // it was in the background. |
157 bool just_selected = !tab->IsSelected(); | 163 bool just_selected = !tab->IsSelected(); |
158 if (just_selected) { | 164 if (just_selected) { |
159 tab->delegate_->SelectTab(tab); | 165 tab->delegate_->SelectTab(tab); |
160 } | 166 } |
(...skipping 24 matching lines...) Expand all Loading... |
185 // static | 191 // static |
186 gboolean TabGtk::OnLeaveNotify(GtkWidget* widget, GdkEventCrossing* event, | 192 gboolean TabGtk::OnLeaveNotify(GtkWidget* widget, GdkEventCrossing* event, |
187 TabGtk* tab) { | 193 TabGtk* tab) { |
188 tab->OnMouseExited(); | 194 tab->OnMouseExited(); |
189 return TRUE; | 195 return TRUE; |
190 } | 196 } |
191 | 197 |
192 // static | 198 // static |
193 void TabGtk::OnDragBegin(GtkWidget* widget, GdkDragContext* context, | 199 void TabGtk::OnDragBegin(GtkWidget* widget, GdkDragContext* context, |
194 TabGtk* tab) { | 200 TabGtk* tab) { |
| 201 gdk_event_handler_set(TabGtk::GdkEventHandler, tab, NULL); |
| 202 |
195 int x, y; | 203 int x, y; |
196 gdk_window_get_pointer(tab->event_box_.get()->window, &x, &y, NULL); | 204 gdk_window_get_pointer(tab->event_box_.get()->window, &x, &y, NULL); |
| 205 |
| 206 // Make the mouse coordinate relative to the tab. |
| 207 x -= tab->bounds().x(); |
| 208 y -= tab->bounds().y(); |
| 209 |
| 210 tab->dragging_ = true; |
197 tab->delegate_->MaybeStartDrag(tab, gfx::Point(x, y)); | 211 tab->delegate_->MaybeStartDrag(tab, gfx::Point(x, y)); |
198 } | 212 } |
199 | 213 |
200 // static | 214 // static |
201 void TabGtk::OnDragEnd(GtkWidget* widget, GdkDragContext* context, | 215 void TabGtk::OnDragEnd(GtkWidget* widget, GdkDragContext* context, |
202 TabGtk* tab) { | 216 TabGtk* tab) { |
| 217 tab->dragging_ = false; |
203 // Notify the drag helper that we're done with any potential drag operations. | 218 // Notify the drag helper that we're done with any potential drag operations. |
204 // Clean up the drag helper, which is re-created on the next mouse press. | 219 // Clean up the drag helper, which is re-created on the next mouse press. |
205 tab->delegate_->EndDrag(false); | 220 tab->delegate_->EndDrag(false); |
206 } | 221 } |
207 | 222 |
208 // static | 223 // static |
209 gboolean TabGtk::OnDragMotion(GtkWidget* widget, | 224 gboolean TabGtk::OnDragMotion(GtkWidget* widget, |
210 GdkDragContext* context, | 225 GdkDragContext* context, |
211 guint x, guint y, | 226 guint x, guint y, |
212 guint time, | 227 guint time, |
213 TabGtk* tab) { | 228 TabGtk* tab) { |
214 tab->delegate_->ContinueDrag(context); | 229 tab->delegate_->ContinueDrag(context); |
215 return TRUE; | 230 return TRUE; |
216 } | 231 } |
217 | 232 |
218 // static | 233 // static |
219 gboolean TabGtk::OnDragFailed(GtkWidget* widget, GdkDragContext* context, | 234 gboolean TabGtk::OnDragFailed(GtkWidget* widget, GdkDragContext* context, |
220 GtkDragResult result, | 235 GtkDragResult result, |
221 TabGtk* tab) { | 236 TabGtk* tab) { |
222 tab->delegate_->EndDrag(true); | 237 tab->delegate_->EndDrag(false); |
223 return TRUE; | 238 return TRUE; |
224 } | 239 } |
225 | 240 |
226 /////////////////////////////////////////////////////////////////////////////// | 241 /////////////////////////////////////////////////////////////////////////////// |
227 // TabGtk, TabRendererGtk overrides: | 242 // TabGtk, TabRendererGtk overrides: |
228 | 243 |
229 bool TabGtk::IsSelected() const { | 244 bool TabGtk::IsSelected() const { |
230 return delegate_->IsTabSelected(this); | 245 return delegate_->IsTabSelected(this); |
231 } | 246 } |
232 | 247 |
| 248 bool TabGtk::IsVisible() const { |
| 249 return GTK_WIDGET_FLAGS(event_box_.get()) & GTK_VISIBLE; |
| 250 } |
| 251 |
| 252 void TabGtk::SetVisible(bool visible) const { |
| 253 if (visible) { |
| 254 gtk_widget_show(event_box_.get()); |
| 255 } else { |
| 256 gtk_widget_hide(event_box_.get()); |
| 257 } |
| 258 } |
| 259 |
233 void TabGtk::CloseButtonResized(const gfx::Rect& bounds) { | 260 void TabGtk::CloseButtonResized(const gfx::Rect& bounds) { |
234 gtk_fixed_move(GTK_FIXED(TabRendererGtk::widget()), | 261 gtk_fixed_move(GTK_FIXED(TabRendererGtk::widget()), |
235 close_button_.get()->widget(), bounds.x(), bounds.y()); | 262 close_button_.get()->widget(), bounds.x(), bounds.y()); |
236 } | 263 } |
237 | 264 |
238 void TabGtk::Paint(GdkEventExpose* event) { | 265 void TabGtk::Paint(GdkEventExpose* event) { |
239 TabRendererGtk::Paint(event); | 266 TabRendererGtk::Paint(event); |
240 | 267 |
241 gtk_container_propagate_expose(GTK_CONTAINER(TabRendererGtk::widget()), | 268 gtk_container_propagate_expose(GTK_CONTAINER(TabRendererGtk::widget()), |
242 close_button_.get()->widget(), event); | 269 close_button_.get()->widget(), event); |
(...skipping 24 matching lines...) Expand all Loading... |
267 IDR_TAB_CLOSE_P, IDR_TAB_CLOSE_H, IDR_TAB_CLOSE); | 294 IDR_TAB_CLOSE_P, IDR_TAB_CLOSE_H, IDR_TAB_CLOSE); |
268 | 295 |
269 g_signal_connect(G_OBJECT(button->widget()), "clicked", | 296 g_signal_connect(G_OBJECT(button->widget()), "clicked", |
270 G_CALLBACK(OnCloseButtonClicked), this); | 297 G_CALLBACK(OnCloseButtonClicked), this); |
271 GTK_WIDGET_UNSET_FLAGS(button->widget(), GTK_CAN_FOCUS); | 298 GTK_WIDGET_UNSET_FLAGS(button->widget(), GTK_CAN_FOCUS); |
272 gtk_fixed_put(GTK_FIXED(TabRendererGtk::widget()), button->widget(), 0, 0); | 299 gtk_fixed_put(GTK_FIXED(TabRendererGtk::widget()), button->widget(), 0, 0); |
273 gtk_widget_show(button->widget()); | 300 gtk_widget_show(button->widget()); |
274 | 301 |
275 return button; | 302 return button; |
276 } | 303 } |
OLD | NEW |