summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--mojo/examples/media_viewer/DEPS2
-rw-r--r--mojo/examples/media_viewer/media_viewer.cc210
-rw-r--r--mojo/examples/media_viewer/media_viewer.mojom13
-rw-r--r--mojo/examples/png_viewer/DEPS1
-rw-r--r--mojo/examples/png_viewer/png_viewer.cc91
-rw-r--r--mojo/mojo_examples.gypi21
6 files changed, 324 insertions, 14 deletions
diff --git a/mojo/examples/media_viewer/DEPS b/mojo/examples/media_viewer/DEPS
index 2930a78..44ca77e 100644
--- a/mojo/examples/media_viewer/DEPS
+++ b/mojo/examples/media_viewer/DEPS
@@ -1,4 +1,6 @@
include_rules = [
+ "+skia/ext",
+ "+third_party/skia/include",
"+ui/events",
"+ui/gfx",
"+ui/views",
diff --git a/mojo/examples/media_viewer/media_viewer.cc b/mojo/examples/media_viewer/media_viewer.cc
index b727b59..e4ea4c6 100644
--- a/mojo/examples/media_viewer/media_viewer.cc
+++ b/mojo/examples/media_viewer/media_viewer.cc
@@ -7,6 +7,8 @@
#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
+#include "base/strings/utf_string_conversions.h"
+#include "mojo/examples/media_viewer/media_viewer.mojom.h"
#include "mojo/public/cpp/application/application_connection.h"
#include "mojo/public/cpp/application/application_delegate.h"
#include "mojo/public/cpp/application/application_impl.h"
@@ -16,17 +18,170 @@
#include "mojo/services/public/cpp/view_manager/view_manager.h"
#include "mojo/services/public/cpp/view_manager/view_manager_delegate.h"
#include "mojo/services/public/interfaces/navigation/navigation.mojom.h"
+#include "mojo/views/native_widget_view_manager.h"
+#include "mojo/views/views_init.h"
+#include "skia/ext/platform_canvas.h"
+#include "skia/ext/refptr.h"
+#include "third_party/skia/include/core/SkBitmap.h"
+#include "third_party/skia/include/core/SkCanvas.h"
+#include "third_party/skia/include/core/SkColor.h"
+#include "third_party/skia/include/core/SkPaint.h"
+#include "third_party/skia/include/core/SkRect.h"
+#include "ui/gfx/canvas.h"
+#include "ui/gfx/geometry/insets.h"
#include "ui/gfx/geometry/rect.h"
+#include "ui/views/border.h"
+#include "ui/views/controls/button/button.h"
+#include "ui/views/controls/button/label_button.h"
+#include "ui/views/layout/box_layout.h"
+#include "ui/views/painter.h"
+#include "ui/views/widget/widget.h"
+#include "ui/views/widget/widget_delegate.h"
namespace mojo {
namespace examples {
class MediaViewer;
+class CustomButtonBorder: public views::Border {
+ public:
+ CustomButtonBorder()
+ : normal_painter_(CreatePainter(SkColorSetRGB(0x80, 0x80, 0x80),
+ SkColorSetRGB(0xC0, 0xC0, 0xC0))),
+ hot_painter_(CreatePainter(SkColorSetRGB(0xA0, 0xA0, 0xA0),
+ SkColorSetRGB(0xD0, 0xD0, 0xD0))),
+ pushed_painter_(CreatePainter(SkColorSetRGB(0x80, 0x80, 0x80),
+ SkColorSetRGB(0x90, 0x90, 0x90))),
+ insets_(2, 6, 2, 6) {
+ }
+ virtual ~CustomButtonBorder() {}
+
+ private:
+ // Overridden from views::Border:
+ virtual void Paint(const views::View& view, gfx::Canvas* canvas) OVERRIDE {
+ const views::LabelButton* button =
+ static_cast<const views::LabelButton*>(&view);
+ views::Button::ButtonState state = button->state();
+
+ views::Painter* painter = normal_painter_.get();
+ if (state == views::Button::STATE_HOVERED) {
+ painter = hot_painter_.get();
+ } else if (state == views::Button::STATE_PRESSED) {
+ painter = pushed_painter_.get();
+ }
+ painter->Paint(canvas, view.size());
+ }
+
+ virtual gfx::Insets GetInsets() const OVERRIDE {
+ return insets_;
+ }
+
+ virtual gfx::Size GetMinimumSize() const OVERRIDE {
+ gfx::Size size;
+ if (normal_painter_)
+ size.SetToMax(normal_painter_->GetMinimumSize());
+ if (hot_painter_)
+ size.SetToMax(hot_painter_->GetMinimumSize());
+ if (pushed_painter_)
+ size.SetToMax(pushed_painter_->GetMinimumSize());
+ return size;
+ }
+
+ scoped_ptr<views::Painter> CreatePainter(SkColor border, SkColor background) {
+ skia::RefPtr<SkCanvas> canvas(skia::AdoptRef(skia::CreatePlatformCanvas(
+ 64, 64, false)));
+ SkPaint paint;
+ paint.setColor(background);
+ canvas->drawRoundRect(SkRect::MakeWH(63, 63), 2, 2, paint);
+ paint.setStyle(SkPaint::kStroke_Style);
+ paint.setColor(border);
+ canvas->drawRoundRect(SkRect::MakeWH(63, 63), 2, 2, paint);
+
+ return scoped_ptr<views::Painter>(
+ views::Painter::CreateImagePainter(
+ gfx::ImageSkia::CreateFrom1xBitmap(
+ skia::GetTopDevice(*canvas)->accessBitmap(true)),
+ gfx::Insets(5, 5, 5, 5)));
+ }
+
+ scoped_ptr<views::Painter> normal_painter_;
+ scoped_ptr<views::Painter> hot_painter_;
+ scoped_ptr<views::Painter> pushed_painter_;
+
+ gfx::Insets insets_;
+
+ DISALLOW_COPY_AND_ASSIGN(CustomButtonBorder);
+};
+
+class ControlPanel : public views::ButtonListener {
+ public:
+ enum ControlType {
+ CONTROL_ZOOM_IN,
+ CONTROL_ACTUAL_SIZE,
+ CONTROL_ZOOM_OUT,
+ CONTROL_COUNT,
+ };
+
+ class Delegate {
+ public:
+ virtual ~Delegate() {}
+
+ virtual void ButtonPressed(ControlType type) = 0;
+ };
+
+ ControlPanel(Delegate* delegate) : delegate_(delegate), buttons_() {}
+
+ virtual ~ControlPanel() {}
+
+ void Initialize(view_manager::Node* node) {
+ const char* kNames[] = { "Zoom In", "Actual Size", "Zoom Out" };
+
+ views::WidgetDelegateView* widget_delegate = new views::WidgetDelegateView;
+
+ widget_delegate->GetContentsView()->SetLayoutManager(
+ new views::BoxLayout(views::BoxLayout::kHorizontal, 5, 2, 5));
+
+ for (int type = 0; type < CONTROL_COUNT; ++type) {
+ views::Button* button = new views::LabelButton(
+ this, base::ASCIIToUTF16(kNames[type]));
+ button->SetBorder(scoped_ptr<views::Border>(new CustomButtonBorder));
+ buttons_[type] = button;
+ widget_delegate->GetContentsView()->AddChildView(button);
+ }
+
+ views::Widget* widget = new views::Widget;
+ views::Widget::InitParams params(
+ views::Widget::InitParams::TYPE_WINDOW_FRAMELESS);
+ params.native_widget = new NativeWidgetViewManager(widget, node);
+ params.delegate = widget_delegate;
+ params.bounds = gfx::Rect(node->bounds().width(), node->bounds().height());
+ params.opacity = views::Widget::InitParams::OPAQUE_WINDOW;
+ widget->Init(params);
+ widget->Show();
+ }
+
+ private:
+ // Overridden from views::ButtonListener:
+ virtual void ButtonPressed(views::Button* sender,
+ const ui::Event& event) OVERRIDE {
+ for (int i = 0; i < CONTROL_COUNT; ++i) {
+ if (sender == buttons_[i]) {
+ delegate_->ButtonPressed(static_cast<ControlType>(i));
+ return;
+ }
+ }
+ }
+
+ Delegate* delegate_;
+ views::Button* buttons_[CONTROL_COUNT];
+
+ DISALLOW_COPY_AND_ASSIGN(ControlPanel);
+};
+
class NavigatorImpl : public InterfaceImpl<navigation::Navigator> {
public:
- explicit NavigatorImpl(ApplicationConnection* connection,
- MediaViewer* viewer) : viewer_(viewer) {}
+ NavigatorImpl(ApplicationConnection* connection,
+ MediaViewer* viewer) : viewer_(viewer) {}
virtual ~NavigatorImpl() {}
private:
@@ -42,11 +197,14 @@ class NavigatorImpl : public InterfaceImpl<navigation::Navigator> {
};
class MediaViewer : public ApplicationDelegate,
- public view_manager::ViewManagerDelegate {
+ public view_manager::ViewManagerDelegate,
+ public ControlPanel::Delegate {
public:
MediaViewer() : app_(NULL),
+ view_manager_(NULL),
+ control_node_(NULL),
content_node_(NULL),
- view_manager_(NULL) {
+ control_panel_(this) {
handler_map_["image/png"] = "mojo:mojo_png_viewer";
}
@@ -66,7 +224,6 @@ class MediaViewer : public ApplicationDelegate,
return;
}
- // TODO(yzshen): provide media control UI.
std::string handler = GetHandlerForContentType(
response_details->response->mime_type);
if (handler.empty())
@@ -80,6 +237,10 @@ class MediaViewer : public ApplicationDelegate,
navigator->Navigate(content_node_->id(), navigation_details.Pass(),
response_details.Pass());
}
+
+ // TODO(yzshen): determine the set of controls to show based on what
+ // interfaces the embedded app provides.
+ app_->ConnectToService(handler, &zoomable_media_);
}
private:
@@ -95,6 +256,7 @@ class MediaViewer : public ApplicationDelegate,
// Overridden from ApplicationDelegate:
virtual void Initialize(ApplicationImpl* app) OVERRIDE {
app_ = app;
+ views_init_.reset(new ViewsInit);
}
virtual bool ConfigureIncomingConnection(ApplicationConnection* connection)
@@ -108,11 +270,20 @@ class MediaViewer : public ApplicationDelegate,
virtual void OnRootAdded(view_manager::ViewManager* view_manager,
view_manager::Node* root) OVERRIDE {
view_manager_ = view_manager;
+
+ control_node_ = view_manager::Node::Create(view_manager_);
+ root->AddChild(control_node_);
+ gfx::Rect control_bounds(root->bounds().width(), 28);
+ control_node_->SetBounds(control_bounds);
+ control_node_->SetActiveView(view_manager::View::Create(view_manager_));
+
+ control_panel_.Initialize(control_node_);
+
content_node_ = view_manager::Node::Create(view_manager_);
root->AddChild(content_node_);
-
- gfx::Rect bounds(root->bounds().size());
- content_node_->SetBounds(bounds);
+ gfx::Rect content_bounds(0, control_bounds.height(), root->bounds().width(),
+ root->bounds().height() - control_bounds.height());
+ content_node_->SetBounds(content_bounds);
if (pending_navigate_request_) {
scoped_ptr<PendingNavigateRequest> request(
@@ -123,14 +294,35 @@ class MediaViewer : public ApplicationDelegate,
}
}
+ // Overridden from ControlPanel::Delegate:
+ virtual void ButtonPressed(ControlPanel::ControlType type) OVERRIDE {
+ switch (type) {
+ case ControlPanel::CONTROL_ZOOM_IN:
+ zoomable_media_->ZoomIn();
+ break;
+ case ControlPanel::CONTROL_ACTUAL_SIZE:
+ zoomable_media_->ZoomToActualSize();
+ break;
+ case ControlPanel::CONTROL_ZOOM_OUT:
+ zoomable_media_->ZoomOut();
+ break;
+ default:
+ NOTIMPLEMENTED();
+ }
+ }
+
std::string GetHandlerForContentType(const std::string& content_type) {
HandlerMap::const_iterator it = handler_map_.find(content_type);
return it != handler_map_.end() ? it->second : std::string();
}
ApplicationImpl* app_;
- view_manager::Node* content_node_;
+ scoped_ptr<ViewsInit> views_init_;
view_manager::ViewManager* view_manager_;
+ view_manager::Node* control_node_;
+ view_manager::Node* content_node_;
+ ControlPanel control_panel_;
+ ZoomableMediaPtr zoomable_media_;
HandlerMap handler_map_;
scoped_ptr<PendingNavigateRequest> pending_navigate_request_;
diff --git a/mojo/examples/media_viewer/media_viewer.mojom b/mojo/examples/media_viewer/media_viewer.mojom
new file mode 100644
index 0000000..773d775
--- /dev/null
+++ b/mojo/examples/media_viewer/media_viewer.mojom
@@ -0,0 +1,13 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+module mojo {
+
+interface ZoomableMedia {
+ ZoomIn();
+ ZoomOut();
+ ZoomToActualSize();
+};
+
+}
diff --git a/mojo/examples/png_viewer/DEPS b/mojo/examples/png_viewer/DEPS
index 41134f5..23b2bf6 100644
--- a/mojo/examples/png_viewer/DEPS
+++ b/mojo/examples/png_viewer/DEPS
@@ -1,4 +1,5 @@
include_rules = [
+ "+skia/ext",
"+third_party/skia/include",
"+ui/gfx",
]
diff --git a/mojo/examples/png_viewer/png_viewer.cc b/mojo/examples/png_viewer/png_viewer.cc
index 6a7218a..dfa8e7b 100644
--- a/mojo/examples/png_viewer/png_viewer.cc
+++ b/mojo/examples/png_viewer/png_viewer.cc
@@ -5,6 +5,7 @@
#include <algorithm>
#include "base/strings/string_tokenizer.h"
+#include "mojo/examples/media_viewer/media_viewer.mojom.h"
#include "mojo/public/cpp/application/application_connection.h"
#include "mojo/public/cpp/application/application_delegate.h"
#include "mojo/services/public/cpp/view_manager/node.h"
@@ -13,7 +14,12 @@
#include "mojo/services/public/cpp/view_manager/view_manager.h"
#include "mojo/services/public/cpp/view_manager/view_manager_delegate.h"
#include "mojo/services/public/interfaces/navigation/navigation.mojom.h"
+#include "skia/ext/platform_canvas.h"
+#include "skia/ext/refptr.h"
#include "third_party/skia/include/core/SkBitmap.h"
+#include "third_party/skia/include/core/SkCanvas.h"
+#include "third_party/skia/include/core/SkPaint.h"
+#include "third_party/skia/include/core/SkScalar.h"
#include "ui/gfx/codec/png_codec.h"
namespace mojo {
@@ -21,10 +27,27 @@ namespace examples {
class PNGViewer;
+class ZoomableMediaImpl : public InterfaceImpl<ZoomableMedia> {
+ public:
+ ZoomableMediaImpl(ApplicationConnection* connection,
+ PNGViewer* viewer) : viewer_(viewer) {}
+ virtual ~ZoomableMediaImpl() {}
+
+ private:
+ // Overridden from ZoomableMedia:
+ virtual void ZoomIn() OVERRIDE;
+ virtual void ZoomOut() OVERRIDE;
+ virtual void ZoomToActualSize() OVERRIDE;
+
+ PNGViewer* viewer_;
+
+ DISALLOW_COPY_AND_ASSIGN(ZoomableMediaImpl);
+};
+
class NavigatorImpl : public InterfaceImpl<navigation::Navigator> {
public:
- explicit NavigatorImpl(ApplicationConnection* connection,
- PNGViewer* viewer) : viewer_(viewer) {}
+ NavigatorImpl(ApplicationConnection* connection,
+ PNGViewer* viewer) : viewer_(viewer) {}
virtual ~NavigatorImpl() {}
private:
@@ -89,19 +112,47 @@ class NavigatorImpl : public InterfaceImpl<navigation::Navigator> {
class PNGViewer : public ApplicationDelegate,
public view_manager::ViewManagerDelegate {
public:
- PNGViewer() : content_view_(NULL) {}
+ PNGViewer() : content_view_(NULL), zoom_percentage_(kDefaultZoomPercentage) {}
virtual ~PNGViewer() {}
void UpdateView(view_manager::Id node_id, const SkBitmap& bitmap) {
bitmap_ = bitmap;
+ zoom_percentage_ = kDefaultZoomPercentage;
+ DrawBitmap();
+ }
+
+ void ZoomIn() {
+ if (zoom_percentage_ >= kMaxZoomPercentage)
+ return;
+ zoom_percentage_ += kZoomStep;
+ DrawBitmap();
+ }
+
+ void ZoomOut() {
+ if (zoom_percentage_ <= kMinZoomPercentage)
+ return;
+ zoom_percentage_ -= kZoomStep;
+ DrawBitmap();
+ }
+
+ void ZoomToActualSize() {
+ if (zoom_percentage_ == kDefaultZoomPercentage)
+ return;
+ zoom_percentage_ = kDefaultZoomPercentage;
DrawBitmap();
}
private:
+ static const uint16_t kMaxZoomPercentage = 400;
+ static const uint16_t kMinZoomPercentage = 20;
+ static const uint16_t kDefaultZoomPercentage = 100;
+ static const uint16_t kZoomStep = 20;
+
// Overridden from ApplicationDelegate:
virtual bool ConfigureIncomingConnection(ApplicationConnection* connection)
MOJO_OVERRIDE {
connection->AddService<NavigatorImpl>(this);
+ connection->AddService<ZoomableMediaImpl>(this);
view_manager::ViewManager::ConfigureIncomingConnection(connection, this);
return true;
}
@@ -117,18 +168,48 @@ class PNGViewer : public ApplicationDelegate,
}
void DrawBitmap() {
- if (content_view_)
+ if (!content_view_)
+ return;
+
+ if (zoom_percentage_ == kDefaultZoomPercentage) {
content_view_->SetContents(bitmap_);
+ return;
+ }
+
+ skia::RefPtr<SkCanvas> canvas(skia::AdoptRef(skia::CreatePlatformCanvas(
+ content_view_->node()->bounds().width(),
+ content_view_->node()->bounds().height(),
+ true)));
+ canvas->drawColor(SK_ColorGRAY);
+ SkPaint paint;
+ SkScalar scale =
+ SkFloatToScalar(zoom_percentage_ * 1.0f / kDefaultZoomPercentage);
+ canvas->scale(scale, scale);
+ canvas->drawBitmap(bitmap_, 0, 0, &paint);
+ content_view_->SetContents(skia::GetTopDevice(*canvas)->accessBitmap(true));
}
view_manager::View* content_view_;
SkBitmap bitmap_;
+ uint16_t zoom_percentage_;
DISALLOW_COPY_AND_ASSIGN(PNGViewer);
};
+void ZoomableMediaImpl::ZoomIn() {
+ viewer_->ZoomIn();
+}
+
+void ZoomableMediaImpl::ZoomOut() {
+ viewer_->ZoomOut();
+}
+
+void ZoomableMediaImpl::ZoomToActualSize() {
+ viewer_->ZoomToActualSize();
+}
+
void NavigatorImpl::UpdateView(view_manager::Id node_id,
- const SkBitmap& bitmap) {
+ const SkBitmap& bitmap) {
viewer_->UpdateView(node_id, bitmap);
}
diff --git a/mojo/mojo_examples.gypi b/mojo/mojo_examples.gypi
index e464e12..009fc9a 100644
--- a/mojo/mojo_examples.gypi
+++ b/mojo/mojo_examples.gypi
@@ -132,6 +132,20 @@
],
},
{
+ 'target_name': 'mojo_media_viewer_bindings',
+ 'type': 'static_library',
+ 'sources': [
+ 'examples/media_viewer/media_viewer.mojom',
+ ],
+ 'includes': [ 'public/tools/bindings/mojom_bindings_generator.gypi' ],
+ 'export_dependent_settings': [
+ 'mojo_cpp_bindings',
+ ],
+ 'dependencies': [
+ 'mojo_cpp_bindings',
+ ],
+ },
+ {
'target_name': 'mojo_png_viewer',
'type': 'shared_library',
'dependencies': [
@@ -140,6 +154,7 @@
'mojo_application',
'mojo_cpp_bindings',
'mojo_environment_chromium',
+ 'mojo_media_viewer_bindings',
'mojo_navigation_bindings',
'mojo_network_bindings',
'mojo_launcher_bindings',
@@ -518,10 +533,16 @@
'type': 'shared_library',
'dependencies': [
'../base/base.gyp:base',
+ '../skia/skia.gyp:skia',
+ '../ui/gfx/gfx.gyp:gfx_geometry',
+ '../ui/views/views.gyp:views',
'mojo_application',
'mojo_environment_chromium',
+ 'mojo_input_events_lib',
+ 'mojo_media_viewer_bindings',
'mojo_navigation_bindings',
'mojo_system_impl',
+ 'mojo_views_support',
'mojo_view_manager_bindings',
'mojo_view_manager_lib',
],