| // Copyright 2019 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/shelf/kiosk_next_shelf_view.h" |
| |
| #include <memory> |
| |
| #include "ash/display/screen_orientation_controller.h" |
| #include "ash/public/cpp/shelf_model.h" |
| #include "ash/shelf/app_list_button.h" |
| #include "ash/shelf/back_button.h" |
| #include "ash/shelf/overflow_button.h" |
| #include "ash/shelf/shelf.h" |
| #include "ash/shelf/shelf_constants.h" |
| #include "ash/shelf/shelf_widget.h" |
| #include "ash/shell.h" |
| #include "ash/system/status_area_widget.h" |
| #include "ash/wm/tablet_mode/tablet_mode_controller.h" |
| #include "base/logging.h" |
| #include "ui/gfx/canvas.h" |
| #include "ui/gfx/geometry/insets.h" |
| #include "ui/gfx/geometry/insets_f.h" |
| #include "ui/gfx/geometry/size.h" |
| #include "ui/views/animation/flood_fill_ink_drop_ripple.h" |
| #include "ui/views/animation/ink_drop_mask.h" |
| #include "ui/views/animation/ink_drop_ripple.h" |
| #include "ui/views/controls/separator.h" |
| #include "ui/views/view.h" |
| #include "ui/views/widget/widget.h" |
| |
| namespace ash { |
| |
| namespace { |
| |
| // Kiosk Next back button with permanent round rectangle background. |
| class KioskNextBackButton : public BackButton { |
| public: |
| explicit KioskNextBackButton(ShelfView* shelf_view) |
| : BackButton(shelf_view) {} |
| ~KioskNextBackButton() override = default; |
| |
| private: |
| // views::BackButton: |
| void PaintButtonContents(gfx::Canvas* canvas) override { |
| PaintBackground(canvas, GetContentsBounds()); |
| BackButton::PaintButtonContents(canvas); |
| } |
| |
| std::unique_ptr<views::InkDropMask> CreateInkDropMask() const override { |
| return std::make_unique<views::RoundRectInkDropMask>( |
| size(), gfx::InsetsF(), kKioskNextShelfControlWidthDp / 2); |
| } |
| |
| std::unique_ptr<views::InkDropRipple> CreateInkDropRipple() const override { |
| return std::make_unique<views::FloodFillInkDropRipple>( |
| size(), gfx::Insets(), GetInkDropCenterBasedOnLastEvent(), |
| GetInkDropBaseColor(), ink_drop_visible_opacity()); |
| } |
| |
| DISALLOW_COPY_AND_ASSIGN(KioskNextBackButton); |
| }; |
| |
| // Kiosk Next home button with permanent round rectangle background. |
| class KioskNextHomeButton : public AppListButton { |
| public: |
| KioskNextHomeButton(ShelfView* shelf_view, Shelf* shelf) |
| : AppListButton(shelf_view, shelf) {} |
| ~KioskNextHomeButton() override = default; |
| |
| private: |
| // views::AppListButton: |
| void PaintButtonContents(gfx::Canvas* canvas) override { |
| PaintBackground(canvas, GetContentsBounds()); |
| AppListButton::PaintButtonContents(canvas); |
| } |
| |
| std::unique_ptr<views::InkDropMask> CreateInkDropMask() const override { |
| return std::make_unique<views::RoundRectInkDropMask>( |
| size(), gfx::InsetsF(), kKioskNextShelfControlWidthDp / 2); |
| } |
| |
| std::unique_ptr<views::InkDropRipple> CreateInkDropRipple() const override { |
| return std::make_unique<views::FloodFillInkDropRipple>( |
| size(), gfx::Insets(), GetInkDropCenterBasedOnLastEvent(), |
| GetInkDropBaseColor(), ink_drop_visible_opacity()); |
| } |
| |
| DISALLOW_COPY_AND_ASSIGN(KioskNextHomeButton); |
| }; |
| |
| bool IsTabletModeEnabled() { |
| return Shell::Get() |
| ->tablet_mode_controller() |
| ->IsTabletModeWindowManagerEnabled(); |
| } |
| |
| } // namespace |
| |
| KioskNextShelfView::KioskNextShelfView(ShelfModel* model, |
| Shelf* shelf, |
| ShelfWidget* shelf_widget) |
| : ShelfView(model, shelf, shelf_widget) { |
| // Kiosk next shelf has 2 buttons and it is expected to be used in tablet mode |
| // with bottom shelf alignment. It can be adapted to different requirements, |
| // but they should be explicitly verified first. |
| DCHECK(IsTabletModeEnabled()); |
| DCHECK(shelf->IsHorizontalAlignment()); |
| DCHECK_EQ(2, model->item_count()); |
| } |
| |
| KioskNextShelfView::~KioskNextShelfView() = default; |
| |
| void KioskNextShelfView::Init() { |
| ShelfView::Init(); |
| |
| // Needs to be called after base class call that creates below objects. |
| // TODO(agawronska): Separator and overflow button are not needed in Kiosk |
| // Next shelf. They should be moved to DefaultShelfView subclass and the below |
| // code should be removed. |
| DCHECK(separator()); |
| DCHECK(overflow_button()); |
| separator()->SetVisible(false); |
| overflow_button()->SetVisible(false); |
| |
| set_first_visible_index(0); |
| set_last_visible_index(model()->item_count() - 1); |
| } |
| |
| void KioskNextShelfView::CalculateIdealBounds() { |
| DCHECK(shelf()->IsHorizontalAlignment()); |
| DCHECK_EQ(2, model()->item_count()); |
| DCHECK_GE(kShelfSize, kKioskNextShelfControlHeightDp); |
| |
| // TODO(https://crbug.com/965690): Button spacing might be relative to shelf |
| // width. Reevaluate this piece once visual spec is available. |
| const int control_buttons_spacing = |
| IsCurrentScreenOrientationLandscape() |
| ? kKioskNextShelfControlSpacingLandscapeDp |
| : kKioskNextShelfControlSpacingPortraitDp; |
| const int total_shelf_width = |
| shelf_widget()->GetWindowBoundsInScreen().width(); |
| int x = total_shelf_width / 2 - kKioskNextShelfControlWidthDp - |
| control_buttons_spacing / 2; |
| int y = (kShelfSize - kKioskNextShelfControlHeightDp) / 2; |
| for (int i = 0; i < view_model()->view_size(); ++i) { |
| view_model()->set_ideal_bounds( |
| i, gfx::Rect(x, y, kKioskNextShelfControlWidthDp, |
| kKioskNextShelfControlHeightDp)); |
| x += (kKioskNextShelfControlWidthDp + control_buttons_spacing); |
| } |
| } |
| |
| views::View* KioskNextShelfView::CreateViewForItem(const ShelfItem& item) { |
| DCHECK(item.type == TYPE_BACK_BUTTON || item.type == TYPE_APP_LIST); |
| |
| if (item.type == TYPE_BACK_BUTTON) { |
| auto* view = new KioskNextBackButton(this); |
| ConfigureChildView(view); |
| return view; |
| } |
| |
| if (item.type == TYPE_APP_LIST) { |
| auto* view = new KioskNextHomeButton(this, shelf()); |
| view->set_context_menu_controller(this); |
| ConfigureChildView(view); |
| return view; |
| } |
| |
| NOTREACHED(); |
| return nullptr; |
| } |
| |
| } // namespace ash |