OLD | NEW |
| (Empty) |
1 // Copyright (c) 2011 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/ui/views/browser_bubble.h" | |
6 | |
7 #include <vector> | |
8 | |
9 #include "chrome/browser/ui/views/bubble/border_contents.h" | |
10 #include "chrome/browser/ui/views/frame/browser_view.h" | |
11 #include "ui/views/widget/native_widget_gtk.h" | |
12 #include "ui/views/widget/root_view.h" | |
13 | |
14 #if defined(OS_CHROMEOS) && defined(TOOLKIT_USES_GTK) | |
15 #include "chrome/browser/chromeos/legacy_window_manager/wm_ipc.h" | |
16 #include "third_party/cros_system_api/window_manager/chromeos_wm_ipc_enums.h" | |
17 #endif | |
18 | |
19 using std::vector; | |
20 | |
21 namespace { | |
22 | |
23 class BubbleWidget : public views::NativeWidgetGtk { | |
24 public: | |
25 BubbleWidget(BrowserBubble* bubble, const gfx::Insets& content_margins) | |
26 : views::NativeWidgetGtk(new views::Widget), | |
27 bubble_(bubble), | |
28 border_contents_(new BorderContents) { | |
29 border_contents_->Init(); | |
30 border_contents_->set_content_margins(content_margins); | |
31 } | |
32 | |
33 void ShowAndActivate(bool activate) { | |
34 // TODO: honor activate. | |
35 views::NativeWidgetGtk::Show(); | |
36 } | |
37 | |
38 virtual void Close() OVERRIDE { | |
39 if (!bubble_) | |
40 return; // We have already been closed. | |
41 if (IsActive()) { | |
42 BrowserBubble::Delegate* delegate = bubble_->delegate(); | |
43 if (delegate) | |
44 delegate->BubbleLostFocus(bubble_, false); | |
45 } | |
46 views::NativeWidgetGtk::Close(); | |
47 bubble_ = NULL; | |
48 } | |
49 | |
50 virtual void Hide() OVERRIDE { | |
51 if (IsActive() && bubble_) { | |
52 BrowserBubble::Delegate* delegate = bubble_->delegate(); | |
53 if (delegate) | |
54 delegate->BubbleLostFocus(bubble_, false); | |
55 } | |
56 views::NativeWidgetGtk::Hide(); | |
57 } | |
58 | |
59 virtual void OnActiveChanged() OVERRIDE { | |
60 if (IsActive() || !bubble_) | |
61 return; | |
62 BrowserBubble::Delegate* delegate = bubble_->delegate(); | |
63 if (!delegate) { | |
64 bubble_->DetachFromBrowser(); | |
65 delete bubble_; | |
66 return; | |
67 } | |
68 | |
69 // TODO(jcampan): http://crbugs.com/29131 Check if the window we are losing | |
70 // focus to is a child window and pass that to the call | |
71 // below. | |
72 delegate->BubbleLostFocus(bubble_, false); | |
73 } | |
74 | |
75 virtual gboolean OnFocusIn(GtkWidget* widget, GdkEventFocus* event) OVERRIDE { | |
76 if (bubble_ && bubble_->delegate()) | |
77 bubble_->delegate()->BubbleGotFocus(bubble_); | |
78 return views::NativeWidgetGtk::OnFocusIn(widget, event); | |
79 } | |
80 | |
81 BorderContents* border_contents() { | |
82 return border_contents_; | |
83 } | |
84 | |
85 private: | |
86 BrowserBubble* bubble_; | |
87 BorderContents* border_contents_; // Owned by root view of this widget. | |
88 | |
89 DISALLOW_COPY_AND_ASSIGN(BubbleWidget); | |
90 }; | |
91 | |
92 } // namespace | |
93 | |
94 void BrowserBubble::InitPopup(const gfx::Insets& content_margins) { | |
95 // TODO(port) | |
96 BubbleWidget* bubble_widget = new BubbleWidget(this, content_margins); | |
97 popup_ = bubble_widget->GetWidget(); | |
98 views::Widget::InitParams params( | |
99 views::Widget::InitParams::TYPE_WINDOW_FRAMELESS); | |
100 params.transparent = true; | |
101 params.parent = frame_->GetNativeView(); | |
102 params.native_widget = bubble_widget; | |
103 popup_->Init(params); | |
104 #if defined(OS_CHROMEOS) && defined(TOOLKIT_USES_GTK) | |
105 { | |
106 vector<int> params; | |
107 params.push_back(0); // don't show while screen is locked | |
108 chromeos::WmIpc::instance()->SetWindowType( | |
109 popup_->GetNativeView(), | |
110 chromeos::WM_IPC_WINDOW_CHROME_INFO_BUBBLE, | |
111 ¶ms); | |
112 } | |
113 #endif | |
114 | |
115 views::View* contents_view = new views::View; | |
116 | |
117 // We add |contents_view| to ourselves before the AddChildView() call below so | |
118 // that when |contents| gets added, it will already have a widget, and thus | |
119 // any NativeButtons it creates in ViewHierarchyChanged() will be functional | |
120 // (e.g. calling SetChecked() on checkboxes is safe). | |
121 popup_->SetContentsView(contents_view); | |
122 | |
123 // Added border_contents before |view_| so it will paint under it. | |
124 contents_view->AddChildView(bubble_widget->border_contents()); | |
125 contents_view->AddChildView(view_); | |
126 | |
127 ResizeToView(); | |
128 Reposition(); | |
129 AttachToBrowser(); | |
130 } | |
131 | |
132 void BrowserBubble::Show(bool activate) { | |
133 if (!popup_->IsVisible()) { | |
134 static_cast<BubbleWidget*>(popup_->native_widget())->ShowAndActivate( | |
135 activate); | |
136 } | |
137 } | |
138 | |
139 void BrowserBubble::Hide() { | |
140 if (popup_->IsVisible()) | |
141 static_cast<BubbleWidget*>(popup_->native_widget())->Hide(); | |
142 } | |
143 | |
144 void BrowserBubble::ResizeToView() { | |
145 BorderContents* border_contents = | |
146 static_cast<BubbleWidget*>(popup_->native_widget())->border_contents(); | |
147 | |
148 // Calculate and set the bounds for all windows and views. | |
149 gfx::Rect window_bounds; | |
150 gfx::Rect contents_bounds; | |
151 border_contents->SizeAndGetBounds(GetAbsoluteRelativeTo(), | |
152 arrow_location_, false, view_->size(), | |
153 &contents_bounds, &window_bounds); | |
154 | |
155 border_contents->SetBoundsRect(gfx::Rect(gfx::Point(), window_bounds.size())); | |
156 view_->SetBoundsRect(contents_bounds); | |
157 | |
158 SetAbsoluteBounds(window_bounds); | |
159 } | |
OLD | NEW |