blob: 7a1fbaadadb5b98d3773660c0fe026e7f7801538 [file] [log] [blame]
// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ui/native_theme/native_theme_mobile.h"
#include "base/notreached.h"
#include "cc/paint/paint_canvas.h"
#include "cc/paint/paint_flags.h"
#include "third_party/skia/include/core/SkColor.h"
#include "third_party/skia/include/core/SkPath.h"
#include "third_party/skia/include/core/SkRect.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/size.h"
#include "ui/gfx/geometry/skia_conversions.h"
#include "ui/native_theme/native_theme_base.h"
namespace ui {
gfx::Size NativeThemeMobile::GetPartSize(
Part part,
State state,
const ExtraParams& extra_params) const {
// Radio buttons and checkboxes are slightly bigger than the defaults in
// `NativeThemeBase`, to make touch easier on small form factor devices.
return (part == kCheckbox || part == kRadio)
? gfx::Size(16, 16)
: NativeThemeBase::GetPartSize(part, state, extra_params);
}
SkColor NativeThemeMobile::GetControlColor(
ControlColorId color_id,
bool dark_mode,
PreferredContrast contrast,
const ColorProvider* color_provider) const {
// TODO(pkasting): Ensure the relevant bits of //ui/color/ are built on
// Android, then have `WebThemeEngineAndroid::Paint()` pass a web-only
// provider that provides the colors below, eliminating the need for this
// override.
const auto maybe_add_alpha = [&](ControlColorId id) {
const SkColor color =
GetControlColor(id, dark_mode, contrast, color_provider);
return (dark_mode || contrast == PreferredContrast::kMore)
? color
: SkColorSetA(color, 0x80);
};
switch (color_id) {
case kBorder:
return dark_mode ? SkColorSetRGB(0x85, 0x85, 0x85)
: SkColorSetRGB(0x76, 0x76, 0x76);
case kDisabledBorder:
return dark_mode ? SkColorSetRGB(0x62, 0x62, 0x62)
: SkColorSetARGB(0x4D, 0x76, 0x76, 0x76);
case kHoveredBorder:
return dark_mode ? SkColorSetRGB(0xAC, 0xAC, 0xAC)
: SkColorSetRGB(0x4F, 0x4F, 0x4F);
case kPressedBorder:
return dark_mode ? SkColorSetRGB(0x6E, 0x6E, 0x6E)
: SkColorSetRGB(0x8D, 0x8D, 0x8D);
case kAccent:
return dark_mode ? SkColorSetRGB(0x99, 0xC8, 0xFF)
: SkColorSetRGB(0x00, 0x75, 0xFF);
case kDisabledAccent:
return dark_mode ? SkColorSetRGB(0x75, 0x75, 0x75)
: SkColorSetARGB(0x4D, 0x76, 0x76, 0x76);
case kHoveredAccent:
return dark_mode ? SkColorSetRGB(0xD1, 0xE6, 0xFF)
: SkColorSetRGB(0x00, 0x5C, 0xC8);
case kPressedAccent:
return dark_mode ? SkColorSetRGB(0x61, 0xA9, 0xFF)
: SkColorSetRGB(0x37, 0x93, 0xFF);
case kCheckboxBackground:
return dark_mode ? SkColorSetRGB(0x3B, 0x3B, 0x3B) : SK_ColorWHITE;
case kDisabledCheckboxBackground:
return dark_mode ? SkColorSetRGB(0x3B, 0x3B, 0x3B)
: SkColorSetA(SK_ColorWHITE, 0x99);
case kFill:
return dark_mode ? SkColorSetRGB(0x3B, 0x3B, 0x3B)
: SkColorSetRGB(0xEF, 0xEF, 0xEF);
case kDisabledFill:
return dark_mode ? SkColorSetRGB(0x36, 0x36, 0x36)
: SkColorSetARGB(0x4D, 0xEF, 0xEF, 0xEF);
case kHoveredFill:
return dark_mode ? SkColorSetRGB(0x3B, 0x3B, 0x3B)
: SkColorSetRGB(0xE5, 0xE5, 0xE5);
case kPressedFill:
return dark_mode ? SkColorSetRGB(0x3B, 0x3B, 0x3B)
: SkColorSetRGB(0xF5, 0xF5, 0xF5);
case kLightenLayer:
return dark_mode ? SkColorSetRGB(0x3B, 0x3B, 0x3B)
: SkColorSetARGB(0x33, 0xA9, 0xA9, 0xA9);
case kProgressValue:
return dark_mode ? SkColorSetRGB(0x63, 0xAD, 0xE5)
: SkColorSetRGB(0x00, 0x75, 0xFF);
case kSlider:
return dark_mode ? SkColorSetRGB(0x99, 0xC8, 0xFF)
: SkColorSetRGB(0x00, 0x75, 0xFF);
case kDisabledSlider:
return dark_mode ? SkColorSetRGB(0x75, 0x75, 0x75)
: SkColorSetRGB(0xCB, 0xCB, 0xCB);
case kHoveredSlider:
return dark_mode ? SkColorSetRGB(0xD1, 0xE6, 0xFF)
: SkColorSetRGB(0x00, 0x5C, 0xC8);
case kPressedSlider:
return dark_mode ? SkColorSetRGB(0x61, 0xA9, 0xFF)
: SkColorSetRGB(0x37, 0x93, 0xFF);
case kSliderBorder:
return maybe_add_alpha(kBorder);
case kHoveredSliderBorder:
return maybe_add_alpha(kHoveredBorder);
case kPressedSliderBorder:
return maybe_add_alpha(kPressedBorder);
case kAutoCompleteBackground:
return dark_mode ? SkColorSetARGB(0x66, 0x46, 0x5A, 0x7E)
: SkColorSetRGB(0xE8, 0xF0, 0xFE);
case kScrollbarArrow:
case kScrollbarArrowHovered:
case kScrollbarArrowPressed:
// Even though Android does not paint scrollbars, these are used for the
// arrow buttons that comprise a web "inner spin button" control.
return dark_mode ? SK_ColorWHITE : SK_ColorBLACK;
case kScrollbarArrowDisabled:
return dark_mode ? SkColorSetRGB(0x55, 0x55, 0x55)
: SkColorSetRGB(0xA3, 0xA3, 0xA3);
case kScrollbarCornerControlColorId:
case kScrollbarTrack:
case kScrollbarThumb:
case kScrollbarThumbPressed:
case kScrollbarThumbHovered:
// These colors are unused because Android does not paint scrollbars.
NOTREACHED();
case kButtonBorder:
return dark_mode ? SkColorSetRGB(0x6B, 0x6B, 0x6B)
: SkColorSetRGB(0x76, 0x76, 0x76);
case kButtonDisabledBorder:
return dark_mode ? SkColorSetRGB(0x36, 0x36, 0x36)
: SkColorSetARGB(0x4D, 0x76, 0x76, 0x76);
case kButtonHoveredBorder:
return dark_mode ? SkColorSetRGB(0x7B, 0x7B, 0x7B)
: SkColorSetRGB(0x4F, 0x4F, 0x4F);
case kButtonPressedBorder:
return dark_mode ? SkColorSetRGB(0x61, 0x61, 0x61)
: SkColorSetRGB(0x8D, 0x8D, 0x8D);
case kButtonFill:
case kScrollbarArrowBackground:
return dark_mode ? SkColorSetRGB(0x6B, 0x6B, 0x6B)
: SkColorSetRGB(0xEF, 0xEF, 0xEF);
case kButtonDisabledFill:
case kScrollbarArrowBackgroundDisabled:
return dark_mode ? SkColorSetRGB(0x36, 0x36, 0x36)
: SkColorSetARGB(0x4D, 0xEF, 0xEF, 0xEF);
case kButtonHoveredFill:
case kScrollbarArrowBackgroundHovered:
return dark_mode ? SkColorSetRGB(0x7B, 0x7B, 0x7B)
: SkColorSetRGB(0xE5, 0xE5, 0xE5);
case kButtonPressedFill:
case kScrollbarArrowBackgroundPressed:
return dark_mode ? SkColorSetRGB(0x61, 0x61, 0x61)
: SkColorSetRGB(0xF5, 0xF5, 0xF5);
}
NOTREACHED();
}
void NativeThemeMobile::PaintArrowButton(
cc::PaintCanvas* canvas,
const ColorProvider* color_provider,
const gfx::Rect& rect,
Part part,
State state,
bool forced_colors,
bool dark_mode,
PreferredContrast contrast,
const ScrollbarArrowExtraParams& extra_params) const {
// Paint the background.
PaintLightenLayer(canvas, color_provider, gfx::RectToSkRect(rect), state, 0,
dark_mode, contrast);
// Paint the button's outline and fill the middle.
SkPath outline;
if (part == kScrollbarUpArrow) {
outline.moveTo(rect.x() + 0.5f, rect.y() + rect.height() + 0.5f);
outline.rLineTo(0, -(rect.height() - 2));
outline.rLineTo(2, -2);
outline.rLineTo(rect.width() - 5, 0);
outline.rLineTo(2, 2);
outline.rLineTo(0, rect.height() - 2);
} else if (part == kScrollbarDownArrow) {
outline.moveTo(rect.x() + 0.5f, rect.y() - 0.5f);
outline.rLineTo(0, rect.height() - 2);
outline.rLineTo(2, 2);
outline.rLineTo(rect.width() - 5, 0);
outline.rLineTo(2, -2);
outline.rLineTo(0, -(rect.height() - 2));
} else if (part == kScrollbarRightArrow) {
outline.moveTo(rect.x() - 0.5f, rect.y() + 0.5f);
outline.rLineTo(rect.width() - 2, 0);
outline.rLineTo(2, 2);
outline.rLineTo(0, rect.height() - 5);
outline.rLineTo(-2, 2);
outline.rLineTo(-(rect.width() - 2), 0);
} else {
CHECK_EQ(kScrollbarLeftArrow, part);
outline.moveTo(rect.x() + rect.width() + 0.5f, rect.y() + 0.5f);
outline.rLineTo(-(rect.width() - 2), 0);
outline.rLineTo(-2, 2);
outline.rLineTo(0, rect.height() - 5);
outline.rLineTo(2, 2);
outline.rLineTo(rect.width() - 2, 0);
}
outline.close();
const SkColor bg_color = GetScrollbarArrowBackgroundColor(
extra_params, state, dark_mode, contrast, color_provider);
cc::PaintFlags flags;
flags.setStyle(cc::PaintFlags::kFill_Style);
flags.setColor(bg_color);
canvas->drawPath(outline, flags);
flags.setAntiAlias(true);
flags.setStyle(cc::PaintFlags::kStroke_Style);
flags.setColor(GetControlColorForState(kButtonBorderColors, state, dark_mode,
contrast, color_provider));
canvas->drawPath(outline, flags);
PaintArrow(
canvas, rect, part, state,
GetScrollbarArrowForegroundColor(bg_color, extra_params, state, dark_mode,
contrast, color_provider));
}
NativeThemeMobile::NativeThemeMobile() = default;
NativeThemeMobile::~NativeThemeMobile() = default;
} // namespace ui