OLD | NEW |
| (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 <algorithm> | |
6 | |
7 #include "app/theme_provider.h" | |
8 #include "chrome/app/chrome_dll_resource.h" | |
9 #include "chrome/browser/chromeos/compact_location_bar.h" | |
10 #include "chrome/browser/chromeos/compact_navigation_bar.h" | |
11 #include "chrome/browser/chromeos/main_menu.h" | |
12 #include "chrome/browser/chromeos/status_area_view.h" | |
13 #include "chrome/browser/chromeos/panel_controller.h" | |
14 #include "chrome/browser/views/frame/browser_extender.h" | |
15 #include "chrome/browser/views/frame/browser_frame_gtk.h" | |
16 #include "chrome/browser/views/frame/browser_view.h" | |
17 #include "chrome/browser/views/tabs/tab_overview_types.h" | |
18 #include "chrome/browser/views/tabs/tab_strip.h" | |
19 #include "chrome/browser/views/tabs/tab_strip_wrapper.h" | |
20 #include "chrome/browser/views/toolbar_view.h" | |
21 #include "grit/generated_resources.h" | |
22 #include "grit/theme_resources.h" | |
23 #include "views/controls/button/button.h" | |
24 #include "views/controls/button/image_button.h" | |
25 #include "views/controls/menu/simple_menu_model.h" | |
26 #include "views/window/window.h" | |
27 | |
28 namespace { | |
29 | |
30 // NormalExtender adds ChromeOS specific controls and menus to a BrowserView | |
31 // created with Browser::TYPE_NORMAL. This extender adds controls to | |
32 // the title bar as follows: | |
33 // ____ __ __ | |
34 // [MainMenu] / \ \ \ [StatusArea] | |
35 // | |
36 // and adds the system context menu to the remaining arae of the titlebar. | |
37 // | |
38 // For Browser::TYPE_POPUP type of BrowserView, see PopupExtender class below. | |
39 class NormalExtender : public BrowserExtender, | |
40 public views::ButtonListener, | |
41 public views::ContextMenuController { | |
42 public: | |
43 explicit NormalExtender(BrowserView* browser_view) | |
44 : BrowserExtender(browser_view), | |
45 main_menu_(NULL), | |
46 status_area_(NULL), | |
47 compact_navigation_bar_(NULL), | |
48 // CompactNavigationBar is disabled by default. | |
49 // TODO(oshima): Get this info from preference. | |
50 compact_navigation_bar_enabled_(false) { | |
51 } | |
52 virtual ~NormalExtender() {} | |
53 | |
54 protected: | |
55 // BrowserExtender overrides. | |
56 virtual void Init() { | |
57 main_menu_ = new views::ImageButton(this); | |
58 ThemeProvider* theme_provider = | |
59 browser_view()->frame()->GetThemeProviderForFrame(); | |
60 SkBitmap* image = theme_provider->GetBitmapNamed(IDR_MAIN_MENU_BUTTON); | |
61 main_menu_->SetImage(views::CustomButton::BS_NORMAL, image); | |
62 main_menu_->SetImage(views::CustomButton::BS_HOT, image); | |
63 main_menu_->SetImage(views::CustomButton::BS_PUSHED, image); | |
64 browser_view()->AddChildView(main_menu_); | |
65 | |
66 compact_location_bar_.reset(new CompactLocationBar(browser_view())); | |
67 compact_navigation_bar_ = | |
68 new CompactNavigationBar(browser_view()->browser()); | |
69 browser_view()->AddChildView(compact_navigation_bar_); | |
70 compact_navigation_bar_->Init(); | |
71 status_area_ = new StatusAreaView( | |
72 browser_view()->browser(), | |
73 browser_view()->GetWindow()->GetNativeWindow()); | |
74 browser_view()->AddChildView(status_area_); | |
75 status_area_->Init(); | |
76 | |
77 InitSystemMenu(); | |
78 MainMenu::ScheduleCreation(); | |
79 | |
80 // The ContextMenuController has to be set to a NonClientView but | |
81 // not to a NonClientFrameView because a TabStrip is not a child of | |
82 // a NonClientFrameView even though visually a TabStrip is over a | |
83 // NonClientFrameView. | |
84 BrowserFrameGtk* gtk_frame = | |
85 static_cast<BrowserFrameGtk*>(browser_view()->frame()); | |
86 gtk_frame->GetNonClientView()->SetContextMenuController(this); | |
87 } | |
88 | |
89 virtual gfx::Rect Layout(const gfx::Rect& bounds) { | |
90 // Skip if there is no space to layout, or if the browser is in | |
91 // fullscreen mode. | |
92 if (bounds.IsEmpty() || browser_view()->IsFullscreen()) { | |
93 main_menu_->SetVisible(false); | |
94 compact_navigation_bar_->SetVisible(false); | |
95 status_area_->SetVisible(false); | |
96 return bounds; | |
97 } else { | |
98 main_menu_->SetVisible(true); | |
99 compact_navigation_bar_->SetVisible(compact_navigation_bar_enabled_); | |
100 status_area_->SetVisible(true); | |
101 } | |
102 | |
103 if (compact_navigation_bar_->IsVisible()) { | |
104 // Update the size and location of the compact location bar. | |
105 compact_location_bar_->UpdateBounds( | |
106 browser_view()->tabstrip()->AsTabStrip()->GetSelectedTab()); | |
107 } | |
108 | |
109 // Layout main menu before tab strip. | |
110 gfx::Size main_menu_size = main_menu_->GetPreferredSize(); | |
111 main_menu_->SetBounds(bounds.x(), bounds.y(), | |
112 main_menu_size.width(), bounds.height()); | |
113 | |
114 // Layout status area after tab strip. | |
115 gfx::Size status_size = status_area_->GetPreferredSize(); | |
116 status_area_->SetBounds(bounds.x() + bounds.width() - status_size.width(), | |
117 bounds.y(), status_size.width(), | |
118 status_size.height()); | |
119 int curx = bounds.x() + main_menu_size.width(); | |
120 int width = bounds.width() - main_menu_size.width() - status_size.width(); | |
121 | |
122 if (compact_navigation_bar_->IsVisible()) { | |
123 gfx::Size cnb_bounds = compact_navigation_bar_->GetPreferredSize(); | |
124 compact_navigation_bar_->SetBounds(curx, bounds.y(), | |
125 cnb_bounds.width(), bounds.height()); | |
126 curx += cnb_bounds.width(); | |
127 width -= cnb_bounds.width(); | |
128 } | |
129 width = std::max(0, width); // In case there is no space left. | |
130 return gfx::Rect(curx, bounds.y(), width, bounds.height()); | |
131 } | |
132 | |
133 virtual bool NonClientHitTest(const gfx::Point& point) { | |
134 gfx::Point point_in_main_menu_coords(point); | |
135 views::View::ConvertPointToView(browser_view(), main_menu_, | |
136 &point_in_main_menu_coords); | |
137 if (main_menu_->HitTest(point_in_main_menu_coords)) | |
138 return true; | |
139 | |
140 gfx::Point point_in_status_area_coords(point); | |
141 views::View::ConvertPointToView(browser_view(), status_area_, | |
142 &point_in_status_area_coords); | |
143 if (status_area_->HitTest(point_in_status_area_coords)) | |
144 return true; | |
145 | |
146 if (compact_navigation_bar_->IsVisible()) { | |
147 gfx::Point point_in_cnb_coords(point); | |
148 views::View::ConvertPointToView(browser_view(), | |
149 compact_navigation_bar_, | |
150 &point_in_cnb_coords); | |
151 return compact_navigation_bar_->HitTest(point_in_cnb_coords); | |
152 } | |
153 return false; | |
154 } | |
155 | |
156 virtual void UpdateTitleBar() {} | |
157 | |
158 virtual void Show() { | |
159 TabOverviewTypes::instance()->SetWindowType( | |
160 GTK_WIDGET(GetBrowserWindow()->GetNativeWindow()), | |
161 TabOverviewTypes::WINDOW_TYPE_CHROME_TOPLEVEL, | |
162 NULL); | |
163 } | |
164 | |
165 virtual void Close() {} | |
166 | |
167 virtual void ActivationChanged() {} | |
168 | |
169 virtual bool ShouldForceHideToolbar() { | |
170 return compact_navigation_bar_enabled_; | |
171 } | |
172 | |
173 virtual void ToggleCompactNavigationBar() { | |
174 compact_navigation_bar_enabled_ = !compact_navigation_bar_enabled_; | |
175 } | |
176 | |
177 virtual void OnMouseEnteredToTab(Tab* tab) { | |
178 ShowCompactLocationBarUnderSelectedTab(); | |
179 } | |
180 | |
181 virtual void OnMouseMovedOnTab(Tab* tab) { | |
182 ShowCompactLocationBarUnderSelectedTab(); | |
183 } | |
184 | |
185 virtual void OnMouseExitedFromTab(Tab* tab) { | |
186 compact_location_bar_->StartPopupTimer(); | |
187 } | |
188 | |
189 private: | |
190 // Shows the compact location bar under the selected tab. | |
191 void ShowCompactLocationBarUnderSelectedTab() { | |
192 if (!compact_navigation_bar_enabled_) | |
193 return; | |
194 compact_location_bar_->Update( | |
195 browser_view()->tabstrip()->AsTabStrip()->GetSelectedTab(), | |
196 browser_view()->browser()->GetSelectedTabContents()); | |
197 } | |
198 | |
199 // Creates system menu. | |
200 void InitSystemMenu() { | |
201 system_menu_contents_.reset(new views::SimpleMenuModel(browser_view())); | |
202 system_menu_contents_->AddItemWithStringId(IDC_RESTORE_TAB, | |
203 IDS_RESTORE_TAB); | |
204 system_menu_contents_->AddItemWithStringId(IDC_NEW_TAB, IDS_NEW_TAB); | |
205 system_menu_contents_->AddSeparator(); | |
206 system_menu_contents_->AddItemWithStringId(IDC_TASK_MANAGER, | |
207 IDS_TASK_MANAGER); | |
208 system_menu_menu_.reset(new views::Menu2(system_menu_contents_.get())); | |
209 } | |
210 | |
211 // views::ButtonListener overrides. | |
212 virtual void ButtonPressed(views::Button* sender, const views::Event& event) { | |
213 MainMenu::Show(browser_view()->browser()); | |
214 } | |
215 | |
216 // views::ContextMenuController overrides. | |
217 virtual void ShowContextMenu(views::View* source, | |
218 int x, | |
219 int y, | |
220 bool is_mouse_gesture) { | |
221 system_menu_menu_->RunMenuAt(gfx::Point(x, y), views::Menu2::ALIGN_TOPLEFT); | |
222 } | |
223 | |
224 // Main menu button. | |
225 views::ImageButton* main_menu_; | |
226 | |
227 // Status Area view. | |
228 StatusAreaView* status_area_; | |
229 | |
230 // System menus. | |
231 scoped_ptr<views::SimpleMenuModel> system_menu_contents_; | |
232 scoped_ptr<views::Menu2> system_menu_menu_; | |
233 | |
234 // CompactNavigationBar view. | |
235 CompactNavigationBar* compact_navigation_bar_; | |
236 | |
237 // A toggle flag to show/hide the compact navigation bar. | |
238 bool compact_navigation_bar_enabled_; | |
239 | |
240 // CompactLocationBar view. | |
241 scoped_ptr<CompactLocationBar> compact_location_bar_; | |
242 | |
243 DISALLOW_COPY_AND_ASSIGN(NormalExtender); | |
244 }; | |
245 | |
246 // PopupExtender class creates dedicated title window for popup window. | |
247 // The size and location of the created title window is controlled by | |
248 // by window manager. | |
249 class PopupExtender : public BrowserExtender { | |
250 public: | |
251 explicit PopupExtender(BrowserView* browser_view) | |
252 : BrowserExtender(browser_view) { | |
253 } | |
254 virtual ~PopupExtender() {} | |
255 | |
256 private: | |
257 // BrowserExtender overrides. | |
258 virtual void Init() { | |
259 // The visibility of toolbar is controlled in | |
260 // the BrowserView::IsToolbarVisible method. | |
261 | |
262 views::Window* window = GetBrowserWindow(); | |
263 gfx::NativeWindow native_window = window->GetNativeWindow(); | |
264 // The window manager needs the min size for popups. | |
265 gfx::Rect bounds = window->GetBounds(); | |
266 gtk_widget_set_size_request( | |
267 GTK_WIDGET(native_window), bounds.width(), bounds.height()); | |
268 // If we don't explicitly resize here there is a race condition between | |
269 // the X Server and the window manager. Windows will appear with a default | |
270 // size of 200x200 if this happens. | |
271 gtk_window_resize(native_window, bounds.width(), bounds.height()); | |
272 } | |
273 | |
274 virtual gfx::Rect Layout(const gfx::Rect& bounds) { | |
275 return bounds; | |
276 } | |
277 | |
278 virtual bool NonClientHitTest(const gfx::Point& point) { | |
279 return false; | |
280 } | |
281 | |
282 virtual void Show() { | |
283 panel_controller_.reset(new PanelController(browser_view())); | |
284 } | |
285 | |
286 virtual void Close() { | |
287 if (panel_controller_.get()) | |
288 panel_controller_->Close(); | |
289 } | |
290 | |
291 virtual void UpdateTitleBar() { | |
292 if (panel_controller_.get()) | |
293 panel_controller_->UpdateTitleBar(); | |
294 } | |
295 | |
296 virtual void ActivationChanged() { | |
297 if (panel_controller_.get()) { | |
298 if (GetBrowserWindow()->IsActive()) | |
299 panel_controller_->OnFocusIn(); | |
300 else | |
301 panel_controller_->OnFocusOut(); | |
302 } | |
303 } | |
304 | |
305 virtual bool ShouldForceHideToolbar() { | |
306 // Always hide toolbar for popups. | |
307 return true; | |
308 } | |
309 | |
310 virtual void ToggleCompactNavigationBar() {} | |
311 | |
312 virtual void OnMouseEnteredToTab(Tab* tab) {} | |
313 | |
314 virtual void OnMouseMovedOnTab(Tab* tab) {} | |
315 | |
316 virtual void OnMouseExitedFromTab(Tab* tab) {} | |
317 | |
318 // Controls interactions with the window manager for popup panels. | |
319 scoped_ptr<PanelController> panel_controller_; | |
320 | |
321 DISALLOW_COPY_AND_ASSIGN(PopupExtender); | |
322 }; | |
323 | |
324 } // namespace | |
325 | |
326 //////////////////////////////////////////////////////////////////////////////// | |
327 // BrowserExtender, public: | |
328 | |
329 // static | |
330 BrowserExtender* BrowserExtender::Create(BrowserView* browser_view) { | |
331 BrowserExtender* extender; | |
332 if (browser_view->browser()->type() & Browser::TYPE_POPUP) | |
333 extender = new PopupExtender(browser_view); | |
334 else | |
335 extender = new NormalExtender(browser_view); | |
336 extender->Init(); | |
337 return extender; | |
338 } | |
OLD | NEW |