| // Copyright 2020 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "ash/hud_display/hud_header_view.h" |
| |
| #include <utility> |
| |
| #include "ash/hud_display/hud_constants.h" |
| #include "ash/hud_display/hud_display.h" |
| #include "ash/hud_display/hud_properties.h" |
| #include "ash/hud_display/solid_source_background.h" |
| #include "ash/hud_display/tab_strip.h" |
| #include "base/functional/bind.h" |
| #include "base/memory/raw_ptr.h" |
| #include "components/vector_icons/vector_icons.h" |
| #include "ui/base/metadata/metadata_impl_macros.h" |
| #include "ui/gfx/canvas.h" |
| #include "ui/gfx/geometry/skia_conversions.h" |
| #include "ui/gfx/paint_vector_icon.h" |
| #include "ui/views/background.h" |
| #include "ui/views/border.h" |
| #include "ui/views/controls/button/button.h" |
| #include "ui/views/controls/button/image_button.h" |
| #include "ui/views/layout/box_layout.h" |
| |
| namespace ash { |
| namespace hud_display { |
| namespace { |
| |
| // Draws bottom left rounded background triangle. |
| class BottomLeftOuterBackground : public views::Background { |
| public: |
| // Background will have left bottom rounded corner with |top_rounding_radius|. |
| BottomLeftOuterBackground(SkColor color, SkScalar top_rounding_radius) |
| : inner_radius_(top_rounding_radius) { |
| SetColor(color); |
| } |
| |
| BottomLeftOuterBackground(const BottomLeftOuterBackground&) = delete; |
| BottomLeftOuterBackground& operator=(const BottomLeftOuterBackground&) = |
| delete; |
| |
| ~BottomLeftOuterBackground() override = default; |
| |
| // views::Background |
| void Paint(gfx::Canvas* canvas, views::View* view) const override { |
| const SkScalar circle_size = inner_radius_ * 2; |
| const SkScalar bottom_edge = view->height(); |
| |
| SkPath path; |
| path.moveTo(0, bottom_edge); |
| /* |false| will draw straight line to the start of the arc */ |
| path.arcTo({0, bottom_edge - circle_size, circle_size, bottom_edge}, 90, 90, |
| false); |
| path.lineTo(0, bottom_edge); |
| |
| cc::PaintFlags flags; |
| flags.setAntiAlias(true); |
| flags.setBlendMode(SkBlendMode::kSrc); |
| flags.setStyle(cc::PaintFlags::kFill_Style); |
| flags.setColor(color().ConvertToSkColor(view->GetColorProvider())); |
| canvas->DrawPath(path, flags); |
| } |
| |
| private: |
| SkScalar inner_radius_; |
| }; |
| |
| // ImageButton with underline |
| class SettingsButton : public views::ImageButton { |
| METADATA_HEADER(SettingsButton, views::ImageButton) |
| |
| public: |
| explicit SettingsButton(views::Button::PressedCallback callback) |
| : views::ImageButton(std::move(callback)) { |
| SetImageModel( |
| views::Button::ButtonState::STATE_NORMAL, |
| ui::ImageModel::FromVectorIcon(vector_icons::kSettingsIcon, |
| kHUDDefaultColor, kHUDSettingsIconSize)); |
| SetBorder(views::CreateEmptyBorder(kHUDSettingsIconBorder)); |
| SetProperty(kHUDClickHandler, HTCLIENT); |
| |
| SetFocusBehavior(views::View::FocusBehavior::ACCESSIBLE_ONLY); |
| } |
| |
| SettingsButton(const SettingsButton&) = delete; |
| SettingsButton& operator=(const SettingsButton&) = delete; |
| |
| ~SettingsButton() override = default; |
| |
| protected: |
| // ImageButton |
| void PaintButtonContents(gfx::Canvas* canvas) override { |
| views::ImageButton::PaintButtonContents(canvas); |
| |
| SkPath path; |
| path.moveTo(0, height()); |
| path.lineTo(height(), width()); |
| |
| cc::PaintFlags flags; |
| flags.setAntiAlias(true); |
| flags.setBlendMode(SkBlendMode::kSrc); |
| flags.setStyle(cc::PaintFlags::kStroke_Style); |
| flags.setStrokeWidth(1); |
| flags.setColor(kHUDDefaultColor); |
| canvas->DrawPath(path, flags); |
| } |
| }; |
| |
| BEGIN_METADATA(SettingsButton) |
| END_METADATA |
| |
| } // namespace |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| // HUDHeaderView |
| |
| BEGIN_METADATA(HUDHeaderView) |
| END_METADATA |
| |
| HUDHeaderView::HUDHeaderView(HUDDisplayView* hud) { |
| // Header should have background under the buttons area only. |
| // |
| // There is additional "padding" view an the end to draw bottom inner |
| // rounded piece of background. |
| |
| views::View* header_buttons = |
| AddChildView(std::make_unique<views::BoxLayoutView>()); |
| header_buttons->SetBackground(std::make_unique<SolidSourceBackground>( |
| kHUDBackground, kHUDTabOverlayCornerRadius)); |
| |
| // Header does not have margin between header and data. |
| // Data has its top margin (kHUDGraphsInset). |
| header_buttons->SetBorder(views::CreateEmptyBorder( |
| gfx::Insets::TLBR(kHUDInset, kHUDInset, 0, kHUDInset))); |
| |
| // Add buttons and tab strip. |
| header_buttons |
| ->AddChildView(std::make_unique<SettingsButton>(base::BindRepeating( |
| &HUDDisplayView::OnSettingsToggle, base::Unretained(hud)))) |
| ->SetTooltipText(u"Trigger Ash HUD Settings"); |
| tab_strip_ = header_buttons->AddChildView(std::make_unique<HUDTabStrip>(hud)); |
| |
| // Padding will take the rest of the header and draw bottom inner left |
| // background padding. |
| views::View* padding = AddChildView(std::make_unique<views::View>()); |
| padding->SetBackground(std::make_unique<BottomLeftOuterBackground>( |
| kHUDBackground, kHUDTabOverlayCornerRadius)); |
| SetFlexForView(padding, 1); |
| } |
| |
| HUDHeaderView::~HUDHeaderView() = default; |
| |
| } // namespace hud_display |
| } // namespace ash |