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/tab_contents_container_gtk.h" | 5 #include "chrome/browser/gtk/tab_contents_container_gtk.h" |
6 | 6 |
7 #include "base/gfx/native_widget_types.h" | 7 #include "base/gfx/native_widget_types.h" |
| 8 #include "chrome/browser/gtk/gtk_floating_container.h" |
8 #include "chrome/browser/gtk/status_bubble_gtk.h" | 9 #include "chrome/browser/gtk/status_bubble_gtk.h" |
9 #include "chrome/browser/tab_contents/tab_contents.h" | 10 #include "chrome/browser/tab_contents/tab_contents.h" |
10 #include "chrome/browser/renderer_host/render_widget_host_view_gtk.h" | 11 #include "chrome/browser/renderer_host/render_widget_host_view_gtk.h" |
11 #include "chrome/common/notification_service.h" | 12 #include "chrome/common/notification_service.h" |
12 | 13 |
13 namespace { | 14 namespace { |
14 | 15 |
15 // Allocates all normal tab contents views to the size of the passed in | 16 // Allocates all normal tab contents views to the size of the passed in |
16 // |allocation|. Ignores StatusBubbles, which are handled separately. | 17 // |allocation|. |
17 void ResizeChildren(GtkWidget* widget, void* param) { | 18 void ResizeChildren(GtkWidget* widget, void* param) { |
18 GtkAllocation* allocation = reinterpret_cast<GtkAllocation*>(param); | 19 GtkAllocation* allocation = reinterpret_cast<GtkAllocation*>(param); |
19 | 20 |
20 if (strcmp(gtk_widget_get_name(widget), "status-bubble") != 0) { | 21 if (widget->allocation.width != allocation->width || |
21 if (widget->allocation.width != allocation->width || | 22 widget->allocation.height != allocation->height) { |
22 widget->allocation.height != allocation->height) { | 23 gtk_widget_set_size_request(widget, allocation->width, |
23 gtk_widget_set_size_request(widget, allocation->width, | 24 allocation->height); |
24 allocation->height); | |
25 } | |
26 } | 25 } |
27 } | 26 } |
28 | 27 |
29 } // namespace | 28 } // namespace |
30 | 29 |
31 TabContentsContainerGtk::TabContentsContainerGtk(StatusBubbleGtk* status_bubble) | 30 TabContentsContainerGtk::TabContentsContainerGtk(StatusBubbleGtk* status_bubble) |
32 : tab_contents_(NULL), | 31 : tab_contents_(NULL), |
33 status_bubble_(status_bubble), | 32 status_bubble_(status_bubble) { |
34 fixed_(gtk_fixed_new()) { | 33 Init(); |
35 gtk_fixed_put(GTK_FIXED(fixed_), status_bubble->widget(), 0, 0); | |
36 | |
37 g_signal_connect(fixed_, "size-allocate", | |
38 G_CALLBACK(OnFixedSizeAllocate), this); | |
39 | |
40 gtk_widget_show(fixed_); | |
41 } | 34 } |
42 | 35 |
43 TabContentsContainerGtk::~TabContentsContainerGtk() { | 36 TabContentsContainerGtk::~TabContentsContainerGtk() { |
44 } | 37 } |
45 | 38 |
| 39 void TabContentsContainerGtk::Init() { |
| 40 // A high level overview of the TabContentsContainer: |
| 41 // |
| 42 // +- GtkFloatingContainer |floating_| -------------------------------+ |
| 43 // |+- GtkFixedContainer |fixed_| -----------------------------------+| |
| 44 // || || |
| 45 // || || |
| 46 // || || |
| 47 // || || |
| 48 // |+- (StatusBubble) ------+ +- (Popups) ------------+| |
| 49 // |+ +----------------+ || |
| 50 // |+-----------------------+ +-----------------------+| |
| 51 // +------------------------------------------------------------------+ |
| 52 |
| 53 floating_ = gtk_floating_container_new(); |
| 54 |
| 55 fixed_ = gtk_fixed_new(); |
| 56 g_signal_connect(fixed_, "size-allocate", |
| 57 G_CALLBACK(OnFixedSizeAllocate), this); |
| 58 gtk_container_add(GTK_CONTAINER(floating_), fixed_); |
| 59 |
| 60 gtk_floating_container_add_floating(GTK_FLOATING_CONTAINER(floating_), |
| 61 status_bubble_->widget()); |
| 62 g_signal_connect(floating_, "set-floating-position", |
| 63 G_CALLBACK(OnSetFloatingPosition), this); |
| 64 |
| 65 gtk_widget_show(fixed_); |
| 66 gtk_widget_show(floating_); |
| 67 } |
| 68 |
46 void TabContentsContainerGtk::AddContainerToBox(GtkWidget* box) { | 69 void TabContentsContainerGtk::AddContainerToBox(GtkWidget* box) { |
47 gtk_box_pack_start(GTK_BOX(box), fixed_, TRUE, TRUE, 0); | 70 gtk_box_pack_start(GTK_BOX(box), floating_, TRUE, TRUE, 0); |
48 } | 71 } |
49 | 72 |
50 void TabContentsContainerGtk::SetTabContents(TabContents* tab_contents) { | 73 void TabContentsContainerGtk::SetTabContents(TabContents* tab_contents) { |
51 if (tab_contents_) { | 74 if (tab_contents_) { |
52 gfx::NativeView widget = tab_contents_->GetNativeView(); | 75 gfx::NativeView widget = tab_contents_->GetNativeView(); |
53 if (widget) | 76 if (widget) |
54 gtk_widget_hide(widget); | 77 gtk_widget_hide(widget); |
55 | 78 |
56 tab_contents_->WasHidden(); | 79 tab_contents_->WasHidden(); |
57 | 80 |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
133 SetTabContents(NULL); | 156 SetTabContents(NULL); |
134 } | 157 } |
135 | 158 |
136 // static | 159 // static |
137 void TabContentsContainerGtk::OnFixedSizeAllocate( | 160 void TabContentsContainerGtk::OnFixedSizeAllocate( |
138 GtkWidget* fixed, | 161 GtkWidget* fixed, |
139 GtkAllocation* allocation, | 162 GtkAllocation* allocation, |
140 TabContentsContainerGtk* container) { | 163 TabContentsContainerGtk* container) { |
141 // Set all the tab contents GtkWidgets to the size of the allocation. | 164 // Set all the tab contents GtkWidgets to the size of the allocation. |
142 gtk_container_foreach(GTK_CONTAINER(fixed), ResizeChildren, allocation); | 165 gtk_container_foreach(GTK_CONTAINER(fixed), ResizeChildren, allocation); |
| 166 } |
143 | 167 |
144 // Tell the status bubble about how large it can be. | 168 // static |
145 container->status_bubble_->SetParentAllocation(fixed, allocation); | 169 void TabContentsContainerGtk::OnSetFloatingPosition( |
| 170 GtkFloatingContainer* floating_container, GtkAllocation* allocation, |
| 171 TabContentsContainerGtk* tab_contents_container) { |
| 172 GtkWidget* widget = tab_contents_container->status_bubble_->widget(); |
| 173 |
| 174 // Look at the size request of the status bubble and tell the |
| 175 // GtkFloatingContainer where we want it positioned. |
| 176 GtkRequisition requisition; |
| 177 gtk_widget_size_request(widget, &requisition); |
| 178 |
| 179 GValue value = { 0, }; |
| 180 g_value_init(&value, G_TYPE_INT); |
| 181 g_value_set_int(&value, 0); |
| 182 // TODO(erg): Since we're absolutely positioning stuff, we probably have to |
| 183 // do manual RTL right here. |
| 184 gtk_container_child_set_property(GTK_CONTAINER(floating_container), |
| 185 widget, "x", &value); |
| 186 |
| 187 int child_y = std::max( |
| 188 allocation->y + allocation->height - requisition.height, 0); |
| 189 g_value_set_int(&value, child_y); |
| 190 gtk_container_child_set_property(GTK_CONTAINER(floating_container), |
| 191 widget, "y", &value); |
| 192 g_value_unset(&value); |
146 } | 193 } |
OLD | NEW |