1a71c9607SAxel Dörfler/*
27a96554cSlooncraz * Copyright 2001-2015 Haiku, Inc. All rights reserved.
3a71c9607SAxel Dörfler * Distributed under the terms of the MIT License.
4a71c9607SAxel Dörfler *
5a71c9607SAxel Dörfler * Authors:
6a71c9607SAxel Dörfler *		Marc Flerackers (mflerackers@androme.be)
7c5c20344SStephan Aßmus *		Stephan A��mus <superstippi@gmx.de>
8a71c9607SAxel Dörfler */
9a71c9607SAxel Dörfler
107ad8e674SJohn Scipione
117ad8e674SJohn Scipione// BCheckBox displays an on/off control.
12a71c9607SAxel Dörfler
13a71c9607SAxel Dörfler
148ce46bc3SMarc Flerackers#include <CheckBox.h>
15c594b2f5SIngo Weinhold
16f8298894SIngo Weinhold#include <algorithm>
17c5c20344SStephan Aßmus#include <new>
18c5c20344SStephan Aßmus
19f8298894SIngo Weinhold#include <Bitmap.h>
202f86ba45SStephan Aßmus#include <ControlLook.h>
21c594b2f5SIngo Weinhold#include <LayoutUtils.h>
2247bc8348SMarc Flerackers#include <Window.h>
238ce46bc3SMarc Flerackers
2439fbf550SOliver Tappe#include <binary_compatibility/Interface.h>
2539fbf550SOliver Tappe
268ce46bc3SMarc Flerackers
277ad8e674SJohn ScipioneBCheckBox::BCheckBox(BRect frame, const char* name, const char* label,
287ad8e674SJohn Scipione	BMessage* message, uint32 resizingMode, uint32 flags)
29a3840a51SStephan Aßmus	:
30a3840a51SStephan Aßmus	BControl(frame, name, label, message, resizingMode, flags),
31a3840a51SStephan Aßmus	fPreferredSize(),
32df37cd4eSIngo Weinhold	fOutlined(false),
33df37cd4eSIngo Weinhold	fPartialToOff(false)
348ce46bc3SMarc Flerackers{
358ce46bc3SMarc Flerackers	// Resize to minimum height if needed
36bc6981ccSStefano Ceccherini	font_height fontHeight;
37bc6981ccSStefano Ceccherini	GetFontHeight(&fontHeight);
38da7c734dSAxel Dörfler	float minHeight = (float)ceil(6.0f + fontHeight.ascent
39da7c734dSAxel Dörfler		+ fontHeight.descent);
408ce46bc3SMarc Flerackers	if (Bounds().Height() < minHeight)
418ce46bc3SMarc Flerackers		ResizeTo(Bounds().Width(), minHeight);
428ce46bc3SMarc Flerackers}
43bc6981ccSStefano Ceccherini
44bc6981ccSStefano Ceccherini
457ad8e674SJohn ScipioneBCheckBox::BCheckBox(const char* name, const char* label, BMessage* message,
46c594b2f5SIngo Weinhold	uint32 flags)
47c5c20344SStephan Aßmus	:
48c5c20344SStephan Aßmus	BControl(name, label, message, flags | B_WILL_DRAW | B_NAVIGABLE),
49c5c20344SStephan Aßmus	fPreferredSize(),
50df37cd4eSIngo Weinhold	fOutlined(false),
51df37cd4eSIngo Weinhold	fPartialToOff(false)
52c594b2f5SIngo Weinhold{
53c594b2f5SIngo Weinhold}
54c594b2f5SIngo Weinhold
55c594b2f5SIngo Weinhold
567ad8e674SJohn ScipioneBCheckBox::BCheckBox(const char* label, BMessage* message)
57c5c20344SStephan Aßmus	:
58c5c20344SStephan Aßmus	BControl(NULL, label, message, B_WILL_DRAW | B_NAVIGABLE),
59c5c20344SStephan Aßmus	fPreferredSize(),
60df37cd4eSIngo Weinhold	fOutlined(false),
61df37cd4eSIngo Weinhold	fPartialToOff(false)
62c594b2f5SIngo Weinhold{
63c594b2f5SIngo Weinhold}
64c594b2f5SIngo Weinhold
65c594b2f5SIngo Weinhold
667ad8e674SJohn ScipioneBCheckBox::BCheckBox(BMessage* data)
67c5c20344SStephan Aßmus	:
687ad8e674SJohn Scipione	BControl(data),
69df37cd4eSIngo Weinhold	fOutlined(false),
70df37cd4eSIngo Weinhold	fPartialToOff(false)
718ce46bc3SMarc Flerackers{
728ce46bc3SMarc Flerackers}
73bc6981ccSStefano Ceccherini
74bc6981ccSStefano Ceccherini
75c5c20344SStephan AßmusBCheckBox::~BCheckBox()
768ce46bc3SMarc Flerackers{
778ce46bc3SMarc Flerackers}
78bc6981ccSStefano Ceccherini
79bc6981ccSStefano Ceccherini
807ad8e674SJohn Scipione// #pragma mark - Archiving methods
81c5c20344SStephan Aßmus
82c5c20344SStephan Aßmus
837ad8e674SJohn ScipioneBArchivable*
847ad8e674SJohn ScipioneBCheckBox::Instantiate(BMessage* data)
858ce46bc3SMarc Flerackers{
867ad8e674SJohn Scipione	if (validate_instantiation(data, "BCheckBox"))
877ad8e674SJohn Scipione		return new(std::nothrow) BCheckBox(data);
882990d21bSAxel Dörfler
892990d21bSAxel Dörfler	return NULL;
908ce46bc3SMarc Flerackers}
91bc6981ccSStefano Ceccherini
92bc6981ccSStefano Ceccherini
93bc6981ccSStefano Ceccherinistatus_t
947ad8e674SJohn ScipioneBCheckBox::Archive(BMessage* data, bool deep) const
958ce46bc3SMarc Flerackers{
967ad8e674SJohn Scipione	return BControl::Archive(data, deep);
978ce46bc3SMarc Flerackers}
98bc6981ccSStefano Ceccherini
99bc6981ccSStefano Ceccherini
1007ad8e674SJohn Scipione// #pragma mark - Hook methods
101c5c20344SStephan Aßmus
102c5c20344SStephan Aßmus
103bc6981ccSStefano Ceccherinivoid
104bc6981ccSStefano CeccheriniBCheckBox::Draw(BRect updateRect)
1058ce46bc3SMarc Flerackers{
106f8298894SIngo Weinhold	rgb_color base = ui_color(B_PANEL_BACKGROUND_COLOR);
1072f86ba45SStephan Aßmus
108f8298894SIngo Weinhold	uint32 flags = be_control_look->Flags(this);
109f8298894SIngo Weinhold	if (fOutlined)
110f8298894SIngo Weinhold		flags |= BControlLook::B_CLICKED;
1112f86ba45SStephan Aßmus
112f8298894SIngo Weinhold	BRect checkBoxRect(_CheckBoxFrame());
113f8298894SIngo Weinhold	BRect rect(checkBoxRect);
1147a96554cSlooncraz	be_control_look->DrawCheckBox(this, rect, updateRect, base, flags);
1152f86ba45SStephan Aßmus
1168b902d94SJohn Scipione	// erase the is control flag before drawing the label so that the label
1178b902d94SJohn Scipione	// will get drawn using B_PANEL_TEXT_COLOR
1188b902d94SJohn Scipione	flags &= ~BControlLook::B_IS_CONTROL;
1198b902d94SJohn Scipione
120f8298894SIngo Weinhold	BRect labelRect(Bounds());
121f8298894SIngo Weinhold	labelRect.left = checkBoxRect.right + 1
122f8298894SIngo Weinhold		+ be_control_look->DefaultLabelSpacing();
1232f86ba45SStephan Aßmus
124f8298894SIngo Weinhold	const BBitmap* icon = IconBitmap(
1255414b3c4SIngo Weinhold		B_INACTIVE_ICON_BITMAP | (IsEnabled() ? 0 : B_DISABLED_ICON_BITMAP));
1268ce46bc3SMarc Flerackers
127f8298894SIngo Weinhold	be_control_look->DrawLabel(this, Label(), icon, labelRect, updateRect,
128f8298894SIngo Weinhold		base, flags);
1298ce46bc3SMarc Flerackers}
130bc6981ccSStefano Ceccherini
131bc6981ccSStefano Ceccherini
132bc6981ccSStefano Ceccherinivoid
133bc6981ccSStefano CeccheriniBCheckBox::AttachedToWindow()
1348ce46bc3SMarc Flerackers{
1358ce46bc3SMarc Flerackers	BControl::AttachedToWindow();
1368ce46bc3SMarc Flerackers}
137bc6981ccSStefano Ceccherini
138bc6981ccSStefano Ceccherini
139c5c20344SStephan Aßmusvoid
140c5c20344SStephan AßmusBCheckBox::DetachedFromWindow()
141c5c20344SStephan Aßmus{
142c5c20344SStephan Aßmus	BControl::DetachedFromWindow();
143c5c20344SStephan Aßmus}
144c5c20344SStephan Aßmus
145c5c20344SStephan Aßmus
146c5c20344SStephan Aßmusvoid
147c5c20344SStephan AßmusBCheckBox::AllAttached()
148c5c20344SStephan Aßmus{
149c5c20344SStephan Aßmus	BControl::AllAttached();
150c5c20344SStephan Aßmus}
151c5c20344SStephan Aßmus
152c5c20344SStephan Aßmus
153c5c20344SStephan Aßmusvoid
154c5c20344SStephan AßmusBCheckBox::AllDetached()
155c5c20344SStephan Aßmus{
156c5c20344SStephan Aßmus	BControl::AllDetached();
157c5c20344SStephan Aßmus}
158c5c20344SStephan Aßmus
159c5c20344SStephan Aßmus
160c5c20344SStephan Aßmusvoid
1617ad8e674SJohn ScipioneBCheckBox::FrameMoved(BPoint newPosition)
162c5c20344SStephan Aßmus{
1637ad8e674SJohn Scipione	BControl::FrameMoved(newPosition);
164c5c20344SStephan Aßmus}
165c5c20344SStephan Aßmus
166c5c20344SStephan Aßmus
167c5c20344SStephan Aßmusvoid
1681f424632SJohn ScipioneBCheckBox::FrameResized(float newWidth, float newHeight)
169c5c20344SStephan Aßmus{
1701f424632SJohn Scipione	BControl::FrameResized(newWidth, newHeight);
171c5c20344SStephan Aßmus}
172c5c20344SStephan Aßmus
173c5c20344SStephan Aßmus
174c5c20344SStephan Aßmusvoid
175c5c20344SStephan AßmusBCheckBox::WindowActivated(bool active)
176c5c20344SStephan Aßmus{
177c5c20344SStephan Aßmus	BControl::WindowActivated(active);
178c5c20344SStephan Aßmus}
179c5c20344SStephan Aßmus
180c5c20344SStephan Aßmus
181c5c20344SStephan Aßmusvoid
1827ad8e674SJohn ScipioneBCheckBox::MessageReceived(BMessage* message)
183c5c20344SStephan Aßmus{
184c5c20344SStephan Aßmus	BControl::MessageReceived(message);
185c5c20344SStephan Aßmus}
186c5c20344SStephan Aßmus
187c5c20344SStephan Aßmus
188c5c20344SStephan Aßmusvoid
1897ad8e674SJohn ScipioneBCheckBox::KeyDown(const char* bytes, int32 numBytes)
190c5c20344SStephan Aßmus{
191df37cd4eSIngo Weinhold	if (*bytes == B_ENTER || *bytes == B_SPACE) {
192df37cd4eSIngo Weinhold		if (!IsEnabled())
193df37cd4eSIngo Weinhold			return;
194df37cd4eSIngo Weinhold
195df37cd4eSIngo Weinhold		SetValue(_NextState());
196df37cd4eSIngo Weinhold		Invoke();
197df37cd4eSIngo Weinhold	} else {
198df37cd4eSIngo Weinhold		// skip the BControl implementation
199df37cd4eSIngo Weinhold		BView::KeyDown(bytes, numBytes);
200df37cd4eSIngo Weinhold	}
201c5c20344SStephan Aßmus}
202c5c20344SStephan Aßmus
203c5c20344SStephan Aßmus
204bc6981ccSStefano Ceccherinivoid
2057ad8e674SJohn ScipioneBCheckBox::MouseDown(BPoint where)
2068ce46bc3SMarc Flerackers{
2078ce46bc3SMarc Flerackers	if (!IsEnabled())
2088ce46bc3SMarc Flerackers		return;
2098ce46bc3SMarc Flerackers
2108ce46bc3SMarc Flerackers	fOutlined = true;
21147bc8348SMarc Flerackers
212bc6981ccSStefano Ceccherini	if (Window()->Flags() & B_ASYNCHRONOUS_CONTROLS) {
21325ad8b2cSStephan Aßmus		Invalidate();
214bc6981ccSStefano Ceccherini		SetTracking(true);
215bc6981ccSStefano Ceccherini		SetMouseEventMask(B_POINTER_EVENTS, B_LOCK_WINDOW_FOCUS);
216bc6981ccSStefano Ceccherini	} else {
21747bc8348SMarc Flerackers		BRect bounds = Bounds();
21847bc8348SMarc Flerackers		uint32 buttons;
21947bc8348SMarc Flerackers
220a0c5ca01SStephan Aßmus		Invalidate();
221a0c5ca01SStephan Aßmus		Window()->UpdateIfNeeded();
22225ad8b2cSStephan Aßmus
223bc6981ccSStefano Ceccherini		do {
22447bc8348SMarc Flerackers			snooze(40000);
22547bc8348SMarc Flerackers
2267ad8e674SJohn Scipione			GetMouse(&where, &buttons, true);
22747bc8348SMarc Flerackers
2287ad8e674SJohn Scipione			bool inside = bounds.Contains(where);
229bc6981ccSStefano Ceccherini			if (fOutlined != inside) {
23047bc8348SMarc Flerackers				fOutlined = inside;
231a0c5ca01SStephan Aßmus				Invalidate();
232a0c5ca01SStephan Aßmus				Window()->UpdateIfNeeded();
23347bc8348SMarc Flerackers			}
23447bc8348SMarc Flerackers		} while (buttons != 0);
23547bc8348SMarc Flerackers
236bc6981ccSStefano Ceccherini		if (fOutlined) {
23747bc8348SMarc Flerackers			fOutlined = false;
238df37cd4eSIngo Weinhold			SetValue(_NextState());
23947bc8348SMarc Flerackers			Invoke();
240bc6981ccSStefano Ceccherini		} else {
241a0c5ca01SStephan Aßmus			Invalidate();
242a0c5ca01SStephan Aßmus			Window()->UpdateIfNeeded();
24347bc8348SMarc Flerackers		}
2447910d8b8SRene Gollent	}
2458ce46bc3SMarc Flerackers}
246bc6981ccSStefano Ceccherini
247bc6981ccSStefano Ceccherini
248bc6981ccSStefano Ceccherinivoid
2497ad8e674SJohn ScipioneBCheckBox::MouseUp(BPoint where)
2508ce46bc3SMarc Flerackers{
25147bc8348SMarc Flerackers	if (!IsTracking())
25247bc8348SMarc Flerackers		return;
25347bc8348SMarc Flerackers
2547ad8e674SJohn Scipione	bool inside = Bounds().Contains(where);
25547bc8348SMarc Flerackers
256bc6981ccSStefano Ceccherini	if (fOutlined != inside) {
25747bc8348SMarc Flerackers		fOutlined = inside;
25825ad8b2cSStephan Aßmus		Invalidate();
25947bc8348SMarc Flerackers	}
2608ce46bc3SMarc Flerackers
261bc6981ccSStefano Ceccherini	if (fOutlined) {
26264603764SMarc Flerackers		fOutlined = false;
263df37cd4eSIngo Weinhold		SetValue(_NextState());
26464603764SMarc Flerackers		Invoke();
265bc6981ccSStefano Ceccherini	} else {
26625ad8b2cSStephan Aßmus		Invalidate();
2678ce46bc3SMarc Flerackers	}
26847bc8348SMarc Flerackers
26947bc8348SMarc Flerackers	SetTracking(false);
2708ce46bc3SMarc Flerackers}
271bc6981ccSStefano Ceccherini
272bc6981ccSStefano Ceccherini
273bc6981ccSStefano Ceccherinivoid
2747ad8e674SJohn ScipioneBCheckBox::MouseMoved(BPoint where, uint32 code,
2757ad8e674SJohn Scipione	const BMessage* dragMessage)
2768ce46bc3SMarc Flerackers{
27747bc8348SMarc Flerackers	if (!IsTracking())
27847bc8348SMarc Flerackers		return;
2798ce46bc3SMarc Flerackers
2807ad8e674SJohn Scipione	bool inside = Bounds().Contains(where);
28147bc8348SMarc Flerackers
282bc6981ccSStefano Ceccherini	if (fOutlined != inside) {
28347bc8348SMarc Flerackers		fOutlined = inside;
28425ad8b2cSStephan Aßmus		Invalidate();
2858ce46bc3SMarc Flerackers	}
2868ce46bc3SMarc Flerackers}
287bc6981ccSStefano Ceccherini
288bc6981ccSStefano Ceccherini
289c5c20344SStephan Aßmus// #pragma mark -
290bc6981ccSStefano Ceccherini
291bc6981ccSStefano Ceccherini
292bc6981ccSStefano Ceccherinivoid
2938643b098SAxel DörflerBCheckBox::GetPreferredSize(float* _width, float* _height)
2948ce46bc3SMarc Flerackers{
295f8298894SIngo Weinhold	_ValidatePreferredSize();
2968ce46bc3SMarc Flerackers
297f8298894SIngo Weinhold	if (_width)
298f8298894SIngo Weinhold		*_width = fPreferredSize.width;
29947bc8348SMarc Flerackers
3008643b098SAxel Dörfler	if (_height)
301f8298894SIngo Weinhold		*_height = fPreferredSize.height;
3028ce46bc3SMarc Flerackers}
303bc6981ccSStefano Ceccherini
304bc6981ccSStefano Ceccherini
305bc6981ccSStefano Ceccherinivoid
306bc6981ccSStefano CeccheriniBCheckBox::ResizeToPreferred()
3078ce46bc3SMarc Flerackers{
3088ce46bc3SMarc Flerackers	BControl::ResizeToPreferred();
3098ce46bc3SMarc Flerackers}
310bc6981ccSStefano Ceccherini
311bc6981ccSStefano Ceccherini
312c5c20344SStephan AßmusBSize
313c5c20344SStephan AßmusBCheckBox::MinSize()
3148ce46bc3SMarc Flerackers{
315c5c20344SStephan Aßmus	return BLayoutUtils::ComposeSize(ExplicitMinSize(),
316c5c20344SStephan Aßmus		_ValidatePreferredSize());
3178ce46bc3SMarc Flerackers}
318bc6981ccSStefano Ceccherini
319bc6981ccSStefano Ceccherini
320c5c20344SStephan AßmusBSize
321c5c20344SStephan AßmusBCheckBox::MaxSize()
3228ce46bc3SMarc Flerackers{
323c5c20344SStephan Aßmus	return BLayoutUtils::ComposeSize(ExplicitMaxSize(),
32446d6e9d9SRene Gollent		_ValidatePreferredSize());
3258ce46bc3SMarc Flerackers}
326bc6981ccSStefano Ceccherini
327bc6981ccSStefano Ceccherini
328c5c20344SStephan AßmusBSize
329c5c20344SStephan AßmusBCheckBox::PreferredSize()
3308ce46bc3SMarc Flerackers{
331c5c20344SStephan Aßmus	return BLayoutUtils::ComposeSize(ExplicitPreferredSize(),
332c5c20344SStephan Aßmus		_ValidatePreferredSize());
3338ce46bc3SMarc Flerackers}
334bc6981ccSStefano Ceccherini
335bc6981ccSStefano Ceccherini
33646d6e9d9SRene GollentBAlignment
33746d6e9d9SRene GollentBCheckBox::LayoutAlignment()
33846d6e9d9SRene Gollent{
33946d6e9d9SRene Gollent	return BLayoutUtils::ComposeAlignment(ExplicitAlignment(),
340426f721bSRene Gollent		BAlignment(B_ALIGN_LEFT, B_ALIGN_VERTICAL_CENTER));
34146d6e9d9SRene Gollent}
34246d6e9d9SRene Gollent
34346d6e9d9SRene Gollent
344c5c20344SStephan Aßmus// #pragma mark -
345bc6981ccSStefano Ceccherini
346bc6981ccSStefano Ceccherini
347bc6981ccSStefano Ceccherinivoid
348bc6981ccSStefano CeccheriniBCheckBox::MakeFocus(bool focused)
3498ce46bc3SMarc Flerackers{
3508ce46bc3SMarc Flerackers	BControl::MakeFocus(focused);
3518ce46bc3SMarc Flerackers}
352bc6981ccSStefano Ceccherini
353bc6981ccSStefano Ceccherini
354bc6981ccSStefano Ceccherinivoid
355c5c20344SStephan AßmusBCheckBox::SetValue(int32 value)
3568ce46bc3SMarc Flerackers{
357df37cd4eSIngo Weinhold	// We only accept three possible values.
358df37cd4eSIngo Weinhold	switch (value) {
359df37cd4eSIngo Weinhold		case B_CONTROL_OFF:
360df37cd4eSIngo Weinhold		case B_CONTROL_ON:
361df37cd4eSIngo Weinhold		case B_CONTROL_PARTIALLY_ON:
362df37cd4eSIngo Weinhold			break;
363df37cd4eSIngo Weinhold		default:
364df37cd4eSIngo Weinhold			value = B_CONTROL_ON;
365df37cd4eSIngo Weinhold			break;
366df37cd4eSIngo Weinhold	}
367c5c20344SStephan Aßmus
368c5c20344SStephan Aßmus	if (value != Value()) {
369c5c20344SStephan Aßmus		BControl::SetValueNoUpdate(value);
370c5c20344SStephan Aßmus		Invalidate(_CheckBoxFrame());
371c5c20344SStephan Aßmus	}
3728ce46bc3SMarc Flerackers}
373bc6981ccSStefano Ceccherini
374bc6981ccSStefano Ceccherini
375c5c20344SStephan Aßmusstatus_t
3767ad8e674SJohn ScipioneBCheckBox::Invoke(BMessage* message)
3778ce46bc3SMarc Flerackers{
378c5c20344SStephan Aßmus	return BControl::Invoke(message);
379c5c20344SStephan Aßmus}
380c5c20344SStephan Aßmus
381c5c20344SStephan Aßmus
3827ad8e674SJohn ScipioneBHandler*
3837ad8e674SJohn ScipioneBCheckBox::ResolveSpecifier(BMessage* message, int32 index,
3847ad8e674SJohn Scipione	BMessage* specifier, int32 what, const char* property)
385c5c20344SStephan Aßmus{
386c5c20344SStephan Aßmus	return BControl::ResolveSpecifier(message, index, specifier, what,
387c5c20344SStephan Aßmus		property);
388c5c20344SStephan Aßmus}
389c5c20344SStephan Aßmus
390c5c20344SStephan Aßmus
391c5c20344SStephan Aßmusstatus_t
3927ad8e674SJohn ScipioneBCheckBox::GetSupportedSuites(BMessage* message)
393c5c20344SStephan Aßmus{
394c5c20344SStephan Aßmus	return BControl::GetSupportedSuites(message);
3958ce46bc3SMarc Flerackers}
396bc6981ccSStefano Ceccherini
397bc6981ccSStefano Ceccherini
398bc6981ccSStefano Ceccherinistatus_t
39939fbf550SOliver TappeBCheckBox::Perform(perform_code code, void* _data)
4008ce46bc3SMarc Flerackers{
40139fbf550SOliver Tappe	switch (code) {
40239fbf550SOliver Tappe		case PERFORM_CODE_MIN_SIZE:
40339fbf550SOliver Tappe			((perform_data_min_size*)_data)->return_value
40439fbf550SOliver Tappe				= BCheckBox::MinSize();
40539fbf550SOliver Tappe			return B_OK;
40639fbf550SOliver Tappe		case PERFORM_CODE_MAX_SIZE:
40739fbf550SOliver Tappe			((perform_data_max_size*)_data)->return_value
40839fbf550SOliver Tappe				= BCheckBox::MaxSize();
40939fbf550SOliver Tappe			return B_OK;
41039fbf550SOliver Tappe		case PERFORM_CODE_PREFERRED_SIZE:
41139fbf550SOliver Tappe			((perform_data_preferred_size*)_data)->return_value
41239fbf550SOliver Tappe				= BCheckBox::PreferredSize();
41339fbf550SOliver Tappe			return B_OK;
41439fbf550SOliver Tappe		case PERFORM_CODE_LAYOUT_ALIGNMENT:
41539fbf550SOliver Tappe			((perform_data_layout_alignment*)_data)->return_value
41639fbf550SOliver Tappe				= BCheckBox::LayoutAlignment();
41739fbf550SOliver Tappe			return B_OK;
41839fbf550SOliver Tappe		case PERFORM_CODE_HAS_HEIGHT_FOR_WIDTH:
41939fbf550SOliver Tappe			((perform_data_has_height_for_width*)_data)->return_value
42039fbf550SOliver Tappe				= BCheckBox::HasHeightForWidth();
42139fbf550SOliver Tappe			return B_OK;
42239fbf550SOliver Tappe		case PERFORM_CODE_GET_HEIGHT_FOR_WIDTH:
42339fbf550SOliver Tappe		{
42439fbf550SOliver Tappe			perform_data_get_height_for_width* data
42539fbf550SOliver Tappe				= (perform_data_get_height_for_width*)_data;
42639fbf550SOliver Tappe			BCheckBox::GetHeightForWidth(data->width, &data->min, &data->max,
42739fbf550SOliver Tappe				&data->preferred);
42839fbf550SOliver Tappe			return B_OK;
429c5c20344SStephan Aßmus		}
43039fbf550SOliver Tappe		case PERFORM_CODE_SET_LAYOUT:
43139fbf550SOliver Tappe		{
43239fbf550SOliver Tappe			perform_data_set_layout* data = (perform_data_set_layout*)_data;
43339fbf550SOliver Tappe			BCheckBox::SetLayout(data->layout);
43439fbf550SOliver Tappe			return B_OK;
43539fbf550SOliver Tappe		}
436eee4243dSAlex Wilson		case PERFORM_CODE_LAYOUT_INVALIDATED:
43739fbf550SOliver Tappe		{
438eee4243dSAlex Wilson			perform_data_layout_invalidated* data
439eee4243dSAlex Wilson				= (perform_data_layout_invalidated*)_data;
440eee4243dSAlex Wilson			BCheckBox::LayoutInvalidated(data->descendants);
44139fbf550SOliver Tappe			return B_OK;
44239fbf550SOliver Tappe		}
44339fbf550SOliver Tappe		case PERFORM_CODE_DO_LAYOUT:
44439fbf550SOliver Tappe		{
44539fbf550SOliver Tappe			BCheckBox::DoLayout();
44639fbf550SOliver Tappe			return B_OK;
44739fbf550SOliver Tappe		}
448be436742SIngo Weinhold		case PERFORM_CODE_SET_ICON:
449be436742SIngo Weinhold		{
450be436742SIngo Weinhold			perform_data_set_icon* data = (perform_data_set_icon*)_data;
451be436742SIngo Weinhold			return BCheckBox::SetIcon(data->icon, data->flags);
452be436742SIngo Weinhold		}
45339fbf550SOliver Tappe	}
45439fbf550SOliver Tappe
45539fbf550SOliver Tappe	return BControl::Perform(code, _data);
4568ce46bc3SMarc Flerackers}
457bc6981ccSStefano Ceccherini
458bc6981ccSStefano Ceccherini
459be436742SIngo Weinholdstatus_t
460be436742SIngo WeinholdBCheckBox::SetIcon(const BBitmap* icon, uint32 flags)
461be436742SIngo Weinhold{
4625414b3c4SIngo Weinhold	return BControl::SetIcon(icon, flags | B_CREATE_DISABLED_ICON_BITMAPS);
463be436742SIngo Weinhold}
464be436742SIngo Weinhold
465be436742SIngo Weinhold
466eee4243dSAlex Wilsonvoid
467eee4243dSAlex WilsonBCheckBox::LayoutInvalidated(bool descendants)
468eee4243dSAlex Wilson{
469eee4243dSAlex Wilson	// invalidate cached preferred size
470eee4243dSAlex Wilson	fPreferredSize.Set(B_SIZE_UNSET, B_SIZE_UNSET);
471eee4243dSAlex Wilson}
472eee4243dSAlex Wilson
473eee4243dSAlex Wilson
474df37cd4eSIngo Weinholdbool
475df37cd4eSIngo WeinholdBCheckBox::IsPartialStateToOff() const
476df37cd4eSIngo Weinhold{
477df37cd4eSIngo Weinhold	return fPartialToOff;
478df37cd4eSIngo Weinhold}
479df37cd4eSIngo Weinhold
480df37cd4eSIngo Weinhold
481df37cd4eSIngo Weinholdvoid
482df37cd4eSIngo WeinholdBCheckBox::SetPartialStateToOff(bool partialToOff)
483df37cd4eSIngo Weinhold{
484df37cd4eSIngo Weinhold	fPartialToOff = partialToOff;
485df37cd4eSIngo Weinhold}
486df37cd4eSIngo Weinhold
487df37cd4eSIngo Weinhold
488c5c20344SStephan Aßmus// #pragma mark - FBC padding
489c594b2f5SIngo Weinhold
490c594b2f5SIngo Weinhold
4918ce46bc3SMarc Flerackersvoid BCheckBox::_ReservedCheckBox1() {}
4928ce46bc3SMarc Flerackersvoid BCheckBox::_ReservedCheckBox2() {}
4938ce46bc3SMarc Flerackersvoid BCheckBox::_ReservedCheckBox3() {}
494bc6981ccSStefano Ceccherini
495bc6981ccSStefano Ceccherini
496f8298894SIngo WeinholdBRect
497f8298894SIngo WeinholdBCheckBox::_CheckBoxFrame(const font_height& fontHeight) const
498f8298894SIngo Weinhold{
499f8298894SIngo Weinhold	return BRect(0.0f, 2.0f, ceilf(3.0f + fontHeight.ascent),
500f8298894SIngo Weinhold		ceilf(5.0f + fontHeight.ascent));
501f8298894SIngo Weinhold}
502f8298894SIngo Weinhold
503f8298894SIngo Weinhold
5040c3344f4SStephan AßmusBRect
5050c3344f4SStephan AßmusBCheckBox::_CheckBoxFrame() const
5060c3344f4SStephan Aßmus{
507da7c734dSAxel Dörfler	font_height fontHeight;
508da7c734dSAxel Dörfler	GetFontHeight(&fontHeight);
509f8298894SIngo Weinhold	return _CheckBoxFrame(fontHeight);
5100c3344f4SStephan Aßmus}
511c594b2f5SIngo Weinhold
512c594b2f5SIngo Weinhold
513c594b2f5SIngo WeinholdBSize
514c594b2f5SIngo WeinholdBCheckBox::_ValidatePreferredSize()
515c594b2f5SIngo Weinhold{
51605e3a106SIngo Weinhold	if (!fPreferredSize.IsWidthSet()) {
517c594b2f5SIngo Weinhold		font_height fontHeight;
518c594b2f5SIngo Weinhold		GetFontHeight(&fontHeight);
519c594b2f5SIngo Weinhold
520f8298894SIngo Weinhold		BRect rect(_CheckBoxFrame(fontHeight));
521f8298894SIngo Weinhold		float width = rect.right + rect.left;
522f8298894SIngo Weinhold		float height = rect.bottom + rect.top;
523c594b2f5SIngo Weinhold
5245414b3c4SIngo Weinhold		const BBitmap* icon = IconBitmap(B_INACTIVE_ICON_BITMAP);
525f8298894SIngo Weinhold		if (icon != NULL) {
526f8298894SIngo Weinhold			width += be_control_look->DefaultLabelSpacing()
527f8298894SIngo Weinhold				+ icon->Bounds().Width() + 1;
528f8298894SIngo Weinhold			height = std::max(height, icon->Bounds().Height());
529f8298894SIngo Weinhold		}
530c594b2f5SIngo Weinhold
531f8298894SIngo Weinhold		if (const char* label = Label()) {
532f8298894SIngo Weinhold			width += be_control_look->DefaultLabelSpacing()
533f8298894SIngo Weinhold				+ ceilf(StringWidth(label));
534f8298894SIngo Weinhold			height = std::max(height,
535f8298894SIngo Weinhold				ceilf(6.0f + fontHeight.ascent + fontHeight.descent));
536f8298894SIngo Weinhold		}
537c594b2f5SIngo Weinhold
538f8298894SIngo Weinhold		fPreferredSize.Set(width, height);
539c944d11fSStephan Aßmus
540c944d11fSStephan Aßmus		ResetLayoutInvalidation();
541c594b2f5SIngo Weinhold	}
542c594b2f5SIngo Weinhold
543c594b2f5SIngo Weinhold	return fPreferredSize;
544c594b2f5SIngo Weinhold}
545c5c20344SStephan Aßmus
546c5c20344SStephan Aßmus
547df37cd4eSIngo Weinholdint32
548df37cd4eSIngo WeinholdBCheckBox::_NextState() const
549df37cd4eSIngo Weinhold{
550df37cd4eSIngo Weinhold	switch (Value()) {
551df37cd4eSIngo Weinhold		case B_CONTROL_OFF:
552df37cd4eSIngo Weinhold			return B_CONTROL_ON;
553df37cd4eSIngo Weinhold		case B_CONTROL_PARTIALLY_ON:
554df37cd4eSIngo Weinhold			return fPartialToOff ? B_CONTROL_OFF : B_CONTROL_ON;
555df37cd4eSIngo Weinhold		case B_CONTROL_ON:
556df37cd4eSIngo Weinhold		default:
557df37cd4eSIngo Weinhold			return B_CONTROL_OFF;
558df37cd4eSIngo Weinhold	}
559df37cd4eSIngo Weinhold}
560df37cd4eSIngo Weinhold
561df37cd4eSIngo Weinhold
562c5c20344SStephan AßmusBCheckBox &
563c5c20344SStephan AßmusBCheckBox::operator=(const BCheckBox &)
564c5c20344SStephan Aßmus{
565c5c20344SStephan Aßmus	return *this;
566c5c20344SStephan Aßmus}
567c5c20344SStephan Aßmus
568466f2b8fSRene Gollent
569466f2b8fSRene Gollentextern "C" void
5708adaa6c5SJerome DuvalB_IF_GCC_2(InvalidateLayout__9BCheckBoxb, _ZN9BCheckBox16InvalidateLayoutEb)(
5718adaa6c5SJerome Duval	BCheckBox* box, bool descendants)
572466f2b8fSRene Gollent{
573f6c8d242SRene Gollent	perform_data_layout_invalidated data;
574f6c8d242SRene Gollent	data.descendants = descendants;
575f6c8d242SRene Gollent
5767910d8b8SRene Gollent	box->Perform(PERFORM_CODE_LAYOUT_INVALIDATED, &data);
577466f2b8fSRene Gollent}
578466f2b8fSRene Gollent
579