| // Copyright 2017 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 "chrome/browser/ui/views/web_apps/frame_toolbar/web_app_frame_toolbar_view.h" |
| |
| #include <memory> |
| |
| #include "base/feature_list.h" |
| #include "chrome/browser/ui/ui_features.h" |
| #include "chrome/browser/ui/view_ids.h" |
| #include "chrome/browser/ui/views/extensions/extensions_toolbar_button.h" |
| #include "chrome/browser/ui/views/extensions/extensions_toolbar_container.h" |
| #include "chrome/browser/ui/views/frame/browser_non_client_frame_view.h" |
| #include "chrome/browser/ui/views/frame/browser_view.h" |
| #include "chrome/browser/ui/views/page_action/page_action_icon_controller.h" |
| #include "chrome/browser/ui/views/toolbar/back_forward_button.h" |
| #include "chrome/browser/ui/views/toolbar/reload_button.h" |
| #include "chrome/browser/ui/views/web_apps/frame_toolbar/web_app_content_settings_container.h" |
| #include "chrome/browser/ui/views/web_apps/frame_toolbar/web_app_menu_button.h" |
| #include "chrome/browser/ui/views/web_apps/frame_toolbar/web_app_navigation_button_container.h" |
| #include "chrome/browser/ui/views/web_apps/frame_toolbar/web_app_toolbar_button_container.h" |
| #include "chrome/browser/ui/web_applications/app_browser_controller.h" |
| #include "ui/views/layout/flex_layout.h" |
| |
| const char WebAppFrameToolbarView::kViewClassName[] = "WebAppFrameToolbarView"; |
| |
| WebAppFrameToolbarView::WebAppFrameToolbarView(views::Widget* widget, |
| BrowserView* browser_view) |
| : browser_view_(browser_view) { |
| DCHECK(browser_view_); |
| DCHECK(web_app::AppBrowserController::IsWebApp(browser_view_->browser())); |
| SetID(VIEW_ID_WEB_APP_FRAME_TOOLBAR); |
| |
| { |
| // TODO(tluk) fix the need for both LayoutInContainer() and a layout |
| // manager for frame layout. |
| views::FlexLayout* layout = |
| SetLayoutManager(std::make_unique<views::FlexLayout>()); |
| layout->SetOrientation(views::LayoutOrientation::kHorizontal); |
| layout->SetMainAxisAlignment(views::LayoutAlignment::kEnd); |
| layout->SetCrossAxisAlignment(views::LayoutAlignment::kStretch); |
| } |
| |
| const auto* app_controller = browser_view_->browser()->app_controller(); |
| |
| if (app_controller->HasMinimalUiButtons()) { |
| left_container_ = AddChildView( |
| std::make_unique<WebAppNavigationButtonContainer>(browser_view_)); |
| left_container_->SetProperty( |
| views::kFlexBehaviorKey, |
| views::FlexSpecification( |
| views::LayoutOrientation::kHorizontal, |
| views::MinimumFlexSizeRule::kScaleToMinimumSnapToZero) |
| .WithOrder(2)); |
| } |
| |
| center_container_ = AddChildView(std::make_unique<views::View>()); |
| center_container_->SetProperty( |
| views::kFlexBehaviorKey, |
| views::FlexSpecification(views::LayoutOrientation::kHorizontal, |
| views::MinimumFlexSizeRule::kScaleToZero, |
| views::MaximumFlexSizeRule::kUnbounded) |
| .WithOrder(3)); |
| |
| right_container_ = |
| AddChildView(std::make_unique<WebAppToolbarButtonContainer>( |
| widget, browser_view, this)); |
| right_container_->SetProperty( |
| views::kFlexBehaviorKey, |
| views::FlexSpecification(right_container_->GetFlexRule()).WithOrder(1)); |
| |
| UpdateStatusIconsVisibility(); |
| |
| DCHECK(!browser_view_->toolbar_button_provider() || |
| browser_view_->toolbar_button_provider() |
| ->GetAsAccessiblePaneView() |
| ->GetClassName() == GetClassName()) |
| << "This should be the first ToolbarButtorProvider or a replacement for " |
| "an existing instance of this class during a window frame refresh."; |
| browser_view_->SetToolbarButtonProvider(this); |
| } |
| |
| WebAppFrameToolbarView::~WebAppFrameToolbarView() = default; |
| |
| void WebAppFrameToolbarView::UpdateStatusIconsVisibility() { |
| right_container_->UpdateStatusIconsVisibility(); |
| } |
| |
| void WebAppFrameToolbarView::UpdateCaptionColors() { |
| const BrowserNonClientFrameView* frame_view = |
| browser_view_->frame()->GetFrameView(); |
| DCHECK(frame_view); |
| |
| active_background_color_ = |
| frame_view->GetFrameColor(BrowserFrameActiveState::kActive); |
| active_foreground_color_ = |
| frame_view->GetCaptionColor(BrowserFrameActiveState::kActive); |
| inactive_background_color_ = |
| frame_view->GetFrameColor(BrowserFrameActiveState::kInactive); |
| inactive_foreground_color_ = |
| frame_view->GetCaptionColor(BrowserFrameActiveState::kInactive); |
| UpdateChildrenColor(); |
| } |
| |
| void WebAppFrameToolbarView::SetPaintAsActive(bool active) { |
| if (paint_as_active_ == active) |
| return; |
| paint_as_active_ = active; |
| UpdateChildrenColor(); |
| } |
| |
| std::pair<int, int> WebAppFrameToolbarView::LayoutInContainer( |
| int leading_x, |
| int trailing_x, |
| int y, |
| int available_height) { |
| SetVisible(available_height > 0); |
| |
| if (available_height == 0) { |
| SetSize(gfx::Size()); |
| return std::pair<int, int>(0, 0); |
| } |
| |
| gfx::Size preferred_size = GetPreferredSize(); |
| const int width = std::max(trailing_x - leading_x, 0); |
| const int height = preferred_size.height(); |
| DCHECK_LE(height, available_height); |
| SetBounds(leading_x, y + (available_height - height) / 2, width, height); |
| Layout(); |
| |
| if (!center_container_->GetVisible()) |
| return std::pair<int, int>(0, 0); |
| |
| // Bounds for remaining inner space, in parent container coordinates. |
| gfx::Rect center_bounds = center_container_->bounds(); |
| DCHECK(center_bounds.x() == 0 || left_container_); |
| center_bounds.Offset(bounds().OffsetFromOrigin()); |
| |
| return std::pair<int, int>(center_bounds.x(), center_bounds.right()); |
| } |
| |
| BrowserActionsContainer* WebAppFrameToolbarView::GetBrowserActionsContainer() { |
| CHECK(!base::FeatureList::IsEnabled(features::kExtensionsToolbarMenu)); |
| return right_container_->browser_actions_container(); |
| } |
| |
| ExtensionsToolbarContainer* |
| WebAppFrameToolbarView::GetExtensionsToolbarContainer() { |
| return right_container_->extensions_container(); |
| } |
| |
| gfx::Size WebAppFrameToolbarView::GetToolbarButtonSize() const { |
| constexpr int kFocusModeButtonSize = 34; |
| int size = browser_view_->browser()->is_focus_mode() |
| ? kFocusModeButtonSize |
| : GetLayoutConstant(WEB_APP_MENU_BUTTON_SIZE); |
| return gfx::Size(size, size); |
| } |
| |
| views::View* WebAppFrameToolbarView::GetDefaultExtensionDialogAnchorView() { |
| if (base::FeatureList::IsEnabled(features::kExtensionsToolbarMenu)) |
| return right_container_->extensions_container()->extensions_button(); |
| return GetAppMenuButton(); |
| } |
| |
| PageActionIconView* WebAppFrameToolbarView::GetPageActionIconView( |
| PageActionIconType type) { |
| return right_container_->page_action_icon_controller()->GetIconView(type); |
| } |
| |
| AppMenuButton* WebAppFrameToolbarView::GetAppMenuButton() { |
| return right_container_->web_app_menu_button(); |
| } |
| |
| gfx::Rect WebAppFrameToolbarView::GetFindBarBoundingBox(int contents_bottom) { |
| if (!IsDrawn()) |
| return gfx::Rect(); |
| |
| // If LTR find bar will be right aligned so align to right edge of app menu |
| // button. Otherwise it will be left aligned so align to the left edge of the |
| // app menu button. |
| views::View* anchor_view = GetAnchorView(PageActionIconType::kFind); |
| gfx::Rect anchor_bounds = |
| anchor_view->ConvertRectToWidget(anchor_view->GetLocalBounds()); |
| int x_pos = 0; |
| int width = anchor_bounds.right(); |
| if (base::i18n::IsRTL()) { |
| x_pos = anchor_bounds.x(); |
| width = GetWidget()->GetRootView()->width() - anchor_bounds.x(); |
| } |
| return gfx::Rect(x_pos, anchor_bounds.bottom(), width, |
| contents_bottom - anchor_bounds.bottom()); |
| } |
| |
| void WebAppFrameToolbarView::FocusToolbar() { |
| SetPaneFocus(nullptr); |
| } |
| |
| views::AccessiblePaneView* WebAppFrameToolbarView::GetAsAccessiblePaneView() { |
| return this; |
| } |
| |
| views::View* WebAppFrameToolbarView::GetAnchorView(PageActionIconType type) { |
| views::View* anchor = GetAppMenuButton(); |
| return anchor ? anchor : this; |
| } |
| |
| void WebAppFrameToolbarView::ZoomChangedForActiveTab(bool can_show_bubble) { |
| right_container_->page_action_icon_controller()->ZoomChangedForActiveTab( |
| can_show_bubble); |
| } |
| |
| AvatarToolbarButton* WebAppFrameToolbarView::GetAvatarToolbarButton() { |
| return nullptr; |
| } |
| |
| ToolbarButton* WebAppFrameToolbarView::GetBackButton() { |
| return left_container_ ? left_container_->back_button() : nullptr; |
| } |
| |
| ReloadButton* WebAppFrameToolbarView::GetReloadButton() { |
| return left_container_ ? left_container_->reload_button() : nullptr; |
| } |
| |
| views::View* WebAppFrameToolbarView::GetLeftContainerForTesting() { |
| return left_container_; |
| } |
| |
| views::View* WebAppFrameToolbarView::GetRightContainerForTesting() { |
| return right_container_; |
| } |
| |
| PageActionIconController* |
| WebAppFrameToolbarView::GetPageActionIconControllerForTesting() { |
| return right_container_->page_action_icon_controller(); |
| } |
| |
| const char* WebAppFrameToolbarView::GetClassName() const { |
| return kViewClassName; |
| } |
| |
| void WebAppFrameToolbarView::ChildPreferredSizeChanged(views::View* child) { |
| PreferredSizeChanged(); |
| } |
| |
| void WebAppFrameToolbarView::OnThemeChanged() { |
| views::AccessiblePaneView::OnThemeChanged(); |
| UpdateCaptionColors(); |
| } |
| |
| views::View* WebAppFrameToolbarView::GetContentSettingContainerForTesting() { |
| return right_container_->content_settings_container(); |
| } |
| |
| const std::vector<ContentSettingImageView*>& |
| WebAppFrameToolbarView::GetContentSettingViewsForTesting() const { |
| return right_container_->content_settings_container() |
| ->get_content_setting_views(); |
| } |
| |
| void WebAppFrameToolbarView::UpdateChildrenColor() { |
| const SkColor foreground_color = |
| paint_as_active_ ? active_foreground_color_ : inactive_foreground_color_; |
| if (left_container_) |
| left_container_->SetIconColor(foreground_color); |
| right_container_->SetColors( |
| foreground_color, |
| paint_as_active_ ? active_background_color_ : inactive_background_color_); |
| } |