/* * Copyright 2007, Ingo Weinhold . * All rights reserved. Distributed under the terms of the MIT License. */ #include "RadioButton.h" #include #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); } }