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