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

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

Issue 113590: Quick reimplementation of StatusBubbleGtk to not suck as much. (Closed)
Patch Set: (git cl uploads dirty tree state!?) Created 11 years, 7 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
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>
8
9 #include "base/gfx/gtk_util.h"
7 #include "base/string_util.h" 10 #include "base/string_util.h"
11 #include "chrome/browser/gtk/slide_animator_gtk.h"
12 #include "chrome/common/gtk_util.h"
8 #include "googleurl/src/gurl.h" 13 #include "googleurl/src/gurl.h"
9 14
10 // NOTE: this code is probably the wrong approach for the status bubble. 15 namespace {
11 // Talk to evanm before you attempt to fix bugs in it -- we're probably
12 // better off restructuring it.
13 16
14 StatusBubbleGtk::StatusBubbleGtk(GtkWindow* parent) 17 const GdkColor kBackgroundColor = GDK_COLOR_RGB(0xe6, 0xed, 0xf4);
15 : parent_(parent), window_(NULL) { 18 const GdkColor kFrameBorderColor = GDK_COLOR_RGB(0xbe, 0xc8, 0xd4);
19
20 // Inner padding between the border and the text label.
21 const int kInternalTopBottomPadding = 1;
22 const int kInternalLeftRightPadding = 2;
23
24 // Border of color kFrameBorderColor around the status bubble.
25 const int kBorderPadding = 1;
26
27 } // namespace
28
29 StatusBubbleGtk::StatusBubbleGtk()
30 : parent_(NULL) {
31 InitWidgets();
16 } 32 }
17 33
18 StatusBubbleGtk::~StatusBubbleGtk() { 34 StatusBubbleGtk::~StatusBubbleGtk() {
19 Hide(); 35 container_.Destroy();
20 } 36 }
21 37
22 void StatusBubbleGtk::SetStatus(const std::string& status) { 38 void StatusBubbleGtk::SetStatus(const std::string& status) {
23 if (status.empty()) { 39 if (status.empty()) {
24 Hide(); 40 Hide();
25 return; 41 return;
26 } 42 }
27 43
28 if (!window_) 44 gtk_label_set_text(GTK_LABEL(label_), status.c_str());
29 Create();
30 45
31 gtk_label_set_text(GTK_LABEL(label_), status.c_str()); 46 Show();
32 Reposition();
33 gtk_widget_show(window_);
34 } 47 }
35 48
36 void StatusBubbleGtk::SetStatus(const std::wstring& status) { 49 void StatusBubbleGtk::SetStatus(const std::wstring& status) {
37 SetStatus(WideToUTF8(status)); 50 SetStatus(WideToUTF8(status));
38 } 51 }
39 52
53 void StatusBubbleGtk::SetParentAllocation(
54 GtkWidget* parent, GtkAllocation* allocation) {
55 parent_ = parent;
56 parent_allocation_ = *allocation;
57 SetStatusBubbleSize();
58 }
59
40 void StatusBubbleGtk::SetURL(const GURL& url, const std::wstring& languages) { 60 void StatusBubbleGtk::SetURL(const GURL& url, const std::wstring& languages) {
41 SetStatus(url.possibly_invalid_spec()); 61 SetStatus(url.possibly_invalid_spec());
42 } 62 }
43 63
64 void StatusBubbleGtk::Show() {
65 SetStatusBubbleSize();
66 gtk_widget_show_all(container_.get());
67
68 if (container_.get()->window)
69 gdk_window_raise(container_.get()->window);
70 }
71
44 void StatusBubbleGtk::Hide() { 72 void StatusBubbleGtk::Hide() {
45 if (!window_) 73 gtk_widget_hide_all(container_.get());
46 return; 74 }
47 gtk_widget_destroy(window_); 75
48 window_ = NULL; 76 void StatusBubbleGtk::SetStatusBubbleSize() {
77 if (parent_) {
78 GtkRequisition requisition;
79 gtk_widget_size_request(container_.get(), &requisition);
80
81 // TODO(erg): Previously, I put a call to gtk_fixed_put() here. It appears
82 // that doing this sets off a size-allocate storm, since gtk_fixed_put()
83 // calls gtk_widget_queue_resize on the GtkFixed that caused this message.
84 // The real solution may be creating a subclass of GtkVBox that has extra
85 // code to deal with floating widgets, but this hack is good enough for
86 // Friday. evanm says that there's a a GtkFixed subclass in test_shell that
87 // we'll be stealing for plugin support anyway that should also do the same
88 // task.
89
90 GtkAllocation widget_allocation;
91 int child_y = std::max(
92 parent_allocation_.y + parent_allocation_.height - requisition.height,
93 0);
94 widget_allocation.x = 0;
95 widget_allocation.y = child_y;
96 widget_allocation.width = std::min(requisition.width,
97 parent_allocation_.width);
98 widget_allocation.height = requisition.height;
99 gtk_widget_size_allocate(container_.get(), &widget_allocation);
100 }
49 } 101 }
50 102
51 void StatusBubbleGtk::MouseMoved() { 103 void StatusBubbleGtk::MouseMoved() {
52 if (!window_) 104 // We can't do that fancy sliding behaviour where the status bubble slides
53 return; 105 // out of the window because the window manager gets in the way. So totally
54 // We ignore for now. 106 // ignore this message for now.
55 // TODO(port): the fancy sliding behavior. 107 //
108 // TODO(erg): At least get some sliding behaviour so that it slides out of
109 // the way to hide the status bubble on mouseover.
56 } 110 }
57 111
58 void StatusBubbleGtk::Create() { 112 void StatusBubbleGtk::InitWidgets() {
59 if (window_) 113 label_ = gtk_label_new(NULL);
60 return;
61 114
62 window_ = gtk_window_new(GTK_WINDOW_POPUP); 115 GtkWidget* padding = gtk_alignment_new(0, 0, 1, 1);
63 gtk_window_set_transient_for(GTK_WINDOW(window_), parent_); 116 gtk_alignment_set_padding(GTK_ALIGNMENT(padding),
64 gtk_container_set_border_width(GTK_CONTAINER(window_), 2); 117 kInternalTopBottomPadding, kInternalTopBottomPadding,
65 label_ = gtk_label_new(""); 118 kInternalLeftRightPadding, kInternalLeftRightPadding);
66 gtk_widget_show(label_); 119 gtk_container_add(GTK_CONTAINER(padding), label_);
67 gtk_container_add(GTK_CONTAINER(window_), label_); 120
121 GtkWidget* bg_box = gtk_event_box_new();
122 gtk_container_add(GTK_CONTAINER(bg_box), padding);
123 gtk_widget_modify_bg(bg_box, GTK_STATE_NORMAL, &kBackgroundColor);
124
125 container_.Own(gtk_util::CreateGtkBorderBin(bg_box, &kFrameBorderColor,
126 kBorderPadding, kBorderPadding, kBorderPadding, kBorderPadding));
127 gtk_widget_set_name(container_.get(), "status-bubble");
128 gtk_widget_set_app_paintable(container_.get(), TRUE);
Evan Stade 2009/05/19 23:41:25 why app paintable?
68 } 129 }
69
70 void StatusBubbleGtk::Reposition() {
71 int x, y, width, parent_height;
72 gdk_window_get_position(GTK_WIDGET(parent_)->window, &x, &y);
73 gtk_window_get_size(parent_, &width, &parent_height);
74 GtkRequisition requisition;
75 gtk_widget_size_request(window_, &requisition);
76 // TODO(port): RTL positioning.
77 gtk_window_move(GTK_WINDOW(window_), x,
78 y + parent_height - requisition.height);
79 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698