| OLD | NEW |
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 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/gtk_chrome_link_button.h" | 5 #include "chrome/browser/gtk/gtk_chrome_link_button.h" |
| 6 | 6 |
| 7 #include <stdlib.h> | 7 #include <stdlib.h> |
| 8 | 8 |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "chrome/common/gtk_util.h" | 10 #include "chrome/common/gtk_util.h" |
| (...skipping 15 matching lines...) Expand all Loading... |
| 26 "style \"chrome-link-button\" {" | 26 "style \"chrome-link-button\" {" |
| 27 " GtkButton::inner-border = {0, 0, 0, 0}" | 27 " GtkButton::inner-border = {0, 0, 0, 0}" |
| 28 " GtkButton::child-displacement-x = 0" | 28 " GtkButton::child-displacement-x = 0" |
| 29 " GtkButton::child-displacement-y = 0" | 29 " GtkButton::child-displacement-y = 0" |
| 30 " xthickness = 0" | 30 " xthickness = 0" |
| 31 " ythickness = 0" | 31 " ythickness = 0" |
| 32 "}" | 32 "}" |
| 33 "widget_class \"*.<GtkChromeLinkButton>\" style \"chrome-link-button\""); | 33 "widget_class \"*.<GtkChromeLinkButton>\" style \"chrome-link-button\""); |
| 34 } | 34 } |
| 35 | 35 |
| 36 static void gtk_chrome_link_button_destroy_text_resources( |
| 37 GtkChromeLinkButton* button) { |
| 38 g_free(button->native_markup); |
| 39 button->native_markup = NULL; |
| 40 g_free(button->normal_markup); |
| 41 button->normal_markup = NULL; |
| 42 g_free(button->pressed_markup); |
| 43 button->pressed_markup = NULL; |
| 44 |
| 45 g_free(button->text); |
| 46 button->text = NULL; |
| 47 } |
| 48 |
| 36 } // namespace | 49 } // namespace |
| 37 | 50 |
| 38 G_BEGIN_DECLS | 51 G_BEGIN_DECLS |
| 39 G_DEFINE_TYPE(GtkChromeLinkButton, gtk_chrome_link_button, GTK_TYPE_BUTTON) | 52 G_DEFINE_TYPE(GtkChromeLinkButton, gtk_chrome_link_button, GTK_TYPE_BUTTON) |
| 40 | 53 |
| 41 // Should be called after we are realized so that the "link-color" property | 54 // Should be called after we are realized so that the "link-color" property |
| 42 // can be read. | 55 // can be read. |
| 43 static void gtk_chrome_link_button_set_text(GtkChromeLinkButton* button) { | 56 static void gtk_chrome_link_button_set_text(GtkChromeLinkButton* button) { |
| 44 // We only set the markup once. | 57 // We only set the markup once. |
| 45 if (button->normal_markup) | 58 if (button->normal_markup) |
| 46 return; | 59 return; |
| 47 | 60 |
| 48 gchar* text = button->text; | 61 gchar* text = button->text; |
| 49 gboolean uses_markup = button->uses_markup; | 62 gboolean uses_markup = button->uses_markup; |
| 50 | 63 |
| 51 if (!uses_markup) { | 64 if (!uses_markup) { |
| 52 button->normal_markup = g_markup_printf_escaped(kLinkMarkup, | 65 button->normal_markup = g_markup_printf_escaped(kLinkMarkup, |
| 53 button->normal_color, | 66 button->normal_color, |
| 54 text); | 67 text); |
| 55 button->pressed_markup = g_markup_printf_escaped(kLinkMarkup, "red", text); | 68 button->pressed_markup = g_markup_printf_escaped(kLinkMarkup, "red", text); |
| 56 } else { | 69 } else { |
| 57 int length = strlen(kLinkMarkup) + 9 + strlen(text) + 1; | 70 button->normal_markup = g_strdup_printf(kLinkMarkup, button->normal_color, |
| 58 button->normal_markup = static_cast<gchar*>(g_malloc(length)); | 71 text); |
| 59 snprintf(button->normal_markup, length, kLinkMarkup, button->normal_color, | |
| 60 text); | |
| 61 | 72 |
| 62 length = strlen(kLinkMarkup) + strlen("red") + strlen(text) + 1; | 73 button->pressed_markup = g_strdup_printf(kLinkMarkup, "red", text); |
| 63 button->pressed_markup = static_cast<gchar*>(g_malloc(length)); | |
| 64 snprintf(button->pressed_markup, length, kLinkMarkup, "red", text); | |
| 65 } | 74 } |
| 66 | 75 |
| 67 // Get the current GTK theme's link button text color. | 76 // Get the current GTK theme's link button text color. |
| 68 GdkColor* native_color = NULL; | 77 GdkColor* native_color = NULL; |
| 69 gtk_widget_style_get(GTK_WIDGET(button), "link-color", &native_color, NULL); | 78 gtk_widget_style_get(GTK_WIDGET(button), "link-color", &native_color, NULL); |
| 70 | 79 |
| 71 if (native_color) { | 80 if (native_color) { |
| 72 gchar color_spec[9]; | 81 gchar color_spec[9]; |
| 73 snprintf(color_spec, 9, "#%02X%02X%02X", native_color->red / 257, | 82 snprintf(color_spec, 9, "#%02X%02X%02X", native_color->red / 257, |
| 74 native_color->green / 257, native_color->blue / 257); | 83 native_color->green / 257, native_color->blue / 257); |
| 75 gdk_color_free(native_color); | 84 gdk_color_free(native_color); |
| 76 | 85 |
| 77 if (!uses_markup) { | 86 if (!uses_markup) { |
| 78 button->native_markup = g_markup_printf_escaped(kLinkMarkup, | 87 button->native_markup = g_markup_printf_escaped(kLinkMarkup, |
| 79 color_spec, text); | 88 color_spec, text); |
| 80 } else { | 89 } else { |
| 81 int length = strlen(kLinkMarkup) + strlen(color_spec) + strlen(text) + 1; | 90 button->native_markup = g_strdup_printf(kLinkMarkup, color_spec, text); |
| 82 button->native_markup = static_cast<gchar*>(g_malloc(length)); | |
| 83 snprintf(button->native_markup, length, kLinkMarkup, color_spec, text); | |
| 84 } | 91 } |
| 85 } else { | 92 } else { |
| 86 // If the theme doesn't have a link color, just use blue. This matches the | 93 // If the theme doesn't have a link color, just use blue. This matches the |
| 87 // default for GtkLinkButton. | 94 // default for GtkLinkButton. |
| 88 button->native_markup = button->normal_markup; | 95 button->native_markup = g_strdup(button->normal_markup); |
| 89 } | 96 } |
| 90 | 97 |
| 91 gtk_label_set_markup(GTK_LABEL(button->label), | 98 gtk_label_set_markup(GTK_LABEL(button->label), |
| 92 button->using_native_theme ? button->native_markup : | 99 button->using_native_theme ? button->native_markup : |
| 93 button->normal_markup); | 100 button->normal_markup); |
| 94 } | 101 } |
| 95 | 102 |
| 96 static gboolean gtk_chrome_link_button_expose(GtkWidget* widget, | 103 static gboolean gtk_chrome_link_button_expose(GtkWidget* widget, |
| 97 GdkEventExpose* event) { | 104 GdkEventExpose* event) { |
| 98 GtkChromeLinkButton* button = GTK_CHROME_LINK_BUTTON(widget); | 105 GtkChromeLinkButton* button = GTK_CHROME_LINK_BUTTON(widget); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 132 gdk_window_set_cursor(widget->window, link_button->hand_cursor); | 139 gdk_window_set_cursor(widget->window, link_button->hand_cursor); |
| 133 } | 140 } |
| 134 | 141 |
| 135 static void gtk_chrome_link_button_leave(GtkButton* button) { | 142 static void gtk_chrome_link_button_leave(GtkButton* button) { |
| 136 GtkWidget* widget = GTK_WIDGET(button); | 143 GtkWidget* widget = GTK_WIDGET(button); |
| 137 gdk_window_set_cursor(widget->window, NULL); | 144 gdk_window_set_cursor(widget->window, NULL); |
| 138 } | 145 } |
| 139 | 146 |
| 140 static void gtk_chrome_link_button_destroy(GtkObject* object) { | 147 static void gtk_chrome_link_button_destroy(GtkObject* object) { |
| 141 GtkChromeLinkButton* button = GTK_CHROME_LINK_BUTTON(object); | 148 GtkChromeLinkButton* button = GTK_CHROME_LINK_BUTTON(object); |
| 142 if (button->native_markup && (button->native_markup != button->normal_markup)) | 149 |
| 143 g_free(button->native_markup); | 150 gtk_chrome_link_button_destroy_text_resources(button); |
| 144 button->native_markup = NULL; | 151 |
| 145 if (button->normal_markup) { | |
| 146 g_free(button->normal_markup); | |
| 147 button->normal_markup = NULL; | |
| 148 } | |
| 149 if (button->pressed_markup) { | |
| 150 g_free(button->pressed_markup); | |
| 151 button->pressed_markup = NULL; | |
| 152 } | |
| 153 if (button->hand_cursor) { | 152 if (button->hand_cursor) { |
| 154 gdk_cursor_unref(button->hand_cursor); | 153 gdk_cursor_unref(button->hand_cursor); |
| 155 button->hand_cursor = NULL; | 154 button->hand_cursor = NULL; |
| 156 } | 155 } |
| 157 | 156 |
| 158 free(button->text); | |
| 159 button->text = NULL; | |
| 160 | |
| 161 GTK_OBJECT_CLASS(gtk_chrome_link_button_parent_class)->destroy(object); | 157 GTK_OBJECT_CLASS(gtk_chrome_link_button_parent_class)->destroy(object); |
| 162 } | 158 } |
| 163 | 159 |
| 164 static void gtk_chrome_link_button_class_init( | 160 static void gtk_chrome_link_button_class_init( |
| 165 GtkChromeLinkButtonClass* link_button_class) { | 161 GtkChromeLinkButtonClass* link_button_class) { |
| 166 GtkWidgetClass* widget_class = | 162 GtkWidgetClass* widget_class = |
| 167 reinterpret_cast<GtkWidgetClass*>(link_button_class); | 163 reinterpret_cast<GtkWidgetClass*>(link_button_class); |
| 168 GtkButtonClass* button_class = | 164 GtkButtonClass* button_class = |
| 169 reinterpret_cast<GtkButtonClass*>(link_button_class); | 165 reinterpret_cast<GtkButtonClass*>(link_button_class); |
| 170 GtkObjectClass* object_class = | 166 GtkObjectClass* object_class = |
| (...skipping 19 matching lines...) Expand all Loading... |
| 190 button->using_native_theme = TRUE; | 186 button->using_native_theme = TRUE; |
| 191 button->hand_cursor = gtk_util::GetCursor(GDK_HAND2); | 187 button->hand_cursor = gtk_util::GetCursor(GDK_HAND2); |
| 192 button->text = NULL; | 188 button->text = NULL; |
| 193 | 189 |
| 194 gtk_container_add(GTK_CONTAINER(button), button->label); | 190 gtk_container_add(GTK_CONTAINER(button), button->label); |
| 195 gtk_widget_set_app_paintable(GTK_WIDGET(button), TRUE); | 191 gtk_widget_set_app_paintable(GTK_WIDGET(button), TRUE); |
| 196 } | 192 } |
| 197 | 193 |
| 198 GtkWidget* gtk_chrome_link_button_new(const char* text) { | 194 GtkWidget* gtk_chrome_link_button_new(const char* text) { |
| 199 GtkWidget* lb = GTK_WIDGET(g_object_new(GTK_TYPE_CHROME_LINK_BUTTON, NULL)); | 195 GtkWidget* lb = GTK_WIDGET(g_object_new(GTK_TYPE_CHROME_LINK_BUTTON, NULL)); |
| 200 GTK_CHROME_LINK_BUTTON(lb)->text = strdup(text); | 196 GTK_CHROME_LINK_BUTTON(lb)->text = g_strdup(text); |
| 201 GTK_CHROME_LINK_BUTTON(lb)->uses_markup = FALSE; | 197 GTK_CHROME_LINK_BUTTON(lb)->uses_markup = FALSE; |
| 202 return lb; | 198 return lb; |
| 203 } | 199 } |
| 204 | 200 |
| 205 GtkWidget* gtk_chrome_link_button_new_with_markup(const char* markup) { | 201 GtkWidget* gtk_chrome_link_button_new_with_markup(const char* markup) { |
| 206 GtkWidget* lb = GTK_WIDGET(g_object_new(GTK_TYPE_CHROME_LINK_BUTTON, NULL)); | 202 GtkWidget* lb = GTK_WIDGET(g_object_new(GTK_TYPE_CHROME_LINK_BUTTON, NULL)); |
| 207 GTK_CHROME_LINK_BUTTON(lb)->text = strdup(markup); | 203 GTK_CHROME_LINK_BUTTON(lb)->text = g_strdup(markup); |
| 208 GTK_CHROME_LINK_BUTTON(lb)->uses_markup = TRUE; | 204 GTK_CHROME_LINK_BUTTON(lb)->uses_markup = TRUE; |
| 209 return lb; | 205 return lb; |
| 210 } | 206 } |
| 211 | 207 |
| 212 void gtk_chrome_link_button_set_use_gtk_theme(GtkChromeLinkButton* button, | 208 void gtk_chrome_link_button_set_use_gtk_theme(GtkChromeLinkButton* button, |
| 213 gboolean use_gtk) { | 209 gboolean use_gtk) { |
| 214 if (use_gtk != button->using_native_theme) { | 210 if (use_gtk != button->using_native_theme) { |
| 215 button->using_native_theme = use_gtk; | 211 button->using_native_theme = use_gtk; |
| 216 if (GTK_WIDGET_VISIBLE(button)) | 212 if (GTK_WIDGET_VISIBLE(button)) |
| 217 gtk_widget_queue_draw(GTK_WIDGET(button)); | 213 gtk_widget_queue_draw(GTK_WIDGET(button)); |
| 218 } | 214 } |
| 219 } | 215 } |
| 220 | 216 |
| 221 void gtk_chrome_link_button_set_label(GtkChromeLinkButton* button, | 217 void gtk_chrome_link_button_set_label(GtkChromeLinkButton* button, |
| 222 const char* text) { | 218 const char* text) { |
| 223 if (button->text) { | |
| 224 free(button->text); | |
| 225 } | |
| 226 button->text = strdup(text); | |
| 227 | |
| 228 // Clear the markup so we can redraw. | 219 // Clear the markup so we can redraw. |
| 229 if (button->native_markup && (button->native_markup != button->normal_markup)) | 220 gtk_chrome_link_button_destroy_text_resources(button); |
| 230 g_free(button->native_markup); | 221 button->text = g_strdup(text); |
| 231 button->native_markup = NULL; | |
| 232 if (button->normal_markup) { | |
| 233 g_free(button->normal_markup); | |
| 234 button->normal_markup = NULL; | |
| 235 } | |
| 236 if (button->pressed_markup) { | |
| 237 g_free(button->pressed_markup); | |
| 238 button->pressed_markup = NULL; | |
| 239 } | |
| 240 | 222 |
| 241 if (GTK_WIDGET_VISIBLE(button)) | 223 if (GTK_WIDGET_VISIBLE(button)) |
| 242 gtk_widget_queue_draw(GTK_WIDGET(button)); | 224 gtk_widget_queue_draw(GTK_WIDGET(button)); |
| 243 } | 225 } |
| 244 | 226 |
| 245 void gtk_chrome_link_button_set_normal_color(GtkChromeLinkButton* button, | 227 void gtk_chrome_link_button_set_normal_color(GtkChromeLinkButton* button, |
| 246 const GdkColor* color) { | 228 const GdkColor* color) { |
| 247 if (button->normal_markup) { | 229 g_free(button->normal_markup); |
| 248 g_free(button->normal_markup); | 230 button->normal_markup = NULL; |
| 249 button->normal_markup = NULL; | |
| 250 } | |
| 251 | 231 |
| 252 if (color) { | 232 if (color) { |
| 253 snprintf(button->normal_color, 9, "#%02X%02X%02X", color->red / 257, | 233 snprintf(button->normal_color, 9, "#%02X%02X%02X", color->red / 257, |
| 254 color->green / 257, color->blue / 257); | 234 color->green / 257, color->blue / 257); |
| 255 } else { | 235 } else { |
| 256 strncpy(button->normal_color, "blue", 9); | 236 strncpy(button->normal_color, "blue", 9); |
| 257 } | 237 } |
| 258 | 238 |
| 259 if (GTK_WIDGET_VISIBLE(button)) | 239 if (GTK_WIDGET_VISIBLE(button)) |
| 260 gtk_widget_queue_draw(GTK_WIDGET(button)); | 240 gtk_widget_queue_draw(GTK_WIDGET(button)); |
| 261 } | 241 } |
| 262 | 242 |
| 263 G_END_DECLS | 243 G_END_DECLS |
| OLD | NEW |