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;
} // 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:
......@@ -129,6 +153,14 @@ void Button::SetState(ButtonState state) {
SchedulePaint();
}
Button::ButtonState Button::GetVisualState() const {
if (PlatformStyle::kInactiveWidgetControlsAppearDisabled && GetWidget() &&
!GetWidget()->IsActive()) {
return STATE_DISABLED;
}
return state();
}
void Button::StartThrobbing(int cycles_til_stop) {
if (!animate_on_state_change_)
return;
......@@ -456,6 +488,15 @@ void Button::OnBlur() {
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<views::InkDropImpl> ink_drop = CreateDefaultInkDropImpl();
ink_drop->SetShowHighlightOnFocus(!focus_ring_);
......@@ -568,4 +609,8 @@ bool Button::ShouldEnterHoveredState() {
return check_mouse_position && IsMouseHovered();
}
void Button::WidgetActivationChanged(Widget* widget, bool active) {
StateChanged(state());
}
} // namespace views
......@@ -15,6 +15,7 @@
#include "ui/views/animation/ink_drop_state.h"
#include "ui/views/controls/focus_ring.h"
#include "ui/views/painter.h"
#include "ui/views/widget/widget_observer.h"
namespace views {
......@@ -96,6 +97,9 @@ class VIEWS_EXPORT Button : public InkDropHostView,
// like event dispatching, focus traversals, etc. Calling SetEnabled(false)
// will also set the state of |this| to STATE_DISABLED.
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.
// This method does nothing if |animate_on_state_change_| is false.
......@@ -183,6 +187,8 @@ class VIEWS_EXPORT Button : public InkDropHostView,
const ViewHierarchyChangedDetails& details) override;
void OnFocus() override;
void OnBlur() override;
void AddedToWidget() override;
void RemovedFromWidget() override;
// Overridden from InkDropHostView:
std::unique_ptr<InkDrop> CreateInkDrop() override;
......@@ -261,6 +267,28 @@ class VIEWS_EXPORT Button : public InkDropHostView,
private:
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.
base::string16 tooltip_text_;
......@@ -306,6 +334,8 @@ class VIEWS_EXPORT Button : public InkDropHostView,
std::unique_ptr<Painter> focus_painter_;
std::unique_ptr<WidgetObserverButtonBridge> widget_observer_;
DISALLOW_COPY_AND_ASSIGN(Button);
};
......
......@@ -493,7 +493,7 @@ void LabelButton::UpdateStyleToIndicateDefaultStatus() {
}
void LabelButton::UpdateImage() {
image_->SetImage(GetImage(state()));
image_->SetImage(GetImage(GetVisualState()));
ResetCachedPreferredSize();
}
......
......@@ -63,6 +63,7 @@ const bool PlatformStyle::kTextfieldScrollsToStartOnFocusChange = false;
const bool PlatformStyle::kTextfieldUsesDragCursorWhenDraggable = true;
const bool PlatformStyle::kShouldElideBookmarksInBookmarksBar = false;
const bool PlatformStyle::kPreferFocusRings = false;
const bool PlatformStyle::kInactiveWidgetControlsAppearDisabled = false;
// static
std::unique_ptr<ScrollBar> PlatformStyle::CreateScrollBar(bool is_horizontal) {
......
......@@ -83,6 +83,9 @@ class VIEWS_EXPORT PlatformStyle {
// hover state on focus.
static const bool kPreferFocusRings;
// Whether controls in inactive widgets appear disabled.
static const bool kInactiveWidgetControlsAppearDisabled;
// Creates the default scrollbar for the given orientation.
static std::unique_ptr<ScrollBar> CreateScrollBar(bool is_horizontal);
......
......@@ -43,6 +43,7 @@ const bool PlatformStyle::kTreeViewSelectionPaintsEntireRow = true;
const bool PlatformStyle::kShouldElideBookmarksInBookmarksBar = true;
const bool PlatformStyle::kUseRipples = false;
const bool PlatformStyle::kPreferFocusRings = true;
const bool PlatformStyle::kInactiveWidgetControlsAppearDisabled = true;
const Button::NotifyAction PlatformStyle::kMenuNotifyActivationAction =
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