Chromecast: extracts Linux window creation code to a common place.
[chromium-blink-merge.git] / ash / shell / window_type_launcher.cc
bloba08c06ee4f3c798a3b9acc4fb25485d979792b05
1 // Copyright (c) 2012 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.
5 #include "ash/shell/window_type_launcher.h"
7 #include "ash/root_window_controller.h"
8 #include "ash/screensaver/screensaver_view.h"
9 #include "ash/session/session_state_delegate.h"
10 #include "ash/shelf/shelf_widget.h"
11 #include "ash/shell.h"
12 #include "ash/shell/example_factory.h"
13 #include "ash/shell/panel_window.h"
14 #include "ash/shell/toplevel_window.h"
15 #include "ash/shell_delegate.h"
16 #include "ash/shell_window_ids.h"
17 #include "ash/system/status_area_widget.h"
18 #include "ash/system/web_notification/web_notification_tray.h"
19 #include "ash/test/child_modal_window.h"
20 #include "base/bind.h"
21 #include "base/strings/utf_string_conversions.h"
22 #include "base/time/time.h"
23 #include "content/public/browser/browser_thread.h"
24 #include "ui/aura/window.h"
25 #include "ui/aura/window_event_dispatcher.h"
26 #include "ui/compositor/layer.h"
27 #include "ui/gfx/canvas.h"
28 #include "ui/message_center/message_center.h"
29 #include "ui/message_center/notification_types.h"
30 #include "ui/views/controls/button/label_button.h"
31 #include "ui/views/controls/menu/menu_item_view.h"
32 #include "ui/views/controls/menu/menu_runner.h"
33 #include "ui/views/examples/examples_window_with_content.h"
34 #include "ui/views/layout/grid_layout.h"
35 #include "ui/views/widget/widget.h"
36 #include "ui/wm/core/shadow_types.h"
38 using views::MenuItemView;
39 using views::MenuRunner;
41 namespace ash {
42 namespace shell {
44 namespace {
46 SkColor g_colors[] = { SK_ColorRED,
47 SK_ColorYELLOW,
48 SK_ColorBLUE,
49 SK_ColorGREEN };
50 int g_color_index = 0;
52 class ModalWindow : public views::WidgetDelegateView,
53 public views::ButtonListener {
54 public:
55 explicit ModalWindow(ui::ModalType modal_type)
56 : modal_type_(modal_type),
57 color_(g_colors[g_color_index]),
58 open_button_(new views::LabelButton(this,
59 base::ASCIIToUTF16("Moar!"))) {
60 ++g_color_index %= arraysize(g_colors);
61 open_button_->SetStyle(views::Button::STYLE_BUTTON);
62 AddChildView(open_button_);
64 virtual ~ModalWindow() {
67 static void OpenModalWindow(aura::Window* parent, ui::ModalType modal_type) {
68 views::Widget* widget =
69 views::Widget::CreateWindowWithParent(new ModalWindow(modal_type),
70 parent);
71 widget->GetNativeView()->SetName("ModalWindow");
72 widget->Show();
75 // Overridden from views::View:
76 virtual void OnPaint(gfx::Canvas* canvas) override {
77 canvas->FillRect(GetLocalBounds(), color_);
79 virtual gfx::Size GetPreferredSize() const override {
80 return gfx::Size(200, 200);
82 virtual void Layout() override {
83 gfx::Size open_ps = open_button_->GetPreferredSize();
84 gfx::Rect local_bounds = GetLocalBounds();
85 open_button_->SetBounds(
86 5, local_bounds.bottom() - open_ps.height() - 5,
87 open_ps.width(), open_ps.height());
90 // Overridden from views::WidgetDelegate:
91 virtual views::View* GetContentsView() override {
92 return this;
94 virtual bool CanResize() const override {
95 return true;
97 virtual base::string16 GetWindowTitle() const override {
98 return base::ASCIIToUTF16("Modal Window");
100 virtual ui::ModalType GetModalType() const override {
101 return modal_type_;
104 // Overridden from views::ButtonListener:
105 virtual void ButtonPressed(views::Button* sender,
106 const ui::Event& event) override {
107 DCHECK(sender == open_button_);
108 OpenModalWindow(GetWidget()->GetNativeView(), modal_type_);
111 private:
112 ui::ModalType modal_type_;
113 SkColor color_;
114 views::LabelButton* open_button_;
116 DISALLOW_COPY_AND_ASSIGN(ModalWindow);
119 class NonModalTransient : public views::WidgetDelegateView {
120 public:
121 NonModalTransient()
122 : color_(g_colors[g_color_index]) {
123 ++g_color_index %= arraysize(g_colors);
125 virtual ~NonModalTransient() {
128 static void OpenNonModalTransient(aura::Window* parent) {
129 views::Widget* widget =
130 views::Widget::CreateWindowWithParent(new NonModalTransient, parent);
131 widget->GetNativeView()->SetName("NonModalTransient");
132 widget->Show();
135 static void ToggleNonModalTransient(aura::Window* parent) {
136 if (!non_modal_transient_) {
137 non_modal_transient_ =
138 views::Widget::CreateWindowWithParent(new NonModalTransient, parent);
139 non_modal_transient_->GetNativeView()->SetName("NonModalTransient");
141 if (non_modal_transient_->IsVisible())
142 non_modal_transient_->Hide();
143 else
144 non_modal_transient_->Show();
147 // Overridden from views::View:
148 virtual void OnPaint(gfx::Canvas* canvas) override {
149 canvas->FillRect(GetLocalBounds(), color_);
151 virtual gfx::Size GetPreferredSize() const override {
152 return gfx::Size(250, 250);
155 // Overridden from views::WidgetDelegate:
156 virtual views::View* GetContentsView() override {
157 return this;
159 virtual bool CanResize() const override {
160 return true;
162 virtual base::string16 GetWindowTitle() const override {
163 return base::ASCIIToUTF16("Non-Modal Transient");
165 virtual void DeleteDelegate() override {
166 if (GetWidget() == non_modal_transient_)
167 non_modal_transient_ = NULL;
169 delete this;
172 private:
173 SkColor color_;
175 static views::Widget* non_modal_transient_;
177 DISALLOW_COPY_AND_ASSIGN(NonModalTransient);
180 // static
181 views::Widget* NonModalTransient::non_modal_transient_ = NULL;
183 void AddViewToLayout(views::GridLayout* layout, views::View* view) {
184 layout->StartRow(0, 0);
185 layout->AddView(view);
186 layout->AddPaddingRow(0, 5);
189 } // namespace
191 void InitWindowTypeLauncher() {
192 views::Widget* widget =
193 views::Widget::CreateWindowWithContextAndBounds(
194 new WindowTypeLauncher,
195 Shell::GetPrimaryRootWindow(),
196 gfx::Rect(120, 150, 300, 410));
197 widget->GetNativeView()->SetName("WindowTypeLauncher");
198 wm::SetShadowType(widget->GetNativeView(),
199 wm::SHADOW_TYPE_RECTANGULAR);
200 widget->Show();
203 WindowTypeLauncher::WindowTypeLauncher()
204 : create_button_(new views::LabelButton(
205 this, base::ASCIIToUTF16("Create Window"))),
206 panel_button_(new views::LabelButton(
207 this, base::ASCIIToUTF16("Create Panel"))),
208 create_nonresizable_button_(new views::LabelButton(
209 this, base::ASCIIToUTF16("Create Non-Resizable Window"))),
210 bubble_button_(new views::LabelButton(
211 this, base::ASCIIToUTF16("Create Pointy Bubble"))),
212 lock_button_(new views::LabelButton(
213 this, base::ASCIIToUTF16("Lock Screen"))),
214 widgets_button_(new views::LabelButton(
215 this, base::ASCIIToUTF16("Show Example Widgets"))),
216 system_modal_button_(new views::LabelButton(
217 this, base::ASCIIToUTF16("Open System Modal Window"))),
218 window_modal_button_(new views::LabelButton(
219 this, base::ASCIIToUTF16("Open Window Modal Window"))),
220 child_modal_button_(new views::LabelButton(
221 this, base::ASCIIToUTF16("Open Child Modal Window"))),
222 transient_button_(new views::LabelButton(
223 this, base::ASCIIToUTF16("Open Non-Modal Transient Window"))),
224 examples_button_(new views::LabelButton(
225 this, base::ASCIIToUTF16("Open Views Examples Window"))),
226 show_hide_window_button_(new views::LabelButton(
227 this, base::ASCIIToUTF16("Show/Hide a Window"))),
228 show_screensaver_(new views::LabelButton(
229 this, base::ASCIIToUTF16("Show the Screensaver [for 5 seconds]"))),
230 show_web_notification_(new views::LabelButton(
231 this, base::ASCIIToUTF16("Show a web/app notification"))) {
232 create_button_->SetStyle(views::Button::STYLE_BUTTON);
233 panel_button_->SetStyle(views::Button::STYLE_BUTTON);
234 create_nonresizable_button_->SetStyle(views::Button::STYLE_BUTTON);
235 bubble_button_->SetStyle(views::Button::STYLE_BUTTON);
236 lock_button_->SetStyle(views::Button::STYLE_BUTTON);
237 widgets_button_->SetStyle(views::Button::STYLE_BUTTON);
238 system_modal_button_->SetStyle(views::Button::STYLE_BUTTON);
239 window_modal_button_->SetStyle(views::Button::STYLE_BUTTON);
240 child_modal_button_->SetStyle(views::Button::STYLE_BUTTON);
241 transient_button_->SetStyle(views::Button::STYLE_BUTTON);
242 examples_button_->SetStyle(views::Button::STYLE_BUTTON);
243 show_hide_window_button_->SetStyle(views::Button::STYLE_BUTTON);
244 show_screensaver_->SetStyle(views::Button::STYLE_BUTTON);
245 show_web_notification_->SetStyle(views::Button::STYLE_BUTTON);
247 views::GridLayout* layout = new views::GridLayout(this);
248 layout->SetInsets(5, 5, 5, 5);
249 SetLayoutManager(layout);
250 views::ColumnSet* column_set = layout->AddColumnSet(0);
251 column_set->AddColumn(views::GridLayout::LEADING,
252 views::GridLayout::CENTER,
254 views::GridLayout::USE_PREF,
257 AddViewToLayout(layout, create_button_);
258 AddViewToLayout(layout, panel_button_);
259 AddViewToLayout(layout, create_nonresizable_button_);
260 AddViewToLayout(layout, bubble_button_);
261 AddViewToLayout(layout, lock_button_);
262 AddViewToLayout(layout, widgets_button_);
263 AddViewToLayout(layout, system_modal_button_);
264 AddViewToLayout(layout, window_modal_button_);
265 AddViewToLayout(layout, child_modal_button_);
266 AddViewToLayout(layout, transient_button_);
267 AddViewToLayout(layout, examples_button_);
268 AddViewToLayout(layout, show_hide_window_button_);
269 AddViewToLayout(layout, show_screensaver_);
270 AddViewToLayout(layout, show_web_notification_);
271 set_context_menu_controller(this);
274 WindowTypeLauncher::~WindowTypeLauncher() {
277 void WindowTypeLauncher::OnPaint(gfx::Canvas* canvas) {
278 canvas->FillRect(GetLocalBounds(), SK_ColorWHITE);
281 bool WindowTypeLauncher::OnMousePressed(const ui::MouseEvent& event) {
282 // Overridden so we get OnMouseReleased and can show the context menu.
283 return true;
286 views::View* WindowTypeLauncher::GetContentsView() {
287 return this;
290 bool WindowTypeLauncher::CanResize() const {
291 return true;
294 base::string16 WindowTypeLauncher::GetWindowTitle() const {
295 return base::ASCIIToUTF16("Examples: Window Builder");
298 bool WindowTypeLauncher::CanMaximize() const {
299 return true;
302 bool WindowTypeLauncher::CanMinimize() const {
303 return true;
306 void WindowTypeLauncher::ButtonPressed(views::Button* sender,
307 const ui::Event& event) {
308 if (sender == create_button_) {
309 ToplevelWindow::CreateParams params;
310 params.can_resize = true;
311 params.can_maximize = true;
312 ToplevelWindow::CreateToplevelWindow(params);
313 } else if (sender == panel_button_) {
314 PanelWindow::CreatePanelWindow(gfx::Rect());
315 } else if (sender == create_nonresizable_button_) {
316 ToplevelWindow::CreateToplevelWindow(ToplevelWindow::CreateParams());
317 } else if (sender == bubble_button_) {
318 CreatePointyBubble(sender);
319 } else if (sender == lock_button_) {
320 Shell::GetInstance()->session_state_delegate()->LockScreen();
321 } else if (sender == widgets_button_) {
322 CreateWidgetsWindow();
323 } else if (sender == system_modal_button_) {
324 ModalWindow::OpenModalWindow(GetWidget()->GetNativeView(),
325 ui::MODAL_TYPE_SYSTEM);
326 } else if (sender == window_modal_button_) {
327 ModalWindow::OpenModalWindow(GetWidget()->GetNativeView(),
328 ui::MODAL_TYPE_WINDOW);
329 } else if (sender == child_modal_button_) {
330 ash::test::CreateChildModalParent(
331 GetWidget()->GetNativeView()->GetRootWindow());
332 } else if (sender == transient_button_) {
333 NonModalTransient::OpenNonModalTransient(GetWidget()->GetNativeView());
334 } else if (sender == show_hide_window_button_) {
335 NonModalTransient::ToggleNonModalTransient(GetWidget()->GetNativeView());
336 } else if (sender == show_screensaver_) {
337 ash::ShowScreensaver(GURL("http://www.google.com"));
338 content::BrowserThread::PostDelayedTask(content::BrowserThread::UI,
339 FROM_HERE,
340 base::Bind(&ash::CloseScreensaver),
341 base::TimeDelta::FromSeconds(5));
343 } else if (sender == show_web_notification_) {
344 scoped_ptr<message_center::Notification> notification;
345 notification.reset(new message_center::Notification(
346 message_center::NOTIFICATION_TYPE_SIMPLE,
347 "id0",
348 base::ASCIIToUTF16("Test Shell Web Notification"),
349 base::ASCIIToUTF16("Notification message body."),
350 gfx::Image(),
351 base::ASCIIToUTF16("www.testshell.org"),
352 message_center::NotifierId(
353 message_center::NotifierId::APPLICATION, "test-id"),
354 message_center::RichNotificationData(),
355 NULL /* delegate */));
357 ash::Shell::GetPrimaryRootWindowController()->shelf()->status_area_widget()
358 ->web_notification_tray()->message_center()
359 ->AddNotification(notification.Pass());
360 } else if (sender == examples_button_) {
361 views::examples::ShowExamplesWindowWithContent(
362 views::examples::DO_NOTHING_ON_CLOSE,
363 Shell::GetInstance()->delegate()->GetActiveBrowserContext(),
364 NULL);
368 void WindowTypeLauncher::ExecuteCommand(int id, int event_flags) {
369 switch (id) {
370 case COMMAND_NEW_WINDOW:
371 InitWindowTypeLauncher();
372 break;
373 case COMMAND_TOGGLE_FULLSCREEN:
374 GetWidget()->SetFullscreen(!GetWidget()->IsFullscreen());
375 break;
376 default:
377 break;
381 void WindowTypeLauncher::ShowContextMenuForView(
382 views::View* source,
383 const gfx::Point& point,
384 ui::MenuSourceType source_type) {
385 MenuItemView* root = new MenuItemView(this);
386 root->AppendMenuItem(COMMAND_NEW_WINDOW,
387 base::ASCIIToUTF16("New Window"),
388 MenuItemView::NORMAL);
389 root->AppendMenuItem(COMMAND_TOGGLE_FULLSCREEN,
390 base::ASCIIToUTF16("Toggle FullScreen"),
391 MenuItemView::NORMAL);
392 // MenuRunner takes ownership of root.
393 menu_runner_.reset(new MenuRunner(
394 root, MenuRunner::HAS_MNEMONICS | views::MenuRunner::CONTEXT_MENU));
395 if (menu_runner_->RunMenuAt(GetWidget(),
396 NULL,
397 gfx::Rect(point, gfx::Size()),
398 views::MENU_ANCHOR_TOPLEFT,
399 source_type) == MenuRunner::MENU_DELETED) {
400 return;
404 } // namespace shell
405 } // namespace ash