| 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 |