Switch global error menu icon to vectorized MD asset
[chromium-blink-merge.git] / chrome / browser / android / compositor / decoration_title.cc
blob0169c65cff91d5030cf5434158bc57e9207fd092
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 "chrome/browser/android/compositor/decoration_title.h"
7 #include <android/bitmap.h>
9 #include "base/i18n/rtl.h"
10 #include "base/logging.h"
11 #include "cc/layers/layer.h"
12 #include "cc/layers/ui_resource_layer.h"
13 #include "chrome/browser/android/compositor/layer_title_cache.h"
14 #include "content/public/browser/android/compositor.h"
15 #include "ui/android/resources/resource_manager.h"
16 #include "ui/android/resources/ui_resource_android.h"
17 #include "ui/base/l10n/l10n_util_android.h"
18 #include "ui/gfx/android/java_bitmap.h"
19 #include "ui/gfx/geometry/vector3d_f.h"
21 namespace chrome {
22 namespace android {
24 DecorationTitle::DecorationTitle(LayerTitleCache* layer_title_cache,
25 ui::ResourceManager* resource_manager,
26 int title_resource_id,
27 int favicon_resource_id,
28 int spinner_resource_id,
29 int spinner_incognito_resource_id,
30 int fade_width,
31 int favicon_start_padding,
32 int favicon_end_padding,
33 bool is_incognito,
34 bool is_rtl)
35 : layer_(cc::Layer::Create(content::Compositor::LayerSettings())),
36 layer_opaque_(
37 cc::UIResourceLayer::Create(content::Compositor::LayerSettings())),
38 layer_fade_(
39 cc::UIResourceLayer::Create(content::Compositor::LayerSettings())),
40 layer_favicon_(
41 cc::UIResourceLayer::Create(content::Compositor::LayerSettings())),
42 title_resource_id_(title_resource_id),
43 favicon_resource_id_(favicon_resource_id),
44 spinner_resource_id_(spinner_resource_id),
45 spinner_incognito_resource_id_(spinner_resource_id),
46 fade_width_(fade_width),
47 spinner_rotation_(0),
48 favicon_start_padding_(favicon_start_padding),
49 favicon_end_padding_(favicon_end_padding),
50 is_incognito_(is_incognito),
51 is_rtl_(is_rtl),
52 is_loading_(false),
53 transform_(new gfx::Transform()),
54 resource_manager_(resource_manager),
55 layer_title_cache_(layer_title_cache) {
56 layer_->AddChild(layer_favicon_);
57 layer_->AddChild(layer_opaque_);
58 layer_->AddChild(layer_fade_);
61 DecorationTitle::~DecorationTitle() {
62 layer_->RemoveFromParent();
65 void DecorationTitle::SetResourceManager(
66 ui::ResourceManager* resource_manager) {
67 resource_manager_ = resource_manager;
70 void DecorationTitle::Update(int title_resource_id,
71 int favicon_resource_id,
72 int fade_width,
73 int favicon_start_padding,
74 int favicon_end_padding,
75 bool is_incognito,
76 bool is_rtl) {
77 title_resource_id_ = title_resource_id;
78 favicon_resource_id_ = favicon_resource_id;
79 is_incognito_ = is_incognito;
80 is_rtl_ = is_rtl;
81 favicon_start_padding_ = favicon_start_padding;
82 favicon_end_padding_ = favicon_end_padding;
83 fade_width_ = fade_width;
86 void DecorationTitle::SetUIResourceIds() {
87 ui::ResourceManager::Resource* title_resource =
88 resource_manager_->GetResource(ui::ANDROID_RESOURCE_TYPE_DYNAMIC_BITMAP,
89 title_resource_id_);
90 if (title_resource) {
91 layer_opaque_->SetUIResourceId(title_resource->ui_resource->id());
92 layer_fade_->SetUIResourceId(title_resource->ui_resource->id());
93 title_size_ = title_resource->size;
96 if (!is_loading_) {
97 ui::ResourceManager::Resource* favicon_resource =
98 resource_manager_->GetResource(ui::ANDROID_RESOURCE_TYPE_DYNAMIC_BITMAP,
99 favicon_resource_id_);
100 if (favicon_resource) {
101 layer_favicon_->SetUIResourceId(favicon_resource->ui_resource->id());
102 favicon_size_ = favicon_resource->size;
103 } else {
104 layer_favicon_->SetUIResourceId(0);
106 layer_favicon_->SetTransform(gfx::Transform());
107 } else {
108 int resource_id =
109 is_incognito_ ? spinner_incognito_resource_id_ : spinner_resource_id_;
111 ui::ResourceManager::Resource* spinner_resource =
112 resource_manager_->GetResource(ui::ANDROID_RESOURCE_TYPE_STATIC,
113 resource_id);
115 if (spinner_resource)
116 layer_favicon_->SetUIResourceId(spinner_resource->ui_resource->id());
118 // Rotate about the center of the layer.
119 layer_favicon_->SetTransformOrigin(
120 gfx::Point3F(favicon_size_.width() / 2, favicon_size_.height() / 2, 0));
123 size_ = gfx::Size(title_size_.width() + favicon_size_.width(),
124 title_size_.height());
127 void DecorationTitle::SetIsLoading(bool is_loading) {
128 if (is_loading != is_loading_) {
129 is_loading_ = is_loading;
130 SetUIResourceIds();
134 void DecorationTitle::SetSpinnerRotation(float rotation) {
135 if (!is_loading_)
136 return;
137 float diff = rotation - spinner_rotation_;
138 spinner_rotation_ = rotation;
139 if (diff != 0) {
140 transform_->RotateAboutZAxis(diff);
142 layer_favicon_->SetTransform(*transform_.get());
145 void DecorationTitle::setOpacity(float opacity) {
146 layer_opaque_->SetOpacity(opacity);
147 layer_favicon_->SetOpacity(opacity);
148 layer_fade_->SetOpacity(opacity);
151 void DecorationTitle::setBounds(const gfx::Size& bounds) {
152 layer_->SetBounds(gfx::Size(bounds.width(), size_.height()));
154 if (bounds.GetArea() == 0.f) {
155 layer_->SetHideLayerAndSubtree(true);
156 return;
157 } else {
158 layer_->SetHideLayerAndSubtree(false);
161 // Current implementation assumes there is always enough space
162 // to draw favicon and title fade.
164 // Note that favicon positon and title aligning depends on the system locale,
165 // l10n_util::IsLayoutRtl(), while title starting and fade out direction
166 // depends on the title text locale (DecorationTitle::is_rtl_).
168 bool sys_rtl = l10n_util::IsLayoutRtl();
169 int favicon_space =
170 favicon_size_.width() + favicon_start_padding_ + favicon_end_padding_;
171 int title_space = std::max(0, bounds.width() - favicon_space - fade_width_);
172 int fade_space = std::max(0, bounds.width() - favicon_space - title_space);
174 if (title_size_.width() <= title_space + fade_space)
175 title_space += fade_space;
177 if (title_size_.width() <= title_space)
178 fade_space = 0.f;
180 float favicon_offset_y = (size_.height() - favicon_size_.height()) / 2.f;
181 float title_offset_y = (size_.height() - title_size_.height()) / 2.f;
183 // Step 1. Place favicon.
184 int favicon_x = favicon_start_padding_;
185 if (sys_rtl) {
186 favicon_x = bounds.width() - favicon_size_.width() - favicon_start_padding_;
188 layer_favicon_->SetIsDrawable(true);
189 layer_favicon_->SetBounds(favicon_size_);
190 layer_favicon_->SetPosition(gfx::PointF(favicon_x, favicon_offset_y));
192 // Step 2. Place the opaque title component.
193 if (title_space > 0.f) {
194 // Calculate the title position and size, taking into account both
195 // system and title RTL.
196 int width = std::min(title_space, title_size_.width());
197 int x_offset = sys_rtl ? title_space - width : favicon_space;
198 int x = x_offset + (is_rtl_ ? fade_space : 0);
200 // Calculate the UV coordinates taking into account title RTL.
201 float width_percentage = (float)width / title_size_.width();
202 float u1 = is_rtl_ ? 1.f - width_percentage : 0.f;
203 float u2 = is_rtl_ ? 1.f : width_percentage;
205 layer_opaque_->SetIsDrawable(true);
206 layer_opaque_->SetBounds(gfx::Size(width, title_size_.height()));
207 layer_opaque_->SetPosition(gfx::PointF(x, title_offset_y));
208 layer_opaque_->SetUV(gfx::PointF(u1, 0.f), gfx::PointF(u2, 1.f));
209 } else {
210 layer_opaque_->SetIsDrawable(false);
213 // Step 3. Place the fade title component.
214 if (fade_space > 0.f) {
215 // Calculate the title position and size, taking into account both
216 // system and title RTL.
217 int x_offset = sys_rtl ? 0 : favicon_space;
218 int x = x_offset + (is_rtl_ ? 0 : title_space);
219 float title_amt = (float)title_space / title_size_.width();
220 float fade_amt = (float)fade_space / title_size_.width();
222 // Calculate UV coordinates taking into account title RTL.
223 float u1 = is_rtl_ ? 1.f - title_amt - fade_amt : title_amt;
224 float u2 = is_rtl_ ? 1.f - title_amt : title_amt + fade_amt;
226 // Calculate vertex alpha taking into account title RTL.
227 float max_alpha = (float)fade_space / fade_width_;
228 float a1 = is_rtl_ ? 0.f : max_alpha;
229 float a2 = is_rtl_ ? max_alpha : 0.f;
231 layer_fade_->SetIsDrawable(true);
232 layer_fade_->SetBounds(gfx::Size(fade_space, title_size_.height()));
233 layer_fade_->SetPosition(gfx::PointF(x, title_offset_y));
234 layer_fade_->SetUV(gfx::PointF(u1, 0.f), gfx::PointF(u2, 1.f));
235 layer_fade_->SetVertexOpacity(a1, a1, a2, a2);
236 } else {
237 layer_fade_->SetIsDrawable(false);
241 scoped_refptr<cc::Layer> DecorationTitle::layer() {
242 DCHECK(layer_.get());
243 return layer_;
246 } // namespace android
247 } // namespace chrome