1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647
|
// 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
|