xref: /haiku/src/kits/interface/TextControl.cpp (revision 455d1c46a62597b8392b78b2ae61671f6f9ce6d5)
1105644bfSAxel Dörfler /*
2105644bfSAxel Dörfler  * Copyright 2001-2005, Haiku Inc.
3105644bfSAxel Dörfler  * Distributed under the terms of the MIT License.
4105644bfSAxel Dörfler  *
5105644bfSAxel Dörfler  * Authors:
6105644bfSAxel Dörfler  *		Frans van Nispen (xlr8@tref.nl)
7105644bfSAxel Dörfler  *		Stephan Aßmus <superstippi@gmx.de>
8105644bfSAxel Dörfler  */
9105644bfSAxel Dörfler 
10105644bfSAxel Dörfler /**	BTextControl displays text that can act like a control. */
11105644bfSAxel Dörfler 
12105644bfSAxel Dörfler 
1352a38012Sejakowatz #include <stdio.h>
1452a38012Sejakowatz 
15058691d4SStefano Ceccherini #include <Message.h>
16*455d1c46SAxel Dörfler #include <Region.h>
1752a38012Sejakowatz #include <TextControl.h>
1852a38012Sejakowatz #include <Window.h>
1952a38012Sejakowatz 
2052a38012Sejakowatz #include "TextInput.h"
2152a38012Sejakowatz 
2252a38012Sejakowatz 
2352a38012Sejakowatz BTextControl::BTextControl(BRect frame, const char *name, const char *label,
2452a38012Sejakowatz 						   const char *text, BMessage *message, uint32 mask,
2552a38012Sejakowatz 						   uint32 flags)
269cb2dbe2SMarc Flerackers 	: BControl(frame, name, label, message, mask, flags | B_FRAME_EVENTS)
2752a38012Sejakowatz {
289cb2dbe2SMarc Flerackers 	InitData(label, text);
2952a38012Sejakowatz 
30105644bfSAxel Dörfler 	float height;
31ee001e26SAxel Dörfler 	BTextControl::GetPreferredSize(NULL, &height);
32105644bfSAxel Dörfler 
33105644bfSAxel Dörfler 	ResizeTo(Bounds().Width(), height);
34105644bfSAxel Dörfler 
35*455d1c46SAxel Dörfler 	float lineHeight = ceil(fText->LineHeight(0));
36105644bfSAxel Dörfler 	fText->ResizeTo(fText->Bounds().Width(), lineHeight);
37105644bfSAxel Dörfler 	fText->MoveTo(fText->Frame().left, (height - lineHeight) / 2);
3852a38012Sejakowatz }
39058691d4SStefano Ceccherini 
40058691d4SStefano Ceccherini 
4152a38012Sejakowatz BTextControl::~BTextControl()
4252a38012Sejakowatz {
439cb2dbe2SMarc Flerackers 	SetModificationMessage(NULL);
4452a38012Sejakowatz }
45058691d4SStefano Ceccherini 
46058691d4SStefano Ceccherini 
4752a38012Sejakowatz BTextControl::BTextControl(BMessage *data)
4852a38012Sejakowatz 	:	BControl(data)
4952a38012Sejakowatz {
509cb2dbe2SMarc Flerackers 	InitData(Label(), NULL, data);
5152a38012Sejakowatz 
529cb2dbe2SMarc Flerackers 	int32 _a_label = B_ALIGN_LEFT;
539cb2dbe2SMarc Flerackers 	int32 _a_text = B_ALIGN_LEFT;
5452a38012Sejakowatz 
559cb2dbe2SMarc Flerackers 	if (data->HasInt32("_a_label"))
569cb2dbe2SMarc Flerackers 		data->FindInt32("_a_label", &_a_label);
5752a38012Sejakowatz 
589cb2dbe2SMarc Flerackers 	if (data->HasInt32("_a_text"))
599cb2dbe2SMarc Flerackers 		data->FindInt32("_a_text", &_a_text);
6052a38012Sejakowatz 
619cb2dbe2SMarc Flerackers 	SetAlignment((alignment)_a_label, (alignment)_a_text);
629cb2dbe2SMarc Flerackers 
639cb2dbe2SMarc Flerackers 	if (data->HasFloat("_divide"))
649cb2dbe2SMarc Flerackers 		data->FindFloat("_a_text", &fDivider);
659cb2dbe2SMarc Flerackers 
66058691d4SStefano Ceccherini 	if (data->HasMessage("_mod_msg")) {
679cb2dbe2SMarc Flerackers 		BMessage *_mod_msg = new BMessage;
689cb2dbe2SMarc Flerackers 		data->FindMessage("_mod_msg", _mod_msg);
699cb2dbe2SMarc Flerackers 		SetModificationMessage(_mod_msg);
709cb2dbe2SMarc Flerackers 	}
7152a38012Sejakowatz }
72058691d4SStefano Ceccherini 
73058691d4SStefano Ceccherini 
74058691d4SStefano Ceccherini BArchivable *
75058691d4SStefano Ceccherini BTextControl::Instantiate(BMessage *archive)
7652a38012Sejakowatz {
779cb2dbe2SMarc Flerackers 	if (validate_instantiation(archive, "BTextControl"))
789cb2dbe2SMarc Flerackers 		return new BTextControl(archive);
799cb2dbe2SMarc Flerackers 	else
8052a38012Sejakowatz 		return NULL;
8152a38012Sejakowatz }
82058691d4SStefano Ceccherini 
83058691d4SStefano Ceccherini 
84058691d4SStefano Ceccherini status_t
85058691d4SStefano Ceccherini BTextControl::Archive(BMessage *data, bool deep) const
8652a38012Sejakowatz {
879cb2dbe2SMarc Flerackers 	BView::Archive(data, deep);
8852a38012Sejakowatz 
89058691d4SStefano Ceccherini 	alignment labelAlignment, textAlignment;
9052a38012Sejakowatz 
91058691d4SStefano Ceccherini 	GetAlignment(&labelAlignment, &textAlignment);
929cb2dbe2SMarc Flerackers 
93058691d4SStefano Ceccherini 	data->AddInt32("_a_label", labelAlignment);
94058691d4SStefano Ceccherini 	data->AddInt32("_a_text", textAlignment);
959cb2dbe2SMarc Flerackers 	data->AddFloat("_divide", Divider());
969cb2dbe2SMarc Flerackers 
979cb2dbe2SMarc Flerackers 	if (ModificationMessage())
989cb2dbe2SMarc Flerackers 		data->AddMessage("_mod_msg", ModificationMessage());
999cb2dbe2SMarc Flerackers 
1009cb2dbe2SMarc Flerackers 	return B_OK;
10152a38012Sejakowatz }
102058691d4SStefano Ceccherini 
103058691d4SStefano Ceccherini 
104058691d4SStefano Ceccherini void
105058691d4SStefano Ceccherini BTextControl::SetText(const char *text)
10652a38012Sejakowatz {
1079cb2dbe2SMarc Flerackers 	if (InvokeKind() != B_CONTROL_INVOKED)
1089cb2dbe2SMarc Flerackers 		return;
1099cb2dbe2SMarc Flerackers 
11052a38012Sejakowatz 	fText->SetText(text);
1119cb2dbe2SMarc Flerackers 
1129cb2dbe2SMarc Flerackers 	if (IsFocus())
1139cb2dbe2SMarc Flerackers 		fText->SetInitialText();
1149cb2dbe2SMarc Flerackers 
1159cb2dbe2SMarc Flerackers 	fText->Invalidate();
11652a38012Sejakowatz }
117058691d4SStefano Ceccherini 
118058691d4SStefano Ceccherini 
119058691d4SStefano Ceccherini const char *
120058691d4SStefano Ceccherini BTextControl::Text() const
12152a38012Sejakowatz {
12252a38012Sejakowatz 	return fText->Text();
12352a38012Sejakowatz }
124058691d4SStefano Ceccherini 
125058691d4SStefano Ceccherini 
126058691d4SStefano Ceccherini void
127058691d4SStefano Ceccherini BTextControl::SetValue(int32 value)
12852a38012Sejakowatz {
1299cb2dbe2SMarc Flerackers 	BControl::SetValue(value);
13052a38012Sejakowatz }
131058691d4SStefano Ceccherini 
132058691d4SStefano Ceccherini 
133058691d4SStefano Ceccherini status_t
134058691d4SStefano Ceccherini BTextControl::Invoke(BMessage *message)
13552a38012Sejakowatz {
136058691d4SStefano Ceccherini 	return BControl::Invoke(message);
13752a38012Sejakowatz }
138058691d4SStefano Ceccherini 
139058691d4SStefano Ceccherini 
140058691d4SStefano Ceccherini BTextView *
141058691d4SStefano Ceccherini BTextControl::TextView() const
14252a38012Sejakowatz {
1439cb2dbe2SMarc Flerackers 	return fText;
14452a38012Sejakowatz }
145058691d4SStefano Ceccherini 
146058691d4SStefano Ceccherini 
147058691d4SStefano Ceccherini void
148058691d4SStefano Ceccherini BTextControl::SetModificationMessage(BMessage *message)
14952a38012Sejakowatz {
1509cb2dbe2SMarc Flerackers 	delete fModificationMessage;
15152a38012Sejakowatz 	fModificationMessage = message;
15252a38012Sejakowatz }
153058691d4SStefano Ceccherini 
154058691d4SStefano Ceccherini 
155058691d4SStefano Ceccherini BMessage *
156058691d4SStefano Ceccherini BTextControl::ModificationMessage() const
15752a38012Sejakowatz {
15852a38012Sejakowatz 	return fModificationMessage;
15952a38012Sejakowatz }
160058691d4SStefano Ceccherini 
161058691d4SStefano Ceccherini 
162058691d4SStefano Ceccherini void
163058691d4SStefano Ceccherini BTextControl::SetAlignment(alignment labelAlignment, alignment textAlignment)
16452a38012Sejakowatz {
165058691d4SStefano Ceccherini 	fText->SetAlignment(textAlignment);
1669cb2dbe2SMarc Flerackers 	fText->AlignTextRect();
1679cb2dbe2SMarc Flerackers 
168058691d4SStefano Ceccherini 	if (fLabelAlign != labelAlignment) {
169058691d4SStefano Ceccherini 		fLabelAlign = labelAlignment;
1709cb2dbe2SMarc Flerackers 		Invalidate();
1719cb2dbe2SMarc Flerackers 	}
17252a38012Sejakowatz }
173058691d4SStefano Ceccherini 
174058691d4SStefano Ceccherini 
175058691d4SStefano Ceccherini void
176058691d4SStefano Ceccherini BTextControl::GetAlignment(alignment *label, alignment *text) const
17752a38012Sejakowatz {
178058691d4SStefano Ceccherini 	if (label)
17952a38012Sejakowatz 		*label = fLabelAlign;
180058691d4SStefano Ceccherini 	if (text)
18152a38012Sejakowatz 		*text = fText->Alignment();
18252a38012Sejakowatz }
1839cb2dbe2SMarc Flerackers 
184058691d4SStefano Ceccherini 
185058691d4SStefano Ceccherini void
186058691d4SStefano Ceccherini BTextControl::SetDivider(float dividingLine)
187058691d4SStefano Ceccherini {
1882e6a5805SStephan Aßmus 	dividingLine = floorf(dividingLine + 0.5);
1892e6a5805SStephan Aßmus 
190058691d4SStefano Ceccherini 	float dx = fDivider - dividingLine;
191058691d4SStefano Ceccherini 
192058691d4SStefano Ceccherini 	fDivider = dividingLine;
19352a38012Sejakowatz 
1949cb2dbe2SMarc Flerackers 	fText->MoveBy(-dx, 0.0f);
1959cb2dbe2SMarc Flerackers 	fText->ResizeBy(dx, 0.0f);
19652a38012Sejakowatz 
197058691d4SStefano Ceccherini 	if (Window()) {
19852a38012Sejakowatz 		fText->Invalidate();
19952a38012Sejakowatz 		Invalidate();
20052a38012Sejakowatz 	}
2019cb2dbe2SMarc Flerackers }
202058691d4SStefano Ceccherini 
203058691d4SStefano Ceccherini 
204058691d4SStefano Ceccherini float
205058691d4SStefano Ceccherini BTextControl::Divider() const
20652a38012Sejakowatz {
20752a38012Sejakowatz 	return fDivider;
20852a38012Sejakowatz }
209058691d4SStefano Ceccherini 
210058691d4SStefano Ceccherini 
211058691d4SStefano Ceccherini void
212058691d4SStefano Ceccherini BTextControl::Draw(BRect updateRect)
21352a38012Sejakowatz {
214105644bfSAxel Dörfler 	rgb_color noTint = ui_color(B_PANEL_BACKGROUND_COLOR),
215105644bfSAxel Dörfler 	lighten1 = tint_color(noTint, B_LIGHTEN_1_TINT),
216105644bfSAxel Dörfler 	lighten2 = tint_color(noTint, B_LIGHTEN_2_TINT),
217105644bfSAxel Dörfler 	lightenMax = tint_color(noTint, B_LIGHTEN_MAX_TINT),
218105644bfSAxel Dörfler 	darken1 = tint_color(noTint, B_DARKEN_1_TINT),
219105644bfSAxel Dörfler 	darken2 = tint_color(noTint, B_DARKEN_2_TINT),
220105644bfSAxel Dörfler 	darken4 = tint_color(noTint, B_DARKEN_4_TINT),
221105644bfSAxel Dörfler 	darkenMax = tint_color(noTint, B_DARKEN_MAX_TINT),
222105644bfSAxel Dörfler 	navigationColor = ui_color(B_KEYBOARD_NAVIGATION_COLOR);
2239cb2dbe2SMarc Flerackers 
2249cb2dbe2SMarc Flerackers 	bool enabled = IsEnabled();
2259cb2dbe2SMarc Flerackers 	bool active = false;
2269cb2dbe2SMarc Flerackers 
2279cb2dbe2SMarc Flerackers 	if (fText->IsFocus() && Window()->IsActive())
2289cb2dbe2SMarc Flerackers 		active = true;
2299cb2dbe2SMarc Flerackers 
230*455d1c46SAxel Dörfler 	// outer bevel
231*455d1c46SAxel Dörfler 
232*455d1c46SAxel Dörfler 	BRect rect = Bounds();
233*455d1c46SAxel Dörfler 	rect.left = fDivider;
234*455d1c46SAxel Dörfler 
235*455d1c46SAxel Dörfler 	if (enabled)
236*455d1c46SAxel Dörfler 		SetHighColor(darken1);
237*455d1c46SAxel Dörfler 	else
238*455d1c46SAxel Dörfler 		SetHighColor(noTint);
239*455d1c46SAxel Dörfler 
240*455d1c46SAxel Dörfler 	StrokeLine(rect.LeftBottom(), rect.LeftTop());
241*455d1c46SAxel Dörfler 	StrokeLine(rect.RightTop());
242*455d1c46SAxel Dörfler 
243*455d1c46SAxel Dörfler 	if (enabled)
244*455d1c46SAxel Dörfler 		SetHighColor(lighten2);
245*455d1c46SAxel Dörfler 	else
246*455d1c46SAxel Dörfler 		SetHighColor(lighten1);
247*455d1c46SAxel Dörfler 
248*455d1c46SAxel Dörfler 	StrokeLine(BPoint(rect.left + 1.0f, rect.bottom), rect.RightBottom());
249*455d1c46SAxel Dörfler 	StrokeLine(BPoint(rect.right, rect.top + 1.0f), rect.RightBottom());
250*455d1c46SAxel Dörfler 
251*455d1c46SAxel Dörfler 	// inner bevel
252*455d1c46SAxel Dörfler 
253*455d1c46SAxel Dörfler 	rect.InsetBy(1.0f, 1.0f);
2549cb2dbe2SMarc Flerackers 
255058691d4SStefano Ceccherini 	if (active) {
256105644bfSAxel Dörfler 		SetHighColor(navigationColor);
2579cb2dbe2SMarc Flerackers 		StrokeRect(rect);
258058691d4SStefano Ceccherini 	} else {
2599cb2dbe2SMarc Flerackers 		if (enabled)
2609cb2dbe2SMarc Flerackers 			SetHighColor(darken4);
2619cb2dbe2SMarc Flerackers 		else
2629cb2dbe2SMarc Flerackers 			SetHighColor(darken2);
2639cb2dbe2SMarc Flerackers 
2649cb2dbe2SMarc Flerackers 		StrokeLine(rect.LeftTop(), rect.LeftBottom());
2659cb2dbe2SMarc Flerackers 		StrokeLine(rect.LeftTop(), rect.RightTop());
2669cb2dbe2SMarc Flerackers 
267105644bfSAxel Dörfler 		SetHighColor(noTint);
2689cb2dbe2SMarc Flerackers 		StrokeLine(BPoint(rect.left + 1.0f, rect.bottom), rect.RightBottom());
2699cb2dbe2SMarc Flerackers 		StrokeLine(BPoint(rect.right, rect.top + 1.0f));
2709cb2dbe2SMarc Flerackers 	}
2719cb2dbe2SMarc Flerackers 
272*455d1c46SAxel Dörfler 	// area around text view
2739cb2dbe2SMarc Flerackers 
274*455d1c46SAxel Dörfler 	SetHighColor(fText->ViewColor());
275*455d1c46SAxel Dörfler 	rect.InsetBy(1, 1);
276*455d1c46SAxel Dörfler 	BRegion region(rect);
277*455d1c46SAxel Dörfler 	BRegion updateRegion(updateRect);
278*455d1c46SAxel Dörfler 		// why is there no IntersectWith(BRect &) version?
279*455d1c46SAxel Dörfler 	region.IntersectWith(&updateRegion);
280*455d1c46SAxel Dörfler 	for (int32 i = region.CountRects(); i-- > 0;) {
281*455d1c46SAxel Dörfler 		FillRect(region.RectAt(i));
282*455d1c46SAxel Dörfler 	}
28352a38012Sejakowatz 
284058691d4SStefano Ceccherini 	if (Label()) {
285105644bfSAxel Dörfler 		font_height fontHeight;
286105644bfSAxel Dörfler 		GetFontHeight(&fontHeight);
2879cb2dbe2SMarc Flerackers 
288105644bfSAxel Dörfler 		float y = fontHeight.ascent + fText->Frame().top + 1;
28952a38012Sejakowatz 		float x;
2909cb2dbe2SMarc Flerackers 
291058691d4SStefano Ceccherini 		switch (fLabelAlign) {
29252a38012Sejakowatz 			case B_ALIGN_RIGHT:
2939cb2dbe2SMarc Flerackers 				x = fDivider - StringWidth(Label()) - 3.0f;
29452a38012Sejakowatz 				break;
29552a38012Sejakowatz 
29652a38012Sejakowatz 			case B_ALIGN_CENTER:
2979cb2dbe2SMarc Flerackers 				x = fDivider - StringWidth(Label()) / 2.0f;
29852a38012Sejakowatz 				break;
29952a38012Sejakowatz 
30052a38012Sejakowatz 			default:
30152a38012Sejakowatz 				x = 3.0f;
30252a38012Sejakowatz 				break;
30352a38012Sejakowatz 		}
30452a38012Sejakowatz 
305105644bfSAxel Dörfler 		SetHighColor(IsEnabled() ? darkenMax
306105644bfSAxel Dörfler 			: tint_color(ui_color(B_PANEL_BACKGROUND_COLOR), B_DISABLED_LABEL_TINT));
30752a38012Sejakowatz 		DrawString(Label(), BPoint(x, y));
30852a38012Sejakowatz 	}
30952a38012Sejakowatz }
310058691d4SStefano Ceccherini 
311058691d4SStefano Ceccherini 
312058691d4SStefano Ceccherini void
313058691d4SStefano Ceccherini BTextControl::MouseDown(BPoint where)
31452a38012Sejakowatz {
315058691d4SStefano Ceccherini 	if (!fText->IsFocus()) {
3169cb2dbe2SMarc Flerackers 		fText->MakeFocus(true);
3179cb2dbe2SMarc Flerackers 		fText->SelectAll();
31852a38012Sejakowatz 	}
31952a38012Sejakowatz }
320058691d4SStefano Ceccherini 
321058691d4SStefano Ceccherini 
322058691d4SStefano Ceccherini void
323058691d4SStefano Ceccherini BTextControl::AttachedToWindow()
32452a38012Sejakowatz {
32552a38012Sejakowatz 	BControl::AttachedToWindow();
32652a38012Sejakowatz 
3279cb2dbe2SMarc Flerackers 	bool enabled = IsEnabled();
3289cb2dbe2SMarc Flerackers 	rgb_color textColor;
3299cb2dbe2SMarc Flerackers 	rgb_color color = HighColor();
3309cb2dbe2SMarc Flerackers 	BFont font;
3319cb2dbe2SMarc Flerackers 
3329cb2dbe2SMarc Flerackers 	fText->GetFontAndColor(0, &font, &color);
3339cb2dbe2SMarc Flerackers 
3349cb2dbe2SMarc Flerackers 	if (enabled)
3359cb2dbe2SMarc Flerackers 		textColor = color;
3369cb2dbe2SMarc Flerackers 	else
3379cb2dbe2SMarc Flerackers 		textColor = tint_color(color, B_LIGHTEN_2_TINT);
3389cb2dbe2SMarc Flerackers 
3399cb2dbe2SMarc Flerackers 	fText->SetFontAndColor(&font, B_FONT_ALL, &textColor);
3409cb2dbe2SMarc Flerackers 
341058691d4SStefano Ceccherini 	if (enabled) {
3429cb2dbe2SMarc Flerackers 		color.red = 255;
3439cb2dbe2SMarc Flerackers 		color.green = 255;
3449cb2dbe2SMarc Flerackers 		color.blue = 255;
345058691d4SStefano Ceccherini 	} else
3469cb2dbe2SMarc Flerackers 		color = tint_color(color, B_LIGHTEN_2_TINT);
3479cb2dbe2SMarc Flerackers 
3489cb2dbe2SMarc Flerackers 	fText->SetViewColor(color);
3499cb2dbe2SMarc Flerackers 	fText->SetLowColor(color);
3509cb2dbe2SMarc Flerackers 
3519cb2dbe2SMarc Flerackers 	fText->MakeEditable(enabled);
35252a38012Sejakowatz }
353058691d4SStefano Ceccherini 
354058691d4SStefano Ceccherini 
355058691d4SStefano Ceccherini void
356058691d4SStefano Ceccherini BTextControl::MakeFocus(bool state)
35752a38012Sejakowatz {
3586d8d6cadSStephan Aßmus 	if (state != fText->IsFocus()) {
35952a38012Sejakowatz 		fText->MakeFocus(state);
3609cb2dbe2SMarc Flerackers 
3619cb2dbe2SMarc Flerackers 		if (state)
3629cb2dbe2SMarc Flerackers 			fText->SelectAll();
36352a38012Sejakowatz 	}
3646d8d6cadSStephan Aßmus }
365058691d4SStefano Ceccherini 
366058691d4SStefano Ceccherini 
367058691d4SStefano Ceccherini void
368058691d4SStefano Ceccherini BTextControl::SetEnabled(bool state)
36952a38012Sejakowatz {
3709cb2dbe2SMarc Flerackers 	if (IsEnabled() == state)
3719cb2dbe2SMarc Flerackers 		return;
3729cb2dbe2SMarc Flerackers 
373058691d4SStefano Ceccherini 	if (Window()) {
3749cb2dbe2SMarc Flerackers 		fText->MakeEditable(state);
3759cb2dbe2SMarc Flerackers 
3769cb2dbe2SMarc Flerackers 		rgb_color textColor;
3779cb2dbe2SMarc Flerackers 		rgb_color color = {0, 0, 0, 255};
3789cb2dbe2SMarc Flerackers 		BFont font;
3799cb2dbe2SMarc Flerackers 
3809cb2dbe2SMarc Flerackers 		fText->GetFontAndColor(0, &font, &color);
3819cb2dbe2SMarc Flerackers 
3829cb2dbe2SMarc Flerackers 		if (state)
3839cb2dbe2SMarc Flerackers 			textColor = color;
3849cb2dbe2SMarc Flerackers 		else
3859cb2dbe2SMarc Flerackers 			textColor = tint_color(color, B_DISABLED_LABEL_TINT);
3869cb2dbe2SMarc Flerackers 
3879cb2dbe2SMarc Flerackers 		fText->SetFontAndColor(&font, B_FONT_ALL, &textColor);
3889cb2dbe2SMarc Flerackers 
389058691d4SStefano Ceccherini 		if (state) {
3909cb2dbe2SMarc Flerackers 			color.red = 255;
3919cb2dbe2SMarc Flerackers 			color.green = 255;
3929cb2dbe2SMarc Flerackers 			color.blue = 255;
393058691d4SStefano Ceccherini 		} else
3949cb2dbe2SMarc Flerackers 			color = tint_color(ui_color(B_PANEL_BACKGROUND_COLOR),
3959cb2dbe2SMarc Flerackers 				B_LIGHTEN_2_TINT);
3969cb2dbe2SMarc Flerackers 
3979cb2dbe2SMarc Flerackers 		fText->SetViewColor(color);
3989cb2dbe2SMarc Flerackers 		fText->SetLowColor(color);
3999cb2dbe2SMarc Flerackers 
4009cb2dbe2SMarc Flerackers 		fText->Invalidate();
4019cb2dbe2SMarc Flerackers 		Window()->UpdateIfNeeded();
4029cb2dbe2SMarc Flerackers 	}
4039cb2dbe2SMarc Flerackers 
40452a38012Sejakowatz 	BControl::SetEnabled(state);
40552a38012Sejakowatz }
406058691d4SStefano Ceccherini 
407058691d4SStefano Ceccherini 
408058691d4SStefano Ceccherini void
409105644bfSAxel Dörfler BTextControl::GetPreferredSize(float *_width, float *_height)
41052a38012Sejakowatz {
411105644bfSAxel Dörfler 	if (_height) {
412105644bfSAxel Dörfler 		// we need enough space for the label and the child text view
413105644bfSAxel Dörfler 		font_height fontHeight;
414105644bfSAxel Dörfler 		GetFontHeight(&fontHeight);
415105644bfSAxel Dörfler 		float labelHeight = ceil(fontHeight.ascent + fontHeight.descent
416105644bfSAxel Dörfler 			+ fontHeight.leading);
417105644bfSAxel Dörfler 		float textHeight = fText->LineHeight(0) + 4.0;
41852a38012Sejakowatz 
419105644bfSAxel Dörfler 		*_height = max_c(labelHeight, textHeight);
420105644bfSAxel Dörfler 	}
421105644bfSAxel Dörfler 
422105644bfSAxel Dörfler 	if (_width) {
42352a38012Sejakowatz 		// TODO: this one I need to find out
424105644bfSAxel Dörfler 		float width = 20.0f + ceilf(StringWidth(Label()));
425105644bfSAxel Dörfler 		if (width < Bounds().Width())
426105644bfSAxel Dörfler 			width = Bounds().Width();
427105644bfSAxel Dörfler 		*_width = width;
428105644bfSAxel Dörfler 	}
42952a38012Sejakowatz }
430058691d4SStefano Ceccherini 
431058691d4SStefano Ceccherini 
432058691d4SStefano Ceccherini void
433058691d4SStefano Ceccherini BTextControl::ResizeToPreferred()
43452a38012Sejakowatz {
435105644bfSAxel Dörfler 	// TODO: change divider?
436105644bfSAxel Dörfler 	BView::ResizeToPreferred();
43752a38012Sejakowatz }
438058691d4SStefano Ceccherini 
439058691d4SStefano Ceccherini 
440058691d4SStefano Ceccherini void
441058691d4SStefano Ceccherini BTextControl::SetFlags(uint32 flags)
44252a38012Sejakowatz {
443058691d4SStefano Ceccherini 	if (!fSkipSetFlags) {
4449cb2dbe2SMarc Flerackers 		// If the textview is navigable, set it to not navigable if needed
4459cb2dbe2SMarc Flerackers 		// Else if it is not navigable, set it to navigable if needed
446058691d4SStefano Ceccherini 		if (fText->Flags() & B_NAVIGABLE) {
4479cb2dbe2SMarc Flerackers 			if (!(flags & B_NAVIGABLE))
4489cb2dbe2SMarc Flerackers 				fText->SetFlags(fText->Flags() & ~B_NAVIGABLE);
449058691d4SStefano Ceccherini 
450058691d4SStefano Ceccherini 		} else {
4519cb2dbe2SMarc Flerackers 			if (flags & B_NAVIGABLE)
4529cb2dbe2SMarc Flerackers 				fText->SetFlags(fText->Flags() | B_NAVIGABLE);
4539cb2dbe2SMarc Flerackers 		}
4549cb2dbe2SMarc Flerackers 
4559cb2dbe2SMarc Flerackers 		// Don't make this one navigable
4569cb2dbe2SMarc Flerackers 		flags &= ~B_NAVIGABLE;
4579cb2dbe2SMarc Flerackers 	}
4589cb2dbe2SMarc Flerackers 
45952a38012Sejakowatz 	BView::SetFlags(flags);
46052a38012Sejakowatz }
461058691d4SStefano Ceccherini 
462058691d4SStefano Ceccherini 
463058691d4SStefano Ceccherini void
464058691d4SStefano Ceccherini BTextControl::MessageReceived(BMessage *msg)
46552a38012Sejakowatz {
466058691d4SStefano Ceccherini 	switch(msg->what) {
4679cb2dbe2SMarc Flerackers 		case B_SET_PROPERTY:
4689cb2dbe2SMarc Flerackers 		case B_GET_PROPERTY:
4699cb2dbe2SMarc Flerackers 			// TODO
47052a38012Sejakowatz 			break;
47152a38012Sejakowatz 		default:
47252a38012Sejakowatz 			BControl::MessageReceived(msg);
47352a38012Sejakowatz 			break;
47452a38012Sejakowatz 	}
47552a38012Sejakowatz }
476058691d4SStefano Ceccherini 
477058691d4SStefano Ceccherini 
478058691d4SStefano Ceccherini BHandler *
479058691d4SStefano Ceccherini BTextControl::ResolveSpecifier(BMessage *msg, int32 index,
48052a38012Sejakowatz 										 BMessage *specifier, int32 form,
48152a38012Sejakowatz 										 const char *property)
48252a38012Sejakowatz {
4839cb2dbe2SMarc Flerackers 	/*
4849cb2dbe2SMarc Flerackers 	BPropertyInfo propInfo(prop_list);
4859cb2dbe2SMarc Flerackers 	BHandler *target = NULL;
4869cb2dbe2SMarc Flerackers 
4879cb2dbe2SMarc Flerackers 	if (propInfo.FindMatch(message, 0, specifier, what, property) < B_OK)
4889cb2dbe2SMarc Flerackers 		return BControl::ResolveSpecifier(message, index, specifier, what,
4899cb2dbe2SMarc Flerackers 			property);
4909cb2dbe2SMarc Flerackers 	else
4919cb2dbe2SMarc Flerackers 		return this;
4929cb2dbe2SMarc Flerackers 	*/
4939cb2dbe2SMarc Flerackers 	return BControl::ResolveSpecifier(msg, index, specifier, form, property);
49452a38012Sejakowatz }
495058691d4SStefano Ceccherini 
496058691d4SStefano Ceccherini 
497058691d4SStefano Ceccherini status_t
498058691d4SStefano Ceccherini BTextControl::GetSupportedSuites(BMessage *data)
49952a38012Sejakowatz {
5009cb2dbe2SMarc Flerackers 	return BControl::GetSupportedSuites(data);
50152a38012Sejakowatz }
502058691d4SStefano Ceccherini 
503058691d4SStefano Ceccherini 
504058691d4SStefano Ceccherini void
505058691d4SStefano Ceccherini BTextControl::MouseUp(BPoint pt)
50652a38012Sejakowatz {
50752a38012Sejakowatz 	BControl::MouseUp(pt);
50852a38012Sejakowatz }
509058691d4SStefano Ceccherini 
510058691d4SStefano Ceccherini 
511058691d4SStefano Ceccherini void
512058691d4SStefano Ceccherini BTextControl::MouseMoved(BPoint pt, uint32 code, const BMessage *msg)
51352a38012Sejakowatz {
51452a38012Sejakowatz 	BControl::MouseMoved(pt, code, msg);
51552a38012Sejakowatz }
516058691d4SStefano Ceccherini 
517058691d4SStefano Ceccherini 
518058691d4SStefano Ceccherini void
519058691d4SStefano Ceccherini BTextControl::DetachedFromWindow()
52052a38012Sejakowatz {
52152a38012Sejakowatz 	BControl::DetachedFromWindow();
52252a38012Sejakowatz }
523058691d4SStefano Ceccherini 
524058691d4SStefano Ceccherini 
525058691d4SStefano Ceccherini void
526058691d4SStefano Ceccherini BTextControl::AllAttached()
52752a38012Sejakowatz {
52852a38012Sejakowatz 	BControl::AllAttached();
52952a38012Sejakowatz }
530058691d4SStefano Ceccherini 
531058691d4SStefano Ceccherini 
532058691d4SStefano Ceccherini void
533058691d4SStefano Ceccherini BTextControl::AllDetached()
53452a38012Sejakowatz {
53552a38012Sejakowatz 	BControl::AllDetached();
53652a38012Sejakowatz }
537058691d4SStefano Ceccherini 
538058691d4SStefano Ceccherini 
539058691d4SStefano Ceccherini void
540058691d4SStefano Ceccherini BTextControl::FrameMoved(BPoint newPosition)
54152a38012Sejakowatz {
54252a38012Sejakowatz 	BControl::FrameMoved(newPosition);
54352a38012Sejakowatz }
544058691d4SStefano Ceccherini 
545058691d4SStefano Ceccherini 
546058691d4SStefano Ceccherini void
547058691d4SStefano Ceccherini BTextControl::FrameResized(float newWidth, float newHeight)
54852a38012Sejakowatz {
54952a38012Sejakowatz 	BControl::FrameResized(newWidth, newHeight);
55052a38012Sejakowatz }
551058691d4SStefano Ceccherini 
552058691d4SStefano Ceccherini 
553058691d4SStefano Ceccherini void
554058691d4SStefano Ceccherini BTextControl::WindowActivated(bool active)
55552a38012Sejakowatz {
5566d8d6cadSStephan Aßmus 	if (fText->IsFocus()) {
5576d8d6cadSStephan Aßmus 		BRect rect(fText->Frame());
5586d8d6cadSStephan Aßmus 		rect.InsetBy(-1.0, -1.0);
5596d8d6cadSStephan Aßmus 		Invalidate(rect);
5606d8d6cadSStephan Aßmus 	}
56152a38012Sejakowatz }
562058691d4SStefano Ceccherini 
563058691d4SStefano Ceccherini 
564058691d4SStefano Ceccherini status_t
565058691d4SStefano Ceccherini BTextControl::Perform(perform_code d, void *arg)
56652a38012Sejakowatz {
56752a38012Sejakowatz 	return BControl::Perform(d, arg);
56852a38012Sejakowatz }
569058691d4SStefano Ceccherini 
570058691d4SStefano Ceccherini 
5719cb2dbe2SMarc Flerackers void BTextControl::_ReservedTextControl1() {}
5729cb2dbe2SMarc Flerackers void BTextControl::_ReservedTextControl2() {}
5739cb2dbe2SMarc Flerackers void BTextControl::_ReservedTextControl3() {}
5749cb2dbe2SMarc Flerackers void BTextControl::_ReservedTextControl4() {}
575058691d4SStefano Ceccherini 
576058691d4SStefano Ceccherini 
577058691d4SStefano Ceccherini BTextControl &
578058691d4SStefano Ceccherini BTextControl::operator=(const BTextControl&)
57952a38012Sejakowatz {
58052a38012Sejakowatz 	return *this;
58152a38012Sejakowatz }
582058691d4SStefano Ceccherini 
583058691d4SStefano Ceccherini 
584058691d4SStefano Ceccherini void
585058691d4SStefano Ceccherini BTextControl::CommitValue()
5869cb2dbe2SMarc Flerackers {
5879cb2dbe2SMarc Flerackers }
588058691d4SStefano Ceccherini 
589058691d4SStefano Ceccherini 
590058691d4SStefano Ceccherini void
591*455d1c46SAxel Dörfler BTextControl::InitData(const char *label, const char *initialText,
5929cb2dbe2SMarc Flerackers 	BMessage *data)
5939cb2dbe2SMarc Flerackers {
5949cb2dbe2SMarc Flerackers 	BRect bounds(Bounds());
5959cb2dbe2SMarc Flerackers 
5969cb2dbe2SMarc Flerackers 	fText = NULL;
5979cb2dbe2SMarc Flerackers 	fModificationMessage = NULL;
5989cb2dbe2SMarc Flerackers 	fLabelAlign = B_ALIGN_LEFT;
5999cb2dbe2SMarc Flerackers 	fDivider = 0.0f;
6009cb2dbe2SMarc Flerackers 	fPrevWidth = 0;
6019cb2dbe2SMarc Flerackers 	fPrevHeight = 0;
6029cb2dbe2SMarc Flerackers 	fSkipSetFlags = false;
6039cb2dbe2SMarc Flerackers 
6049cb2dbe2SMarc Flerackers 	int32 flags = 0;
6059cb2dbe2SMarc Flerackers 
606918a22d9SDarkWyrm 	BFont font(be_plain_font);
6079cb2dbe2SMarc Flerackers 
6089cb2dbe2SMarc Flerackers 	if (!data || !data->HasString("_fname"))
609058691d4SStefano Ceccherini 		flags |= B_FONT_FAMILY_AND_STYLE;
6109cb2dbe2SMarc Flerackers 
6119cb2dbe2SMarc Flerackers 	if (!data || !data->HasFloat("_fflt"))
612058691d4SStefano Ceccherini 		flags |= B_FONT_SIZE;
6139cb2dbe2SMarc Flerackers 
6149cb2dbe2SMarc Flerackers 	if (flags != 0)
6159cb2dbe2SMarc Flerackers 		SetFont(&font, flags);
6169cb2dbe2SMarc Flerackers 
6179cb2dbe2SMarc Flerackers 	if (label)
6182e6a5805SStephan Aßmus 		fDivider = floorf(bounds.Width() / 2.0f);
6199cb2dbe2SMarc Flerackers 
620105644bfSAxel Dörfler 	uint32 navigableFlags = Flags() & B_NAVIGABLE;
621105644bfSAxel Dörfler 	if (navigableFlags != 0) {
6229cb2dbe2SMarc Flerackers 		fSkipSetFlags = true;
6239cb2dbe2SMarc Flerackers 		SetFlags(Flags() & ~B_NAVIGABLE);
6249cb2dbe2SMarc Flerackers 		fSkipSetFlags = false;
6259cb2dbe2SMarc Flerackers 	}
6269cb2dbe2SMarc Flerackers 
6279cb2dbe2SMarc Flerackers 	if (data)
628058691d4SStefano Ceccherini 		fText = static_cast<_BTextInput_ *>(FindView("_input_"));
629058691d4SStefano Ceccherini 	else {
6302e6a5805SStephan Aßmus 		BRect frame(fDivider, bounds.top,
6312e6a5805SStephan Aßmus 					bounds.right, bounds.bottom);
632105644bfSAxel Dörfler 		// we are stroking the frame around the text view, which
6332e6a5805SStephan Aßmus 		// is 2 pixels wide
634*455d1c46SAxel Dörfler 		frame.InsetBy(4.0, 3.0);
6359cb2dbe2SMarc Flerackers 		BRect textRect(frame.OffsetToCopy(0.0f, 0.0f));
6369cb2dbe2SMarc Flerackers 
6379cb2dbe2SMarc Flerackers 		fText = new _BTextInput_(frame, textRect,
6387a70a2d6SStephan Aßmus 			B_FOLLOW_LEFT_RIGHT | B_FOLLOW_TOP,
639105644bfSAxel Dörfler 			B_WILL_DRAW | B_FRAME_EVENTS | navigableFlags);
6409cb2dbe2SMarc Flerackers 		AddChild(fText);
6419cb2dbe2SMarc Flerackers 
642*455d1c46SAxel Dörfler 		SetText(initialText);
6439cb2dbe2SMarc Flerackers 		fText->SetAlignment(B_ALIGN_LEFT);
6449cb2dbe2SMarc Flerackers 		fText->AlignTextRect();
6459cb2dbe2SMarc Flerackers 	}
6469cb2dbe2SMarc Flerackers }
647