text: // Copyright (c) 2012 The Chromium Authors. All rights reserved.
  // Use of this source code is governed by a BSD-style license that can be
  // found in the LICENSE file.
  
  #include "ash/shell/window_type_launcher.h"
  
  #include "ash/root_window_controller.h"
  #include "ash/screensaver/screensaver_view.h"
  #include "ash/session_state_delegate.h"
  #include "ash/shelf/shelf_widget.h"
  #include "ash/shell.h"
  #include "ash/shell/example_factory.h"
  #include "ash/shell/panel_window.h"
  #include "ash/shell/toplevel_window.h"
  #include "ash/shell_delegate.h"
  #include "ash/shell_window_ids.h"
  #include "ash/system/status_area_widget.h"
  #include "ash/system/web_notification/web_notification_tray.h"
  #include "base/bind.h"
  #include "base/strings/utf_string_conversions.h"
  #include "base/time/time.h"
  #include "content/public/browser/browser_thread.h"
  #include "ui/aura/window.h"
  #include "ui/aura/window_event_dispatcher.h"
  #include "ui/compositor/layer.h"
  #include "ui/gfx/canvas.h"
  #include "ui/message_center/message_center.h"
  #include "ui/message_center/notification_types.h"
  #include "ui/views/controls/button/label_button.h"
  #include "ui/views/controls/menu/menu_item_view.h"
  #include "ui/views/controls/menu/menu_runner.h"
  #include "ui/views/examples/examples_window_with_content.h"
  #include "ui/views/layout/grid_layout.h"
  #include "ui/views/test/child_modal_window.h"
  #include "ui/views/widget/widget.h"
  #include "ui/wm/core/shadow_types.h"
  
  using views::MenuItemView;
  using views::MenuRunner;
  
  namespace ash {
  namespace shell {
  
  namespace {
  
  SkColor g_colors[] = { SK_ColorRED,
                         SK_ColorYELLOW,
                         SK_ColorBLUE,
                         SK_ColorGREEN };
  int g_color_index = 0;
  
  class ModalWindow : public views::WidgetDelegateView,
                      public views::ButtonListener {
   public:
    explicit ModalWindow(ui::ModalType modal_type)
        : modal_type_(modal_type),
          color_(g_colors[g_color_index]),
          open_button_(new views::LabelButton(this,
                                              base::ASCIIToUTF16("Moar!"))) {
      ++g_color_index %= arraysize(g_colors);
      open_button_->SetStyle(views::Button::STYLE_BUTTON);
      AddChildView(open_button_);
    }
    virtual ~ModalWindow() {
    }
  
    static void OpenModalWindow(aura::Window* parent, ui::ModalType modal_type) {
      views::Widget* widget =
          views::Widget::CreateWindowWithParent(new ModalWindow(modal_type),
                                                parent);
      widget->GetNativeView()->SetName("ModalWindow");
      widget->Show();
    }
  
    // Overridden from views::View:
    virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE {
      canvas->FillRect(GetLocalBounds(), color_);
    }
    virtual gfx::Size GetPreferredSize() OVERRIDE {
      return gfx::Size(200, 200);
    }
    virtual void Layout() OVERRIDE {
      gfx::Size open_ps = open_button_->GetPreferredSize();
      gfx::Rect local_bounds = GetLocalBounds();
      open_button_->SetBounds(
          5, local_bounds.bottom() - open_ps.height() - 5,
          open_ps.width(), open_ps.height());
    }
  
    // Overridden from views::WidgetDelegate:
    virtual views::View* GetContentsView() OVERRIDE {
      return this;
    }
    virtual bool CanResize() const OVERRIDE {
      return true;
    }
    virtual base::string16 GetWindowTitle() const OVERRIDE {
      return base::ASCIIToUTF16("Modal Window");
    }
    virtual ui::ModalType GetModalType() const OVERRIDE {
      return modal_type_;
    }
  
    // Overridden from views::ButtonListener:
    virtual void ButtonPressed(views::Button* sender,
                               const ui::Event& event) OVERRIDE {
      DCHECK(sender == open_button_);
      OpenModalWindow(GetWidget()->GetNativeView(), modal_type_);
    }
  
   private:
    ui::ModalType modal_type_;
    SkColor color_;
    views::LabelButton* open_button_;
  
    DISALLOW_COPY_AND_ASSIGN(ModalWindow);
  };
  
  class NonModalTransient : public views::WidgetDelegateView {
   public:
    NonModalTransient()
        : color_(g_colors[g_color_index]) {
      ++g_color_index %= arraysize(g_colors);
    }
    virtual ~NonModalTransient() {
    }
  
    static void OpenNonModalTransient(aura::Window* parent) {
      views::Widget* widget =
          views::Widget::CreateWindowWithParent(new NonModalTransient, parent);
      widget->GetNativeView()->SetName("NonModalTransient");
      widget->Show();
    }
  
    static void ToggleNonModalTransient(aura::Window* parent) {
      if (!non_modal_transient_) {
        non_modal_transient_ =
            views::Widget::CreateWindowWithParent(new NonModalTransient, parent);
        non_modal_transient_->GetNativeView()->SetName("NonModalTransient");
      }
      if (non_modal_transient_->IsVisible())
        non_modal_transient_->Hide();
      else
        non_modal_transient_->Show();
    }
  
    // Overridden from views::View:
    virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE {
      canvas->FillRect(GetLocalBounds(), color_);
    }
    virtual gfx::Size GetPreferredSize() OVERRIDE {
      return gfx::Size(250, 250);
    }
  
    // Overridden from views::WidgetDelegate:
    virtual views::View* GetContentsView() OVERRIDE {
      return this;
    }
    virtual bool CanResize() const OVERRIDE {
      return true;
    }
    virtual base::string16 GetWindowTitle() const OVERRIDE {
      return base::ASCIIToUTF16("Non-Modal Transient");
    }
    virtual void DeleteDelegate() OVERRIDE {
      if (GetWidget() == non_modal_transient_)
        non_modal_transient_ = NULL;
  
      delete this;
    }
  
   private:
    SkColor color_;
  
    static views::Widget* non_modal_transient_;
  
    DISALLOW_COPY_AND_ASSIGN(NonModalTransient);
  };
  
  // static
  views::Widget* NonModalTransient::non_modal_transient_ = NULL;
  
  void AddViewToLayout(views::GridLayout* layout, views::View* view) {
    layout->StartRow(0, 0);
    layout->AddView(view);
    layout->AddPaddingRow(0, 5);
  }
  
  }  // namespace
  
  void InitWindowTypeLauncher() {
    views::Widget* widget =
        views::Widget::CreateWindowWithContextAndBounds(
            new WindowTypeLauncher,
            Shell::GetPrimaryRootWindow(),
            gfx::Rect(120, 150, 300, 410));
    widget->GetNativeView()->SetName("WindowTypeLauncher");
    wm::SetShadowType(widget->GetNativeView(),
                                 wm::SHADOW_TYPE_RECTANGULAR);
    widget->Show();
  }
  
  WindowTypeLauncher::WindowTypeLauncher()
      : create_button_(new views::LabelButton(
            this, base::ASCIIToUTF16("Create Window"))),
        panel_button_(new views::LabelButton(
            this, base::ASCIIToUTF16("Create Panel"))),
        create_nonresizable_button_(new views::LabelButton(
            this, base::ASCIIToUTF16("Create Non-Resizable Window"))),
        bubble_button_(new views::LabelButton(
            this, base::ASCIIToUTF16("Create Pointy Bubble"))),
        lock_button_(new views::LabelButton(
            this, base::ASCIIToUTF16("Lock Screen"))),
        widgets_button_(new views::LabelButton(
            this, base::ASCIIToUTF16("Show Example Widgets"))),
        system_modal_button_(new views::LabelButton(
            this, base::ASCIIToUTF16("Open System Modal Window"))),
        window_modal_button_(new views::LabelButton(
            this, base::ASCIIToUTF16("Open Window Modal Window"))),
        child_modal_button_(new views::LabelButton(
            this, base::ASCIIToUTF16("Open Child Modal Window"))),
        transient_button_(new views::LabelButton(
            this, base::ASCIIToUTF16("Open Non-Modal Transient Window"))),
        examples_button_(new views::LabelButton(
            this, base::ASCIIToUTF16("Open Views Examples Window"))),
        show_hide_window_button_(new views::LabelButton(
            this, base::ASCIIToUTF16("Show/Hide a Window"))),
        show_screensaver_(new views::LabelButton(
            this, base::ASCIIToUTF16("Show the Screensaver [for 5 seconds]"))),
        show_web_notification_(new views::LabelButton(
            this, base::ASCIIToUTF16("Show a web/app notification"))) {
    create_button_->SetStyle(views::Button::STYLE_BUTTON);
    panel_button_->SetStyle(views::Button::STYLE_BUTTON);
    create_nonresizable_button_->SetStyle(views::Button::STYLE_BUTTON);
    bubble_button_->SetStyle(views::Button::STYLE_BUTTON);
    lock_button_->SetStyle(views::Button::STYLE_BUTTON);
    widgets_button_->SetStyle(views::Button::STYLE_BUTTON);
    system_modal_button_->SetStyle(views::Button::STYLE_BUTTON);
    window_modal_button_->SetStyle(views::Button::STYLE_BUTTON);
    child_modal_button_->SetStyle(views::Button::STYLE_BUTTON);
    transient_button_->SetStyle(views::Button::STYLE_BUTTON);
    examples_button_->SetStyle(views::Button::STYLE_BUTTON);
    show_hide_window_button_->SetStyle(views::Button::STYLE_BUTTON);
    show_screensaver_->SetStyle(views::Button::STYLE_BUTTON);
    show_web_notification_->SetStyle(views::Button::STYLE_BUTTON);
  
    views::GridLayout* layout = new views::GridLayout(this);
    layout->SetInsets(5, 5, 5, 5);
    SetLayoutManager(layout);
    views::ColumnSet* column_set = layout->AddColumnSet(0);
    column_set->AddColumn(views::GridLayout::LEADING,
                          views::GridLayout::CENTER,
                          0,
                          views::GridLayout::USE_PREF,
                          0,
                          0);
    AddViewToLayout(layout, create_button_);
    AddViewToLayout(layout, panel_button_);
    AddViewToLayout(layout, create_nonresizable_button_);
    AddViewToLayout(layout, bubble_button_);
    AddViewToLayout(layout, lock_button_);
    AddViewToLayout(layout, widgets_button_);
    AddViewToLayout(layout, system_modal_button_);
    AddViewToLayout(layout, window_modal_button_);
    AddViewToLayout(layout, child_modal_button_);
    AddViewToLayout(layout, transient_button_);
    AddViewToLayout(layout, examples_button_);
    AddViewToLayout(layout, show_hide_window_button_);
    AddViewToLayout(layout, show_screensaver_);
    AddViewToLayout(layout, show_web_notification_);
    set_context_menu_controller(this);
  }
  
  WindowTypeLauncher::~WindowTypeLauncher() {
  }
  
  void WindowTypeLauncher::OnPaint(gfx::Canvas* canvas) {
    canvas->FillRect(GetLocalBounds(), SK_ColorWHITE);
  }
  
  bool WindowTypeLauncher::OnMousePressed(const ui::MouseEvent& event) {
    // Overridden so we get OnMouseReleased and can show the context menu.
    return true;
  }
  
  views::View* WindowTypeLauncher::GetContentsView() {
    return this;
  }
  
  bool WindowTypeLauncher::CanResize() const {
    return true;
  }
  
  base::string16 WindowTypeLauncher::GetWindowTitle() const {
    return base::ASCIIToUTF16("Examples: Window Builder");
  }
  
  bool WindowTypeLauncher::CanMaximize() const {
    return true;
  }
  
  void WindowTypeLauncher::ButtonPressed(views::Button* sender,
                                         const ui::Event& event) {
    if (sender == create_button_) {
      ToplevelWindow::CreateParams params;
      params.can_resize = true;
      params.can_maximize = true;
      ToplevelWindow::CreateToplevelWindow(params);
    } else if (sender == panel_button_) {
      PanelWindow::CreatePanelWindow(gfx::Rect());
    } else if (sender == create_nonresizable_button_) {
      ToplevelWindow::CreateToplevelWindow(ToplevelWindow::CreateParams());
    } else if (sender == bubble_button_) {
      CreatePointyBubble(sender);
    } else if (sender == lock_button_) {
      Shell::GetInstance()->session_state_delegate()->LockScreen();
    } else if (sender == widgets_button_) {
      CreateWidgetsWindow();
    } else if (sender == system_modal_button_) {
      ModalWindow::OpenModalWindow(GetWidget()->GetNativeView(),
                                   ui::MODAL_TYPE_SYSTEM);
    } else if (sender == window_modal_button_) {
      ModalWindow::OpenModalWindow(GetWidget()->GetNativeView(),
                                   ui::MODAL_TYPE_WINDOW);
    } else if (sender == child_modal_button_) {
      views::test::CreateChildModalParent(
          GetWidget()->GetNativeView()->GetRootWindow());
    } else if (sender == transient_button_) {
      NonModalTransient::OpenNonModalTransient(GetWidget()->GetNativeView());
    } else if (sender == show_hide_window_button_) {
      NonModalTransient::ToggleNonModalTransient(GetWidget()->GetNativeView());
    } else if (sender == show_screensaver_) {
      ash::ShowScreensaver(GURL("http://www.google.com"));
      content::BrowserThread::PostDelayedTask(content::BrowserThread::UI,
                                              FROM_HERE,
                                              base::Bind(&ash::CloseScreensaver),
                                              base::TimeDelta::FromSeconds(5));
  
    } else if (sender == show_web_notification_) {
      scoped_ptr<message_center::Notification> notification;
      notification.reset(new message_center::Notification(
          message_center::NOTIFICATION_TYPE_SIMPLE,
          "id0",
          base::ASCIIToUTF16("Test Shell Web Notification"),
          base::ASCIIToUTF16("Notification message body."),
          gfx::Image(),
          base::ASCIIToUTF16("www.testshell.org"),
          message_center::NotifierId(
              message_center::NotifierId::APPLICATION, "test-id"),
          message_center::RichNotificationData(),
          NULL /* delegate */));
  
      ash::Shell::GetPrimaryRootWindowController()->shelf()->status_area_widget()
          ->web_notification_tray()->message_center()
          ->AddNotification(notification.Pass());
    } else if (sender == examples_button_) {
      views::examples::ShowExamplesWindowWithContent(
          views::examples::DO_NOTHING_ON_CLOSE,
          Shell::GetInstance()->delegate()->GetActiveBrowserContext(),
          NULL);
    }
  }
  
  void WindowTypeLauncher::ExecuteCommand(int id, int event_flags) {
    switch (id) {
      case COMMAND_NEW_WINDOW:
        InitWindowTypeLauncher();
        break;
      case COMMAND_TOGGLE_FULLSCREEN:
        GetWidget()->SetFullscreen(!GetWidget()->IsFullscreen());
        break;
      default:
        break;
    }
  }
  
  void WindowTypeLauncher::ShowContextMenuForView(
      views::View* source,
      const gfx::Point& point,
      ui::MenuSourceType source_type) {
    MenuItemView* root = new MenuItemView(this);
    root->AppendMenuItem(COMMAND_NEW_WINDOW,
                         base::ASCIIToUTF16("New Window"),
                         MenuItemView::NORMAL);
    root->AppendMenuItem(COMMAND_TOGGLE_FULLSCREEN,
                         base::ASCIIToUTF16("Toggle FullScreen"),
                         MenuItemView::NORMAL);
    // MenuRunner takes ownership of root.
    menu_runner_.reset(new MenuRunner(root));
    if (menu_runner_->RunMenuAt(GetWidget(), NULL,
          gfx::Rect(point, gfx::Size()),
          MenuItemView::TOPLEFT,
          source_type,
          MenuRunner::HAS_MNEMONICS | views::MenuRunner::CONTEXT_MENU) ==
          MenuRunner::MENU_DELETED)
      return;
  }
  
  }  // namespace shell
  }  // namespace ash
  