1 // Copyright 2014 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 "mojo/examples/wm_flow/wm/frame_controller.h" 6 7 #include "base/strings/utf_string_conversions.h" 8 #include "mojo/services/public/cpp/view_manager/view.h" 9 #include "mojo/views/native_widget_view_manager.h" 10 #include "ui/views/background.h" 11 #include "ui/views/controls/button/label_button.h" 12 #include "ui/views/layout/layout_manager.h" 13 #include "ui/views/widget/widget.h" 14 15 class FrameController::LayoutManager : public views::LayoutManager, 16 public views::ButtonListener { 17 public: 18 explicit LayoutManager(FrameController* controller) 19 : controller_(controller), 20 close_button_( 21 new views::LabelButton(this, base::ASCIIToUTF16("Begone"))), 22 maximize_button_( 23 new views::LabelButton(this, base::ASCIIToUTF16("Embiggen"))) {} 24 virtual ~LayoutManager() {} 25 26 private: 27 static const int kButtonFrameMargin = 5; 28 static const int kButtonFrameSpacing = 2; 29 static const int kFrameSize = 10; 30 31 // Overridden from views::LayoutManager: 32 virtual void Installed(views::View* host) OVERRIDE { 33 host->AddChildView(close_button_); 34 host->AddChildView(maximize_button_); 35 } 36 virtual void Layout(views::View* host) OVERRIDE { 37 gfx::Size ps = close_button_->GetPreferredSize(); 38 gfx::Rect bounds = host->GetLocalBounds(); 39 close_button_->SetBounds(bounds.right() - kButtonFrameMargin - ps.width(), 40 kButtonFrameMargin, ps.width(), ps.height()); 41 42 ps = maximize_button_->GetPreferredSize(); 43 maximize_button_->SetBounds( 44 close_button_->x() - kButtonFrameSpacing - ps.width(), 45 kButtonFrameMargin, ps.width(), ps.height()); 46 47 bounds.Inset(kFrameSize, 48 close_button_->bounds().bottom() + kButtonFrameMargin, 49 kFrameSize, kFrameSize); 50 controller_->app_view_->SetBounds(bounds); 51 } 52 virtual gfx::Size GetPreferredSize(const views::View* host) const OVERRIDE { 53 return gfx::Size(); 54 } 55 56 // Overridden from views::ButtonListener: 57 virtual void ButtonPressed(views::Button* sender, 58 const ui::Event& event) OVERRIDE { 59 if (sender == close_button_) 60 controller_->CloseWindow(); 61 else if (sender == maximize_button_) 62 controller_->ToggleMaximize(); 63 } 64 65 FrameController* controller_; 66 views::Button* close_button_; 67 views::Button* maximize_button_; 68 69 DISALLOW_COPY_AND_ASSIGN(LayoutManager); 70 }; 71 72 //////////////////////////////////////////////////////////////////////////////// 73 // FrameController, public: 74 75 FrameController::FrameController(mojo::View* view, mojo::View** app_view) 76 : view_(view), 77 app_view_(mojo::View::Create(view->view_manager())), 78 frame_view_(new views::View), 79 frame_view_layout_manager_(new LayoutManager(this)), 80 widget_(new views::Widget), 81 maximized_(false) { 82 view_->AddChild(app_view_); 83 view_->AddObserver(this); 84 *app_view = app_view_; 85 frame_view_->set_background( 86 views::Background::CreateSolidBackground(SK_ColorBLUE)); 87 frame_view_->SetLayoutManager(frame_view_layout_manager_); 88 views::Widget::InitParams params( 89 views::Widget::InitParams::TYPE_WINDOW_FRAMELESS); 90 params.native_widget = new mojo::NativeWidgetViewManager(widget_, view_); 91 params.bounds = gfx::Rect(view_->bounds().size()); 92 widget_->Init(params); 93 widget_->SetContentsView(frame_view_); 94 widget_->Show(); 95 } 96 97 FrameController::~FrameController() {} 98 99 void FrameController::CloseWindow() { 100 app_view_->Destroy(); 101 view_->Destroy(); 102 } 103 104 void FrameController::ToggleMaximize() { 105 if (!maximized_) 106 restored_bounds_ = view_->bounds(); 107 maximized_ = !maximized_; 108 if (maximized_) 109 view_->SetBounds(view_->parent()->bounds()); 110 else 111 view_->SetBounds(restored_bounds_); 112 } 113 114 //////////////////////////////////////////////////////////////////////////////// 115 // FrameController, mojo::ViewObserver implementation: 116 117 void FrameController::OnViewDestroyed(mojo::View* view) { 118 view_->RemoveObserver(this); 119 delete this; 120 } 121