media_viewer.cc revision 5f1c94371a64b3196d4be9466099bb892df9b88e
1116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// Copyright 2014 The Chromium Authors. All rights reserved.
2116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// Use of this source code is governed by a BSD-style license that can be
3116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// found in the LICENSE file.
4116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
5116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include <map>
6116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include <string>
7116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
8116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "base/macros.h"
9116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "base/memory/scoped_ptr.h"
10116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "base/strings/utf_string_conversions.h"
11116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "mojo/examples/media_viewer/media_viewer.mojom.h"
12116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "mojo/public/cpp/application/application_connection.h"
13116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "mojo/public/cpp/application/application_delegate.h"
14116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "mojo/public/cpp/application/application_impl.h"
155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "mojo/public/cpp/application/interface_factory_impl.h"
16116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "mojo/public/cpp/bindings/interface_impl.h"
17116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "mojo/services/public/cpp/view_manager/node.h"
18116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "mojo/services/public/cpp/view_manager/node_observer.h"
19116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "mojo/services/public/cpp/view_manager/view.h"
20116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "mojo/services/public/cpp/view_manager/view_manager.h"
215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "mojo/services/public/cpp/view_manager/view_manager_client_factory.h"
22116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "mojo/services/public/cpp/view_manager/view_manager_delegate.h"
23116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "mojo/services/public/interfaces/navigation/navigation.mojom.h"
24116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "mojo/views/native_widget_view_manager.h"
25116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "mojo/views/views_init.h"
26116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "skia/ext/platform_canvas.h"
27116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "skia/ext/refptr.h"
28116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "third_party/skia/include/core/SkBitmap.h"
29116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "third_party/skia/include/core/SkCanvas.h"
30116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "third_party/skia/include/core/SkColor.h"
31116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "third_party/skia/include/core/SkPaint.h"
32116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "third_party/skia/include/core/SkRect.h"
33116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "ui/gfx/canvas.h"
34116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "ui/gfx/geometry/insets.h"
35116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "ui/gfx/geometry/rect.h"
36116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "ui/views/background.h"
37116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "ui/views/border.h"
38116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "ui/views/controls/button/button.h"
39116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "ui/views/controls/button/label_button.h"
40116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "ui/views/layout/box_layout.h"
41116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "ui/views/painter.h"
42116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "ui/views/widget/widget.h"
43116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "ui/views/widget/widget_delegate.h"
44116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
45116680a4aac90f2aa7413d9095a592090648e557Ben Murdochnamespace mojo {
46116680a4aac90f2aa7413d9095a592090648e557Ben Murdochnamespace examples {
47116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
48116680a4aac90f2aa7413d9095a592090648e557Ben Murdochclass MediaViewer;
49116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
50116680a4aac90f2aa7413d9095a592090648e557Ben Murdochclass CustomButtonBorder: public views::Border {
51116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch public:
52116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  CustomButtonBorder()
53116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      : normal_painter_(CreatePainter(SkColorSetRGB(0x80, 0x80, 0x80),
54116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                      SkColorSetRGB(0xC0, 0xC0, 0xC0))),
55116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        hot_painter_(CreatePainter(SkColorSetRGB(0xA0, 0xA0, 0xA0),
56116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                   SkColorSetRGB(0xD0, 0xD0, 0xD0))),
57116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        pushed_painter_(CreatePainter(SkColorSetRGB(0x80, 0x80, 0x80),
58116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                      SkColorSetRGB(0x90, 0x90, 0x90))),
59116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        insets_(2, 6, 2, 6) {
60116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
61116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  virtual ~CustomButtonBorder() {}
62116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
63116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch private:
64116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Overridden from views::Border:
65116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  virtual void Paint(const views::View& view, gfx::Canvas* canvas) OVERRIDE {
66116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const views::LabelButton* button =
67116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        static_cast<const views::LabelButton*>(&view);
68116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    views::Button::ButtonState state = button->state();
69116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
70116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    views::Painter* painter = normal_painter_.get();
71116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    if (state == views::Button::STATE_HOVERED) {
72116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      painter = hot_painter_.get();
73116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    } else if (state == views::Button::STATE_PRESSED) {
74116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      painter = pushed_painter_.get();
75116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    }
76116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    painter->Paint(canvas, view.size());
77116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
78116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
79116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  virtual gfx::Insets GetInsets() const OVERRIDE {
80116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return insets_;
81116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
82116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
83116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  virtual gfx::Size GetMinimumSize() const OVERRIDE {
84116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    gfx::Size size;
85116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    if (normal_painter_)
86116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      size.SetToMax(normal_painter_->GetMinimumSize());
87116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    if (hot_painter_)
88116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      size.SetToMax(hot_painter_->GetMinimumSize());
89116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    if (pushed_painter_)
90116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      size.SetToMax(pushed_painter_->GetMinimumSize());
91116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return size;
92116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
93116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
94116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  scoped_ptr<views::Painter> CreatePainter(SkColor border, SkColor background) {
95116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    skia::RefPtr<SkCanvas> canvas(skia::AdoptRef(skia::CreatePlatformCanvas(
96116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        64, 64, false)));
97116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    SkPaint paint;
98116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    paint.setColor(background);
99116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    canvas->drawRoundRect(SkRect::MakeWH(63, 63), 2, 2, paint);
100116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    paint.setStyle(SkPaint::kStroke_Style);
101116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    paint.setColor(border);
102116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    canvas->drawRoundRect(SkRect::MakeWH(63, 63), 2, 2, paint);
103116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
104116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return scoped_ptr<views::Painter>(
105116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        views::Painter::CreateImagePainter(
106116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch            gfx::ImageSkia::CreateFrom1xBitmap(
107116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                skia::GetTopDevice(*canvas)->accessBitmap(true)),
108116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch            gfx::Insets(5, 5, 5, 5)));
109116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
110116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
111116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  scoped_ptr<views::Painter> normal_painter_;
112116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  scoped_ptr<views::Painter> hot_painter_;
113116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  scoped_ptr<views::Painter> pushed_painter_;
114116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
115116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  gfx::Insets insets_;
116116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
117116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DISALLOW_COPY_AND_ASSIGN(CustomButtonBorder);
118116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch};
119116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
120116680a4aac90f2aa7413d9095a592090648e557Ben Murdochclass ControlPanel : public views::ButtonListener {
121116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch public:
122116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  enum ControlType {
123116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    CONTROL_ZOOM_IN,
124116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    CONTROL_ACTUAL_SIZE,
125116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    CONTROL_ZOOM_OUT,
126116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    CONTROL_COUNT,
127116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  };
128116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
129116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  class Delegate {
130116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch   public:
131116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    virtual ~Delegate() {}
132116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
133116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    virtual void ButtonPressed(ControlType type) = 0;
134116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  };
135116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
136116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  ControlPanel(Delegate* delegate) : delegate_(delegate), buttons_() {}
137116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
138116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  virtual ~ControlPanel() {}
139116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
1405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  void Initialize(Node* node) {
141116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const char* kNames[] = { "Zoom In", "Actual Size", "Zoom Out" };
142116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
143116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    views::WidgetDelegateView* widget_delegate = new views::WidgetDelegateView;
144116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
145116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    widget_delegate->GetContentsView()->SetLayoutManager(
146116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        new views::BoxLayout(views::BoxLayout::kHorizontal, 5, 2, 5));
147116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
148116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    widget_delegate->GetContentsView()->set_background(
149116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        views::Background::CreateSolidBackground(SK_ColorLTGRAY));
150116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
151116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    for (int type = 0; type < CONTROL_COUNT; ++type) {
152116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      views::Button* button = new views::LabelButton(
153116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          this, base::ASCIIToUTF16(kNames[type]));
154116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      button->SetBorder(scoped_ptr<views::Border>(new CustomButtonBorder));
155116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      buttons_[type] = button;
156116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      widget_delegate->GetContentsView()->AddChildView(button);
157116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    }
158116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
159116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    views::Widget* widget = new views::Widget;
160116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    views::Widget::InitParams params(
161116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        views::Widget::InitParams::TYPE_WINDOW_FRAMELESS);
162116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    params.native_widget = new NativeWidgetViewManager(widget, node);
163116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    params.delegate = widget_delegate;
164116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    params.bounds = gfx::Rect(node->bounds().width(), node->bounds().height());
165116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    params.opacity = views::Widget::InitParams::OPAQUE_WINDOW;
166116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    widget->Init(params);
167116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    widget->Show();
168116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
169116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
170116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch private:
171116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Overridden from views::ButtonListener:
172116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  virtual void ButtonPressed(views::Button* sender,
173116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                             const ui::Event& event) OVERRIDE {
174116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    for (int i = 0; i < CONTROL_COUNT; ++i) {
175116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      if (sender == buttons_[i]) {
176116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        delegate_->ButtonPressed(static_cast<ControlType>(i));
177116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        return;
178116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      }
179116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    }
180116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
181116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
182116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  Delegate* delegate_;
183116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  views::Button* buttons_[CONTROL_COUNT];
184116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
185116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DISALLOW_COPY_AND_ASSIGN(ControlPanel);
186116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch};
187116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
1885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class NavigatorImpl : public InterfaceImpl<Navigator> {
189116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch public:
1905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  explicit NavigatorImpl(MediaViewer* viewer) : viewer_(viewer) {}
191116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  virtual ~NavigatorImpl() {}
192116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
193116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch private:
1945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Overridden from Navigator:
195116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  virtual void Navigate(
196116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      uint32_t node_id,
1975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      NavigationDetailsPtr navigation_details,
1985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      ResponseDetailsPtr response_details) OVERRIDE;
199116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
200116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  MediaViewer* viewer_;
201116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
202116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DISALLOW_COPY_AND_ASSIGN(NavigatorImpl);
203116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch};
204116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
2055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class MediaViewer
2065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    : public ApplicationDelegate,
2075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      public ViewManagerDelegate,
2085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      public ControlPanel::Delegate,
2095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      public NodeObserver {
210116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch public:
2115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  MediaViewer()
2125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      : navigator_factory_(this),
2135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        view_manager_client_factory_(this),
2145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        app_(NULL),
2155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        view_manager_(NULL),
2165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        root_node_(NULL),
2175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        control_node_(NULL),
2185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        content_node_(NULL),
2195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        control_panel_(this) {
220116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    handler_map_["image/png"] = "mojo:mojo_png_viewer";
221116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
222116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
223116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  virtual ~MediaViewer() {
224116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    if (root_node_)
225116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      root_node_->RemoveObserver(this);
226116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
227116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
228116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  void Navigate(
229116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      uint32_t node_id,
2305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      NavigationDetailsPtr navigation_details,
2315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      ResponseDetailsPtr response_details) {
232116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // TODO(yzshen): This shouldn't be needed once FIFO is ready.
233116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    if (!view_manager_) {
234116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      pending_navigate_request_.reset(new PendingNavigateRequest);
235116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      pending_navigate_request_->node_id = node_id;
236116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      pending_navigate_request_->navigation_details = navigation_details.Pass();
237116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      pending_navigate_request_->response_details = response_details.Pass();
238116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
239116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      return;
240116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    }
241116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
242116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    std::string handler = GetHandlerForContentType(
243116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        response_details->response->mime_type);
244116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    if (handler.empty())
245116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      return;
246116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
247116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    content_node_->Embed(handler);
248116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
249116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    if (navigation_details) {
2505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      NavigatorPtr navigator;
251116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      app_->ConnectToService(handler, &navigator);
252116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      navigator->Navigate(content_node_->id(), navigation_details.Pass(),
253116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                          response_details.Pass());
254116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    }
255116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
256116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // TODO(yzshen): determine the set of controls to show based on what
257116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // interfaces the embedded app provides.
258116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    app_->ConnectToService(handler, &zoomable_media_);
259116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
260116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
261116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch private:
262116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  typedef std::map<std::string, std::string> HandlerMap;
263116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
264116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  struct PendingNavigateRequest {
265116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    uint32_t node_id;
2665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    NavigationDetailsPtr navigation_details;
2675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    ResponseDetailsPtr response_details;
268116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  };
269116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
270116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
271116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Overridden from ApplicationDelegate:
272116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  virtual void Initialize(ApplicationImpl* app) OVERRIDE {
273116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    app_ = app;
274116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    views_init_.reset(new ViewsInit);
275116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
276116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
277116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  virtual bool ConfigureIncomingConnection(ApplicationConnection* connection)
278116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      OVERRIDE {
2795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    connection->AddService(&navigator_factory_);
2805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    connection->AddService(&view_manager_client_factory_);
281116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return true;
282116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
283116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
284116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  void LayoutNodes() {
2855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    Node* root = content_node_->parent();
286116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    gfx::Rect control_bounds(root->bounds().width(), 28);
287116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    control_node_->SetBounds(control_bounds);
288116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    gfx::Rect content_bounds(0, control_bounds.height(), root->bounds().width(),
289116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                             root->bounds().height() - control_bounds.height());
290116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    content_node_->SetBounds(content_bounds);
291116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
292116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
2935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Overridden from ViewManagerDelegate:
2945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  virtual void OnEmbed(ViewManager* view_manager, Node* root) OVERRIDE {
295116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    root_node_ = root;
296116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    view_manager_ = view_manager;
297116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
2985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    control_node_ = Node::Create(view_manager_);
299116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    root_node_->AddChild(control_node_);
300116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
3015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    content_node_ = Node::Create(view_manager_);
302116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    root_node_->AddChild(content_node_);
303116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
3045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    control_node_->SetActiveView(View::Create(view_manager_));
305116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    control_panel_.Initialize(control_node_);
306116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
307116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    LayoutNodes();
308116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    root_node_->AddObserver(this);
309116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
310116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    if (pending_navigate_request_) {
311116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      scoped_ptr<PendingNavigateRequest> request(
312116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          pending_navigate_request_.release());
313116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
314116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      Navigate(request->node_id, request->navigation_details.Pass(),
315116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch               request->response_details.Pass());
316116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    }
317116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
318116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  virtual void OnViewManagerDisconnected(
3195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      ViewManager* view_manager) OVERRIDE {
320116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    DCHECK_EQ(view_manager_, view_manager);
321116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    view_manager_ = NULL;
322116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    base::MessageLoop::current()->Quit();
323116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
324116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
325116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Overridden from ControlPanel::Delegate:
326116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  virtual void ButtonPressed(ControlPanel::ControlType type) OVERRIDE {
327116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    switch (type) {
328116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      case ControlPanel::CONTROL_ZOOM_IN:
329116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        zoomable_media_->ZoomIn();
330116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        break;
331116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      case ControlPanel::CONTROL_ACTUAL_SIZE:
332116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch       zoomable_media_->ZoomToActualSize();
333116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        break;
334116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      case ControlPanel::CONTROL_ZOOM_OUT:
335116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        zoomable_media_->ZoomOut();
336116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        break;
337116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      default:
338116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        NOTIMPLEMENTED();
339116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    }
340116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
341116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
342116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // NodeObserver:
3435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  virtual void OnNodeBoundsChanged(Node* node,
344116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                   const gfx::Rect& old_bounds,
345116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                   const gfx::Rect& new_bounds) OVERRIDE {
346116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    LayoutNodes();
347116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
3485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  virtual void OnNodeDestroyed(Node* node) OVERRIDE {
349116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    DCHECK_EQ(node, root_node_);
350116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    node->RemoveObserver(this);
351116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    root_node_ = NULL;
352116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
353116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
354116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  std::string GetHandlerForContentType(const std::string& content_type) {
355116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    HandlerMap::const_iterator it = handler_map_.find(content_type);
356116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return it != handler_map_.end() ? it->second : std::string();
357116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
358116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
3595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  InterfaceFactoryImplWithContext<NavigatorImpl, MediaViewer>
3605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      navigator_factory_;
3615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ViewManagerClientFactory view_manager_client_factory_;
3625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
363116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  ApplicationImpl* app_;
364116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  scoped_ptr<ViewsInit> views_init_;
3655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ViewManager* view_manager_;
3665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  Node* root_node_;
3675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  Node* control_node_;
3685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  Node* content_node_;
369116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  ControlPanel control_panel_;
370116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  ZoomableMediaPtr zoomable_media_;
371116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  HandlerMap handler_map_;
372116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  scoped_ptr<PendingNavigateRequest> pending_navigate_request_;
373116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
374116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DISALLOW_COPY_AND_ASSIGN(MediaViewer);
375116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch};
376116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
377116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid NavigatorImpl::Navigate(
378116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    uint32_t node_id,
3795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    NavigationDetailsPtr navigation_details,
3805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    ResponseDetailsPtr response_details) {
381116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  viewer_->Navigate(node_id, navigation_details.Pass(),
382116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                    response_details.Pass());
383116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
384116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
385116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}  // namespace examples
386116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
387116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// static
388116680a4aac90f2aa7413d9095a592090648e557Ben MurdochApplicationDelegate* ApplicationDelegate::Create() {
389116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return new examples::MediaViewer;
390116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
391116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
392116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}  // namespace mojo
393