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