Re-subimission of https://codereview.chromium.org/1041213003/
[chromium-blink-merge.git] / content / browser / android / composited_touch_handle_drawable.cc
blob91a019eba89157780bd68ed5d82c979b050d0c88
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 "content/browser/android/composited_touch_handle_drawable.h"
7 #include "base/lazy_instance.h"
8 #include "base/logging.h"
9 #include "base/trace_event/trace_event.h"
10 #include "cc/layers/ui_resource_layer.h"
11 #include "jni/HandleViewResources_jni.h"
12 #include "ui/gfx/android/java_bitmap.h"
14 namespace content {
16 namespace {
18 static SkBitmap CreateSkBitmapFromJavaBitmap(
19 base::android::ScopedJavaLocalRef<jobject> jbitmap) {
20 return jbitmap.is_null()
21 ? SkBitmap()
22 : CreateSkBitmapFromJavaBitmap(gfx::JavaBitmap(jbitmap.obj()));
25 class HandleResources {
26 public:
27 HandleResources() : loaded_(false) {
30 void LoadIfNecessary(jobject context) {
31 if (loaded_)
32 return;
34 loaded_ = true;
36 TRACE_EVENT0("browser", "HandleResources::Create");
37 JNIEnv* env = base::android::AttachCurrentThread();
38 if (!context)
39 context = base::android::GetApplicationContext();
41 left_bitmap_ = CreateSkBitmapFromJavaBitmap(
42 Java_HandleViewResources_getLeftHandleBitmap(env, context));
43 right_bitmap_ = CreateSkBitmapFromJavaBitmap(
44 Java_HandleViewResources_getRightHandleBitmap(env, context));
45 center_bitmap_ = CreateSkBitmapFromJavaBitmap(
46 Java_HandleViewResources_getCenterHandleBitmap(env, context));
48 left_bitmap_.setImmutable();
49 right_bitmap_.setImmutable();
50 center_bitmap_.setImmutable();
53 const SkBitmap& GetBitmap(ui::TouchHandleOrientation orientation) {
54 DCHECK(loaded_);
55 switch (orientation) {
56 case ui::TouchHandleOrientation::LEFT:
57 return left_bitmap_;
58 case ui::TouchHandleOrientation::RIGHT:
59 return right_bitmap_;
60 case ui::TouchHandleOrientation::CENTER:
61 return center_bitmap_;
62 case ui::TouchHandleOrientation::UNDEFINED:
63 NOTREACHED() << "Invalid touch handle orientation.";
65 return center_bitmap_;
68 private:
69 SkBitmap left_bitmap_;
70 SkBitmap right_bitmap_;
71 SkBitmap center_bitmap_;
72 bool loaded_;
74 DISALLOW_COPY_AND_ASSIGN(HandleResources);
77 base::LazyInstance<HandleResources>::Leaky g_selection_resources;
79 } // namespace
81 CompositedTouchHandleDrawable::CompositedTouchHandleDrawable(
82 cc::Layer* root_layer,
83 float dpi_scale,
84 jobject context)
85 : dpi_scale_(dpi_scale),
86 orientation_(ui::TouchHandleOrientation::UNDEFINED),
87 layer_(cc::UIResourceLayer::Create()) {
88 g_selection_resources.Get().LoadIfNecessary(context);
89 DCHECK(root_layer);
90 root_layer->AddChild(layer_.get());
93 CompositedTouchHandleDrawable::~CompositedTouchHandleDrawable() {
94 DetachLayer();
97 void CompositedTouchHandleDrawable::SetEnabled(bool enabled) {
98 layer_->SetIsDrawable(enabled);
99 // Force a position update in case the disabled layer's properties are stale.
100 if (enabled)
101 UpdateLayerPosition();
104 void CompositedTouchHandleDrawable::SetOrientation(
105 ui::TouchHandleOrientation orientation) {
106 DCHECK(layer_->parent());
107 orientation_ = orientation;
109 const SkBitmap& bitmap = g_selection_resources.Get().GetBitmap(orientation);
110 layer_->SetBitmap(bitmap);
111 layer_->SetBounds(gfx::Size(bitmap.width(), bitmap.height()));
113 switch (orientation_) {
114 case ui::TouchHandleOrientation::LEFT:
115 focal_offset_from_origin_ = gfx::Vector2dF(bitmap.width() * 0.75f, 0);
116 break;
117 case ui::TouchHandleOrientation::RIGHT:
118 focal_offset_from_origin_ = gfx::Vector2dF(bitmap.width() * 0.25f, 0);
119 break;
120 case ui::TouchHandleOrientation::CENTER:
121 focal_offset_from_origin_ = gfx::Vector2dF(bitmap.width() * 0.5f, 0);
122 break;
123 case ui::TouchHandleOrientation::UNDEFINED:
124 NOTREACHED() << "Invalid touch handle orientation.";
125 break;
128 UpdateLayerPosition();
131 void CompositedTouchHandleDrawable::SetAlpha(float alpha) {
132 DCHECK(layer_->parent());
133 alpha = std::max(0.f, std::min(1.f, alpha));
134 bool hidden = alpha <= 0;
135 layer_->SetOpacity(alpha);
136 layer_->SetHideLayerAndSubtree(hidden);
139 void CompositedTouchHandleDrawable::SetFocus(const gfx::PointF& position) {
140 DCHECK(layer_->parent());
141 focal_position_ = gfx::ScalePoint(position, dpi_scale_);
142 UpdateLayerPosition();
145 gfx::RectF CompositedTouchHandleDrawable::GetVisibleBounds() const {
146 return gfx::ScaleRect(gfx::RectF(layer_->position().x(),
147 layer_->position().y(),
148 layer_->bounds().width(),
149 layer_->bounds().height()),
150 1.f / dpi_scale_);
153 void CompositedTouchHandleDrawable::DetachLayer() {
154 layer_->RemoveFromParent();
157 void CompositedTouchHandleDrawable::UpdateLayerPosition() {
158 layer_->SetPosition(focal_position_ - focal_offset_from_origin_);
161 // static
162 bool CompositedTouchHandleDrawable::RegisterHandleViewResources(JNIEnv* env) {
163 return RegisterNativesImpl(env);
166 } // namespace content