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/find_bar_gtk.h" | 5 #include "chrome/browser/gtk/find_bar_gtk.h" |
6 | 6 |
7 #include <gdk/gdkkeysyms.h> | 7 #include <gdk/gdkkeysyms.h> |
8 | 8 |
9 #include "base/gfx/gtk_util.h" | 9 #include "base/gfx/gtk_util.h" |
10 #include "base/string_util.h" | 10 #include "base/string_util.h" |
11 #include "chrome/browser/find_bar_controller.h" | 11 #include "chrome/browser/find_bar_controller.h" |
12 #include "chrome/browser/gtk/browser_window_gtk.h" | 12 #include "chrome/browser/gtk/browser_window_gtk.h" |
13 #include "chrome/browser/gtk/custom_button.h" | 13 #include "chrome/browser/gtk/custom_button.h" |
14 #include "chrome/browser/gtk/tab_contents_container_gtk.h" | 14 #include "chrome/browser/gtk/tab_contents_container_gtk.h" |
15 #include "chrome/browser/tab_contents/web_contents.h" | 15 #include "chrome/browser/tab_contents/web_contents.h" |
16 #include "chrome/common/gtk_util.h" | 16 #include "chrome/common/gtk_util.h" |
17 #include "chrome/common/l10n_util.h" | 17 #include "chrome/common/l10n_util.h" |
18 #include "grit/generated_resources.h" | 18 #include "grit/generated_resources.h" |
19 | 19 |
20 namespace { | 20 namespace { |
21 | 21 |
22 const GdkColor kBackgroundColor = GDK_COLOR_RGB(0xe6, 0xed, 0xf4); | 22 const GdkColor kBackgroundColor = GDK_COLOR_RGB(0xe6, 0xed, 0xf4); |
23 const GdkColor kBorderColor = GDK_COLOR_RGB(0xbe, 0xc8, 0xd4); | 23 const GdkColor kBorderColor = GDK_COLOR_RGB(0xbe, 0xc8, 0xd4); |
24 | 24 |
25 // Padding around the container. | 25 // Padding around the container. |
26 const int kBarPadding = 4; | 26 const int kBarPadding = 4; |
27 | 27 |
| 28 // The vertical positioning of |container_| in |fixed_|. |
| 29 const int kVerticalOffset = -1; |
| 30 |
28 gboolean EntryContentsChanged(GtkWindow* window, FindBarGtk* find_bar) { | 31 gboolean EntryContentsChanged(GtkWindow* window, FindBarGtk* find_bar) { |
29 find_bar->ContentsChanged(); | 32 find_bar->ContentsChanged(); |
30 return FALSE; | 33 return FALSE; |
31 } | 34 } |
32 | 35 |
33 gboolean KeyPressEvent(GtkWindow* window, GdkEventKey* event, | 36 gboolean KeyPressEvent(GtkWindow* window, GdkEventKey* event, |
34 FindBarGtk* find_bar) { | 37 FindBarGtk* find_bar) { |
35 if (GDK_Escape == event->keyval) { | 38 if (GDK_Escape == event->keyval) { |
36 find_bar->EscapePressed(); | 39 find_bar->EscapePressed(); |
37 return TRUE; | 40 return TRUE; |
38 } | 41 } |
39 return FALSE; | 42 return FALSE; |
40 } | 43 } |
41 | 44 |
42 } | 45 } |
43 | 46 |
44 FindBarGtk::FindBarGtk(BrowserWindowGtk* browser) { | 47 FindBarGtk::FindBarGtk(BrowserWindowGtk* browser) { |
45 InitWidgets(); | 48 InitWidgets(); |
46 | 49 |
47 // Insert the widget into the browser gtk hierarchy. | 50 // Insert the widget into the browser gtk hierarchy. |
48 browser->AddFindBar(container_.get()); | 51 browser->AddFindBar(this); |
49 | 52 |
50 // Hook up signals after the widget has been added to the hierarchy so the | 53 // Hook up signals after the widget has been added to the hierarchy so the |
51 // widget will be realized. | 54 // widget will be realized. |
52 g_signal_connect(G_OBJECT(find_text_), "changed", | 55 g_signal_connect(find_text_, "changed", |
53 G_CALLBACK(EntryContentsChanged), this); | 56 G_CALLBACK(EntryContentsChanged), this); |
54 g_signal_connect(G_OBJECT(find_text_), "key-press-event", | 57 g_signal_connect(find_text_, "key-press-event", |
55 G_CALLBACK(KeyPressEvent), this); | 58 G_CALLBACK(KeyPressEvent), this); |
| 59 g_signal_connect(widget(), "size-allocate", |
| 60 G_CALLBACK(OnSizeAllocate), this); |
56 } | 61 } |
57 | 62 |
58 FindBarGtk::~FindBarGtk() { | 63 FindBarGtk::~FindBarGtk() { |
59 container_.Destroy(); | 64 fixed_.Destroy(); |
60 } | 65 } |
61 | 66 |
62 void FindBarGtk::InitWidgets() { | 67 void FindBarGtk::InitWidgets() { |
63 // The find bar is basically an hbox with a gtkentry (text box) followed by 3 | 68 // The find bar is basically an hbox with a gtkentry (text box) followed by 3 |
64 // buttons (previous result, next result, close). We wrap the hbox in a gtk | 69 // buttons (previous result, next result, close). We wrap the hbox in a gtk |
65 // alignment and a gtk event box to get the padding and light blue | 70 // alignment and a gtk event box to get the padding and light blue |
66 // background. | 71 // background. We put that event box in a fixed in order to control its |
| 72 // position. |
67 GtkWidget* hbox = gtk_hbox_new(false, 0); | 73 GtkWidget* hbox = gtk_hbox_new(false, 0); |
68 container_.Own(gfx::CreateGtkBorderBin(hbox, &kBackgroundColor, kBarPadding, | 74 container_ = gfx::CreateGtkBorderBin(hbox, &kBackgroundColor, |
69 kBarPadding, kBarPadding, kBarPadding)); | 75 kBarPadding, kBarPadding, kBarPadding, kBarPadding); |
| 76 fixed_.Own(gtk_fixed_new()); |
| 77 |
| 78 // |fixed_| has to be at least one pixel tall. We color this pixel the same |
| 79 // color as the border that separates the toolbar from the web contents. |
| 80 // TODO(estade): find a better solution. (Ideally the tool bar shouldn't draw |
| 81 // its own border, but the border is part of the background bitmap, so |
| 82 // changing that would affect all platforms.) |
| 83 border_ = gtk_event_box_new(); |
| 84 gtk_widget_set_size_request(border_, 1, 1); |
| 85 gtk_widget_modify_bg(border_, GTK_STATE_NORMAL, &kBorderColor); |
| 86 |
| 87 gtk_fixed_put(GTK_FIXED(widget()), border_, 0, 0); |
| 88 gtk_fixed_put(GTK_FIXED(widget()), container_, 0, kVerticalOffset); |
| 89 gtk_widget_set_size_request(widget(), -1, 0); |
70 | 90 |
71 close_button_.reset(CustomDrawButton::AddBarCloseButton(hbox)); | 91 close_button_.reset(CustomDrawButton::AddBarCloseButton(hbox)); |
72 g_signal_connect(G_OBJECT(close_button_->widget()), "clicked", | 92 g_signal_connect(G_OBJECT(close_button_->widget()), "clicked", |
73 G_CALLBACK(OnButtonPressed), this); | 93 G_CALLBACK(OnButtonPressed), this); |
74 gtk_widget_set_tooltip_text(close_button_->widget(), | 94 gtk_widget_set_tooltip_text(close_button_->widget(), |
75 l10n_util::GetStringUTF8(IDS_FIND_IN_PAGE_CLOSE_TOOLTIP).c_str()); | 95 l10n_util::GetStringUTF8(IDS_FIND_IN_PAGE_CLOSE_TOOLTIP).c_str()); |
76 | 96 |
77 find_next_button_.reset(new CustomDrawButton(IDR_FINDINPAGE_NEXT, | 97 find_next_button_.reset(new CustomDrawButton(IDR_FINDINPAGE_NEXT, |
78 IDR_FINDINPAGE_NEXT_H, IDR_FINDINPAGE_NEXT_H, IDR_FINDINPAGE_NEXT_P)); | 98 IDR_FINDINPAGE_NEXT_H, IDR_FINDINPAGE_NEXT_H, IDR_FINDINPAGE_NEXT_P)); |
79 g_signal_connect(G_OBJECT(find_next_button_->widget()), "clicked", | 99 g_signal_connect(G_OBJECT(find_next_button_->widget()), "clicked", |
(...skipping 15 matching lines...) Expand all Loading... |
95 find_text_ = gtk_entry_new(); | 115 find_text_ = gtk_entry_new(); |
96 // Force the text widget height so it lines up with the buttons regardless of | 116 // Force the text widget height so it lines up with the buttons regardless of |
97 // font size. | 117 // font size. |
98 gtk_widget_set_size_request(find_text_, -1, 20); | 118 gtk_widget_set_size_request(find_text_, -1, 20); |
99 gtk_entry_set_has_frame(GTK_ENTRY(find_text_), FALSE); | 119 gtk_entry_set_has_frame(GTK_ENTRY(find_text_), FALSE); |
100 GtkWidget* border_bin = gfx::CreateGtkBorderBin(find_text_, &kBorderColor, | 120 GtkWidget* border_bin = gfx::CreateGtkBorderBin(find_text_, &kBorderColor, |
101 1, 1, 1, 0); | 121 1, 1, 1, 0); |
102 GtkWidget* centering_vbox = gtk_vbox_new(FALSE, 0); | 122 GtkWidget* centering_vbox = gtk_vbox_new(FALSE, 0); |
103 gtk_box_pack_start(GTK_BOX(centering_vbox), border_bin, TRUE, FALSE, 0); | 123 gtk_box_pack_start(GTK_BOX(centering_vbox), border_bin, TRUE, FALSE, 0); |
104 gtk_box_pack_end(GTK_BOX(hbox), centering_vbox, FALSE, FALSE, 0); | 124 gtk_box_pack_end(GTK_BOX(hbox), centering_vbox, FALSE, FALSE, 0); |
| 125 |
| 126 // We show just the GtkFixed and |border_| (not |container_|). |
| 127 gtk_widget_show(widget()); |
| 128 gtk_widget_show(border_); |
105 } | 129 } |
106 | 130 |
107 void FindBarGtk::Show() { | 131 void FindBarGtk::Show() { |
108 // TODO(tc): This should be an animated slide in. | 132 // TODO(tc): This should be an animated slide in. |
109 gtk_widget_show_all(container_.get()); | 133 gtk_widget_show_all(widget()); |
110 gtk_widget_grab_focus(find_text_); | 134 gtk_widget_grab_focus(find_text_); |
111 } | 135 } |
112 | 136 |
113 void FindBarGtk::Hide(bool animate) { | 137 void FindBarGtk::Hide(bool animate) { |
114 // TODO(tc): Animated slide away. | 138 // TODO(tc): Animated slide away. |
115 gtk_widget_hide(container_.get()); | 139 gtk_widget_hide(container_); |
116 } | 140 } |
117 | 141 |
118 void FindBarGtk::SetFocusAndSelection() { | 142 void FindBarGtk::SetFocusAndSelection() { |
119 gtk_widget_grab_focus(find_text_); | 143 gtk_widget_grab_focus(find_text_); |
120 // Select all the text. | 144 // Select all the text. |
121 gtk_entry_select_region(GTK_ENTRY(find_text_), 0, -1); | 145 gtk_entry_select_region(GTK_ENTRY(find_text_), 0, -1); |
122 } | 146 } |
123 | 147 |
124 void FindBarGtk::ClearResults(const FindNotificationDetails& results) { | 148 void FindBarGtk::ClearResults(const FindNotificationDetails& results) { |
125 } | 149 } |
(...skipping 10 matching lines...) Expand all Loading... |
136 void FindBarGtk::SetFindText(const string16& find_text) { | 160 void FindBarGtk::SetFindText(const string16& find_text) { |
137 std::string find_text_utf8 = UTF16ToUTF8(find_text); | 161 std::string find_text_utf8 = UTF16ToUTF8(find_text); |
138 gtk_entry_set_text(GTK_ENTRY(find_text_), find_text_utf8.c_str()); | 162 gtk_entry_set_text(GTK_ENTRY(find_text_), find_text_utf8.c_str()); |
139 } | 163 } |
140 | 164 |
141 void FindBarGtk::UpdateUIForFindResult(const FindNotificationDetails& result, | 165 void FindBarGtk::UpdateUIForFindResult(const FindNotificationDetails& result, |
142 const string16& find_text) { | 166 const string16& find_text) { |
143 } | 167 } |
144 | 168 |
145 gfx::Rect FindBarGtk::GetDialogPosition(gfx::Rect avoid_overlapping_rect) { | 169 gfx::Rect FindBarGtk::GetDialogPosition(gfx::Rect avoid_overlapping_rect) { |
146 return gfx::Rect(); | 170 // TODO(estade): Logic for the positioning of the find bar should be factored |
| 171 // out of here and browser/views/* and into FindBarController. |
| 172 int xposition = widget()->allocation.width - container_->allocation.width - |
| 173 50; |
| 174 |
| 175 return gfx::Rect(xposition, 0, 1, 1); |
147 } | 176 } |
148 | 177 |
149 void FindBarGtk::SetDialogPosition(const gfx::Rect& new_pos, bool no_redraw) { | 178 void FindBarGtk::SetDialogPosition(const gfx::Rect& new_pos, bool no_redraw) { |
150 if (!IsFindBarVisible()) | 179 gtk_fixed_move(GTK_FIXED(widget()), container_, new_pos.x(), kVerticalOffset); |
151 Show(); // TODO(tc): This should be a no animation show. | |
152 } | 180 } |
153 | 181 |
154 bool FindBarGtk::IsFindBarVisible() { | 182 bool FindBarGtk::IsFindBarVisible() { |
155 return GTK_WIDGET_VISIBLE(container_.get()); | 183 return GTK_WIDGET_VISIBLE(widget()); |
156 } | 184 } |
157 | 185 |
158 void FindBarGtk::RestoreSavedFocus() { | 186 void FindBarGtk::RestoreSavedFocus() { |
159 } | 187 } |
160 | 188 |
161 FindBarTesting* FindBarGtk::GetFindBarTesting() { | 189 FindBarTesting* FindBarGtk::GetFindBarTesting() { |
162 return this; | 190 return this; |
163 } | 191 } |
164 | 192 |
165 bool FindBarGtk::GetFindBarWindowInfo(gfx::Point* position, | 193 bool FindBarGtk::GetFindBarWindowInfo(gfx::Point* position, |
166 bool* fully_visible) { | 194 bool* fully_visible) { |
167 NOTIMPLEMENTED(); | 195 NOTIMPLEMENTED(); |
168 return false; | 196 return false; |
169 } | 197 } |
170 | 198 |
| 199 void FindBarGtk::AssureOnTop() { |
| 200 gtk_widget_hide(container_); |
| 201 gtk_widget_show_all(container_); |
| 202 } |
| 203 |
171 void FindBarGtk::ContentsChanged() { | 204 void FindBarGtk::ContentsChanged() { |
172 WebContents* web_contents = find_bar_controller_->web_contents(); | 205 WebContents* web_contents = find_bar_controller_->web_contents(); |
173 if (!web_contents) | 206 if (!web_contents) |
174 return; | 207 return; |
175 | 208 |
176 std::string new_contents(gtk_entry_get_text(GTK_ENTRY(find_text_))); | 209 std::string new_contents(gtk_entry_get_text(GTK_ENTRY(find_text_))); |
177 | 210 |
178 if (new_contents.length() > 0) { | 211 if (new_contents.length() > 0) { |
179 web_contents->StartFinding(UTF8ToUTF16(new_contents), true); | 212 web_contents->StartFinding(UTF8ToUTF16(new_contents), true); |
180 } else { | 213 } else { |
181 // The textbox is empty so we reset. | 214 // The textbox is empty so we reset. |
182 web_contents->StopFinding(true); // true = clear selection on page. | 215 web_contents->StopFinding(true); // true = clear selection on page. |
183 } | 216 } |
184 } | 217 } |
185 | 218 |
186 void FindBarGtk::EscapePressed() { | 219 void FindBarGtk::EscapePressed() { |
187 find_bar_controller_->EndFindSession(); | 220 find_bar_controller_->EndFindSession(); |
188 } | 221 } |
189 | 222 |
190 // static | 223 // static |
191 void FindBarGtk::OnButtonPressed(GtkWidget* button, FindBarGtk* find_bar) { | 224 void FindBarGtk::OnButtonPressed(GtkWidget* button, FindBarGtk* find_bar) { |
192 if (button == find_bar->close_button_->widget()) { | 225 if (button == find_bar->close_button_->widget()) { |
193 find_bar->find_bar_controller_->EndFindSession(); | 226 find_bar->find_bar_controller_->EndFindSession(); |
194 } else if (button == find_bar->find_previous_button_->widget() || | 227 } else if (button == find_bar->find_previous_button_->widget() || |
195 button == find_bar->find_next_button_->widget()) { | 228 button == find_bar->find_next_button_->widget()) { |
196 std::string find_text_utf8( | 229 std::string find_text_utf8( |
197 gtk_entry_get_text(GTK_ENTRY(find_bar->find_text_))); | 230 gtk_entry_get_text(GTK_ENTRY(find_bar->find_text_))); |
198 find_bar->find_bar_controller_->web_contents()->StartFinding( | 231 find_bar->find_bar_controller_->web_contents()->StartFinding( |
199 UTF8ToUTF16(find_text_utf8), | 232 UTF8ToUTF16(find_text_utf8), |
200 button == find_bar->find_next_button_->widget()); | 233 button == find_bar->find_next_button_->widget()); |
201 } else { | 234 } else { |
202 NOTREACHED(); | 235 NOTREACHED(); |
203 } | 236 } |
204 } | 237 } |
| 238 |
| 239 // static |
| 240 void FindBarGtk::OnSizeAllocate(GtkWidget* fixed, |
| 241 GtkAllocation* allocation, |
| 242 FindBarGtk* findbar) { |
| 243 // Set the background widget to the size of |fixed|. |
| 244 if (findbar->border_->allocation.width != allocation->width) { |
| 245 gtk_widget_set_size_request(findbar->border_, allocation->width, 1); |
| 246 } |
| 247 |
| 248 // Reposition |container_|. |
| 249 GtkWidget* container = findbar->container_; |
| 250 DCHECK(container); |
| 251 if (!GTK_WIDGET_VISIBLE(container)) |
| 252 return; |
| 253 |
| 254 int xposition = findbar->GetDialogPosition(gfx::Rect()).x(); |
| 255 if (xposition == container->allocation.x) { |
| 256 return; |
| 257 } else { |
| 258 gtk_fixed_move(GTK_FIXED(fixed), container, xposition, kVerticalOffset); |
| 259 } |
| 260 } |
OLD | NEW |