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/layer/contextual_search_layer.h"
7 #include "cc/layers/layer.h"
8 #include "cc/layers/nine_patch_layer.h"
9 #include "cc/layers/solid_color_layer.h"
10 #include "cc/layers/ui_resource_layer.h"
11 #include "content/public/browser/android/compositor.h"
12 #include "content/public/browser/android/content_view_core.h"
13 #include "third_party/skia/include/core/SkColor.h"
14 #include "ui/android/resources/resource_manager.h"
15 #include "ui/android/resources/ui_resource_android.h"
16 #include "ui/base/l10n/l10n_util_android.h"
20 const SkColor kSearchBackgroundColor
= SkColorSetRGB(0xee, 0xee, 0xee);
21 const SkColor kSearchBarBackgroundColor
= SkColorSetRGB(0xff, 0xff, 0xff);
22 const SkColor kSearchBarBorderColor
= SkColorSetRGB(0xf1, 0xf1, 0xf1);
30 scoped_refptr
<ContextualSearchLayer
> ContextualSearchLayer::Create(
31 ui::ResourceManager
* resource_manager
) {
32 return make_scoped_refptr(new ContextualSearchLayer(resource_manager
));
35 void ContextualSearchLayer::SetProperties(
36 int panel_shadow_resource_id
,
37 int search_context_resource_id
,
38 int search_term_resource_id
,
39 int search_bar_shadow_resource_id
,
40 int search_provider_icon_resource_id
,
41 int arrow_up_resource_id
,
42 int close_icon_resource_id
,
43 int progress_bar_background_resource_id
,
44 int progress_bar_resource_id
,
45 int search_promo_resource_id
,
46 content::ContentViewCore
* content_view_core
,
47 bool search_promo_visible
,
48 float search_promo_height
,
49 float search_promo_opacity
,
52 float search_panel_width
,
53 float search_panel_height
,
54 float search_bar_margin_side
,
55 float search_bar_height
,
56 float search_context_opacity
,
57 float search_term_opacity
,
58 bool search_bar_border_visible
,
59 float search_bar_border_y
,
60 float search_bar_border_height
,
61 bool search_bar_shadow_visible
,
62 float search_bar_shadow_opacity
,
63 float arrow_icon_opacity
,
64 float arrow_icon_rotation
,
65 bool close_icon_visible
,
66 float close_icon_opacity
,
67 bool progress_bar_visible
,
69 float progress_bar_height
,
70 float progress_bar_opacity
,
71 int progress_bar_completion
) {
72 // Grabs the dynamic Search Bar Text resource.
73 ui::ResourceManager::Resource
* search_context_resource
=
74 resource_manager_
->GetResource(ui::ANDROID_RESOURCE_TYPE_DYNAMIC
,
75 search_context_resource_id
);
76 ui::ResourceManager::Resource
* search_term_resource
=
77 resource_manager_
->GetResource(ui::ANDROID_RESOURCE_TYPE_DYNAMIC
,
78 search_term_resource_id
);
80 // Grabs required static resources.
81 ui::ResourceManager::Resource
* panel_shadow_resource
=
82 resource_manager_
->GetResource(ui::ANDROID_RESOURCE_TYPE_STATIC
,
83 panel_shadow_resource_id
);
84 ui::ResourceManager::Resource
* search_provider_icon_resource
=
85 resource_manager_
->GetResource(ui::ANDROID_RESOURCE_TYPE_STATIC
,
86 search_provider_icon_resource_id
);
88 DCHECK(panel_shadow_resource
);
89 DCHECK(search_provider_icon_resource
);
91 // Round values to avoid pixel gap between layers.
92 search_bar_height
= floor(search_bar_height
);
94 bool is_rtl
= l10n_util::IsLayoutRtl();
96 // ---------------------------------------------------------------------------
98 // ---------------------------------------------------------------------------
99 gfx::Size shadow_res_size
= panel_shadow_resource
->size
;
100 gfx::Rect shadow_res_padding
= panel_shadow_resource
->padding
;
101 gfx::Size
shadow_bounds(
102 search_panel_width
+ shadow_res_size
.width()
103 - shadow_res_padding
.size().width(),
104 search_panel_height
+ shadow_res_size
.height()
105 - shadow_res_padding
.size().height());
106 panel_shadow_
->SetUIResourceId(panel_shadow_resource
->ui_resource
->id());
107 panel_shadow_
->SetBorder(panel_shadow_resource
->Border(shadow_bounds
));
108 panel_shadow_
->SetAperture(panel_shadow_resource
->aperture
);
109 panel_shadow_
->SetBounds(shadow_bounds
);
110 gfx::Point
shadow_position(
111 -shadow_res_padding
.origin().x(),
112 -shadow_res_padding
.origin().y());
113 panel_shadow_
->SetPosition(shadow_position
);
115 // ---------------------------------------------------------------------------
116 // Search Bar Background
117 // ---------------------------------------------------------------------------
118 gfx::Size
background_size(search_panel_width
, search_bar_height
);
119 search_bar_background_
->SetBounds(background_size
);
120 search_bar_background_
->SetPosition(gfx::PointF(0.f
, 0.f
));
122 // ---------------------------------------------------------------------------
124 // ---------------------------------------------------------------------------
125 if (search_context_resource
) {
126 // Centers the text vertically in the Search Bar.
127 float search_bar_padding_top
=
128 search_bar_height
/ 2 -
129 search_context_resource
->size
.height() / 2;
130 search_context_
->SetUIResourceId(
131 search_context_resource
->ui_resource
->id());
132 search_context_
->SetBounds(search_context_resource
->size
);
133 search_context_
->SetPosition(gfx::PointF(0.f
, search_bar_padding_top
));
134 search_context_
->SetOpacity(search_context_opacity
);
137 if (search_term_resource
) {
138 // Centers the text vertically in the Search Bar.
139 float search_bar_padding_top
=
140 search_bar_height
/ 2 -
141 search_term_resource
->size
.height() / 2;
142 search_term_
->SetUIResourceId(search_term_resource
->ui_resource
->id());
143 search_term_
->SetBounds(search_term_resource
->size
);
144 search_term_
->SetPosition(gfx::PointF(0.f
, search_bar_padding_top
));
145 search_term_
->SetOpacity(search_term_opacity
);
148 // ---------------------------------------------------------------------------
149 // Search Provider Icon
150 // ---------------------------------------------------------------------------
151 // Positions the Search Provider Icon at the start of the Search Bar.
152 float search_provider_icon_left
;
154 search_provider_icon_left
= search_panel_width
-
155 search_provider_icon_resource
->size
.width() - search_bar_margin_side
;
157 search_provider_icon_left
= search_bar_margin_side
;
160 // Centers the Search Provider Icon vertically in the Search Bar.
161 float search_provider_icon_top
=
162 search_bar_height
/ 2 -
163 search_provider_icon_resource
->size
.height() / 2;
165 search_provider_icon_
->SetUIResourceId(
166 search_provider_icon_resource
->ui_resource
->id());
167 search_provider_icon_
->SetBounds(search_provider_icon_resource
->size
);
168 search_provider_icon_
->SetPosition(
169 gfx::PointF(search_provider_icon_left
, search_provider_icon_top
));
171 // ---------------------------------------------------------------------------
173 // ---------------------------------------------------------------------------
174 // Grabs the Search Arrow Icon resource.
175 ui::ResourceManager::Resource
* arrow_icon_resource
=
176 resource_manager_
->GetResource(ui::ANDROID_RESOURCE_TYPE_STATIC
,
177 arrow_up_resource_id
);
178 if (arrow_icon_
->parent() != layer_
) {
179 layer_
->AddChild(arrow_icon_
);
182 // Positions the icon at the end of the Search Bar.
183 float arrow_icon_left
;
185 arrow_icon_left
= search_bar_margin_side
;
187 arrow_icon_left
= search_panel_width
-
188 arrow_icon_resource
->size
.width() - search_bar_margin_side
;
191 // Centers the Arrow Icon vertically in the Search Bar.
192 float arrow_icon_top
= search_bar_height
/ 2 -
193 arrow_icon_resource
->size
.height() / 2;
195 arrow_icon_
->SetUIResourceId(arrow_icon_resource
->ui_resource
->id());
196 arrow_icon_
->SetBounds(arrow_icon_resource
->size
);
197 arrow_icon_
->SetPosition(
198 gfx::PointF(arrow_icon_left
, arrow_icon_top
));
199 arrow_icon_
->SetOpacity(arrow_icon_opacity
);
201 gfx::Transform transform
;
202 if (arrow_icon_rotation
!= 0.f
) {
203 // Apply rotation about the center of the icon.
204 float pivot_x
= floor(arrow_icon_resource
->size
.width() / 2);
205 float pivot_y
= floor(arrow_icon_resource
->size
.height() / 2);
206 gfx::PointF
pivot_origin(pivot_x
, pivot_y
);
207 transform
.Translate(pivot_origin
.x(), pivot_origin
.y());
208 transform
.RotateAboutZAxis(arrow_icon_rotation
);
209 transform
.Translate(-pivot_origin
.x(), -pivot_origin
.y());
211 arrow_icon_
->SetTransform(transform
);
213 // ---------------------------------------------------------------------------
215 // ---------------------------------------------------------------------------
216 if (close_icon_visible
) {
217 // Grab the Close Icon resource.
218 ui::ResourceManager::Resource
* close_icon_resource
=
219 resource_manager_
->GetResource(ui::ANDROID_RESOURCE_TYPE_STATIC
,
220 close_icon_resource_id
);
221 if (close_icon_
->parent() != layer_
) {
222 layer_
->AddChild(close_icon_
);
225 // Positions the icon at the end of the Search Bar.
226 float close_icon_left
;
228 close_icon_left
= search_bar_margin_side
;
230 close_icon_left
= search_panel_width
-
231 close_icon_resource
->size
.width() - search_bar_margin_side
;
234 // Centers the Close Icon vertically in the Search Bar.
235 float close_icon_top
=
236 search_bar_height
/ 2 -
237 close_icon_resource
->size
.height() / 2;
239 close_icon_
->SetUIResourceId(close_icon_resource
->ui_resource
->id());
240 close_icon_
->SetBounds(close_icon_resource
->size
);
241 close_icon_
->SetPosition(
242 gfx::PointF(close_icon_left
, close_icon_top
));
243 close_icon_
->SetOpacity(close_icon_opacity
);
245 if (close_icon_
.get() && close_icon_
->parent())
246 close_icon_
->RemoveFromParent();
249 // ---------------------------------------------------------------------------
251 // ---------------------------------------------------------------------------
252 if (search_promo_visible
) {
253 // Grabs the Search Opt Out Promo resource.
254 ui::ResourceManager::Resource
* search_promo_resource
=
255 resource_manager_
->GetResource(ui::ANDROID_RESOURCE_TYPE_DYNAMIC
,
256 search_promo_resource_id
);
257 // Search Promo Container
258 if (search_promo_container_
->parent() != layer_
) {
259 // NOTE(pedrosimonetti): The Promo layer should be always placed before
260 // Search Bar Shadow to make sure it won't occlude the shadow.
261 layer_
->InsertChild(search_promo_container_
, 0);
264 if (search_promo_resource
) {
265 int search_promo_content_height
= search_promo_resource
->size
.height();
266 gfx::Size
search_promo_size(search_panel_width
, search_promo_height
);
267 search_promo_container_
->SetBounds(search_promo_size
);
268 search_promo_container_
->SetPosition(gfx::PointF(0.f
, search_bar_height
));
269 search_promo_container_
->SetMasksToBounds(true);
272 if (search_promo_
->parent() != search_promo_container_
)
273 search_promo_container_
->AddChild(search_promo_
);
275 search_promo_
->SetUIResourceId(search_promo_resource
->ui_resource
->id());
276 search_promo_
->SetBounds(search_promo_resource
->size
);
277 // Align promo at the bottom of the container so the confirmation button
278 // is is not clipped when resizing the promo.
279 search_promo_
->SetPosition(
280 gfx::PointF(0.f
, search_promo_height
- search_promo_content_height
));
281 search_promo_
->SetOpacity(search_promo_opacity
);
284 // Search Promo Container
285 if (search_promo_container_
.get() && search_promo_container_
->parent())
286 search_promo_container_
->RemoveFromParent();
289 // ---------------------------------------------------------------------------
290 // Search Content View
291 // ---------------------------------------------------------------------------
292 content_view_container_
->SetPosition(
293 gfx::PointF(0.f
, search_bar_height
+ search_promo_height
));
294 if (content_view_core
&& content_view_core
->GetLayer().get()) {
295 scoped_refptr
<cc::Layer
> content_view_layer
= content_view_core
->GetLayer();
296 if (content_view_layer
->parent() != content_view_container_
)
297 content_view_container_
->AddChild(content_view_layer
);
299 content_view_container_
->RemoveAllChildren();
302 // ---------------------------------------------------------------------------
304 // ---------------------------------------------------------------------------
305 if (search_bar_shadow_visible
) {
306 ui::ResourceManager::Resource
* search_bar_shadow_resource
=
307 resource_manager_
->GetResource(ui::ANDROID_RESOURCE_TYPE_STATIC
,
308 search_bar_shadow_resource_id
);
310 if (search_bar_shadow_resource
) {
311 if (search_bar_shadow_
->parent() != layer_
)
312 layer_
->AddChild(search_bar_shadow_
);
314 int shadow_height
= search_bar_shadow_resource
->size
.height();
315 gfx::Size
shadow_size(search_panel_width
, shadow_height
);
317 search_bar_shadow_
->SetUIResourceId(
318 search_bar_shadow_resource
->ui_resource
->id());
319 search_bar_shadow_
->SetBounds(shadow_size
);
320 search_bar_shadow_
->SetPosition(gfx::PointF(0.f
, search_bar_height
));
321 search_bar_shadow_
->SetOpacity(search_bar_shadow_opacity
);
324 if (search_bar_shadow_
.get() && search_bar_shadow_
->parent())
325 search_bar_shadow_
->RemoveFromParent();
328 // ---------------------------------------------------------------------------
330 // ---------------------------------------------------------------------------
331 layer_
->SetPosition(gfx::PointF(search_panel_x
, search_panel_y
));
333 // ---------------------------------------------------------------------------
335 // ---------------------------------------------------------------------------
336 bool should_render_progress_bar
=
337 progress_bar_visible
&& progress_bar_opacity
> 0.f
;
338 if (should_render_progress_bar
) {
339 // Grabs Progress Bar resources.
340 ui::ResourceManager::Resource
* progress_bar_background_resource
=
341 resource_manager_
->GetResource(ui::ANDROID_RESOURCE_TYPE_STATIC
,
342 progress_bar_background_resource_id
);
343 ui::ResourceManager::Resource
* progress_bar_resource
=
344 resource_manager_
->GetResource(ui::ANDROID_RESOURCE_TYPE_STATIC
,
345 progress_bar_resource_id
);
347 DCHECK(progress_bar_background_resource
);
348 DCHECK(progress_bar_resource
);
350 // Progress Bar Background
351 if (progress_bar_background_
->parent() != layer_
)
352 layer_
->AddChild(progress_bar_background_
);
354 gfx::Size
progress_bar_background_size(search_panel_width
,
355 progress_bar_height
);
356 progress_bar_background_
->SetUIResourceId(
357 progress_bar_background_resource
->ui_resource
->id());
358 progress_bar_background_
->SetBorder(
359 progress_bar_background_resource
->Border(progress_bar_background_size
));
360 progress_bar_background_
->SetAperture(
361 progress_bar_background_resource
->aperture
);
362 progress_bar_background_
->SetBounds(progress_bar_background_size
);
363 progress_bar_background_
->SetPosition(gfx::PointF(0.f
, progress_bar_y
));
364 progress_bar_background_
->SetOpacity(progress_bar_opacity
);
367 if (progress_bar_
->parent() != layer_
)
368 layer_
->AddChild(progress_bar_
);
370 float progress_bar_width
=
371 floor(search_panel_width
* progress_bar_completion
/ 100.f
);
372 gfx::Size
progress_bar_size(progress_bar_width
, progress_bar_height
);
373 progress_bar_
->SetUIResourceId(progress_bar_resource
->ui_resource
->id());
374 progress_bar_
->SetBorder(progress_bar_resource
->Border(progress_bar_size
));
375 progress_bar_
->SetAperture(progress_bar_resource
->aperture
);
376 progress_bar_
->SetBounds(progress_bar_size
);
377 progress_bar_
->SetPosition(gfx::PointF(0.f
, progress_bar_y
));
378 progress_bar_
->SetOpacity(progress_bar_opacity
);
380 // Removes Progress Bar and its Background from the Layer Tree.
381 if (progress_bar_background_
.get() && progress_bar_background_
->parent())
382 progress_bar_background_
->RemoveFromParent();
384 if (progress_bar_
.get() && progress_bar_
->parent())
385 progress_bar_
->RemoveFromParent();
388 // ---------------------------------------------------------------------------
389 // Search Bar border.
390 // ---------------------------------------------------------------------------
391 if (!should_render_progress_bar
&& search_bar_border_visible
) {
392 gfx::Size
search_bar_border_size(search_panel_width
,
393 search_bar_border_height
);
394 search_bar_border_
->SetBounds(search_bar_border_size
);
395 search_bar_border_
->SetPosition(gfx::PointF(0.f
, search_bar_border_y
));
396 layer_
->AddChild(search_bar_border_
);
397 } else if (search_bar_border_
.get() && search_bar_border_
->parent()) {
398 search_bar_border_
->RemoveFromParent();
402 ContextualSearchLayer::ContextualSearchLayer(
403 ui::ResourceManager
* resource_manager
)
404 : resource_manager_(resource_manager
),
405 layer_(cc::Layer::Create(content::Compositor::LayerSettings())),
407 cc::NinePatchLayer::Create(content::Compositor::LayerSettings())),
408 search_bar_background_(
409 cc::SolidColorLayer::Create(content::Compositor::LayerSettings())),
411 cc::UIResourceLayer::Create(content::Compositor::LayerSettings())),
413 cc::UIResourceLayer::Create(content::Compositor::LayerSettings())),
415 cc::UIResourceLayer::Create(content::Compositor::LayerSettings())),
416 search_provider_icon_(
417 cc::UIResourceLayer::Create(content::Compositor::LayerSettings())),
419 cc::UIResourceLayer::Create(content::Compositor::LayerSettings())),
421 cc::UIResourceLayer::Create(content::Compositor::LayerSettings())),
422 content_view_container_(
423 cc::Layer::Create(content::Compositor::LayerSettings())),
425 cc::SolidColorLayer::Create(content::Compositor::LayerSettings())),
427 cc::NinePatchLayer::Create(content::Compositor::LayerSettings())),
428 progress_bar_background_(
429 cc::NinePatchLayer::Create(content::Compositor::LayerSettings())),
431 cc::UIResourceLayer::Create(content::Compositor::LayerSettings())),
432 search_promo_container_(
433 cc::SolidColorLayer::Create(content::Compositor::LayerSettings())) {
434 layer_
->SetMasksToBounds(false);
435 layer_
->SetIsDrawable(true);
438 panel_shadow_
->SetIsDrawable(true);
439 panel_shadow_
->SetFillCenter(false);
440 layer_
->AddChild(panel_shadow_
);
442 // Search Bar Background
443 search_bar_background_
->SetIsDrawable(true);
444 search_bar_background_
->SetBackgroundColor(kSearchBarBackgroundColor
);
445 layer_
->AddChild(search_bar_background_
);
448 search_context_
->SetIsDrawable(true);
449 layer_
->AddChild(search_context_
);
450 search_term_
->SetIsDrawable(true);
451 layer_
->AddChild(search_term_
);
453 // Search Provider Icon
454 search_provider_icon_
->SetIsDrawable(true);
455 layer_
->AddChild(search_provider_icon_
);
458 arrow_icon_
->SetIsDrawable(true);
461 close_icon_
->SetIsDrawable(true);
463 // Search Opt Out Promo
464 search_promo_container_
->SetIsDrawable(true);
465 search_promo_container_
->SetBackgroundColor(kSearchBackgroundColor
);
466 search_promo_
->SetIsDrawable(true);
469 search_bar_border_
->SetIsDrawable(true);
470 search_bar_border_
->SetBackgroundColor(kSearchBarBorderColor
);
472 // Progress Bar Background
473 progress_bar_background_
->SetIsDrawable(true);
474 progress_bar_background_
->SetFillCenter(true);
477 progress_bar_
->SetIsDrawable(true);
478 progress_bar_
->SetFillCenter(true);
480 // Search Content View Container
481 layer_
->AddChild(content_view_container_
);
484 search_bar_shadow_
->SetIsDrawable(true);
487 ContextualSearchLayer::~ContextualSearchLayer() {
490 scoped_refptr
<cc::Layer
> ContextualSearchLayer::layer() {
494 } // namespace android
495 } // namespace chrome