Commit 1f7bb9fa authored by Ahmed Fakhry's avatar Ahmed Fakhry Committed by Commit Bot

[GM2 Top bars]: Caption Buttons

This CL implements the new GM2 styles for the non-
client frames caption buttons:
- Use circular inkdrop flood fill and highlight.
- Use the new colors and opacities for the caption icons.
- Use a height of 32dp for the non-browser frames.

TODO: Implement the same styles for PWAs' frame buttons

BUG=831872
TEST=manual

Cq-Include-Trybots: master.tryserver.chromium.linux:closure_compilation
Change-Id: Id2c2603b67b290b5eba1970d78d5d0c395df7fe4
Reviewed-on: https://chromium-review.googlesource.com/1041144
Commit-Queue: Ahmed Fakhry <afakhry@chromium.org>
Reviewed-by: default avatarScott Violet <sky@chromium.org>
Cr-Commit-Position: refs/heads/master@{#555864}
parent 31474e8b
......@@ -16,10 +16,6 @@ const int kResizeInsideBoundsSize = 1;
const SkColor kChromeOsBootColor = SkColorSetRGB(0xfe, 0xfe, 0xfe);
const float kInactiveFrameButtonIconAlphaRatio = 0.2f;
const float kInactiveFrameButtonIconAlphaRatioTouch = 0.43f;
const int kDefaultLargeCursorSize = 64;
} // namespace ash
......@@ -28,12 +28,6 @@ ASH_EXPORT extern const int kResizeInsideBoundsSize;
// Background color used for the Chrome OS boot splash screen.
extern const SkColor kChromeOsBootColor;
// The alpha to draw inactive browser frame icons with.
ASH_EXPORT extern const float kInactiveFrameButtonIconAlphaRatio;
// Similar to the above but for touch-optimized UI.
ASH_EXPORT extern const float kInactiveFrameButtonIconAlphaRatioTouch;
// The border color of keyboard focus for launcher items and system tray.
constexpr SkColor kFocusBorderColor = SK_ColorTRANSPARENT;
constexpr int kFocusBorderThickness = 0;
......
......@@ -21,7 +21,7 @@ gfx::Size GetAshLayoutSize(AshLayoutSize size) {
return gfx::Size(kButtonWidth, kBrowserRestoredCaptionButtonHeight[mode]);
}
case AshLayoutSize::kNonBrowserCaption:
return gfx::Size(kButtonWidth, 33);
return gfx::Size(kButtonWidth, 32);
}
NOTREACHED();
......
......@@ -5,18 +5,29 @@
#include "ash/frame/caption_buttons/frame_caption_button.h"
#include "ash/ash_constants.h"
#include "ui/base/material_design/material_design_controller.h"
#include "ui/gfx/animation/slide_animation.h"
#include "ui/gfx/animation/throb_animation.h"
#include "ui/gfx/canvas.h"
#include "ui/gfx/color_palette.h"
#include "ui/gfx/color_utils.h"
#include "ui/gfx/paint_vector_icon.h"
#include "ui/views/animation/flood_fill_ink_drop_ripple.h"
#include "ui/views/animation/ink_drop_highlight.h"
#include "ui/views/animation/ink_drop_impl.h"
#include "ui/views/animation/ink_drop_mask.h"
#include "ui/views/animation/ink_drop_ripple.h"
namespace ash {
namespace {
// Ink drop parameters.
constexpr float kInkDropVisibleOpacity = 0.06f;
constexpr float kHighlightVisibleOpacity = 0.08f;
constexpr int kInkDropCornerRadius = 14;
constexpr gfx::Size kInkDropHighlightSize{2 * kInkDropCornerRadius,
2 * kInkDropCornerRadius};
// The duration of the crossfade animation when swapping the button's images.
const int kSwapImagesAnimationDurationMs = 200;
......@@ -27,12 +38,6 @@ const float kFadeOutRatio = 0.5f;
// The ratio applied to the button's alpha when the button is disabled.
const float kDisabledButtonAlphaRatio = 0.5f;
// The colors and alpha values used for the button background hovered and
// pressed states.
// TODO(tdanderson|estade): Request these colors from ThemeProvider.
const int kHoveredAlpha = 0x14;
const int kPressedAlpha = 0x24;
// Minimum theme light color contrast.
const float kContrastLightItemThreshold = 3;
// The amount to darken a light theme color by for use as foreground color.
......@@ -49,6 +54,15 @@ bool UseLightColor(FrameCaptionButton::ColorMode color_mode,
return color_utils::IsDark(background_color);
}
// Returns the amount by which the inkdrop ripple and mask should be insetted
// from the button size in order to achieve a circular inkdrop with a size
// equals to kInkDropHighlightSize.
gfx::Insets GetInkdropInsets(const gfx::Size& button_size) {
return gfx::Insets(
(button_size.height() - kInkDropHighlightSize.height()) / 2,
(button_size.width() - kInkDropHighlightSize.width()) / 2);
}
} // namespace
// static
......@@ -66,6 +80,11 @@ FrameCaptionButton::FrameCaptionButton(views::ButtonListener* listener,
set_animate_on_state_change(true);
swap_images_animation_->Reset(1);
set_has_ink_drop_action_on_click(true);
SetInkDropMode(InkDropMode::ON);
set_ink_drop_visible_opacity(kInkDropVisibleOpacity);
UpdateInkDropBaseColor();
// Do not flip the gfx::Canvas passed to the OnPaint() method. The snap left
// and snap right button icons should not be flipped. The other icons are
// horizontally symmetrical.
......@@ -87,17 +106,12 @@ SkColor FrameCaptionButton::GetButtonColor(ColorMode color_mode,
}
DCHECK_EQ(color_mode, ColorMode::kDefault);
if (ui::MaterialDesignController::IsTouchOptimizedUiEnabled())
return use_light_color ? gfx::kGoogleGrey100 : gfx::kGoogleGrey800;
return use_light_color ? SK_ColorWHITE : gfx::kChromeIconGrey;
return use_light_color ? gfx::kGoogleGrey200 : gfx::kGoogleGrey700;
}
// static
float FrameCaptionButton::GetInactiveButtonColorAlphaRatio() {
return ui::MaterialDesignController::IsTouchOptimizedUiEnabled()
? kInactiveFrameButtonIconAlphaRatioTouch
: kInactiveFrameButtonIconAlphaRatio;
return 0.38f;
}
void FrameCaptionButton::SetImage(CaptionButtonIcon icon,
......@@ -174,22 +188,48 @@ views::PaintInfo::ScaleType FrameCaptionButton::GetPaintScaleType() const {
return views::PaintInfo::ScaleType::kUniformScaling;
}
void FrameCaptionButton::PaintButtonContents(gfx::Canvas* canvas) {
SkAlpha bg_alpha = SK_AlphaTRANSPARENT;
if (hover_animation().is_animating())
bg_alpha = hover_animation().CurrentValueBetween(0, kHoveredAlpha);
else if (state() == STATE_HOVERED)
bg_alpha = kHoveredAlpha;
else if (state() == STATE_PRESSED)
bg_alpha = kPressedAlpha;
if (bg_alpha != SK_AlphaTRANSPARENT) {
canvas->DrawColor(SkColorSetA(UseLightColor(color_mode_, background_color_)
? SK_ColorWHITE
: SK_ColorBLACK,
bg_alpha));
}
std::unique_ptr<views::InkDrop> FrameCaptionButton::CreateInkDrop() {
auto ink_drop = std::make_unique<views::InkDropImpl>(this, size());
ink_drop->SetAutoHighlightMode(
views::InkDropImpl::AutoHighlightMode::SHOW_ON_RIPPLE);
ink_drop->SetShowHighlightOnHover(true);
return ink_drop;
}
std::unique_ptr<views::InkDropRipple> FrameCaptionButton::CreateInkDropRipple()
const {
return std::make_unique<views::FloodFillInkDropRipple>(
size(), GetInkdropInsets(size()), GetInkDropCenterBasedOnLastEvent(),
GetInkDropBaseColor(), ink_drop_visible_opacity());
}
std::unique_ptr<views::InkDropHighlight>
FrameCaptionButton::CreateInkDropHighlight() const {
auto highlight = std::make_unique<views::InkDropHighlight>(
kInkDropHighlightSize, kInkDropCornerRadius,
gfx::PointF(GetMirroredRect(GetContentsBounds()).CenterPoint()),
GetInkDropBaseColor());
highlight->set_visible_opacity(kHighlightVisibleOpacity);
return highlight;
}
std::unique_ptr<views::InkDropMask> FrameCaptionButton::CreateInkDropMask()
const {
return std::make_unique<views::RoundRectInkDropMask>(
size(), GetInkdropInsets(size()), kInkDropCornerRadius);
}
void FrameCaptionButton::SetBackgroundColor(SkColor background_color) {
background_color_ = background_color;
UpdateInkDropBaseColor();
}
void FrameCaptionButton::SetColorMode(ColorMode color_mode) {
color_mode_ = color_mode;
UpdateInkDropBaseColor();
}
void FrameCaptionButton::PaintButtonContents(gfx::Canvas* canvas) {
int icon_alpha = swap_images_animation_->CurrentValueBetween(0, 255);
int crossfade_icon_alpha = 0;
if (icon_alpha < static_cast<int>(kFadeOutRatio * 255))
......@@ -239,4 +279,10 @@ int FrameCaptionButton::GetAlphaForIcon(int base_alpha) const {
return base_alpha * inactive_alpha;
}
void FrameCaptionButton::UpdateInkDropBaseColor() {
set_ink_drop_base_color(UseLightColor(color_mode_, background_color_)
? SK_ColorWHITE
: SK_ColorBLACK);
}
} // namespace ash
......@@ -59,11 +59,15 @@ class ASH_EXPORT FrameCaptionButton : public views::Button {
void OnGestureEvent(ui::GestureEvent* event) override;
views::PaintInfo::ScaleType GetPaintScaleType() const override;
void set_background_color(SkColor background_color) {
background_color_ = background_color;
}
// views::InkDropHostView:
std::unique_ptr<views::InkDrop> CreateInkDrop() override;
std::unique_ptr<views::InkDropRipple> CreateInkDropRipple() const override;
std::unique_ptr<views::InkDropHighlight> CreateInkDropHighlight()
const override;
std::unique_ptr<views::InkDropMask> CreateInkDropMask() const override;
void set_color_mode(ColorMode color_mode) { color_mode_ = color_mode; }
void SetBackgroundColor(SkColor background_color);
void SetColorMode(ColorMode color_mode);
void set_paint_as_active(bool paint_as_active) {
paint_as_active_ = paint_as_active;
......@@ -84,6 +88,8 @@ class ASH_EXPORT FrameCaptionButton : public views::Button {
// active state.
int GetAlphaForIcon(int base_alpha) const;
void UpdateInkDropBaseColor();
// The button's current icon.
CaptionButtonIcon icon_;
......
......@@ -241,18 +241,18 @@ void FrameCaptionButtonContainerView::SetPaintAsActive(bool paint_as_active) {
void FrameCaptionButtonContainerView::SetColorMode(
FrameCaptionButton::ColorMode color_mode) {
menu_button_->set_color_mode(color_mode);
minimize_button_->set_color_mode(color_mode);
size_button_->set_color_mode(color_mode);
close_button_->set_color_mode(color_mode);
menu_button_->SetColorMode(color_mode);
minimize_button_->SetColorMode(color_mode);
size_button_->SetColorMode(color_mode);
close_button_->SetColorMode(color_mode);
}
void FrameCaptionButtonContainerView::SetBackgroundColor(
SkColor background_color) {
menu_button_->set_background_color(background_color);
minimize_button_->set_background_color(background_color);
size_button_->set_background_color(background_color);
close_button_->set_background_color(background_color);
menu_button_->SetBackgroundColor(background_color);
minimize_button_->SetBackgroundColor(background_color);
size_button_->SetBackgroundColor(background_color);
close_button_->SetBackgroundColor(background_color);
}
void FrameCaptionButtonContainerView::ResetWindowControls() {
......
......@@ -523,7 +523,7 @@ TEST_F(CustomFrameViewAshTest, FrameVisibility) {
delegate, kShellWindowId_DefaultContainer, window_bounds);
// The height is smaller by the top border height.
gfx::Size client_bounds(200, 67);
gfx::Size client_bounds(200, 68);
CustomFrameViewAsh* custom_frame_view = delegate->custom_frame_view();
EXPECT_EQ(client_bounds, widget->client_view()->GetLocalBounds().size());
......@@ -539,8 +539,8 @@ TEST_F(CustomFrameViewAshTest, FrameVisibility) {
widget->GetRootView()->Layout();
EXPECT_EQ(client_bounds, widget->client_view()->GetLocalBounds().size());
EXPECT_TRUE(widget->non_client_view()->frame_view()->visible());
EXPECT_EQ(33, delegate->GetCustomFrameViewTopBorderHeight());
EXPECT_EQ(gfx::Rect(gfx::Point(10, 43), client_bounds),
EXPECT_EQ(32, delegate->GetCustomFrameViewTopBorderHeight());
EXPECT_EQ(gfx::Rect(gfx::Point(10, 42), client_bounds),
custom_frame_view->GetClientBoundsForWindowBounds(window_bounds));
}
......@@ -668,7 +668,7 @@ TEST_F(CustomFrameViewAshTest, WideFrame) {
EXPECT_FALSE(wide_header_view->in_immersive_mode());
// visible fraction should be ignored in non immersive.
wide_header_view->SetVisibleFraction(0.5);
EXPECT_EQ(33, wide_header_view->GetPreferredOnScreenHeight());
EXPECT_EQ(32, wide_header_view->GetPreferredOnScreenHeight());
UpdateDisplay("1234x800");
EXPECT_EQ(1234,
......
......@@ -39,7 +39,7 @@ namespace {
const SkColor kTitleTextColor = SkColorSetRGB(40, 40, 40);
const SkColor kLightTitleTextColor = SK_ColorWHITE;
// The default color of the frame.
const SkColor kDefaultFrameColor = SkColorSetRGB(242, 242, 242);
const SkColor kDefaultFrameColor = SkColorSetRGB(0xFD, 0xFE, 0xFF);
// Duration of crossfade animation for activating and deactivating frame.
const int kActivationCrossfadeDurationMs = 200;
......@@ -171,8 +171,8 @@ void DefaultFrameHeader::LayoutHeader() {
int origin = 0;
if (back_button_) {
back_button_->set_background_color(GetCurrentFrameColor());
back_button_->set_color_mode(button_color_mode_);
back_button_->SetBackgroundColor(GetCurrentFrameColor());
back_button_->SetColorMode(button_color_mode_);
gfx::Size size = back_button_->GetPreferredSize();
back_button_->SetBounds(0, 0, size.width(),
caption_button_container_size.height());
......@@ -319,8 +319,8 @@ void DefaultFrameHeader::UpdateAllButtonImages() {
caption_button_container_->SetBackgroundColor(GetCurrentFrameColor());
caption_button_container_->SetColorMode(button_color_mode_);
if (back_button_) {
back_button_->set_background_color(GetCurrentFrameColor());
back_button_->set_color_mode(button_color_mode_);
back_button_->SetBackgroundColor(GetCurrentFrameColor());
back_button_->SetColorMode(button_color_mode_);
back_button_->SetImage(CAPTION_BUTTON_ICON_BACK,
FrameCaptionButton::ANIMATE_NO,
kWindowControlBackIcon);
......
......@@ -67,10 +67,15 @@ gfx::Rect FrameHeaderUtil::GetAvailableTitleBounds(
const int x = left_view ? left_view->bounds().right() + kTitleIconOffsetX
: kTitleNoIconOffsetX;
const int title_height = title_font_list.GetHeight();
// Floor when computing the center of |caption_button_container| and when
// computing the center of the text.
DCHECK_LE(right_view->height(), header_height);
const int y = std::max(0, (header_height - title_height) / 2);
// We want to align the center points of the header and title vertically.
// Note that we can't just do (header_height - title_height) / 2, since this
// won't make the center points align perfectly vertically due to rounding.
// Floor when computing the center of |header_height| and when computing the
// center of the text.
const int header_center_y = header_height / 2;
const int title_center_y = title_height / 2;
const int y = std::max(0, header_center_y - title_center_y);
const int width =
std::max(0, right_view->x() - kTitleCaptionButtonSpacing - x);
return gfx::Rect(x, y, width, title_height);
......
......@@ -148,7 +148,7 @@ void BrowserFrameHeaderAsh::Init(
back_button_ = back_button;
if (back_button_)
back_button_->set_background_color(frame_color);
back_button_->SetBackgroundColor(frame_color);
}
int BrowserFrameHeaderAsh::GetMinimumHeaderWidth() const {
......@@ -217,7 +217,7 @@ void BrowserFrameHeaderAsh::SetPaintAsActive(bool paint_as_active) {
caption_button_container_->SetBackgroundColor(frame_color);
if (back_button_) {
back_button_->set_paint_as_active(paint_as_active);
back_button_->set_background_color(frame_color);
back_button_->SetBackgroundColor(frame_color);
}
}
......
......@@ -457,7 +457,7 @@ TEST_F(ClientControlledShellSurfaceTest, Frame) {
gfx::Rect client_bounds(20, 50, 300, 200);
gfx::Rect fullscreen_bounds(0, 0, 800, 500);
// The window bounds is the client bounds + frame size.
gfx::Rect normal_window_bounds(20, 17, 300, 233);
gfx::Rect normal_window_bounds(20, 18, 300, 232);
auto shell_surface =
exo_test_helper()->CreateClientControlledShellSurface(surface.get());
......@@ -484,7 +484,7 @@ TEST_F(ClientControlledShellSurfaceTest, Frame) {
EXPECT_TRUE(frame_view->visible());
EXPECT_EQ(fullscreen_bounds, widget->GetWindowBoundsInScreen());
EXPECT_EQ(
gfx::Size(800, 467),
gfx::Size(800, 468),
frame_view->GetClientBoundsForWindowBounds(fullscreen_bounds).size());
// AutoHide
......
......@@ -364,7 +364,7 @@ TEST_F(ShellSurfaceTest, SetMinimumSize) {
->delegate()
->GetMinimumSize());
gfx::Size size_with_frame(50, 83);
gfx::Size size_with_frame(50, 82);
surface->SetFrame(SurfaceFrameType::NORMAL);
EXPECT_EQ(size, shell_surface->GetMinimumSize());
EXPECT_EQ(size_with_frame, shell_surface->GetWidget()->GetMinimumSize());
......
......@@ -16,7 +16,7 @@ function openSingleImage(testVolumeName, volumeType) {
var launchedPromise = launch(testVolumeName, volumeType, [ENTRIES.desktop]);
return launchedPromise.then(function(args) {
var WIDTH = 880;
var HEIGHT = 603; /* Inner height 570px + native header 33px. */
var HEIGHT = 602; /* Inner height 570px + native header 32px. */
var appId = args.appId;
var resizedWindowPromise = gallery.callRemoteTestUtil(
'resizeWindow', appId, [WIDTH, HEIGHT]
......
......@@ -105,8 +105,8 @@ function cropImage(testVolumeName, volumeType) {
then(function() {
return gallery.waitForSlideImage(
appId,
532,
398,
534,
400,
'My Desktop Background');
}).
then(function() {
......@@ -375,7 +375,7 @@ testcase.resizeImageOnDownloads = function() {
*/
testcase.resizeImageOnDrive = function() {
return resizeImage('drive', 'drive');
}
};
/**
* The enableDisableOverwriteOriginalCheckbox test for Downloads.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment