blob: 76f008ac0eb797359b847341e4906f9e71a89ed4 [file] [log] [blame]
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ash/hud_display/graph_page_view_base.h"
#include "ash/hud_display/grid.h"
#include "ash/hud_display/hud_constants.h"
#include "ash/hud_display/hud_properties.h"
#include "ash/hud_display/legend.h"
#include "ash/hud_display/solid_source_background.h"
#include "base/bind.h"
#include "ui/gfx/canvas.h"
#include "ui/gfx/paint_vector_icon.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"
#include "ui/views/layout/fill_layout.h"
#include "ui/views/metadata/metadata_impl_macros.h"
#include "ui/views/window/vector_icons/vector_icons.h"
namespace ash {
namespace hud_display {
namespace {
constexpr int kMinMaxButtonIconSize = 10;
constexpr int kMinMaxButtonBorder = 5;
// ImageButton with underline
class MinMaxButton : public views::ImageButton {
public:
METADATA_HEADER(MinMaxButton);
explicit MinMaxButton(views::Button::PressedCallback callback)
: views::ImageButton(callback) {
SetBorder(views::CreateEmptyBorder(gfx::Insets(kMinMaxButtonBorder)));
SetBackground(std::make_unique<SolidSourceBackground>(kHUDLegendBackground,
/*radius=*/0));
SetProperty(kHUDClickHandler, HTCLIENT);
SetFocusBehavior(views::View::FocusBehavior::ACCESSIBLE_ONLY);
}
MinMaxButton(const MinMaxButton&) = delete;
MinMaxButton& operator=(const MinMaxButton&) = delete;
~MinMaxButton() 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(MinMaxButton, views::ImageButton)
END_METADATA
void SetMinimizeIconToButton(views::ImageButton* button) {
button->SetImage(
views::Button::ButtonState::STATE_NORMAL,
gfx::CreateVectorIcon(views::kWindowControlMinimizeIcon,
kMinMaxButtonIconSize, kHUDDefaultColor));
}
void SetRestoreIconToButton(views::ImageButton* button) {
button->SetImage(
views::Button::ButtonState::STATE_NORMAL,
gfx::CreateVectorIcon(views::kWindowControlRestoreIcon,
kMinMaxButtonIconSize, kHUDDefaultColor));
}
} // namespace
BEGIN_METADATA(GraphPageViewBase, views::View)
END_METADATA
GraphPageViewBase::GraphPageViewBase() {
DCHECK_CALLED_ON_VALID_SEQUENCE(ui_sequence_checker_);
// There are two overlaid children: grid and container for the legend.
SetLayoutManager(std::make_unique<views::FillLayout>());
// Grid is added after this object is fully initialized, but it should be
// located under control elements (or they will never receive events). This
// way we need to create a separate container for it.
grid_container_ = AddChildView(std::make_unique<views::View>());
grid_container_->SetLayoutManager(std::make_unique<views::FillLayout>());
// Legend is floating in its own container. Invisible border of
// kLegendPositionOffset makes it float on top of the graph.
constexpr int kLegendPositionOffset = 20;
legend_container_ = AddChildView(std::make_unique<views::View>());
legend_container_
->SetLayoutManager(std::make_unique<views::BoxLayout>(
views::BoxLayout::Orientation::kVertical))
->set_cross_axis_alignment(views::BoxLayout::CrossAxisAlignment::kStart);
legend_container_->SetBorder(
views::CreateEmptyBorder(gfx::Insets(kLegendPositionOffset)));
legend_container_->SetVisible(false);
legend_min_max_button_ = legend_container_->AddChildView(
std::make_unique<MinMaxButton>(base::BindRepeating(
&GraphPageViewBase::OnButtonPressed, base::Unretained(this))));
SetMinimizeIconToButton(legend_min_max_button_);
}
GraphPageViewBase::~GraphPageViewBase() {
DCHECK_CALLED_ON_VALID_SEQUENCE(ui_sequence_checker_);
}
void GraphPageViewBase::OnButtonPressed() {
if (legend_->GetVisible()) {
legend_->SetVisible(false);
SetRestoreIconToButton(legend_min_max_button_);
} else {
legend_->SetVisible(true);
SetMinimizeIconToButton(legend_min_max_button_);
}
}
void GraphPageViewBase::CreateLegend(
const std::vector<Legend::Entry>& entries) {
DCHECK(!legend_);
legend_ = legend_container_->AddChildView(std::make_unique<Legend>(entries));
legend_container_->SetVisible(true);
}
// Put grid in its dedicated container.
Grid* GraphPageViewBase::CreateGrid(float left,
float top,
float right,
float bottom,
const base::string16& x_unit,
const base::string16& y_unit,
int horizontal_points_number,
int horizontal_ticks_interval,
float vertical_ticks_interval) {
DCHECK(grid_container_->children().empty());
return grid_container_->AddChildView(std::make_unique<Grid>(
left, top, right, bottom, x_unit, y_unit, horizontal_points_number,
horizontal_ticks_interval, vertical_ticks_interval));
}
void GraphPageViewBase::RefreshLegendValues() {
if (legend_)
legend_->RefreshValues();
}
} // namespace hud_display
} // namespace ash