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.
4 
5 #include "chrome/browser/android/compositor/layer/toolbar_layer.h"
6 
7 #include "cc/layers/nine_patch_layer.h"
8 #include "cc/layers/solid_color_layer.h"
9 #include "cc/layers/ui_resource_layer.h"
10 #include "cc/resources/scoped_ui_resource.h"
11 #include "chrome/browser/android/compositor/resources/toolbar_resource.h"
12 #include "third_party/skia/include/core/SkColor.h"
13 #include "ui/android/resources/nine_patch_resource.h"
14 #include "ui/android/resources/resource_manager.h"
15 
16 namespace android {
17 
18 // static
Create(ui::ResourceManager * resource_manager)19 scoped_refptr<ToolbarLayer> ToolbarLayer::Create(
20     ui::ResourceManager* resource_manager) {
21   return base::WrapRefCounted(new ToolbarLayer(resource_manager));
22 }
23 
layer()24 scoped_refptr<cc::Layer> ToolbarLayer::layer() {
25   return layer_;
26 }
27 
PushResource(int toolbar_resource_id,int toolbar_background_color,bool anonymize,int toolbar_textbox_background_color,int url_bar_background_resource_id,float content_offset,bool show_debug,bool clip_shadow)28 void ToolbarLayer::PushResource(int toolbar_resource_id,
29                                 int toolbar_background_color,
30                                 bool anonymize,
31                                 int toolbar_textbox_background_color,
32                                 int url_bar_background_resource_id,
33                                 float content_offset,
34                                 bool show_debug,
35                                 bool clip_shadow) {
36   ToolbarResource* resource =
37       ToolbarResource::From(resource_manager_->GetResource(
38           ui::ANDROID_RESOURCE_TYPE_DYNAMIC, toolbar_resource_id));
39 
40   // Ensure the toolbar resource is available before making the layer visible.
41   layer_->SetHideLayerAndSubtree(!resource);
42   if (!resource)
43     return;
44 
45   // This layer effectively draws over the space the resource takes for shadows.
46   // Set the bounds to the non-shadow size so that other things can properly
47   // line up.
48   gfx::Size toolbar_bounds =
49       gfx::Size(resource->size().width(),
50                 resource->size().height() - resource->shadow_height());
51   layer_->SetBounds(toolbar_bounds);
52 
53   toolbar_background_layer_->SetBounds(resource->toolbar_rect().size());
54   toolbar_background_layer_->SetPosition(
55       gfx::PointF(resource->toolbar_rect().origin()));
56   toolbar_background_layer_->SetBackgroundColor(toolbar_background_color);
57 
58   bool url_bar_visible = resource->location_bar_content_rect().width() != 0;
59   url_bar_background_layer_->SetHideLayerAndSubtree(!url_bar_visible);
60   if (url_bar_visible) {
61     ui::NinePatchResource* url_bar_background_resource;
62     url_bar_background_resource = ui::NinePatchResource::From(
63         resource_manager_->GetStaticResourceWithTint(
64             url_bar_background_resource_id, toolbar_textbox_background_color));
65 
66     gfx::Size draw_size(url_bar_background_resource->DrawSize(
67         resource->location_bar_content_rect().size()));
68     gfx::Rect border(url_bar_background_resource->Border(draw_size));
69     gfx::PointF position(url_bar_background_resource->DrawPosition(
70         resource->location_bar_content_rect().origin()));
71 
72     url_bar_background_layer_->SetBounds(draw_size);
73     url_bar_background_layer_->SetPosition(position);
74     url_bar_background_layer_->SetBorder(border);
75     url_bar_background_layer_->SetAperture(
76         url_bar_background_resource->aperture());
77     url_bar_background_layer_->SetUIResourceId(
78         url_bar_background_resource->ui_resource()->id());
79   }
80 
81   bitmap_layer_->SetUIResourceId(resource->ui_resource()->id());
82   bitmap_layer_->SetBounds(resource->size());
83 
84   layer_->SetMasksToBounds(clip_shadow);
85 
86   // The location bar background doubles as the anonymize layer -- it just
87   // needs to be drawn on top of the toolbar bitmap.
88   int background_layer_index = GetIndexOfLayer(toolbar_background_layer_);
89 
90   bool needs_move_to_front =
91       anonymize && layer_->children().back() != url_bar_background_layer_;
92   bool needs_move_to_back =
93       !anonymize &&
94       layer_->children()[background_layer_index] != url_bar_background_layer_;
95 
96   // If the layer needs to move, remove and re-add it.
97   if (needs_move_to_front) {
98     layer_->AddChild(url_bar_background_layer_);
99   } else if (needs_move_to_back) {
100     layer_->InsertChild(url_bar_background_layer_, background_layer_index + 1);
101   }
102 
103   debug_layer_->SetBounds(resource->size());
104   if (show_debug && !debug_layer_->parent())
105     layer_->AddChild(debug_layer_);
106   else if (!show_debug && debug_layer_->parent())
107     debug_layer_->RemoveFromParent();
108 
109   // Position the toolbar at the bottom of the space available for top controls.
110   layer_->SetPosition(
111       gfx::PointF(0, content_offset - layer_->bounds().height()));
112 }
113 
GetIndexOfLayer(scoped_refptr<cc::Layer> layer)114 int ToolbarLayer::GetIndexOfLayer(scoped_refptr<cc::Layer> layer) {
115   for (unsigned int i = 0; i < layer_->children().size(); ++i) {
116     if (layer_->children()[i] == layer)
117       return i;
118   }
119   return -1;
120 }
121 
UpdateProgressBar(int progress_bar_x,int progress_bar_y,int progress_bar_width,int progress_bar_height,int progress_bar_color,int progress_bar_background_x,int progress_bar_background_y,int progress_bar_background_width,int progress_bar_background_height,int progress_bar_background_color)122 void ToolbarLayer::UpdateProgressBar(int progress_bar_x,
123                                      int progress_bar_y,
124                                      int progress_bar_width,
125                                      int progress_bar_height,
126                                      int progress_bar_color,
127                                      int progress_bar_background_x,
128                                      int progress_bar_background_y,
129                                      int progress_bar_background_width,
130                                      int progress_bar_background_height,
131                                      int progress_bar_background_color) {
132   bool is_progress_bar_background_visible = SkColorGetA(
133       progress_bar_background_color);
134   progress_bar_background_layer_->SetHideLayerAndSubtree(
135       !is_progress_bar_background_visible);
136   if (is_progress_bar_background_visible) {
137     progress_bar_background_layer_->SetPosition(
138         gfx::PointF(progress_bar_background_x, progress_bar_background_y));
139     progress_bar_background_layer_->SetBounds(
140         gfx::Size(progress_bar_background_width,
141                   progress_bar_background_height));
142     progress_bar_background_layer_->SetBackgroundColor(
143         progress_bar_background_color);
144   }
145 
146   bool is_progress_bar_visible = SkColorGetA(progress_bar_background_color);
147   progress_bar_layer_->SetHideLayerAndSubtree(!is_progress_bar_visible);
148   if (is_progress_bar_visible) {
149     progress_bar_layer_->SetPosition(
150         gfx::PointF(progress_bar_x, progress_bar_y));
151     progress_bar_layer_->SetBounds(
152         gfx::Size(progress_bar_width, progress_bar_height));
153     progress_bar_layer_->SetBackgroundColor(progress_bar_color);
154   }
155 }
156 
SetOpacity(float opacity)157 void ToolbarLayer::SetOpacity(float opacity) {
158   toolbar_background_layer_->SetOpacity(opacity);
159   url_bar_background_layer_->SetOpacity(opacity);
160   bitmap_layer_->SetOpacity(opacity);
161   progress_bar_layer_->SetOpacity(opacity);
162   progress_bar_background_layer_->SetOpacity(opacity);
163 }
164 
ToolbarLayer(ui::ResourceManager * resource_manager)165 ToolbarLayer::ToolbarLayer(ui::ResourceManager* resource_manager)
166     : resource_manager_(resource_manager),
167       layer_(cc::Layer::Create()),
168       toolbar_background_layer_(cc::SolidColorLayer::Create()),
169       url_bar_background_layer_(cc::NinePatchLayer::Create()),
170       bitmap_layer_(cc::UIResourceLayer::Create()),
171       progress_bar_layer_(cc::SolidColorLayer::Create()),
172       progress_bar_background_layer_(cc::SolidColorLayer::Create()),
173       debug_layer_(cc::SolidColorLayer::Create()) {
174   toolbar_background_layer_->SetIsDrawable(true);
175   layer_->AddChild(toolbar_background_layer_);
176 
177   url_bar_background_layer_->SetIsDrawable(true);
178   url_bar_background_layer_->SetFillCenter(true);
179   layer_->AddChild(url_bar_background_layer_);
180 
181   bitmap_layer_->SetIsDrawable(true);
182   layer_->AddChild(bitmap_layer_);
183 
184   progress_bar_background_layer_->SetIsDrawable(true);
185   progress_bar_background_layer_->SetHideLayerAndSubtree(true);
186   layer_->AddChild(progress_bar_background_layer_);
187 
188   progress_bar_layer_->SetIsDrawable(true);
189   progress_bar_layer_->SetHideLayerAndSubtree(true);
190   layer_->AddChild(progress_bar_layer_);
191 
192   debug_layer_->SetIsDrawable(true);
193   debug_layer_->SetBackgroundColor(SK_ColorGREEN);
194   debug_layer_->SetOpacity(0.5f);
195 }
196 
~ToolbarLayer()197 ToolbarLayer::~ToolbarLayer() {
198 }
199 
200 }  //  namespace android
201