xref: /haiku/src/kits/interface/TextControl.cpp (revision 12aefeb42adc80999081b974d7f440a647f74816)
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>
16455d1c46SAxel 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 {
28ffe72abdSAxel Dörfler 	_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 
35455d1c46SAxel 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);
38ffe72abdSAxel Dörfler 
39ffe72abdSAxel Dörfler 	fPreviousHeight = Bounds().Height();
4052a38012Sejakowatz }
41058691d4SStefano Ceccherini 
42058691d4SStefano Ceccherini 
4352a38012Sejakowatz BTextControl::~BTextControl()
4452a38012Sejakowatz {
459cb2dbe2SMarc Flerackers 	SetModificationMessage(NULL);
4652a38012Sejakowatz }
47058691d4SStefano Ceccherini 
48058691d4SStefano Ceccherini 
49ffe72abdSAxel Dörfler BTextControl::BTextControl(BMessage* archive)
50ffe72abdSAxel Dörfler 	: BControl(archive)
5152a38012Sejakowatz {
52ffe72abdSAxel Dörfler 	_InitData(Label(), NULL, archive);
5352a38012Sejakowatz 
54ffe72abdSAxel Dörfler 	int32 labelAlignment = B_ALIGN_LEFT;
55ffe72abdSAxel Dörfler 	int32 textAlignment = B_ALIGN_LEFT;
5652a38012Sejakowatz 
57ffe72abdSAxel Dörfler 	if (archive->HasInt32("_a_label"))
58ffe72abdSAxel Dörfler 		archive->FindInt32("_a_label", &labelAlignment);
5952a38012Sejakowatz 
60ffe72abdSAxel Dörfler 	if (archive->HasInt32("_a_text"))
61ffe72abdSAxel Dörfler 		archive->FindInt32("_a_text", &textAlignment);
6252a38012Sejakowatz 
63ffe72abdSAxel Dörfler 	SetAlignment((alignment)labelAlignment, (alignment)textAlignment);
649cb2dbe2SMarc Flerackers 
65ffe72abdSAxel Dörfler 	if (archive->HasFloat("_divide"))
66ffe72abdSAxel Dörfler 		archive->FindFloat("_a_text", &fDivider);
679cb2dbe2SMarc Flerackers 
68ffe72abdSAxel Dörfler 	if (archive->HasMessage("_mod_msg")) {
69ffe72abdSAxel Dörfler 		BMessage* message = new BMessage;
70ffe72abdSAxel Dörfler 		archive->FindMessage("_mod_msg", message);
71ffe72abdSAxel Dörfler 		SetModificationMessage(message);
729cb2dbe2SMarc Flerackers 	}
7352a38012Sejakowatz }
74058691d4SStefano Ceccherini 
75058691d4SStefano Ceccherini 
76058691d4SStefano Ceccherini BArchivable *
77058691d4SStefano Ceccherini BTextControl::Instantiate(BMessage *archive)
7852a38012Sejakowatz {
799cb2dbe2SMarc Flerackers 	if (validate_instantiation(archive, "BTextControl"))
809cb2dbe2SMarc Flerackers 		return new BTextControl(archive);
819cb2dbe2SMarc Flerackers 	else
8252a38012Sejakowatz 		return NULL;
8352a38012Sejakowatz }
84058691d4SStefano Ceccherini 
85058691d4SStefano Ceccherini 
86058691d4SStefano Ceccherini status_t
87058691d4SStefano Ceccherini BTextControl::Archive(BMessage *data, bool deep) const
8852a38012Sejakowatz {
899cb2dbe2SMarc Flerackers 	BView::Archive(data, deep);
9052a38012Sejakowatz 
91058691d4SStefano Ceccherini 	alignment labelAlignment, textAlignment;
9252a38012Sejakowatz 
93058691d4SStefano Ceccherini 	GetAlignment(&labelAlignment, &textAlignment);
949cb2dbe2SMarc Flerackers 
95058691d4SStefano Ceccherini 	data->AddInt32("_a_label", labelAlignment);
96058691d4SStefano Ceccherini 	data->AddInt32("_a_text", textAlignment);
979cb2dbe2SMarc Flerackers 	data->AddFloat("_divide", Divider());
989cb2dbe2SMarc Flerackers 
999cb2dbe2SMarc Flerackers 	if (ModificationMessage())
1009cb2dbe2SMarc Flerackers 		data->AddMessage("_mod_msg", ModificationMessage());
1019cb2dbe2SMarc Flerackers 
1029cb2dbe2SMarc Flerackers 	return B_OK;
10352a38012Sejakowatz }
104058691d4SStefano Ceccherini 
105058691d4SStefano Ceccherini 
106058691d4SStefano Ceccherini void
107058691d4SStefano Ceccherini BTextControl::SetText(const char *text)
10852a38012Sejakowatz {
1099cb2dbe2SMarc Flerackers 	if (InvokeKind() != B_CONTROL_INVOKED)
1109cb2dbe2SMarc Flerackers 		return;
1119cb2dbe2SMarc Flerackers 
11252a38012Sejakowatz 	fText->SetText(text);
1139cb2dbe2SMarc Flerackers 
1149cb2dbe2SMarc Flerackers 	if (IsFocus())
1159cb2dbe2SMarc Flerackers 		fText->SetInitialText();
1169cb2dbe2SMarc Flerackers 
1179cb2dbe2SMarc Flerackers 	fText->Invalidate();
11852a38012Sejakowatz }
119058691d4SStefano Ceccherini 
120058691d4SStefano Ceccherini 
121058691d4SStefano Ceccherini const char *
122058691d4SStefano Ceccherini BTextControl::Text() const
12352a38012Sejakowatz {
12452a38012Sejakowatz 	return fText->Text();
12552a38012Sejakowatz }
126058691d4SStefano Ceccherini 
127058691d4SStefano Ceccherini 
128058691d4SStefano Ceccherini void
129058691d4SStefano Ceccherini BTextControl::SetValue(int32 value)
13052a38012Sejakowatz {
1319cb2dbe2SMarc Flerackers 	BControl::SetValue(value);
13252a38012Sejakowatz }
133058691d4SStefano Ceccherini 
134058691d4SStefano Ceccherini 
135058691d4SStefano Ceccherini status_t
136058691d4SStefano Ceccherini BTextControl::Invoke(BMessage *message)
13752a38012Sejakowatz {
138058691d4SStefano Ceccherini 	return BControl::Invoke(message);
13952a38012Sejakowatz }
140058691d4SStefano Ceccherini 
141058691d4SStefano Ceccherini 
142058691d4SStefano Ceccherini BTextView *
143058691d4SStefano Ceccherini BTextControl::TextView() const
14452a38012Sejakowatz {
1459cb2dbe2SMarc Flerackers 	return fText;
14652a38012Sejakowatz }
147058691d4SStefano Ceccherini 
148058691d4SStefano Ceccherini 
149058691d4SStefano Ceccherini void
150058691d4SStefano Ceccherini BTextControl::SetModificationMessage(BMessage *message)
15152a38012Sejakowatz {
1529cb2dbe2SMarc Flerackers 	delete fModificationMessage;
15352a38012Sejakowatz 	fModificationMessage = message;
15452a38012Sejakowatz }
155058691d4SStefano Ceccherini 
156058691d4SStefano Ceccherini 
157058691d4SStefano Ceccherini BMessage *
158058691d4SStefano Ceccherini BTextControl::ModificationMessage() const
15952a38012Sejakowatz {
16052a38012Sejakowatz 	return fModificationMessage;
16152a38012Sejakowatz }
162058691d4SStefano Ceccherini 
163058691d4SStefano Ceccherini 
164058691d4SStefano Ceccherini void
165058691d4SStefano Ceccherini BTextControl::SetAlignment(alignment labelAlignment, alignment textAlignment)
16652a38012Sejakowatz {
167058691d4SStefano Ceccherini 	fText->SetAlignment(textAlignment);
1689cb2dbe2SMarc Flerackers 	fText->AlignTextRect();
1699cb2dbe2SMarc Flerackers 
170058691d4SStefano Ceccherini 	if (fLabelAlign != labelAlignment) {
171058691d4SStefano Ceccherini 		fLabelAlign = labelAlignment;
1729cb2dbe2SMarc Flerackers 		Invalidate();
1739cb2dbe2SMarc Flerackers 	}
17452a38012Sejakowatz }
175058691d4SStefano Ceccherini 
176058691d4SStefano Ceccherini 
177058691d4SStefano Ceccherini void
178058691d4SStefano Ceccherini BTextControl::GetAlignment(alignment *label, alignment *text) const
17952a38012Sejakowatz {
180058691d4SStefano Ceccherini 	if (label)
18152a38012Sejakowatz 		*label = fLabelAlign;
182058691d4SStefano Ceccherini 	if (text)
18352a38012Sejakowatz 		*text = fText->Alignment();
18452a38012Sejakowatz }
1859cb2dbe2SMarc Flerackers 
186058691d4SStefano Ceccherini 
187058691d4SStefano Ceccherini void
188058691d4SStefano Ceccherini BTextControl::SetDivider(float dividingLine)
189058691d4SStefano Ceccherini {
1902e6a5805SStephan Aßmus 	dividingLine = floorf(dividingLine + 0.5);
1912e6a5805SStephan Aßmus 
192058691d4SStefano Ceccherini 	float dx = fDivider - dividingLine;
193058691d4SStefano Ceccherini 
194058691d4SStefano Ceccherini 	fDivider = dividingLine;
19552a38012Sejakowatz 
1969cb2dbe2SMarc Flerackers 	fText->MoveBy(-dx, 0.0f);
1979cb2dbe2SMarc Flerackers 	fText->ResizeBy(dx, 0.0f);
19852a38012Sejakowatz 
199058691d4SStefano Ceccherini 	if (Window()) {
20052a38012Sejakowatz 		fText->Invalidate();
20152a38012Sejakowatz 		Invalidate();
20252a38012Sejakowatz 	}
2039cb2dbe2SMarc Flerackers }
204058691d4SStefano Ceccherini 
205058691d4SStefano Ceccherini 
206058691d4SStefano Ceccherini float
207058691d4SStefano Ceccherini BTextControl::Divider() const
20852a38012Sejakowatz {
20952a38012Sejakowatz 	return fDivider;
21052a38012Sejakowatz }
211058691d4SStefano Ceccherini 
212058691d4SStefano Ceccherini 
213058691d4SStefano Ceccherini void
214058691d4SStefano Ceccherini BTextControl::Draw(BRect updateRect)
21552a38012Sejakowatz {
216105644bfSAxel Dörfler 	rgb_color noTint = ui_color(B_PANEL_BACKGROUND_COLOR),
217105644bfSAxel Dörfler 	lighten1 = tint_color(noTint, B_LIGHTEN_1_TINT),
218105644bfSAxel Dörfler 	lighten2 = tint_color(noTint, B_LIGHTEN_2_TINT),
219105644bfSAxel Dörfler 	lightenMax = tint_color(noTint, B_LIGHTEN_MAX_TINT),
220105644bfSAxel Dörfler 	darken1 = tint_color(noTint, B_DARKEN_1_TINT),
221105644bfSAxel Dörfler 	darken2 = tint_color(noTint, B_DARKEN_2_TINT),
222105644bfSAxel Dörfler 	darken4 = tint_color(noTint, B_DARKEN_4_TINT),
223105644bfSAxel Dörfler 	darkenMax = tint_color(noTint, B_DARKEN_MAX_TINT),
224105644bfSAxel Dörfler 	navigationColor = ui_color(B_KEYBOARD_NAVIGATION_COLOR);
2259cb2dbe2SMarc Flerackers 
2269cb2dbe2SMarc Flerackers 	bool enabled = IsEnabled();
2279cb2dbe2SMarc Flerackers 	bool active = false;
2289cb2dbe2SMarc Flerackers 
2299cb2dbe2SMarc Flerackers 	if (fText->IsFocus() && Window()->IsActive())
2309cb2dbe2SMarc Flerackers 		active = true;
2319cb2dbe2SMarc Flerackers 
232455d1c46SAxel Dörfler 	// outer bevel
233455d1c46SAxel Dörfler 
234455d1c46SAxel Dörfler 	BRect rect = Bounds();
235455d1c46SAxel Dörfler 	rect.left = fDivider;
236455d1c46SAxel Dörfler 
237455d1c46SAxel Dörfler 	if (enabled)
238455d1c46SAxel Dörfler 		SetHighColor(darken1);
239455d1c46SAxel Dörfler 	else
240455d1c46SAxel Dörfler 		SetHighColor(noTint);
241455d1c46SAxel Dörfler 
242455d1c46SAxel Dörfler 	StrokeLine(rect.LeftBottom(), rect.LeftTop());
243455d1c46SAxel Dörfler 	StrokeLine(rect.RightTop());
244455d1c46SAxel Dörfler 
245455d1c46SAxel Dörfler 	if (enabled)
246455d1c46SAxel Dörfler 		SetHighColor(lighten2);
247455d1c46SAxel Dörfler 	else
248455d1c46SAxel Dörfler 		SetHighColor(lighten1);
249455d1c46SAxel Dörfler 
250455d1c46SAxel Dörfler 	StrokeLine(BPoint(rect.left + 1.0f, rect.bottom), rect.RightBottom());
251455d1c46SAxel Dörfler 	StrokeLine(BPoint(rect.right, rect.top + 1.0f), rect.RightBottom());
252455d1c46SAxel Dörfler 
253455d1c46SAxel Dörfler 	// inner bevel
254455d1c46SAxel Dörfler 
255455d1c46SAxel Dörfler 	rect.InsetBy(1.0f, 1.0f);
2569cb2dbe2SMarc Flerackers 
257058691d4SStefano Ceccherini 	if (active) {
258105644bfSAxel Dörfler 		SetHighColor(navigationColor);
2599cb2dbe2SMarc Flerackers 		StrokeRect(rect);
260058691d4SStefano Ceccherini 	} else {
2619cb2dbe2SMarc Flerackers 		if (enabled)
2629cb2dbe2SMarc Flerackers 			SetHighColor(darken4);
2639cb2dbe2SMarc Flerackers 		else
2649cb2dbe2SMarc Flerackers 			SetHighColor(darken2);
2659cb2dbe2SMarc Flerackers 
2669cb2dbe2SMarc Flerackers 		StrokeLine(rect.LeftTop(), rect.LeftBottom());
2679cb2dbe2SMarc Flerackers 		StrokeLine(rect.LeftTop(), rect.RightTop());
2689cb2dbe2SMarc Flerackers 
269105644bfSAxel Dörfler 		SetHighColor(noTint);
2709cb2dbe2SMarc Flerackers 		StrokeLine(BPoint(rect.left + 1.0f, rect.bottom), rect.RightBottom());
2719cb2dbe2SMarc Flerackers 		StrokeLine(BPoint(rect.right, rect.top + 1.0f));
2729cb2dbe2SMarc Flerackers 	}
2739cb2dbe2SMarc Flerackers 
274455d1c46SAxel Dörfler 	// area around text view
2759cb2dbe2SMarc Flerackers 
276455d1c46SAxel Dörfler 	SetHighColor(fText->ViewColor());
277455d1c46SAxel Dörfler 	rect.InsetBy(1, 1);
278455d1c46SAxel Dörfler 	BRegion region(rect);
279455d1c46SAxel Dörfler 	BRegion updateRegion(updateRect);
280455d1c46SAxel Dörfler 		// why is there no IntersectWith(BRect &) version?
281455d1c46SAxel Dörfler 	region.IntersectWith(&updateRegion);
2820efe29e0SStefano Ceccherini 	FillRegion(&region);
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 
32779c35b39SAxel Dörfler 	_UpdateTextViewColors(IsEnabled());
3283a3f6c1eSAxel Dörfler 	fText->MakeEditable(IsEnabled());
32952a38012Sejakowatz }
330058691d4SStefano Ceccherini 
331058691d4SStefano Ceccherini 
332058691d4SStefano Ceccherini void
333058691d4SStefano Ceccherini BTextControl::MakeFocus(bool state)
33452a38012Sejakowatz {
3356d8d6cadSStephan Aßmus 	if (state != fText->IsFocus()) {
33652a38012Sejakowatz 		fText->MakeFocus(state);
3379cb2dbe2SMarc Flerackers 
3389cb2dbe2SMarc Flerackers 		if (state)
3399cb2dbe2SMarc Flerackers 			fText->SelectAll();
34052a38012Sejakowatz 	}
3416d8d6cadSStephan Aßmus }
342058691d4SStefano Ceccherini 
343058691d4SStefano Ceccherini 
344058691d4SStefano Ceccherini void
34579c35b39SAxel Dörfler BTextControl::SetEnabled(bool enabled)
34652a38012Sejakowatz {
34779c35b39SAxel Dörfler 	if (IsEnabled() == enabled)
3489cb2dbe2SMarc Flerackers 		return;
3499cb2dbe2SMarc Flerackers 
350058691d4SStefano Ceccherini 	if (Window()) {
35179c35b39SAxel Dörfler 		fText->MakeEditable(enabled);
3529cb2dbe2SMarc Flerackers 
35379c35b39SAxel Dörfler 		_UpdateTextViewColors(enabled);
3549cb2dbe2SMarc Flerackers 
3559cb2dbe2SMarc Flerackers 		fText->Invalidate();
3569cb2dbe2SMarc Flerackers 		Window()->UpdateIfNeeded();
3579cb2dbe2SMarc Flerackers 	}
3589cb2dbe2SMarc Flerackers 
35979c35b39SAxel Dörfler 	BControl::SetEnabled(enabled);
36052a38012Sejakowatz }
361058691d4SStefano Ceccherini 
362058691d4SStefano Ceccherini 
363058691d4SStefano Ceccherini void
364105644bfSAxel Dörfler BTextControl::GetPreferredSize(float *_width, float *_height)
36552a38012Sejakowatz {
366105644bfSAxel Dörfler 	if (_height) {
367105644bfSAxel Dörfler 		// we need enough space for the label and the child text view
368105644bfSAxel Dörfler 		font_height fontHeight;
369105644bfSAxel Dörfler 		GetFontHeight(&fontHeight);
370105644bfSAxel Dörfler 		float labelHeight = ceil(fontHeight.ascent + fontHeight.descent
371105644bfSAxel Dörfler 			+ fontHeight.leading);
372105644bfSAxel Dörfler 		float textHeight = fText->LineHeight(0) + 4.0;
37352a38012Sejakowatz 
374105644bfSAxel Dörfler 		*_height = max_c(labelHeight, textHeight);
375105644bfSAxel Dörfler 	}
376105644bfSAxel Dörfler 
377105644bfSAxel Dörfler 	if (_width) {
37852a38012Sejakowatz 		// TODO: this one I need to find out
379105644bfSAxel Dörfler 		float width = 20.0f + ceilf(StringWidth(Label()));
380105644bfSAxel Dörfler 		if (width < Bounds().Width())
381105644bfSAxel Dörfler 			width = Bounds().Width();
382105644bfSAxel Dörfler 		*_width = width;
383105644bfSAxel Dörfler 	}
38452a38012Sejakowatz }
385058691d4SStefano Ceccherini 
386058691d4SStefano Ceccherini 
387058691d4SStefano Ceccherini void
388058691d4SStefano Ceccherini BTextControl::ResizeToPreferred()
38952a38012Sejakowatz {
390105644bfSAxel Dörfler 	// TODO: change divider?
391105644bfSAxel Dörfler 	BView::ResizeToPreferred();
39252a38012Sejakowatz }
393058691d4SStefano Ceccherini 
394058691d4SStefano Ceccherini 
395058691d4SStefano Ceccherini void
396058691d4SStefano Ceccherini BTextControl::SetFlags(uint32 flags)
39752a38012Sejakowatz {
398058691d4SStefano Ceccherini 	if (!fSkipSetFlags) {
3999cb2dbe2SMarc Flerackers 		// If the textview is navigable, set it to not navigable if needed
4009cb2dbe2SMarc Flerackers 		// Else if it is not navigable, set it to navigable if needed
401058691d4SStefano Ceccherini 		if (fText->Flags() & B_NAVIGABLE) {
4029cb2dbe2SMarc Flerackers 			if (!(flags & B_NAVIGABLE))
4039cb2dbe2SMarc Flerackers 				fText->SetFlags(fText->Flags() & ~B_NAVIGABLE);
404058691d4SStefano Ceccherini 
405058691d4SStefano Ceccherini 		} else {
4069cb2dbe2SMarc Flerackers 			if (flags & B_NAVIGABLE)
4079cb2dbe2SMarc Flerackers 				fText->SetFlags(fText->Flags() | B_NAVIGABLE);
4089cb2dbe2SMarc Flerackers 		}
4099cb2dbe2SMarc Flerackers 
4109cb2dbe2SMarc Flerackers 		// Don't make this one navigable
4119cb2dbe2SMarc Flerackers 		flags &= ~B_NAVIGABLE;
4129cb2dbe2SMarc Flerackers 	}
4139cb2dbe2SMarc Flerackers 
41452a38012Sejakowatz 	BView::SetFlags(flags);
41552a38012Sejakowatz }
416058691d4SStefano Ceccherini 
417058691d4SStefano Ceccherini 
418058691d4SStefano Ceccherini void
419058691d4SStefano Ceccherini BTextControl::MessageReceived(BMessage *msg)
42052a38012Sejakowatz {
421058691d4SStefano Ceccherini 	switch(msg->what) {
4229cb2dbe2SMarc Flerackers 		case B_SET_PROPERTY:
4239cb2dbe2SMarc Flerackers 		case B_GET_PROPERTY:
4249cb2dbe2SMarc Flerackers 			// TODO
42552a38012Sejakowatz 			break;
42652a38012Sejakowatz 		default:
42752a38012Sejakowatz 			BControl::MessageReceived(msg);
42852a38012Sejakowatz 			break;
42952a38012Sejakowatz 	}
43052a38012Sejakowatz }
431058691d4SStefano Ceccherini 
432058691d4SStefano Ceccherini 
433058691d4SStefano Ceccherini BHandler *
434058691d4SStefano Ceccherini BTextControl::ResolveSpecifier(BMessage *msg, int32 index,
43552a38012Sejakowatz 										 BMessage *specifier, int32 form,
43652a38012Sejakowatz 										 const char *property)
43752a38012Sejakowatz {
4389cb2dbe2SMarc Flerackers 	/*
4399cb2dbe2SMarc Flerackers 	BPropertyInfo propInfo(prop_list);
4409cb2dbe2SMarc Flerackers 	BHandler *target = NULL;
4419cb2dbe2SMarc Flerackers 
4429cb2dbe2SMarc Flerackers 	if (propInfo.FindMatch(message, 0, specifier, what, property) < B_OK)
4439cb2dbe2SMarc Flerackers 		return BControl::ResolveSpecifier(message, index, specifier, what,
4449cb2dbe2SMarc Flerackers 			property);
4459cb2dbe2SMarc Flerackers 	else
4469cb2dbe2SMarc Flerackers 		return this;
4479cb2dbe2SMarc Flerackers 	*/
4489cb2dbe2SMarc Flerackers 	return BControl::ResolveSpecifier(msg, index, specifier, form, property);
44952a38012Sejakowatz }
450058691d4SStefano Ceccherini 
451058691d4SStefano Ceccherini 
452058691d4SStefano Ceccherini status_t
453058691d4SStefano Ceccherini BTextControl::GetSupportedSuites(BMessage *data)
45452a38012Sejakowatz {
4559cb2dbe2SMarc Flerackers 	return BControl::GetSupportedSuites(data);
45652a38012Sejakowatz }
457058691d4SStefano Ceccherini 
458058691d4SStefano Ceccherini 
459058691d4SStefano Ceccherini void
460058691d4SStefano Ceccherini BTextControl::MouseUp(BPoint pt)
46152a38012Sejakowatz {
46252a38012Sejakowatz 	BControl::MouseUp(pt);
46352a38012Sejakowatz }
464058691d4SStefano Ceccherini 
465058691d4SStefano Ceccherini 
466058691d4SStefano Ceccherini void
467058691d4SStefano Ceccherini BTextControl::MouseMoved(BPoint pt, uint32 code, const BMessage *msg)
46852a38012Sejakowatz {
46952a38012Sejakowatz 	BControl::MouseMoved(pt, code, msg);
47052a38012Sejakowatz }
471058691d4SStefano Ceccherini 
472058691d4SStefano Ceccherini 
473058691d4SStefano Ceccherini void
474058691d4SStefano Ceccherini BTextControl::DetachedFromWindow()
47552a38012Sejakowatz {
47652a38012Sejakowatz 	BControl::DetachedFromWindow();
47752a38012Sejakowatz }
478058691d4SStefano Ceccherini 
479058691d4SStefano Ceccherini 
480058691d4SStefano Ceccherini void
481058691d4SStefano Ceccherini BTextControl::AllAttached()
48252a38012Sejakowatz {
48352a38012Sejakowatz 	BControl::AllAttached();
48452a38012Sejakowatz }
485058691d4SStefano Ceccherini 
486058691d4SStefano Ceccherini 
487058691d4SStefano Ceccherini void
488058691d4SStefano Ceccherini BTextControl::AllDetached()
48952a38012Sejakowatz {
49052a38012Sejakowatz 	BControl::AllDetached();
49152a38012Sejakowatz }
492058691d4SStefano Ceccherini 
493058691d4SStefano Ceccherini 
494058691d4SStefano Ceccherini void
495058691d4SStefano Ceccherini BTextControl::FrameMoved(BPoint newPosition)
49652a38012Sejakowatz {
49752a38012Sejakowatz 	BControl::FrameMoved(newPosition);
49852a38012Sejakowatz }
499058691d4SStefano Ceccherini 
500058691d4SStefano Ceccherini 
501058691d4SStefano Ceccherini void
502ffe72abdSAxel Dörfler BTextControl::FrameResized(float width, float height)
50352a38012Sejakowatz {
504ffe72abdSAxel Dörfler 	BControl::FrameResized(width, height);
505ffe72abdSAxel Dörfler 
506ffe72abdSAxel Dörfler 	// changes in width
507ffe72abdSAxel Dörfler 
508ffe72abdSAxel Dörfler 	BRect bounds = Bounds();
509ffe72abdSAxel Dörfler 	const float border = 2.0f;
510ffe72abdSAxel Dörfler 
511ffe72abdSAxel Dörfler 	if (bounds.Width() > fPreviousWidth) {
512ffe72abdSAxel Dörfler 		// invalidate the region between the old and the new right border
513ffe72abdSAxel Dörfler 		BRect rect = bounds;
514ffe72abdSAxel Dörfler 		rect.left += fPreviousWidth - border;
515ffe72abdSAxel Dörfler 		rect.right--;
516ffe72abdSAxel Dörfler 		Invalidate(rect);
517ffe72abdSAxel Dörfler 	} else if (bounds.Width() < fPreviousWidth) {
518ffe72abdSAxel Dörfler 		// invalidate the region of the new right border
519ffe72abdSAxel Dörfler 		BRect rect = bounds;
520ffe72abdSAxel Dörfler 		rect.left = rect.right - border;
521ffe72abdSAxel Dörfler 		Invalidate(rect);
522ffe72abdSAxel Dörfler 	}
523ffe72abdSAxel Dörfler 
524ffe72abdSAxel Dörfler 	// changes in height
525ffe72abdSAxel Dörfler 
526ffe72abdSAxel Dörfler 	if (bounds.Height() > fPreviousHeight) {
527ffe72abdSAxel Dörfler 		// invalidate the region between the old and the new bottom border
528ffe72abdSAxel Dörfler 		BRect rect = bounds;
529ffe72abdSAxel Dörfler 		rect.top += fPreviousHeight - border;
530ffe72abdSAxel Dörfler 		rect.bottom--;
531ffe72abdSAxel Dörfler 		Invalidate(rect);
532ffe72abdSAxel Dörfler 	} else if (bounds.Height() < fPreviousHeight) {
533ffe72abdSAxel Dörfler 		// invalidate the region of the new bottom border
534ffe72abdSAxel Dörfler 		BRect rect = bounds;
535ffe72abdSAxel Dörfler 		rect.top = rect.bottom - border;
536ffe72abdSAxel Dörfler 		Invalidate(rect);
537ffe72abdSAxel Dörfler 	}
538ffe72abdSAxel Dörfler 
539ffe72abdSAxel Dörfler 	fPreviousWidth = uint16(bounds.Width());
540ffe72abdSAxel Dörfler 	fPreviousHeight = uint16(bounds.Height());
54152a38012Sejakowatz }
542058691d4SStefano Ceccherini 
543058691d4SStefano Ceccherini 
544058691d4SStefano Ceccherini void
545058691d4SStefano Ceccherini BTextControl::WindowActivated(bool active)
54652a38012Sejakowatz {
5476d8d6cadSStephan Aßmus 	if (fText->IsFocus()) {
548dde10e45SStephan Aßmus 		// invalidate to remove/show focus indication
549dde10e45SStephan Aßmus 		BRect rect = Bounds();
550dde10e45SStephan Aßmus 		rect.left = fDivider;
5516d8d6cadSStephan Aßmus 		Invalidate(rect);
552dde10e45SStephan Aßmus 
553dde10e45SStephan Aßmus 		// help out embedded text view which doesn't
554dde10e45SStephan Aßmus 		// get notified of this
555dde10e45SStephan Aßmus 		fText->Invalidate();
5566d8d6cadSStephan Aßmus 	}
55752a38012Sejakowatz }
558058691d4SStefano Ceccherini 
559058691d4SStefano Ceccherini 
560058691d4SStefano Ceccherini status_t
561058691d4SStefano Ceccherini BTextControl::Perform(perform_code d, void *arg)
56252a38012Sejakowatz {
56352a38012Sejakowatz 	return BControl::Perform(d, arg);
56452a38012Sejakowatz }
565058691d4SStefano Ceccherini 
566058691d4SStefano Ceccherini 
5679cb2dbe2SMarc Flerackers void BTextControl::_ReservedTextControl1() {}
5689cb2dbe2SMarc Flerackers void BTextControl::_ReservedTextControl2() {}
5699cb2dbe2SMarc Flerackers void BTextControl::_ReservedTextControl3() {}
5709cb2dbe2SMarc Flerackers void BTextControl::_ReservedTextControl4() {}
571058691d4SStefano Ceccherini 
572058691d4SStefano Ceccherini 
573058691d4SStefano Ceccherini BTextControl &
574058691d4SStefano Ceccherini BTextControl::operator=(const BTextControl&)
57552a38012Sejakowatz {
57652a38012Sejakowatz 	return *this;
57752a38012Sejakowatz }
578058691d4SStefano Ceccherini 
579058691d4SStefano Ceccherini 
580058691d4SStefano Ceccherini void
58179c35b39SAxel Dörfler BTextControl::_UpdateTextViewColors(bool enabled)
5823a3f6c1eSAxel Dörfler {
5833a3f6c1eSAxel Dörfler 	rgb_color textColor;
5843a3f6c1eSAxel Dörfler 	rgb_color color = {0, 0, 0, 255};
5853a3f6c1eSAxel Dörfler 	BFont font;
5863a3f6c1eSAxel Dörfler 
5873a3f6c1eSAxel Dörfler 	fText->GetFontAndColor(0, &font, &color);
5883a3f6c1eSAxel Dörfler 
5893a3f6c1eSAxel Dörfler 	if (enabled)
5903a3f6c1eSAxel Dörfler 		textColor = color;
591*12aefeb4SAxel Dörfler 	else {
592*12aefeb4SAxel Dörfler 		textColor = tint_color(ui_color(B_PANEL_BACKGROUND_COLOR),
593*12aefeb4SAxel Dörfler 			B_DISABLED_LABEL_TINT);
594*12aefeb4SAxel Dörfler 	}
5953a3f6c1eSAxel Dörfler 
5963a3f6c1eSAxel Dörfler 	fText->SetFontAndColor(&font, B_FONT_ALL, &textColor);
5973a3f6c1eSAxel Dörfler 
5983a3f6c1eSAxel Dörfler 	if (enabled) {
5993a3f6c1eSAxel Dörfler 		color.red = 255;
6003a3f6c1eSAxel Dörfler 		color.green = 255;
6013a3f6c1eSAxel Dörfler 		color.blue = 255;
6023a3f6c1eSAxel Dörfler 	} else {
6033a3f6c1eSAxel Dörfler 		color = tint_color(ui_color(B_PANEL_BACKGROUND_COLOR),
6043a3f6c1eSAxel Dörfler 			B_LIGHTEN_2_TINT);
6053a3f6c1eSAxel Dörfler 	}
6063a3f6c1eSAxel Dörfler 
6073a3f6c1eSAxel Dörfler 	fText->SetViewColor(color);
6083a3f6c1eSAxel Dörfler 	fText->SetLowColor(color);
6093a3f6c1eSAxel Dörfler }
6103a3f6c1eSAxel Dörfler 
6113a3f6c1eSAxel Dörfler 
6123a3f6c1eSAxel Dörfler void
613ffe72abdSAxel Dörfler BTextControl::_CommitValue()
6149cb2dbe2SMarc Flerackers {
6159cb2dbe2SMarc Flerackers }
616058691d4SStefano Ceccherini 
617058691d4SStefano Ceccherini 
618058691d4SStefano Ceccherini void
619ffe72abdSAxel Dörfler BTextControl::_InitData(const char* label, const char* initialText,
620ffe72abdSAxel Dörfler 	BMessage* archive)
6219cb2dbe2SMarc Flerackers {
6229cb2dbe2SMarc Flerackers 	BRect bounds(Bounds());
6239cb2dbe2SMarc Flerackers 
6249cb2dbe2SMarc Flerackers 	fText = NULL;
6259cb2dbe2SMarc Flerackers 	fModificationMessage = NULL;
6269cb2dbe2SMarc Flerackers 	fLabelAlign = B_ALIGN_LEFT;
6279cb2dbe2SMarc Flerackers 	fDivider = 0.0f;
628ffe72abdSAxel Dörfler 	fPreviousWidth = bounds.Width();
629ffe72abdSAxel Dörfler 	fPreviousHeight = bounds.Height();
6309cb2dbe2SMarc Flerackers 	fSkipSetFlags = false;
6319cb2dbe2SMarc Flerackers 
6329cb2dbe2SMarc Flerackers 	int32 flags = 0;
6339cb2dbe2SMarc Flerackers 
634918a22d9SDarkWyrm 	BFont font(be_plain_font);
6359cb2dbe2SMarc Flerackers 
636ffe72abdSAxel Dörfler 	if (!archive || !archive->HasString("_fname"))
637058691d4SStefano Ceccherini 		flags |= B_FONT_FAMILY_AND_STYLE;
6389cb2dbe2SMarc Flerackers 
639ffe72abdSAxel Dörfler 	if (!archive || !archive->HasFloat("_fflt"))
640058691d4SStefano Ceccherini 		flags |= B_FONT_SIZE;
6419cb2dbe2SMarc Flerackers 
6429cb2dbe2SMarc Flerackers 	if (flags != 0)
6439cb2dbe2SMarc Flerackers 		SetFont(&font, flags);
6449cb2dbe2SMarc Flerackers 
6459cb2dbe2SMarc Flerackers 	if (label)
6462e6a5805SStephan Aßmus 		fDivider = floorf(bounds.Width() / 2.0f);
6479cb2dbe2SMarc Flerackers 
648105644bfSAxel Dörfler 	uint32 navigableFlags = Flags() & B_NAVIGABLE;
649105644bfSAxel Dörfler 	if (navigableFlags != 0) {
6509cb2dbe2SMarc Flerackers 		fSkipSetFlags = true;
6519cb2dbe2SMarc Flerackers 		SetFlags(Flags() & ~B_NAVIGABLE);
6529cb2dbe2SMarc Flerackers 		fSkipSetFlags = false;
6539cb2dbe2SMarc Flerackers 	}
6549cb2dbe2SMarc Flerackers 
655ffe72abdSAxel Dörfler 	if (archive)
656058691d4SStefano Ceccherini 		fText = static_cast<_BTextInput_ *>(FindView("_input_"));
657058691d4SStefano Ceccherini 	else {
6582e6a5805SStephan Aßmus 		BRect frame(fDivider, bounds.top,
6592e6a5805SStephan Aßmus 					bounds.right, bounds.bottom);
660105644bfSAxel Dörfler 		// we are stroking the frame around the text view, which
6612e6a5805SStephan Aßmus 		// is 2 pixels wide
662455d1c46SAxel Dörfler 		frame.InsetBy(4.0, 3.0);
6639cb2dbe2SMarc Flerackers 		BRect textRect(frame.OffsetToCopy(0.0f, 0.0f));
6649cb2dbe2SMarc Flerackers 
6659cb2dbe2SMarc Flerackers 		fText = new _BTextInput_(frame, textRect,
6667a70a2d6SStephan Aßmus 			B_FOLLOW_LEFT_RIGHT | B_FOLLOW_TOP,
667105644bfSAxel Dörfler 			B_WILL_DRAW | B_FRAME_EVENTS | navigableFlags);
6689cb2dbe2SMarc Flerackers 		AddChild(fText);
6699cb2dbe2SMarc Flerackers 
670455d1c46SAxel Dörfler 		SetText(initialText);
6719cb2dbe2SMarc Flerackers 		fText->SetAlignment(B_ALIGN_LEFT);
6729cb2dbe2SMarc Flerackers 		fText->AlignTextRect();
6739cb2dbe2SMarc Flerackers 	}
6749cb2dbe2SMarc Flerackers }
675