| // Copyright 2014 The Chromium Authors |
| // 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/contextual_search_layer.h" |
| |
| #include "cc/resources/scoped_ui_resource.h" |
| #include "cc/slim/layer.h" |
| #include "cc/slim/nine_patch_layer.h" |
| #include "cc/slim/solid_color_layer.h" |
| #include "cc/slim/ui_resource_layer.h" |
| #include "third_party/skia/include/core/SkColor.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 kSearchBackgroundColor = SkColorSetRGB(0xee, 0xee, 0xee); |
| const SkColor kTouchHighlightColor = SkColorSetARGB(0x33, 0x99, 0x99, 0x99); |
| |
| } // namespace |
| |
| namespace android { |
| |
| // static |
| scoped_refptr<ContextualSearchLayer> ContextualSearchLayer::Create( |
| ui::ResourceManager* resource_manager) { |
| return base::WrapRefCounted(new ContextualSearchLayer(resource_manager)); |
| } |
| |
| void ContextualSearchLayer::SetProperties( |
| int panel_shadow_resource_id, |
| int search_bar_background_color, |
| int search_context_resource_id, |
| int search_term_resource_id, |
| int search_caption_resource_id, |
| int search_bar_shadow_resource_id, |
| int search_provider_icon_resource_id, |
| int quick_action_icon_resource_id, |
| int drag_handlebar_resource_id, |
| int open_tab_icon_resource_id, |
| int close_icon_resource_id, |
| int progress_bar_background_resource_id, |
| int progress_bar_background_tint, |
| int progress_bar_resource_id, |
| int progress_bar_tint, |
| int search_promo_resource_id, |
| float dp_to_px, |
| const scoped_refptr<cc::slim::Layer>& content_layer, |
| bool search_promo_visible, |
| float search_promo_height, |
| float search_promo_opacity, |
| int search_promo_background_color, |
| // Related Searches |
| int related_searches_in_bar_resource_id, |
| bool related_searches_in_bar_visible, |
| float related_searches_in_bar_height, |
| float related_searches_in_bar_redundant_padding, |
| // Position etc |
| float search_panel_x, |
| float search_panel_y, |
| float search_panel_width, |
| float search_panel_height, |
| float search_bar_margin_side, |
| float search_bar_margin_top, |
| float search_bar_margin_bottom, |
| float search_bar_height, |
| float search_context_opacity, |
| float search_text_layer_min_height, |
| float search_term_opacity, |
| float search_term_caption_spacing, |
| float search_caption_animation_percentage, |
| bool search_caption_visible, |
| bool search_bar_border_visible, |
| float search_bar_border_height, |
| bool quick_action_icon_visible, |
| bool thumbnail_visible, |
| float custom_image_visibility_percentage, |
| int bar_image_size, |
| int icon_color, |
| int drag_handlebar_color, |
| float close_icon_opacity, |
| bool progress_bar_visible, |
| float progress_bar_height, |
| float progress_bar_opacity, |
| float progress_bar_completion, |
| bool touch_highlight_visible, |
| float touch_highlight_x_offset, |
| float touch_highlight_width, |
| int rounded_bar_top_resource_id, |
| int separator_line_color, |
| int callout_resource_id, |
| float callout_opacity) { |
| // Round values to avoid pixel gap between layers. |
| search_bar_height = floor(search_bar_height); |
| |
| float search_bar_top = 0.f; |
| float search_bar_bottom = search_bar_top + search_bar_height; |
| bool should_render_progress_bar = |
| progress_bar_visible && progress_bar_opacity > 0.f; |
| |
| OverlayPanelLayer::SetResourceIds( |
| search_term_resource_id, panel_shadow_resource_id, |
| rounded_bar_top_resource_id, search_bar_shadow_resource_id, |
| search_provider_icon_resource_id, drag_handlebar_resource_id, |
| open_tab_icon_resource_id, close_icon_resource_id); |
| |
| // TODO(donnd): Update when moving Related Searches. |
| float content_view_top = search_bar_bottom + search_promo_height; |
| float should_render_bar_border = search_bar_border_visible |
| && !should_render_progress_bar; |
| |
| // ----------------------------------------------------------------- |
| // Overlay Panel |
| // ----------------------------------------------------------------- |
| OverlayPanelLayer::SetProperties( |
| dp_to_px, content_layer, content_view_top, search_panel_x, search_panel_y, |
| search_panel_width, search_panel_height, search_bar_background_color, |
| search_bar_margin_side, search_bar_margin_top, search_bar_margin_bottom, |
| search_bar_height, search_bar_top, search_term_opacity, |
| should_render_bar_border, search_bar_border_height, icon_color, |
| drag_handlebar_color, close_icon_opacity, separator_line_color, |
| related_searches_in_bar_height); |
| |
| // ----------------------------------------------------------------- |
| // Content setup, to center in space below drag handle. |
| // ----------------------------------------------------------------- |
| int content_height = search_bar_height - search_bar_margin_top - |
| related_searches_in_bar_height - |
| search_bar_margin_bottom; |
| int content_top = search_bar_top + search_bar_margin_top; |
| |
| // --------------------------------------------------------------------------- |
| // Search Term, Context and Search Caption |
| // --------------------------------------------------------------------------- |
| int text_layer_height = |
| SetupTextLayer(content_top, content_height, search_text_layer_min_height, |
| search_caption_resource_id, search_caption_visible, |
| search_caption_animation_percentage, search_term_opacity, |
| search_context_resource_id, search_context_opacity, |
| search_term_caption_spacing); |
| |
| // Tracks the top of the next section to draw. |
| int next_section_top = search_bar_bottom; |
| |
| // --------------------------------------------------------------------------- |
| // Callout Control |
| // --------------------------------------------------------------------------- |
| if (callout_opacity > 0) { |
| ui::Resource* callout_resource = resource_manager_->GetResource( |
| ui::ANDROID_RESOURCE_TYPE_DYNAMIC, callout_resource_id); |
| if (callout_resource) { |
| if (callout_layer_->parent() != layer_) { |
| layer_->AddChild(callout_layer_); |
| } |
| |
| float callout_position_top = content_top + content_height / 2 - |
| callout_resource->size().height() / 2; |
| callout_layer_->SetUIResourceId(callout_resource->ui_resource()->id()); |
| callout_layer_->SetBounds(callout_resource->size()); |
| callout_layer_->SetPosition(gfx::PointF(0.f, callout_position_top)); |
| callout_layer_->SetOpacity(callout_opacity); |
| } |
| } else if (callout_layer_->parent()) { |
| callout_layer_->RemoveFromParent(); |
| } |
| |
| // --------------------------------------------------------------------------- |
| // Related Searches In-Bar Control |
| // --------------------------------------------------------------------------- |
| if (related_searches_in_bar_visible) { |
| // Grabs the Related Searches in-bar resource. |
| ui::Resource* related_searches_resource = resource_manager_->GetResource( |
| ui::ANDROID_RESOURCE_TYPE_DYNAMIC, related_searches_in_bar_resource_id); |
| DCHECK(related_searches_resource); |
| if (related_searches_resource) { |
| gfx::Size related_searches_size( |
| search_panel_width, related_searches_resource->size().height()); |
| if (related_searches_in_bar_->parent() != layer_) { |
| layer_->AddChild(related_searches_in_bar_); |
| } |
| related_searches_in_bar_->SetUIResourceId( |
| related_searches_resource->ui_resource()->id()); |
| related_searches_in_bar_->SetBounds(related_searches_size); |
| int related_searches_top = |
| search_bar_bottom - related_searches_in_bar_height - |
| related_searches_in_bar_redundant_padding - search_bar_margin_bottom; |
| related_searches_in_bar_->SetPosition( |
| gfx::PointF(0.f, related_searches_top)); |
| } |
| } else if (related_searches_in_bar_.get() && |
| related_searches_in_bar_->parent()) { |
| related_searches_in_bar_->RemoveFromParent(); |
| } |
| |
| // --------------------------------------------------------------------------- |
| // Search Promo |
| // --------------------------------------------------------------------------- |
| if (search_promo_visible) { |
| // Grabs the Search Opt Out Promo resource. |
| ui::Resource* search_promo_resource = resource_manager_->GetResource( |
| ui::ANDROID_RESOURCE_TYPE_DYNAMIC, search_promo_resource_id); |
| // Search Promo Container |
| if (search_promo_container_->parent() != layer_) { |
| // NOTE(donnd): This layer can appear just below the Bar so it should be |
| // always placed before the Search Bar Shadow to make sure it won't |
| // occlude the shadow. Since layer 0 is the shadow for the sheet itself, |
| // this needs to be layer 1. |
| layer_->InsertChild(search_promo_container_, 1); |
| } |
| |
| if (search_promo_resource) { |
| int search_promo_content_height = search_promo_resource->size().height(); |
| gfx::Size search_promo_size(search_panel_width, search_promo_height); |
| search_promo_container_->SetBounds(search_promo_size); |
| search_promo_container_->SetPosition(gfx::PointF(0.f, next_section_top)); |
| search_promo_container_->SetMasksToBounds(true); |
| // TODO(crbug.com/40219248): Remove FromColor and make all SkColor4f. |
| search_promo_container_->SetBackgroundColor( |
| SkColor4f::FromColor(search_promo_background_color)); |
| |
| // Search Promo |
| if (search_promo_->parent() != search_promo_container_) |
| search_promo_container_->AddChild(search_promo_); |
| |
| search_promo_->SetUIResourceId( |
| search_promo_resource->ui_resource()->id()); |
| search_promo_->SetBounds(search_promo_resource->size()); |
| // Align promo at the bottom of the container so the confirmation button |
| // is not clipped when resizing the promo. |
| search_promo_->SetPosition( |
| gfx::PointF(0.f, search_promo_height - search_promo_content_height)); |
| search_promo_->SetOpacity(search_promo_opacity); |
| // Next section goes beyond this section. |
| next_section_top += search_promo_content_height; |
| } |
| } else { |
| // Search Promo Container |
| if (search_promo_container_.get() && search_promo_container_->parent()) |
| search_promo_container_->RemoveFromParent(); |
| } |
| |
| // --------------------------------------------------------------------------- |
| // Progress Bar |
| // --------------------------------------------------------------------------- |
| OverlayPanelLayer::SetProgressBar( |
| progress_bar_background_resource_id, progress_bar_background_tint, |
| progress_bar_resource_id, progress_bar_tint, progress_bar_visible, |
| search_bar_bottom, progress_bar_height, progress_bar_opacity, |
| progress_bar_completion, search_panel_width); |
| |
| // --------------------------------------------------------------------------- |
| // Touch Highlight Layer |
| // --------------------------------------------------------------------------- |
| if (touch_highlight_visible) { |
| if (touch_highlight_layer_->parent() != layer_) |
| layer_->AddChild(touch_highlight_layer_); |
| // In the new layout don't highlight the whole bar due to rounded corners. |
| int highlight_height = text_layer_height; |
| int highlight_top = content_top; |
| highlight_top += (content_height - text_layer_height) / 2; |
| gfx::Size background_size(touch_highlight_width, highlight_height); |
| touch_highlight_layer_->SetBounds(background_size); |
| touch_highlight_layer_->SetPosition( |
| gfx::PointF(touch_highlight_x_offset, highlight_top)); |
| } else { |
| touch_highlight_layer_->RemoveFromParent(); |
| } |
| |
| // --------------------------------------------------------------------------- |
| // Icon Layer |
| // --------------------------------------------------------------------------- |
| bar_image_size_ = bar_image_size; |
| SetupIconLayer(search_provider_icon_resource_id, quick_action_icon_visible, |
| quick_action_icon_resource_id, thumbnail_visible, |
| custom_image_visibility_percentage); |
| } |
| |
| scoped_refptr<cc::slim::Layer> ContextualSearchLayer::GetIconLayer() { |
| return icon_layer_; |
| } |
| |
| void ContextualSearchLayer::SetupIconLayer( |
| int search_provider_icon_resource_id, |
| bool quick_action_icon_visible, |
| int quick_action_icon_resource_id, |
| bool thumbnail_visible, |
| float custom_image_visibility_percentage) { |
| icon_layer_->SetBounds(gfx::Size(bar_image_size_, bar_image_size_)); |
| icon_layer_->SetMasksToBounds(true); |
| |
| if (quick_action_icon_visible) { |
| if (quick_action_icon_layer_->parent() != icon_layer_) |
| icon_layer_->AddChild(quick_action_icon_layer_); |
| |
| ui::Resource* quick_action_icon_resource = resource_manager_->GetResource( |
| ui::ANDROID_RESOURCE_TYPE_DYNAMIC, quick_action_icon_resource_id); |
| if (quick_action_icon_resource) { |
| quick_action_icon_layer_->SetUIResourceId( |
| quick_action_icon_resource->ui_resource()->id()); |
| quick_action_icon_layer_->SetBounds( |
| gfx::Size(bar_image_size_, bar_image_size_)); |
| |
| SetCustomImageProperties(quick_action_icon_layer_, 0, 0, |
| custom_image_visibility_percentage); |
| } |
| } else if (quick_action_icon_layer_->parent()) { |
| quick_action_icon_layer_->RemoveFromParent(); |
| } |
| |
| // Thumbnail |
| if (!quick_action_icon_visible && thumbnail_visible) { |
| if (thumbnail_layer_->parent() != icon_layer_) |
| icon_layer_->AddChild(thumbnail_layer_); |
| |
| SetCustomImageProperties(thumbnail_layer_, thumbnail_top_margin_, |
| thumbnail_side_margin_, |
| custom_image_visibility_percentage); |
| } else if (thumbnail_layer_->parent()) { |
| thumbnail_layer_->RemoveFromParent(); |
| } |
| |
| // Search Provider Icon |
| if (search_provider_icon_layer_->parent() != icon_layer_) |
| icon_layer_->AddChild(search_provider_icon_layer_); |
| |
| ui::Resource* search_provider_icon_resource = resource_manager_->GetResource( |
| ui::ANDROID_RESOURCE_TYPE_STATIC, search_provider_icon_resource_id); |
| if (search_provider_icon_resource) { |
| gfx::Size icon_size = search_provider_icon_resource->size(); |
| search_provider_icon_layer_->SetUIResourceId( |
| search_provider_icon_resource->ui_resource()->id()); |
| search_provider_icon_layer_->SetBounds(icon_size); |
| |
| search_provider_icon_layer_->SetOpacity(1.f - |
| custom_image_visibility_percentage); |
| |
| // Determine x and y offsets to center the icon in its parent layer |
| float icon_x_offset = (bar_image_size_ - icon_size.width()) / 2; |
| float icon_y_offset = (bar_image_size_ - icon_size.height()) / 2; |
| |
| // Determine extra y-offset if thumbnail or quick action are visible. |
| icon_y_offset -= (bar_image_size_ * custom_image_visibility_percentage); |
| |
| search_provider_icon_layer_->SetPosition( |
| gfx::PointF(icon_x_offset, icon_y_offset)); |
| } |
| } |
| |
| void ContextualSearchLayer::SetCustomImageProperties( |
| scoped_refptr<cc::slim::UIResourceLayer> custom_image_layer, |
| float top_margin, |
| float side_margin, |
| float visibility_percentage) { |
| custom_image_layer->SetOpacity(visibility_percentage); |
| |
| // When animating, the custom image and search provider icon slide through |
| // |icon_layer_|. This effect is achieved by changing the y-offset |
| // for each child layer. |
| // If the custom image has a height less than |bar_image_size_|, it will |
| // have a top margin that needs to be accounted for while running the |
| // animation. The final |custom_image_y_offset| should be equal to |
| // |tpp_margin|. |
| float custom_image_y_offset = |
| (bar_image_size_ * (1.f - visibility_percentage)) + top_margin; |
| custom_image_layer->SetPosition( |
| gfx::PointF(side_margin, custom_image_y_offset)); |
| } |
| |
| int ContextualSearchLayer::SetupTextLayer(float content_top, |
| float content_height, |
| float search_text_layer_min_height, |
| int caption_resource_id, |
| bool caption_visible, |
| float animation_percentage, |
| float search_term_opacity, |
| int context_resource_id, |
| float context_opacity, |
| float term_caption_spacing) { |
| // --------------------------------------------------------------------------- |
| // Setup the Drawing Hierarchy |
| // --------------------------------------------------------------------------- |
| // Search Term |
| DCHECK(text_layer_.get()); |
| DCHECK(bar_text_.get()); |
| DCHECK(search_caption_.get()); |
| bool bar_text_visible = search_term_opacity > 0.0f; |
| if (bar_text_visible && bar_text_->parent() != text_layer_) |
| text_layer_->AddChild(bar_text_); |
| |
| // Search Context |
| ui::Resource* context_resource = resource_manager_->GetResource( |
| ui::ANDROID_RESOURCE_TYPE_DYNAMIC, context_resource_id); |
| if (context_resource) { |
| search_context_->SetUIResourceId(context_resource->ui_resource()->id()); |
| search_context_->SetBounds(context_resource->size()); |
| } |
| |
| // Search Caption |
| ui::Resource* caption_resource = nullptr; |
| if (caption_visible) { |
| // Grabs the dynamic Search Caption resource so we can get a snapshot. |
| caption_resource = resource_manager_->GetResource( |
| ui::ANDROID_RESOURCE_TYPE_DYNAMIC, caption_resource_id); |
| } |
| |
| if (caption_visible && animation_percentage != 0.f) { |
| if (search_caption_->parent() != text_layer_) { |
| text_layer_->AddChild(search_caption_); |
| } |
| if (caption_resource) { |
| search_caption_->SetUIResourceId(caption_resource->ui_resource()->id()); |
| search_caption_->SetBounds(caption_resource->size()); |
| } |
| } else if (search_caption_->parent()) { |
| search_caption_->RemoveFromParent(); |
| } |
| |
| // --------------------------------------------------------------------------- |
| // Calculate Text Layer Size |
| // --------------------------------------------------------------------------- |
| // If space allows, the Term, Context and Caption should occupy a Text |
| // section of fixed size. |
| // We may not be able to fit these inside the ideal size as the user may have |
| // their Font Size set to large. |
| |
| // The Term might not be visible or initialized yet, so set up main_text with |
| // whichever main bar text seems appropriate. |
| scoped_refptr<cc::slim::UIResourceLayer> main_text = |
| (bar_text_visible ? bar_text_ : search_context_); |
| |
| // The search_caption_ may not have had it's resource set by this point, if so |
| // the bounds will be zero and everything will still work. |
| float term_height = main_text->bounds().height(); |
| float caption_height = search_caption_->bounds().height(); |
| |
| float layer_height = std::max(search_text_layer_min_height, |
| term_height + caption_height + term_caption_spacing); |
| float layer_width = |
| std::max(main_text->bounds().width(), search_caption_->bounds().width()); |
| |
| float layer_top = content_top + (content_height - layer_height) / 2; |
| text_layer_->SetBounds(gfx::Size(layer_width, layer_height)); |
| text_layer_->SetPosition(gfx::PointF(0.f, layer_top)); |
| text_layer_->SetMasksToBounds(true); |
| |
| // --------------------------------------------------------------------------- |
| // Layout Text Layer |
| // --------------------------------------------------------------------------- |
| // ---Top of Search Bar--- <- bar_top |
| // |
| // ---Top of Text Layer--- <- layer_top |
| // } remaining_height / 2 |
| // Term & Context } term_height |
| // } term_caption_spacing |
| // Caption } caption_height |
| // } remaining_height / 2 |
| // --Bottom of Text Layer- |
| // |
| // --Bottom of Search Bar- |
| // If the Caption is not visible the Term is centered in this space, when |
| // the Caption becomes visible it is animated sliding up into it's position |
| // with the spacings determined by UI. |
| // The Term and the Context are assumed to be the same height and will be |
| // positioned one on top of the other. When the Context is resolved it will |
| // fade out and the Term will fade in. |
| |
| search_context_->SetOpacity(context_opacity); |
| bar_text_->SetOpacity(search_term_opacity); |
| |
| // If there is no caption, just vertically center the Search Term. |
| float term_top = (layer_height - term_height) / 2; |
| |
| // If we aren't displaying the caption we're done. |
| if (!caption_visible || animation_percentage == 0.f || !caption_resource) { |
| bar_text_->SetPosition(gfx::PointF(0.f, term_top)); |
| search_context_->SetPosition(gfx::PointF(0.f, term_top)); |
| return layer_height; |
| } |
| |
| // Calculate the positions for the Term and Caption when the Caption |
| // animation is complete. |
| float remaining_height = layer_height |
| - term_height |
| - term_caption_spacing |
| - caption_height; |
| |
| float term_top_end = remaining_height / 2; |
| float caption_top_end = term_top_end + term_height + term_caption_spacing; |
| |
| // Interpolate between the animation start and end positions (short cut |
| // if the animation is at the end or start). |
| term_top = term_top * (1.f - animation_percentage) |
| + term_top_end * animation_percentage; |
| |
| // The Caption starts off the bottom of the Text Layer. |
| float caption_top = layer_height * (1.f - animation_percentage) |
| + caption_top_end * animation_percentage; |
| |
| bar_text_->SetPosition(gfx::PointF(0.f, term_top)); |
| search_context_->SetPosition(gfx::PointF(0.f, term_top)); |
| search_caption_->SetPosition(gfx::PointF(0.f, caption_top)); |
| return layer_height; |
| } |
| |
| void ContextualSearchLayer::SetThumbnail(const SkBitmap* thumbnail) { |
| // Determine the scaled thumbnail width and height. If both the height and |
| // width of |thumbnail| are larger than |bar_image_size_|, the thumbnail |
| // will be scaled down by a call to Layer::SetBounds() below. |
| int min_dimension = std::min(thumbnail->width(), thumbnail->height()); |
| int scaled_thumbnail_width = thumbnail->width(); |
| int scaled_thumbnail_height = thumbnail->height(); |
| if (min_dimension > bar_image_size_) { |
| scaled_thumbnail_width = |
| scaled_thumbnail_width * bar_image_size_ / min_dimension; |
| scaled_thumbnail_height = |
| scaled_thumbnail_height * bar_image_size_ / min_dimension; |
| } |
| |
| // Determine the UV transform coordinates. This will crop the thumbnail. |
| // (0, 0) is the default top left corner. (1, 1) is the default bottom |
| // right corner. |
| float top_left_x = 0; |
| float top_left_y = 0; |
| float bottom_right_x = 1; |
| float bottom_right_y = 1; |
| |
| if (scaled_thumbnail_width > bar_image_size_) { |
| // Crop an even amount on the left and right sides of the thumbnail. |
| float top_left_x_px = (scaled_thumbnail_width - bar_image_size_) / 2.f; |
| float bottom_right_x_px = top_left_x_px + bar_image_size_; |
| |
| top_left_x = top_left_x_px / scaled_thumbnail_width; |
| bottom_right_x = bottom_right_x_px / scaled_thumbnail_width; |
| } else if (scaled_thumbnail_height > bar_image_size_) { |
| // Crop an even amount on the top and bottom of the thumbnail. |
| float top_left_y_px = (scaled_thumbnail_height - bar_image_size_) / 2.f; |
| float bottom_right_y_px = top_left_y_px + bar_image_size_; |
| |
| top_left_y = top_left_y_px / scaled_thumbnail_height; |
| bottom_right_y = bottom_right_y_px / scaled_thumbnail_height; |
| } |
| |
| // If the original |thumbnail| height or width is smaller than |
| // |bar_image_size_| determine the side and top margins needed to center |
| // the thumbnail. |
| thumbnail_side_margin_ = 0; |
| thumbnail_top_margin_ = 0; |
| |
| if (scaled_thumbnail_width < bar_image_size_) { |
| thumbnail_side_margin_ = (bar_image_size_ - scaled_thumbnail_width) / 2.f; |
| } |
| |
| if (scaled_thumbnail_height < bar_image_size_) { |
| thumbnail_top_margin_ = (bar_image_size_ - scaled_thumbnail_height) / 2.f; |
| } |
| |
| // Determine the layer bounds. This will down scale the thumbnail if |
| // necessary and ensure it is displayed at |bar_image_size_|. If |
| // either the original |thumbnail| height or width is smaller than |
| // |bar_image_size_|, the thumbnail will not be scaled. |
| int layer_width = std::min(bar_image_size_, scaled_thumbnail_width); |
| int layer_height = std::min(bar_image_size_, scaled_thumbnail_height); |
| |
| // UIResourceLayer requires an immutable copy of the input |thumbnail|. |
| SkBitmap thumbnail_copy; |
| if (thumbnail->isImmutable()) { |
| thumbnail_copy = *thumbnail; |
| } else { |
| if (thumbnail_copy.tryAllocPixels(thumbnail->info())) { |
| thumbnail->readPixels(thumbnail_copy.info(), thumbnail_copy.getPixels(), |
| thumbnail_copy.rowBytes(), 0, 0); |
| } |
| thumbnail_copy.setImmutable(); |
| } |
| |
| thumbnail_layer_->SetBitmap(thumbnail_copy); |
| thumbnail_layer_->SetBounds(gfx::Size(layer_width, layer_height)); |
| thumbnail_layer_->SetPosition( |
| gfx::PointF(thumbnail_side_margin_, thumbnail_top_margin_)); |
| thumbnail_layer_->SetUV(gfx::PointF(top_left_x, top_left_y), |
| gfx::PointF(bottom_right_x, bottom_right_y)); |
| } |
| |
| ContextualSearchLayer::ContextualSearchLayer( |
| ui::ResourceManager* resource_manager) |
| : OverlayPanelLayer(resource_manager), |
| search_context_(cc::slim::UIResourceLayer::Create()), |
| icon_layer_(cc::slim::Layer::Create()), |
| search_provider_icon_layer_(cc::slim::UIResourceLayer::Create()), |
| thumbnail_layer_(cc::slim::UIResourceLayer::Create()), |
| quick_action_icon_layer_(cc::slim::UIResourceLayer::Create()), |
| search_promo_(cc::slim::UIResourceLayer::Create()), |
| search_promo_container_(cc::slim::SolidColorLayer::Create()), |
| related_searches_in_bar_(cc::slim::UIResourceLayer::Create()), |
| search_caption_(cc::slim::UIResourceLayer::Create()), |
| text_layer_(cc::slim::UIResourceLayer::Create()), |
| touch_highlight_layer_(cc::slim::SolidColorLayer::Create()), |
| callout_layer_(cc::slim::UIResourceLayer::Create()) { |
| // Search Bar Text |
| search_context_->SetIsDrawable(true); |
| |
| // Search Bar Caption |
| search_caption_->SetIsDrawable(true); |
| |
| // Search Opt Out Promo |
| search_promo_container_->SetIsDrawable(true); |
| search_promo_container_->SetBackgroundColor( |
| SkColor4f::FromColor(kSearchBackgroundColor)); |
| search_promo_->SetIsDrawable(true); |
| |
| // Related Searches sections |
| related_searches_in_bar_->SetIsDrawable(true); |
| |
| // Icon - holds thumbnail, search provider icon and/or quick action icon |
| icon_layer_->SetIsDrawable(true); |
| layer_->AddChild(icon_layer_); |
| |
| // Search provider icon |
| search_provider_icon_layer_->SetIsDrawable(true); |
| |
| // Thumbnail |
| thumbnail_layer_->SetIsDrawable(true); |
| |
| // Quick action icon |
| quick_action_icon_layer_->SetIsDrawable(true); |
| |
| // Content layer |
| text_layer_->SetIsDrawable(true); |
| // NOTE(mdjones): This can be called multiple times to add other text layers. |
| AddBarTextLayer(text_layer_); |
| text_layer_->AddChild(search_context_); |
| |
| // Touch Highlight Layer |
| touch_highlight_layer_->SetIsDrawable(true); |
| touch_highlight_layer_->SetBackgroundColor( |
| SkColor4f::FromColor(kTouchHighlightColor)); |
| |
| // Callout Layer |
| callout_layer_->SetIsDrawable(true); |
| } |
| |
| ContextualSearchLayer::~ContextualSearchLayer() = default; |
| |
| } // namespace android |