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