#include <GroupLayout.h>
#include <MenuField.h>
#include <MenuItem.h>
#include <OptionPopUp.h>
#include <PopUpMenu.h>
#include <stdio.h>
const float kLabelSpace = 8.0;
const float kWidthModifier = 25.0;
const float kHeightModifier = 10.0;
BOptionPopUp::BOptionPopUp(BRect frame, const char* name, const char* label,
BMessage* message, uint32 resize, uint32 flags)
: BOptionControl(frame, name, label, message, resize, flags)
{
BPopUpMenu* popUp = new BPopUpMenu(label, true, true);
fMenuField = new BMenuField(Bounds(), "_menu", label, popUp);
AddChild(fMenuField);
}
BOptionPopUp::BOptionPopUp(BRect frame, const char* name, const char* label,
BMessage* message, bool fixed, uint32 resize, uint32 flags)
: BOptionControl(frame, name, label, message, resize, flags)
{
BPopUpMenu* popUp = new BPopUpMenu(label, true, true);
fMenuField = new BMenuField(Bounds(), "_menu", label, popUp, fixed);
AddChild(fMenuField);
}
BOptionPopUp::BOptionPopUp(const char* name, const char* label,
BMessage* message, uint32 flags)
: BOptionControl(name, label, message, flags)
{
SetLayout(new BGroupLayout(B_HORIZONTAL));
BPopUpMenu* popUp = new BPopUpMenu(label, true, true);
fMenuField = new BMenuField("_menu", label, popUp);
AddChild(fMenuField);
}
BOptionPopUp::~BOptionPopUp()
{
}
BMenuField*
BOptionPopUp::MenuField()
{
return fMenuField;
}
bool
BOptionPopUp::GetOptionAt(int32 index, const char** outName, int32* outValue)
{
bool result = false;
BMenu* menu = fMenuField->Menu();
if (menu != NULL) {
BMenuItem* item = menu->ItemAt(index);
if (item != NULL) {
if (outName != NULL)
*outName = item->Label();
if (outValue != NULL && item->Message() != NULL)
item->Message()->FindInt32("be:value", outValue);
result = true;
}
}
return result;
}
void
BOptionPopUp::RemoveOptionAt(int32 index)
{
BMenu* menu = fMenuField->Menu();
if (menu != NULL)
delete menu->RemoveItem(index);
}
int32
BOptionPopUp::CountOptions() const
{
BMenu* menu = fMenuField->Menu();
return (menu != NULL) ? menu->CountItems() : 0;
}
status_t
BOptionPopUp::AddOptionAt(const char* name, int32 value, int32 index)
{
BMenu* menu = fMenuField->Menu();
if (menu == NULL)
return B_ERROR;
int32 numItems = menu->CountItems();
if (index < 0 || index > numItems)
return B_BAD_VALUE;
BMessage* message = MakeValueMessage(value);
if (message == NULL)
return B_NO_MEMORY;
BMenuItem* newItem = new BMenuItem(name, message);
if (newItem == NULL) {
delete message;
return B_NO_MEMORY;
}
if (!menu->AddItem(newItem, index)) {
delete newItem;
return B_NO_MEMORY;
}
newItem->SetTarget(this);
if (numItems == 0)
SetValue(value);
return B_OK;
}
void
BOptionPopUp::AllAttached()
{
BOptionControl::AllAttached();
}
void
BOptionPopUp::AttachedToWindow()
{
BOptionControl::AttachedToWindow();
BMenu* menu = fMenuField->Menu();
if (menu != NULL) {
float labelWidth = fMenuField->StringWidth(fMenuField->Label());
if (labelWidth > 0.f)
labelWidth += kLabelSpace;
fMenuField->SetDivider(labelWidth);
menu->SetTargetForItems(this);
}
}
void
BOptionPopUp::MessageReceived(BMessage* message)
{
BOptionControl::MessageReceived(message);
}
void
BOptionPopUp::SetLabel(const char* text)
{
BControl::SetLabel(text);
fMenuField->SetLabel(text);
float newWidth = fMenuField->StringWidth(fMenuField->Label());
if (newWidth > 0.f)
newWidth += kLabelSpace;
fMenuField->SetDivider(newWidth);
}
void
BOptionPopUp::SetValue(int32 value)
{
BControl::SetValue(value);
BMenu* menu = fMenuField->Menu();
if (menu == NULL)
return;
int32 numItems = menu->CountItems();
for (int32 i = 0; i < numItems; i++) {
BMenuItem* item = menu->ItemAt(i);
if (item && item->Message()) {
int32 itemValue;
item->Message()->FindInt32("be:value", &itemValue);
if (itemValue == value) {
item->SetMarked(true);
break;
}
}
}
}
void
BOptionPopUp::SetEnabled(bool state)
{
BOptionControl::SetEnabled(state);
if (fMenuField)
fMenuField->SetEnabled(state);
}
void
BOptionPopUp::GetPreferredSize(float* _width, float* _height)
{
float width, height;
fMenuField->GetPreferredSize(&width, &height);
if (_height != NULL) {
font_height fontHeight;
GetFontHeight(&fontHeight);
*_height = max_c(height, fontHeight.ascent + fontHeight.descent
+ fontHeight.leading + kHeightModifier);
}
if (_width != NULL) {
width += fMenuField->StringWidth(BControl::Label())
+ kLabelSpace + kWidthModifier;
*_width = width;
}
}
void
BOptionPopUp::ResizeToPreferred()
{
float width, height;
GetPreferredSize(&width, &height);
ResizeTo(width, height);
float newWidth = fMenuField->StringWidth(BControl::Label());
fMenuField->SetDivider(newWidth + kLabelSpace);
}
int32
BOptionPopUp::SelectedOption(const char** outName, int32* outValue) const
{
BMenu* menu = fMenuField->Menu();
if (menu == NULL)
return B_ERROR;
BMenuItem* marked = menu->FindMarked();
if (marked == NULL)
return -1;
if (outName != NULL)
*outName = marked->Label();
if (outValue != NULL)
marked->Message()->FindInt32("be:value", outValue);
return menu->IndexOf(marked);
}
BOptionPopUp::BOptionPopUp()
:
BOptionControl(BRect(), "", "", NULL)
{
}
BOptionPopUp::BOptionPopUp(const BOptionPopUp& clone)
:
BOptionControl(clone.Frame(), "", "", clone.Message())
{
}
BOptionPopUp &
BOptionPopUp::operator=(const BOptionPopUp& clone)
{
return *this;
}
status_t BOptionPopUp::_Reserved_OptionControl_0(void *, ...) { return B_ERROR; }
status_t BOptionPopUp::_Reserved_OptionControl_1(void *, ...) { return B_ERROR; }
status_t BOptionPopUp::_Reserved_OptionControl_2(void *, ...) { return B_ERROR; }
status_t BOptionPopUp::_Reserved_OptionControl_3(void *, ...) { return B_ERROR; }
status_t BOptionPopUp::_Reserved_OptionPopUp_0(void *, ...) { return B_ERROR; }
status_t BOptionPopUp::_Reserved_OptionPopUp_1(void *, ...) { return B_ERROR; }
status_t BOptionPopUp::_Reserved_OptionPopUp_2(void *, ...) { return B_ERROR; }
status_t BOptionPopUp::_Reserved_OptionPopUp_3(void *, ...) { return B_ERROR; }
status_t BOptionPopUp::_Reserved_OptionPopUp_4(void *, ...) { return B_ERROR; }
status_t BOptionPopUp::_Reserved_OptionPopUp_5(void *, ...) { return B_ERROR; }
status_t BOptionPopUp::_Reserved_OptionPopUp_6(void *, ...) { return B_ERROR; }
status_t BOptionPopUp::_Reserved_OptionPopUp_7(void *, ...) { return B_ERROR; }