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/session/session_state_delegate.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 "ash/test/child_modal_window.h"
19 #include "base/strings/utf_string_conversions.h"
20 #include "ui/aura/window.h"
21 #include "ui/aura/window_event_dispatcher.h"
22 #include "ui/compositor/layer.h"
23 #include "ui/gfx/canvas.h"
24 #include "ui/message_center/message_center.h"
25 #include "ui/message_center/notification_types.h"
26 #include "ui/views/controls/button/label_button.h"
27 #include "ui/views/controls/menu/menu_item_view.h"
28 #include "ui/views/controls/menu/menu_runner.h"
29 #include "ui/views/examples/examples_window_with_content.h"
30 #include "ui/views/layout/grid_layout.h"
31 #include "ui/views/widget/widget.h"
32 #include "ui/wm/core/shadow_types.h"
34 using views::MenuItemView
;
35 using views::MenuRunner
;
42 SkColor g_colors
[] = { SK_ColorRED
,
46 int g_color_index
= 0;
48 class ModalWindow
: public views::WidgetDelegateView
,
49 public views::ButtonListener
{
51 explicit ModalWindow(ui::ModalType modal_type
)
52 : modal_type_(modal_type
),
53 color_(g_colors
[g_color_index
]),
54 open_button_(new views::LabelButton(this,
55 base::ASCIIToUTF16("Moar!"))) {
56 ++g_color_index
%= arraysize(g_colors
);
57 open_button_
->SetStyle(views::Button::STYLE_BUTTON
);
58 AddChildView(open_button_
);
60 ~ModalWindow() override
{}
62 static void OpenModalWindow(aura::Window
* parent
, ui::ModalType modal_type
) {
63 views::Widget
* widget
=
64 views::Widget::CreateWindowWithParent(new ModalWindow(modal_type
),
66 widget
->GetNativeView()->SetName("ModalWindow");
70 // Overridden from views::View:
71 void OnPaint(gfx::Canvas
* canvas
) override
{
72 canvas
->FillRect(GetLocalBounds(), color_
);
74 gfx::Size
GetPreferredSize() const override
{ return gfx::Size(200, 200); }
75 void Layout() override
{
76 gfx::Size open_ps
= open_button_
->GetPreferredSize();
77 gfx::Rect local_bounds
= GetLocalBounds();
78 open_button_
->SetBounds(
79 5, local_bounds
.bottom() - open_ps
.height() - 5,
80 open_ps
.width(), open_ps
.height());
83 // Overridden from views::WidgetDelegate:
84 views::View
* GetContentsView() override
{ return this; }
85 bool CanResize() const override
{ return true; }
86 base::string16
GetWindowTitle() const override
{
87 return base::ASCIIToUTF16("Modal Window");
89 ui::ModalType
GetModalType() const override
{ return modal_type_
; }
91 // Overridden from views::ButtonListener:
92 void ButtonPressed(views::Button
* sender
, const ui::Event
& event
) override
{
93 DCHECK(sender
== open_button_
);
94 OpenModalWindow(GetWidget()->GetNativeView(), modal_type_
);
98 ui::ModalType modal_type_
;
100 views::LabelButton
* open_button_
;
102 DISALLOW_COPY_AND_ASSIGN(ModalWindow
);
105 class NonModalTransient
: public views::WidgetDelegateView
{
108 : color_(g_colors
[g_color_index
]) {
109 ++g_color_index
%= arraysize(g_colors
);
111 ~NonModalTransient() override
{}
113 static void OpenNonModalTransient(aura::Window
* parent
) {
114 views::Widget
* widget
=
115 views::Widget::CreateWindowWithParent(new NonModalTransient
, parent
);
116 widget
->GetNativeView()->SetName("NonModalTransient");
120 static void ToggleNonModalTransient(aura::Window
* parent
) {
121 if (!non_modal_transient_
) {
122 non_modal_transient_
=
123 views::Widget::CreateWindowWithParent(new NonModalTransient
, parent
);
124 non_modal_transient_
->GetNativeView()->SetName("NonModalTransient");
126 if (non_modal_transient_
->IsVisible())
127 non_modal_transient_
->Hide();
129 non_modal_transient_
->Show();
132 // Overridden from views::View:
133 void OnPaint(gfx::Canvas
* canvas
) override
{
134 canvas
->FillRect(GetLocalBounds(), color_
);
136 gfx::Size
GetPreferredSize() const override
{ return gfx::Size(250, 250); }
138 // Overridden from views::WidgetDelegate:
139 views::View
* GetContentsView() override
{ return this; }
140 bool CanResize() const override
{ return true; }
141 base::string16
GetWindowTitle() const override
{
142 return base::ASCIIToUTF16("Non-Modal Transient");
144 void DeleteDelegate() override
{
145 if (GetWidget() == non_modal_transient_
)
146 non_modal_transient_
= NULL
;
154 static views::Widget
* non_modal_transient_
;
156 DISALLOW_COPY_AND_ASSIGN(NonModalTransient
);
160 views::Widget
* NonModalTransient::non_modal_transient_
= NULL
;
162 void AddViewToLayout(views::GridLayout
* layout
, views::View
* view
) {
163 layout
->StartRow(0, 0);
164 layout
->AddView(view
);
165 layout
->AddPaddingRow(0, 5);
170 void InitWindowTypeLauncher() {
171 views::Widget
* widget
=
172 views::Widget::CreateWindowWithContextAndBounds(
173 new WindowTypeLauncher
,
174 Shell::GetPrimaryRootWindow(),
175 gfx::Rect(120, 150, 300, 410));
176 widget
->GetNativeView()->SetName("WindowTypeLauncher");
177 wm::SetShadowType(widget
->GetNativeView(),
178 wm::SHADOW_TYPE_RECTANGULAR
);
182 WindowTypeLauncher::WindowTypeLauncher()
183 : create_button_(new views::LabelButton(
184 this, base::ASCIIToUTF16("Create Window"))),
185 panel_button_(new views::LabelButton(
186 this, base::ASCIIToUTF16("Create Panel"))),
187 create_nonresizable_button_(new views::LabelButton(
188 this, base::ASCIIToUTF16("Create Non-Resizable Window"))),
189 bubble_button_(new views::LabelButton(
190 this, base::ASCIIToUTF16("Create Pointy Bubble"))),
191 lock_button_(new views::LabelButton(
192 this, base::ASCIIToUTF16("Lock Screen"))),
193 widgets_button_(new views::LabelButton(
194 this, base::ASCIIToUTF16("Show Example Widgets"))),
195 system_modal_button_(new views::LabelButton(
196 this, base::ASCIIToUTF16("Open System Modal Window"))),
197 window_modal_button_(new views::LabelButton(
198 this, base::ASCIIToUTF16("Open Window Modal Window"))),
199 child_modal_button_(new views::LabelButton(
200 this, base::ASCIIToUTF16("Open Child Modal Window"))),
201 transient_button_(new views::LabelButton(
202 this, base::ASCIIToUTF16("Open Non-Modal Transient Window"))),
203 examples_button_(new views::LabelButton(
204 this, base::ASCIIToUTF16("Open Views Examples Window"))),
205 show_hide_window_button_(new views::LabelButton(
206 this, base::ASCIIToUTF16("Show/Hide a Window"))),
207 show_web_notification_(new views::LabelButton(
208 this, base::ASCIIToUTF16("Show a web/app notification"))) {
209 create_button_
->SetStyle(views::Button::STYLE_BUTTON
);
210 panel_button_
->SetStyle(views::Button::STYLE_BUTTON
);
211 create_nonresizable_button_
->SetStyle(views::Button::STYLE_BUTTON
);
212 bubble_button_
->SetStyle(views::Button::STYLE_BUTTON
);
213 lock_button_
->SetStyle(views::Button::STYLE_BUTTON
);
214 widgets_button_
->SetStyle(views::Button::STYLE_BUTTON
);
215 system_modal_button_
->SetStyle(views::Button::STYLE_BUTTON
);
216 window_modal_button_
->SetStyle(views::Button::STYLE_BUTTON
);
217 child_modal_button_
->SetStyle(views::Button::STYLE_BUTTON
);
218 transient_button_
->SetStyle(views::Button::STYLE_BUTTON
);
219 examples_button_
->SetStyle(views::Button::STYLE_BUTTON
);
220 show_hide_window_button_
->SetStyle(views::Button::STYLE_BUTTON
);
221 show_web_notification_
->SetStyle(views::Button::STYLE_BUTTON
);
223 views::GridLayout
* layout
= new views::GridLayout(this);
224 layout
->SetInsets(5, 5, 5, 5);
225 SetLayoutManager(layout
);
226 views::ColumnSet
* column_set
= layout
->AddColumnSet(0);
227 column_set
->AddColumn(views::GridLayout::LEADING
,
228 views::GridLayout::CENTER
,
230 views::GridLayout::USE_PREF
,
233 AddViewToLayout(layout
, create_button_
);
234 AddViewToLayout(layout
, panel_button_
);
235 AddViewToLayout(layout
, create_nonresizable_button_
);
236 AddViewToLayout(layout
, bubble_button_
);
237 AddViewToLayout(layout
, lock_button_
);
238 AddViewToLayout(layout
, widgets_button_
);
239 AddViewToLayout(layout
, system_modal_button_
);
240 AddViewToLayout(layout
, window_modal_button_
);
241 AddViewToLayout(layout
, child_modal_button_
);
242 AddViewToLayout(layout
, transient_button_
);
243 AddViewToLayout(layout
, examples_button_
);
244 AddViewToLayout(layout
, show_hide_window_button_
);
245 AddViewToLayout(layout
, show_web_notification_
);
246 set_context_menu_controller(this);
249 WindowTypeLauncher::~WindowTypeLauncher() {
252 void WindowTypeLauncher::OnPaint(gfx::Canvas
* canvas
) {
253 canvas
->FillRect(GetLocalBounds(), SK_ColorWHITE
);
256 bool WindowTypeLauncher::OnMousePressed(const ui::MouseEvent
& event
) {
257 // Overridden so we get OnMouseReleased and can show the context menu.
261 views::View
* WindowTypeLauncher::GetContentsView() {
265 bool WindowTypeLauncher::CanResize() const {
269 base::string16
WindowTypeLauncher::GetWindowTitle() const {
270 return base::ASCIIToUTF16("Examples: Window Builder");
273 bool WindowTypeLauncher::CanMaximize() const {
277 bool WindowTypeLauncher::CanMinimize() const {
281 void WindowTypeLauncher::ButtonPressed(views::Button
* sender
,
282 const ui::Event
& event
) {
283 if (sender
== create_button_
) {
284 ToplevelWindow::CreateParams params
;
285 params
.can_resize
= true;
286 params
.can_maximize
= true;
287 ToplevelWindow::CreateToplevelWindow(params
);
288 } else if (sender
== panel_button_
) {
289 PanelWindow::CreatePanelWindow(gfx::Rect());
290 } else if (sender
== create_nonresizable_button_
) {
291 ToplevelWindow::CreateToplevelWindow(ToplevelWindow::CreateParams());
292 } else if (sender
== bubble_button_
) {
293 CreatePointyBubble(sender
);
294 } else if (sender
== lock_button_
) {
295 Shell::GetInstance()->session_state_delegate()->LockScreen();
296 } else if (sender
== widgets_button_
) {
297 CreateWidgetsWindow();
298 } else if (sender
== system_modal_button_
) {
299 ModalWindow::OpenModalWindow(GetWidget()->GetNativeView(),
300 ui::MODAL_TYPE_SYSTEM
);
301 } else if (sender
== window_modal_button_
) {
302 ModalWindow::OpenModalWindow(GetWidget()->GetNativeView(),
303 ui::MODAL_TYPE_WINDOW
);
304 } else if (sender
== child_modal_button_
) {
305 ash::test::CreateChildModalParent(
306 GetWidget()->GetNativeView()->GetRootWindow());
307 } else if (sender
== transient_button_
) {
308 NonModalTransient::OpenNonModalTransient(GetWidget()->GetNativeView());
309 } else if (sender
== show_hide_window_button_
) {
310 NonModalTransient::ToggleNonModalTransient(GetWidget()->GetNativeView());
311 } else if (sender
== show_web_notification_
) {
312 scoped_ptr
<message_center::Notification
> notification
;
313 notification
.reset(new message_center::Notification(
314 message_center::NOTIFICATION_TYPE_SIMPLE
,
316 base::ASCIIToUTF16("Test Shell Web Notification"),
317 base::ASCIIToUTF16("Notification message body."),
319 base::ASCIIToUTF16("www.testshell.org"),
320 message_center::NotifierId(
321 message_center::NotifierId::APPLICATION
, "test-id"),
322 message_center::RichNotificationData(),
323 NULL
/* delegate */));
325 ash::Shell::GetPrimaryRootWindowController()->shelf()->status_area_widget()
326 ->web_notification_tray()->message_center()
327 ->AddNotification(notification
.Pass());
328 } else if (sender
== examples_button_
) {
329 views::examples::ShowExamplesWindowWithContent(
330 views::examples::DO_NOTHING_ON_CLOSE
,
331 Shell::GetInstance()->delegate()->GetActiveBrowserContext(),
336 void WindowTypeLauncher::ExecuteCommand(int id
, int event_flags
) {
338 case COMMAND_NEW_WINDOW
:
339 InitWindowTypeLauncher();
341 case COMMAND_TOGGLE_FULLSCREEN
:
342 GetWidget()->SetFullscreen(!GetWidget()->IsFullscreen());
349 void WindowTypeLauncher::ShowContextMenuForView(
351 const gfx::Point
& point
,
352 ui::MenuSourceType source_type
) {
353 MenuItemView
* root
= new MenuItemView(this);
354 root
->AppendMenuItem(COMMAND_NEW_WINDOW
,
355 base::ASCIIToUTF16("New Window"),
356 MenuItemView::NORMAL
);
357 root
->AppendMenuItem(COMMAND_TOGGLE_FULLSCREEN
,
358 base::ASCIIToUTF16("Toggle FullScreen"),
359 MenuItemView::NORMAL
);
360 // MenuRunner takes ownership of root.
361 menu_runner_
.reset(new MenuRunner(
362 root
, MenuRunner::HAS_MNEMONICS
| views::MenuRunner::CONTEXT_MENU
));
363 if (menu_runner_
->RunMenuAt(GetWidget(),
365 gfx::Rect(point
, gfx::Size()),
366 views::MENU_ANCHOR_TOPLEFT
,
367 source_type
) == MenuRunner::MENU_DELETED
) {