BButton: Add flat property

* Add methods SetFlat()/IsFlat(). A flat button doesn't draw its frame,
  unless the mouse is hovering over it or it is otherwise activated.
* As a side effect this change also activates the hover glow that was
  already implemented in BControlLook, but not activated in BButton.
This commit is contained in:
Ingo Weinhold 2013-12-29 00:02:35 +01:00
parent 94c2eb2092
commit a249edfbfc
4 changed files with 106 additions and 19 deletions

View File

@ -39,6 +39,9 @@ public:
virtual void SetLabel(const char* string);
bool IsDefault() const;
bool IsFlat() const;
void SetFlat(bool flat);
virtual void MessageReceived(BMessage* message);
virtual void WindowActivated(bool active);
virtual void MouseMoved(BPoint point, uint32 transit,
@ -79,7 +82,6 @@ private:
virtual void _ReservedButton2();
virtual void _ReservedButton3();
private:
BButton& operator=(const BButton &);
BSize _ValidatePreferredSize();
@ -87,9 +89,15 @@ private:
BRect _DrawDefault(BRect bounds, bool enabled);
void _DrawFocusLine(float x, float y, float width,
bool bVisible);
inline bool _Flag(uint32 flag) const;
inline bool _SetFlag(uint32 flag, bool set);
private:
BSize fPreferredSize;
uint32 fFlags;
bool fDrawAsDefault;
bool fFlat;
uint32 _reserved[2];
};

View File

@ -82,6 +82,7 @@ public:
B_DEFAULT_BUTTON = 1 << 5,
B_IGNORE_OUTLINE = 1 << 6,
B_PARTIALLY_ACTIVATED = 1 << 7, // like B_ACTIVATED, but for tri-state
B_FLAT = 1 << 8, // flat look (e.g. button background)
B_BLEND_FRAME = 1 << 16
};

View File

@ -26,6 +26,13 @@
#include <binary_compatibility/Interface.h>
enum {
FLAG_DEFAULT = 0x01,
FLAG_FLAT = 0x02,
FLAG_INSIDE = 0x04,
};
static const float kLabelMargin = 3;
@ -34,7 +41,7 @@ BButton::BButton(BRect frame, const char* name, const char* label,
: BControl(frame, name, label, message, resizingMode,
flags | B_WILL_DRAW | B_FULL_UPDATE_ON_RESIZE),
fPreferredSize(-1, -1),
fDrawAsDefault(false)
fFlags(0)
{
// Resize to minimum height if needed
font_height fh;
@ -50,7 +57,7 @@ BButton::BButton(const char* name, const char* label, BMessage* message,
: BControl(name, label, message,
flags | B_WILL_DRAW | B_FULL_UPDATE_ON_RESIZE),
fPreferredSize(-1, -1),
fDrawAsDefault(false)
fFlags(0)
{
}
@ -59,7 +66,7 @@ BButton::BButton(const char* label, BMessage* message)
: BControl(NULL, label, message,
B_WILL_DRAW | B_NAVIGABLE | B_FULL_UPDATE_ON_RESIZE),
fPreferredSize(-1, -1),
fDrawAsDefault(false)
fFlags(0)
{
}
@ -71,10 +78,12 @@ BButton::~BButton()
BButton::BButton(BMessage* archive)
: BControl(archive),
fPreferredSize(-1, -1)
fPreferredSize(-1, -1),
fFlags(0)
{
if (archive->FindBool("_default", &fDrawAsDefault) != B_OK)
fDrawAsDefault = false;
bool isDefault = false;
if (archive->FindBool("_default", &isDefault) == B_OK && isDefault)
_SetFlag(FLAG_DEFAULT, true);
// NOTE: Default button state will be synchronized with the window
// in AttachedToWindow().
}
@ -112,8 +121,13 @@ BButton::Draw(BRect updateRect)
rgb_color background = LowColor();
rgb_color base = background;
uint32 flags = be_control_look->Flags(this);
if (IsDefault())
if (_Flag(FLAG_DEFAULT))
flags |= BControlLook::B_DEFAULT_BUTTON;
if (_Flag(FLAG_FLAT) && !IsTracking())
flags |= BControlLook::B_FLAT;
if (_Flag(FLAG_INSIDE))
flags |= BControlLook::B_HOVER;
be_control_look->DrawButtonFrame(this, rect, updateRect,
base, background, flags);
be_control_look->DrawButtonBackground(this, rect, updateRect,
@ -207,12 +221,10 @@ BButton::MakeDefault(bool flag)
oldDefault = window->DefaultButton();
if (flag) {
if (fDrawAsDefault && oldDefault == this)
if (_Flag(FLAG_DEFAULT) && oldDefault == this)
return;
if (!fDrawAsDefault) {
fDrawAsDefault = true;
if (_SetFlag(FLAG_DEFAULT, true)) {
if ((Flags() & B_SUPPORTS_LAYOUT) != 0)
InvalidateLayout();
else {
@ -224,11 +236,9 @@ BButton::MakeDefault(bool flag)
if (window && oldDefault != this)
window->SetDefaultButton(this);
} else {
if (!fDrawAsDefault)
if (!_SetFlag(FLAG_DEFAULT, false))
return;
fDrawAsDefault = false;
if ((Flags() & B_SUPPORTS_LAYOUT) != 0)
InvalidateLayout();
else {
@ -252,7 +262,22 @@ BButton::SetLabel(const char *string)
bool
BButton::IsDefault() const
{
return fDrawAsDefault;
return _Flag(FLAG_DEFAULT);
}
bool
BButton::IsFlat() const
{
return _Flag(FLAG_FLAT);
}
void
BButton::SetFlat(bool flat)
{
if (_SetFlag(FLAG_FLAT, flat))
Invalidate();
}
@ -273,11 +298,13 @@ BButton::WindowActivated(bool active)
void
BButton::MouseMoved(BPoint point, uint32 transit, const BMessage *message)
{
bool inside = Bounds().Contains(point);
if (_SetFlag(FLAG_INSIDE, inside))
Invalidate();
if (!IsTracking())
return;
bool inside = Bounds().Contains(point);
if ((Value() == B_CONTROL_ON) != inside)
SetValue(inside ? B_CONTROL_ON : B_CONTROL_OFF);
}
@ -291,6 +318,8 @@ BButton::MouseUp(BPoint point)
if (Bounds().Contains(point))
Invoke();
else if (_Flag(FLAG_FLAT))
Invalidate();
SetTracking(false);
}
@ -516,7 +545,7 @@ BButton::_ValidatePreferredSize()
float left, top, right, bottom;
be_control_look->GetInsets(BControlLook::B_BUTTON_FRAME,
BControlLook::B_BUTTON_BACKGROUND,
fDrawAsDefault ? BControlLook::B_DEFAULT_BUTTON : 0,
IsDefault() ? BControlLook::B_DEFAULT_BUTTON : 0,
left, top, right, bottom);
// width
@ -608,6 +637,28 @@ BButton::_DrawFocusLine(float x, float y, float width, bool visible)
}
inline bool
BButton::_Flag(uint32 flag) const
{
return (fFlags & flag) != 0;
}
inline bool
BButton::_SetFlag(uint32 flag, bool set)
{
if (((fFlags & flag) != 0) == set)
return false;
if (set)
fFlags |= flag;
else
fFlags &= ~flag;
return true;
}
extern "C" void
B_IF_GCC_2(InvalidateLayout__7BButtonb, _ZN7BButton16InvalidateLayoutEb)(
BView* view, bool descendants)

View File

@ -2046,6 +2046,20 @@ BControlLook::_DrawButtonFrame(BView* view, BRect& rect,
BRegion clipping(updateRect);
view->ConstrainClippingRegion(&clipping);
// If the button is flat and neither activated nor otherwise highlighted
// (mouse hovering or focussed), draw it flat.
if ((flags & B_FLAT) != 0
&& (flags & (B_ACTIVATED | B_PARTIALLY_ACTIVATED)) == 0
&& ((flags & (B_HOVER | B_FOCUSED)) == 0
|| (flags & B_DISABLED) != 0)) {
_DrawFrame(view, rect, background, background, background,
background, borders);
_DrawFrame(view, rect, background, background, background,
background, borders);
view->PopState();
return;
}
// outer edge colors
rgb_color edgeLightColor;
rgb_color edgeShadowColor;
@ -2317,6 +2331,19 @@ BControlLook::_DrawButtonBackground(BView* view, BRect& rect,
BRegion clipping(updateRect);
view->ConstrainClippingRegion(&clipping);
// If the button is flat and neither activated nor otherwise highlighted
// (mouse hovering or focussed), draw it flat.
if ((flags & B_FLAT) != 0
&& (flags & (B_ACTIVATED | B_PARTIALLY_ACTIVATED)) == 0
&& ((flags & (B_HOVER | B_FOCUSED)) == 0
|| (flags & B_DISABLED) != 0)) {
_DrawFrame(view, rect, base, base, base, base, borders);
view->SetHighColor(base);
view->FillRect(rect);
view->PopState();
return;
}
// inner bevel colors
rgb_color bevelLightColor = _BevelLightColor(base, flags);
rgb_color bevelShadowColor = _BevelShadowColor(base, flags);