Commit 821bb5d7 authored by Elly Fong-Jones's avatar Elly Fong-Jones Committed by Commit Bot

views: fade buttons in inactive widgets

This change:
1) Adds an inner WidgetObserver subclass to Button to allow Button to observe
   its Widget's activation state changing;
2) Introduces a notion of "visual state" to buttons, as distinct from their
   existing state; the visual state governs how a button is drawn.
3) Has LabelButton use the visual state to decide which image to use instead
   of the raw state.

The end result is that when a LabelButton's Widget deactivates, that LabelButton
will take on a disabled appearance.

Bug: 848593
Change-Id: If5bd135c254fd36669e76fd39338dc24387602aa
Reviewed-on: https://chromium-review.googlesource.com/c/1251330
Commit-Queue: Elly Fong-Jones <ellyjones@chromium.org>
Reviewed-by: default avatarScott Violet <sky@chromium.org>
Cr-Commit-Position: refs/heads/master@{#600471}
parent 691013e6
...@@ -43,6 +43,30 @@ const int kHoverFadeDurationMs = 150; ...@@ -43,6 +43,30 @@ const int kHoverFadeDurationMs = 150;
} // namespace } // namespace
////////////////////////////////////////////////////////////////////////////////
// WidgetObserverButtonBridge:
Button::WidgetObserverButtonBridge::WidgetObserverButtonBridge(Button* button)
: owner_(button) {
DCHECK(button->GetWidget());
button->GetWidget()->AddObserver(this);
}
Button::WidgetObserverButtonBridge::~WidgetObserverButtonBridge() {
if (owner_)
owner_->GetWidget()->RemoveObserver(this);
}
void Button::WidgetObserverButtonBridge::OnWidgetActivationChanged(
Widget* widget,
bool active) {
owner_->WidgetActivationChanged(widget, active);
}
void Button::WidgetObserverButtonBridge::OnWidgetDestroying(Widget* widget) {
widget->RemoveObserver(this);
owner_ = nullptr;
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// Button, static public: // Button, static public:
...@@ -129,6 +153,14 @@ void Button::SetState(ButtonState state) { ...@@ -129,6 +153,14 @@ void Button::SetState(ButtonState state) {
SchedulePaint(); SchedulePaint();
} }
Button::ButtonState Button::GetVisualState() const {
if (PlatformStyle::kInactiveWidgetControlsAppearDisabled && GetWidget() &&
!GetWidget()->IsActive()) {
return STATE_DISABLED;
}
return state();
}
void Button::StartThrobbing(int cycles_til_stop) { void Button::StartThrobbing(int cycles_til_stop) {
if (!animate_on_state_change_) if (!animate_on_state_change_)
return; return;
...@@ -456,6 +488,15 @@ void Button::OnBlur() { ...@@ -456,6 +488,15 @@ void Button::OnBlur() {
SchedulePaint(); SchedulePaint();
} }
void Button::AddedToWidget() {
if (PlatformStyle::kInactiveWidgetControlsAppearDisabled)
widget_observer_ = std::make_unique<WidgetObserverButtonBridge>(this);
}
void Button::RemovedFromWidget() {
widget_observer_.reset();
}
std::unique_ptr<InkDrop> Button::CreateInkDrop() { std::unique_ptr<InkDrop> Button::CreateInkDrop() {
std::unique_ptr<views::InkDropImpl> ink_drop = CreateDefaultInkDropImpl(); std::unique_ptr<views::InkDropImpl> ink_drop = CreateDefaultInkDropImpl();
ink_drop->SetShowHighlightOnFocus(!focus_ring_); ink_drop->SetShowHighlightOnFocus(!focus_ring_);
...@@ -568,4 +609,8 @@ bool Button::ShouldEnterHoveredState() { ...@@ -568,4 +609,8 @@ bool Button::ShouldEnterHoveredState() {
return check_mouse_position && IsMouseHovered(); return check_mouse_position && IsMouseHovered();
} }
void Button::WidgetActivationChanged(Widget* widget, bool active) {
StateChanged(state());
}
} // namespace views } // namespace views
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include "ui/views/animation/ink_drop_state.h" #include "ui/views/animation/ink_drop_state.h"
#include "ui/views/controls/focus_ring.h" #include "ui/views/controls/focus_ring.h"
#include "ui/views/painter.h" #include "ui/views/painter.h"
#include "ui/views/widget/widget_observer.h"
namespace views { namespace views {
...@@ -96,6 +97,9 @@ class VIEWS_EXPORT Button : public InkDropHostView, ...@@ -96,6 +97,9 @@ class VIEWS_EXPORT Button : public InkDropHostView,
// like event dispatching, focus traversals, etc. Calling SetEnabled(false) // like event dispatching, focus traversals, etc. Calling SetEnabled(false)
// will also set the state of |this| to STATE_DISABLED. // will also set the state of |this| to STATE_DISABLED.
void SetState(ButtonState state); void SetState(ButtonState state);
// Returns the visual appearance state of the button. This takes into account
// both the button's display state and the state of the containing widget.
ButtonState GetVisualState() const;
// Starts throbbing. See HoverAnimation for a description of cycles_til_stop. // Starts throbbing. See HoverAnimation for a description of cycles_til_stop.
// This method does nothing if |animate_on_state_change_| is false. // This method does nothing if |animate_on_state_change_| is false.
...@@ -183,6 +187,8 @@ class VIEWS_EXPORT Button : public InkDropHostView, ...@@ -183,6 +187,8 @@ class VIEWS_EXPORT Button : public InkDropHostView,
const ViewHierarchyChangedDetails& details) override; const ViewHierarchyChangedDetails& details) override;
void OnFocus() override; void OnFocus() override;
void OnBlur() override; void OnBlur() override;
void AddedToWidget() override;
void RemovedFromWidget() override;
// Overridden from InkDropHostView: // Overridden from InkDropHostView:
std::unique_ptr<InkDrop> CreateInkDrop() override; std::unique_ptr<InkDrop> CreateInkDrop() override;
...@@ -261,6 +267,28 @@ class VIEWS_EXPORT Button : public InkDropHostView, ...@@ -261,6 +267,28 @@ class VIEWS_EXPORT Button : public InkDropHostView,
private: private:
FRIEND_TEST_ALL_PREFIXES(BlueButtonTest, Border); FRIEND_TEST_ALL_PREFIXES(BlueButtonTest, Border);
// Bridge class to allow Button to observe a Widget without being a
// WidgetObserver. This is desirable because many Button subclasses are
// themselves WidgetObservers, and if Button is a WidgetObserver, any change
// to its WidgetObserver overrides requires updating all the subclasses as
// well.
class WidgetObserverButtonBridge : public WidgetObserver {
public:
WidgetObserverButtonBridge(Button* owner);
~WidgetObserverButtonBridge() override;
// WidgetObserver:
void OnWidgetActivationChanged(Widget* widget, bool active) override;
void OnWidgetDestroying(Widget* widget) override;
private:
Button* owner_;
DISALLOW_COPY_AND_ASSIGN(WidgetObserverButtonBridge);
};
void WidgetActivationChanged(Widget* widget, bool active);
// The text shown in a tooltip. // The text shown in a tooltip.
base::string16 tooltip_text_; base::string16 tooltip_text_;
...@@ -306,6 +334,8 @@ class VIEWS_EXPORT Button : public InkDropHostView, ...@@ -306,6 +334,8 @@ class VIEWS_EXPORT Button : public InkDropHostView,
std::unique_ptr<Painter> focus_painter_; std::unique_ptr<Painter> focus_painter_;
std::unique_ptr<WidgetObserverButtonBridge> widget_observer_;
DISALLOW_COPY_AND_ASSIGN(Button); DISALLOW_COPY_AND_ASSIGN(Button);
}; };
......
...@@ -493,7 +493,7 @@ void LabelButton::UpdateStyleToIndicateDefaultStatus() { ...@@ -493,7 +493,7 @@ void LabelButton::UpdateStyleToIndicateDefaultStatus() {
} }
void LabelButton::UpdateImage() { void LabelButton::UpdateImage() {
image_->SetImage(GetImage(state())); image_->SetImage(GetImage(GetVisualState()));
ResetCachedPreferredSize(); ResetCachedPreferredSize();
} }
......
...@@ -63,6 +63,7 @@ const bool PlatformStyle::kTextfieldScrollsToStartOnFocusChange = false; ...@@ -63,6 +63,7 @@ const bool PlatformStyle::kTextfieldScrollsToStartOnFocusChange = false;
const bool PlatformStyle::kTextfieldUsesDragCursorWhenDraggable = true; const bool PlatformStyle::kTextfieldUsesDragCursorWhenDraggable = true;
const bool PlatformStyle::kShouldElideBookmarksInBookmarksBar = false; const bool PlatformStyle::kShouldElideBookmarksInBookmarksBar = false;
const bool PlatformStyle::kPreferFocusRings = false; const bool PlatformStyle::kPreferFocusRings = false;
const bool PlatformStyle::kInactiveWidgetControlsAppearDisabled = false;
// static // static
std::unique_ptr<ScrollBar> PlatformStyle::CreateScrollBar(bool is_horizontal) { std::unique_ptr<ScrollBar> PlatformStyle::CreateScrollBar(bool is_horizontal) {
......
...@@ -83,6 +83,9 @@ class VIEWS_EXPORT PlatformStyle { ...@@ -83,6 +83,9 @@ class VIEWS_EXPORT PlatformStyle {
// hover state on focus. // hover state on focus.
static const bool kPreferFocusRings; static const bool kPreferFocusRings;
// Whether controls in inactive widgets appear disabled.
static const bool kInactiveWidgetControlsAppearDisabled;
// Creates the default scrollbar for the given orientation. // Creates the default scrollbar for the given orientation.
static std::unique_ptr<ScrollBar> CreateScrollBar(bool is_horizontal); static std::unique_ptr<ScrollBar> CreateScrollBar(bool is_horizontal);
......
...@@ -43,6 +43,7 @@ const bool PlatformStyle::kTreeViewSelectionPaintsEntireRow = true; ...@@ -43,6 +43,7 @@ const bool PlatformStyle::kTreeViewSelectionPaintsEntireRow = true;
const bool PlatformStyle::kShouldElideBookmarksInBookmarksBar = true; const bool PlatformStyle::kShouldElideBookmarksInBookmarksBar = true;
const bool PlatformStyle::kUseRipples = false; const bool PlatformStyle::kUseRipples = false;
const bool PlatformStyle::kPreferFocusRings = true; const bool PlatformStyle::kPreferFocusRings = true;
const bool PlatformStyle::kInactiveWidgetControlsAppearDisabled = true;
const Button::NotifyAction PlatformStyle::kMenuNotifyActivationAction = const Button::NotifyAction PlatformStyle::kMenuNotifyActivationAction =
Button::NOTIFY_ON_PRESS; Button::NOTIFY_ON_PRESS;
......
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