1105644bfSAxel Dörfler/*
28bc3ecb0SAxel Dörfler * Copyright 2001-2015, 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
1109d87d91SAxel Dörfler
12991c062fSAxel Dörfler/*!	BTextControl displays text that can act like a control. */
13105644bfSAxel Dörfler
14c121b41fSRene Gollent
152f86ba45SStephan Aßmus#include <TextControl.h>
16105644bfSAxel Dörfler
1709d87d91SAxel Dörfler#include <string.h>
1809d87d91SAxel Dörfler
199ecf9d1cSIngo Weinhold#include <AbstractLayoutItem.h>
202f86ba45SStephan Aßmus#include <ControlLook.h>
219ecf9d1cSIngo Weinhold#include <LayoutUtils.h>
22058691d4SStefano Ceccherini#include <Message.h>
232a30a9e9SRene Gollent#include <PropertyInfo.h>
24455d1c46SAxel Dörfler#include <Region.h>
2552a38012Sejakowatz#include <Window.h>
2652a38012Sejakowatz
2739fbf550SOliver Tappe#include <binary_compatibility/Interface.h>
285c47e35eSAlex Wilson#include <binary_compatibility/Support.h>
2939fbf550SOliver Tappe
3052a38012Sejakowatz#include "TextInput.h"
3152a38012Sejakowatz
3252a38012Sejakowatz
3393ba577cSStephan Aßmus//#define TRACE_TEXT_CONTROL
3493ba577cSStephan Aßmus#ifdef TRACE_TEXT_CONTROL
3573161598SJérôme Duval#	include <stdio.h>
3693ba577cSStephan Aßmus#	include <FunctionTracer.h>
3793ba577cSStephan Aßmus	static int32 sFunctionDepth = -1;
38349c911eSStephan Aßmus#	define CALLED(x...)	FunctionTracer _ft("BTextControl", __FUNCTION__, \
3993ba577cSStephan Aßmus							sFunctionDepth)
4093ba577cSStephan Aßmus#	define TRACE(x...)	{ BString _to; \
4193ba577cSStephan Aßmus							_to.Append(' ', (sFunctionDepth + 1) * 2); \
4293ba577cSStephan Aßmus							printf("%s", _to.String()); printf(x); }
4393ba577cSStephan Aßmus#else
4493ba577cSStephan Aßmus#	define CALLED(x...)
4593ba577cSStephan Aßmus#	define TRACE(x...)
4693ba577cSStephan Aßmus#endif
4793ba577cSStephan Aßmus
4893ba577cSStephan Aßmus
495c47e35eSAlex Wilsonnamespace {
505c47e35eSAlex Wilson	const char* const kFrameField = "BTextControl:layoutitem:frame";
515c47e35eSAlex Wilson	const char* const kTextViewItemField = "BTextControl:textViewItem";
525c47e35eSAlex Wilson	const char* const kLabelItemField = "BMenuField:labelItem";
535c47e35eSAlex Wilson}
545c47e35eSAlex Wilson
555c47e35eSAlex Wilson
562a30a9e9SRene Gollentstatic property_info sPropertyList[] = {
572a30a9e9SRene Gollent	{
582a30a9e9SRene Gollent		"Value",
592a30a9e9SRene Gollent		{ B_GET_PROPERTY, B_SET_PROPERTY },
602a30a9e9SRene Gollent		{ B_DIRECT_SPECIFIER },
612a30a9e9SRene Gollent		NULL, 0,
622a30a9e9SRene Gollent		{ B_STRING_TYPE }
632a30a9e9SRene Gollent	},
64346d1496SHumdinger
65346d1496SHumdinger	{ 0 }
662a30a9e9SRene Gollent};
672a30a9e9SRene Gollent
682a30a9e9SRene Gollent
699ecf9d1cSIngo Weinholdclass BTextControl::LabelLayoutItem : public BAbstractLayoutItem {
709ecf9d1cSIngo Weinholdpublic:
719ecf9d1cSIngo Weinhold								LabelLayoutItem(BTextControl* parent);
725c47e35eSAlex Wilson								LabelLayoutItem(BMessage* from);
739ecf9d1cSIngo Weinhold
749ecf9d1cSIngo Weinhold	virtual	bool				IsVisible();
759ecf9d1cSIngo Weinhold	virtual	void				SetVisible(bool visible);
769ecf9d1cSIngo Weinhold
779ecf9d1cSIngo Weinhold	virtual	BRect				Frame();
789ecf9d1cSIngo Weinhold	virtual	void				SetFrame(BRect frame);
799ecf9d1cSIngo Weinhold
805c47e35eSAlex Wilson			void				SetParent(BTextControl* parent);
819ecf9d1cSIngo Weinhold	virtual	BView*				View();
829ecf9d1cSIngo Weinhold
839ecf9d1cSIngo Weinhold	virtual	BSize				BaseMinSize();
849ecf9d1cSIngo Weinhold	virtual	BSize				BaseMaxSize();
859ecf9d1cSIngo Weinhold	virtual	BSize				BasePreferredSize();
869ecf9d1cSIngo Weinhold	virtual	BAlignment			BaseAlignment();
879ecf9d1cSIngo Weinhold
8809d87d91SAxel Dörfler			BRect				FrameInParent() const;
8909d87d91SAxel Dörfler
905c47e35eSAlex Wilson	virtual status_t			Archive(BMessage* into, bool deep = true) const;
915c47e35eSAlex Wilson	static	BArchivable*		Instantiate(BMessage* from);
9209d87d91SAxel Dörfler
939ecf9d1cSIngo Weinholdprivate:
949ecf9d1cSIngo Weinhold			BTextControl*		fParent;
959ecf9d1cSIngo Weinhold			BRect				fFrame;
969ecf9d1cSIngo Weinhold};
979ecf9d1cSIngo Weinhold
989ecf9d1cSIngo Weinhold
999ecf9d1cSIngo Weinholdclass BTextControl::TextViewLayoutItem : public BAbstractLayoutItem {
1009ecf9d1cSIngo Weinholdpublic:
1019ecf9d1cSIngo Weinhold								TextViewLayoutItem(BTextControl* parent);
1025c47e35eSAlex Wilson								TextViewLayoutItem(BMessage* from);
1039ecf9d1cSIngo Weinhold
1049ecf9d1cSIngo Weinhold	virtual	bool				IsVisible();
1059ecf9d1cSIngo Weinhold	virtual	void				SetVisible(bool visible);
1069ecf9d1cSIngo Weinhold
1079ecf9d1cSIngo Weinhold	virtual	BRect				Frame();
1089ecf9d1cSIngo Weinhold	virtual	void				SetFrame(BRect frame);
1099ecf9d1cSIngo Weinhold
1105c47e35eSAlex Wilson			void				SetParent(BTextControl* parent);
1119ecf9d1cSIngo Weinhold	virtual	BView*				View();
1129ecf9d1cSIngo Weinhold
1139ecf9d1cSIngo Weinhold	virtual	BSize				BaseMinSize();
1149ecf9d1cSIngo Weinhold	virtual	BSize				BaseMaxSize();
1159ecf9d1cSIngo Weinhold	virtual	BSize				BasePreferredSize();
1169ecf9d1cSIngo Weinhold	virtual	BAlignment			BaseAlignment();
1179ecf9d1cSIngo Weinhold
11809d87d91SAxel Dörfler			BRect				FrameInParent() const;
11909d87d91SAxel Dörfler
1205c47e35eSAlex Wilson	virtual status_t			Archive(BMessage* into, bool deep = true) const;
1215c47e35eSAlex Wilson	static	BArchivable*		Instantiate(BMessage* from);
1229ecf9d1cSIngo Weinholdprivate:
1239ecf9d1cSIngo Weinhold			BTextControl*		fParent;
1249ecf9d1cSIngo Weinhold			BRect				fFrame;
1259ecf9d1cSIngo Weinhold};
1269ecf9d1cSIngo Weinhold
1279ecf9d1cSIngo Weinhold
128349c911eSStephan Aßmusstruct BTextControl::LayoutData {
129349c911eSStephan Aßmus	LayoutData(float width, float height)
1305c47e35eSAlex Wilson		:
1315c47e35eSAlex Wilson		label_layout_item(NULL),
1325c47e35eSAlex Wilson		text_view_layout_item(NULL),
1335c47e35eSAlex Wilson		previous_width(width),
1345c47e35eSAlex Wilson		previous_height(height),
1355c47e35eSAlex Wilson		valid(false)
136349c911eSStephan Aßmus	{
137349c911eSStephan Aßmus	}
138349c911eSStephan Aßmus
139349c911eSStephan Aßmus	LabelLayoutItem*	label_layout_item;
140349c911eSStephan Aßmus	TextViewLayoutItem*	text_view_layout_item;
141349c911eSStephan Aßmus	float				previous_width;		// used in FrameResized() for
142349c911eSStephan Aßmus	float				previous_height;	// invalidation
143349c911eSStephan Aßmus	font_height			font_info;
144349c911eSStephan Aßmus	float				label_width;
145349c911eSStephan Aßmus	float				label_height;
146349c911eSStephan Aßmus	BSize				min;
147349c911eSStephan Aßmus	BSize				text_view_min;
148349c911eSStephan Aßmus	bool				valid;
149349c911eSStephan Aßmus};
150349c911eSStephan Aßmus
151349c911eSStephan Aßmus
152349c911eSStephan Aßmusstatic const int32 kFrameMargin = 2;
153349c911eSStephan Aßmusstatic const int32 kLabelInputSpacing = 3;
154349c911eSStephan Aßmus
155349c911eSStephan Aßmus
156b11edca4SJohn Scipione// #pragma mark - BTextControl
157b11edca4SJohn Scipione
158b11edca4SJohn Scipione
159991c062fSAxel DörflerBTextControl::BTextControl(BRect frame, const char* name, const char* label,
160f4664459SJohn Scipione	const char* text, BMessage* message, uint32 resizeMask, uint32 flags)
1615c47e35eSAlex Wilson	:
162f4664459SJohn Scipione	BControl(frame, name, label, message, resizeMask, flags | B_FRAME_EVENTS)
16352a38012Sejakowatz{
1645c47e35eSAlex Wilson	_InitData(label);
1655c47e35eSAlex Wilson	_InitText(text);
1669ecf9d1cSIngo Weinhold	_ValidateLayout();
1679ecf9d1cSIngo Weinhold}
16852a38012Sejakowatz
16952a38012Sejakowatz
170991c062fSAxel DörflerBTextControl::BTextControl(const char* name, const char* label,
171f4664459SJohn Scipione	const char* text, BMessage* message, uint32 flags)
1725c47e35eSAlex Wilson	:
1735c47e35eSAlex Wilson	BControl(name, label, message, flags | B_FRAME_EVENTS)
1749ecf9d1cSIngo Weinhold{
1755c47e35eSAlex Wilson	_InitData(label);
1765c47e35eSAlex Wilson	_InitText(text);
1779ecf9d1cSIngo Weinhold	_ValidateLayout();
1789ecf9d1cSIngo Weinhold}
17952a38012Sejakowatz
180ffe72abdSAxel Dörfler
181991c062fSAxel DörflerBTextControl::BTextControl(const char* label, const char* text,
182f4664459SJohn Scipione	BMessage* message)
1835c47e35eSAlex Wilson	:
1845c47e35eSAlex Wilson	BControl(NULL, label, message,
18593ba577cSStephan Aßmus		B_WILL_DRAW | B_NAVIGABLE | B_FRAME_EVENTS)
1869ecf9d1cSIngo Weinhold{
1875c47e35eSAlex Wilson	_InitData(label);
1885c47e35eSAlex Wilson	_InitText(text);
1899ecf9d1cSIngo Weinhold	_ValidateLayout();
19052a38012Sejakowatz}
191058691d4SStefano Ceccherini
192058691d4SStefano Ceccherini
19352a38012SejakowatzBTextControl::~BTextControl()
19452a38012Sejakowatz{
1959cb2dbe2SMarc Flerackers	SetModificationMessage(NULL);
19653aaed9fSStephan Aßmus	delete fLayoutData;
19752a38012Sejakowatz}
198058691d4SStefano Ceccherini
199058691d4SStefano Ceccherini
200f4664459SJohn Scipione//	#pragma mark - Archiving
201f4664459SJohn Scipione
202f4664459SJohn Scipione
203ffe72abdSAxel DörflerBTextControl::BTextControl(BMessage* archive)
2045c47e35eSAlex Wilson	:
2055c47e35eSAlex Wilson	BControl(BUnarchiver::PrepareArchive(archive))
20652a38012Sejakowatz{
2075c47e35eSAlex Wilson	BUnarchiver unarchiver(archive);
20852a38012Sejakowatz
2095c47e35eSAlex Wilson	_InitData(Label(), archive);
21052a38012Sejakowatz
2115c47e35eSAlex Wilson	if (!BUnarchiver::IsArchiveManaged(archive))
2125c47e35eSAlex Wilson		_InitText(NULL, archive);
2139cb2dbe2SMarc Flerackers
2145c47e35eSAlex Wilson	status_t err = B_OK;
215ffe72abdSAxel Dörfler	if (archive->HasFloat("_divide"))
2165c47e35eSAlex Wilson		err = archive->FindFloat("_divide", &fDivider);
2179cb2dbe2SMarc Flerackers
2185c47e35eSAlex Wilson	if (err == B_OK && archive->HasMessage("_mod_msg")) {
219ffe72abdSAxel Dörfler		BMessage* message = new BMessage;
2205c47e35eSAlex Wilson		err = archive->FindMessage("_mod_msg", message);
221ffe72abdSAxel Dörfler		SetModificationMessage(message);
22252a38012Sejakowatz	}
2235c47e35eSAlex Wilson
2245c47e35eSAlex Wilson	unarchiver.Finish(err);
22552a38012Sejakowatz}
226058691d4SStefano Ceccherini
227058691d4SStefano Ceccherini
228991c062fSAxel DörflerBArchivable*
229991c062fSAxel DörflerBTextControl::Instantiate(BMessage* archive)
23052a38012Sejakowatz{
2319cb2dbe2SMarc Flerackers	if (validate_instantiation(archive, "BTextControl"))
2329cb2dbe2SMarc Flerackers		return new BTextControl(archive);
233991c062fSAxel Dörfler
234991c062fSAxel Dörfler	return NULL;
23552a38012Sejakowatz}
236058691d4SStefano Ceccherini
237058691d4SStefano Ceccherini
238058691d4SStefano Ceccherinistatus_t
239f4664459SJohn ScipioneBTextControl::Archive(BMessage* data, bool deep) const
24052a38012Sejakowatz{
2415c47e35eSAlex Wilson	BArchiver archiver(data);
242f4664459SJohn Scipione	status_t result = BControl::Archive(data, deep);
243f4664459SJohn Scipione
244f4664459SJohn Scipione	alignment labelAlignment;
245f4664459SJohn Scipione	alignment textAlignment;
246f4664459SJohn Scipione	if (result == B_OK)
247f4664459SJohn Scipione		GetAlignment(&labelAlignment, &textAlignment);
248f4664459SJohn Scipione
249f4664459SJohn Scipione	if (result == B_OK)
250f4664459SJohn Scipione		result = data->AddInt32("_a_label", labelAlignment);
2519cb2dbe2SMarc Flerackers
252f4664459SJohn Scipione	if (result == B_OK)
253f4664459SJohn Scipione		result = data->AddInt32("_a_text", textAlignment);
25452a38012Sejakowatz
255f4664459SJohn Scipione	if (result == B_OK)
256f4664459SJohn Scipione		result = data->AddFloat("_divide", Divider());
2579cb2dbe2SMarc Flerackers
258f4664459SJohn Scipione	if (result == B_OK && ModificationMessage() != NULL)
259f4664459SJohn Scipione		result = data->AddMessage("_mod_msg", ModificationMessage());
2609cb2dbe2SMarc Flerackers
261f4664459SJohn Scipione	return archiver.Finish(result);
2625c47e35eSAlex Wilson}
2635c47e35eSAlex Wilson
2645c47e35eSAlex Wilson
2655c47e35eSAlex Wilsonstatus_t
2665c47e35eSAlex WilsonBTextControl::AllArchived(BMessage* into) const
2675c47e35eSAlex Wilson{
2685c47e35eSAlex Wilson	BArchiver archiver(into);
2695c47e35eSAlex Wilson	status_t err = B_OK;
2705c47e35eSAlex Wilson
2715c47e35eSAlex Wilson	if (archiver.IsArchived(fLayoutData->text_view_layout_item)) {
2725c47e35eSAlex Wilson		err = archiver.AddArchivable(kTextViewItemField,
2735c47e35eSAlex Wilson			fLayoutData->text_view_layout_item);
2745c47e35eSAlex Wilson	}
2755c47e35eSAlex Wilson
2765c47e35eSAlex Wilson	if (err == B_OK && archiver.IsArchived(fLayoutData->label_layout_item)) {
2775c47e35eSAlex Wilson		err = archiver.AddArchivable(kLabelItemField,
2785c47e35eSAlex Wilson			fLayoutData->label_layout_item);
2795c47e35eSAlex Wilson	}
2805c47e35eSAlex Wilson
2815c47e35eSAlex Wilson	return err;
2825c47e35eSAlex Wilson}
2835c47e35eSAlex Wilson
2845c47e35eSAlex Wilson
2855c47e35eSAlex Wilsonstatus_t
2865c47e35eSAlex WilsonBTextControl::AllUnarchived(const BMessage* from)
2875c47e35eSAlex Wilson{
2885c47e35eSAlex Wilson	status_t err;
2895c47e35eSAlex Wilson	if ((err = BControl::AllUnarchived(from)) != B_OK)
2905c47e35eSAlex Wilson		return err;
2915c47e35eSAlex Wilson
2925c47e35eSAlex Wilson	_InitText(NULL, from);
2935c47e35eSAlex Wilson
2945c47e35eSAlex Wilson	BUnarchiver unarchiver(from);
2955c47e35eSAlex Wilson	if (unarchiver.IsInstantiated(kTextViewItemField)) {
2965c47e35eSAlex Wilson		err = unarchiver.FindObject(kTextViewItemField,
2975c47e35eSAlex Wilson			BUnarchiver::B_DONT_ASSUME_OWNERSHIP,
2985c47e35eSAlex Wilson			fLayoutData->text_view_layout_item);
2995c47e35eSAlex Wilson
3005c47e35eSAlex Wilson		if (err == B_OK)
3015c47e35eSAlex Wilson			fLayoutData->text_view_layout_item->SetParent(this);
3025c47e35eSAlex Wilson		else
3035c47e35eSAlex Wilson			return err;
3045c47e35eSAlex Wilson	}
3055c47e35eSAlex Wilson
3065c47e35eSAlex Wilson	if (unarchiver.IsInstantiated(kLabelItemField)) {
3075c47e35eSAlex Wilson		err = unarchiver.FindObject(kLabelItemField,
3085c47e35eSAlex Wilson			BUnarchiver::B_DONT_ASSUME_OWNERSHIP,
3095c47e35eSAlex Wilson			fLayoutData->label_layout_item);
3105c47e35eSAlex Wilson
3115c47e35eSAlex Wilson		if (err == B_OK)
3125c47e35eSAlex Wilson			fLayoutData->label_layout_item->SetParent(this);
3135c47e35eSAlex Wilson	}
3145c47e35eSAlex Wilson	return err;
31552a38012Sejakowatz}
316058691d4SStefano Ceccherini
317058691d4SStefano Ceccherini
318f4664459SJohn Scipione//	#pragma mark - Hook methods
319f4664459SJohn Scipione
320f4664459SJohn Scipione
321f4664459SJohn Scipionevoid
322f4664459SJohn ScipioneBTextControl::AllAttached()
323f4664459SJohn Scipione{
324f4664459SJohn Scipione	BControl::AllAttached();
325f4664459SJohn Scipione}
326f4664459SJohn Scipione
327f4664459SJohn Scipione
328f4664459SJohn Scipionevoid
329f4664459SJohn ScipioneBTextControl::AllDetached()
330f4664459SJohn Scipione{
331f4664459SJohn Scipione	BControl::AllDetached();
332f4664459SJohn Scipione}
333f4664459SJohn Scipione
334f4664459SJohn Scipione
335058691d4SStefano Ceccherinivoid
336f4664459SJohn ScipioneBTextControl::AttachedToWindow()
337f4664459SJohn Scipione{
338f4664459SJohn Scipione	BControl::AttachedToWindow();
339f4664459SJohn Scipione
340f4664459SJohn Scipione	_UpdateTextViewColors(IsEnabled());
341f4664459SJohn Scipione	fText->MakeEditable(IsEnabled());
342f4664459SJohn Scipione}
343f4664459SJohn Scipione
344f4664459SJohn Scipione
345f4664459SJohn Scipionevoid
346f4664459SJohn ScipioneBTextControl::DetachedFromWindow()
347f4664459SJohn Scipione{
348f4664459SJohn Scipione	BControl::DetachedFromWindow();
349f4664459SJohn Scipione}
350f4664459SJohn Scipione
351f4664459SJohn Scipione
352f4664459SJohn Scipionevoid
353f4664459SJohn ScipioneBTextControl::Draw(BRect updateRect)
354f4664459SJohn Scipione{
355f4664459SJohn Scipione	bool enabled = IsEnabled();
356f4664459SJohn Scipione	bool active = fText->IsFocus() && Window()->IsActive();
357f4664459SJohn Scipione
358f4664459SJohn Scipione	BRect rect = fText->Frame();
359f4664459SJohn Scipione	rect.InsetBy(-2, -2);
360f4664459SJohn Scipione
3617a96554cSlooncraz	rgb_color base = ViewColor();
362f4664459SJohn Scipione	uint32 flags = fLook;
363f4664459SJohn Scipione	if (!enabled)
364f4664459SJohn Scipione		flags |= BControlLook::B_DISABLED;
365f4664459SJohn Scipione
366f4664459SJohn Scipione	if (active)
367f4664459SJohn Scipione		flags |= BControlLook::B_FOCUSED;
368f4664459SJohn Scipione
369f4664459SJohn Scipione	be_control_look->DrawTextControlBorder(this, rect, updateRect, base,
370f4664459SJohn Scipione		flags);
371f4664459SJohn Scipione
372f4664459SJohn Scipione	if (Label() != NULL) {
373f4664459SJohn Scipione		if (fLayoutData->label_layout_item != NULL) {
374f4664459SJohn Scipione			rect = fLayoutData->label_layout_item->FrameInParent();
375f4664459SJohn Scipione		} else {
376f4664459SJohn Scipione			rect = Bounds();
377f4664459SJohn Scipione			rect.right = fDivider - kLabelInputSpacing;
378f4664459SJohn Scipione		}
379f4664459SJohn Scipione
3808b902d94SJohn Scipione		// erase the is control flag before drawing the label so that the label
3818b902d94SJohn Scipione		// will get drawn using B_PANEL_TEXT_COLOR
3828b902d94SJohn Scipione		flags &= ~BControlLook::B_IS_CONTROL;
3838b902d94SJohn Scipione
384f4664459SJohn Scipione		be_control_look->DrawLabel(this, Label(), rect, updateRect,
385f4664459SJohn Scipione			base, flags, BAlignment(fLabelAlign, B_ALIGN_MIDDLE));
386f4664459SJohn Scipione	}
387f4664459SJohn Scipione}
388f4664459SJohn Scipione
389f4664459SJohn Scipione
390f4664459SJohn Scipionevoid
391f4664459SJohn ScipioneBTextControl::FrameMoved(BPoint newPosition)
392f4664459SJohn Scipione{
393f4664459SJohn Scipione	BControl::FrameMoved(newPosition);
394f4664459SJohn Scipione}
395f4664459SJohn Scipione
396f4664459SJohn Scipione
397f4664459SJohn Scipionevoid
398f4664459SJohn ScipioneBTextControl::FrameResized(float width, float height)
399f4664459SJohn Scipione{
400f4664459SJohn Scipione	CALLED();
401f4664459SJohn Scipione
402f4664459SJohn Scipione	BControl::FrameResized(width, height);
403f4664459SJohn Scipione
404f4664459SJohn Scipione	// TODO: this causes flickering still...
405f4664459SJohn Scipione
406f4664459SJohn Scipione	// changes in width
407f4664459SJohn Scipione
408f4664459SJohn Scipione	BRect bounds = Bounds();
409f4664459SJohn Scipione
410f4664459SJohn Scipione	if (bounds.Width() > fLayoutData->previous_width) {
411f4664459SJohn Scipione		// invalidate the region between the old and the new right border
412f4664459SJohn Scipione		BRect rect = bounds;
413f4664459SJohn Scipione		rect.left += fLayoutData->previous_width - kFrameMargin;
414f4664459SJohn Scipione		rect.right--;
415f4664459SJohn Scipione		Invalidate(rect);
416f4664459SJohn Scipione	} else if (bounds.Width() < fLayoutData->previous_width) {
417f4664459SJohn Scipione		// invalidate the region of the new right border
418f4664459SJohn Scipione		BRect rect = bounds;
419f4664459SJohn Scipione		rect.left = rect.right - kFrameMargin;
420f4664459SJohn Scipione		Invalidate(rect);
421f4664459SJohn Scipione	}
422f4664459SJohn Scipione
423f4664459SJohn Scipione	// changes in height
424f4664459SJohn Scipione
425f4664459SJohn Scipione	if (bounds.Height() > fLayoutData->previous_height) {
426f4664459SJohn Scipione		// invalidate the region between the old and the new bottom border
427f4664459SJohn Scipione		BRect rect = bounds;
428f4664459SJohn Scipione		rect.top += fLayoutData->previous_height - kFrameMargin;
429f4664459SJohn Scipione		rect.bottom--;
430f4664459SJohn Scipione		Invalidate(rect);
431f4664459SJohn Scipione		// invalidate label area
432f4664459SJohn Scipione		rect = bounds;
433f4664459SJohn Scipione		rect.right = fDivider;
434f4664459SJohn Scipione		Invalidate(rect);
435f4664459SJohn Scipione	} else if (bounds.Height() < fLayoutData->previous_height) {
436f4664459SJohn Scipione		// invalidate the region of the new bottom border
437f4664459SJohn Scipione		BRect rect = bounds;
438f4664459SJohn Scipione		rect.top = rect.bottom - kFrameMargin;
439f4664459SJohn Scipione		Invalidate(rect);
440f4664459SJohn Scipione		// invalidate label area
441f4664459SJohn Scipione		rect = bounds;
442f4664459SJohn Scipione		rect.right = fDivider;
443f4664459SJohn Scipione		Invalidate(rect);
444f4664459SJohn Scipione	}
445f4664459SJohn Scipione
446f4664459SJohn Scipione	fLayoutData->previous_width = bounds.Width();
447f4664459SJohn Scipione	fLayoutData->previous_height = bounds.Height();
448f4664459SJohn Scipione
449f4664459SJohn Scipione	TRACE("width: %.2f, height: %.2f\n", bounds.Width(), bounds.Height());
450f4664459SJohn Scipione}
451f4664459SJohn Scipione
452f4664459SJohn Scipione
453f4664459SJohn Scipionestatus_t
454f4664459SJohn ScipioneBTextControl::Invoke(BMessage* message)
455f4664459SJohn Scipione{
456f4664459SJohn Scipione	return BControl::Invoke(message);
457f4664459SJohn Scipione}
458f4664459SJohn Scipione
459f4664459SJohn Scipione
460f4664459SJohn Scipionevoid
461f4664459SJohn ScipioneBTextControl::LayoutInvalidated(bool descendants)
462f4664459SJohn Scipione{
463f4664459SJohn Scipione	CALLED();
464f4664459SJohn Scipione
465f4664459SJohn Scipione	fLayoutData->valid = false;
466f4664459SJohn Scipione}
467f4664459SJohn Scipione
468f4664459SJohn Scipione
469f4664459SJohn Scipionevoid
470f4664459SJohn ScipioneBTextControl::MessageReceived(BMessage* message)
471f4664459SJohn Scipione{
4727a96554cSlooncraz	if (message->what == B_COLORS_UPDATED) {
4737a96554cSlooncraz
4747a96554cSlooncraz		if (message->HasColor(ui_color_name(B_PANEL_BACKGROUND_COLOR))
4757a96554cSlooncraz			|| message->HasColor(ui_color_name(B_PANEL_TEXT_COLOR))
4767a96554cSlooncraz			|| message->HasColor(ui_color_name(B_DOCUMENT_BACKGROUND_COLOR))
4777a96554cSlooncraz			|| message->HasColor(ui_color_name(B_DOCUMENT_TEXT_COLOR))) {
4787a96554cSlooncraz			_UpdateTextViewColors(IsEnabled());
4797a96554cSlooncraz		}
4807a96554cSlooncraz	}
4817a96554cSlooncraz
482f4664459SJohn Scipione	if (message->what == B_GET_PROPERTY || message->what == B_SET_PROPERTY) {
483f4664459SJohn Scipione		BMessage reply(B_REPLY);
484f4664459SJohn Scipione		bool handled = false;
485f4664459SJohn Scipione
486f4664459SJohn Scipione		BMessage specifier;
487f4664459SJohn Scipione		int32 index;
488f4664459SJohn Scipione		int32 form;
489f4664459SJohn Scipione		const char* property;
490f4664459SJohn Scipione		if (message->GetCurrentSpecifier(&index, &specifier, &form, &property) == B_OK) {
491f4664459SJohn Scipione			if (strcmp(property, "Value") == 0) {
492f4664459SJohn Scipione				if (message->what == B_GET_PROPERTY) {
493f4664459SJohn Scipione					reply.AddString("result", fText->Text());
494f4664459SJohn Scipione					handled = true;
495f4664459SJohn Scipione				} else {
496f4664459SJohn Scipione					const char* value = NULL;
497f4664459SJohn Scipione					// B_SET_PROPERTY
498f4664459SJohn Scipione					if (message->FindString("data", &value) == B_OK) {
499f4664459SJohn Scipione						fText->SetText(value);
500f4664459SJohn Scipione						reply.AddInt32("error", B_OK);
501f4664459SJohn Scipione						handled = true;
502f4664459SJohn Scipione					}
503f4664459SJohn Scipione				}
504f4664459SJohn Scipione			}
505f4664459SJohn Scipione		}
506f4664459SJohn Scipione
507f4664459SJohn Scipione		if (handled) {
508f4664459SJohn Scipione			message->SendReply(&reply);
509f4664459SJohn Scipione			return;
510f4664459SJohn Scipione		}
511f4664459SJohn Scipione	}
512f4664459SJohn Scipione
513f4664459SJohn Scipione	BControl::MessageReceived(message);
514f4664459SJohn Scipione}
515f4664459SJohn Scipione
516f4664459SJohn Scipione
517f4664459SJohn Scipionevoid
518f4664459SJohn ScipioneBTextControl::MouseDown(BPoint where)
519f4664459SJohn Scipione{
520f4664459SJohn Scipione	if (!fText->IsFocus())
521f4664459SJohn Scipione		fText->MakeFocus(true);
522f4664459SJohn Scipione}
523f4664459SJohn Scipione
524f4664459SJohn Scipione
525f4664459SJohn Scipionevoid
526f4664459SJohn ScipioneBTextControl::MouseMoved(BPoint where, uint32 transit,
527f4664459SJohn Scipione	const BMessage* dragMessage)
528f4664459SJohn Scipione{
529f4664459SJohn Scipione	BControl::MouseMoved(where, transit, dragMessage);
530f4664459SJohn Scipione}
531f4664459SJohn Scipione
532f4664459SJohn Scipione
533f4664459SJohn Scipionevoid
534f4664459SJohn ScipioneBTextControl::MouseUp(BPoint where)
535f4664459SJohn Scipione{
536f4664459SJohn Scipione	BControl::MouseUp(where);
537f4664459SJohn Scipione}
538f4664459SJohn Scipione
539f4664459SJohn Scipione
540f4664459SJohn Scipionevoid
541f4664459SJohn ScipioneBTextControl::WindowActivated(bool active)
542f4664459SJohn Scipione{
543f4664459SJohn Scipione	if (fText->IsFocus()) {
544f4664459SJohn Scipione		// invalidate to remove/show focus indication
545f4664459SJohn Scipione		BRect rect = fText->Frame();
546f4664459SJohn Scipione		rect.InsetBy(-1, -1);
547f4664459SJohn Scipione		Invalidate(rect);
548f4664459SJohn Scipione
549f4664459SJohn Scipione		// help out embedded text view which doesn't
550f4664459SJohn Scipione		// get notified of this
551f4664459SJohn Scipione		fText->Invalidate();
552f4664459SJohn Scipione	}
553f4664459SJohn Scipione}
554f4664459SJohn Scipione
555f4664459SJohn Scipione
556f4664459SJohn Scipione//	#pragma mark - Getters and Setters
557f4664459SJohn Scipione
558f4664459SJohn Scipione
559f4664459SJohn Scipionevoid
560f4664459SJohn ScipioneBTextControl::SetText(const char* text)
56152a38012Sejakowatz{
5629cb2dbe2SMarc Flerackers	if (InvokeKind() != B_CONTROL_INVOKED)
5639cb2dbe2SMarc Flerackers		return;
5649cb2dbe2SMarc Flerackers
56593ba577cSStephan Aßmus	CALLED();
56693ba577cSStephan Aßmus
56752a38012Sejakowatz	fText->SetText(text);
5689cb2dbe2SMarc Flerackers
5695b349aa2SJérôme Duval	if (fText->IsFocus()) {
5709cb2dbe2SMarc Flerackers		fText->SetInitialText();
5715b349aa2SJérôme Duval		fText->SelectAll();
5725b349aa2SJérôme Duval	}
5739cb2dbe2SMarc Flerackers
5749cb2dbe2SMarc Flerackers	fText->Invalidate();
57552a38012Sejakowatz}
576058691d4SStefano Ceccherini
577058691d4SStefano Ceccherini
578f4664459SJohn Scipioneconst char*
579058691d4SStefano CeccheriniBTextControl::Text() const
58052a38012Sejakowatz{
58152a38012Sejakowatz	return fText->Text();
58252a38012Sejakowatz}
583058691d4SStefano Ceccherini
584058691d4SStefano Ceccherini
5858bc3ecb0SAxel Dörflerint32
5868bc3ecb0SAxel DörflerBTextControl::TextLength() const
5878bc3ecb0SAxel Dörfler{
5888bc3ecb0SAxel Dörfler	return fText->TextLength();
5898bc3ecb0SAxel Dörfler}
5908bc3ecb0SAxel Dörfler
5918bc3ecb0SAxel Dörfler
59213d147b1SAdrien Destuguesvoid
59313d147b1SAdrien DestuguesBTextControl::MarkAsInvalid(bool invalid)
59413d147b1SAdrien Destugues{
5956f9eb8d1SStephan Aßmus	uint32 look = fLook;
5966f9eb8d1SStephan Aßmus
59713d147b1SAdrien Destugues	if (invalid)
59813d147b1SAdrien Destugues		fLook |= BControlLook::B_INVALID;
59913d147b1SAdrien Destugues	else
60013d147b1SAdrien Destugues		fLook &= ~BControlLook::B_INVALID;
6016f9eb8d1SStephan Aßmus
6026f9eb8d1SStephan Aßmus	if (look != fLook)
6036f9eb8d1SStephan Aßmus		Invalidate();
60413d147b1SAdrien Destugues}
60513d147b1SAdrien Destugues
60613d147b1SAdrien Destugues
607058691d4SStefano Ceccherinivoid
608058691d4SStefano CeccheriniBTextControl::SetValue(int32 value)
60952a38012Sejakowatz{
6109cb2dbe2SMarc Flerackers	BControl::SetValue(value);
61152a38012Sejakowatz}
612058691d4SStefano Ceccherini
613058691d4SStefano Ceccherini
614b11edca4SJohn ScipioneBTextView*
615058691d4SStefano CeccheriniBTextControl::TextView() const
61652a38012Sejakowatz{
6179cb2dbe2SMarc Flerackers	return fText;
61852a38012Sejakowatz}
619058691d4SStefano Ceccherini
620058691d4SStefano Ceccherini
621058691d4SStefano Ceccherinivoid
622f4664459SJohn ScipioneBTextControl::SetModificationMessage(BMessage* message)
62352a38012Sejakowatz{
62428930a12SStephan Aßmus	delete fModificationMessage;
62552a38012Sejakowatz	fModificationMessage = message;
62652a38012Sejakowatz}
627058691d4SStefano Ceccherini
628058691d4SStefano Ceccherini
629f4664459SJohn ScipioneBMessage*
630058691d4SStefano CeccheriniBTextControl::ModificationMessage() const
63152a38012Sejakowatz{
63252a38012Sejakowatz	return fModificationMessage;
63352a38012Sejakowatz}
634058691d4SStefano Ceccherini
635058691d4SStefano Ceccherini
636058691d4SStefano Ceccherinivoid
637058691d4SStefano CeccheriniBTextControl::SetAlignment(alignment labelAlignment, alignment textAlignment)
63852a38012Sejakowatz{
639058691d4SStefano Ceccherini	fText->SetAlignment(textAlignment);
6409cb2dbe2SMarc Flerackers	fText->AlignTextRect();
6419cb2dbe2SMarc Flerackers
642058691d4SStefano Ceccherini	if (fLabelAlign != labelAlignment) {
643058691d4SStefano Ceccherini		fLabelAlign = labelAlignment;
6449cb2dbe2SMarc Flerackers		Invalidate();
6459cb2dbe2SMarc Flerackers	}
64652a38012Sejakowatz}
647058691d4SStefano Ceccherini
648058691d4SStefano Ceccherini
649058691d4SStefano Ceccherinivoid
650c432fbbbSAxel DörflerBTextControl::GetAlignment(alignment* _label, alignment* _text) const
65152a38012Sejakowatz{
652b11edca4SJohn Scipione	if (_label != NULL)
653c432fbbbSAxel Dörfler		*_label = fLabelAlign;
654b11edca4SJohn Scipione
655b11edca4SJohn Scipione	if (_text != NULL)
656c432fbbbSAxel Dörfler		*_text = fText->Alignment();
65752a38012Sejakowatz}
658058691d4SStefano Ceccherini
659058691d4SStefano Ceccherini
660058691d4SStefano Ceccherinivoid
661f4664459SJohn ScipioneBTextControl::SetDivider(float position)
66252a38012Sejakowatz{
663f4664459SJohn Scipione	fDivider = floorf(position + 0.5);
6642e6a5805SStephan Aßmus
665a431f44bSStephan Aßmus	_LayoutTextView();
6669cb2dbe2SMarc Flerackers
667058691d4SStefano Ceccherini	if (Window()) {
6689cb2dbe2SMarc Flerackers		fText->Invalidate();
6699cb2dbe2SMarc Flerackers		Invalidate();
67052a38012Sejakowatz	}
67152a38012Sejakowatz}
672058691d4SStefano Ceccherini
673058691d4SStefano Ceccherini
674058691d4SStefano Ceccherinifloat
675058691d4SStefano CeccheriniBTextControl::Divider() const
67652a38012Sejakowatz{
67752a38012Sejakowatz	return fDivider;
67852a38012Sejakowatz}
679058691d4SStefano Ceccherini
680058691d4SStefano Ceccherini
681058691d4SStefano Ceccherinivoid
682058691d4SStefano CeccheriniBTextControl::MakeFocus(bool state)
68352a38012Sejakowatz{
6846d8d6cadSStephan Aßmus	if (state != fText->IsFocus()) {
6856d8d6cadSStephan Aßmus		fText->MakeFocus(state);
6869cb2dbe2SMarc Flerackers
6876d8d6cadSStephan Aßmus		if (state)
6886d8d6cadSStephan Aßmus			fText->SelectAll();
6896d8d6cadSStephan Aßmus	}
69052a38012Sejakowatz}
691058691d4SStefano Ceccherini
692058691d4SStefano Ceccherini
693058691d4SStefano Ceccherinivoid
694f4664459SJohn ScipioneBTextControl::SetEnabled(bool enable)
69552a38012Sejakowatz{
696f4664459SJohn Scipione	if (IsEnabled() == enable)
6979cb2dbe2SMarc Flerackers		return;
6989cb2dbe2SMarc Flerackers
699f4664459SJohn Scipione	if (Window() != NULL) {
700f4664459SJohn Scipione		fText->MakeEditable(enable);
701f4664459SJohn Scipione		if (enable)
702c80f8962SJérôme Duval			fText->SetFlags(fText->Flags() | B_NAVIGABLE);
703c80f8962SJérôme Duval		else
704c80f8962SJérôme Duval			fText->SetFlags(fText->Flags() & ~B_NAVIGABLE);
7059cb2dbe2SMarc Flerackers
706f4664459SJohn Scipione		_UpdateTextViewColors(enable);
7079cb2dbe2SMarc Flerackers
7089cb2dbe2SMarc Flerackers		fText->Invalidate();
7099cb2dbe2SMarc Flerackers		Window()->UpdateIfNeeded();
7109cb2dbe2SMarc Flerackers	}
7119cb2dbe2SMarc Flerackers
712f4664459SJohn Scipione	BControl::SetEnabled(enable);
71352a38012Sejakowatz}
714058691d4SStefano Ceccherini
715058691d4SStefano Ceccherini
716058691d4SStefano Ceccherinivoid
717f4664459SJohn ScipioneBTextControl::GetPreferredSize(float* _width, float* _height)
71852a38012Sejakowatz{
719349c911eSStephan Aßmus	CALLED();
72052a38012Sejakowatz
721349c911eSStephan Aßmus	_ValidateLayoutData();
722105644bfSAxel Dörfler
7231aaf53ecSStephan Aßmus	if (_width) {
7241aaf53ecSStephan Aßmus		float minWidth = fLayoutData->min.width;
7251aaf53ecSStephan Aßmus		if (Label() == NULL && !(Flags() & B_SUPPORTS_LAYOUT)) {
7261aaf53ecSStephan Aßmus			// Indeed, only if there is no label! BeOS backwards compatible
7271aaf53ecSStephan Aßmus			// behavior:
7281aaf53ecSStephan Aßmus			minWidth = max_c(minWidth, Bounds().Width());
7291aaf53ecSStephan Aßmus		}
7301aaf53ecSStephan Aßmus		*_width = minWidth;
7311aaf53ecSStephan Aßmus	}
732349c911eSStephan Aßmus
733349c911eSStephan Aßmus	if (_height)
734349c911eSStephan Aßmus		*_height = fLayoutData->min.height;
73552a38012Sejakowatz}
736058691d4SStefano Ceccherini
737058691d4SStefano Ceccherini
738058691d4SStefano Ceccherinivoid
739058691d4SStefano CeccheriniBTextControl::ResizeToPreferred()
74052a38012Sejakowatz{
741105644bfSAxel Dörfler	BView::ResizeToPreferred();
7421bdc2a52SKarsten Heimrich
7431bdc2a52SKarsten Heimrich	fDivider = 0.0;
7441bdc2a52SKarsten Heimrich	const char* label = Label();
7451bdc2a52SKarsten Heimrich	if (label)
7461bdc2a52SKarsten Heimrich		fDivider = ceil(StringWidth(label)) + 2.0;
7471bdc2a52SKarsten Heimrich
7481bdc2a52SKarsten Heimrich	_LayoutTextView();
74952a38012Sejakowatz}
750058691d4SStefano Ceccherini
751058691d4SStefano Ceccherini
752058691d4SStefano Ceccherinivoid
753058691d4SStefano CeccheriniBTextControl::SetFlags(uint32 flags)
75452a38012Sejakowatz{
75593ba577cSStephan Aßmus	// If the textview is navigable, set it to not navigable if needed
75693ba577cSStephan Aßmus	// Else if it is not navigable, set it to navigable if needed
75793ba577cSStephan Aßmus	if (fText->Flags() & B_NAVIGABLE) {
75893ba577cSStephan Aßmus		if (!(flags & B_NAVIGABLE))
75993ba577cSStephan Aßmus			fText->SetFlags(fText->Flags() & ~B_NAVIGABLE);
760058691d4SStefano Ceccherini
76193ba577cSStephan Aßmus	} else {
76293ba577cSStephan Aßmus		if (flags & B_NAVIGABLE)
76393ba577cSStephan Aßmus			fText->SetFlags(fText->Flags() | B_NAVIGABLE);
7649cb2dbe2SMarc Flerackers	}
7655c47e35eSAlex Wilson
766c80f8962SJérôme Duval	// Don't make this one navigable
767c80f8962SJérôme Duval	flags &= ~B_NAVIGABLE;
768c80f8962SJérôme Duval
76952a38012Sejakowatz	BView::SetFlags(flags);
77052a38012Sejakowatz}
771058691d4SStefano Ceccherini
772058691d4SStefano Ceccherini
773f4664459SJohn Scipione//	#pragma mark - Scripting
774058691d4SStefano Ceccherini
775058691d4SStefano Ceccherini
776b11edca4SJohn ScipioneBHandler*
777b11edca4SJohn ScipioneBTextControl::ResolveSpecifier(BMessage* message, int32 index,
778b11edca4SJohn Scipione	BMessage* specifier, int32 what, const char* property)
77952a38012Sejakowatz{
7802a30a9e9SRene Gollent	BPropertyInfo propInfo(sPropertyList);
7819cb2dbe2SMarc Flerackers
7822a30a9e9SRene Gollent	if (propInfo.FindMatch(message, 0, specifier, what, property) >= B_OK)
7839cb2dbe2SMarc Flerackers		return this;
7842a30a9e9SRene Gollent
7852a30a9e9SRene Gollent	return BControl::ResolveSpecifier(message, index, specifier, what,
7862a30a9e9SRene Gollent		property);
78752a38012Sejakowatz}
788058691d4SStefano Ceccherini
789058691d4SStefano Ceccherini
790058691d4SStefano Ceccherinistatus_t
791b11edca4SJohn ScipioneBTextControl::GetSupportedSuites(BMessage* data)
79252a38012Sejakowatz{
7939cb2dbe2SMarc Flerackers	return BControl::GetSupportedSuites(data);
79452a38012Sejakowatz}
795058691d4SStefano Ceccherini
796058691d4SStefano Ceccherini
797f4664459SJohn Scipione//	#pragma mark - Layout
798058691d4SStefano Ceccherini
799058691d4SStefano Ceccherini
800349c911eSStephan AßmusBSize
801349c911eSStephan AßmusBTextControl::MinSize()
80252a38012Sejakowatz{
803349c911eSStephan Aßmus	CALLED();
804349c911eSStephan Aßmus
805349c911eSStephan Aßmus	_ValidateLayoutData();
806349c911eSStephan Aßmus	return BLayoutUtils::ComposeSize(ExplicitMinSize(), fLayoutData->min);
807349c911eSStephan Aßmus}
808349c911eSStephan Aßmus
809349c911eSStephan Aßmus
810349c911eSStephan AßmusBSize
811349c911eSStephan AßmusBTextControl::MaxSize()
812349c911eSStephan Aßmus{
813349c911eSStephan Aßmus	CALLED();
814349c911eSStephan Aßmus
815349c911eSStephan Aßmus	_ValidateLayoutData();
816349c911eSStephan Aßmus
817349c911eSStephan Aßmus	BSize max = fLayoutData->min;
818349c911eSStephan Aßmus	max.width = B_SIZE_UNLIMITED;
819349c911eSStephan Aßmus
820349c911eSStephan Aßmus	return BLayoutUtils::ComposeSize(ExplicitMaxSize(), max);
821349c911eSStephan Aßmus}
822349c911eSStephan Aßmus
823349c911eSStephan Aßmus
824349c911eSStephan AßmusBSize
825349c911eSStephan AßmusBTextControl::PreferredSize()
826349c911eSStephan Aßmus{
827349c911eSStephan Aßmus	CALLED();
828349c911eSStephan Aßmus
829349c911eSStephan Aßmus	_ValidateLayoutData();
830349c911eSStephan Aßmus	return BLayoutUtils::ComposeSize(ExplicitPreferredSize(), fLayoutData->min);
831349c911eSStephan Aßmus}
832349c911eSStephan Aßmus
833349c911eSStephan Aßmus
83446d6e9d9SRene GollentBAlignment
83546d6e9d9SRene GollentBTextControl::LayoutAlignment()
83646d6e9d9SRene Gollent{
83746d6e9d9SRene Gollent	CALLED();
83846d6e9d9SRene Gollent
83946d6e9d9SRene Gollent	_ValidateLayoutData();
84046d6e9d9SRene Gollent	return BLayoutUtils::ComposeAlignment(ExplicitAlignment(),
841be92485fSHumdinger		BAlignment(B_ALIGN_LEFT, B_ALIGN_VERTICAL_CENTER));
84246d6e9d9SRene Gollent}
84346d6e9d9SRene Gollent
84446d6e9d9SRene Gollent
8459ecf9d1cSIngo WeinholdBLayoutItem*
8469ecf9d1cSIngo WeinholdBTextControl::CreateLabelLayoutItem()
8479ecf9d1cSIngo Weinhold{
848349c911eSStephan Aßmus	if (!fLayoutData->label_layout_item)
849349c911eSStephan Aßmus		fLayoutData->label_layout_item = new LabelLayoutItem(this);
850b11edca4SJohn Scipione
851349c911eSStephan Aßmus	return fLayoutData->label_layout_item;
8529ecf9d1cSIngo Weinhold}
8539ecf9d1cSIngo Weinhold
8549ecf9d1cSIngo Weinhold
8559ecf9d1cSIngo WeinholdBLayoutItem*
8569ecf9d1cSIngo WeinholdBTextControl::CreateTextViewLayoutItem()
8579ecf9d1cSIngo Weinhold{
858349c911eSStephan Aßmus	if (!fLayoutData->text_view_layout_item)
859349c911eSStephan Aßmus		fLayoutData->text_view_layout_item = new TextViewLayoutItem(this);
860b11edca4SJohn Scipione
861349c911eSStephan Aßmus	return fLayoutData->text_view_layout_item;
862349c911eSStephan Aßmus}
863349c911eSStephan Aßmus
864349c911eSStephan Aßmus
865349c911eSStephan Aßmusvoid
866349c911eSStephan AßmusBTextControl::DoLayout()
867349c911eSStephan Aßmus{
868349c911eSStephan Aßmus	// Bail out, if we shan't do layout.
869349c911eSStephan Aßmus	if (!(Flags() & B_SUPPORTS_LAYOUT))
870349c911eSStephan Aßmus		return;
871