blob: 8de3728e757f7f94198aa4abf83ca099b4f1532b [file] [log] [blame]
// Copyright 2015 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.
#include "chrome/browser/android/compositor/layer/overlay_panel_layer.h"
#include "cc/layers/layer.h"
#include "cc/layers/nine_patch_layer.h"
#include "cc/layers/solid_color_layer.h"
#include "cc/layers/ui_resource_layer.h"
#include "cc/resources/scoped_ui_resource.h"
#include "content/public/browser/android/compositor.h"
#include "third_party/skia/include/core/SkColor.h"
#include "ui/android/resources/crushed_sprite_resource.h"
#include "ui/android/resources/nine_patch_resource.h"
#include "ui/android/resources/resource_manager.h"
#include "ui/base/l10n/l10n_util_android.h"
#include "ui/gfx/color_utils.h"
namespace {
const SkColor kBarBackgroundColor = SkColorSetRGB(0xff, 0xff, 0xff);
const SkColor kBarBorderColor = SkColorSetRGB(0xf1, 0xf1, 0xf1);
// This is the default width for any icon displayed on an OverlayPanel.
const float kDefaultIconWidthDp = 36.0f;
} // namespace
namespace android {
scoped_refptr<cc::Layer> OverlayPanelLayer::GetIconLayer() {
ui::Resource* panel_icon_resource = resource_manager_->GetResource(
ui::ANDROID_RESOURCE_TYPE_STATIC, panel_icon_resource_id_);
DCHECK(panel_icon_resource);
if (panel_icon_->parent() != layer_) {
layer_->AddChild(panel_icon_);
}
panel_icon_->SetUIResourceId(panel_icon_resource->ui_resource()->id());
panel_icon_->SetBounds(panel_icon_resource->size());
return panel_icon_;
}
void OverlayPanelLayer::AddBarTextLayer(scoped_refptr<cc::Layer> text_layer) {
text_container_->AddChild(text_layer);
}
void OverlayPanelLayer::SetResourceIds(
int bar_text_resource_id,
int panel_shadow_resource_id,
int bar_shadow_resource_id,
int panel_icon_resource_id,
int close_icon_resource_id) {
bar_text_resource_id_ = bar_text_resource_id;
panel_shadow_resource_id_ = panel_shadow_resource_id;
bar_shadow_resource_id_ = bar_shadow_resource_id;
panel_icon_resource_id_ = panel_icon_resource_id;
close_icon_resource_id_ = close_icon_resource_id;
}
void OverlayPanelLayer::SetProperties(
float dp_to_px,
const scoped_refptr<cc::Layer>& content_layer,
float content_offset_y,
float panel_x,
float panel_y,
float panel_width,
float panel_height,
float bar_margin_side,
float bar_height,
float bar_offset_y,
float bar_text_opacity,
bool bar_border_visible,
float bar_border_height,
bool bar_shadow_visible,
float bar_shadow_opacity,
float close_icon_opacity) {
// Grabs required static resources.
ui::NinePatchResource* panel_shadow_resource =
ui::NinePatchResource::From(resource_manager_->GetResource(
ui::ANDROID_RESOURCE_TYPE_STATIC, panel_shadow_resource_id_));
DCHECK(panel_shadow_resource);
// Round values to avoid pixel gap between layers.
bar_height = floor(bar_height);
float bar_top = bar_offset_y;
float bar_bottom = bar_top + bar_height;
bool is_rtl = l10n_util::IsLayoutRtl();
// ---------------------------------------------------------------------------
// Panel Shadow
// ---------------------------------------------------------------------------
gfx::Size shadow_res_size = panel_shadow_resource->size();
gfx::Rect shadow_res_padding = panel_shadow_resource->padding();
gfx::Size shadow_bounds(
panel_width + shadow_res_size.width()
- shadow_res_padding.size().width(),
panel_height + shadow_res_size.height()
- shadow_res_padding.size().height());
panel_shadow_->SetUIResourceId(panel_shadow_resource->ui_resource()->id());
panel_shadow_->SetBorder(panel_shadow_resource->Border(shadow_bounds));
panel_shadow_->SetAperture(panel_shadow_resource->aperture());
panel_shadow_->SetBounds(shadow_bounds);
gfx::PointF shadow_position(-shadow_res_padding.origin().x(),
-shadow_res_padding.origin().y());
panel_shadow_->SetPosition(shadow_position);
// ---------------------------------------------------------------------------
// Bar Background
// ---------------------------------------------------------------------------
gfx::Size background_size(panel_width, bar_height);
bar_background_->SetBounds(background_size);
bar_background_->SetPosition(gfx::PointF(0.f, bar_top));
// ---------------------------------------------------------------------------
// Bar Text
// ---------------------------------------------------------------------------
ui::Resource* bar_text_resource = resource_manager_->GetResource(
ui::ANDROID_RESOURCE_TYPE_DYNAMIC, bar_text_resource_id_);
if (bar_text_resource) {
// Centers the text vertically in the Search Bar.
float bar_padding_top =
bar_top + bar_height / 2 - bar_text_resource->size().height() / 2;
bar_text_->SetUIResourceId(bar_text_resource->ui_resource()->id());
bar_text_->SetBounds(bar_text_resource->size());
bar_text_->SetPosition(gfx::PointF(0.f, bar_padding_top));
bar_text_->SetOpacity(bar_text_opacity);
}
// ---------------------------------------------------------------------------
// Panel Icon
// ---------------------------------------------------------------------------
scoped_refptr<cc::Layer> icon_layer = GetIconLayer();
if (icon_layer) {
// If the icon is not the default width, add or remove padding so it appears
// centered.
float icon_padding = (kDefaultIconWidthDp * dp_to_px -
icon_layer->bounds().width()) / 2.0f;
// Positions the Icon at the start of the bar.
float icon_x;
if (is_rtl) {
icon_x = panel_width - icon_layer->bounds().width() -
(bar_margin_side + icon_padding);
} else {
icon_x = bar_margin_side + icon_padding;
}
// Centers the Icon vertically in the bar.
float icon_y = bar_top + bar_height / 2 -
icon_layer->bounds().height() / 2;
icon_layer->SetPosition(gfx::PointF(icon_x, icon_y));
}
// ---------------------------------------------------------------------------
// Close Icon
// ---------------------------------------------------------------------------
// Grab the Close Icon resource.
ui::Resource* close_icon_resource = resource_manager_->GetResource(
ui::ANDROID_RESOURCE_TYPE_STATIC, close_icon_resource_id_);
// Positions the icon at the end of the bar.
float close_icon_left;
if (is_rtl) {
close_icon_left = bar_margin_side;
} else {
close_icon_left =
panel_width - close_icon_resource->size().width() - bar_margin_side;
}
// Centers the Close Icon vertically in the bar.
float close_icon_top =
bar_top + bar_height / 2 - close_icon_resource->size().height() / 2;
close_icon_->SetUIResourceId(close_icon_resource->ui_resource()->id());
close_icon_->SetBounds(close_icon_resource->size());
close_icon_->SetPosition(
gfx::PointF(close_icon_left, close_icon_top));
close_icon_->SetOpacity(close_icon_opacity);
// ---------------------------------------------------------------------------
// Content
// ---------------------------------------------------------------------------
content_container_->SetPosition(
gfx::PointF(0.f, content_offset_y));
content_container_->SetBounds(gfx::Size(panel_width, panel_height));
if (content_layer) {
if (content_layer->parent() != content_container_)
content_container_->AddChild(content_layer);
} else {
content_container_->RemoveAllChildren();
}
// ---------------------------------------------------------------------------
// Bar Shadow
// ---------------------------------------------------------------------------
if (bar_shadow_visible) {
ui::Resource* bar_shadow_resource = resource_manager_->GetResource(
ui::ANDROID_RESOURCE_TYPE_STATIC, bar_shadow_resource_id_);
if (bar_shadow_resource) {
if (bar_shadow_->parent() != layer_)
layer_->AddChild(bar_shadow_);
int shadow_height = bar_shadow_resource->size().height();
gfx::Size shadow_size(panel_width, shadow_height);
bar_shadow_->SetUIResourceId(bar_shadow_resource->ui_resource()->id());
bar_shadow_->SetBounds(shadow_size);
bar_shadow_->SetPosition(gfx::PointF(0.f, bar_bottom));
bar_shadow_->SetOpacity(bar_shadow_opacity);
}
} else {
if (bar_shadow_.get() && bar_shadow_->parent())
bar_shadow_->RemoveFromParent();
}
// ---------------------------------------------------------------------------
// Panel
// ---------------------------------------------------------------------------
layer_->SetPosition(gfx::PointF(panel_x, panel_y));
// ---------------------------------------------------------------------------
// Bar border
// ---------------------------------------------------------------------------
if (bar_border_visible) {
gfx::Size bar_border_size(panel_width,
bar_border_height);
float border_y = bar_bottom - bar_border_height;
bar_border_->SetBounds(bar_border_size);
bar_border_->SetPosition(
gfx::PointF(0.f, border_y));
layer_->AddChild(bar_border_);
} else if (bar_border_.get() && bar_border_->parent()) {
bar_border_->RemoveFromParent();
}
}
OverlayPanelLayer::OverlayPanelLayer(ui::ResourceManager* resource_manager)
: resource_manager_(resource_manager),
layer_(cc::Layer::Create()),
panel_shadow_(cc::NinePatchLayer::Create()),
bar_background_(cc::SolidColorLayer::Create()),
bar_text_(cc::UIResourceLayer::Create()),
bar_shadow_(cc::UIResourceLayer::Create()),
panel_icon_(cc::UIResourceLayer::Create()),
close_icon_(cc::UIResourceLayer::Create()),
content_container_(cc::SolidColorLayer::Create()),
text_container_(cc::Layer::Create()),
bar_border_(cc::SolidColorLayer::Create()) {
layer_->SetMasksToBounds(false);
layer_->SetIsDrawable(true);
// Panel Shadow
panel_shadow_->SetIsDrawable(true);
panel_shadow_->SetFillCenter(false);
layer_->AddChild(panel_shadow_);
// Bar Background
bar_background_->SetIsDrawable(true);
bar_background_->SetBackgroundColor(kBarBackgroundColor);
layer_->AddChild(bar_background_);
// Bar Text
bar_text_->SetIsDrawable(true);
AddBarTextLayer(bar_text_);
layer_->AddChild(text_container_);
// Panel Icon
panel_icon_->SetIsDrawable(true);
// The container that any text in the bar will be added to.
text_container_->SetIsDrawable(true);
// Close Icon
close_icon_->SetIsDrawable(true);
layer_->AddChild(close_icon_);
// Content Container
content_container_->SetIsDrawable(true);
content_container_->SetBackgroundColor(kBarBackgroundColor);
layer_->AddChild(content_container_);
// Bar Border
bar_border_->SetIsDrawable(true);
bar_border_->SetBackgroundColor(kBarBorderColor);
// Bar Shadow
bar_shadow_->SetIsDrawable(true);
}
OverlayPanelLayer::~OverlayPanelLayer() {
}
scoped_refptr<cc::Layer> OverlayPanelLayer::layer() {
return layer_;
}
} // namespace android