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.
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"
51 class CustomButtonBorder
: public views::Border
{
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))),
62 virtual ~CustomButtonBorder() {}
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
{
84 virtual gfx::Size
GetMinimumSize() const OVERRIDE
{
87 size
.SetToMax(normal_painter_
->GetMinimumSize());
89 size
.SetToMax(hot_painter_
->GetMinimumSize());
91 size
.SetToMax(pushed_painter_
->GetMinimumSize());
95 scoped_ptr
<views::Painter
> CreatePainter(SkColor border
, SkColor background
) {
96 skia::RefPtr
<SkCanvas
> canvas(skia::AdoptRef(skia::CreatePlatformCanvas(
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_
;
118 DISALLOW_COPY_AND_ASSIGN(CustomButtonBorder
);
121 class ControlPanel
: public views::ButtonListener
{
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
);
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
));
184 views::Button
* buttons_
[CONTROL_COUNT
];
186 DISALLOW_COPY_AND_ASSIGN(ControlPanel
);
190 : public ApplicationDelegate
,
191 public ViewManagerDelegate
,
192 public ControlPanel::Delegate
,
193 public ViewObserver
{
201 control_panel_(this) {
202 handler_map_
["image/png"] = "mojo:mojo_png_viewer";
205 virtual ~MediaViewer() {
207 root_view_
->RemoveObserver(this);
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));
219 views_init_
.reset(new ViewsInit
);
222 virtual bool ConfigureIncomingConnection(ApplicationConnection
* connection
)
224 connection
->AddService(view_manager_client_factory_
.get());
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
,
240 ServiceProviderImpl
* exported_services
,
241 scoped_ptr
<ServiceProvider
> imported_services
) OVERRIDE
{
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_
);
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
{
269 case ControlPanel::CONTROL_ZOOM_IN
:
270 zoomable_media_
->ZoomIn();
272 case ControlPanel::CONTROL_ACTUAL_SIZE
:
273 zoomable_media_
->ZoomToActualSize();
275 case ControlPanel::CONTROL_ZOOM_OUT
:
276 zoomable_media_
->ZoomOut();
284 virtual void OnViewBoundsChanged(View
* view
,
285 const gfx::Rect
& old_bounds
,
286 const gfx::Rect
& new_bounds
) OVERRIDE
{
289 virtual void OnViewDestroyed(View
* view
) OVERRIDE
{
290 DCHECK_EQ(view
, root_view_
);
291 view
->RemoveObserver(this);
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_
;
308 ControlPanel control_panel_
;
309 ZoomableMediaPtr zoomable_media_
;
310 HandlerMap handler_map_
;
312 DISALLOW_COPY_AND_ASSIGN(MediaViewer
);
315 } // namespace examples
318 MojoResult
MojoMain(MojoHandle shell_handle
) {
319 mojo::ApplicationRunnerChromium
runner(new mojo::examples::MediaViewer
);
320 return runner
.Run(shell_handle
);