BCheckBox: Add tri-state support
* Add possible control state B_CONTROL_PARTIALLY_ON and support it in BCheckBox and BControlLook. * BCheckBox: Add partialStateToOff property defining whether the partial state should transition to off. Defaults to false (i.e. partial to on).
This commit is contained in:
@@ -69,6 +69,9 @@ public:
|
||||
|
||||
virtual status_t Perform(perform_code code, void* data);
|
||||
|
||||
bool IsPartialStateToOff() const;
|
||||
void SetPartialStateToOff(bool partialToOff);
|
||||
|
||||
protected:
|
||||
virtual void LayoutInvalidated(bool descendants = false);
|
||||
|
||||
@@ -81,6 +84,7 @@ private:
|
||||
private:
|
||||
BRect _CheckBoxFrame() const;
|
||||
BSize _ValidatePreferredSize();
|
||||
int32 _NextState() const;
|
||||
|
||||
private:
|
||||
// Forbidden
|
||||
@@ -89,6 +93,7 @@ private:
|
||||
private:
|
||||
BSize fPreferredSize;
|
||||
bool fOutlined;
|
||||
bool fPartialToOff;
|
||||
};
|
||||
|
||||
#endif // _CHECK_BOX_H
|
||||
|
||||
@@ -12,7 +12,8 @@
|
||||
|
||||
enum {
|
||||
B_CONTROL_OFF = 0,
|
||||
B_CONTROL_ON = 1
|
||||
B_CONTROL_ON = 1,
|
||||
B_CONTROL_PARTIALLY_ON = 2
|
||||
};
|
||||
|
||||
class BWindow;
|
||||
|
||||
@@ -69,13 +69,14 @@ public:
|
||||
};
|
||||
|
||||
enum {
|
||||
B_FOCUSED = 1 << 0,
|
||||
B_CLICKED = 1 << 1, // some controls activate on mouse up
|
||||
B_ACTIVATED = 1 << 2,
|
||||
B_HOVER = 1 << 3,
|
||||
B_DISABLED = 1 << 4,
|
||||
B_DEFAULT_BUTTON = 1 << 5,
|
||||
B_IGNORE_OUTLINE = 1 << 6,
|
||||
B_FOCUSED = 1 << 0,
|
||||
B_CLICKED = 1 << 1, // some controls activate on mouse up
|
||||
B_ACTIVATED = 1 << 2,
|
||||
B_HOVER = 1 << 3,
|
||||
B_DISABLED = 1 << 4,
|
||||
B_DEFAULT_BUTTON = 1 << 5,
|
||||
B_IGNORE_OUTLINE = 1 << 6,
|
||||
B_PARTIALLY_ACTIVATED = 1 << 7, // like B_ACTIVATED, but for tri-state
|
||||
|
||||
B_BLEND_FRAME = 1 << 16
|
||||
};
|
||||
|
||||
@@ -26,7 +26,8 @@ BCheckBox::BCheckBox(BRect frame, const char *name, const char *label,
|
||||
:
|
||||
BControl(frame, name, label, message, resizingMode, flags),
|
||||
fPreferredSize(),
|
||||
fOutlined(false)
|
||||
fOutlined(false),
|
||||
fPartialToOff(false)
|
||||
{
|
||||
// Resize to minimum height if needed
|
||||
font_height fontHeight;
|
||||
@@ -43,7 +44,8 @@ BCheckBox::BCheckBox(const char *name, const char *label, BMessage *message,
|
||||
:
|
||||
BControl(name, label, message, flags | B_WILL_DRAW | B_NAVIGABLE),
|
||||
fPreferredSize(),
|
||||
fOutlined(false)
|
||||
fOutlined(false),
|
||||
fPartialToOff(false)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -52,7 +54,8 @@ BCheckBox::BCheckBox(const char *label, BMessage *message)
|
||||
:
|
||||
BControl(NULL, label, message, B_WILL_DRAW | B_NAVIGABLE),
|
||||
fPreferredSize(),
|
||||
fOutlined(false)
|
||||
fOutlined(false),
|
||||
fPartialToOff(false)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -60,7 +63,8 @@ BCheckBox::BCheckBox(const char *label, BMessage *message)
|
||||
BCheckBox::BCheckBox(BMessage *archive)
|
||||
:
|
||||
BControl(archive),
|
||||
fOutlined(false)
|
||||
fOutlined(false),
|
||||
fPartialToOff(false)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -322,7 +326,16 @@ BCheckBox::MessageReceived(BMessage *message)
|
||||
void
|
||||
BCheckBox::KeyDown(const char *bytes, int32 numBytes)
|
||||
{
|
||||
BControl::KeyDown(bytes, numBytes);
|
||||
if (*bytes == B_ENTER || *bytes == B_SPACE) {
|
||||
if (!IsEnabled())
|
||||
return;
|
||||
|
||||
SetValue(_NextState());
|
||||
Invoke();
|
||||
} else {
|
||||
// skip the BControl implementation
|
||||
BView::KeyDown(bytes, numBytes);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -360,7 +373,7 @@ BCheckBox::MouseDown(BPoint point)
|
||||
|
||||
if (fOutlined) {
|
||||
fOutlined = false;
|
||||
SetValue(!Value());
|
||||
SetValue(_NextState());
|
||||
Invoke();
|
||||
} else {
|
||||
Invalidate();
|
||||
@@ -385,7 +398,7 @@ BCheckBox::MouseUp(BPoint point)
|
||||
|
||||
if (fOutlined) {
|
||||
fOutlined = false;
|
||||
SetValue(!Value());
|
||||
SetValue(_NextState());
|
||||
Invoke();
|
||||
} else {
|
||||
Invalidate();
|
||||
@@ -485,8 +498,16 @@ BCheckBox::MakeFocus(bool focused)
|
||||
void
|
||||
BCheckBox::SetValue(int32 value)
|
||||
{
|
||||
value = value ? B_CONTROL_ON : B_CONTROL_OFF;
|
||||
// we only accept boolean values
|
||||
// We only accept three possible values.
|
||||
switch (value) {
|
||||
case B_CONTROL_OFF:
|
||||
case B_CONTROL_ON:
|
||||
case B_CONTROL_PARTIALLY_ON:
|
||||
break;
|
||||
default:
|
||||
value = B_CONTROL_ON;
|
||||
break;
|
||||
}
|
||||
|
||||
if (value != Value()) {
|
||||
BControl::SetValueNoUpdate(value);
|
||||
@@ -582,6 +603,20 @@ BCheckBox::LayoutInvalidated(bool descendants)
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
BCheckBox::IsPartialStateToOff() const
|
||||
{
|
||||
return fPartialToOff;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BCheckBox::SetPartialStateToOff(bool partialToOff)
|
||||
{
|
||||
fPartialToOff = partialToOff;
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark - FBC padding
|
||||
|
||||
|
||||
@@ -625,6 +660,21 @@ BCheckBox::_ValidatePreferredSize()
|
||||
}
|
||||
|
||||
|
||||
int32
|
||||
BCheckBox::_NextState() const
|
||||
{
|
||||
switch (Value()) {
|
||||
case B_CONTROL_OFF:
|
||||
return B_CONTROL_ON;
|
||||
case B_CONTROL_PARTIALLY_ON:
|
||||
return fPartialToOff ? B_CONTROL_OFF : B_CONTROL_ON;
|
||||
case B_CONTROL_ON:
|
||||
default:
|
||||
return B_CONTROL_OFF;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
BCheckBox &
|
||||
BCheckBox::operator=(const BCheckBox &)
|
||||
{
|
||||
|
||||
@@ -92,8 +92,14 @@ BControlLook::Flags(BControl* control) const
|
||||
flags |= B_FOCUSED;
|
||||
}
|
||||
|
||||
if (control->Value() == B_CONTROL_ON)
|
||||
flags |= B_ACTIVATED;
|
||||
switch (control->Value()) {
|
||||
case B_CONTROL_ON:
|
||||
flags |= B_ACTIVATED;
|
||||
break;
|
||||
case B_CONTROL_PARTIALLY_ON:
|
||||
flags |= B_PARTIALLY_ACTIVATED;
|
||||
break;
|
||||
}
|
||||
|
||||
if (control->Parent() != NULL
|
||||
&& (control->Parent()->Flags() & B_DRAW_ON_CHILDREN) != 0) {
|
||||
@@ -3198,7 +3204,7 @@ bool
|
||||
BControlLook::_RadioButtonAndCheckBoxMarkColor(const rgb_color& base,
|
||||
rgb_color& color, uint32 flags) const
|
||||
{
|
||||
if ((flags & (B_ACTIVATED | B_CLICKED)) == 0) {
|
||||
if ((flags & (B_ACTIVATED | B_PARTIALLY_ACTIVATED | B_CLICKED)) == 0) {
|
||||
// no mark to be drawn at all
|
||||
return false;
|
||||
}
|
||||
@@ -3212,12 +3218,15 @@ BControlLook::_RadioButtonAndCheckBoxMarkColor(const rgb_color& base,
|
||||
mix = 0.4;
|
||||
} else if ((flags & B_CLICKED) != 0) {
|
||||
if ((flags & B_ACTIVATED) != 0) {
|
||||
// loosing activation
|
||||
// losing activation
|
||||
mix = 0.7;
|
||||
} else {
|
||||
// becoming activated
|
||||
// becoming activated (or losing partial activation)
|
||||
mix = 0.3;
|
||||
}
|
||||
} else if ((flags & B_PARTIALLY_ACTIVATED) != 0) {
|
||||
// partially activated
|
||||
mix = 0.5;
|
||||
} else {
|
||||
// simply activated
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user