Commit c25dbbd2 authored by Mitsuru Oshima's avatar Mitsuru Oshima Committed by Commit Bot

Add menu/zoom button

BUG=822960
TEST=covered by unittets

Change-Id: Ia6c7f3c9a54b4059f85b049ecaa3f8a0b0c30e30
Reviewed-on: https://chromium-review.googlesource.com/977023Reviewed-by: default avatarMalay Keshav <malaykeshav@chromium.org>
Commit-Queue: Mitsuru Oshima <oshima@chromium.org>
Cr-Commit-Position: refs/heads/master@{#545998}
parent 8314c303
...@@ -20,6 +20,10 @@ class CaptionButtonModel { ...@@ -20,6 +20,10 @@ class CaptionButtonModel {
// Returns true if |type| is enabled. // Returns true if |type| is enabled.
virtual bool IsEnabled(CaptionButtonIcon type) const = 0; virtual bool IsEnabled(CaptionButtonIcon type) const = 0;
// In zoom mode, the maximize/restore button will be repalced
// with zoom/unzoom button.
virtual bool InZoomMode() const = 0;
}; };
} // namespace ash } // namespace ash
......
...@@ -17,6 +17,7 @@ enum CaptionButtonIcon { ...@@ -17,6 +17,7 @@ enum CaptionButtonIcon {
CAPTION_BUTTON_ICON_RIGHT_SNAPPED, CAPTION_BUTTON_ICON_RIGHT_SNAPPED,
CAPTION_BUTTON_ICON_BACK, CAPTION_BUTTON_ICON_BACK,
CAPTION_BUTTON_ICON_LOCATION, CAPTION_BUTTON_ICON_LOCATION,
CAPTION_BUTTON_ICON_MENU,
CAPTION_BUTTON_ICON_COUNT CAPTION_BUTTON_ICON_COUNT
}; };
......
...@@ -130,7 +130,9 @@ class DefaultCaptionButtonModel : public CaptionButtonModel { ...@@ -130,7 +130,9 @@ class DefaultCaptionButtonModel : public CaptionButtonModel {
return frame_->widget_delegate()->CanResize(); return frame_->widget_delegate()->CanResize();
case CAPTION_BUTTON_ICON_CLOSE: case CAPTION_BUTTON_ICON_CLOSE:
return true; return true;
// No back or menu button by default.
case CAPTION_BUTTON_ICON_BACK: case CAPTION_BUTTON_ICON_BACK:
case CAPTION_BUTTON_ICON_MENU:
return false; return false;
case CAPTION_BUTTON_ICON_LOCATION: case CAPTION_BUTTON_ICON_LOCATION:
case CAPTION_BUTTON_ICON_COUNT: case CAPTION_BUTTON_ICON_COUNT:
...@@ -141,6 +143,7 @@ class DefaultCaptionButtonModel : public CaptionButtonModel { ...@@ -141,6 +143,7 @@ class DefaultCaptionButtonModel : public CaptionButtonModel {
return false; return false;
} }
bool IsEnabled(CaptionButtonIcon type) const override { return true; } bool IsEnabled(CaptionButtonIcon type) const override { return true; }
bool InZoomMode() const override { return false; }
private: private:
views::Widget* frame_; views::Widget* frame_;
...@@ -180,6 +183,11 @@ FrameCaptionButtonContainerView::FrameCaptionButtonContainerView( ...@@ -180,6 +183,11 @@ FrameCaptionButtonContainerView::FrameCaptionButtonContainerView(
tablet_mode_animation_->Reset(1.0f); tablet_mode_animation_->Reset(1.0f);
// Insert the buttons left to right. // Insert the buttons left to right.
menu_button_ = new FrameCaptionButton(this, CAPTION_BUTTON_ICON_MENU);
menu_button_->SetAccessibleName(
l10n_util::GetStringUTF16(IDS_APP_ACCNAME_MENU));
AddChildView(menu_button_);
minimize_button_ = new FrameCaptionButton(this, CAPTION_BUTTON_ICON_MINIMIZE); minimize_button_ = new FrameCaptionButton(this, CAPTION_BUTTON_ICON_MINIMIZE);
minimize_button_->SetAccessibleName( minimize_button_->SetAccessibleName(
l10n_util::GetStringUTF16(IDS_APP_ACCNAME_MINIMIZE)); l10n_util::GetStringUTF16(IDS_APP_ACCNAME_MINIMIZE));
...@@ -209,7 +217,7 @@ void FrameCaptionButtonContainerView::SetButtonImage( ...@@ -209,7 +217,7 @@ void FrameCaptionButtonContainerView::SetButtonImage(
const gfx::VectorIcon& icon_definition) { const gfx::VectorIcon& icon_definition) {
button_icon_map_[icon] = &icon_definition; button_icon_map_[icon] = &icon_definition;
FrameCaptionButton* buttons[] = {minimize_button_, size_button_, FrameCaptionButton* buttons[] = {menu_button_, minimize_button_, size_button_,
close_button_}; close_button_};
for (size_t i = 0; i < arraysize(buttons); ++i) { for (size_t i = 0; i < arraysize(buttons); ++i) {
if (buttons[i]->icon() == icon) if (buttons[i]->icon() == icon)
...@@ -219,12 +227,14 @@ void FrameCaptionButtonContainerView::SetButtonImage( ...@@ -219,12 +227,14 @@ void FrameCaptionButtonContainerView::SetButtonImage(
} }
void FrameCaptionButtonContainerView::SetPaintAsActive(bool paint_as_active) { void FrameCaptionButtonContainerView::SetPaintAsActive(bool paint_as_active) {
menu_button_->set_paint_as_active(paint_as_active);
minimize_button_->set_paint_as_active(paint_as_active); minimize_button_->set_paint_as_active(paint_as_active);
size_button_->set_paint_as_active(paint_as_active); size_button_->set_paint_as_active(paint_as_active);
close_button_->set_paint_as_active(paint_as_active); close_button_->set_paint_as_active(paint_as_active);
} }
void FrameCaptionButtonContainerView::SetUseLightImages(bool light) { void FrameCaptionButtonContainerView::SetUseLightImages(bool light) {
menu_button_->set_use_light_images(light);
minimize_button_->set_use_light_images(light); minimize_button_->set_use_light_images(light);
size_button_->set_use_light_images(light); size_button_->set_use_light_images(light);
close_button_->set_use_light_images(light); close_button_->set_use_light_images(light);
...@@ -245,6 +255,9 @@ int FrameCaptionButtonContainerView::NonClientHitTest( ...@@ -245,6 +255,9 @@ int FrameCaptionButtonContainerView::NonClientHitTest(
} else if (minimize_button_->visible() && } else if (minimize_button_->visible() &&
ConvertPointToViewAndHitTest(this, minimize_button_, point)) { ConvertPointToViewAndHitTest(this, minimize_button_, point)) {
return HTMINBUTTON; return HTMINBUTTON;
} else if (menu_button_->visible() &&
ConvertPointToViewAndHitTest(this, menu_button_, point)) {
return HTMENU;
} }
return HTNOWHERE; return HTNOWHERE;
} }
...@@ -270,9 +283,12 @@ void FrameCaptionButtonContainerView::UpdateCaptionButtonState(bool animate) { ...@@ -270,9 +283,12 @@ void FrameCaptionButtonContainerView::UpdateCaptionButtonState(bool animate) {
model_->IsEnabled(CAPTION_BUTTON_ICON_MAXIMIZE_RESTORE)); model_->IsEnabled(CAPTION_BUTTON_ICON_MAXIMIZE_RESTORE));
minimize_button_->SetVisible(model_->IsVisible(CAPTION_BUTTON_ICON_MINIMIZE)); minimize_button_->SetVisible(model_->IsVisible(CAPTION_BUTTON_ICON_MINIMIZE));
minimize_button_->SetEnabled(model_->IsEnabled(CAPTION_BUTTON_ICON_MINIMIZE)); minimize_button_->SetEnabled(model_->IsEnabled(CAPTION_BUTTON_ICON_MINIMIZE));
menu_button_->SetVisible(model_->IsVisible(CAPTION_BUTTON_ICON_MENU));
menu_button_->SetEnabled(model_->IsEnabled(CAPTION_BUTTON_ICON_MENU));
} }
void FrameCaptionButtonContainerView::SetButtonSize(const gfx::Size& size) { void FrameCaptionButtonContainerView::SetButtonSize(const gfx::Size& size) {
menu_button_->SetPreferredSize(size);
minimize_button_->SetPreferredSize(size); minimize_button_->SetPreferredSize(size);
size_button_->SetPreferredSize(size); size_button_->SetPreferredSize(size);
close_button_->SetPreferredSize(size); close_button_->SetPreferredSize(size);
...@@ -417,6 +433,7 @@ bool FrameCaptionButtonContainerView::IsMinimizeButtonVisible() const { ...@@ -417,6 +433,7 @@ bool FrameCaptionButtonContainerView::IsMinimizeButtonVisible() const {
void FrameCaptionButtonContainerView::SetButtonsToNormal(Animate animate) { void FrameCaptionButtonContainerView::SetButtonsToNormal(Animate animate) {
SetButtonIcons(CAPTION_BUTTON_ICON_MINIMIZE, CAPTION_BUTTON_ICON_CLOSE, SetButtonIcons(CAPTION_BUTTON_ICON_MINIMIZE, CAPTION_BUTTON_ICON_CLOSE,
animate); animate);
menu_button_->SetState(views::Button::STATE_NORMAL);
minimize_button_->SetState(views::Button::STATE_NORMAL); minimize_button_->SetState(views::Button::STATE_NORMAL);
size_button_->SetState(views::Button::STATE_NORMAL); size_button_->SetState(views::Button::STATE_NORMAL);
close_button_->SetState(views::Button::STATE_NORMAL); close_button_->SetState(views::Button::STATE_NORMAL);
...@@ -438,7 +455,7 @@ const FrameCaptionButton* FrameCaptionButtonContainerView::GetButtonClosestTo( ...@@ -438,7 +455,7 @@ const FrameCaptionButton* FrameCaptionButtonContainerView::GetButtonClosestTo(
gfx::Point position(position_in_screen); gfx::Point position(position_in_screen);
views::View::ConvertPointFromScreen(this, &position); views::View::ConvertPointFromScreen(this, &position);
FrameCaptionButton* buttons[] = {minimize_button_, size_button_, FrameCaptionButton* buttons[] = {menu_button_, minimize_button_, size_button_,
close_button_}; close_button_};
int min_squared_distance = INT_MAX; int min_squared_distance = INT_MAX;
FrameCaptionButton* closest_button = NULL; FrameCaptionButton* closest_button = NULL;
...@@ -463,7 +480,7 @@ const FrameCaptionButton* FrameCaptionButtonContainerView::GetButtonClosestTo( ...@@ -463,7 +480,7 @@ const FrameCaptionButton* FrameCaptionButtonContainerView::GetButtonClosestTo(
void FrameCaptionButtonContainerView::SetHoveredAndPressedButtons( void FrameCaptionButtonContainerView::SetHoveredAndPressedButtons(
const FrameCaptionButton* to_hover, const FrameCaptionButton* to_hover,
const FrameCaptionButton* to_press) { const FrameCaptionButton* to_press) {
FrameCaptionButton* buttons[] = {minimize_button_, size_button_, FrameCaptionButton* buttons[] = {menu_button_, minimize_button_, size_button_,
close_button_}; close_button_};
for (size_t i = 0; i < arraysize(buttons); ++i) { for (size_t i = 0; i < arraysize(buttons); ++i) {
FrameCaptionButton* button = buttons[i]; FrameCaptionButton* button = buttons[i];
......
...@@ -63,6 +63,10 @@ class ASH_EXPORT FrameCaptionButtonContainerView ...@@ -63,6 +63,10 @@ class ASH_EXPORT FrameCaptionButtonContainerView
return container_view_->close_button_; return container_view_->close_button_;
} }
FrameCaptionButton* menu_button() const {
return container_view_->menu_button_;
}
private: private:
FrameCaptionButtonContainerView* container_view_; FrameCaptionButtonContainerView* container_view_;
...@@ -142,6 +146,7 @@ class ASH_EXPORT FrameCaptionButtonContainerView ...@@ -142,6 +146,7 @@ class ASH_EXPORT FrameCaptionButtonContainerView
// The buttons. In the normal button style, at most one of |minimize_button_| // The buttons. In the normal button style, at most one of |minimize_button_|
// and |size_button_| is visible. // and |size_button_| is visible.
FrameCaptionButton* menu_button_ = nullptr;
FrameCaptionButton* minimize_button_ = nullptr; FrameCaptionButton* minimize_button_ = nullptr;
FrameCaptionButton* size_button_ = nullptr; FrameCaptionButton* size_button_ = nullptr;
FrameCaptionButton* close_button_ = nullptr; FrameCaptionButton* close_button_ = nullptr;
......
...@@ -207,6 +207,7 @@ void FrameSizeButton::UpdateSnapType(const ui::LocatedEvent& event) { ...@@ -207,6 +207,7 @@ void FrameSizeButton::UpdateSnapType(const ui::LocatedEvent& event) {
case CAPTION_BUTTON_ICON_CLOSE: case CAPTION_BUTTON_ICON_CLOSE:
case CAPTION_BUTTON_ICON_BACK: case CAPTION_BUTTON_ICON_BACK:
case CAPTION_BUTTON_ICON_LOCATION: case CAPTION_BUTTON_ICON_LOCATION:
case CAPTION_BUTTON_ICON_MENU:
case CAPTION_BUTTON_ICON_COUNT: case CAPTION_BUTTON_ICON_COUNT:
NOTREACHED(); NOTREACHED();
break; break;
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include "ash/frame/caption_buttons/frame_caption_button.h" #include "ash/frame/caption_buttons/frame_caption_button.h"
#include "ash/frame/caption_buttons/frame_caption_button_container_view.h" #include "ash/frame/caption_buttons/frame_caption_button_container_view.h"
#include "ash/frame/header_view.h" #include "ash/frame/header_view.h"
#include "ash/public/cpp/vector_icons/vector_icons.h"
#include "ash/public/cpp/window_properties.h" #include "ash/public/cpp/window_properties.h"
#include "ash/shell.h" #include "ash/shell.h"
#include "ash/test/ash_test_base.h" #include "ash/test/ash_test_base.h"
...@@ -424,6 +425,8 @@ class TestButtonModel : public CaptionButtonModel { ...@@ -424,6 +425,8 @@ class TestButtonModel : public CaptionButtonModel {
TestButtonModel() = default; TestButtonModel() = default;
~TestButtonModel() override = default; ~TestButtonModel() override = default;
void set_zoom_mode(bool zoom_mode) { zoom_mode_ = zoom_mode; }
void SetVisible(CaptionButtonIcon type, bool visible) { void SetVisible(CaptionButtonIcon type, bool visible) {
if (visible) if (visible)
visible_buttons_.insert(type); visible_buttons_.insert(type);
...@@ -445,10 +448,12 @@ class TestButtonModel : public CaptionButtonModel { ...@@ -445,10 +448,12 @@ class TestButtonModel : public CaptionButtonModel {
bool IsEnabled(CaptionButtonIcon type) const override { bool IsEnabled(CaptionButtonIcon type) const override {
return enabled_buttons_.count(type); return enabled_buttons_.count(type);
} }
bool InZoomMode() const override { return zoom_mode_; }
private: private:
base::flat_set<CaptionButtonIcon> visible_buttons_; base::flat_set<CaptionButtonIcon> visible_buttons_;
base::flat_set<CaptionButtonIcon> enabled_buttons_; base::flat_set<CaptionButtonIcon> enabled_buttons_;
bool zoom_mode_ = false;
DISALLOW_COPY_AND_ASSIGN(TestButtonModel); DISALLOW_COPY_AND_ASSIGN(TestButtonModel);
}; };
...@@ -566,6 +571,7 @@ TEST_F(CustomFrameViewAshTest, CustomButtonModel) { ...@@ -566,6 +571,7 @@ TEST_F(CustomFrameViewAshTest, CustomButtonModel) {
EXPECT_FALSE(test_api.minimize_button()->visible()); EXPECT_FALSE(test_api.minimize_button()->visible());
EXPECT_FALSE(test_api.size_button()->visible()); EXPECT_FALSE(test_api.size_button()->visible());
EXPECT_FALSE(test_api.menu_button()->visible());
// Back button // Back button
model_ptr->SetVisible(CAPTION_BUTTON_ICON_BACK, true); model_ptr->SetVisible(CAPTION_BUTTON_ICON_BACK, true);
...@@ -596,6 +602,31 @@ TEST_F(CustomFrameViewAshTest, CustomButtonModel) { ...@@ -596,6 +602,31 @@ TEST_F(CustomFrameViewAshTest, CustomButtonModel) {
model_ptr->SetEnabled(CAPTION_BUTTON_ICON_MINIMIZE, true); model_ptr->SetEnabled(CAPTION_BUTTON_ICON_MINIMIZE, true);
custom_frame_view->SizeConstraintsChanged(); custom_frame_view->SizeConstraintsChanged();
EXPECT_TRUE(test_api.minimize_button()->enabled()); EXPECT_TRUE(test_api.minimize_button()->enabled());
// menu button
model_ptr->SetVisible(CAPTION_BUTTON_ICON_MENU, true);
custom_frame_view->SizeConstraintsChanged();
EXPECT_TRUE(test_api.menu_button()->visible());
EXPECT_FALSE(test_api.menu_button()->enabled());
model_ptr->SetEnabled(CAPTION_BUTTON_ICON_MENU, true);
custom_frame_view->SizeConstraintsChanged();
EXPECT_TRUE(test_api.menu_button()->enabled());
// The addresses in library and in the main binary differ in
// comoponent build.
#if !defined(COMPONENT_BUILD)
// zoom button
EXPECT_EQ(&kWindowControlMaximizeIcon,
test_api.size_button()->icon_definition_for_test());
model_ptr->set_zoom_mode(true);
custom_frame_view->SizeConstraintsChanged();
EXPECT_EQ(&ash::kWindowControlZoomIcon,
test_api.size_button()->icon_definition_for_test());
widget->Maximize();
EXPECT_EQ(&ash::kWindowControlDezoomIcon,
test_api.size_button()->icon_definition_for_test());
#endif
} }
namespace { namespace {
......
...@@ -324,6 +324,9 @@ void DefaultFrameHeader::UpdateAllButtonImages() { ...@@ -324,6 +324,9 @@ void DefaultFrameHeader::UpdateAllButtonImages() {
UpdateSizeButtonImages(); UpdateSizeButtonImages();
caption_button_container_->SetButtonImage(CAPTION_BUTTON_ICON_MENU,
kWindowControlMenuIcon);
caption_button_container_->SetButtonImage(CAPTION_BUTTON_ICON_CLOSE, caption_button_container_->SetButtonImage(CAPTION_BUTTON_ICON_CLOSE,
kWindowControlCloseIcon); kWindowControlCloseIcon);
...@@ -339,9 +342,14 @@ void DefaultFrameHeader::UpdateSizeButtonImages() { ...@@ -339,9 +342,14 @@ void DefaultFrameHeader::UpdateSizeButtonImages() {
// buttons as it would cause mismatch beteen window state and size button. // buttons as it would cause mismatch beteen window state and size button.
if (frame_->IsMinimized()) if (frame_->IsMinimized())
return; return;
bool use_zoom_icons = caption_button_container_->model()->InZoomMode();
const gfx::VectorIcon& restore_icon =
use_zoom_icons ? kWindowControlDezoomIcon : kWindowControlRestoreIcon;
const gfx::VectorIcon& maximize_icon =
use_zoom_icons ? kWindowControlZoomIcon : kWindowControlMaximizeIcon;
const gfx::VectorIcon& icon = frame_->IsMaximized() || frame_->IsFullscreen() const gfx::VectorIcon& icon = frame_->IsMaximized() || frame_->IsFullscreen()
? kWindowControlRestoreIcon ? restore_icon
: kWindowControlMaximizeIcon; : maximize_icon;
caption_button_container_->SetButtonImage( caption_button_container_->SetButtonImage(
CAPTION_BUTTON_ICON_MAXIMIZE_RESTORE, icon); CAPTION_BUTTON_ICON_MAXIMIZE_RESTORE, icon);
} }
......
...@@ -435,6 +435,9 @@ need to be translated for each locale.--> ...@@ -435,6 +435,9 @@ need to be translated for each locale.-->
<message name="IDS_APP_ACCNAME_RESTORE" desc="The accessible name for the Restore button."> <message name="IDS_APP_ACCNAME_RESTORE" desc="The accessible name for the Restore button.">
Restore Restore
</message> </message>
<message name="IDS_APP_ACCNAME_MENU" desc="The accessible name for the Menu button.">
Menu
</message>
<!-- Scroll Bar Context Menu Labels --> <!-- Scroll Bar Context Menu Labels -->
<message name="IDS_APP_SCROLLBAR_CXMENU_SCROLLHERE" desc="The label for the 'Scroll Here' item"> <message name="IDS_APP_SCROLLBAR_CXMENU_SCROLLHERE" desc="The label for the 'Scroll Here' item">
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment