15ac57aebSStephan Aßmus/*
243f8c614SStephan Aßmus * Copyright 2001-2008, Haiku, Inc. All rights reserved.
35ac57aebSStephan Aßmus * Distributed under the terms of the MIT license.
45ac57aebSStephan Aßmus *
55ac57aebSStephan Aßmus * Authors:
65ac57aebSStephan Aßmus *		Marc Flerackers (mflerackers@androme.be)
75ac57aebSStephan Aßmus *		Stephan A��mus <superstippi@gmx.de>
88643b098SAxel Dörfler */
98643b098SAxel Dörfler
1040fc37b0SAxel Dörfler
119ecf9d1cSIngo Weinhold#include <RadioButton.h>
125ac57aebSStephan Aßmus
135e815cf3SIngo Weinhold#include <algorithm>
145e815cf3SIngo Weinhold
15b29d84a8SJohn Scipione#include <Box.h>
162f86ba45SStephan Aßmus#include <ControlLook.h>
1717408188SJérôme Duval#include <Debug.h>
189ecf9d1cSIngo Weinhold#include <LayoutUtils.h>
198053a364SMarc Flerackers#include <Window.h>
20ac6f7aa8SMarc Flerackers
2139fbf550SOliver Tappe#include <binary_compatibility/Interface.h>
2239fbf550SOliver Tappe
23ac6f7aa8SMarc Flerackers
2443f8c614SStephan AßmusBRadioButton::BRadioButton(BRect frame, const char* name, const char* label,
25b29d84a8SJohn Scipione	BMessage* message, uint32 resizingMode, uint32 flags)
26b29d84a8SJohn Scipione	:
27b29d84a8SJohn Scipione	BControl(frame, name, label, message, resizingMode, flags | B_FRAME_EVENTS),
28b29d84a8SJohn Scipione	fOutlined(false)
29ac6f7aa8SMarc Flerackers{
3043f8c614SStephan Aßmus	// Resize to minimum height if needed for BeOS compatibility
3143f8c614SStephan Aßmus	float minHeight;
3243f8c614SStephan Aßmus	GetPreferredSize(NULL, &minHeight);
338053a364SMarc Flerackers	if (Bounds().Height() < minHeight)
348053a364SMarc Flerackers		ResizeTo(Bounds().Width(), minHeight);
35ac6f7aa8SMarc Flerackers}
365ac57aebSStephan Aßmus
375ac57aebSStephan Aßmus
3843f8c614SStephan AßmusBRadioButton::BRadioButton(const char* name, const char* label,
39b29d84a8SJohn Scipione	BMessage* message, uint32 flags)
40b29d84a8SJohn Scipione	:
41b29d84a8SJohn Scipione	BControl(name, label, message, flags | B_FRAME_EVENTS),
42b29d84a8SJohn Scipione	fOutlined(false)
439ecf9d1cSIngo Weinhold{
449ecf9d1cSIngo Weinhold}
459ecf9d1cSIngo Weinhold
469ecf9d1cSIngo Weinhold
4743f8c614SStephan AßmusBRadioButton::BRadioButton(const char* label, BMessage* message)
48b29d84a8SJohn Scipione	:
49b29d84a8SJohn Scipione	BControl(NULL, label, message, B_WILL_DRAW | B_NAVIGABLE | B_FRAME_EVENTS),
50b29d84a8SJohn Scipione	fOutlined(false)
519ecf9d1cSIngo Weinhold{
529ecf9d1cSIngo Weinhold}
539ecf9d1cSIngo Weinhold
549ecf9d1cSIngo Weinhold
55b29d84a8SJohn ScipioneBRadioButton::BRadioButton(BMessage* data)
56b29d84a8SJohn Scipione	:
57b29d84a8SJohn Scipione	BControl(data),
58b29d84a8SJohn Scipione	fOutlined(false)
59ac6f7aa8SMarc Flerackers{
60ac6f7aa8SMarc Flerackers}
615ac57aebSStephan Aßmus
625ac57aebSStephan Aßmus
63ac6f7aa8SMarc FlerackersBRadioButton::~BRadioButton()
64ac6f7aa8SMarc Flerackers{
65ac6f7aa8SMarc Flerackers}
665ac57aebSStephan Aßmus
675ac57aebSStephan Aßmus
685ac57aebSStephan AßmusBArchivable*
69b29d84a8SJohn ScipioneBRadioButton::Instantiate(BMessage* data)
70ac6f7aa8SMarc Flerackers{
71b29d84a8SJohn Scipione	if (validate_instantiation(data, "BRadioButton"))
72b29d84a8SJohn Scipione		return new BRadioButton(data);
7340fc37b0SAxel Dörfler
7440fc37b0SAxel Dörfler	return NULL;
75ac6f7aa8SMarc Flerackers}
765ac57aebSStephan Aßmus
775ac57aebSStephan Aßmus
785ac57aebSStephan Aßmusstatus_t
79b29d84a8SJohn ScipioneBRadioButton::Archive(BMessage* data, bool deep) const
80ac6f7aa8SMarc Flerackers{
81b29d84a8SJohn Scipione	return BControl::Archive(data, deep);
82ac6f7aa8SMarc Flerackers}
83c7694b4aSStephan Aßmus
84ac6f7aa8SMarc Flerackers
855ac57aebSStephan Aßmusvoid
865ac57aebSStephan AßmusBRadioButton::Draw(BRect updateRect)
875ac57aebSStephan Aßmus{
88c7694b4aSStephan Aßmus	// its size depends on the text height
8940fc37b0SAxel Dörfler	font_height fontHeight;
9040fc37b0SAxel Dörfler	GetFontHeight(&fontHeight);
912f86ba45SStephan Aßmus
9236e15662SIngo Weinhold	rgb_color base = ui_color(B_PANEL_BACKGROUND_COLOR);
932f86ba45SStephan Aßmus
9436e15662SIngo Weinhold	uint32 flags = be_control_look->Flags(this);
9536e15662SIngo Weinhold	if (fOutlined)
9636e15662SIngo Weinhold		flags |= BControlLook::B_CLICKED;
972f86ba45SStephan Aßmus
9836e15662SIngo Weinhold	BRect knobRect(_KnobFrame(fontHeight));
9936e15662SIngo Weinhold	BRect rect(knobRect);
10036e15662SIngo Weinhold	be_control_look->DrawRadioButton(this, rect, updateRect, base, flags);
1012f86ba45SStephan Aßmus
1028b902d94SJohn Scipione	// erase the is control flag before drawing the label so that the label
1038b902d94SJohn Scipione	// will get drawn using B_PANEL_TEXT_COLOR.
1048b902d94SJohn Scipione	flags &= ~BControlLook::B_IS_CONTROL;
1058b902d94SJohn Scipione
10636e15662SIngo Weinhold	BRect labelRect(Bounds());
1075e815cf3SIngo Weinhold	labelRect.left = knobRect.right + 1
10836e15662SIngo Weinhold		+ be_control_look->DefaultLabelSpacing();
1092f86ba45SStephan Aßmus
1105e815cf3SIngo Weinhold	const BBitmap* icon = IconBitmap(
1115e815cf3SIngo Weinhold		B_INACTIVE_ICON_BITMAP | (IsEnabled() ? 0 : B_DISABLED_ICON_BITMAP));
1125e815cf3SIngo Weinhold
1135e815cf3SIngo Weinhold	be_control_look->DrawLabel(this, Label(), icon, labelRect, updateRect,
11436e15662SIngo Weinhold		base, flags);
115ac6f7aa8SMarc Flerackers}
1165ac57aebSStephan Aßmus
1175ac57aebSStephan Aßmus
1185ac57aebSStephan Aßmusvoid
119b29d84a8SJohn ScipioneBRadioButton::MouseDown(BPoint where)
120ac6f7aa8SMarc Flerackers{
121ac6f7aa8SMarc Flerackers	if (!IsEnabled())
122ac6f7aa8SMarc Flerackers		return;
123ac6f7aa8SMarc Flerackers
124ac6f7aa8SMarc Flerackers	fOutlined = true;
1258053a364SMarc Flerackers
126b29d84a8SJohn Scipione	if ((Window()->Flags() & B_ASYNCHRONOUS_CONTROLS) != 0) {
127c7694b4aSStephan Aßmus		Invalidate();
1289199a339SStefano Ceccherini		SetTracking(true);
1299199a339SStefano Ceccherini		SetMouseEventMask(B_POINTER_EVENTS, B_LOCK_WINDOW_FOCUS);
130c7694b4aSStephan Aßmus	} else {
1315ac57aebSStephan Aßmus		_Redraw();
132c7694b4aSStephan Aßmus
1338053a364SMarc Flerackers		BRect bounds = Bounds();
1348053a364SMarc Flerackers		uint32 buttons;
1358053a364SMarc Flerackers
136c7694b4aSStephan Aßmus		do {
1378053a364SMarc Flerackers			snooze(40000);
138b29d84a8SJohn Scipione			GetMouse(&where, &buttons, true);
139b29d84a8SJohn Scipione			bool inside = bounds.Contains(where);
1408053a364SMarc Flerackers
141c7694b4aSStephan Aßmus			if (fOutlined != inside) {
1428053a364SMarc Flerackers				fOutlined = inside;
1435ac57aebSStephan Aßmus				_Redraw();
1448053a364SMarc Flerackers			}
1458053a364SMarc Flerackers		} while (buttons != 0);
1468053a364SMarc Flerackers
147c7694b4aSStephan Aßmus		if (fOutlined) {
1488053a364SMarc Flerackers			fOutlined = false;
1495ac57aebSStephan Aßmus			_Redraw();
1508053a364SMarc Flerackers			SetValue(B_CONTROL_ON);
1518053a364SMarc Flerackers			Invoke();
152b29d84a8SJohn Scipione		} else
1535ac57aebSStephan Aßmus			_Redraw();
1548053a364SMarc Flerackers	}
155ac6f7aa8SMarc Flerackers}
1565ac57aebSStephan Aßmus
1575ac57aebSStephan Aßmus
1585ac57aebSStephan Aßmusvoid
1595ac57aebSStephan AßmusBRadioButton::AttachedToWindow()
160ac6f7aa8SMarc Flerackers{
161ac6f7aa8SMarc Flerackers	BControl::AttachedToWindow();
162ac6f7aa8SMarc Flerackers}
1635ac57aebSStephan Aßmus
1645ac57aebSStephan Aßmus
1655ac57aebSStephan Aßmusvoid
16643f8c614SStephan AßmusBRadioButton::KeyDown(const char* bytes, int32 numBytes)
167ac6f7aa8SMarc Flerackers{
16843f8c614SStephan Aßmus	// TODO: Add selecting the next button functionality (navigating radio
16943f8c614SStephan Aßmus	// buttons with the cursor keys)!
1708053a364SMarc Flerackers
1715ac57aebSStephan Aßmus	switch (bytes[0]) {
1725ac57aebSStephan Aßmus		case B_RETURN:
1735ac57aebSStephan Aßmus			// override B_RETURN, which BControl would use to toggle the value
1745ac57aebSStephan Aßmus			// but we don't allow setting the control to "off", only "on"
1755ac57aebSStephan Aßmus		case B_SPACE: {
1765ac57aebSStephan Aßmus			if (IsEnabled() && !Value()) {
1778053a364SMarc Flerackers				SetValue(B_CONTROL_ON);
1788053a364SMarc Flerackers				Invoke();
1798053a364SMarc Flerackers			}
1808053a364SMarc Flerackers			break;
1818053a364SMarc Flerackers		}
182b29d84a8SJohn Scipione
1838053a364SMarc Flerackers		default:
1848053a364SMarc Flerackers			BControl::KeyDown(bytes, numBytes);
1858053a364SMarc Flerackers	}
186ac6f7aa8SMarc Flerackers}
1875ac57aebSStephan Aßmus
1885ac57aebSStephan Aßmus
1895ac57aebSStephan Aßmusvoid
1905ac57aebSStephan AßmusBRadioButton::SetValue(int32 value)
191ac6f7aa8SMarc Flerackers{
1920c3344f4SStephan Aßmus	if (value != Value()) {
193a71c9607SAxel Dörfler		BControl::SetValueNoUpdate(value);
1940c3344f4SStephan Aßmus		Invalidate(_KnobFrame());
1950c3344f4SStephan Aßmus	}
1968053a364SMarc Flerackers
197b29d84a8SJohn Scipione	if (value == 0)
198ac6f7aa8SMarc Flerackers		return;
199ac6f7aa8SMarc Flerackers
20043f8c614SStephan Aßmus	BView* parent = Parent();
20143f8c614SStephan Aßmus	BView* child = NULL;
2028053a364SMarc Flerackers
203b29d84a8SJohn Scipione	if (parent != NULL) {
2048053a364SMarc Flerackers		// If the parent is a BBox, the group parent is the parent of the BBox
20543f8c614SStephan Aßmus		BBox* box = dynamic_cast<BBox*>(parent);
2068053a364SMarc Flerackers
207b29d84a8SJohn Scipione		if (box != NULL && box->LabelView() == this)
2088053a364SMarc Flerackers			parent = box->Parent();
2098053a364SMarc Flerackers
210b29d84a8SJohn Scipione		if (parent != NULL) {
21143f8c614SStephan Aßmus			BBox* box = dynamic_cast<BBox*>(parent);
2128053a364SMarc Flerackers
2138053a364SMarc Flerackers			// If the parent is a BBox, skip the label if there is one
214b29d84a8SJohn Scipione			if (box != NULL && box->LabelView())
2158053a364SMarc Flerackers				child = parent->ChildAt(1);
2168053a364SMarc Flerackers			else
2178053a364SMarc Flerackers				child = parent->ChildAt(0);
2185ac57aebSStephan Aßmus		} else
2198053a364SMarc Flerackers			child = Window()->ChildAt(0);
220b29d84a8SJohn Scipione	} else if (Window() != NULL)
2218053a364SMarc Flerackers		child = Window()->ChildAt(0);
2228053a364SMarc Flerackers
223b29d84a8SJohn Scipione	while (child != NULL) {
22443f8c614SStephan Aßmus		BRadioButton* radio = dynamic_cast<BRadioButton*>(child);
2258053a364SMarc Flerackers
226b29d84a8SJohn Scipione		if (radio != NULL && (radio != this))
2278053a364SMarc Flerackers			radio->SetValue(B_CONTROL_OFF);
2285ac57aebSStephan Aßmus		else {
2298053a364SMarc Flerackers			// If the child is a BBox, check if the label is a radiobutton
23043f8c614SStephan Aßmus			BBox* box = dynamic_cast<BBox*>(child);
2318053a364SMarc Flerackers
232b29d84a8SJohn Scipione			if (box != NULL && box->LabelView()) {
2338053a364SMarc Flerackers				radio = dynamic_cast<BRadioButton*>(box->LabelView());
2348053a364SMarc Flerackers
235b29d84a8SJohn Scipione				if (radio != NULL && (radio != this))
2368053a364SMarc Flerackers					radio->SetValue(B_CONTROL_OFF);
2378053a364SMarc Flerackers			}
238ac6f7aa8SMarc Flerackers		}
239ac6f7aa8SMarc Flerackers
2408053a364SMarc Flerackers		child = child->NextSibling();
2418053a364SMarc Flerackers	}
24217408188SJérôme Duval
24317408188SJérôme Duval	ASSERT(Value() == B_CONTROL_ON);
244ac6f7aa8SMarc Flerackers}
2455ac57aebSStephan Aßmus
2465ac57aebSStephan Aßmus
2475ac57aebSStephan Aßmusvoid
2488643b098SAxel DörflerBRadioButton::GetPreferredSize(float* _width, float* _height)
249ac6f7aa8SMarc Flerackers{
25040fc37b0SAxel Dörfler	font_height fontHeight;
25140fc37b0SAxel Dörfler	GetFontHeight(&fontHeight);
25240fc37b0SAxel Dörfler
2535e815cf3SIngo Weinhold	BRect rect(_KnobFrame(fontHeight));
2545e815cf3SIngo Weinhold	float width = rect.right + rect.left;
2555e815cf3SIngo Weinhold	float height = rect.bottom + rect.top;
256ac6f7aa8SMarc Flerackers
2575e815cf3SIngo Weinhold	const BBitmap* icon = IconBitmap(B_INACTIVE_ICON_BITMAP);
2585e815cf3SIngo Weinhold	if (icon != NULL) {
2595e815cf3SIngo Weinhold		width += be_control_look->DefaultLabelSpacing()
2605e815cf3SIngo Weinhold			+ icon->Bounds().Width() + 1;
2615e815cf3SIngo Weinhold		height = std::max(height, icon->Bounds().Height());
2628643b098SAxel Dörfler	}
2638053a364SMarc Flerackers
2645e815cf3SIngo Weinhold	if (const char* label = Label()) {
2655e815cf3SIngo Weinhold		width += be_control_look->DefaultLabelSpacing()
2665e815cf3SIngo Weinhold			+ ceilf(StringWidth(label));
2675e815cf3SIngo Weinhold		height = std::max(height,
2685e815cf3SIngo Weinhold			ceilf(6.0f + fontHeight.ascent + fontHeight.descent));
2695e815cf3SIngo Weinhold	}
2705e815cf3SIngo Weinhold
2715e815cf3SIngo Weinhold	if (_width != NULL)
2725e815cf3SIngo Weinhold		*_width = width;
2735e815cf3SIngo Weinhold
2745e815cf3SIngo Weinhold	if (_height != NULL)
2755e815cf3SIngo Weinhold		*_height = height;
276ac6f7aa8SMarc Flerackers}
2775ac57aebSStephan Aßmus
2785ac57aebSStephan Aßmus
2795ac57aebSStephan Aßmusvoid
2805ac57aebSStephan AßmusBRadioButton::ResizeToPreferred()
281ac6f7aa8SMarc Flerackers{
282ac6f7aa8SMarc Flerackers	BControl::ResizeToPreferred();
283ac6f7aa8SMarc Flerackers}
2845ac57aebSStephan Aßmus
2855ac57aebSStephan Aßmus
2865ac57aebSStephan Aßmusstatus_t
28743f8c614SStephan AßmusBRadioButton::Invoke(BMessage* message)
288ac6f7aa8SMarc Flerackers{
289ac6f7aa8SMarc Flerackers	return BControl::Invoke(message);
290ac6f7aa8SMarc Flerackers}
2915ac57aebSStephan Aßmus
2925ac57aebSStephan Aßmus
2935ac57aebSStephan Aßmusvoid
29443f8c614SStephan AßmusBRadioButton::MessageReceived(BMessage* message)
295ac6f7aa8SMarc Flerackers{
296ac6f7aa8SMarc Flerackers	BControl::MessageReceived(message);
297ac6f7aa8SMarc Flerackers}
2985ac57aebSStephan Aßmus
2995ac57aebSStephan Aßmus
3005ac57aebSStephan Aßmusvoid
3015ac57aebSStephan AßmusBRadioButton::WindowActivated(bool active)
302ac6f7aa8SMarc Flerackers{
303ac6f7aa8SMarc Flerackers	BControl::WindowActivated(active);
304ac6f7aa8SMarc Flerackers}
3055ac57aebSStephan Aßmus
3065ac57aebSStephan Aßmus
3075ac57aebSStephan Aßmusvoid
308b29d84a8SJohn ScipioneBRadioButton::MouseUp(BPoint where)
309ac6f7aa8SMarc Flerackers{
3108053a364SMarc Flerackers	if (!IsTracking())
3118053a364SMarc Flerackers		return;
3128053a364SMarc Flerackers
313b29d84a8SJohn Scipione	fOutlined = Bounds().Contains(where);
314c7694b4aSStephan Aßmus	if (fOutlined) {
3158053a364SMarc Flerackers		fOutlined = false;
31657973ac9SIngo Weinhold		if (Value() != B_CONTROL_ON) {
31757973ac9SIngo Weinhold			SetValue(B_CONTROL_ON);
31857973ac9SIngo Weinhold			Invoke();
31957973ac9SIngo Weinhold		}
320ac6f7aa8SMarc Flerackers	}
321c7694b4aSStephan Aßmus	Invalidate();
322ac6f7aa8SMarc Flerackers
3238053a364SMarc Flerackers	SetTracking(false);
324ac6f7aa8SMarc Flerackers}
3255ac57aebSStephan Aßmus
3265ac57aebSStephan Aßmus
3275ac57aebSStephan Aßmusvoid
328b29d84a8SJohn ScipioneBRadioButton::MouseMoved(BPoint where, uint32 code,
329b29d84a8SJohn Scipione	const BMessage* dragMessage)
330ac6f7aa8SMarc Flerackers{
3318053a364SMarc Flerackers	if (!IsTracking())
3328053a364SMarc Flerackers		return;
3338053a364SMarc Flerackers
334b29d84a8SJohn Scipione	bool inside = Bounds().Contains(where);
335ac6f7aa8SMarc Flerackers
336c7694b4aSStephan Aßmus	if (fOutlined != inside) {
3378053a364SMarc Flerackers		fOutlined = inside;
338c7694b4aSStephan Aßmus		Invalidate();
339ac6f7aa8SMarc Flerackers	}
340ac6f7aa8SMarc Flerackers}
3415ac57aebSStephan Aßmus
3425ac57aebSStephan Aßmus
3435ac57aebSStephan Aßmusvoid
3445ac57aebSStephan AßmusBRadioButton::DetachedFromWindow()
345ac6f7aa8SMarc Flerackers{
346ac6f7aa8SMarc Flerackers	BControl::DetachedFromWindow();
347ac6f7aa8SMarc Flerackers}
3485ac57aebSStephan Aßmus
3495ac57aebSStephan Aßmus
3505ac57aebSStephan Aßmusvoid
351b29d84a8SJohn ScipioneBRadioButton::FrameMoved(BPoint newPosition)
352ac6f7aa8SMarc Flerackers{
353b29d84a8SJohn Scipione	BControl::FrameMoved(newPosition);
354ac6f7aa8SMarc Flerackers}
3555ac57aebSStephan Aßmus
3565ac57aebSStephan Aßmus
3575ac57aebSStephan Aßmusvoid
3581f424632SJohn ScipioneBRadioButton::FrameResized(float newWidth, float newHeight)
359ac6f7aa8SMarc Flerackers{
36043f8c614SStephan Aßmus	Invalidate();
3611f424632SJohn Scipione	BControl::FrameResized(newWidth, newHeight);
362ac6f7aa8SMarc Flerackers}
3635ac57aebSStephan Aßmus
3645ac57aebSStephan Aßmus
3655ac57aebSStephan AßmusBHandler*
36643f8c614SStephan AßmusBRadioButton::ResolveSpecifier(BMessage* message, int32 index,
36743f8c614SStephan Aßmus	BMessage* specifier, int32 what, const char* property)
368ac6f7aa8SMarc Flerackers{
3698053a364SMarc Flerackers	return BControl::ResolveSpecifier(message, index, specifier, what,
3708053a364SMarc Flerackers		property);
371ac6f7aa8SMarc Flerackers}
3725ac57aebSStephan Aßmus
3735ac57aebSStephan Aßmus
3745ac57aebSStephan Aßmusvoid
3751f424632SJohn ScipioneBRadioButton::MakeFocus(bool focus)
376ac6f7aa8SMarc Flerackers{
3771f424632SJohn Scipione	BControl::MakeFocus(focus);
378ac6f7aa8SMarc Flerackers}
3795ac57aebSStephan Aßmus
3805ac57aebSStephan Aßmus
3815ac57aebSStephan Aßmusvoid
3825ac57aebSStephan AßmusBRadioButton::AllAttached()
383ac6f7aa8SMarc Flerackers{
384ac6f7aa8SMarc Flerackers	BControl::AllAttached();
385ac6f7aa8SMarc Flerackers}
3865ac57aebSStephan Aßmus
3875ac57aebSStephan Aßmus
3885ac57aebSStephan Aßmusvoid
3895ac57aebSStephan AßmusBRadioButton::AllDetached()
390ac6f7aa8SMarc Flerackers{
391ac6f7aa8SMarc Flerackers	BControl::AllDetached();
392ac6f7aa8SMarc Flerackers}
3935ac57aebSStephan Aßmus
3945ac57aebSStephan Aßmus
3955ac57aebSStephan Aßmusstatus_t
39643f8c614SStephan AßmusBRadioButton::GetSupportedSuites(BMessage* message)
397ac6f7aa8SMarc Flerackers{
3988053a364SMarc Flerackers	return BControl::GetSupportedSuites(message);
399ac6f7aa8SMarc Flerackers}
4005ac57aebSStephan Aßmus
4015ac57aebSStephan Aßmus
4025ac57aebSStephan Aßmusstatus_t
40339fbf550SOliver TappeBRadioButton::Perform(perform_code code, void* _data)
404ac6f7aa8SMarc Flerackers{
40539fbf550SOliver Tappe	switch (code) {
40639fbf550SOliver Tappe		case PERFORM_CODE_MIN_SIZE:
40739fbf550SOliver Tappe			((perform_data_min_size*)_data)->return_value
40839fbf550SOliver Tappe				= BRadioButton::MinSize();
40939fbf550SOliver Tappe			return B_OK;
410b29d84a8SJohn Scipione
41139fbf550SOliver Tappe		case PERFORM_CODE_MAX_SIZE:
41239fbf550SOliver Tappe			((perform_data_max_size*)_data)->return_value
41339fbf550SOliver Tappe				= BRadioButton::MaxSize();
41439fbf550SOliver Tappe			return B_OK;
415b29d84a8SJohn Scipione
41639fbf550SOliver Tappe		case PERFORM_CODE_PREFERRED_SIZE:
41739fbf550SOliver Tappe			((perform_data_preferred_size*)_data)->return_value
41839fbf550SOliver Tappe				= BRadioButton::PreferredSize();
41939fbf550SOliver Tappe			return B_OK;
420b29d84a8SJohn Scipione
42139fbf550SOliver Tappe		case PERFORM_CODE_LAYOUT_ALIGNMENT:
42239fbf550SOliver Tappe			((perform_data_layout_alignment*)_data)->return_value
42339fbf550SOliver Tappe				= BRadioButton::LayoutAlignment();
42439fbf550SOliver Tappe			return B_OK;
425b29d84a8SJohn Scipione
42639fbf550SOliver Tappe		case PERFORM_CODE_HAS_HEIGHT_FOR_WIDTH:
42739fbf550SOliver Tappe			((perform_data_has_height_for_width*)_data)->return_value
42839fbf550SOliver Tappe				= BRadioButton::HasHeightForWidth();
42939fbf550SOliver Tappe			return B_OK;
430b29d84a8SJohn Scipione
43139fbf550SOliver Tappe		case PERFORM_CODE_GET_HEIGHT_FOR_WIDTH:
43239fbf550SOliver Tappe		{
43339fbf550SOliver Tappe			perform_data_get_height_for_width* data
43439fbf550SOliver Tappe				= (perform_data_get_height_for_width*)_data;
43539fbf550SOliver Tappe			BRadioButton::GetHeightForWidth(data->width, &data->min, &data->max,
43639fbf550SOliver Tappe				&data->preferred);
43739fbf550SOliver Tappe			return B_OK;
43826fe4141SStephan Aßmus		}
439b29d84a8SJohn Scipione
44039fbf550SOliver Tappe		case PERFORM_CODE_SET_LAYOUT:
44139fbf550SOliver Tappe		{
44239fbf550SOliver Tappe			perform_data_set_layout* data = (perform_data_set_layout*)_data;
44339fbf550SOliver Tappe			BRadioButton::SetLayout(data->layout);
44439fbf550SOliver Tappe			return B_OK;
44539fbf550SOliver Tappe		}
446b29d84a8SJohn Scipione
447eee4243dSAlex Wilson		case PERFORM_CODE_LAYOUT_INVALIDATED:
44839fbf550SOliver Tappe		{
449eee4243dSAlex Wilson			perform_data_layout_invalidated* data
450eee4243dSAlex Wilson				= (perform_data_layout_invalidated*)_data;
451eee4243dSAlex Wilson			BRadioButton::LayoutInvalidated(data->descendants);
45239fbf550SOliver Tappe			return B_OK;
45339fbf550SOliver Tappe		}
454b29d84a8SJohn Scipione
45539fbf550SOliver Tappe		case PERFORM_CODE_DO_LAYOUT:
45639fbf550SOliver Tappe		{
45739fbf550SOliver Tappe			BRadioButton::DoLayout();
45839fbf550SOliver Tappe			return B_OK;
45939fbf550SOliver Tappe		}
460b29d84a8SJohn Scipione
461be436742SIngo Weinhold		case PERFORM_CODE_SET_ICON:
462be436742SIngo Weinhold		{
463be436742SIngo Weinhold			perform_data_set_icon* data = (perform_data_set_icon*)_data;
464be436742SIngo Weinhold			return BRadioButton::SetIcon(data->icon, data->flags);
465be436742SIngo Weinhold		}
46639fbf550SOliver Tappe	}
46739fbf550SOliver Tappe
46839fbf550SOliver Tappe	return BControl::Perform(code, _data);
469ac6f7aa8SMarc Flerackers}
4705ac57aebSStephan Aßmus
4715ac57aebSStephan Aßmus
4729ecf9d1cSIngo WeinholdBSize
4739ecf9d1cSIngo WeinholdBRadioButton::MaxSize()
4749ecf9d1cSIngo Weinhold{
4759ecf9d1cSIngo Weinhold	float width, height;
4769ecf9d1cSIngo Weinhold	GetPreferredSize(&width, &height);
4779ecf9d1cSIngo Weinhold
4789ecf9d1cSIngo Weinhold	return BLayoutUtils::ComposeSize(ExplicitMaxSize(),
47946d6e9d9SRene Gollent		BSize(width, height));
4809ecf9d1cSIngo Weinhold}
4819ecf9d1cSIngo Weinhold
4829ecf9d1cSIngo Weinhold
48346d6e9d9SRene GollentBAlignment
48446d6e9d9SRene GollentBRadioButton::LayoutAlignment()
48546d6e9d9SRene Gollent{
48646d6e9d9SRene Gollent	return BLayoutUtils::ComposeAlignment(ExplicitAlignment(),
48746d6e9d9SRene Gollent		BAlignment(B_ALIGN_LEFT, B_ALIGN_VERTICAL_UNSET));
48846d6e9d9SRene Gollent}
48946d6e9d9SRene Gollent
4909ecf9d1cSIngo Weinhold
491be436742SIngo Weinholdstatus_t
492be436742SIngo WeinholdBRadioButton::SetIcon(const BBitmap* icon, uint32 flags)
493be436742SIngo Weinhold{
4945e815cf3SIngo Weinhold	return BControl::SetIcon(icon, flags | B_CREATE_DISABLED_ICON_BITMAPS);
495be436742SIngo Weinhold}
496be436742SIngo Weinhold
4979ecf9d1cSIngo Weinhold
498ac6f7aa8SMarc Flerackersvoid BRadioButton::_ReservedRadioButton1() {}
499ac6f7aa8SMarc Flerackersvoid BRadioButton::_ReservedRadioButton2() {}
5005ac57aebSStephan Aßmus
5015ac57aebSStephan Aßmus
5025ac57aebSStephan AßmusBRadioButton&
5035ac57aebSStephan AßmusBRadioButton::operator=(const BRadioButton &)
504ac6f7aa8SMarc Flerackers{
505ac6f7aa8SMarc Flerackers	return *this;
506ac6f7aa8SMarc Flerackers}
5075ac57aebSStephan Aßmus
5085ac57aebSStephan Aßmus
5090c3344f4SStephan AßmusBRect
5100c3344f4SStephan AßmusBRadioButton::_KnobFrame() const
5110c3344f4SStephan Aßmus{
51240fc37b0SAxel Dörfler	font_height fontHeight;
51340fc37b0SAxel Dörfler	GetFontHeight(&fontHeight);
51443f8c614SStephan Aßmus	return _KnobFrame(fontHeight);
51543f8c614SStephan Aßmus}
51643f8c614SStephan Aßmus
5170c3344f4SStephan Aßmus
51843f8c614SStephan AßmusBRect
51943f8c614SStephan AßmusBRadioButton::_KnobFrame(const font_height& fontHeight) const
52043f8c614SStephan Aßmus{
52136e15662SIngo Weinhold	// Same as BCheckBox...
52236e15662SIngo Weinhold	return BRect(0.0f, 2.0f, ceilf(3.0f + fontHeight.ascent),
52336e15662SIngo Weinhold		ceilf(5.0f + fontHeight.ascent));
5240c3344f4SStephan Aßmus}
5250c3344f4SStephan Aßmus
526ac6f7aa8SMarc Flerackers
5275ac57aebSStephan Aßmusvoid
5285ac57aebSStephan AßmusBRadioButton::_Redraw()
5295ac57aebSStephan Aßmus{
530b29d84a8SJohn Scipione	BRect bounds(Bounds());
531b29d84a8SJohn Scipione
5325ac57aebSStephan Aßmus	// fill background with ViewColor()
5335ac57aebSStephan Aßmus	rgb_color highColor = HighColor();
5345ac57aebSStephan Aßmus	SetHighColor(ViewColor());
535b29d84a8SJohn Scipione	FillRect(bounds);
536b29d84a8SJohn Scipione
5375ac57aebSStephan Aßmus	// restore previous HighColor()
5385ac57aebSStephan Aßmus	SetHighColor(highColor);
539b29d84a8SJohn Scipione	Draw(bounds);
5405ac57aebSStephan Aßmus	Flush();
5415ac57aebSStephan Aßmus}
542