xref: /haiku/src/kits/interface/TextControl.cpp (revision 1aaf53ecac2cdc76688cd7e7d08b474efaa64196)
1105644bfSAxel Dörfler /*
2991c062fSAxel Dörfler  * Copyright 2001-2008, 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>
89ecf9d1cSIngo Weinhold  *		Ingo Weinhold <bonefish@cs.tu-berlin.de>
9105644bfSAxel Dörfler  */
10105644bfSAxel Dörfler 
11991c062fSAxel Dörfler /*!	BTextControl displays text that can act like a control. */
12105644bfSAxel Dörfler 
13105644bfSAxel Dörfler 
1452a38012Sejakowatz #include <stdio.h>
1552a38012Sejakowatz 
169ecf9d1cSIngo Weinhold #include <AbstractLayoutItem.h>
179ecf9d1cSIngo Weinhold #include <LayoutUtils.h>
18058691d4SStefano Ceccherini #include <Message.h>
19455d1c46SAxel Dörfler #include <Region.h>
2052a38012Sejakowatz #include <TextControl.h>
2152a38012Sejakowatz #include <Window.h>
2252a38012Sejakowatz 
2352a38012Sejakowatz #include "TextInput.h"
2452a38012Sejakowatz 
2552a38012Sejakowatz 
2693ba577cSStephan Aßmus //#define TRACE_TEXT_CONTROL
2793ba577cSStephan Aßmus #ifdef TRACE_TEXT_CONTROL
2893ba577cSStephan Aßmus #	include <FunctionTracer.h>
2993ba577cSStephan Aßmus 	static int32 sFunctionDepth = -1;
30349c911eSStephan Aßmus #	define CALLED(x...)	FunctionTracer _ft("BTextControl", __FUNCTION__, \
3193ba577cSStephan Aßmus 							sFunctionDepth)
3293ba577cSStephan Aßmus #	define TRACE(x...)	{ BString _to; \
3393ba577cSStephan Aßmus 							_to.Append(' ', (sFunctionDepth + 1) * 2); \
3493ba577cSStephan Aßmus 							printf("%s", _to.String()); printf(x); }
3593ba577cSStephan Aßmus #else
3693ba577cSStephan Aßmus #	define CALLED(x...)
3793ba577cSStephan Aßmus #	define TRACE(x...)
3893ba577cSStephan Aßmus #endif
3993ba577cSStephan Aßmus 
4093ba577cSStephan Aßmus 
419ecf9d1cSIngo Weinhold class BTextControl::LabelLayoutItem : public BAbstractLayoutItem {
429ecf9d1cSIngo Weinhold public:
439ecf9d1cSIngo Weinhold 								LabelLayoutItem(BTextControl* parent);
449ecf9d1cSIngo Weinhold 
459ecf9d1cSIngo Weinhold 	virtual	bool				IsVisible();
469ecf9d1cSIngo Weinhold 	virtual	void				SetVisible(bool visible);
479ecf9d1cSIngo Weinhold 
489ecf9d1cSIngo Weinhold 	virtual	BRect				Frame();
499ecf9d1cSIngo Weinhold 	virtual	void				SetFrame(BRect frame);
509ecf9d1cSIngo Weinhold 
519ecf9d1cSIngo Weinhold 	virtual	BView*				View();
529ecf9d1cSIngo Weinhold 
539ecf9d1cSIngo Weinhold 	virtual	BSize				BaseMinSize();
549ecf9d1cSIngo Weinhold 	virtual	BSize				BaseMaxSize();
559ecf9d1cSIngo Weinhold 	virtual	BSize				BasePreferredSize();
569ecf9d1cSIngo Weinhold 	virtual	BAlignment			BaseAlignment();
579ecf9d1cSIngo Weinhold 
589ecf9d1cSIngo Weinhold private:
599ecf9d1cSIngo Weinhold 			BTextControl*		fParent;
609ecf9d1cSIngo Weinhold 			BRect				fFrame;
619ecf9d1cSIngo Weinhold };
629ecf9d1cSIngo Weinhold 
639ecf9d1cSIngo Weinhold 
649ecf9d1cSIngo Weinhold class BTextControl::TextViewLayoutItem : public BAbstractLayoutItem {
659ecf9d1cSIngo Weinhold public:
669ecf9d1cSIngo Weinhold 								TextViewLayoutItem(BTextControl* parent);
679ecf9d1cSIngo Weinhold 
689ecf9d1cSIngo Weinhold 	virtual	bool				IsVisible();
699ecf9d1cSIngo Weinhold 	virtual	void				SetVisible(bool visible);
709ecf9d1cSIngo Weinhold 
719ecf9d1cSIngo Weinhold 	virtual	BRect				Frame();
729ecf9d1cSIngo Weinhold 	virtual	void				SetFrame(BRect frame);
739ecf9d1cSIngo Weinhold 
749ecf9d1cSIngo Weinhold 	virtual	BView*				View();
759ecf9d1cSIngo Weinhold 
769ecf9d1cSIngo Weinhold 	virtual	BSize				BaseMinSize();
779ecf9d1cSIngo Weinhold 	virtual	BSize				BaseMaxSize();
789ecf9d1cSIngo Weinhold 	virtual	BSize				BasePreferredSize();
799ecf9d1cSIngo Weinhold 	virtual	BAlignment			BaseAlignment();
809ecf9d1cSIngo Weinhold 
819ecf9d1cSIngo Weinhold private:
829ecf9d1cSIngo Weinhold 			BTextControl*		fParent;
839ecf9d1cSIngo Weinhold 			BRect				fFrame;
849ecf9d1cSIngo Weinhold };
859ecf9d1cSIngo Weinhold 
869ecf9d1cSIngo Weinhold 
87349c911eSStephan Aßmus struct BTextControl::LayoutData {
88349c911eSStephan Aßmus 	LayoutData(float width, float height)
89349c911eSStephan Aßmus 		: label_layout_item(NULL),
90349c911eSStephan Aßmus 		  text_view_layout_item(NULL),
91349c911eSStephan Aßmus 		  previous_width(width),
92349c911eSStephan Aßmus 		  previous_height(height),
93349c911eSStephan Aßmus 		  valid(false)
94349c911eSStephan Aßmus 	{
95349c911eSStephan Aßmus 	}
96349c911eSStephan Aßmus 
97349c911eSStephan Aßmus 	LabelLayoutItem*	label_layout_item;
98349c911eSStephan Aßmus 	TextViewLayoutItem*	text_view_layout_item;
99349c911eSStephan Aßmus 	float				previous_width;		// used in FrameResized() for
100349c911eSStephan Aßmus 	float				previous_height;	// invalidation
101349c911eSStephan Aßmus 	font_height			font_info;
102349c911eSStephan Aßmus 	float				label_width;
103349c911eSStephan Aßmus 	float				label_height;
104349c911eSStephan Aßmus 	BSize				min;
105349c911eSStephan Aßmus 	BSize				text_view_min;
106349c911eSStephan Aßmus 	bool				valid;
107349c911eSStephan Aßmus };
108349c911eSStephan Aßmus 
109349c911eSStephan Aßmus 
1109ecf9d1cSIngo Weinhold // #pragma mark -
1119ecf9d1cSIngo Weinhold 
1129ecf9d1cSIngo Weinhold 
113349c911eSStephan Aßmus static const int32 kFrameMargin = 2;
114349c911eSStephan Aßmus static const int32 kLabelInputSpacing = 3;
115349c911eSStephan Aßmus 
116349c911eSStephan Aßmus 
11752a38012Sejakowatz BTextControl::BTextControl(BRect frame, const char* name, const char* label,
118991c062fSAxel Dörfler 		const char* text, BMessage* message, uint32 mask, uint32 flags)
1199cb2dbe2SMarc Flerackers 	: BControl(frame, name, label, message, mask, flags | B_FRAME_EVENTS)
12052a38012Sejakowatz {
121ffe72abdSAxel Dörfler 	_InitData(label, text);
1229ecf9d1cSIngo Weinhold 	_ValidateLayout();
1239ecf9d1cSIngo Weinhold }
12452a38012Sejakowatz 
125105644bfSAxel Dörfler 
1269ecf9d1cSIngo Weinhold BTextControl::BTextControl(const char* name, const char* label,
127991c062fSAxel Dörfler 		const char* text, BMessage* message, uint32 flags)
12893ba577cSStephan Aßmus 	: BControl(name, label, message, flags | B_FRAME_EVENTS)
1299ecf9d1cSIngo Weinhold {
1309ecf9d1cSIngo Weinhold 	_InitData(label, text);
1319ecf9d1cSIngo Weinhold 	_ValidateLayout();
1329ecf9d1cSIngo Weinhold }
133105644bfSAxel Dörfler 
134ffe72abdSAxel Dörfler 
135991c062fSAxel Dörfler BTextControl::BTextControl(const char* label, const char* text,
136991c062fSAxel Dörfler 		BMessage* message)
13793ba577cSStephan Aßmus 	: BControl(NULL, label, message,
13893ba577cSStephan Aßmus 		B_WILL_DRAW | B_NAVIGABLE | B_FRAME_EVENTS)
1399ecf9d1cSIngo Weinhold {
1409ecf9d1cSIngo Weinhold 	_InitData(label, text);
1419ecf9d1cSIngo Weinhold 	_ValidateLayout();
14252a38012Sejakowatz }
143058691d4SStefano Ceccherini 
144058691d4SStefano Ceccherini 
14552a38012Sejakowatz BTextControl::~BTextControl()
14652a38012Sejakowatz {
1479cb2dbe2SMarc Flerackers 	SetModificationMessage(NULL);
14852a38012Sejakowatz }
149058691d4SStefano Ceccherini 
150058691d4SStefano Ceccherini 
151ffe72abdSAxel Dörfler BTextControl::BTextControl(BMessage* archive)
152ffe72abdSAxel Dörfler 	: BControl(archive)
15352a38012Sejakowatz {
154ffe72abdSAxel Dörfler 	_InitData(Label(), NULL, archive);
15552a38012Sejakowatz 
156ffe72abdSAxel Dörfler 	int32 labelAlignment = B_ALIGN_LEFT;
157ffe72abdSAxel Dörfler 	int32 textAlignment = B_ALIGN_LEFT;
15852a38012Sejakowatz 
159ffe72abdSAxel Dörfler 	if (archive->HasInt32("_a_label"))
160ffe72abdSAxel Dörfler 		archive->FindInt32("_a_label", &labelAlignment);
16152a38012Sejakowatz 
162ffe72abdSAxel Dörfler 	if (archive->HasInt32("_a_text"))
163ffe72abdSAxel Dörfler 		archive->FindInt32("_a_text", &textAlignment);
16452a38012Sejakowatz 
165ffe72abdSAxel Dörfler 	SetAlignment((alignment)labelAlignment, (alignment)textAlignment);
1669cb2dbe2SMarc Flerackers 
167ffe72abdSAxel Dörfler 	if (archive->HasFloat("_divide"))
168ed1c257aSKarsten Heimrich 		archive->FindFloat("_divide", &fDivider);
1699cb2dbe2SMarc Flerackers 
170ffe72abdSAxel Dörfler 	if (archive->HasMessage("_mod_msg")) {
171ffe72abdSAxel Dörfler 		BMessage* message = new BMessage;
172ffe72abdSAxel Dörfler 		archive->FindMessage("_mod_msg", message);
173ffe72abdSAxel Dörfler 		SetModificationMessage(message);
1749cb2dbe2SMarc Flerackers 	}
17552a38012Sejakowatz }
176058691d4SStefano Ceccherini 
177058691d4SStefano Ceccherini 
178058691d4SStefano Ceccherini BArchivable*
179058691d4SStefano Ceccherini BTextControl::Instantiate(BMessage* archive)
18052a38012Sejakowatz {
1819cb2dbe2SMarc Flerackers 	if (validate_instantiation(archive, "BTextControl"))
1829cb2dbe2SMarc Flerackers 		return new BTextControl(archive);
183991c062fSAxel Dörfler 
18452a38012Sejakowatz 	return NULL;
18552a38012Sejakowatz }
186058691d4SStefano Ceccherini 
187058691d4SStefano Ceccherini 
188058691d4SStefano Ceccherini status_t
189058691d4SStefano Ceccherini BTextControl::Archive(BMessage *data, bool deep) const
19052a38012Sejakowatz {
1913a543720SJérôme Duval 	status_t ret = BControl::Archive(data, deep);
192058691d4SStefano Ceccherini 	alignment labelAlignment, textAlignment;
19352a38012Sejakowatz 
194058691d4SStefano Ceccherini 	GetAlignment(&labelAlignment, &textAlignment);
1959cb2dbe2SMarc Flerackers 
19611d7ecebSJérôme Duval 	if (ret == B_OK)
19711d7ecebSJérôme Duval 		ret = data->AddInt32("_a_label", labelAlignment);
19811d7ecebSJérôme Duval 	if (ret == B_OK)
19911d7ecebSJérôme Duval 		ret = data->AddInt32("_a_text", textAlignment);
20011d7ecebSJérôme Duval 	if (ret == B_OK)
20111d7ecebSJérôme Duval 		ret = data->AddFloat("_divide", Divider());
2029cb2dbe2SMarc Flerackers 
20311d7ecebSJérôme Duval 	if (ModificationMessage() && (ret == B_OK))
20411d7ecebSJérôme Duval 		ret = data->AddMessage("_mod_msg", ModificationMessage());
2059cb2dbe2SMarc Flerackers 
20611d7ecebSJérôme Duval 	return ret;
20752a38012Sejakowatz }
208058691d4SStefano Ceccherini 
209058691d4SStefano Ceccherini 
210058691d4SStefano Ceccherini void
211058691d4SStefano Ceccherini BTextControl::SetText(const char *text)
21252a38012Sejakowatz {
2139cb2dbe2SMarc Flerackers 	if (InvokeKind() != B_CONTROL_INVOKED)
2149cb2dbe2SMarc Flerackers 		return;
2159cb2dbe2SMarc Flerackers 
21693ba577cSStephan Aßmus 	CALLED();
21793ba577cSStephan Aßmus 
21852a38012Sejakowatz 	fText->SetText(text);
2199cb2dbe2SMarc Flerackers 
2209cb2dbe2SMarc Flerackers 	if (IsFocus())
2219cb2dbe2SMarc Flerackers 		fText->SetInitialText();
2229cb2dbe2SMarc Flerackers 
2239cb2dbe2SMarc Flerackers 	fText->Invalidate();
22452a38012Sejakowatz }
225058691d4SStefano Ceccherini 
226058691d4SStefano Ceccherini 
227058691d4SStefano Ceccherini const char *
228058691d4SStefano Ceccherini BTextControl::Text() const
22952a38012Sejakowatz {
23052a38012Sejakowatz 	return fText->Text();
23152a38012Sejakowatz }
232058691d4SStefano Ceccherini 
233058691d4SStefano Ceccherini 
234058691d4SStefano Ceccherini void
235058691d4SStefano Ceccherini BTextControl::SetValue(int32 value)
23652a38012Sejakowatz {
2379cb2dbe2SMarc Flerackers 	BControl::SetValue(value);
23852a38012Sejakowatz }
239058691d4SStefano Ceccherini 
240058691d4SStefano Ceccherini 
241058691d4SStefano Ceccherini status_t
242058691d4SStefano Ceccherini BTextControl::Invoke(BMessage *message)
24352a38012Sejakowatz {
244058691d4SStefano Ceccherini 	return BControl::Invoke(message);
24552a38012Sejakowatz }
246058691d4SStefano Ceccherini 
247058691d4SStefano Ceccherini 
248058691d4SStefano Ceccherini BTextView *
249058691d4SStefano Ceccherini BTextControl::TextView() const
25052a38012Sejakowatz {
2519cb2dbe2SMarc Flerackers 	return fText;
25252a38012Sejakowatz }
253058691d4SStefano Ceccherini 
254058691d4SStefano Ceccherini 
255058691d4SStefano Ceccherini void
256058691d4SStefano Ceccherini BTextControl::SetModificationMessage(BMessage *message)
25752a38012Sejakowatz {
2589cb2dbe2SMarc Flerackers 	delete fModificationMessage;
25952a38012Sejakowatz 	fModificationMessage = message;
26052a38012Sejakowatz }
261058691d4SStefano Ceccherini 
262058691d4SStefano Ceccherini 
263058691d4SStefano Ceccherini BMessage *
264058691d4SStefano Ceccherini BTextControl::ModificationMessage() const
26552a38012Sejakowatz {
26652a38012Sejakowatz 	return fModificationMessage;
26752a38012Sejakowatz }
268058691d4SStefano Ceccherini 
269058691d4SStefano Ceccherini 
270058691d4SStefano Ceccherini void
271058691d4SStefano Ceccherini BTextControl::SetAlignment(alignment labelAlignment, alignment textAlignment)
27252a38012Sejakowatz {
273058691d4SStefano Ceccherini 	fText->SetAlignment(textAlignment);
2749cb2dbe2SMarc Flerackers 	fText->AlignTextRect();
2759cb2dbe2SMarc Flerackers 
276058691d4SStefano Ceccherini 	if (fLabelAlign != labelAlignment) {
277058691d4SStefano Ceccherini 		fLabelAlign = labelAlignment;
2789cb2dbe2SMarc Flerackers 		Invalidate();
2799cb2dbe2SMarc Flerackers 	}
28052a38012Sejakowatz }
281058691d4SStefano Ceccherini 
282058691d4SStefano Ceccherini 
283058691d4SStefano Ceccherini void
284c432fbbbSAxel Dörfler BTextControl::GetAlignment(alignment* _label, alignment* _text) const
28552a38012Sejakowatz {
286c432fbbbSAxel Dörfler 	if (_label)
287c432fbbbSAxel Dörfler 		*_label = fLabelAlign;
288c432fbbbSAxel Dörfler 	if (_text)
289c432fbbbSAxel Dörfler 		*_text = fText->Alignment();
29052a38012Sejakowatz }
2919cb2dbe2SMarc Flerackers 
292058691d4SStefano Ceccherini 
293058691d4SStefano Ceccherini void
294058691d4SStefano Ceccherini BTextControl::SetDivider(float dividingLine)
295058691d4SStefano Ceccherini {
296a431f44bSStephan Aßmus 	fDivider = floorf(dividingLine + 0.5);
2972e6a5805SStephan Aßmus 
298a431f44bSStephan Aßmus 	_LayoutTextView();
29952a38012Sejakowatz 
300058691d4SStefano Ceccherini 	if (Window()) {
30152a38012Sejakowatz 		fText->Invalidate();
30252a38012Sejakowatz 		Invalidate();
30352a38012Sejakowatz 	}
3049cb2dbe2SMarc Flerackers }
305058691d4SStefano Ceccherini 
306058691d4SStefano Ceccherini 
307058691d4SStefano Ceccherini float
308058691d4SStefano Ceccherini BTextControl::Divider() const
30952a38012Sejakowatz {
31052a38012Sejakowatz 	return fDivider;
31152a38012Sejakowatz }
312058691d4SStefano Ceccherini 
313058691d4SStefano Ceccherini 
314058691d4SStefano Ceccherini void
315058691d4SStefano Ceccherini BTextControl::Draw(BRect updateRect)
31652a38012Sejakowatz {
317c432fbbbSAxel Dörfler 	rgb_color noTint = ui_color(B_PANEL_BACKGROUND_COLOR);
318c432fbbbSAxel Dörfler 	rgb_color lighten1 = tint_color(noTint, B_LIGHTEN_1_TINT);
319c432fbbbSAxel Dörfler 	rgb_color lighten2 = tint_color(noTint, B_LIGHTEN_2_TINT);
320c432fbbbSAxel Dörfler 	rgb_color lightenMax = tint_color(noTint, B_LIGHTEN_MAX_TINT);
321c432fbbbSAxel Dörfler 	rgb_color darken1 = tint_color(noTint, B_DARKEN_1_TINT);
322c432fbbbSAxel Dörfler 	rgb_color darken2 = tint_color(noTint, B_DARKEN_2_TINT);
323c432fbbbSAxel Dörfler 	rgb_color darken4 = tint_color(noTint, B_DARKEN_4_TINT);
324c432fbbbSAxel Dörfler 	rgb_color navigationColor = ui_color(B_KEYBOARD_NAVIGATION_COLOR);
3259cb2dbe2SMarc Flerackers 
3269cb2dbe2SMarc Flerackers 	bool enabled = IsEnabled();
3279cb2dbe2SMarc Flerackers 	bool active = false;
3289cb2dbe2SMarc Flerackers 
3299cb2dbe2SMarc Flerackers 	if (fText->IsFocus() && Window()->IsActive())
3309cb2dbe2SMarc Flerackers 		active = true;
3319cb2dbe2SMarc Flerackers 
332455d1c46SAxel Dörfler 	// outer bevel
333455d1c46SAxel Dörfler 
334a431f44bSStephan Aßmus 	BRect rect = fText->Frame();
335a431f44bSStephan Aßmus 	rect.InsetBy(-2, -2);
336455d1c46SAxel Dörfler 
337455d1c46SAxel Dörfler 	if (enabled)
338455d1c46SAxel Dörfler 		SetHighColor(darken1);
339455d1c46SAxel Dörfler 	else
340455d1c46SAxel Dörfler 		SetHighColor(noTint);
341455d1c46SAxel Dörfler 
342455d1c46SAxel Dörfler 	StrokeLine(rect.LeftBottom(), rect.LeftTop());
343455d1c46SAxel Dörfler 	StrokeLine(rect.RightTop());
344455d1c46SAxel Dörfler 
345455d1c46SAxel Dörfler 	if (enabled)
346455d1c46SAxel Dörfler 		SetHighColor(lighten2);
347455d1c46SAxel Dörfler 	else
348455d1c46SAxel Dörfler 		SetHighColor(lighten1);
349455d1c46SAxel Dörfler 
350455d1c46SAxel Dörfler 	StrokeLine(BPoint(rect.left + 1.0f, rect.bottom), rect.RightBottom());
351455d1c46SAxel Dörfler 	StrokeLine(BPoint(rect.right, rect.top + 1.0f), rect.RightBottom());
352455d1c46SAxel Dörfler 
353455d1c46SAxel Dörfler 	// inner bevel
354455d1c46SAxel Dörfler 
355455d1c46SAxel Dörfler 	rect.InsetBy(1.0f, 1.0f);
3569cb2dbe2SMarc Flerackers 
357058691d4SStefano Ceccherini 	if (active) {
358105644bfSAxel Dörfler 		SetHighColor(navigationColor);
3599cb2dbe2SMarc Flerackers 		StrokeRect(rect);
360058691d4SStefano Ceccherini 	} else {
3619cb2dbe2SMarc Flerackers 		if (enabled)
3629cb2dbe2SMarc Flerackers 			SetHighColor(darken4);
3639cb2dbe2SMarc Flerackers 		else
3649cb2dbe2SMarc Flerackers 			SetHighColor(darken2);
3659cb2dbe2SMarc Flerackers 
3669cb2dbe2SMarc Flerackers 		StrokeLine(rect.LeftTop(), rect.LeftBottom());
3679cb2dbe2SMarc Flerackers 		StrokeLine(rect.LeftTop(), rect.RightTop());
3689cb2dbe2SMarc Flerackers 
369105644bfSAxel Dörfler 		SetHighColor(noTint);
3709cb2dbe2SMarc Flerackers 		StrokeLine(BPoint(rect.left + 1.0f, rect.bottom), rect.RightBottom());
3719cb2dbe2SMarc Flerackers 		StrokeLine(BPoint(rect.right, rect.top + 1.0f));
3729cb2dbe2SMarc Flerackers 	}
3739cb2dbe2SMarc Flerackers 
3747a25fcafSStefano Ceccherini 	// label
3757a25fcafSStefano Ceccherini 
376058691d4SStefano Ceccherini 	if (Label()) {
377349c911eSStephan Aßmus 		_ValidateLayoutData();
378349c911eSStephan Aßmus 		font_height& fontHeight = fLayoutData->font_info;
3799cb2dbe2SMarc Flerackers 
380a68292ddSStephan Aßmus 		float y = Bounds().top + (Bounds().Height() + 1 - fontHeight.ascent
381a68292ddSStephan Aßmus 			- fontHeight.descent) / 2 + fontHeight.ascent;
38252a38012Sejakowatz 		float x;
3839cb2dbe2SMarc Flerackers 
3847a25fcafSStefano Ceccherini 		float labelWidth = StringWidth(Label());
385058691d4SStefano Ceccherini 		switch (fLabelAlign) {
38652a38012Sejakowatz 			case B_ALIGN_RIGHT:
387349c911eSStephan Aßmus 				x = fDivider - labelWidth - kLabelInputSpacing;
38852a38012Sejakowatz 				break;
38952a38012Sejakowatz 
39052a38012Sejakowatz 			case B_ALIGN_CENTER:
391b8872c02SStephan Aßmus 				x = fDivider - labelWidth / 2.0;
39252a38012Sejakowatz 				break;
39352a38012Sejakowatz 
39452a38012Sejakowatz 			default:
395b8872c02SStephan Aßmus 				x = 0.0;
39652a38012Sejakowatz 				break;
39752a38012Sejakowatz 		}
39852a38012Sejakowatz 
3992c5a8894SStephan Aßmus 		BRect labelArea(x, Bounds().top, x + labelWidth, Bounds().bottom);
4007a25fcafSStefano Ceccherini 		if (x < fDivider && updateRect.Intersects(labelArea)) {
401349c911eSStephan Aßmus 			labelArea.right = fText->Frame().left - kLabelInputSpacing;
4027a25fcafSStefano Ceccherini 
4037a25fcafSStefano Ceccherini 			BRegion clipRegion(labelArea);
4047a25fcafSStefano Ceccherini 			ConstrainClippingRegion(&clipRegion);
405c432fbbbSAxel Dörfler 			SetHighColor(IsEnabled() ? ui_color(B_CONTROL_TEXT_COLOR)
406fa815db3SAxel Dörfler 				: tint_color(noTint, B_DISABLED_LABEL_TINT));
40752a38012Sejakowatz 			DrawString(Label(), BPoint(x, y));
40852a38012Sejakowatz 		}
40952a38012Sejakowatz 	}
4107a25fcafSStefano Ceccherini }
411058691d4SStefano Ceccherini 
412058691d4SStefano Ceccherini 
413058691d4SStefano Ceccherini void
414058691d4SStefano Ceccherini BTextControl::MouseDown(BPoint where)
41552a38012Sejakowatz {
416058691d4SStefano Ceccherini 	if (!fText->IsFocus()) {
4179cb2dbe2SMarc Flerackers 		fText->MakeFocus(true);
41852a38012Sejakowatz 	}
41952a38012Sejakowatz }
420058691d4SStefano Ceccherini 
421058691d4SStefano Ceccherini 
422058691d4SStefano Ceccherini void
423058691d4SStefano Ceccherini BTextControl::AttachedToWindow()
42452a38012Sejakowatz {
42552a38012Sejakowatz 	BControl::AttachedToWindow();
42652a38012Sejakowatz 
42779c35b39SAxel Dörfler 	_UpdateTextViewColors(IsEnabled());
4283a3f6c1eSAxel Dörfler 	fText->MakeEditable(IsEnabled());
42952a38012Sejakowatz }
430058691d4SStefano Ceccherini 
431058691d4SStefano Ceccherini 
432058691d4SStefano Ceccherini void
433058691d4SStefano Ceccherini BTextControl::MakeFocus(bool state)
43452a38012Sejakowatz {
4356d8d6cadSStephan Aßmus 	if (state != fText->IsFocus()) {
43652a38012Sejakowatz 		fText->MakeFocus(state);
4379cb2dbe2SMarc Flerackers 
4389cb2dbe2SMarc Flerackers 		if (state)
4399cb2dbe2SMarc Flerackers 			fText->SelectAll();
44052a38012Sejakowatz 	}
4416d8d6cadSStephan Aßmus }
442058691d4SStefano Ceccherini 
443058691d4SStefano Ceccherini 
444058691d4SStefano Ceccherini void
44579c35b39SAxel Dörfler BTextControl::SetEnabled(bool enabled)
44652a38012Sejakowatz {
44779c35b39SAxel Dörfler 	if (IsEnabled() == enabled)
4489cb2dbe2SMarc Flerackers 		return;
4499cb2dbe2SMarc Flerackers 
450058691d4SStefano Ceccherini 	if (Window()) {
45179c35b39SAxel Dörfler 		fText->MakeEditable(enabled);
4529cb2dbe2SMarc Flerackers 
45379c35b39SAxel Dörfler 		_UpdateTextViewColors(enabled);
4549cb2dbe2SMarc Flerackers 
4559cb2dbe2SMarc Flerackers 		fText->Invalidate();
4569cb2dbe2SMarc Flerackers 		Window()->UpdateIfNeeded();
4579cb2dbe2SMarc Flerackers 	}
4589cb2dbe2SMarc Flerackers 
45979c35b39SAxel Dörfler 	BControl::SetEnabled(enabled);
46052a38012Sejakowatz }
461058691d4SStefano Ceccherini 
462058691d4SStefano Ceccherini 
463058691d4SStefano Ceccherini void
464105644bfSAxel Dörfler BTextControl::GetPreferredSize(float *_width, float *_height)
46552a38012Sejakowatz {
466349c911eSStephan Aßmus 	CALLED();
46752a38012Sejakowatz 
468349c911eSStephan Aßmus 	_ValidateLayoutData();
469105644bfSAxel Dörfler 
470*1aaf53ecSStephan Aßmus 	if (_width) {
471*1aaf53ecSStephan Aßmus 		float minWidth = fLayoutData->min.width;
472*1aaf53ecSStephan Aßmus 		if (Label() == NULL && !(Flags() & B_SUPPORTS_LAYOUT)) {
473*1aaf53ecSStephan Aßmus 			// Indeed, only if there is no label! BeOS backwards compatible
474*1aaf53ecSStephan Aßmus 			// behavior:
475*1aaf53ecSStephan Aßmus 			minWidth = max_c(minWidth, Bounds().Width());
476*1aaf53ecSStephan Aßmus 		}
477*1aaf53ecSStephan Aßmus 		*_width = minWidth;
478*1aaf53ecSStephan Aßmus 	}
479349c911eSStephan Aßmus 
480349c911eSStephan Aßmus 	if (_height)
481349c911eSStephan Aßmus 		*_height = fLayoutData->min.height;
48252a38012Sejakowatz }
483058691d4SStefano Ceccherini 
484058691d4SStefano Ceccherini 
485058691d4SStefano Ceccherini void
486058691d4SStefano Ceccherini BTextControl::ResizeToPreferred()
48752a38012Sejakowatz {
488105644bfSAxel Dörfler 	BView::ResizeToPreferred();
4891bdc2a52SKarsten Heimrich 
4901bdc2a52SKarsten Heimrich 	fDivider = 0.0;
4911bdc2a52SKarsten Heimrich 	const char* label = Label();
4921bdc2a52SKarsten Heimrich 	if (label)
4931bdc2a52SKarsten Heimrich 		fDivider = ceil(StringWidth(label)) + 2.0;
4941bdc2a52SKarsten Heimrich 
4951bdc2a52SKarsten Heimrich 	_LayoutTextView();
49652a38012Sejakowatz }
497058691d4SStefano Ceccherini 
498058691d4SStefano Ceccherini 
499058691d4SStefano Ceccherini void
500058691d4SStefano Ceccherini BTextControl::SetFlags(uint32 flags)
50152a38012Sejakowatz {
5029cb2dbe2SMarc Flerackers 	// If the textview is navigable, set it to not navigable if needed
5039cb2dbe2SMarc Flerackers 	// Else if it is not navigable, set it to navigable if needed
504058691d4SStefano Ceccherini 	if (fText->Flags() & B_NAVIGABLE) {
5059cb2dbe2SMarc Flerackers 		if (!(flags & B_NAVIGABLE))
5069cb2dbe2SMarc Flerackers 			fText->SetFlags(fText->Flags() & ~B_NAVIGABLE);
507058691d4SStefano Ceccherini 
508058691d4SStefano Ceccherini 	} else {
5099cb2dbe2SMarc Flerackers 		if (flags & B_NAVIGABLE)
5109cb2dbe2SMarc Flerackers 			fText->SetFlags(fText->Flags() | B_NAVIGABLE);
5119cb2dbe2SMarc Flerackers 	}
5129cb2dbe2SMarc Flerackers 
5139cb2dbe2SMarc Flerackers 	// Don't make this one navigable
5149cb2dbe2SMarc Flerackers 	flags &= ~B_NAVIGABLE;
5159cb2dbe2SMarc Flerackers 
51652a38012Sejakowatz 	BView::SetFlags(flags);
51752a38012Sejakowatz }
518058691d4SStefano Ceccherini 
519058691d4SStefano Ceccherini 
520058691d4SStefano Ceccherini void
521058691d4SStefano Ceccherini BTextControl::MessageReceived(BMessage *msg)
52252a38012Sejakowatz {
523058691d4SStefano Ceccherini 	switch(msg->what) {
5249cb2dbe2SMarc Flerackers 		case B_SET_PROPERTY:
5259cb2dbe2SMarc Flerackers 		case B_GET_PROPERTY:
5269cb2dbe2SMarc Flerackers 			// TODO
52752a38012Sejakowatz 			break;
52852a38012Sejakowatz 		default:
52952a38012Sejakowatz 			BControl::MessageReceived(msg);
53052a38012Sejakowatz 			break;
53152a38012Sejakowatz 	}
53252a38012Sejakowatz }
533058691d4SStefano Ceccherini 
534058691d4SStefano Ceccherini 
535058691d4SStefano Ceccherini BHandler *
536058691d4SStefano Ceccherini BTextControl::ResolveSpecifier(BMessage *msg, int32 index,
53752a38012Sejakowatz 										 BMessage *specifier, int32 form,
53852a38012Sejakowatz 										 const char *property)
53952a38012Sejakowatz {
5409cb2dbe2SMarc Flerackers 	/*
5419cb2dbe2SMarc Flerackers 	BPropertyInfo propInfo(prop_list);
5429cb2dbe2SMarc Flerackers 	BHandler *target = NULL;
5439cb2dbe2SMarc Flerackers 
5449cb2dbe2SMarc Flerackers 	if (propInfo.FindMatch(message, 0, specifier, what, property) < B_OK)
5459cb2dbe2SMarc Flerackers 		return BControl::ResolveSpecifier(message, index, specifier, what,
5469cb2dbe2SMarc Flerackers 			property);
5479cb2dbe2SMarc Flerackers 	else
5489cb2dbe2SMarc Flerackers 		return this;
5499cb2dbe2SMarc Flerackers 	*/
5509cb2dbe2SMarc Flerackers 	return BControl::ResolveSpecifier(msg, index, specifier, form, property);
55152a38012Sejakowatz }
552058691d4SStefano Ceccherini 
553058691d4SStefano Ceccherini 
554058691d4SStefano Ceccherini status_t
555058691d4SStefano Ceccherini BTextControl::GetSupportedSuites(BMessage *data)
55652a38012Sejakowatz {
5579cb2dbe2SMarc Flerackers 	return BControl::GetSupportedSuites(data);
55852a38012Sejakowatz }
559058691d4SStefano Ceccherini 
560058691d4SStefano Ceccherini 
561058691d4SStefano Ceccherini void
562058691d4SStefano Ceccherini BTextControl::MouseUp(BPoint pt)
56352a38012Sejakowatz {
56452a38012Sejakowatz 	BControl::MouseUp(pt);
56552a38012Sejakowatz }
566058691d4SStefano Ceccherini 
567058691d4SStefano Ceccherini 
568058691d4SStefano Ceccherini void
569058691d4SStefano Ceccherini BTextControl::MouseMoved(BPoint pt, uint32 code, const BMessage *msg)
57052a38012Sejakowatz {
57152a38012Sejakowatz 	BControl::MouseMoved(pt, code, msg);
57252a38012Sejakowatz }
573058691d4SStefano Ceccherini 
574058691d4SStefano Ceccherini 
575058691d4SStefano Ceccherini void
576058691d4SStefano Ceccherini BTextControl::DetachedFromWindow()
57752a38012Sejakowatz {
57852a38012Sejakowatz 	BControl::DetachedFromWindow();
57952a38012Sejakowatz }
580058691d4SStefano Ceccherini 
581058691d4SStefano Ceccherini 
582058691d4SStefano Ceccherini void
583058691d4SStefano Ceccherini BTextControl::AllAttached()
58452a38012Sejakowatz {
58552a38012Sejakowatz 	BControl::AllAttached();
58652a38012Sejakowatz }
587058691d4SStefano Ceccherini 
588058691d4SStefano Ceccherini 
589058691d4SStefano Ceccherini void
590058691d4SStefano Ceccherini BTextControl::AllDetached()
59152a38012Sejakowatz {
59252a38012Sejakowatz 	BControl::AllDetached();
59352a38012Sejakowatz }
594058691d4SStefano Ceccherini 
595058691d4SStefano Ceccherini 
596058691d4SStefano Ceccherini void
597058691d4SStefano Ceccherini BTextControl::FrameMoved(BPoint newPosition)
59852a38012Sejakowatz {
59952a38012Sejakowatz 	BControl::FrameMoved(newPosition);
60052a38012Sejakowatz }
601058691d4SStefano Ceccherini 
602058691d4SStefano Ceccherini 
603058691d4SStefano Ceccherini void
604ffe72abdSAxel Dörfler BTextControl::FrameResized(float width, float height)
60552a38012Sejakowatz {
60693ba577cSStephan Aßmus 	CALLED();
60793ba577cSStephan Aßmus 
608ffe72abdSAxel Dörfler 	BControl::FrameResized(width, height);
609ffe72abdSAxel Dörfler 
610349c911eSStephan Aßmus 	// TODO: this causes flickering still...
611349c911eSStephan Aßmus 
612ffe72abdSAxel Dörfler 	// changes in width
613ffe72abdSAxel Dörfler 
614ffe72abdSAxel Dörfler 	BRect bounds = Bounds();
615ffe72abdSAxel Dörfler 
616349c911eSStephan Aßmus 	if (bounds.Width() > fLayoutData->previous_width) {
617ffe72abdSAxel Dörfler 		// invalidate the region between the old and the new right border
618ffe72abdSAxel Dörfler 		BRect rect = bounds;
619349c911eSStephan Aßmus 		rect.left += fLayoutData->previous_width - kFrameMargin;
620ffe72abdSAxel Dörfler 		rect.right--;
621ffe72abdSAxel Dörfler 		Invalidate(rect);
622349c911eSStephan Aßmus 	} else if (bounds.Width() < fLayoutData->previous_width) {
623ffe72abdSAxel Dörfler 		// invalidate the region of the new right border
624ffe72abdSAxel Dörfler 		BRect rect = bounds;
625349c911eSStephan Aßmus 		rect.left = rect.right - kFrameMargin;
626ffe72abdSAxel Dörfler 		Invalidate(rect);
627ffe72abdSAxel Dörfler 	}
628ffe72abdSAxel Dörfler 
629ffe72abdSAxel Dörfler 	// changes in height
630ffe72abdSAxel Dörfler 
631349c911eSStephan Aßmus 	if (bounds.Height() > fLayoutData->previous_height) {
632ffe72abdSAxel Dörfler 		// invalidate the region between the old and the new bottom border
633ffe72abdSAxel Dörfler 		BRect rect = bounds;
634349c911eSStephan Aßmus 		rect.top += fLayoutData->previous_height - kFrameMargin;
635ffe72abdSAxel Dörfler 		rect.bottom--;
636ffe72abdSAxel Dörfler 		Invalidate(rect);
637349c911eSStephan Aßmus 		// invalidate label area
638349c911eSStephan Aßmus 		rect = bounds;
639349c911eSStephan Aßmus 		rect.right = fDivider;
640349c911eSStephan Aßmus 		Invalidate(rect);
641349c911eSStephan Aßmus 	} else if (bounds.Height() < fLayoutData->previous_height) {
642ffe72abdSAxel Dörfler 		// invalidate the region of the new bottom border
643ffe72abdSAxel Dörfler 		BRect rect = bounds;
644349c911eSStephan Aßmus 		rect.top = rect.bottom - kFrameMargin;
645349c911eSStephan Aßmus 		Invalidate(rect);
646349c911eSStephan Aßmus 		// invalidate label area
647349c911eSStephan Aßmus 		rect = bounds;
648349c911eSStephan Aßmus 		rect.right = fDivider;
649ffe72abdSAxel Dörfler 		Invalidate(rect);
650ffe72abdSAxel Dörfler 	}
651ffe72abdSAxel Dörfler 
652349c911eSStephan Aßmus 	fLayoutData->previous_width = bounds.Width();
653349c911eSStephan Aßmus 	fLayoutData->previous_height = bounds.Height();
65493ba577cSStephan Aßmus 
65593ba577cSStephan Aßmus 	TRACE("width: %.2f, height: %.2f\n", bounds.Width(), bounds.Height());
65652a38012Sejakowatz }
657058691d4SStefano Ceccherini 
658058691d4SStefano Ceccherini 
659058691d4SStefano Ceccherini void
660058691d4SStefano Ceccherini BTextControl::WindowActivated(bool active)
66152a38012Sejakowatz {
6626d8d6cadSStephan Aßmus 	if (fText->IsFocus()) {
663dde10e45SStephan Aßmus 		// invalidate to remove/show focus indication
6642c5a8894SStephan Aßmus 		BRect rect = fText->Frame();
6652c5a8894SStephan Aßmus 		rect.InsetBy(-1, -1);
6666d8d6cadSStephan Aßmus 		Invalidate(rect);
667dde10e45SStephan Aßmus 
668dde10e45SStephan Aßmus 		// help out embedded text view which doesn't
669dde10e45SStephan Aßmus 		// get notified of this
670dde10e45SStephan Aßmus 		fText->Invalidate();
6716d8d6cadSStephan Aßmus 	}
67252a38012Sejakowatz }
673058691d4SStefano Ceccherini 
674058691d4SStefano Ceccherini 
675349c911eSStephan Aßmus BSize
676349c911eSStephan Aßmus BTextControl::MinSize()
67752a38012Sejakowatz {
678349c911eSStephan Aßmus 	CALLED();
679349c911eSStephan Aßmus 
680349c911eSStephan Aßmus 	_ValidateLayoutData();
681349c911eSStephan Aßmus 	return BLayoutUtils::ComposeSize(ExplicitMinSize(), fLayoutData->min);
682349c911eSStephan Aßmus }
683349c911eSStephan Aßmus 
684349c911eSStephan Aßmus 
685349c911eSStephan Aßmus BSize
686349c911eSStephan Aßmus BTextControl::MaxSize()
687349c911eSStephan Aßmus {
688349c911eSStephan Aßmus 	CALLED();
689349c911eSStephan Aßmus 
690349c911eSStephan Aßmus 	_ValidateLayoutData();
691349c911eSStephan Aßmus 
692349c911eSStephan Aßmus 	BSize max = fLayoutData->min;
693349c911eSStephan Aßmus 	max.width = B_SIZE_UNLIMITED;
694349c911eSStephan Aßmus 
695349c911eSStephan Aßmus 	return BLayoutUtils::ComposeSize(ExplicitMaxSize(), max);
696349c911eSStephan Aßmus }
697349c911eSStephan Aßmus 
698349c911eSStephan Aßmus 
699349c911eSStephan Aßmus BSize
700349c911eSStephan Aßmus BTextControl::PreferredSize()
701349c911eSStephan Aßmus {
702349c911eSStephan Aßmus 	CALLED();
703349c911eSStephan Aßmus 
704349c911eSStephan Aßmus 	_ValidateLayoutData();
705349c911eSStephan Aßmus 	return BLayoutUtils::ComposeSize(ExplicitPreferredSize(), fLayoutData->min);
706349c911eSStephan Aßmus }
707349c911eSStephan Aßmus 
708349c911eSStephan Aßmus 
709349c911eSStephan Aßmus void
710349c911eSStephan Aßmus BTextControl::InvalidateLayout(bool descendants)
711349c911eSStephan Aßmus {
712349c911eSStephan Aßmus 	CALLED();
713349c911eSStephan Aßmus 
714349c911eSStephan Aßmus 	fLayoutData->valid = false;
715349c911eSStephan Aßmus 
716349c911eSStephan Aßmus 	BView::InvalidateLayout(descendants);
71752a38012Sejakowatz }
718058691d4SStefano Ceccherini 
719058691d4SStefano Ceccherini 
7209ecf9d1cSIngo Weinhold BLayoutItem*
7219ecf9d1cSIngo Weinhold BTextControl::CreateLabelLayoutItem()
7229ecf9d1cSIngo Weinhold {
723349c911eSStephan Aßmus 	if (!fLayoutData->label_layout_item)
724349c911eSStephan Aßmus 		fLayoutData->label_layout_item = new LabelLayoutItem(this);
725349c911eSStephan Aßmus 	return fLayoutData->label_layout_item;
7269ecf9d1cSIngo Weinhold }
7279ecf9d1cSIngo Weinhold 
7289ecf9d1cSIngo Weinhold 
7299ecf9d1cSIngo Weinhold BLayoutItem*
7309ecf9d1cSIngo Weinhold BTextControl::CreateTextViewLayoutItem()
7319ecf9d1cSIngo Weinhold {
732349c911eSStephan Aßmus 	if (!fLayoutData->text_view_layout_item)
733349c911eSStephan Aßmus 		fLayoutData->text_view_layout_item = new TextViewLayoutItem(this);
734349c911eSStephan Aßmus 	return fLayoutData->text_view_layout_item;
735349c911eSStephan Aßmus }
736349c911eSStephan Aßmus 
737349c911eSStephan Aßmus 
738349c911eSStephan Aßmus void
739349c911eSStephan Aßmus BTextControl::DoLayout()
740349c911eSStephan Aßmus {
741349c911eSStephan Aßmus 	// Bail out, if we shan't do layout.
742349c911eSStephan Aßmus 	if (!(Flags() & B_SUPPORTS_LAYOUT))
743349c911eSStephan Aßmus 		return;
744349c911eSStephan Aßmus 
745349c911eSStephan Aßmus 	CALLED();
746349c911eSStephan Aßmus 
747349c911eSStephan Aßmus 	// If the user set a layout, we let the base class version call its
748349c911eSStephan Aßmus 	// hook.
749349c911eSStephan Aßmus 	if (GetLayout()) {
750349c911eSStephan Aßmus 		BView::DoLayout();
751349c911eSStephan Aßmus 		return;
752349c911eSStephan Aßmus 	}
753349c911eSStephan Aßmus 
754349c911eSStephan Aßmus 	_ValidateLayoutData();
755349c911eSStephan Aßmus 
756349c911eSStephan Aßmus 	// validate current size
757349c911eSStephan Aßmus 	BSize size(Bounds().Size());
758349c911eSStephan Aßmus 	if (size.width < fLayoutData->min.width)
759349c911eSStephan Aßmus 		size.width = fLayoutData->min.width;
760349c911eSStephan Aßmus 	if (size.height < fLayoutData->min.height)
761349c911eSStephan Aßmus 		size.height = fLayoutData->min.height;
762349c911eSStephan Aßmus 
763349c911eSStephan Aßmus 	// divider
764349c911eSStephan Aßmus 	float divider = 0;
765349c911eSStephan Aßmus 	if (fLayoutData->label_layout_item && fLayoutData->text_view_layout_item) {
766349c911eSStephan Aßmus 		// We have layout items. They define the divider location.
767349c911eSStephan Aßmus 		divider = fLayoutData->text_view_layout_item->Frame().left
768349c911eSStephan Aßmus 			- fLayoutData->label_layout_item->Frame().left;
769349c911eSStephan Aßmus 	} else {
770349c911eSStephan Aßmus 		if (fLayoutData->label_width > 0)
771349c911eSStephan Aßmus 			divider = fLayoutData->label_width + 5;
772349c911eSStephan Aßmus 	}
773349c911eSStephan Aßmus 
774349c911eSStephan Aßmus 	// text view
775349c911eSStephan Aßmus 	BRect dirty(fText->Frame());
776349c911eSStephan Aßmus 	BRect textFrame(divider + 1, kFrameMargin, size.width - 2,
777349c911eSStephan Aßmus 		size.height - kFrameMargin);
778349c911eSStephan Aßmus 
779349c911eSStephan Aßmus 	// place the text view and set the divider
780349c911eSStephan Aßmus 	BLayoutUtils::AlignInFrame(fText, textFrame);
781349c911eSStephan Aßmus 
782349c911eSStephan Aßmus 	fDivider = divider;
783349c911eSStephan Aßmus 
784349c911eSStephan Aßmus 	// invalidate dirty region
785349c911eSStephan Aßmus 	dirty = dirty | fText->Frame();
786349c911eSStephan Aßmus 	dirty.InsetBy(-kFrameMargin, -kFrameMargin);
787349c911eSStephan Aßmus 
788349c911eSStephan Aßmus 	Invalidate(dirty);
789349c911eSStephan Aßmus }
790349c911eSStephan Aßmus 
791349c911eSStephan Aßmus 
792349c911eSStephan Aßmus // #pragma mark -
793349c911eSStephan Aßmus 
794349c911eSStephan Aßmus 
795349c911eSStephan Aßmus status_t
796349c911eSStephan Aßmus BTextControl::Perform(perform_code d, void *arg)
797349c911eSStephan Aßmus {
798349c911eSStephan Aßmus 	return BControl::Perform(d, arg);
7999ecf9d1cSIngo Weinhold }
8009ecf9d1cSIngo Weinhold 
8019ecf9d1cSIngo Weinhold 
8029cb2dbe2SMarc Flerackers void BTextControl::_ReservedTextControl1() {}
8039cb2dbe2SMarc Flerackers void BTextControl::_ReservedTextControl2() {}
8049cb2dbe2SMarc Flerackers void BTextControl::_ReservedTextControl3() {}
8059cb2dbe2SMarc Flerackers void BTextControl::_ReservedTextControl4() {}
806058691d4SStefano Ceccherini 
807058691d4SStefano Ceccherini 
808058691d4SStefano Ceccherini BTextControl &
809058691d4SStefano Ceccherini BTextControl::operator=(const BTextControl&)
81052a38012Sejakowatz {
81152a38012Sejakowatz 	return *this;
81252a38012Sejakowatz }
813058691d4SStefano Ceccherini 
814058691d4SStefano Ceccherini 
815058691d4SStefano Ceccherini void
81679c35b39SAxel Dörfler BTextControl::_UpdateTextViewColors(bool enabled)
8173a3f6c1eSAxel Dörfler {
8183a3f6c1eSAxel Dörfler 	rgb_color textColor;
819aae7000dSAxel Dörfler 	rgb_color color;
8203a3f6c1eSAxel Dörfler 	BFont font;
8213a3f6c1eSAxel Dörfler 
822aae7000dSAxel Dörfler 	fText->GetFontAndColor(0, &font);
8233a3f6c1eSAxel Dörfler 
8243a3f6c1eSAxel Dörfler 	if (enabled)
825aae7000dSAxel Dörfler 		textColor = ui_color(B_DOCUMENT_TEXT_COLOR);
82612aefeb4SAxel Dörfler 	else {
82712aefeb4SAxel Dörfler 		textColor = tint_color(ui_color(B_PANEL_BACKGROUND_COLOR),
82812aefeb4SAxel Dörfler 			B_DISABLED_LABEL_TINT);
82912aefeb4SAxel Dörfler 	}
8303a3f6c1eSAxel Dörfler 
8313a3f6c1eSAxel Dörfler 	fText->SetFontAndColor(&font, B_FONT_ALL, &textColor);
8323a3f6c1eSAxel Dörfler 
8333a3f6c1eSAxel Dörfler 	if (enabled) {
834aae7000dSAxel Dörfler 		color = ui_color(B_DOCUMENT_BACKGROUND_COLOR);
8353a3f6c1eSAxel Dörfler 	} else {
8363a3f6c1eSAxel Dörfler 		color = tint_color(ui_color(B_PANEL_BACKGROUND_COLOR),
8373a3f6c1eSAxel Dörfler 			B_LIGHTEN_2_TINT);
8383a3f6c1eSAxel Dörfler 	}
8393a3f6c1eSAxel Dörfler 
8403a3f6c1eSAxel Dörfler 	fText->SetViewColor(color);
8413a3f6c1eSAxel Dörfler 	fText->SetLowColor(color);
8423a3f6c1eSAxel Dörfler }
8433a3f6c1eSAxel Dörfler 
8443a3f6c1eSAxel Dörfler 
8453a3f6c1eSAxel Dörfler void
846ffe72abdSAxel Dörfler BTextControl::_CommitValue()
8479cb2dbe2SMarc Flerackers {
8489cb2dbe2SMarc Flerackers }
849058691d4SStefano Ceccherini 
850058691d4SStefano Ceccherini 
851058691d4SStefano Ceccherini void
852ffe72abdSAxel Dörfler BTextControl::_InitData(const char* label, const char* initialText,
853ffe72abdSAxel Dörfler 	BMessage* archive)
8549cb2dbe2SMarc Flerackers {
8559cb2dbe2SMarc Flerackers 	BRect bounds(Bounds());
8569cb2dbe2SMarc Flerackers 
8579cb2dbe2SMarc Flerackers 	fText = NULL;
8589cb2dbe2SMarc Flerackers 	fModificationMessage = NULL;
8599cb2dbe2SMarc Flerackers 	fLabelAlign = B_ALIGN_LEFT;
8609cb2dbe2SMarc Flerackers 	fDivider = 0.0f;
861349c911eSStephan Aßmus 	fLayoutData = new LayoutData(bounds.Width(), bounds.Height());
8629cb2dbe2SMarc Flerackers 
8639cb2dbe2SMarc Flerackers 	int32 flags = 0;
8649cb2dbe2SMarc Flerackers 
865918a22d9SDarkWyrm 	BFont font(be_plain_font);
8669cb2dbe2SMarc Flerackers 
867ffe72abdSAxel Dörfler 	if (!archive || !archive->HasString("_fname"))
868058691d4SStefano Ceccherini 		flags |= B_FONT_FAMILY_AND_STYLE;
8699cb2dbe2SMarc Flerackers 
870ffe72abdSAxel Dörfler 	if (!archive || !archive->HasFloat("_fflt"))
871058691d4SStefano Ceccherini 		flags |= B_FONT_SIZE;
8729cb2dbe2SMarc Flerackers 
8739cb2dbe2SMarc Flerackers 	if (flags != 0)
8749cb2dbe2SMarc Flerackers 		SetFont(&font, flags);
8759cb2dbe2SMarc Flerackers 
8769cb2dbe2SMarc Flerackers 	if (label)
8772e6a5805SStephan Aßmus 		fDivider = floorf(bounds.Width() / 2.0f);
8789cb2dbe2SMarc Flerackers 
879105644bfSAxel Dörfler 	uint32 navigableFlags = Flags() & B_NAVIGABLE;
88093ba577cSStephan Aßmus 	if (navigableFlags != 0)
88193ba577cSStephan Aßmus 		BView::SetFlags(Flags() & ~B_NAVIGABLE);
8829cb2dbe2SMarc Flerackers 
883ffe72abdSAxel Dörfler 	if (archive)
884b8872c02SStephan Aßmus 		fText = static_cast<BPrivate::_BTextInput_*>(FindView("_input_"));
885991c062fSAxel Dörfler 
886991c062fSAxel Dörfler 	if (fText == NULL) {
887ee2a3473SStephan Aßmus 		BRect frame(fDivider, bounds.top, bounds.right, bounds.bottom);
888105644bfSAxel Dörfler 		// we are stroking the frame around the text view, which
8892e6a5805SStephan Aßmus 		// is 2 pixels wide
890349c911eSStephan Aßmus 		frame.InsetBy(kFrameMargin, kFrameMargin);
891111b4fbcSStefano Ceccherini 		BRect textRect(frame.OffsetToCopy(B_ORIGIN));
8929cb2dbe2SMarc Flerackers 
893b8872c02SStephan Aßmus 		fText = new BPrivate::_BTextInput_(frame, textRect,
89493ba577cSStephan Aßmus 			B_FOLLOW_ALL, B_WILL_DRAW | B_FRAME_EVENTS | navigableFlags);
8959cb2dbe2SMarc Flerackers 		AddChild(fText);
8969cb2dbe2SMarc Flerackers 
897455d1c46SAxel Dörfler 		SetText(initialText);
8989cb2dbe2SMarc Flerackers 		fText->SetAlignment(B_ALIGN_LEFT);
8999cb2dbe2SMarc Flerackers 		fText->AlignTextRect();
9009cb2dbe2SMarc Flerackers 	}
9019cb2dbe2SMarc Flerackers }
9029ecf9d1cSIngo Weinhold 
9039ecf9d1cSIngo Weinhold 
9049ecf9d1cSIngo Weinhold void
9059ecf9d1cSIngo Weinhold BTextControl::_ValidateLayout()
9069ecf9d1cSIngo Weinhold {
90793ba577cSStephan Aßmus 	CALLED();
90893ba577cSStephan Aßmus 
909349c911eSStephan Aßmus 	_ValidateLayoutData();
9109ecf9d1cSIngo Weinhold 
911349c911eSStephan Aßmus 	ResizeTo(Bounds().Width(), fLayoutData->min.height);
9129ecf9d1cSIngo Weinhold 
913a431f44bSStephan Aßmus 	_LayoutTextView();
9149ecf9d1cSIngo Weinhold }
9159ecf9d1cSIngo Weinhold 
9169ecf9d1cSIngo Weinhold 
9179ecf9d1cSIngo Weinhold void
918a431f44bSStephan Aßmus BTextControl::_LayoutTextView()
919a431f44bSStephan Aßmus {
92093ba577cSStephan Aßmus 	CALLED();
92193ba577cSStephan Aßmus 
922a431f44bSStephan Aßmus 	BRect frame = Bounds();
923a431f44bSStephan Aßmus 	frame.left = fDivider;
924a431f44bSStephan Aßmus 	// we are stroking the frame around the text view, which
925a431f44bSStephan Aßmus 	// is 2 pixels wide
926a431f44bSStephan Aßmus 	frame.InsetBy(2.0, 2.0);
927a431f44bSStephan Aßmus 	fText->MoveTo(frame.left, frame.top);
928a431f44bSStephan Aßmus 	fText->ResizeTo(frame.Width(), frame.Height());
929b8872c02SStephan Aßmus 	fText->AlignTextRect();
93093ba577cSStephan Aßmus 
93193ba577cSStephan Aßmus 	TRACE("width: %.2f, height: %.2f\n", Frame().Width(), Frame().Height());
93293ba577cSStephan Aßmus 	TRACE("fDivider: %.2f\n", fDivider);
93393ba577cSStephan Aßmus 	TRACE("fText frame: (%.2f, %.2f, %.2f, %.2f)\n",
93493ba577cSStephan Aßmus 		frame.left, frame.top, frame.right, frame.bottom);
935a431f44bSStephan Aßmus }
936a431f44bSStephan Aßmus 
937a431f44bSStephan Aßmus 
938a431f44bSStephan Aßmus void
9399ecf9d1cSIngo Weinhold BTextControl::_UpdateFrame()
9409ecf9d1cSIngo Weinhold {
941349c911eSStephan Aßmus 	CALLED();
942349c911eSStephan Aßmus 
943349c911eSStephan Aßmus 	if (fLayoutData->label_layout_item && fLayoutData->text_view_layout_item) {
944349c911eSStephan Aßmus 		BRect labelFrame = fLayoutData->label_layout_item->Frame();
945349c911eSStephan Aßmus 		BRect textFrame = fLayoutData->text_view_layout_item->Frame();
946349c911eSStephan Aßmus 
947349c911eSStephan Aßmus 		// update divider
948349c911eSStephan Aßmus 		fDivider = textFrame.left - labelFrame.left;
949349c911eSStephan Aßmus 
9509ecf9d1cSIngo Weinhold 		MoveTo(labelFrame.left, labelFrame.top);
951349c911eSStephan Aßmus 		BSize oldSize = Bounds().Size();
9529ecf9d1cSIngo Weinhold 		ResizeTo(textFrame.left + textFrame.Width() - labelFrame.left,
9539ecf9d1cSIngo Weinhold 			textFrame.top + textFrame.Height() - labelFrame.top);
954349c911eSStephan Aßmus 		BSize newSize = Bounds().Size();
955349c911eSStephan Aßmus 
956349c911eSStephan Aßmus 		// If the size changes, ResizeTo() will trigger a relayout, otherwise
957349c911eSStephan Aßmus 		// we need to do that explicitly.
958349c911eSStephan Aßmus 		if (newSize != oldSize)
959349c911eSStephan Aßmus 			Relayout();
9609ecf9d1cSIngo Weinhold 	}
9619ecf9d1cSIngo Weinhold }
9629ecf9d1cSIngo Weinhold 
9639ecf9d1cSIngo Weinhold 
964349c911eSStephan Aßmus void
965349c911eSStephan Aßmus BTextControl::_ValidateLayoutData()
966349c911eSStephan Aßmus {
967349c911eSStephan Aßmus 	CALLED();
968349c911eSStephan Aßmus 
969349c911eSStephan Aßmus 	if (fLayoutData->valid)
970349c911eSStephan Aßmus 		return;
971349c911eSStephan Aßmus 
972349c911eSStephan Aßmus 	// cache font height
973349c911eSStephan Aßmus 	font_height& fh = fLayoutData->font_info;
974349c911eSStephan Aßmus 	GetFontHeight(&fh);
975349c911eSStephan Aßmus 
976349c911eSStephan Aßmus 	if (Label() != NULL) {
977349c911eSStephan Aßmus 		fLayoutData->label_width = ceilf(StringWidth(Label()));
978349c911eSStephan Aßmus 		fLayoutData->label_height = ceilf(fh.ascent) + ceilf(fh.descent);
979349c911eSStephan Aßmus 	} else {
980349c911eSStephan Aßmus 		fLayoutData->label_width = 0;
981349c911eSStephan Aßmus 		fLayoutData->label_height = 0;
982349c911eSStephan Aßmus 	}
983349c911eSStephan Aßmus 
984349c911eSStephan Aßmus 	// compute the minimal divider
985349c911eSStephan Aßmus 	float divider = 0;
986349c911eSStephan Aßmus 	if (fLayoutData->label_width > 0)
987349c911eSStephan Aßmus 		divider = fLayoutData->label_width + 5;
988349c911eSStephan Aßmus 
989349c911eSStephan Aßmus 	// If we shan't do real layout, we let the current divider take influence.
990349c911eSStephan Aßmus 	if (!(Flags() & B_SUPPORTS_LAYOUT))
991349c911eSStephan Aßmus 		divider = max_c(divider, fDivider);
992349c911eSStephan Aßmus 
993349c911eSStephan Aßmus 	// get the minimal (== preferred) text view size
994349c911eSStephan Aßmus 	fLayoutData->text_view_min = fText->MinSize();
995349c911eSStephan Aßmus 
996349c911eSStephan Aßmus 	TRACE("text view min width: %.2f\n", fLayoutData->text_view_min.width);
997349c911eSStephan Aßmus 
998349c911eSStephan Aßmus 	// compute our minimal (== preferred) size
999349c911eSStephan Aßmus 	BSize min(fLayoutData->text_view_min);
1000349c911eSStephan Aßmus 	min.width += 2 * kFrameMargin;
1001349c911eSStephan Aßmus 	min.height += 2 * kFrameMargin;
1002349c911eSStephan Aßmus 
1003349c911eSStephan Aßmus 	if (divider > 0)
1004349c911eSStephan Aßmus 		min.width += divider;
1005349c911eSStephan Aßmus 	if (fLayoutData->label_height > min.height)
1006349c911eSStephan Aßmus 		min.height = fLayoutData->label_height;
1007349c911eSStephan Aßmus 
1008349c911eSStephan Aßmus 	fLayoutData->min = min;
1009349c911eSStephan Aßmus 
1010349c911eSStephan Aßmus 	fLayoutData->valid = true;
1011349c911eSStephan Aßmus 
1012349c911eSStephan Aßmus 	TRACE("width: %.2f, height: %.2f\n", min.width, min.height);
1013349c911eSStephan Aßmus }
1014349c911eSStephan Aßmus 
1015349c911eSStephan Aßmus 
10169ecf9d1cSIngo Weinhold // #pragma mark -
10179ecf9d1cSIngo Weinhold 
10189ecf9d1cSIngo Weinhold 
10199ecf9d1cSIngo Weinhold BTextControl::LabelLayoutItem::LabelLayoutItem(BTextControl* parent)
10209ecf9d1cSIngo Weinhold 	: fParent(parent),
10219ecf9d1cSIngo Weinhold 	  fFrame()
10229ecf9d1cSIngo Weinhold {
10239ecf9d1cSIngo Weinhold }
10249ecf9d1cSIngo Weinhold 
10259ecf9d1cSIngo Weinhold 
10269ecf9d1cSIngo Weinhold bool
10279ecf9d1cSIngo Weinhold BTextControl::LabelLayoutItem::IsVisible()
10289ecf9d1cSIngo Weinhold {
10299ecf9d1cSIngo Weinhold 	return !fParent->IsHidden(fParent);
10309ecf9d1cSIngo Weinhold }
10319ecf9d1cSIngo Weinhold 
10329ecf9d1cSIngo Weinhold 
10339ecf9d1cSIngo Weinhold void
10349ecf9d1cSIngo Weinhold BTextControl::LabelLayoutItem::SetVisible(bool visible)
10359ecf9d1cSIngo Weinhold {
10369ecf9d1cSIngo Weinhold 	// not allowed
10379ecf9d1cSIngo Weinhold }
10389ecf9d1cSIngo Weinhold 
10399ecf9d1cSIngo Weinhold 
10409ecf9d1cSIngo Weinhold BRect
10419ecf9d1cSIngo Weinhold BTextControl::LabelLayoutItem::Frame()
10429ecf9d1cSIngo Weinhold {
10439ecf9d1cSIngo Weinhold 	return fFrame;
10449ecf9d1cSIngo Weinhold }
10459ecf9d1cSIngo Weinhold 
10469ecf9d1cSIngo Weinhold 
10479ecf9d1cSIngo Weinhold void
10489ecf9d1cSIngo Weinhold BTextControl::LabelLayoutItem::SetFrame(BRect frame)
10499ecf9d1cSIngo Weinhold {
10509ecf9d1cSIngo Weinhold 	fFrame = frame;
10519ecf9d1cSIngo Weinhold 	fParent->_UpdateFrame();
10529ecf9d1cSIngo Weinhold }
10539ecf9d1cSIngo Weinhold 
10549ecf9d1cSIngo Weinhold 
10559ecf9d1cSIngo Weinhold BView*
10569ecf9d1cSIngo Weinhold BTextControl::LabelLayoutItem::View()
10579ecf9d1cSIngo Weinhold {
10589ecf9d1cSIngo Weinhold 	return fParent;
10599ecf9d1cSIngo Weinhold }
10609ecf9d1cSIngo Weinhold 
10619ecf9d1cSIngo Weinhold 
10629ecf9d1cSIngo Weinhold BSize
10639ecf9d1cSIngo Weinhold BTextControl::LabelLayoutItem::BaseMinSize()
10649ecf9d1cSIngo Weinhold {
1065349c911eSStephan Aßmus 	fParent->_ValidateLayoutData();
1066349c911eSStephan Aßmus 
1067349c911eSStephan Aßmus 	if (!fParent->Label())
10689ecf9d1cSIngo Weinhold 		return BSize(-1, -1);
10699ecf9d1cSIngo Weinhold 
1070349c911eSStephan Aßmus 	return BSize(fParent->fLayoutData->label_width + 5,
1071349c911eSStephan Aßmus 		fParent->fLayoutData->label_height);
10729ecf9d1cSIngo Weinhold }
10739ecf9d1cSIngo Weinhold 
10749ecf9d1cSIngo Weinhold 
10759ecf9d1cSIngo Weinhold BSize
10769ecf9d1cSIngo Weinhold BTextControl::LabelLayoutItem::BaseMaxSize()
10779ecf9d1cSIngo Weinhold {
10789ecf9d1cSIngo Weinhold 	return BaseMinSize();
10799ecf9d1cSIngo Weinhold }
10809ecf9d1cSIngo Weinhold 
10819ecf9d1cSIngo Weinhold 
10829ecf9d1cSIngo Weinhold BSize
10839ecf9d1cSIngo Weinhold BTextControl::LabelLayoutItem::BasePreferredSize()
10849ecf9d1cSIngo Weinhold {
10859ecf9d1cSIngo Weinhold 	return BaseMinSize();
10869ecf9d1cSIngo Weinhold }
10879ecf9d1cSIngo Weinhold 
10889ecf9d1cSIngo Weinhold 
10899ecf9d1cSIngo Weinhold BAlignment
10909ecf9d1cSIngo Weinhold BTextControl::LabelLayoutItem::BaseAlignment()
10919ecf9d1cSIngo Weinhold {
10929ecf9d1cSIngo Weinhold 	return BAlignment(B_ALIGN_USE_FULL_WIDTH, B_ALIGN_USE_FULL_HEIGHT);
10939ecf9d1cSIngo Weinhold }
10949ecf9d1cSIngo Weinhold 
10959ecf9d1cSIngo Weinhold 
10969ecf9d1cSIngo Weinhold // #pragma mark -
10979ecf9d1cSIngo Weinhold 
10989ecf9d1cSIngo Weinhold 
10999ecf9d1cSIngo Weinhold BTextControl::TextViewLayoutItem::TextViewLayoutItem(BTextControl* parent)
11009ecf9d1cSIngo Weinhold 	: fParent(parent),
11019ecf9d1cSIngo Weinhold 	  fFrame()
11029ecf9d1cSIngo Weinhold {
1103349c911eSStephan Aßmus 	// by default the part right of the divider shall have an unlimited maximum
1104349c911eSStephan Aßmus 	// width
1105349c911eSStephan Aßmus 	SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, B_SIZE_UNSET));
11069ecf9d1cSIngo Weinhold }
11079ecf9d1cSIngo Weinhold 
11089ecf9d1cSIngo Weinhold 
11099ecf9d1cSIngo Weinhold bool
11109ecf9d1cSIngo Weinhold BTextControl::TextViewLayoutItem::IsVisible()
11119ecf9d1cSIngo Weinhold {
11129ecf9d1cSIngo Weinhold 	return !fParent->IsHidden(fParent);
11139ecf9d1cSIngo Weinhold }
11149ecf9d1cSIngo Weinhold 
11159ecf9d1cSIngo Weinhold 
11169ecf9d1cSIngo Weinhold void
11179ecf9d1cSIngo Weinhold BTextControl::TextViewLayoutItem::SetVisible(bool visible)
11189ecf9d1cSIngo Weinhold {
11199ecf9d1cSIngo Weinhold 	// not allowed
11209ecf9d1cSIngo Weinhold }
11219ecf9d1cSIngo Weinhold 
11229ecf9d1cSIngo Weinhold 
11239ecf9d1cSIngo Weinhold BRect
11249ecf9d1cSIngo Weinhold BTextControl::TextViewLayoutItem::Frame()
11259ecf9d1cSIngo Weinhold {
11269ecf9d1cSIngo Weinhold 	return fFrame;
11279ecf9d1cSIngo Weinhold }
11289ecf9d1cSIngo Weinhold 
11299ecf9d1cSIngo Weinhold 
11309ecf9d1cSIngo Weinhold void
11319ecf9d1cSIngo Weinhold BTextControl::TextViewLayoutItem::SetFrame(BRect frame)
11329ecf9d1cSIngo Weinhold {
11339ecf9d1cSIngo Weinhold 	fFrame = frame;
11349ecf9d1cSIngo Weinhold 	fParent->_UpdateFrame();
11359ecf9d1cSIngo Weinhold }
11369ecf9d1cSIngo Weinhold 
11379ecf9d1cSIngo Weinhold 
11389ecf9d1cSIngo Weinhold BView*
11399ecf9d1cSIngo Weinhold BTextControl::TextViewLayoutItem::View()
11409ecf9d1cSIngo Weinhold {
11419ecf9d1cSIngo Weinhold 	return fParent;
11429ecf9d1cSIngo Weinhold }
11439ecf9d1cSIngo Weinhold 
11449ecf9d1cSIngo Weinhold 
11459ecf9d1cSIngo Weinhold BSize
11469ecf9d1cSIngo Weinhold BTextControl::TextViewLayoutItem::BaseMinSize()
11479ecf9d1cSIngo Weinhold {
1148349c911eSStephan Aßmus 	fParent->_ValidateLayoutData();
11499ecf9d1cSIngo Weinhold 
1150349c911eSStephan Aßmus 	BSize size = fParent->fLayoutData->text_view_min;
1151349c911eSStephan Aßmus 	size.width += 2 * kFrameMargin;
1152349c911eSStephan Aßmus 	size.height += 2 * kFrameMargin;
11539ecf9d1cSIngo Weinhold 
11549ecf9d1cSIngo Weinhold 	return size;
11559ecf9d1cSIngo Weinhold }
11569ecf9d1cSIngo Weinhold 
11579ecf9d1cSIngo Weinhold 
11589ecf9d1cSIngo Weinhold BSize
11599ecf9d1cSIngo Weinhold BTextControl::TextViewLayoutItem::BaseMaxSize()
11609ecf9d1cSIngo Weinhold {
11619ecf9d1cSIngo Weinhold 	BSize size(BaseMinSize());
11629ecf9d1cSIngo Weinhold 	size.width = B_SIZE_UNLIMITED;
11639ecf9d1cSIngo Weinhold 	return size;
11649ecf9d1cSIngo Weinhold }
11659ecf9d1cSIngo Weinhold 
11669ecf9d1cSIngo Weinhold 
11679ecf9d1cSIngo Weinhold BSize
11689ecf9d1cSIngo Weinhold BTextControl::TextViewLayoutItem::BasePreferredSize()
11699ecf9d1cSIngo Weinhold {
11709ecf9d1cSIngo Weinhold 	BSize size(BaseMinSize());
11719ecf9d1cSIngo Weinhold 	// puh, no idea...
11729ecf9d1cSIngo Weinhold 	size.width = 100;
11739ecf9d1cSIngo Weinhold 	return size;
11749ecf9d1cSIngo Weinhold }
11759ecf9d1cSIngo Weinhold 
11769ecf9d1cSIngo Weinhold 
11779ecf9d1cSIngo Weinhold BAlignment
11789ecf9d1cSIngo Weinhold BTextControl::TextViewLayoutItem::BaseAlignment()
11799ecf9d1cSIngo Weinhold {
11809ecf9d1cSIngo Weinhold 	return BAlignment(B_ALIGN_USE_FULL_WIDTH, B_ALIGN_USE_FULL_HEIGHT);
11819ecf9d1cSIngo Weinhold }
11829ecf9d1cSIngo Weinhold 
1183