Introduce new SPDY Version UMA histogram.
[chromium-blink-merge.git] / mojo / examples / media_viewer / media_viewer.cc
blob05b5904031b4246efb4f98868372de4823e64a28
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.
5 #include <map>
6 #include <string>
8 #include "base/macros.h"
9 #include "base/memory/scoped_ptr.h"
10 #include "base/strings/utf_string_conversions.h"
11 #include "mojo/application/application_runner_chromium.h"
12 #include "mojo/examples/media_viewer/media_viewer.mojom.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/public/cpp/view_manager/view.h"
20 #include "mojo/services/public/cpp/view_manager/view_manager.h"
21 #include "mojo/services/public/cpp/view_manager/view_manager_client_factory.h"
22 #include "mojo/services/public/cpp/view_manager/view_manager_delegate.h"
23 #include "mojo/services/public/cpp/view_manager/view_observer.h"
24 #include "mojo/services/public/interfaces/navigation/navigation.mojom.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/views/background.h"
38 #include "ui/views/border.h"
39 #include "ui/views/controls/button/button.h"
40 #include "ui/views/controls/button/label_button.h"
41 #include "ui/views/layout/box_layout.h"
42 #include "ui/views/painter.h"
43 #include "ui/views/widget/widget.h"
44 #include "ui/views/widget/widget_delegate.h"
46 namespace mojo {
47 namespace examples {
49 class MediaViewer;
51 class CustomButtonBorder: public views::Border {
52 public:
53 CustomButtonBorder()
54 : normal_painter_(CreatePainter(SkColorSetRGB(0x80, 0x80, 0x80),
55 SkColorSetRGB(0xC0, 0xC0, 0xC0))),
56 hot_painter_(CreatePainter(SkColorSetRGB(0xA0, 0xA0, 0xA0),
57 SkColorSetRGB(0xD0, 0xD0, 0xD0))),
58 pushed_painter_(CreatePainter(SkColorSetRGB(0x80, 0x80, 0x80),
59 SkColorSetRGB(0x90, 0x90, 0x90))),
60 insets_(2, 6, 2, 6) {
62 virtual ~CustomButtonBorder() {}
64 private:
65 // Overridden from views::Border:
66 virtual void Paint(const views::View& view, gfx::Canvas* canvas) OVERRIDE {
67 const views::LabelButton* button =
68 static_cast<const views::LabelButton*>(&view);
69 views::Button::ButtonState state = button->state();
71 views::Painter* painter = normal_painter_.get();
72 if (state == views::Button::STATE_HOVERED) {
73 painter = hot_painter_.get();
74 } else if (state == views::Button::STATE_PRESSED) {
75 painter = pushed_painter_.get();
77 painter->Paint(canvas, view.size());
80 virtual gfx::Insets GetInsets() const OVERRIDE {
81 return insets_;
84 virtual gfx::Size GetMinimumSize() const OVERRIDE {
85 gfx::Size size;
86 if (normal_painter_)
87 size.SetToMax(normal_painter_->GetMinimumSize());
88 if (hot_painter_)
89 size.SetToMax(hot_painter_->GetMinimumSize());
90 if (pushed_painter_)
91 size.SetToMax(pushed_painter_->GetMinimumSize());
92 return size;
95 scoped_ptr<views::Painter> CreatePainter(SkColor border, SkColor background) {
96 skia::RefPtr<SkCanvas> canvas(skia::AdoptRef(skia::CreatePlatformCanvas(
97 64, 64, false)));
98 SkPaint paint;
99 paint.setColor(background);
100 canvas->drawRoundRect(SkRect::MakeWH(63, 63), 2, 2, paint);
101 paint.setStyle(SkPaint::kStroke_Style);
102 paint.setColor(border);
103 canvas->drawRoundRect(SkRect::MakeWH(63, 63), 2, 2, paint);
105 return scoped_ptr<views::Painter>(
106 views::Painter::CreateImagePainter(
107 gfx::ImageSkia::CreateFrom1xBitmap(
108 skia::GetTopDevice(*canvas)->accessBitmap(true)),
109 gfx::Insets(5, 5, 5, 5)));
112 scoped_ptr<views::Painter> normal_painter_;
113 scoped_ptr<views::Painter> hot_painter_;
114 scoped_ptr<views::Painter> pushed_painter_;
116 gfx::Insets insets_;
118 DISALLOW_COPY_AND_ASSIGN(CustomButtonBorder);
121 class ControlPanel : public views::ButtonListener {
122 public:
123 enum ControlType {
124 CONTROL_ZOOM_IN,
125 CONTROL_ACTUAL_SIZE,
126 CONTROL_ZOOM_OUT,
127 CONTROL_COUNT,
130 class Delegate {
131 public:
132 virtual ~Delegate() {}
134 virtual void ButtonPressed(ControlType type) = 0;
137 ControlPanel(Delegate* delegate) : delegate_(delegate), buttons_() {}
139 virtual ~ControlPanel() {}
141 void Initialize(View* view) {
142 const char* kNames[] = { "Zoom In", "Actual Size", "Zoom Out" };
144 views::WidgetDelegateView* widget_delegate = new views::WidgetDelegateView;
146 widget_delegate->GetContentsView()->SetLayoutManager(
147 new views::BoxLayout(views::BoxLayout::kHorizontal, 5, 2, 5));
149 widget_delegate->GetContentsView()->set_background(
150 views::Background::CreateSolidBackground(SK_ColorLTGRAY));
152 for (int type = 0; type < CONTROL_COUNT; ++type) {
153 views::Button* button = new views::LabelButton(
154 this, base::ASCIIToUTF16(kNames[type]));
155 button->SetBorder(scoped_ptr<views::Border>(new CustomButtonBorder));
156 buttons_[type] = button;
157 widget_delegate->GetContentsView()->AddChildView(button);
160 views::Widget* widget = new views::Widget;
161 views::Widget::InitParams params(
162 views::Widget::InitParams::TYPE_WINDOW_FRAMELESS);
163 params.native_widget = new NativeWidgetViewManager(widget, view);
164 params.delegate = widget_delegate;
165 params.bounds = gfx::Rect(view->bounds().width(), view->bounds().height());
166 params.opacity = views::Widget::InitParams::OPAQUE_WINDOW;
167 widget->Init(params);
168 widget->Show();
171 private:
172 // Overridden from views::ButtonListener:
173 virtual void ButtonPressed(views::Button* sender,
174 const ui::Event& event) OVERRIDE {
175 for (int i = 0; i < CONTROL_COUNT; ++i) {
176 if (sender == buttons_[i]) {
177 delegate_->ButtonPressed(static_cast<ControlType>(i));
178 return;
183 Delegate* delegate_;
184 views::Button* buttons_[CONTROL_COUNT];
186 DISALLOW_COPY_AND_ASSIGN(ControlPanel);
189 class MediaViewer
190 : public ApplicationDelegate,
191 public ViewManagerDelegate,
192 public ControlPanel::Delegate,
193 public ViewObserver {
194 public:
195 MediaViewer()
196 : app_(NULL),
197 view_manager_(NULL),
198 root_view_(NULL),
199 control_view_(NULL),
200 content_view_(NULL),
201 control_panel_(this) {
202 handler_map_["image/png"] = "mojo:mojo_png_viewer";
205 virtual ~MediaViewer() {
206 if (root_view_)
207 root_view_->RemoveObserver(this);
210 private:
211 typedef std::map<std::string, std::string> HandlerMap;
214 // Overridden from ApplicationDelegate:
215 virtual void Initialize(ApplicationImpl* app) OVERRIDE {
216 view_manager_client_factory_.reset(
217 new ViewManagerClientFactory(app->shell(), this));
218 app_ = app;
219 views_init_.reset(new ViewsInit);
222 virtual bool ConfigureIncomingConnection(ApplicationConnection* connection)
223 OVERRIDE {
224 connection->AddService(view_manager_client_factory_.get());
225 return true;
228 void LayoutViews() {
229 View* root = content_view_->parent();
230 gfx::Rect control_bounds(root->bounds().width(), 28);
231 control_view_->SetBounds(control_bounds);
232 gfx::Rect content_bounds(0, control_bounds.height(), root->bounds().width(),
233 root->bounds().height() - control_bounds.height());
234 content_view_->SetBounds(content_bounds);
237 // Overridden from ViewManagerDelegate:
238 virtual void OnEmbed(ViewManager* view_manager,
239 View* root,
240 ServiceProviderImpl* exported_services,
241 scoped_ptr<ServiceProvider> imported_services) OVERRIDE {
242 root_view_ = root;
243 view_manager_ = view_manager;
245 control_view_ = View::Create(view_manager_);
246 root_view_->AddChild(control_view_);
248 content_view_ = View::Create(view_manager_);
249 root_view_->AddChild(content_view_);
251 control_panel_.Initialize(control_view_);
253 LayoutViews();
254 root_view_->AddObserver(this);
256 content_view_->Embed("TODO");
259 virtual void OnViewManagerDisconnected(
260 ViewManager* view_manager) OVERRIDE {
261 DCHECK_EQ(view_manager_, view_manager);
262 view_manager_ = NULL;
263 base::MessageLoop::current()->Quit();
266 // Overridden from ControlPanel::Delegate:
267 virtual void ButtonPressed(ControlPanel::ControlType type) OVERRIDE {
268 switch (type) {
269 case ControlPanel::CONTROL_ZOOM_IN:
270 zoomable_media_->ZoomIn();
271 break;
272 case ControlPanel::CONTROL_ACTUAL_SIZE:
273 zoomable_media_->ZoomToActualSize();
274 break;
275 case ControlPanel::CONTROL_ZOOM_OUT:
276 zoomable_media_->ZoomOut();
277 break;
278 default:
279 NOTIMPLEMENTED();
283 // ViewObserver:
284 virtual void OnViewBoundsChanged(View* view,
285 const gfx::Rect& old_bounds,
286 const gfx::Rect& new_bounds) OVERRIDE {
287 LayoutViews();
289 virtual void OnViewDestroyed(View* view) OVERRIDE {
290 DCHECK_EQ(view, root_view_);
291 view->RemoveObserver(this);
292 root_view_ = NULL;
295 std::string GetHandlerForContentType(const std::string& content_type) {
296 HandlerMap::const_iterator it = handler_map_.find(content_type);
297 return it != handler_map_.end() ? it->second : std::string();
300 scoped_ptr<ViewManagerClientFactory> view_manager_client_factory_;
302 ApplicationImpl* app_;
303 scoped_ptr<ViewsInit> views_init_;
304 ViewManager* view_manager_;
305 View* root_view_;
306 View* control_view_;
307 View* content_view_;
308 ControlPanel control_panel_;
309 ZoomableMediaPtr zoomable_media_;
310 HandlerMap handler_map_;
312 DISALLOW_COPY_AND_ASSIGN(MediaViewer);
315 } // namespace examples
316 } // namespace mojo
318 MojoResult MojoMain(MojoHandle shell_handle) {
319 mojo::ApplicationRunnerChromium runner(new mojo::examples::MediaViewer);
320 return runner.Run(shell_handle);