Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1264)

Side by Side Diff: chrome/browser/gtk/status_bubble_gtk.cc

Issue 164010: GTK: Rounded corner on status bubble. (Closed)
Patch Set: Completely different implementation based on region instead of mask Created 11 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « chrome/browser/gtk/status_bubble_gtk.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/status_bubble_gtk.h" 5 #include "chrome/browser/gtk/status_bubble_gtk.h"
6 6
7 #include <gtk/gtk.h> 7 #include <gtk/gtk.h>
8 8
9 #include "app/gfx/text_elider.h" 9 #include "app/gfx/text_elider.h"
10 #include "app/l10n_util.h"
10 #include "base/gfx/gtk_util.h" 11 #include "base/gfx/gtk_util.h"
11 #include "base/message_loop.h" 12 #include "base/message_loop.h"
12 #include "base/string_util.h" 13 #include "base/string_util.h"
13 #include "chrome/browser/gtk/gtk_theme_provider.h" 14 #include "chrome/browser/gtk/gtk_theme_provider.h"
14 #include "chrome/browser/gtk/slide_animator_gtk.h" 15 #include "chrome/browser/gtk/slide_animator_gtk.h"
15 #include "chrome/common/gtk_util.h" 16 #include "chrome/common/gtk_util.h"
16 #include "chrome/common/notification_service.h" 17 #include "chrome/common/notification_service.h"
17 #include "googleurl/src/gurl.h" 18 #include "googleurl/src/gurl.h"
18 19
19 namespace { 20 namespace {
20 21
21 const GdkColor kTextColor = GDK_COLOR_RGB(100, 100, 100);
22 const GdkColor kBackgroundColor = GDK_COLOR_RGB(0xe6, 0xed, 0xf4);
23 const GdkColor kFrameBorderColor = GDK_COLOR_RGB(0xbe, 0xc8, 0xd4); 22 const GdkColor kFrameBorderColor = GDK_COLOR_RGB(0xbe, 0xc8, 0xd4);
24 23
25 // Inner padding between the border and the text label. 24 // Inner padding between the border and the text label.
26 const int kInternalTopBottomPadding = 1; 25 const int kInternalTopBottomPadding = 1;
27 const int kInternalLeftRightPadding = 2; 26 const int kInternalLeftRightPadding = 2;
28 27
29 // Border of color kFrameBorderColor around the status bubble. 28 // The roundedness of the edges of our bubble.
Evan Martin 2009/08/06 18:05:38 roundedness = radius, right?
30 const int kBorderPadding = 1; 29 const int kCornerSize = 4;
31 30
32 // Milliseconds before we hide the status bubble widget when you mouseout. 31 // Milliseconds before we hide the status bubble widget when you mouseout.
33 static const int kHideDelay = 250; 32 const int kHideDelay = 250;
33
34 // Number of times that the background color should be counted when trying to
35 // calculate the border color in GTK theme mode.
36 const int kBgWeight = 3;
37
38 GdkPoint MakeBidiGdkPoint(gint x, gint y, gint width, bool ltr) {
Evan Martin 2009/08/06 18:05:38 docs on all functions
39 GdkPoint point = {ltr ? x : width - x, y};
40 return point;
41 }
42
43 enum FrameType {
44 FRAME_MASK,
45 FRAME_STROKE,
46 };
47
48 std::vector<GdkPoint> MakeFramePolygonPoints(int width,
49 int height,
50 FrameType type) {
51 std::vector<GdkPoint> points;
52
53 bool ltr = l10n_util::GetTextDirection() == l10n_util::LEFT_TO_RIGHT;
54 // If we have a stroke, we have to offset some of our points by 1 pixel.
55 // We have to inset by 1 pixel when we draw horizontal lines that are on the
56 // bottom or when we draw vertical lines that are closer to the end (end is
57 // right for ltr).
58 int y_off = (type == FRAME_MASK) ? 0 : -1;
59 // We use this one for LTR.
60 int x_off_l = ltr ? y_off : 0;
61
62 // Top left corner.
63 points.push_back(MakeBidiGdkPoint(0, 0, width, ltr));
64
65 // Top right (rounded) corner.
66 points.push_back(MakeBidiGdkPoint(
67 width - kCornerSize + 1 + x_off_l, 0, width, ltr));
68 points.push_back(MakeBidiGdkPoint(
69 width + x_off_l, kCornerSize - 1, width, ltr));
70
71 // Bottom right corner.
72 points.push_back(MakeBidiGdkPoint(
73 width + x_off_l, height + y_off, width, ltr));
74
75 if (type == FRAME_MASK) {
76 // Bottom left corner.
77 points.push_back(MakeBidiGdkPoint(0, height + y_off, width, ltr));
78 }
79
80 return points;
81 }
34 82
35 } // namespace 83 } // namespace
36 84
37 StatusBubbleGtk::StatusBubbleGtk(Profile* profile) 85 StatusBubbleGtk::StatusBubbleGtk(Profile* profile)
38 : theme_provider_(GtkThemeProvider::GetFrom(profile)), 86 : theme_provider_(GtkThemeProvider::GetFrom(profile)),
39 timer_factory_(this) { 87 timer_factory_(this) {
40 InitWidgets(); 88 InitWidgets();
41 89
42 registrar_.Add(this, NotificationType::BROWSER_THEME_CHANGED, 90 registrar_.Add(this, NotificationType::BROWSER_THEME_CHANGED,
43 NotificationService::AllSources()); 91 NotificationService::AllSources());
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
131 UserChangedTheme(); 179 UserChangedTheme();
132 } 180 }
133 } 181 }
134 182
135 void StatusBubbleGtk::InitWidgets() { 183 void StatusBubbleGtk::InitWidgets() {
136 label_ = gtk_label_new(NULL); 184 label_ = gtk_label_new(NULL);
137 185
138 GtkWidget* padding = gtk_alignment_new(0, 0, 1, 1); 186 GtkWidget* padding = gtk_alignment_new(0, 0, 1, 1);
139 gtk_alignment_set_padding(GTK_ALIGNMENT(padding), 187 gtk_alignment_set_padding(GTK_ALIGNMENT(padding),
140 kInternalTopBottomPadding, kInternalTopBottomPadding, 188 kInternalTopBottomPadding, kInternalTopBottomPadding,
141 kInternalLeftRightPadding, kInternalLeftRightPadding); 189 kInternalLeftRightPadding,
190 kInternalLeftRightPadding + kCornerSize);
142 gtk_container_add(GTK_CONTAINER(padding), label_); 191 gtk_container_add(GTK_CONTAINER(padding), label_);
143 192
144 bg_box_ = gtk_event_box_new(); 193 container_.Own(gtk_event_box_new());
145 gtk_container_add(GTK_CONTAINER(bg_box_), padding);
146
147 container_.Own(gtk_util::CreateGtkBorderBin(bg_box_, &kFrameBorderColor,
148 kBorderPadding, kBorderPadding, kBorderPadding, kBorderPadding));
149 gtk_widget_set_name(container_.get(), "status-bubble"); 194 gtk_widget_set_name(container_.get(), "status-bubble");
195 gtk_container_add(GTK_CONTAINER(container_.get()), padding);
150 gtk_widget_set_app_paintable(container_.get(), TRUE); 196 gtk_widget_set_app_paintable(container_.get(), TRUE);
197 g_signal_connect(G_OBJECT(container_.get()), "expose-event",
198 G_CALLBACK(OnExpose), this);
199 g_signal_connect(G_OBJECT(container_.get()), "size-allocate",
200 G_CALLBACK(OnSizeAllocate), this);
151 201
152 UserChangedTheme(); 202 UserChangedTheme();
153 } 203 }
154 204
155 void StatusBubbleGtk::UserChangedTheme() { 205 void StatusBubbleGtk::UserChangedTheme() {
156 if (theme_provider_->UseGtkTheme()) { 206 if (theme_provider_->UseGtkTheme()) {
157 gtk_widget_modify_fg(label_, GTK_STATE_NORMAL, NULL); 207 gtk_widget_modify_fg(label_, GTK_STATE_NORMAL, NULL);
158 gtk_widget_modify_bg(bg_box_, GTK_STATE_NORMAL, NULL); 208 gtk_widget_modify_bg(container_.get(), GTK_STATE_NORMAL, NULL);
209
210 // Creates a weighted average between the text and base color where
211 // the base color counts twice.
Evan Martin 2009/08/06 18:05:38 clever!
212 GtkStyle* style = gtk_rc_get_style(container_.get());
213 border_color_.pixel = 0;
214 border_color_.red = (style->text[GTK_STATE_NORMAL].red +
215 (style->bg[GTK_STATE_NORMAL].red * kBgWeight)) /
216 (1 + kBgWeight);
217 border_color_.green = (style->text[GTK_STATE_NORMAL].green +
218 (style->bg[GTK_STATE_NORMAL].green * kBgWeight)) /
219 (1 + kBgWeight);
220 border_color_.blue = (style->text[GTK_STATE_NORMAL].blue +
221 (style->bg[GTK_STATE_NORMAL].blue * kBgWeight)) /
222 (1 + kBgWeight);
159 } else { 223 } else {
160 // TODO(erg): This is the closest to "text that will look good on a 224 // TODO(erg): This is the closest to "text that will look good on a
161 // toolbar" that I can find. Maybe in later iterations of the theme system, 225 // toolbar" that I can find. Maybe in later iterations of the theme system,
162 // there will be a better color to pick. 226 // there will be a better color to pick.
163 GdkColor bookmark_text = 227 GdkColor bookmark_text =
164 theme_provider_->GetGdkColor(BrowserThemeProvider::COLOR_BOOKMARK_TEXT); 228 theme_provider_->GetGdkColor(BrowserThemeProvider::COLOR_BOOKMARK_TEXT);
165 gtk_widget_modify_fg(label_, GTK_STATE_NORMAL, &bookmark_text); 229 gtk_widget_modify_fg(label_, GTK_STATE_NORMAL, &bookmark_text);
166 230
167 GdkColor toolbar_color = 231 GdkColor toolbar_color =
168 theme_provider_->GetGdkColor(BrowserThemeProvider::COLOR_TOOLBAR); 232 theme_provider_->GetGdkColor(BrowserThemeProvider::COLOR_TOOLBAR);
169 gtk_widget_modify_bg(bg_box_, GTK_STATE_NORMAL, &toolbar_color); 233 gtk_widget_modify_bg(container_.get(), GTK_STATE_NORMAL, &toolbar_color);
234
235 border_color_ = kFrameBorderColor;
170 } 236 }
237 }
171 238
172 // TODO(erg): I don't know what to do with the status bubble border 239 // static
173 // (|container_|). There needs to be a border in GTK mode, and I'm not sure 240 gboolean StatusBubbleGtk::OnExpose(GtkWidget* widget,
174 // which BrowserThemeProvider::COLOR I'm supposed to use here since the Views 241 GdkEventExpose* event,
175 // implementation still uses constants in the equivalent, and it's used for 242 StatusBubbleGtk* bubble) {
176 // alpha blending instead of drawing a real border. 243 GdkDrawable* drawable = GDK_DRAWABLE(event->window);
177 // 244 GdkGC* gc = gdk_gc_new(drawable);
178 // This doesn't really matter because this part of the UI needs to be 245 gdk_gc_set_rgb_fg_color(gc, &bubble->border_color_);
179 // rewritten per the UI review anyway; we should be matching windows with a 246
180 // semi-transparent, rounded border instead of our constantly 247 // Stroke the frame border.
181 // CreateGtkBorderBin() usage. 248 std::vector<GdkPoint> points = MakeFramePolygonPoints(
249 widget->allocation.width, widget->allocation.height, FRAME_STROKE);
250 gdk_draw_lines(drawable, gc, &points[0], points.size());
251
252 g_object_unref(gc);
253 return FALSE; // Propagate so our children paint, etc.
182 } 254 }
255
256 // static
257 void StatusBubbleGtk::OnSizeAllocate(GtkWidget* widget,
258 GtkAllocation* allocation,
259 StatusBubbleGtk* bubble) {
Evan Martin 2009/08/06 18:05:38 Does this get called only when the allocation chan
260 std::vector<GdkPoint> points = MakeFramePolygonPoints(
261 widget->allocation.width, widget->allocation.height, FRAME_MASK);
262 GdkRegion* mask_region = gdk_region_polygon(&points[0],
263 points.size(),
264 GDK_EVEN_ODD_RULE);
265 gdk_window_shape_combine_region(widget->window, mask_region, 0, 0);
266 gdk_region_destroy(mask_region);
267 }
OLDNEW
« no previous file with comments | « chrome/browser/gtk/status_bubble_gtk.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698