* Pulled generic button code out of CheckBox into a new base class
AbstractButton. * Added RadioButton and RadioButtonGroup. * In the BBox test the border style can be switched now. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@21343 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -0,0 +1,201 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2007, Ingo Weinhold <[email protected]>.
|
||||||
|
* All rights reserved. Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "AbstractButton.h"
|
||||||
|
|
||||||
|
#include <View.h>
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark - AbstractButton
|
||||||
|
|
||||||
|
|
||||||
|
AbstractButton::AbstractButton(button_policy policy, BMessage* message,
|
||||||
|
BMessenger target)
|
||||||
|
: View(BRect(0, 0, 0, 0)),
|
||||||
|
BInvoker(message, target),
|
||||||
|
fPolicy(policy),
|
||||||
|
fSelected(false),
|
||||||
|
fPressed(false),
|
||||||
|
fPressedInBounds(false)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
AbstractButton::SetPolicy(button_policy policy)
|
||||||
|
{
|
||||||
|
fPolicy = policy;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
button_policy
|
||||||
|
AbstractButton::Policy() const
|
||||||
|
{
|
||||||
|
return fPolicy;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
AbstractButton::SetSelected(bool selected)
|
||||||
|
{
|
||||||
|
if (selected != fSelected) {
|
||||||
|
fSelected = selected;
|
||||||
|
Invalidate();
|
||||||
|
|
||||||
|
// check whether to notify the listeners depending on the button policy
|
||||||
|
bool notify = false;
|
||||||
|
switch (fPolicy) {
|
||||||
|
case BUTTON_POLICY_TOGGLE_ON_RELEASE:
|
||||||
|
case BUTTON_POLICY_SELECT_ON_RELEASE:
|
||||||
|
// always notify on selection changes
|
||||||
|
notify = true;
|
||||||
|
break;
|
||||||
|
case BUTTON_POLICY_INVOKE_ON_RELEASE:
|
||||||
|
// only notify when the user interaction has been finished
|
||||||
|
notify = !fPressed;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (notify) {
|
||||||
|
// notify synchronous listeners
|
||||||
|
_NotifyListeners();
|
||||||
|
|
||||||
|
// send the message
|
||||||
|
if (Message()) {
|
||||||
|
BMessage message(*Message());
|
||||||
|
message.AddBool("selected", IsSelected());
|
||||||
|
InvokeNotify(&message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
AbstractButton::IsSelected() const
|
||||||
|
{
|
||||||
|
return fSelected;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
AbstractButton::MouseDown(BPoint where, uint32 buttons, int32 modifiers)
|
||||||
|
{
|
||||||
|
if (fPressed)
|
||||||
|
return;
|
||||||
|
|
||||||
|
fPressed = true;
|
||||||
|
_PressedUpdate(where);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
AbstractButton::MouseUp(BPoint where, uint32 buttons, int32 modifiers)
|
||||||
|
{
|
||||||
|
if (!fPressed || (buttons & B_PRIMARY_MOUSE_BUTTON))
|
||||||
|
return;
|
||||||
|
|
||||||
|
_PressedUpdate(where);
|
||||||
|
fPressed = false;
|
||||||
|
if (fPressedInBounds) {
|
||||||
|
fPressedInBounds = false;
|
||||||
|
|
||||||
|
// update selected state according to policy
|
||||||
|
bool selected = fSelected;
|
||||||
|
switch (fPolicy) {
|
||||||
|
case BUTTON_POLICY_TOGGLE_ON_RELEASE:
|
||||||
|
selected = !fSelected;
|
||||||
|
break;
|
||||||
|
case BUTTON_POLICY_SELECT_ON_RELEASE:
|
||||||
|
selected = true;
|
||||||
|
break;
|
||||||
|
case BUTTON_POLICY_INVOKE_ON_RELEASE:
|
||||||
|
selected = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
SetSelected(selected);
|
||||||
|
}
|
||||||
|
Invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
AbstractButton::MouseMoved(BPoint where, uint32 buttons, int32 modifiers)
|
||||||
|
{
|
||||||
|
if (!fPressed)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_PressedUpdate(where);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
AbstractButton::AddListener(Listener* listener)
|
||||||
|
{
|
||||||
|
if (listener && !fListeners.HasItem(listener))
|
||||||
|
fListeners.AddItem(listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
AbstractButton::RemoveListener(Listener* listener)
|
||||||
|
{
|
||||||
|
if (listener)
|
||||||
|
fListeners.RemoveItem(listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
AbstractButton::IsPressed() const
|
||||||
|
{
|
||||||
|
return (fPressed && fPressedInBounds);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
AbstractButton::_PressedUpdate(BPoint where)
|
||||||
|
{
|
||||||
|
bool pressedInBounds = Bounds().Contains(where);
|
||||||
|
if (pressedInBounds == fPressedInBounds)
|
||||||
|
return;
|
||||||
|
|
||||||
|
fPressedInBounds = pressedInBounds;
|
||||||
|
|
||||||
|
// update the selected state according to the button policy
|
||||||
|
switch (fPolicy) {
|
||||||
|
case BUTTON_POLICY_TOGGLE_ON_RELEASE:
|
||||||
|
case BUTTON_POLICY_SELECT_ON_RELEASE:
|
||||||
|
// nothing to do
|
||||||
|
break;
|
||||||
|
case BUTTON_POLICY_INVOKE_ON_RELEASE:
|
||||||
|
SetSelected(fPressedInBounds);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
Invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
AbstractButton::_NotifyListeners()
|
||||||
|
{
|
||||||
|
if (!fListeners.IsEmpty()) {
|
||||||
|
BList listeners(fListeners);
|
||||||
|
for (int32 i = 0; Listener* listener = (Listener*)listeners.ItemAt(i);
|
||||||
|
i++) {
|
||||||
|
listener->SelectionChanged(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark - AbstractButton::Listener
|
||||||
|
|
||||||
|
|
||||||
|
AbstractButton::Listener::~Listener()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,74 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2007, Ingo Weinhold <[email protected]>.
|
||||||
|
* All rights reserved. Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
|
#ifndef WIDGET_LAYOUT_TEST_ABSTRACT_BUTTON_H
|
||||||
|
#define WIDGET_LAYOUT_TEST_ABSTRACT_BUTTON_H
|
||||||
|
|
||||||
|
|
||||||
|
#include <Invoker.h>
|
||||||
|
#include <List.h>
|
||||||
|
|
||||||
|
#include "View.h"
|
||||||
|
|
||||||
|
|
||||||
|
// button behavior policy
|
||||||
|
enum button_policy {
|
||||||
|
BUTTON_POLICY_TOGGLE_ON_RELEASE, // check box
|
||||||
|
BUTTON_POLICY_SELECT_ON_RELEASE, // radio button
|
||||||
|
BUTTON_POLICY_INVOKE_ON_RELEASE // button
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// AbstractButton
|
||||||
|
class AbstractButton : public View, public BInvoker {
|
||||||
|
public:
|
||||||
|
AbstractButton(button_policy policy,
|
||||||
|
BMessage* message = NULL,
|
||||||
|
BMessenger target = BMessenger());
|
||||||
|
|
||||||
|
void SetPolicy(button_policy policy);
|
||||||
|
button_policy Policy() const;
|
||||||
|
|
||||||
|
void SetSelected(bool selected);
|
||||||
|
bool IsSelected() const;
|
||||||
|
|
||||||
|
virtual void MouseDown(BPoint where, uint32 buttons,
|
||||||
|
int32 modifiers);
|
||||||
|
virtual void MouseUp(BPoint where, uint32 buttons,
|
||||||
|
int32 modifiers);
|
||||||
|
virtual void MouseMoved(BPoint where, uint32 buttons,
|
||||||
|
int32 modifiers);
|
||||||
|
|
||||||
|
public:
|
||||||
|
class Listener;
|
||||||
|
|
||||||
|
void AddListener(Listener* listener);
|
||||||
|
void RemoveListener(Listener* listener);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool IsPressed() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void _PressedUpdate(BPoint where);
|
||||||
|
void _NotifyListeners();
|
||||||
|
|
||||||
|
private:
|
||||||
|
button_policy fPolicy;
|
||||||
|
bool fSelected;
|
||||||
|
bool fPressed;
|
||||||
|
bool fPressedInBounds;
|
||||||
|
BList fListeners;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// synchronous listener interface
|
||||||
|
class AbstractButton::Listener {
|
||||||
|
public:
|
||||||
|
virtual ~Listener();
|
||||||
|
|
||||||
|
virtual void SelectionChanged(AbstractButton* button) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif // WIDGET_LAYOUT_TEST_ABSTRACT_BUTTON_H
|
||||||
@@ -10,11 +10,34 @@
|
|||||||
#include <Box.h>
|
#include <Box.h>
|
||||||
#include <Message.h>
|
#include <Message.h>
|
||||||
|
|
||||||
|
#include "GroupView.h"
|
||||||
|
#include "RadioButton.h"
|
||||||
|
|
||||||
|
|
||||||
|
// messages
|
||||||
|
enum {
|
||||||
|
MSG_BORDER_STYLE_CHANGED = 'bstc',
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// BorderStyleRadioButton
|
||||||
|
class BoxTest::BorderStyleRadioButton : public LabeledRadioButton {
|
||||||
|
public:
|
||||||
|
BorderStyleRadioButton(const char* label, border_style style)
|
||||||
|
: LabeledRadioButton(label),
|
||||||
|
fBorderStyle(style)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
border_style fBorderStyle;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
// constructor
|
// constructor
|
||||||
BoxTest::BoxTest()
|
BoxTest::BoxTest()
|
||||||
: Test("Box", NULL),
|
: Test("Box", NULL),
|
||||||
fBox(new BBox(BRect(0, 0, 9, 9), "test box", B_FOLLOW_NONE))
|
fBox(new BBox(BRect(0, 0, 9, 9), "test box", B_FOLLOW_NONE)),
|
||||||
|
fBorderStyleRadioGroup(NULL)
|
||||||
// TODO: Layout-friendly constructor
|
// TODO: Layout-friendly constructor
|
||||||
{
|
{
|
||||||
SetView(fBox);
|
SetView(fBox);
|
||||||
@@ -24,6 +47,7 @@ BoxTest::BoxTest()
|
|||||||
// destructor
|
// destructor
|
||||||
BoxTest::~BoxTest()
|
BoxTest::~BoxTest()
|
||||||
{
|
{
|
||||||
|
delete fBorderStyleRadioGroup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -31,26 +55,41 @@ BoxTest::~BoxTest()
|
|||||||
void
|
void
|
||||||
BoxTest::ActivateTest(View* controls)
|
BoxTest::ActivateTest(View* controls)
|
||||||
{
|
{
|
||||||
/* GroupView* group = new GroupView(B_VERTICAL);
|
// BBox sets its background color to that of its parent in
|
||||||
|
// AttachedToWindow(). Override.
|
||||||
|
rgb_color background = ui_color(B_PANEL_BACKGROUND_COLOR);
|
||||||
|
fBox->SetViewColor(background);
|
||||||
|
fBox->SetLowColor(background);
|
||||||
|
|
||||||
|
GroupView* group = new GroupView(B_VERTICAL);
|
||||||
group->SetFrame(controls->Bounds());
|
group->SetFrame(controls->Bounds());
|
||||||
group->SetSpacing(0, 8);
|
group->SetSpacing(0, 8);
|
||||||
controls->AddChild(group);
|
controls->AddChild(group);
|
||||||
|
|
||||||
// long button text
|
// the radio button group for selecting the border style
|
||||||
fLongTextCheckBox = new LabeledCheckBox("Long Button Text",
|
fBorderStyleRadioGroup = new RadioButtonGroup(
|
||||||
new BMessage(MSG_CHANGE_BUTTON_TEXT), this);
|
new BMessage(MSG_BORDER_STYLE_CHANGED), this);
|
||||||
group->AddChild(fLongTextCheckBox);
|
|
||||||
|
|
||||||
// big font
|
// no border
|
||||||
fBigFontCheckBox = new LabeledCheckBox("Big Button Font",
|
LabeledRadioButton* button = new BorderStyleRadioButton("no border",
|
||||||
new BMessage(MSG_CHANGE_BUTTON_FONT), this);
|
B_NO_BORDER);
|
||||||
group->AddChild(fBigFontCheckBox);
|
group->AddChild(button);
|
||||||
|
fBorderStyleRadioGroup->AddButton(button->GetRadioButton());
|
||||||
|
|
||||||
|
// plain border
|
||||||
|
button = new BorderStyleRadioButton("plain border", B_PLAIN_BORDER);
|
||||||
|
group->AddChild(button);
|
||||||
|
fBorderStyleRadioGroup->AddButton(button->GetRadioButton());
|
||||||
|
|
||||||
|
// fancy border
|
||||||
|
button = new BorderStyleRadioButton("fancy border", B_FANCY_BORDER);
|
||||||
|
group->AddChild(button);
|
||||||
|
fBorderStyleRadioGroup->AddButton(button->GetRadioButton());
|
||||||
|
|
||||||
|
// default to no border
|
||||||
|
fBorderStyleRadioGroup->SelectButton(0L);
|
||||||
|
|
||||||
group->AddChild(new Glue());
|
group->AddChild(new Glue());
|
||||||
|
|
||||||
_SetButtonText(false);
|
|
||||||
_SetButtonFont(false);
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -59,3 +98,37 @@ void
|
|||||||
BoxTest::DectivateTest()
|
BoxTest::DectivateTest()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// MessageReceived
|
||||||
|
void
|
||||||
|
BoxTest::MessageReceived(BMessage* message)
|
||||||
|
{
|
||||||
|
switch (message->what) {
|
||||||
|
case MSG_BORDER_STYLE_CHANGED:
|
||||||
|
_UpdateBorderStyle();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
Test::MessageReceived(message);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// _UpdateBorderStyle
|
||||||
|
void
|
||||||
|
BoxTest::_UpdateBorderStyle()
|
||||||
|
{
|
||||||
|
if (fBorderStyleRadioGroup) {
|
||||||
|
// We need to get the parent of the actually selected button, since
|
||||||
|
// that is the labeled radio button we've derived our
|
||||||
|
// BorderStyleRadioButton from.
|
||||||
|
AbstractButton* selectedButton
|
||||||
|
= fBorderStyleRadioGroup->SelectedButton();
|
||||||
|
View* parent = (selectedButton ? selectedButton->Parent() : NULL);
|
||||||
|
BorderStyleRadioButton* button = dynamic_cast<BorderStyleRadioButton*>(
|
||||||
|
parent);
|
||||||
|
if (button)
|
||||||
|
fBox->SetBorder(button->fBorderStyle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
|
|
||||||
class BBox;
|
class BBox;
|
||||||
class View;
|
class RadioButtonGroup;
|
||||||
|
|
||||||
|
|
||||||
class BoxTest : public Test {
|
class BoxTest : public Test {
|
||||||
@@ -21,8 +21,16 @@ public:
|
|||||||
virtual void ActivateTest(View* controls);
|
virtual void ActivateTest(View* controls);
|
||||||
virtual void DectivateTest();
|
virtual void DectivateTest();
|
||||||
|
|
||||||
|
virtual void MessageReceived(BMessage* message);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void _UpdateBorderStyle();
|
||||||
|
|
||||||
|
private:
|
||||||
|
class BorderStyleRadioButton;
|
||||||
|
|
||||||
BBox* fBox;
|
BBox* fBox;
|
||||||
|
RadioButtonGroup* fBorderStyleRadioGroup;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -14,39 +14,12 @@
|
|||||||
|
|
||||||
|
|
||||||
CheckBox::CheckBox(BMessage* message, BMessenger target)
|
CheckBox::CheckBox(BMessage* message, BMessenger target)
|
||||||
: View(BRect(0, 0, 12, 12)),
|
: AbstractButton(BUTTON_POLICY_TOGGLE_ON_RELEASE, message, target)
|
||||||
BInvoker(message, target),
|
|
||||||
fSelected(false),
|
|
||||||
fPressed(false)
|
|
||||||
{
|
{
|
||||||
SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
|
SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
CheckBox::SetSelected(bool selected)
|
|
||||||
{
|
|
||||||
if (selected != fSelected) {
|
|
||||||
fSelected = selected;
|
|
||||||
Invalidate();
|
|
||||||
|
|
||||||
// send the message
|
|
||||||
if (Message()) {
|
|
||||||
BMessage message(*Message());
|
|
||||||
message.AddBool("selected", IsSelected());
|
|
||||||
InvokeNotify(&message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool
|
|
||||||
CheckBox::IsSelected() const
|
|
||||||
{
|
|
||||||
return fSelected;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
BSize
|
BSize
|
||||||
CheckBox::MinSize()
|
CheckBox::MinSize()
|
||||||
{
|
{
|
||||||
@@ -66,14 +39,14 @@ CheckBox::Draw(BView* container, BRect updateRect)
|
|||||||
{
|
{
|
||||||
BRect rect(Bounds());
|
BRect rect(Bounds());
|
||||||
|
|
||||||
if (fPressed)
|
if (IsPressed())
|
||||||
container->SetHighColor((rgb_color){ 120, 0, 0, 255 });
|
container->SetHighColor((rgb_color){ 120, 0, 0, 255 });
|
||||||
else
|
else
|
||||||
container->SetHighColor((rgb_color){ 0, 0, 0, 255 });
|
container->SetHighColor((rgb_color){ 0, 0, 0, 255 });
|
||||||
|
|
||||||
container->StrokeRect(rect);
|
container->StrokeRect(rect);
|
||||||
|
|
||||||
if (fPressed ? fPressedSelected : fSelected) {
|
if (IsSelected()) {
|
||||||
rect.InsetBy(2, 2);
|
rect.InsetBy(2, 2);
|
||||||
container->StrokeLine(rect.LeftTop(), rect.RightBottom());
|
container->StrokeLine(rect.LeftTop(), rect.RightBottom());
|
||||||
container->StrokeLine(rect.RightTop(), rect.LeftBottom());
|
container->StrokeLine(rect.RightTop(), rect.LeftBottom());
|
||||||
@@ -81,52 +54,6 @@ CheckBox::Draw(BView* container, BRect updateRect)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
CheckBox::MouseDown(BPoint where, uint32 buttons, int32 modifiers)
|
|
||||||
{
|
|
||||||
if (fPressed)
|
|
||||||
return;
|
|
||||||
|
|
||||||
fPressed = true;
|
|
||||||
fPressedSelected = fSelected;
|
|
||||||
_PressedUpdate(where);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
CheckBox::MouseUp(BPoint where, uint32 buttons, int32 modifiers)
|
|
||||||
{
|
|
||||||
if (!fPressed || (buttons & B_PRIMARY_MOUSE_BUTTON))
|
|
||||||
return;
|
|
||||||
|
|
||||||
_PressedUpdate(where);
|
|
||||||
fPressed = false;
|
|
||||||
SetSelected(fPressedSelected);
|
|
||||||
Invalidate();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
CheckBox::MouseMoved(BPoint where, uint32 buttons, int32 modifiers)
|
|
||||||
{
|
|
||||||
if (!fPressed)
|
|
||||||
return;
|
|
||||||
|
|
||||||
_PressedUpdate(where);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
CheckBox::_PressedUpdate(BPoint where)
|
|
||||||
{
|
|
||||||
bool pressedSelected = Bounds().Contains(where) ^ fSelected;
|
|
||||||
if (pressedSelected != fPressedSelected) {
|
|
||||||
fPressedSelected = pressedSelected;
|
|
||||||
Invalidate();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark - LabeledCheckBox
|
// #pragma mark - LabeledCheckBox
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -8,37 +8,20 @@
|
|||||||
|
|
||||||
#include <Invoker.h>
|
#include <Invoker.h>
|
||||||
|
|
||||||
|
#include "AbstractButton.h"
|
||||||
#include "GroupView.h"
|
#include "GroupView.h"
|
||||||
|
|
||||||
|
|
||||||
// CheckBox
|
// CheckBox
|
||||||
class CheckBox : public View, public BInvoker {
|
class CheckBox : public AbstractButton {
|
||||||
public:
|
public:
|
||||||
CheckBox(BMessage* message = NULL,
|
CheckBox(BMessage* message = NULL,
|
||||||
BMessenger target = BMessenger());
|
BMessenger target = BMessenger());
|
||||||
|
|
||||||
void SetSelected(bool selected);
|
|
||||||
bool IsSelected() const;
|
|
||||||
|
|
||||||
virtual BSize MinSize();
|
virtual BSize MinSize();
|
||||||
virtual BSize MaxSize();
|
virtual BSize MaxSize();
|
||||||
|
|
||||||
virtual void Draw(BView* container, BRect updateRect);
|
virtual void Draw(BView* container, BRect updateRect);
|
||||||
|
|
||||||
virtual void MouseDown(BPoint where, uint32 buttons,
|
|
||||||
int32 modifiers);
|
|
||||||
virtual void MouseUp(BPoint where, uint32 buttons,
|
|
||||||
int32 modifiers);
|
|
||||||
virtual void MouseMoved(BPoint where, uint32 buttons,
|
|
||||||
int32 modifiers);
|
|
||||||
|
|
||||||
private:
|
|
||||||
void _PressedUpdate(BPoint where);
|
|
||||||
|
|
||||||
private:
|
|
||||||
bool fSelected;
|
|
||||||
bool fPressed;
|
|
||||||
bool fPressedSelected;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -5,10 +5,12 @@ SetSubDirSupportedPlatforms haiku libbe_test ;
|
|||||||
SimpleTest WidgetLayoutTest :
|
SimpleTest WidgetLayoutTest :
|
||||||
WidgetLayoutTest.cpp
|
WidgetLayoutTest.cpp
|
||||||
|
|
||||||
|
AbstractButton.cpp
|
||||||
BoxTest.cpp
|
BoxTest.cpp
|
||||||
ButtonTest.cpp
|
ButtonTest.cpp
|
||||||
CheckBox.cpp
|
CheckBox.cpp
|
||||||
GroupView.cpp
|
GroupView.cpp
|
||||||
|
RadioButton.cpp
|
||||||
StringView.cpp
|
StringView.cpp
|
||||||
Test.cpp
|
Test.cpp
|
||||||
TwoDimensionalSliderView.cpp
|
TwoDimensionalSliderView.cpp
|
||||||
|
|||||||
@@ -0,0 +1,246 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2007, Ingo Weinhold <[email protected]>.
|
||||||
|
* All rights reserved. Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "RadioButton.h"
|
||||||
|
|
||||||
|
#include <View.h>
|
||||||
|
|
||||||
|
#include "StringView.h"
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark - RadioButton
|
||||||
|
|
||||||
|
|
||||||
|
RadioButton::RadioButton(BMessage* message, BMessenger target)
|
||||||
|
: AbstractButton(BUTTON_POLICY_SELECT_ON_RELEASE, message, target)
|
||||||
|
{
|
||||||
|
SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BSize
|
||||||
|
RadioButton::MinSize()
|
||||||
|
{
|
||||||
|
return BSize(12, 12);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BSize
|
||||||
|
RadioButton::MaxSize()
|
||||||
|
{
|
||||||
|
return MinSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
RadioButton::Draw(BView* container, BRect updateRect)
|
||||||
|
{
|
||||||
|
BRect rect(Bounds());
|
||||||
|
|
||||||
|
if (IsPressed())
|
||||||
|
container->SetHighColor((rgb_color){ 120, 0, 0, 255 });
|
||||||
|
else
|
||||||
|
container->SetHighColor((rgb_color){ 0, 0, 0, 255 });
|
||||||
|
|
||||||
|
container->StrokeRect(rect);
|
||||||
|
|
||||||
|
if (IsSelected()) {
|
||||||
|
rect.InsetBy(4, 4);
|
||||||
|
container->FillRect(rect);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark - LabeledRadioButton
|
||||||
|
|
||||||
|
|
||||||
|
LabeledRadioButton::LabeledRadioButton(const char* label, BMessage* message,
|
||||||
|
BMessenger target)
|
||||||
|
: GroupView(B_HORIZONTAL),
|
||||||
|
fRadioButton(new RadioButton(message, target))
|
||||||
|
{
|
||||||
|
SetSpacing(8, 0);
|
||||||
|
|
||||||
|
AddChild(fRadioButton);
|
||||||
|
if (label)
|
||||||
|
AddChild(new StringView(label));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
LabeledRadioButton::SetTarget(BMessenger messenger)
|
||||||
|
{
|
||||||
|
fRadioButton->SetTarget(messenger);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
LabeledRadioButton::SetSelected(bool selected)
|
||||||
|
{
|
||||||
|
fRadioButton->SetSelected(selected);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
LabeledRadioButton::IsSelected() const
|
||||||
|
{
|
||||||
|
return fRadioButton->IsSelected();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark - RadioButtonGroup
|
||||||
|
|
||||||
|
|
||||||
|
RadioButtonGroup::RadioButtonGroup(BMessage* message, BMessenger target)
|
||||||
|
: BInvoker(message, target),
|
||||||
|
fButtons(10),
|
||||||
|
fSelected(NULL)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
RadioButtonGroup::~RadioButtonGroup()
|
||||||
|
{
|
||||||
|
// remove as listener from buttons
|
||||||
|
for (int32 i = 0; AbstractButton* button = ButtonAt(i); i++)
|
||||||
|
button->RemoveListener(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
RadioButtonGroup::AddButton(AbstractButton* button)
|
||||||
|
{
|
||||||
|
if (!button || fButtons.HasItem(button))
|
||||||
|
return;
|
||||||
|
|
||||||
|
// force radio button policy
|
||||||
|
button->SetPolicy(BUTTON_POLICY_SELECT_ON_RELEASE);
|
||||||
|
|
||||||
|
// deselect the button, if we do already have a selected one
|
||||||
|
if (fSelected)
|
||||||
|
button->SetSelected(false);
|
||||||
|
|
||||||
|
// add ourselves as listener
|
||||||
|
button->AddListener(this);
|
||||||
|
|
||||||
|
// add the button to our list
|
||||||
|
fButtons.AddItem(button);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
RadioButtonGroup::RemoveButton(AbstractButton* button)
|
||||||
|
{
|
||||||
|
return RemoveButton(IndexOfButton(button));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
AbstractButton*
|
||||||
|
RadioButtonGroup::RemoveButton(int32 index)
|
||||||
|
{
|
||||||
|
// remove the button from our list
|
||||||
|
AbstractButton* button = (AbstractButton*)fButtons.RemoveItem(index);
|
||||||
|
if (!button)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
// remove ourselves as listener
|
||||||
|
button->RemoveListener(this);
|
||||||
|
|
||||||
|
// if it was the selected one, we don't have a selection anymore
|
||||||
|
if (button == fSelected) {
|
||||||
|
fSelected = NULL;
|
||||||
|
_SelectionChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
return button;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int32
|
||||||
|
RadioButtonGroup::CountButtons() const
|
||||||
|
{
|
||||||
|
return fButtons.CountItems();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
AbstractButton*
|
||||||
|
RadioButtonGroup::ButtonAt(int32 index) const
|
||||||
|
{
|
||||||
|
return (AbstractButton*)fButtons.ItemAt(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int32
|
||||||
|
RadioButtonGroup::IndexOfButton(AbstractButton* button) const
|
||||||
|
{
|
||||||
|
return fButtons.IndexOf(button);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
RadioButtonGroup::SelectButton(AbstractButton* button)
|
||||||
|
{
|
||||||
|
if (button && fButtons.HasItem(button))
|
||||||
|
button->SetSelected(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
RadioButtonGroup::SelectButton(int32 index)
|
||||||
|
{
|
||||||
|
if (AbstractButton* button = ButtonAt(index))
|
||||||
|
button->SetSelected(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
AbstractButton*
|
||||||
|
RadioButtonGroup::SelectedButton() const
|
||||||
|
{
|
||||||
|
return fSelected;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int32
|
||||||
|
RadioButtonGroup::SelectedIndex() const
|
||||||
|
{
|
||||||
|
return (fSelected ? IndexOfButton(fSelected) : -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
RadioButtonGroup::SelectionChanged(AbstractButton* button)
|
||||||
|
{
|
||||||
|
// We're only interested in a notification when one of our buttons that
|
||||||
|
// has not been selected one before has become selected.
|
||||||
|
if (!button || !fButtons.HasItem(button) || !button->IsSelected()
|
||||||
|
|| button == fSelected) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// set the new selection
|
||||||
|
AbstractButton* oldSelected = fSelected;
|
||||||
|
fSelected = button;
|
||||||
|
|
||||||
|
// deselect the old selected button
|
||||||
|
if (oldSelected)
|
||||||
|
oldSelected->SetSelected(false);
|
||||||
|
|
||||||
|
// send out notifications
|
||||||
|
_SelectionChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
RadioButtonGroup::_SelectionChanged()
|
||||||
|
{
|
||||||
|
// send the message
|
||||||
|
if (Message()) {
|
||||||
|
BMessage message(*Message());
|
||||||
|
message.AddPointer("button group", this);
|
||||||
|
message.AddPointer("selected button", fSelected);
|
||||||
|
message.AddInt32("selected index", SelectedIndex());
|
||||||
|
InvokeNotify(&message);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,79 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2007, Ingo Weinhold <[email protected]>.
|
||||||
|
* All rights reserved. Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
|
#ifndef WIDGET_LAYOUT_TEST_CHECK_BOX_H
|
||||||
|
#define WIDGET_LAYOUT_TEST_CHECK_BOX_H
|
||||||
|
|
||||||
|
|
||||||
|
#include <Invoker.h>
|
||||||
|
#include <List.h>
|
||||||
|
|
||||||
|
#include "AbstractButton.h"
|
||||||
|
#include "GroupView.h"
|
||||||
|
|
||||||
|
|
||||||
|
// RadioButton
|
||||||
|
class RadioButton : public AbstractButton {
|
||||||
|
public:
|
||||||
|
RadioButton(BMessage* message = NULL,
|
||||||
|
BMessenger target = BMessenger());
|
||||||
|
|
||||||
|
virtual BSize MinSize();
|
||||||
|
virtual BSize MaxSize();
|
||||||
|
|
||||||
|
virtual void Draw(BView* container, BRect updateRect);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// LabeledRadioButton
|
||||||
|
class LabeledRadioButton : public GroupView {
|
||||||
|
public:
|
||||||
|
LabeledRadioButton(const char* label,
|
||||||
|
BMessage* message = NULL,
|
||||||
|
BMessenger target = BMessenger());
|
||||||
|
|
||||||
|
RadioButton* GetRadioButton() const { return fRadioButton; }
|
||||||
|
|
||||||
|
void SetTarget(BMessenger messenger);
|
||||||
|
|
||||||
|
void SetSelected(bool selected);
|
||||||
|
bool IsSelected() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
RadioButton* fRadioButton;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// RadioButtonGroup
|
||||||
|
class RadioButtonGroup : public BInvoker, private AbstractButton::Listener {
|
||||||
|
public:
|
||||||
|
RadioButtonGroup(BMessage* message = NULL,
|
||||||
|
BMessenger target = BMessenger());
|
||||||
|
virtual ~RadioButtonGroup();
|
||||||
|
|
||||||
|
void AddButton(AbstractButton* button);
|
||||||
|
bool RemoveButton(AbstractButton* button);
|
||||||
|
AbstractButton* RemoveButton(int32 index);
|
||||||
|
|
||||||
|
int32 CountButtons() const;
|
||||||
|
AbstractButton* ButtonAt(int32 index) const;
|
||||||
|
int32 IndexOfButton(AbstractButton* button) const;
|
||||||
|
|
||||||
|
void SelectButton(AbstractButton* button);
|
||||||
|
void SelectButton(int32 index);
|
||||||
|
AbstractButton* SelectedButton() const;
|
||||||
|
int32 SelectedIndex() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
virtual void SelectionChanged(AbstractButton* button);
|
||||||
|
|
||||||
|
void _SelectionChanged();
|
||||||
|
|
||||||
|
private:
|
||||||
|
BList fButtons;
|
||||||
|
AbstractButton* fSelected;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif // WIDGET_LAYOUT_TEST_CHECK_BOX_H
|
||||||
Reference in New Issue
Block a user