| OLD | NEW |
| (Empty) |
| 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 <map> | |
| 6 #include <string> | |
| 7 | |
| 8 #include "base/macros.h" | |
| 9 #include "base/memory/scoped_ptr.h" | |
| 10 #include "base/strings/utf_string_conversions.h" | |
| 11 #include "examples/media_viewer/media_viewer.mojom.h" | |
| 12 #include "mojo/application/application_runner_chromium.h" | |
| 13 #include "mojo/public/c/system/main.h" | |
| 14 #include "mojo/public/cpp/application/application_connection.h" | |
| 15 #include "mojo/public/cpp/application/application_delegate.h" | |
| 16 #include "mojo/public/cpp/application/application_impl.h" | |
| 17 #include "mojo/public/cpp/application/interface_factory_impl.h" | |
| 18 #include "mojo/public/cpp/bindings/interface_impl.h" | |
| 19 #include "mojo/services/navigation/public/interfaces/navigation.mojom.h" | |
| 20 #include "mojo/services/view_manager/public/cpp/view.h" | |
| 21 #include "mojo/services/view_manager/public/cpp/view_manager.h" | |
| 22 #include "mojo/services/view_manager/public/cpp/view_manager_client_factory.h" | |
| 23 #include "mojo/services/view_manager/public/cpp/view_manager_delegate.h" | |
| 24 #include "mojo/services/view_manager/public/cpp/view_observer.h" | |
| 25 #include "mojo/views/native_widget_view_manager.h" | |
| 26 #include "mojo/views/views_init.h" | |
| 27 #include "skia/ext/platform_canvas.h" | |
| 28 #include "skia/ext/refptr.h" | |
| 29 #include "third_party/skia/include/core/SkBitmap.h" | |
| 30 #include "third_party/skia/include/core/SkCanvas.h" | |
| 31 #include "third_party/skia/include/core/SkColor.h" | |
| 32 #include "third_party/skia/include/core/SkPaint.h" | |
| 33 #include "third_party/skia/include/core/SkRect.h" | |
| 34 #include "ui/gfx/canvas.h" | |
| 35 #include "ui/gfx/geometry/insets.h" | |
| 36 #include "ui/gfx/geometry/rect.h" | |
| 37 #include "ui/gfx/image/image_skia.h" | |
| 38 #include "ui/views/background.h" | |
| 39 #include "ui/views/border.h" | |
| 40 #include "ui/views/controls/button/button.h" | |
| 41 #include "ui/views/controls/button/label_button.h" | |
| 42 #include "ui/views/layout/box_layout.h" | |
| 43 #include "ui/views/painter.h" | |
| 44 #include "ui/views/widget/widget.h" | |
| 45 #include "ui/views/widget/widget_delegate.h" | |
| 46 | |
| 47 namespace mojo { | |
| 48 namespace examples { | |
| 49 | |
| 50 class MediaViewer; | |
| 51 | |
| 52 class CustomButtonBorder: public views::Border { | |
| 53 public: | |
| 54 CustomButtonBorder() | |
| 55 : normal_painter_(CreatePainter(SkColorSetRGB(0x80, 0x80, 0x80), | |
| 56 SkColorSetRGB(0xC0, 0xC0, 0xC0))), | |
| 57 hot_painter_(CreatePainter(SkColorSetRGB(0xA0, 0xA0, 0xA0), | |
| 58 SkColorSetRGB(0xD0, 0xD0, 0xD0))), | |
| 59 pushed_painter_(CreatePainter(SkColorSetRGB(0x80, 0x80, 0x80), | |
| 60 SkColorSetRGB(0x90, 0x90, 0x90))), | |
| 61 insets_(2, 6, 2, 6) { | |
| 62 } | |
| 63 virtual ~CustomButtonBorder() {} | |
| 64 | |
| 65 private: | |
| 66 // Overridden from views::Border: | |
| 67 virtual void Paint(const views::View& view, gfx::Canvas* canvas) override { | |
| 68 const views::LabelButton* button = | |
| 69 static_cast<const views::LabelButton*>(&view); | |
| 70 views::Button::ButtonState state = button->state(); | |
| 71 | |
| 72 views::Painter* painter = normal_painter_.get(); | |
| 73 if (state == views::Button::STATE_HOVERED) { | |
| 74 painter = hot_painter_.get(); | |
| 75 } else if (state == views::Button::STATE_PRESSED) { | |
| 76 painter = pushed_painter_.get(); | |
| 77 } | |
| 78 painter->Paint(canvas, view.size()); | |
| 79 } | |
| 80 | |
| 81 virtual gfx::Insets GetInsets() const override { | |
| 82 return insets_; | |
| 83 } | |
| 84 | |
| 85 virtual gfx::Size GetMinimumSize() const override { | |
| 86 gfx::Size size; | |
| 87 if (normal_painter_) | |
| 88 size.SetToMax(normal_painter_->GetMinimumSize()); | |
| 89 if (hot_painter_) | |
| 90 size.SetToMax(hot_painter_->GetMinimumSize()); | |
| 91 if (pushed_painter_) | |
| 92 size.SetToMax(pushed_painter_->GetMinimumSize()); | |
| 93 return size; | |
| 94 } | |
| 95 | |
| 96 scoped_ptr<views::Painter> CreatePainter(SkColor border, SkColor background) { | |
| 97 skia::RefPtr<SkCanvas> canvas(skia::AdoptRef(skia::CreatePlatformCanvas( | |
| 98 64, 64, false))); | |
| 99 SkPaint paint; | |
| 100 paint.setColor(background); | |
| 101 canvas->drawRoundRect(SkRect::MakeWH(63, 63), 2, 2, paint); | |
| 102 paint.setStyle(SkPaint::kStroke_Style); | |
| 103 paint.setColor(border); | |
| 104 canvas->drawRoundRect(SkRect::MakeWH(63, 63), 2, 2, paint); | |
| 105 | |
| 106 return scoped_ptr<views::Painter>( | |
| 107 views::Painter::CreateImagePainter( | |
| 108 gfx::ImageSkia::CreateFrom1xBitmap( | |
| 109 skia::GetTopDevice(*canvas)->accessBitmap(true)), | |
| 110 gfx::Insets(5, 5, 5, 5))); | |
| 111 } | |
| 112 | |
| 113 scoped_ptr<views::Painter> normal_painter_; | |
| 114 scoped_ptr<views::Painter> hot_painter_; | |
| 115 scoped_ptr<views::Painter> pushed_painter_; | |
| 116 | |
| 117 gfx::Insets insets_; | |
| 118 | |
| 119 DISALLOW_COPY_AND_ASSIGN(CustomButtonBorder); | |
| 120 }; | |
| 121 | |
| 122 class ControlPanel : public views::ButtonListener { | |
| 123 public: | |
| 124 enum ControlType { | |
| 125 CONTROL_ZOOM_IN, | |
| 126 CONTROL_ACTUAL_SIZE, | |
| 127 CONTROL_ZOOM_OUT, | |
| 128 CONTROL_COUNT, | |
| 129 }; | |
| 130 | |
| 131 class Delegate { | |
| 132 public: | |
| 133 virtual ~Delegate() {} | |
| 134 | |
| 135 virtual void ButtonPressed(ControlType type) = 0; | |
| 136 }; | |
| 137 | |
| 138 explicit ControlPanel(Delegate* delegate) | |
| 139 : delegate_(delegate), shell_(nullptr), buttons_() {} | |
| 140 | |
| 141 virtual ~ControlPanel() {} | |
| 142 | |
| 143 void Initialize(View* view, Shell* shell) { | |
| 144 const char* kNames[] = { "Zoom In", "Actual Size", "Zoom Out" }; | |
| 145 | |
| 146 views::WidgetDelegateView* widget_delegate = new views::WidgetDelegateView; | |
| 147 | |
| 148 widget_delegate->GetContentsView()->SetLayoutManager( | |
| 149 new views::BoxLayout(views::BoxLayout::kHorizontal, 5, 2, 5)); | |
| 150 | |
| 151 widget_delegate->GetContentsView()->set_background( | |
| 152 views::Background::CreateSolidBackground(SK_ColorLTGRAY)); | |
| 153 | |
| 154 for (int type = 0; type < CONTROL_COUNT; ++type) { | |
| 155 views::Button* button = new views::LabelButton( | |
| 156 this, base::ASCIIToUTF16(kNames[type])); | |
| 157 button->SetBorder(scoped_ptr<views::Border>(new CustomButtonBorder)); | |
| 158 buttons_[type] = button; | |
| 159 widget_delegate->GetContentsView()->AddChildView(button); | |
| 160 } | |
| 161 | |
| 162 views::Widget* widget = new views::Widget; | |
| 163 views::Widget::InitParams params( | |
| 164 views::Widget::InitParams::TYPE_WINDOW_FRAMELESS); | |
| 165 params.native_widget = new NativeWidgetViewManager(widget, shell, view); | |
| 166 params.delegate = widget_delegate; | |
| 167 params.bounds = gfx::Rect(view->bounds().width, view->bounds().height); | |
| 168 params.opacity = views::Widget::InitParams::OPAQUE_WINDOW; | |
| 169 widget->Init(params); | |
| 170 widget->Show(); | |
| 171 } | |
| 172 | |
| 173 private: | |
| 174 // Overridden from views::ButtonListener: | |
| 175 virtual void ButtonPressed(views::Button* sender, | |
| 176 const ui::Event& event) override { | |
| 177 for (int i = 0; i < CONTROL_COUNT; ++i) { | |
| 178 if (sender == buttons_[i]) { | |
| 179 delegate_->ButtonPressed(static_cast<ControlType>(i)); | |
| 180 return; | |
| 181 } | |
| 182 } | |
| 183 } | |
| 184 | |
| 185 Delegate* delegate_; | |
| 186 Shell* shell_; | |
| 187 views::Button* buttons_[CONTROL_COUNT]; | |
| 188 | |
| 189 DISALLOW_COPY_AND_ASSIGN(ControlPanel); | |
| 190 }; | |
| 191 | |
| 192 class MediaViewer | |
| 193 : public ApplicationDelegate, | |
| 194 public ViewManagerDelegate, | |
| 195 public ControlPanel::Delegate, | |
| 196 public ViewObserver { | |
| 197 public: | |
| 198 MediaViewer() | |
| 199 : shell_(nullptr), | |
| 200 app_(NULL), | |
| 201 root_view_(NULL), | |
| 202 control_view_(NULL), | |
| 203 content_view_(NULL), | |
| 204 control_panel_(this) { | |
| 205 handler_map_["image/png"] = "mojo:png_viewer"; | |
| 206 } | |
| 207 | |
| 208 virtual ~MediaViewer() { | |
| 209 if (root_view_) | |
| 210 root_view_->RemoveObserver(this); | |
| 211 } | |
| 212 | |
| 213 private: | |
| 214 typedef std::map<std::string, std::string> HandlerMap; | |
| 215 | |
| 216 | |
| 217 // Overridden from ApplicationDelegate: | |
| 218 virtual void Initialize(ApplicationImpl* app) override { | |
| 219 shell_ = app->shell(); | |
| 220 view_manager_client_factory_.reset( | |
| 221 new ViewManagerClientFactory(app->shell(), this)); | |
| 222 app_ = app; | |
| 223 views_init_.reset(new ViewsInit); | |
| 224 } | |
| 225 | |
| 226 virtual bool ConfigureIncomingConnection(ApplicationConnection* connection) | |
| 227 override { | |
| 228 connection->AddService(view_manager_client_factory_.get()); | |
| 229 return true; | |
| 230 } | |
| 231 | |
| 232 void LayoutViews() { | |
| 233 View* root = content_view_->parent(); | |
| 234 Rect control_bounds; | |
| 235 control_bounds.width = root->bounds().width; | |
| 236 control_bounds.height = 28; | |
| 237 control_view_->SetBounds(control_bounds); | |
| 238 Rect content_bounds; | |
| 239 content_bounds.y = control_bounds.height; | |
| 240 content_bounds.width = root->bounds().width; | |
| 241 content_bounds.height = root->bounds().height - control_bounds.height; | |
| 242 content_view_->SetBounds(content_bounds); | |
| 243 } | |
| 244 | |
| 245 // Overridden from ViewManagerDelegate: | |
| 246 virtual void OnEmbed(View* root, | |
| 247 ServiceProviderImpl* exported_services, | |
| 248 scoped_ptr<ServiceProvider> imported_services) override { | |
| 249 root_view_ = root; | |
| 250 | |
| 251 control_view_ = root->view_manager()->CreateView(); | |
| 252 control_view_->SetVisible(true); | |
| 253 root_view_->AddChild(control_view_); | |
| 254 | |
| 255 content_view_ = root->view_manager()->CreateView(); | |
| 256 content_view_->SetVisible(true); | |
| 257 root_view_->AddChild(content_view_); | |
| 258 | |
| 259 control_panel_.Initialize(control_view_, shell_); | |
| 260 | |
| 261 LayoutViews(); | |
| 262 root_view_->AddObserver(this); | |
| 263 | |
| 264 content_view_->Embed("TODO"); | |
| 265 } | |
| 266 | |
| 267 virtual void OnViewManagerDisconnected( | |
| 268 ViewManager* view_manager) override { | |
| 269 base::MessageLoop::current()->Quit(); | |
| 270 } | |
| 271 | |
| 272 // Overridden from ControlPanel::Delegate: | |
| 273 virtual void ButtonPressed(ControlPanel::ControlType type) override { | |
| 274 switch (type) { | |
| 275 case ControlPanel::CONTROL_ZOOM_IN: | |
| 276 zoomable_media_->ZoomIn(); | |
| 277 break; | |
| 278 case ControlPanel::CONTROL_ACTUAL_SIZE: | |
| 279 zoomable_media_->ZoomToActualSize(); | |
| 280 break; | |
| 281 case ControlPanel::CONTROL_ZOOM_OUT: | |
| 282 zoomable_media_->ZoomOut(); | |
| 283 break; | |
| 284 default: | |
| 285 NOTIMPLEMENTED(); | |
| 286 } | |
| 287 } | |
| 288 | |
| 289 // ViewObserver: | |
| 290 virtual void OnViewBoundsChanged(View* view, | |
| 291 const Rect& old_bounds, | |
| 292 const Rect& new_bounds) override { | |
| 293 LayoutViews(); | |
| 294 } | |
| 295 virtual void OnViewDestroyed(View* view) override { | |
| 296 DCHECK_EQ(view, root_view_); | |
| 297 view->RemoveObserver(this); | |
| 298 root_view_ = NULL; | |
| 299 } | |
| 300 | |
| 301 std::string GetHandlerForContentType(const std::string& content_type) { | |
| 302 HandlerMap::const_iterator it = handler_map_.find(content_type); | |
| 303 return it != handler_map_.end() ? it->second : std::string(); | |
| 304 } | |
| 305 | |
| 306 Shell* shell_; | |
| 307 | |
| 308 scoped_ptr<ViewManagerClientFactory> view_manager_client_factory_; | |
| 309 | |
| 310 ApplicationImpl* app_; | |
| 311 scoped_ptr<ViewsInit> views_init_; | |
| 312 View* root_view_; | |
| 313 View* control_view_; | |
| 314 View* content_view_; | |
| 315 ControlPanel control_panel_; | |
| 316 ZoomableMediaPtr zoomable_media_; | |
| 317 HandlerMap handler_map_; | |
| 318 | |
| 319 DISALLOW_COPY_AND_ASSIGN(MediaViewer); | |
| 320 }; | |
| 321 | |
| 322 } // namespace examples | |
| 323 } // namespace mojo | |
| 324 | |
| 325 MojoResult MojoMain(MojoHandle shell_handle) { | |
| 326 mojo::ApplicationRunnerChromium runner(new mojo::examples::MediaViewer); | |
| 327 return runner.Run(shell_handle); | |
| 328 } | |
| OLD | NEW |