OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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/reload_button_gtk.h" | 5 #include "chrome/browser/gtk/reload_button_gtk.h" |
6 | 6 |
7 #include "app/l10n_util.h" | 7 #include "app/l10n_util.h" |
8 #include "base/logging.h" | 8 #include "base/logging.h" |
9 #include "chrome/app/chrome_dll_resource.h" | 9 #include "chrome/app/chrome_dll_resource.h" |
10 #include "chrome/browser/browser.h" | 10 #include "chrome/browser/browser.h" |
(...skipping 14 matching lines...) Expand all Loading... |
25 Browser* browser) | 25 Browser* browser) |
26 : location_bar_(location_bar), | 26 : location_bar_(location_bar), |
27 browser_(browser), | 27 browser_(browser), |
28 button_delay_(0), | 28 button_delay_(0), |
29 pretend_timer_is_running_for_unittest_(false), | 29 pretend_timer_is_running_for_unittest_(false), |
30 intended_mode_(MODE_RELOAD), | 30 intended_mode_(MODE_RELOAD), |
31 visible_mode_(MODE_RELOAD), | 31 visible_mode_(MODE_RELOAD), |
32 theme_provider_(browser ? | 32 theme_provider_(browser ? |
33 GtkThemeProvider::GetFrom(browser->profile()) : NULL), | 33 GtkThemeProvider::GetFrom(browser->profile()) : NULL), |
34 reload_(theme_provider_, IDR_RELOAD, IDR_RELOAD_P, IDR_RELOAD_H, 0), | 34 reload_(theme_provider_, IDR_RELOAD, IDR_RELOAD_P, IDR_RELOAD_H, 0), |
35 stop_(theme_provider_, IDR_STOP, IDR_STOP_P, IDR_STOP_H, 0), | 35 stop_(theme_provider_, IDR_STOP, IDR_STOP_P, IDR_STOP_H, IDR_STOP_D), |
36 widget_(gtk_chrome_button_new()) { | 36 widget_(gtk_chrome_button_new()) { |
37 gtk_widget_set_size_request(widget(), reload_.Width(), reload_.Height()); | 37 gtk_widget_set_size_request(widget(), reload_.Width(), reload_.Height()); |
38 | 38 |
39 gtk_widget_set_app_paintable(widget(), TRUE); | 39 gtk_widget_set_app_paintable(widget(), TRUE); |
40 | 40 |
41 g_signal_connect(widget(), "clicked", G_CALLBACK(OnClickedThunk), this); | 41 g_signal_connect(widget(), "clicked", G_CALLBACK(OnClickedThunk), this); |
42 g_signal_connect(widget(), "expose-event", G_CALLBACK(OnExposeThunk), this); | 42 g_signal_connect(widget(), "expose-event", G_CALLBACK(OnExposeThunk), this); |
43 g_signal_connect(widget(), "leave-notify-event", | 43 g_signal_connect(widget(), "leave-notify-event", |
44 G_CALLBACK(OnLeaveNotifyThunk), this); | 44 G_CALLBACK(OnLeaveNotifyThunk), this); |
45 GTK_WIDGET_UNSET_FLAGS(widget(), GTK_CAN_FOCUS); | 45 GTK_WIDGET_UNSET_FLAGS(widget(), GTK_CAN_FOCUS); |
(...skipping 22 matching lines...) Expand all Loading... |
68 | 68 |
69 // If the change is forced, or the user isn't hovering the icon, or it's safe | 69 // If the change is forced, or the user isn't hovering the icon, or it's safe |
70 // to change it to the other image type, make the change immediately; | 70 // to change it to the other image type, make the change immediately; |
71 // otherwise we'll let it happen later. | 71 // otherwise we'll let it happen later. |
72 if (force || GTK_WIDGET_STATE(widget()) == GTK_STATE_NORMAL || | 72 if (force || GTK_WIDGET_STATE(widget()) == GTK_STATE_NORMAL || |
73 ((mode == MODE_STOP) ? | 73 ((mode == MODE_STOP) ? |
74 !timer_running() : (visible_mode_ != MODE_STOP))) { | 74 !timer_running() : (visible_mode_ != MODE_STOP))) { |
75 timer_.Stop(); | 75 timer_.Stop(); |
76 visible_mode_ = mode; | 76 visible_mode_ = mode; |
77 | 77 |
| 78 stop_.set_paint_override(-1); |
| 79 gtk_chrome_button_unset_paint_state(GTK_CHROME_BUTTON(widget_.get())); |
| 80 |
78 UpdateThemeButtons(); | 81 UpdateThemeButtons(); |
79 gtk_widget_queue_draw(widget()); | 82 gtk_widget_queue_draw(widget()); |
| 83 } else if (visible_mode_ != MODE_RELOAD) { |
| 84 // If you read the views implementation of reload_button.cc, you'll see |
| 85 // that instead of screwing with paint states, the views implementation |
| 86 // just changes whether the view is enabled. We can't do that here because |
| 87 // changing the widget state to GTK_STATE_INSENSITIVE will cause a cascade |
| 88 // of messages on all its children and will also trigger a synthesized |
| 89 // leave notification and prevent the real leave notification from turning |
| 90 // the button back to normal. So instead, override the stop_ paint state |
| 91 // for chrome-theme mode, and use this as a flag to discard click events. |
| 92 stop_.set_paint_override(GTK_STATE_INSENSITIVE); |
| 93 |
| 94 // Also set the gtk_chrome_button paint state to insensitive to hide |
| 95 // the border drawn around the stop icon. |
| 96 gtk_chrome_button_set_paint_state(GTK_CHROME_BUTTON(widget_.get()), |
| 97 GTK_STATE_INSENSITIVE); |
| 98 |
| 99 // If we're in GTK theme mode, we need to also render the correct icon for |
| 100 // the stop/insensitive since we won't be using |stop_| to render the icon. |
| 101 UpdateThemeButtons(); |
80 } | 102 } |
81 } | 103 } |
82 | 104 |
83 void ReloadButtonGtk::Observe(NotificationType type, | 105 void ReloadButtonGtk::Observe(NotificationType type, |
84 const NotificationSource& source, | 106 const NotificationSource& source, |
85 const NotificationDetails& details) { | 107 const NotificationDetails& details) { |
86 DCHECK(NotificationType::BROWSER_THEME_CHANGED == type); | 108 DCHECK(NotificationType::BROWSER_THEME_CHANGED == type); |
87 | 109 |
88 GtkThemeProvider* provider = static_cast<GtkThemeProvider*>( | 110 GtkThemeProvider* provider = static_cast<GtkThemeProvider*>( |
89 Source<GtkThemeProvider>(source).ptr()); | 111 Source<GtkThemeProvider>(source).ptr()); |
90 DCHECK_EQ(provider, theme_provider_); | 112 DCHECK_EQ(provider, theme_provider_); |
91 GtkButtonWidth = 0; | 113 GtkButtonWidth = 0; |
92 UpdateThemeButtons(); | 114 UpdateThemeButtons(); |
93 } | 115 } |
94 | 116 |
95 void ReloadButtonGtk::OnButtonTimer() { | 117 void ReloadButtonGtk::OnButtonTimer() { |
96 ChangeMode(intended_mode_, false); | 118 ChangeMode(intended_mode_, false); |
97 } | 119 } |
98 | 120 |
99 void ReloadButtonGtk::OnClicked(GtkWidget* sender) { | 121 void ReloadButtonGtk::OnClicked(GtkWidget* sender) { |
100 if (visible_mode_ == MODE_STOP) { | 122 if (visible_mode_ == MODE_STOP) { |
| 123 // The stop button is disabled because the user hovered over the button |
| 124 // until the stop action is no longer selectable. |
| 125 if (stop_.paint_override() == GTK_STATE_INSENSITIVE) |
| 126 return; |
| 127 |
101 if (browser_) | 128 if (browser_) |
102 browser_->Stop(); | 129 browser_->Stop(); |
103 | 130 |
104 // The user has clicked, so we can feel free to update the button, | 131 // The user has clicked, so we can feel free to update the button, |
105 // even if the mouse is still hovering. | 132 // even if the mouse is still hovering. |
106 ChangeMode(MODE_RELOAD, true); | 133 ChangeMode(MODE_RELOAD, true); |
107 } else if (!timer_running()) { | 134 } else if (!timer_running()) { |
108 // Shift-clicking or Ctrl-clicking the reload button means we should ignore | 135 // Shift-clicking or Ctrl-clicking the reload button means we should ignore |
109 // any cached content. | 136 // any cached content. |
110 int command; | 137 int command; |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
175 gtk_tooltip_set_text(tooltip, l10n_util::GetStringUTF8( | 202 gtk_tooltip_set_text(tooltip, l10n_util::GetStringUTF8( |
176 (visible_mode_ == MODE_RELOAD) ? | 203 (visible_mode_ == MODE_RELOAD) ? |
177 IDS_TOOLTIP_RELOAD : IDS_TOOLTIP_STOP).c_str()); | 204 IDS_TOOLTIP_RELOAD : IDS_TOOLTIP_STOP).c_str()); |
178 return TRUE; | 205 return TRUE; |
179 } | 206 } |
180 | 207 |
181 void ReloadButtonGtk::UpdateThemeButtons() { | 208 void ReloadButtonGtk::UpdateThemeButtons() { |
182 bool use_gtk = theme_provider_ && theme_provider_->UseGtkTheme(); | 209 bool use_gtk = theme_provider_ && theme_provider_->UseGtkTheme(); |
183 | 210 |
184 if (use_gtk) { | 211 if (use_gtk) { |
185 GdkPixbuf* pixbuf = gtk_widget_render_icon(widget(), | 212 gtk_widget_ensure_style(widget()); |
186 (intended_mode_ == MODE_RELOAD) ? GTK_STOCK_REFRESH : GTK_STOCK_STOP, | 213 GtkIconSet* icon_set = gtk_style_lookup_icon_set( |
187 GTK_ICON_SIZE_SMALL_TOOLBAR, NULL); | 214 widget()->style, |
| 215 (visible_mode_ == MODE_RELOAD) ? GTK_STOCK_REFRESH : GTK_STOCK_STOP); |
| 216 if (icon_set) { |
| 217 GtkStateType state = static_cast<GtkStateType>( |
| 218 GTK_WIDGET_STATE(widget())); |
| 219 if (visible_mode_ == MODE_STOP && stop_.paint_override() != -1) |
| 220 state = static_cast<GtkStateType>(stop_.paint_override()); |
188 | 221 |
189 gtk_button_set_image(GTK_BUTTON(widget()), | 222 GdkPixbuf* pixbuf = gtk_icon_set_render_icon( |
190 gtk_image_new_from_pixbuf(pixbuf)); | 223 icon_set, |
191 g_object_unref(pixbuf); | 224 widget()->style, |
| 225 gtk_widget_get_direction(widget()), |
| 226 state, |
| 227 GTK_ICON_SIZE_SMALL_TOOLBAR, |
| 228 widget(), |
| 229 NULL); |
| 230 |
| 231 gtk_button_set_image(GTK_BUTTON(widget()), |
| 232 gtk_image_new_from_pixbuf(pixbuf)); |
| 233 g_object_unref(pixbuf); |
| 234 } |
192 | 235 |
193 gtk_widget_set_size_request(widget(), -1, -1); | 236 gtk_widget_set_size_request(widget(), -1, -1); |
194 GtkRequisition req; | 237 GtkRequisition req; |
195 gtk_widget_size_request(widget(), &req); | 238 gtk_widget_size_request(widget(), &req); |
196 GtkButtonWidth = std::max(GtkButtonWidth, req.width); | 239 GtkButtonWidth = std::max(GtkButtonWidth, req.width); |
197 gtk_widget_set_size_request(widget(), GtkButtonWidth, -1); | 240 gtk_widget_set_size_request(widget(), GtkButtonWidth, -1); |
198 | 241 |
199 gtk_widget_set_app_paintable(widget(), FALSE); | 242 gtk_widget_set_app_paintable(widget(), FALSE); |
200 gtk_widget_set_double_buffered(widget(), TRUE); | 243 gtk_widget_set_double_buffered(widget(), TRUE); |
201 } else { | 244 } else { |
202 gtk_button_set_image(GTK_BUTTON(widget()), NULL); | 245 gtk_button_set_image(GTK_BUTTON(widget()), NULL); |
203 | 246 |
204 gtk_widget_set_size_request(widget(), reload_.Width(), reload_.Height()); | 247 gtk_widget_set_size_request(widget(), reload_.Width(), reload_.Height()); |
205 | 248 |
206 gtk_widget_set_app_paintable(widget(), TRUE); | 249 gtk_widget_set_app_paintable(widget(), TRUE); |
207 // We effectively double-buffer by virtue of having only one image... | 250 // We effectively double-buffer by virtue of having only one image... |
208 gtk_widget_set_double_buffered(widget(), FALSE); | 251 gtk_widget_set_double_buffered(widget(), FALSE); |
209 } | 252 } |
210 | 253 |
211 gtk_chrome_button_set_use_gtk_rendering(GTK_CHROME_BUTTON(widget()), use_gtk); | 254 gtk_chrome_button_set_use_gtk_rendering(GTK_CHROME_BUTTON(widget()), use_gtk); |
212 } | 255 } |
OLD | NEW |