Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/gtk_chrome_link_button.h" | 5 #include "chrome/browser/ui/gtk/gtk_chrome_link_button.h" |
| 6 | 6 |
| 7 #include <stdlib.h> | 7 #include <stdlib.h> |
| 8 | 8 |
| 9 #include "chrome/browser/ui/gtk/gtk_util.h" | 9 #include "chrome/browser/ui/gtk/gtk_util.h" |
| 10 #include "ui/base/gtk/gtk_compat.h" | 10 #include "ui/base/gtk/gtk_compat.h" |
| 11 #include "ui/gfx/gtk_util.h" | 11 #include "ui/gfx/gtk_util.h" |
| 12 | 12 |
| 13 static const gchar* kLinkMarkup = "<u><span color=\"%s\">%s</span></u>"; | 13 static const gchar* kLinkMarkup = "<u><span color=\"%s\">%s</span></u>"; |
| 14 static const gchar* kInsensitiveLinkMarkup = "<span color=\"%s\">%s</span>"; | |
| 14 | 15 |
| 15 namespace { | 16 namespace { |
| 16 | 17 |
| 17 // Set the GTK style on our custom link button. We don't want any border around | 18 // Set the GTK style on our custom link button. We don't want any border around |
| 18 // the link text. | 19 // the link text. |
| 19 void SetLinkButtonStyle() { | 20 void SetLinkButtonStyle() { |
| 20 static bool style_was_set = false; | 21 static bool style_was_set = false; |
| 21 | 22 |
| 22 if (style_was_set) | 23 if (style_was_set) |
| 23 return; | 24 return; |
| 24 style_was_set = true; | 25 style_was_set = true; |
| 25 | 26 |
| 26 gtk_rc_parse_string( | 27 gtk_rc_parse_string( |
| 27 "style \"chrome-link-button\" {" | 28 "style \"chrome-link-button\" {" |
| 28 " GtkButton::inner-border = {0, 0, 0, 0}" | 29 " GtkButton::inner-border = {0, 0, 0, 0}" |
| 29 " GtkButton::child-displacement-x = 0" | 30 " GtkButton::child-displacement-x = 0" |
| 30 " GtkButton::child-displacement-y = 0" | 31 " GtkButton::child-displacement-y = 0" |
| 31 " xthickness = 0" | 32 " xthickness = 0" |
| 32 " ythickness = 0" | 33 " ythickness = 0" |
| 33 "}" | 34 "}" |
| 34 "widget_class \"*.<GtkChromeLinkButton>\" style \"chrome-link-button\""); | 35 "widget_class \"*.<GtkChromeLinkButton>\" style \"chrome-link-button\""); |
| 35 } | 36 } |
| 36 | 37 |
| 37 static void gtk_chrome_link_button_destroy_text_resources( | 38 static void gtk_chrome_link_button_destroy_text_resources( |
| 38 GtkChromeLinkButton* button) { | 39 GtkChromeLinkButton* button) { |
| 39 g_free(button->native_markup); | 40 g_free(button->native_markup); |
| 40 button->native_markup = NULL; | 41 button->native_markup = NULL; |
| 41 g_free(button->normal_markup); | 42 g_free(button->normal_markup); |
| 42 button->normal_markup = NULL; | 43 button->normal_markup = NULL; |
| 44 g_free(button->insensitive_markup); | |
|
Evan Stade
2012/04/02 21:16:40
nit: add this after pressed_markup
binji
2012/04/02 21:36:05
Done.
| |
| 45 button->insensitive_markup = NULL; | |
| 43 g_free(button->pressed_markup); | 46 g_free(button->pressed_markup); |
| 44 button->pressed_markup = NULL; | 47 button->pressed_markup = NULL; |
| 45 | 48 |
| 46 g_free(button->text); | 49 g_free(button->text); |
| 47 button->text = NULL; | 50 button->text = NULL; |
| 48 } | 51 } |
| 49 | 52 |
| 50 } // namespace | 53 } // namespace |
| 51 | 54 |
| 52 G_BEGIN_DECLS | 55 G_BEGIN_DECLS |
| 53 G_DEFINE_TYPE(GtkChromeLinkButton, gtk_chrome_link_button, GTK_TYPE_BUTTON) | 56 G_DEFINE_TYPE(GtkChromeLinkButton, gtk_chrome_link_button, GTK_TYPE_BUTTON) |
| 54 | 57 |
| 55 static void gtk_chrome_link_button_set_text(GtkChromeLinkButton* button) { | 58 static void gtk_chrome_link_button_set_text(GtkChromeLinkButton* button) { |
| 56 // If we were called before we were realized, abort. We'll be called for | 59 // If we were called before we were realized, abort. We'll be called for |
| 57 // real when |button| is realized. | 60 // real when |button| is realized. |
| 58 if (!gtk_widget_get_realized(GTK_WIDGET(button))) | 61 if (!gtk_widget_get_realized(GTK_WIDGET(button))) |
| 59 return; | 62 return; |
| 60 | 63 |
| 61 g_free(button->native_markup); | 64 g_free(button->native_markup); |
| 62 button->native_markup = NULL; | 65 button->native_markup = NULL; |
| 63 g_free(button->normal_markup); | 66 g_free(button->normal_markup); |
| 64 button->normal_markup = NULL; | 67 button->normal_markup = NULL; |
| 65 g_free(button->pressed_markup); | 68 g_free(button->pressed_markup); |
| 66 button->pressed_markup = NULL; | 69 button->pressed_markup = NULL; |
| 70 g_free(button->insensitive_markup); | |
| 71 button->insensitive_markup = NULL; | |
| 67 | 72 |
| 68 gchar* text = button->text; | 73 gchar* text = button->text; |
| 69 gboolean uses_markup = button->uses_markup; | 74 gboolean uses_markup = button->uses_markup; |
| 70 | 75 |
| 76 GtkStyle* style = gtk_rc_get_style(button->label); | |
| 77 GdkColor insensitive_color = style->fg[GTK_STATE_INSENSITIVE]; | |
| 78 gchar insensitive_color_spec[9]; | |
| 79 snprintf(insensitive_color_spec, 9, "#%02X%02X%02X", | |
| 80 insensitive_color.red / 257, insensitive_color.green / 257, | |
| 81 insensitive_color.blue / 257); | |
| 82 | |
| 71 if (!uses_markup) { | 83 if (!uses_markup) { |
| 72 button->normal_markup = g_markup_printf_escaped(kLinkMarkup, | 84 button->normal_markup = g_markup_printf_escaped(kLinkMarkup, |
| 73 button->normal_color, | 85 button->normal_color, |
| 74 text); | 86 text); |
| 75 button->pressed_markup = g_markup_printf_escaped(kLinkMarkup, "red", text); | 87 button->pressed_markup = g_markup_printf_escaped(kLinkMarkup, "red", text); |
| 88 button->insensitive_markup = g_markup_printf_escaped(kInsensitiveLinkMarkup, | |
| 89 insensitive_color_spec, | |
| 90 text); | |
| 76 } else { | 91 } else { |
| 77 button->normal_markup = g_strdup_printf(kLinkMarkup, button->normal_color, | 92 button->normal_markup = g_strdup_printf(kLinkMarkup, button->normal_color, |
| 78 text); | 93 text); |
| 79 | 94 |
| 80 button->pressed_markup = g_strdup_printf(kLinkMarkup, "red", text); | 95 button->pressed_markup = g_strdup_printf(kLinkMarkup, "red", text); |
| 96 button->insensitive_markup = g_strdup_printf(kInsensitiveLinkMarkup, | |
| 97 insensitive_color_spec, | |
| 98 text); | |
| 81 } | 99 } |
| 82 | 100 |
| 83 // Get the current GTK theme's link button text color. | 101 // Get the current GTK theme's link button text color. |
| 84 GdkColor* native_color = NULL; | 102 GdkColor* native_color = NULL; |
| 85 gtk_widget_style_get(GTK_WIDGET(button), "link-color", &native_color, NULL); | 103 gtk_widget_style_get(GTK_WIDGET(button), "link-color", &native_color, NULL); |
| 86 | 104 |
| 87 if (native_color) { | 105 if (native_color) { |
| 88 gchar color_spec[9]; | 106 gchar color_spec[9]; |
| 89 snprintf(color_spec, 9, "#%02X%02X%02X", native_color->red / 257, | 107 snprintf(color_spec, 9, "#%02X%02X%02X", native_color->red / 257, |
| 90 native_color->green / 257, native_color->blue / 257); | 108 native_color->green / 257, native_color->blue / 257); |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 113 gtk_chrome_link_button_set_text(button); | 131 gtk_chrome_link_button_set_text(button); |
| 114 | 132 |
| 115 if (gtk_widget_get_visible(GTK_WIDGET(button))) | 133 if (gtk_widget_get_visible(GTK_WIDGET(button))) |
| 116 gtk_widget_queue_draw(GTK_WIDGET(button)); | 134 gtk_widget_queue_draw(GTK_WIDGET(button)); |
| 117 } | 135 } |
| 118 | 136 |
| 119 static gboolean gtk_chrome_link_button_expose(GtkWidget* widget, | 137 static gboolean gtk_chrome_link_button_expose(GtkWidget* widget, |
| 120 GdkEventExpose* event) { | 138 GdkEventExpose* event) { |
| 121 GtkChromeLinkButton* button = GTK_CHROME_LINK_BUTTON(widget); | 139 GtkChromeLinkButton* button = GTK_CHROME_LINK_BUTTON(widget); |
| 122 GtkWidget* label = button->label; | 140 GtkWidget* label = button->label; |
| 141 GtkStateType widget_state = gtk_widget_get_state(widget); | |
| 123 | 142 |
| 124 if (gtk_widget_get_state(widget) == GTK_STATE_ACTIVE && button->is_normal) { | 143 if (widget_state != button->label_state) { |
| 125 gtk_label_set_markup(GTK_LABEL(label), button->pressed_markup); | 144 switch (widget_state) { |
| 126 button->is_normal = FALSE; | 145 case GTK_STATE_NORMAL: |
| 127 } else if (gtk_widget_get_state(widget) != GTK_STATE_ACTIVE && | 146 gtk_label_set_markup(GTK_LABEL(label), |
| 128 !button->is_normal) { | 147 button->using_native_theme ? button->native_markup : |
| 129 gtk_label_set_markup(GTK_LABEL(label), | 148 button->normal_markup); |
| 130 button->using_native_theme ? button->native_markup : | 149 break; |
| 131 button->normal_markup); | 150 case GTK_STATE_ACTIVE: |
| 132 button->is_normal = TRUE; | 151 gtk_label_set_markup(GTK_LABEL(label), button->pressed_markup); |
| 152 break; | |
| 153 case GTK_STATE_INSENSITIVE: | |
| 154 gtk_label_set_markup(GTK_LABEL(label), button->insensitive_markup); | |
| 155 break; | |
| 156 default: | |
| 157 break; | |
| 158 } | |
| 159 button->label_state = widget_state; | |
| 133 } | 160 } |
| 134 | 161 |
| 135 // Draw the link inside the button. | 162 // Draw the link inside the button. |
| 136 gtk_container_propagate_expose(GTK_CONTAINER(widget), label, event); | 163 gtk_container_propagate_expose(GTK_CONTAINER(widget), label, event); |
| 137 | 164 |
| 138 // Draw the focus rectangle. | 165 // Draw the focus rectangle. |
| 139 if (gtk_widget_has_focus(widget)) { | 166 if (gtk_widget_has_focus(widget)) { |
| 140 GtkAllocation allocation; | 167 GtkAllocation allocation; |
| 141 gtk_widget_get_allocation(widget, &allocation); | 168 gtk_widget_get_allocation(widget, &allocation); |
| 142 gtk_paint_focus(gtk_widget_get_style(widget), | 169 gtk_paint_focus(gtk_widget_get_style(widget), |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 188 | 215 |
| 189 static void gtk_chrome_link_button_init(GtkChromeLinkButton* button) { | 216 static void gtk_chrome_link_button_init(GtkChromeLinkButton* button) { |
| 190 SetLinkButtonStyle(); | 217 SetLinkButtonStyle(); |
| 191 | 218 |
| 192 // We put a label in a button so we can connect to the click event. We don't | 219 // We put a label in a button so we can connect to the click event. We don't |
| 193 // let the button draw itself; catch all expose events to the button and pass | 220 // let the button draw itself; catch all expose events to the button and pass |
| 194 // them through to the label. | 221 // them through to the label. |
| 195 button->label = gtk_label_new(NULL); | 222 button->label = gtk_label_new(NULL); |
| 196 button->normal_markup = NULL; | 223 button->normal_markup = NULL; |
| 197 button->pressed_markup = NULL; | 224 button->pressed_markup = NULL; |
| 198 button->is_normal = TRUE; | 225 button->label_state = GTK_STATE_NORMAL; |
| 199 strncpy(button->normal_color, "blue", 9); | 226 strncpy(button->normal_color, "blue", 9); |
| 200 button->native_markup = NULL; | 227 button->native_markup = NULL; |
| 201 button->using_native_theme = TRUE; | 228 button->using_native_theme = TRUE; |
| 202 button->hand_cursor = gfx::GetCursor(GDK_HAND2); | 229 button->hand_cursor = gfx::GetCursor(GDK_HAND2); |
| 203 button->text = NULL; | 230 button->text = NULL; |
| 204 | 231 |
| 205 gtk_container_add(GTK_CONTAINER(button), button->label); | 232 gtk_container_add(GTK_CONTAINER(button), button->label); |
| 206 gtk_widget_set_app_paintable(GTK_WIDGET(button), TRUE); | 233 gtk_widget_set_app_paintable(GTK_WIDGET(button), TRUE); |
| 207 g_signal_connect(button, "realize", | 234 g_signal_connect(button, "realize", |
| 208 G_CALLBACK(gtk_chrome_link_button_set_text), NULL); | 235 G_CALLBACK(gtk_chrome_link_button_set_text), NULL); |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 258 strncpy(button->normal_color, "blue", 9); | 285 strncpy(button->normal_color, "blue", 9); |
| 259 } | 286 } |
| 260 | 287 |
| 261 gtk_chrome_link_button_set_text(button); | 288 gtk_chrome_link_button_set_text(button); |
| 262 | 289 |
| 263 if (gtk_widget_get_visible(GTK_WIDGET(button))) | 290 if (gtk_widget_get_visible(GTK_WIDGET(button))) |
| 264 gtk_widget_queue_draw(GTK_WIDGET(button)); | 291 gtk_widget_queue_draw(GTK_WIDGET(button)); |
| 265 } | 292 } |
| 266 | 293 |
| 267 G_END_DECLS | 294 G_END_DECLS |
| OLD | NEW |