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

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

Issue 6251001: Move chrome/browser/gtk/ to chrome/browser/ui/gtk/... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 9 years, 11 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 | Annotate | Revision Log
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "chrome/browser/gtk/tab_contents_container_gtk.h"
6
7 #include <algorithm>
8
9 #include "base/i18n/rtl.h"
10 #include "chrome/browser/gtk/gtk_expanded_container.h"
11 #include "chrome/browser/gtk/gtk_floating_container.h"
12 #include "chrome/browser/gtk/status_bubble_gtk.h"
13 #include "chrome/browser/tab_contents/tab_contents.h"
14 #include "chrome/browser/renderer_host/render_widget_host_view_gtk.h"
15 #include "chrome/common/notification_source.h"
16 #include "gfx/native_widget_types.h"
17
18 TabContentsContainerGtk::TabContentsContainerGtk(StatusBubbleGtk* status_bubble)
19 : tab_contents_(NULL),
20 preview_contents_(NULL),
21 status_bubble_(status_bubble) {
22 Init();
23 }
24
25 TabContentsContainerGtk::~TabContentsContainerGtk() {
26 floating_.Destroy();
27 }
28
29 void TabContentsContainerGtk::Init() {
30 // A high level overview of the TabContentsContainer:
31 //
32 // +- GtkFloatingContainer |floating_| -------------------------------+
33 // |+- GtkExpandedContainer |expanded_| -----------------------------+|
34 // || ||
35 // || ||
36 // || ||
37 // || ||
38 // |+- (StatusBubble) ------+ ||
39 // |+ + ||
40 // |+-----------------------+----------------------------------------+|
41 // +------------------------------------------------------------------+
42
43 floating_.Own(gtk_floating_container_new());
44 gtk_widget_set_name(floating_.get(), "chrome-tab-contents-container");
45 g_signal_connect(floating_.get(), "focus", G_CALLBACK(OnFocusThunk), this);
46
47 expanded_ = gtk_expanded_container_new();
48 gtk_container_add(GTK_CONTAINER(floating_.get()), expanded_);
49
50 if (status_bubble_) {
51 gtk_floating_container_add_floating(GTK_FLOATING_CONTAINER(floating_.get()),
52 status_bubble_->widget());
53 g_signal_connect(floating_.get(), "set-floating-position",
54 G_CALLBACK(OnSetFloatingPosition), this);
55 }
56
57 gtk_widget_show(expanded_);
58 gtk_widget_show(floating_.get());
59
60 ViewIDUtil::SetDelegateForWidget(widget(), this);
61 }
62
63 void TabContentsContainerGtk::SetTabContents(TabContents* tab_contents) {
64 HideTabContents(tab_contents_);
65 if (tab_contents_) {
66 registrar_.Remove(this, NotificationType::TAB_CONTENTS_DESTROYED,
67 Source<TabContents>(tab_contents_));
68 }
69
70 tab_contents_ = tab_contents;
71
72 if (tab_contents_ == preview_contents_) {
73 // If the preview contents is becoming the new permanent tab contents, we
74 // just reassign some pointers.
75 preview_contents_ = NULL;
76 } else if (tab_contents_) {
77 // Otherwise we actually have to add it to the widget hierarchy.
78 PackTabContents(tab_contents);
79 registrar_.Add(this, NotificationType::TAB_CONTENTS_DESTROYED,
80 Source<TabContents>(tab_contents_));
81 }
82 }
83
84 TabContents* TabContentsContainerGtk::GetVisibleTabContents() {
85 return preview_contents_ ? preview_contents_ : tab_contents_;
86 }
87
88 void TabContentsContainerGtk::SetPreviewContents(TabContents* preview) {
89 if (preview_contents_)
90 RemovePreviewContents();
91 else
92 HideTabContents(tab_contents_);
93
94 preview_contents_ = preview;
95
96 PackTabContents(preview);
97 registrar_.Add(this, NotificationType::TAB_CONTENTS_DESTROYED,
98 Source<TabContents>(preview_contents_));
99 }
100
101 void TabContentsContainerGtk::RemovePreviewContents() {
102 if (!preview_contents_)
103 return;
104
105 HideTabContents(preview_contents_);
106
107 GtkWidget* preview_widget = preview_contents_->GetNativeView();
108 if (preview_widget)
109 gtk_container_remove(GTK_CONTAINER(expanded_), preview_widget);
110
111 registrar_.Remove(this, NotificationType::TAB_CONTENTS_DESTROYED,
112 Source<TabContents>(preview_contents_));
113 preview_contents_ = NULL;
114 }
115
116 void TabContentsContainerGtk::PopPreviewContents() {
117 if (!preview_contents_)
118 return;
119
120 RemovePreviewContents();
121
122 PackTabContents(tab_contents_);
123 }
124
125 void TabContentsContainerGtk::PackTabContents(TabContents* contents) {
126 if (!contents)
127 return;
128
129 gfx::NativeView widget = contents->GetNativeView();
130 if (widget) {
131 if (widget->parent != expanded_)
132 gtk_container_add(GTK_CONTAINER(expanded_), widget);
133 gtk_widget_show(widget);
134 }
135
136 // We need to make sure that we are below the findbar.
137 // Sometimes the content native view will be null.
138 if (contents->GetContentNativeView()) {
139 GdkWindow* content_gdk_window =
140 contents->GetContentNativeView()->window;
141 if (content_gdk_window)
142 gdk_window_lower(content_gdk_window);
143 }
144
145 contents->ShowContents();
146 }
147
148 void TabContentsContainerGtk::HideTabContents(TabContents* contents) {
149 if (!contents)
150 return;
151
152 gfx::NativeView widget = contents->GetNativeView();
153 if (widget)
154 gtk_widget_hide(widget);
155
156 contents->WasHidden();
157 }
158
159 void TabContentsContainerGtk::DetachTabContents(TabContents* tab_contents) {
160 gfx::NativeView widget = tab_contents->GetNativeView();
161
162 // It is possible to detach an unrealized, unparented TabContents if you
163 // slow things down enough in valgrind. Might happen in the real world, too.
164 if (widget && widget->parent) {
165 DCHECK_EQ(widget->parent, expanded_);
166 gtk_container_remove(GTK_CONTAINER(expanded_), widget);
167 }
168 }
169
170 void TabContentsContainerGtk::Observe(NotificationType type,
171 const NotificationSource& source,
172 const NotificationDetails& details) {
173 DCHECK(type == NotificationType::TAB_CONTENTS_DESTROYED);
174
175 TabContentsDestroyed(Source<TabContents>(source).ptr());
176 }
177
178 void TabContentsContainerGtk::TabContentsDestroyed(TabContents* contents) {
179 // Sometimes, a TabContents is destroyed before we know about it. This allows
180 // us to clean up our state in case this happens.
181 if (contents == preview_contents_)
182 PopPreviewContents();
183 else if (contents == tab_contents_)
184 SetTabContents(NULL);
185 else
186 NOTREACHED();
187 }
188
189 // Prevent |preview_contents_| from getting focus via the tab key. If
190 // |tab_contents_| exists, try to focus that. Otherwise, do nothing, but stop
191 // event propagation. See bug http://crbug.com/63365
192 gboolean TabContentsContainerGtk::OnFocus(GtkWidget* widget,
193 GtkDirectionType focus) {
194 if (preview_contents_) {
195 gtk_widget_child_focus(tab_contents_->GetContentNativeView(), focus);
196 return TRUE;
197 }
198
199 // No preview contents; let the default handler run.
200 return FALSE;
201 }
202
203 // -----------------------------------------------------------------------------
204 // ViewIDUtil::Delegate implementation
205
206 GtkWidget* TabContentsContainerGtk::GetWidgetForViewID(ViewID view_id) {
207 if (view_id == VIEW_ID_TAB_CONTAINER ||
208 view_id == VIEW_ID_TAB_CONTAINER_FOCUS_VIEW) {
209 return widget();
210 }
211
212 return NULL;
213 }
214
215 // -----------------------------------------------------------------------------
216
217 // static
218 void TabContentsContainerGtk::OnSetFloatingPosition(
219 GtkFloatingContainer* floating_container, GtkAllocation* allocation,
220 TabContentsContainerGtk* tab_contents_container) {
221 StatusBubbleGtk* status = tab_contents_container->status_bubble_;
222
223 // Look at the size request of the status bubble and tell the
224 // GtkFloatingContainer where we want it positioned.
225 GtkRequisition requisition;
226 gtk_widget_size_request(status->widget(), &requisition);
227
228 bool ltr = !base::i18n::IsRTL();
229
230 GValue value = { 0, };
231 g_value_init(&value, G_TYPE_INT);
232 if (ltr ^ status->flip_horizontally()) // Is it on the left?
233 g_value_set_int(&value, 0);
234 else
235 g_value_set_int(&value, allocation->width - requisition.width);
236 gtk_container_child_set_property(GTK_CONTAINER(floating_container),
237 status->widget(), "x", &value);
238
239 int child_y = std::max(allocation->height - requisition.height, 0);
240 g_value_set_int(&value, child_y + status->y_offset());
241 gtk_container_child_set_property(GTK_CONTAINER(floating_container),
242 status->widget(), "y", &value);
243 g_value_unset(&value);
244 }
OLDNEW
« no previous file with comments | « chrome/browser/gtk/tab_contents_container_gtk.h ('k') | chrome/browser/gtk/tab_contents_drag_source.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698