1f9776157SAxel Dörfler/*
295fdee0bSAxel Dörfler * Copyright 2001-2015, Haiku, Inc. All rights reserved.
3f9776157SAxel Dörfler * Distributed under the terms of the MIT License.
4f9776157SAxel Dörfler *
5f9776157SAxel Dörfler * Authors:
695fdee0bSAxel Dörfler *		Stephan A��mus <superstippi@gmx.de>
795fdee0bSAxel Dörfler *		Axel D��rfler, axeld@pinc-software.de
8f9776157SAxel Dörfler *		Frans van Nispen (xlr8@tref.nl)
9d3fe87ceSStephan Aßmus *		Ingo Weinhold <ingo_weinhold@gmx.de>
10f9776157SAxel Dörfler */
11f9776157SAxel Dörfler
1295fdee0bSAxel Dörfler
13d3fe87ceSStephan Aßmus//!	BStringView draws a non-editable text string.
14f9776157SAxel Dörfler
1552a38012Sejakowatz
1652a38012Sejakowatz#include <StringView.h>
179ecf9d1cSIngo Weinhold
18a2bea84dSJohn Scipione#include <stdio.h>
19a2bea84dSJohn Scipione#include <stdlib.h>
20a2bea84dSJohn Scipione#include <string.h>
21a2bea84dSJohn Scipione
229ecf9d1cSIngo Weinhold#include <LayoutUtils.h>
239ecf9d1cSIngo Weinhold#include <Message.h>
24bee420ffSJohn Scipione#include <PropertyInfo.h>
25800e6fe4SKacper Kasper#include <StringList.h>
2652a38012Sejakowatz#include <View.h>
2752a38012Sejakowatz#include <Window.h>
2852a38012Sejakowatz
2939fbf550SOliver Tappe#include <binary_compatibility/Interface.h>
3039fbf550SOliver Tappe
3152a38012Sejakowatz
32bee420ffSJohn Scipionestatic property_info sPropertyList[] = {
33bee420ffSJohn Scipione	{
34bee420ffSJohn Scipione		"Text",
35bee420ffSJohn Scipione		{ B_GET_PROPERTY, B_SET_PROPERTY },
36bee420ffSJohn Scipione		{ B_DIRECT_SPECIFIER },
37bee420ffSJohn Scipione		NULL, 0,
38bee420ffSJohn Scipione		{ B_STRING_TYPE }
39bee420ffSJohn Scipione	},
40bee420ffSJohn Scipione	{
41bee420ffSJohn Scipione		"Alignment",
42bee420ffSJohn Scipione		{ B_GET_PROPERTY, B_SET_PROPERTY },
43bee420ffSJohn Scipione		{ B_DIRECT_SPECIFIER },
44bee420ffSJohn Scipione		NULL, 0,
45bee420ffSJohn Scipione		{ B_INT32_TYPE }
46bee420ffSJohn Scipione	},
47346d1496SHumdinger
48346d1496SHumdinger	{ 0 }
49bee420ffSJohn Scipione};
50bee420ffSJohn Scipione
51bee420ffSJohn Scipione
5252a38012SejakowatzBStringView::BStringView(BRect frame, const char* name, const char* text,
535ae0cde3SJohn Scipione	uint32 resizingMode, uint32 flags)
545ae0cde3SJohn Scipione	:
555ae0cde3SJohn Scipione	BView(frame, name, resizingMode, flags | B_FULL_UPDATE_ON_RESIZE),
565ae0cde3SJohn Scipione	fText(text ? strdup(text) : NULL),
5795fdee0bSAxel Dörfler	fTruncation(B_NO_TRUNCATION),
585ae0cde3SJohn Scipione	fAlign(B_ALIGN_LEFT),
59800e6fe4SKacper Kasper	fPreferredSize(text ? _StringWidth(text) : 0.0, -1)
60d3fe87ceSStephan Aßmus{
61d3fe87ceSStephan Aßmus}
62d3fe87ceSStephan Aßmus
63d3fe87ceSStephan Aßmus
64d3fe87ceSStephan AßmusBStringView::BStringView(const char* name, const char* text, uint32 flags)
655ae0cde3SJohn Scipione	:
665ae0cde3SJohn Scipione	BView(name, flags | B_FULL_UPDATE_ON_RESIZE),
675ae0cde3SJohn Scipione	fText(text ? strdup(text) : NULL),
6895fdee0bSAxel Dörfler	fTruncation(B_NO_TRUNCATION),
695ae0cde3SJohn Scipione	fAlign(B_ALIGN_LEFT),
70800e6fe4SKacper Kasper	fPreferredSize(text ? _StringWidth(text) : 0.0, -1)
7152a38012Sejakowatz{
7252a38012Sejakowatz}
73f9776157SAxel Dörfler
74f9776157SAxel Dörfler
755ae0cde3SJohn ScipioneBStringView::BStringView(BMessage* archive)
765ae0cde3SJohn Scipione	:
775ae0cde3SJohn Scipione	BView(archive),
785ae0cde3SJohn Scipione	fText(NULL),
7995fdee0bSAxel Dörfler	fTruncation(B_NO_TRUNCATION),
8095fdee0bSAxel Dörfler	fPreferredSize(0, -1)
8152a38012Sejakowatz{
8295fdee0bSAxel Dörfler	fAlign = (alignment)archive->GetInt32("_align", B_ALIGN_LEFT);
8395fdee0bSAxel Dörfler	fTruncation = (uint32)archive->GetInt32("_truncation", B_NO_TRUNCATION);
8452a38012Sejakowatz
8595fdee0bSAxel Dörfler	const char* text = archive->GetString("_text", NULL);
8652a38012Sejakowatz
8752a38012Sejakowatz	SetText(text);
88b10020deSStephan Aßmus	SetFlags(Flags() | B_FULL_UPDATE_ON_RESIZE);
8952a38012Sejakowatz}
90f9776157SAxel Dörfler
91f9776157SAxel Dörfler
9289208c77SStephan AßmusBStringView::~BStringView()
9389208c77SStephan Aßmus{
9489208c77SStephan Aßmus	free(fText);
9589208c77SStephan Aßmus}
9689208c77SStephan Aßmus
9789208c77SStephan Aßmus
985ae0cde3SJohn Scipione// #pragma mark - Archiving methods
995ae0cde3SJohn Scipione
1005ae0cde3SJohn Scipione
101f9776157SAxel DörflerBArchivable*
102f9776157SAxel DörflerBStringView::Instantiate(BMessage* data)
10352a38012Sejakowatz{
104f9776157SAxel Dörfler	if (!validate_instantiation(data, "BStringView"))
10552a38012Sejakowatz		return NULL;
10652a38012Sejakowatz
10752a38012Sejakowatz	return new BStringView(data);
10852a38012Sejakowatz}
109f9776157SAxel Dörfler
110f9776157SAxel Dörfler
111f9776157SAxel Dörflerstatus_t
112f9776157SAxel DörflerBStringView::Archive(BMessage* data, bool deep) const
11352a38012Sejakowatz{
11495fdee0bSAxel Dörfler	status_t status = BView::Archive(data, deep);
115f9776157SAxel Dörfler
11695fdee0bSAxel Dörfler	if (status == B_OK && fText)
11795fdee0bSAxel Dörfler		status = data->AddString("_text", fText);
11895fdee0bSAxel Dörfler	if (status == B_OK && fTruncation != B_NO_TRUNCATION)
11995fdee0bSAxel Dörfler		status = data->AddInt32("_truncation", fTruncation);
12095fdee0bSAxel Dörfler	if (status == B_OK)
12195fdee0bSAxel Dörfler		status = data->AddInt32("_align", fAlign);
12252a38012Sejakowatz
12395fdee0bSAxel Dörfler	return status;
12452a38012Sejakowatz}
125f9776157SAxel Dörfler
126f9776157SAxel Dörfler
1275ae0cde3SJohn Scipione// #pragma mark - Hook methods
12889208c77SStephan Aßmus
12989208c77SStephan Aßmus
13089208c77SStephan Aßmusvoid
13189208c77SStephan AßmusBStringView::AttachedToWindow()
13252a38012Sejakowatz{
13304039d6fSlooncraz	if (HasDefaultColors())
1347a96554cSlooncraz		SetHighUIColor(B_PANEL_TEXT_COLOR);
1357a96554cSlooncraz
13604039d6fSlooncraz	BView* parent = Parent();
13704039d6fSlooncraz
13804039d6fSlooncraz	if (parent != NULL) {
13904039d6fSlooncraz		float tint = B_NO_TINT;
14004039d6fSlooncraz		color_which which = parent->ViewUIColor(&tint);
14104039d6fSlooncraz
14204039d6fSlooncraz		if (which != B_NO_COLOR) {
14304039d6fSlooncraz			SetViewUIColor(which, tint);
14404039d6fSlooncraz			SetLowUIColor(which, tint);
14504039d6fSlooncraz		} else {
14604039d6fSlooncraz			SetViewColor(parent->ViewColor());
14704039d6fSlooncraz			SetLowColor(ViewColor());
14804039d6fSlooncraz		}
1497a96554cSlooncraz	}
15004039d6fSlooncraz
15104039d6fSlooncraz	if (ViewColor() == B_TRANSPARENT_COLOR)
15204039d6fSlooncraz		AdoptSystemColors();
15352a38012Sejakowatz}
154f9776157SAxel Dörfler
155f9776157SAxel Dörfler
156f9776157SAxel Dörflervoid
15789208c77SStephan AßmusBStringView::DetachedFromWindow()
15852a38012Sejakowatz{
15989208c77SStephan Aßmus	BView::DetachedFromWindow();
16089208c77SStephan Aßmus}
161d3fe87ceSStephan Aßmus
162d3fe87ceSStephan Aßmus
16389208c77SStephan Aßmusvoid
16489208c77SStephan AßmusBStringView::AllAttached()
16589208c77SStephan Aßmus{
16689208c77SStephan Aßmus	BView::AllAttached();
16752a38012Sejakowatz}
168f9776157SAxel Dörfler
169f9776157SAxel Dörfler
17089208c77SStephan Aßmusvoid
17189208c77SStephan AßmusBStringView::AllDetached()
17252a38012Sejakowatz{
17389208c77SStephan Aßmus	BView::AllDetached();
17452a38012Sejakowatz}
175f9776157SAxel Dörfler
176f9776157SAxel Dörfler
1775ae0cde3SJohn Scipione// #pragma mark - Layout methods
17889208c77SStephan Aßmus
17989208c77SStephan Aßmus
180f9776157SAxel Dörflervoid
1815ae0cde3SJohn ScipioneBStringView::MakeFocus(bool focus)
18252a38012Sejakowatz{
1835ae0cde3SJohn Scipione	BView::MakeFocus(focus);
18452a38012Sejakowatz}
185f9776157SAxel Dörfler
186f9776157SAxel Dörfler
18789208c77SStephan Aßmusvoid
18889208c77SStephan AßmusBStringView::GetPreferredSize(float* _width, float* _height)
18952a38012Sejakowatz{
19089208c77SStephan Aßmus	_ValidatePreferredSize();
19189208c77SStephan Aßmus
19289208c77SStephan Aßmus	if (_width)
19389208c77SStephan Aßmus		*_width = fPreferredSize.width;
19489208c77SStephan Aßmus
19589208c77SStephan Aßmus	if (_height)
19689208c77SStephan Aßmus		*_height = fPreferredSize.height;
19789208c77SStephan Aßmus}
19889208c77SStephan Aßmus
19989208c77SStephan Aßmus
20089208c77SStephan AßmusBSize
20189208c77SStephan AßmusBStringView::MinSize()
20289208c77SStephan Aßmus{
20389208c77SStephan Aßmus	return BLayoutUtils::ComposeSize(ExplicitMinSize(),
20489208c77SStephan Aßmus		_ValidatePreferredSize());
20589208c77SStephan Aßmus}
20689208c77SStephan Aßmus
20789208c77SStephan Aßmus
20889208c77SStephan AßmusBSize
20989208c77SStephan AßmusBStringView::MaxSize()
21089208c77SStephan Aßmus{
21189208c77SStephan Aßmus	return BLayoutUtils::ComposeSize(ExplicitMaxSize(),
21289208c77SStephan Aßmus		_ValidatePreferredSize());
21389208c77SStephan Aßmus}
21489208c77SStephan Aßmus
21589208c77SStephan Aßmus
21689208c77SStephan AßmusBSize
21789208c77SStephan AßmusBStringView::PreferredSize()
21889208c77SStephan Aßmus{
21989208c77SStephan Aßmus	return BLayoutUtils::ComposeSize(ExplicitPreferredSize(),
22089208c77SStephan Aßmus		_ValidatePreferredSize());
22152a38012Sejakowatz}
222f9776157SAxel Dörfler
223f9776157SAxel Dörfler
22489208c77SStephan Aßmusvoid
22589208c77SStephan AßmusBStringView::ResizeToPreferred()
22689208c77SStephan Aßmus{
22789208c77SStephan Aßmus	float width, height;
22889208c77SStephan Aßmus	GetPreferredSize(&width, &height);
22989208c77SStephan Aßmus
23089208c77SStephan Aßmus	// Resize the width only for B_ALIGN_LEFT (if its large enough already, that is)
23189208c77SStephan Aßmus	if (Bounds().Width() > width && Alignment() != B_ALIGN_LEFT)
23289208c77SStephan Aßmus		width = Bounds().Width();
23389208c77SStephan Aßmus
23489208c77SStephan Aßmus	BView::ResizeTo(width, height);
23589208c77SStephan Aßmus}
23689208c77SStephan Aßmus
23789208c77SStephan Aßmus
238a2bea84dSJohn ScipioneBAlignment
239a2bea84dSJohn ScipioneBStringView::LayoutAlignment()
240a2bea84dSJohn Scipione{
241a2bea84dSJohn Scipione	return BLayoutUtils::ComposeAlignment(ExplicitAlignment(),
242a2bea84dSJohn Scipione		BAlignment(fAlign, B_ALIGN_MIDDLE));
243a2bea84dSJohn Scipione}
244a2bea84dSJohn Scipione
245a2bea84dSJohn Scipione
2465ae0cde3SJohn Scipione// #pragma mark - More hook methods
2475ae0cde3SJohn Scipione
2485ae0cde3SJohn Scipione
24989208c77SStephan Aßmusvoid
25089208c77SStephan AßmusBStringView::FrameMoved(BPoint newPosition)
25189208c77SStephan Aßmus{
25289208c77SStephan Aßmus	BView::FrameMoved(newPosition);
25352a38012Sejakowatz}
254f9776157SAxel Dörfler
255f9776157SAxel Dörfler
25689208c77SStephan Aßmusvoid
25789208c77SStephan AßmusBStringView::FrameResized(float newWidth, float newHeight)
25889208c77SStephan Aßmus{
25989208c77SStephan Aßmus	BView::FrameResized(newWidth, newHeight);
26089208c77SStephan Aßmus}
26189208c77SStephan Aßmus
26289208c77SStephan Aßmus
263f9776157SAxel Dörflervoid
264e87506afSStephan AßmusBStringView::Draw(BRect updateRect)
26552a38012Sejakowatz{
26645b01319SStephan Aßmus	if (!fText)
26745b01319SStephan Aßmus		return;
26845b01319SStephan Aßmus
2697a96554cSlooncraz	if (LowUIColor() == B_NO_COLOR)
2707a96554cSlooncraz		SetLowColor(ViewColor());
271f9776157SAxel Dörfler
272f9776157SAxel Dörfler	font_height fontHeight;
273f9776157SAxel Dörfler	GetFontHeight(&fontHeight);
274f9776157SAxel Dörfler
275d3fe87ceSStephan Aßmus	BRect bounds = Bounds();
276d3fe87ceSStephan Aßmus
277800e6fe4SKacper Kasper	BStringList lines;
278800e6fe4SKacper Kasper	BString(fText).Split("\n", false, lines);
279800e6fe4SKacper Kasper	for (int i = 0; i < lines.CountStrings(); i++) {
280800e6fe4SKacper Kasper		const char* text = lines.StringAt(i).String();
281800e6fe4SKacper Kasper		float width = StringWidth(text);
282800e6fe4SKacper Kasper		BString truncated;
283800e6fe4SKacper Kasper		if (fTruncation != B_NO_TRUNCATION && width > bounds.Width()) {
284800e6fe4SKacper Kasper			// The string needs to be truncated
285800e6fe4SKacper Kasper			// TODO: we should cache this
286800e6fe4SKacper Kasper			truncated = lines.StringAt(i);
287800e6fe4SKacper Kasper			TruncateString(&truncated, fTruncation, bounds.Width());
288800e6fe4SKacper Kasper			text = truncated.String();
289800e6fe4SKacper Kasper			width = StringWidth(text);
290800e6fe4SKacper Kasper		}
29195fdee0bSAxel Dörfler
292800e6fe4SKacper Kasper		float y = (bounds.top + bounds.bottom - ceilf(fontHeight.descent))
293800e6fe4SKacper Kasper			- ceilf(fontHeight.ascent + fontHeight.descent + fontHeight.leading)
294800e6fe4SKacper Kasper				* (lines.CountStrings() - i - 1);
295800e6fe4SKacper Kasper		float x;
296800e6fe4SKacper Kasper		switch (fAlign) {
297800e6fe4SKacper Kasper			case B_ALIGN_RIGHT:
298800e6fe4SKacper Kasper				x = bounds.Width() - width;
299800e6fe4SKacper Kasper				break;
300800e6fe4SKacper Kasper
301800e6fe4SKacper Kasper			case B_ALIGN_CENTER:
302800e6fe4SKacper Kasper				x = (bounds.Width() - width) / 2.0;
303800e6fe4SKacper Kasper				break;
304800e6fe4SKacper Kasper
305800e6fe4SKacper Kasper			default:
306800e6fe4SKacper Kasper				x = 0.0;
307800e6fe4SKacper Kasper				break;
308800e6fe4SKacper Kasper		}
30952a38012Sejakowatz
310800e6fe4SKacper Kasper		DrawString(text, BPoint(x, y));
311800e6fe4SKacper Kasper	}
31252a38012Sejakowatz}
313f9776157SAxel Dörfler
314f9776157SAxel Dörfler
315f9776157SAxel Dörflervoid
316f9776157SAxel DörflerBStringView::MessageReceived(BMessage* message)
31752a38012Sejakowatz{
318bee420ffSJohn Scipione	if (message->what == B_GET_PROPERTY || message->what == B_SET_PROPERTY) {
319bee420ffSJohn Scipione		int32 index;
320bee420ffSJohn Scipione		BMessage specifier;
321bee420ffSJohn Scipione		int32 form;
322bee420ffSJohn Scipione		const char* property;
323bee420ffSJohn Scipione		if (message->GetCurrentSpecifier(&index, &specifier, &form, &property)
324bee420ffSJohn Scipione				!= B_OK) {
325bee420ffSJohn Scipione			BView::MessageReceived(message);
326bee420ffSJohn Scipione			return;
327bee420ffSJohn Scipione		}
328bee420ffSJohn Scipione
329bee420ffSJohn Scipione		BMessage reply(B_REPLY);
330bee420ffSJohn Scipione		bool handled = false;
331bee420ffSJohn Scipione		if (strcmp(property, "Text") == 0) {
332bee420ffSJohn Scipione			if (message->what == B_GET_PROPERTY) {
333bee420ffSJohn Scipione				reply.AddString("result", fText);
334bee420ffSJohn Scipione				handled = true;
335bee420ffSJohn Scipione			} else {
336bee420ffSJohn Scipione				const char* text;
337bee420ffSJohn Scipione				if (message->FindString("data", &text) == B_OK) {
338bee420ffSJohn Scipione					SetText(text);
339bee420ffSJohn Scipione					reply.AddInt32("error", B_OK);
340bee420ffSJohn Scipione					handled = true;
341bee420ffSJohn Scipione				}
342bee420ffSJohn Scipione			}
343bee420ffSJohn Scipione		} else if (strcmp(property, "Alignment") == 0) {
344bee420ffSJohn Scipione			if (message->what == B_GET_PROPERTY) {
345bee420ffSJohn Scipione				reply.AddInt32("result", (int32)fAlign);
346bee420ffSJohn Scipione				handled = true;
347bee420ffSJohn Scipione			} else {
348bee420ffSJohn Scipione				int32 align;
349bee420ffSJohn Scipione				if (message->FindInt32("data", &align) == B_OK) {
350bee420ffSJohn Scipione					SetAlignment((alignment)align);
351bee420ffSJohn Scipione					reply.AddInt32("error", B_OK);
352bee420ffSJohn Scipione					handled = true;
353bee420ffSJohn Scipione				}
354bee420ffSJohn Scipione			}
355bee420ffSJohn Scipione		}
356bee420ffSJohn Scipione
357bee420ffSJohn Scipione		if (handled) {
358bee420ffSJohn Scipione			message->SendReply(&reply);
359bee420ffSJohn Scipione			return;
360bee420ffSJohn Scipione		}
361bee420ffSJohn Scipione	}
362bee420ffSJohn Scipione
363f9776157SAxel Dörfler	BView::MessageReceived(message);
36452a38012Sejakowatz}
365f9776157SAxel Dörfler
366f9776157SAxel Dörfler
367f9776157SAxel Dörflervoid
368f9776157SAxel DörflerBStringView::MouseDown(BPoint point)
36952a38012Sejakowatz{
370f9776157SAxel Dörfler	BView::MouseDown(point);
37152a38012Sejakowatz}
372f9776157SAxel Dörfler
373f9776157SAxel Dörfler
374f9776157SAxel Dörflervoid
375f9776157SAxel DörflerBStringView::MouseUp(BPoint point)
37652a38012Sejakowatz{
377f9776157SAxel Dörfler	BView::MouseUp(point);
37852a38012Sejakowatz}
379f9776157SAxel Dörfler
380f9776157SAxel Dörfler
381f9776157SAxel Dörflervoid
382f9776157SAxel DörflerBStringView::MouseMoved(BPoint point, uint32 transit, const BMessage* msg)
38352a38012Sejakowatz{
384f9776157SAxel Dörfler	BView::MouseMoved(point, transit, msg);
38552a38012Sejakowatz}
386f9776157SAxel Dörfler
387f9776157SAxel Dörfler
38889208c77SStephan Aßmus// #pragma mark -
389f9776157SAxel Dörfler
390f9776157SAxel Dörfler
391f9776157SAxel Dörflervoid
39289208c77SStephan AßmusBStringView::SetText(const char* text)
39352a38012Sejakowatz{
39489208c77SStephan Aßmus	if ((text && fText && !strcmp(text, fText)) || (!text && !fText))
39589208c77SStephan Aßmus		return;
396f9776157SAxel Dörfler
39789208c77SStephan Aßmus	free(fText);
39889208c77SStephan Aßmus	fText = text ? strdup(text) : NULL;
399f9776157SAxel Dörfler
400800e6fe4SKacper Kasper	float newStringWidth = _StringWidth(fText);
40195fdee0bSAxel Dörfler	if (fPreferredSize.width != newStringWidth) {
40295fdee0bSAxel Dörfler		fPreferredSize.width = newStringWidth;
40338c4dc0eSStephan Aßmus		InvalidateLayout();
4047ae97406SPhilippe Houdoin	}
40538c4dc0eSStephan Aßmus
40689208c77SStephan Aßmus	Invalidate();
40752a38012Sejakowatz}
408f9776157SAxel Dörfler
409f9776157SAxel Dörfler
41089208c77SStephan Aßmusconst char*
41189208c77SStephan AßmusBStringView::Text() const
41252a38012Sejakowatz{
41389208c77SStephan Aßmus	return fText;
41452a38012Sejakowatz}
415f9776157SAxel Dörfler
416f9776157SAxel Dörfler
417f9776157SAxel Dörflervoid
41889208c77SStephan AßmusBStringView::SetAlignment(alignment flag)
41952a38012Sejakowatz{
42089208c77SStephan Aßmus	fAlign = flag;
42189208c77SStephan Aßmus	Invalidate();
42252a38012Sejakowatz}
423f9776157SAxel Dörfler
424f9776157SAxel Dörfler
42589208c77SStephan Aßmusalignment
42689208c77SStephan AßmusBStringView::Alignment() const
42752a38012Sejakowatz{
42889208c77SStephan Aßmus	return fAlign;
42952a38012Sejakowatz}
430f9776157SAxel Dörfler
431f9776157SAxel Dörfler
43295fdee0bSAxel Dörflervoid
43395fdee0bSAxel DörflerBStringView::SetTruncation(uint32 truncationMode)
43495fdee0bSAxel Dörfler{
43595fdee0bSAxel Dörfler	if (fTruncation != truncationMode) {
43695fdee0bSAxel Dörfler		fTruncation = truncationMode;
43795fdee0bSAxel Dörfler		Invalidate();
43895fdee0bSAxel Dörfler	}
43995fdee0bSAxel Dörfler}
44095fdee0bSAxel Dörfler
44195fdee0bSAxel Dörfler
44295fdee0bSAxel Dörfleruint32
44395fdee0bSAxel DörflerBStringView::Truncation() const
44495fdee0bSAxel Dörfler{
44595fdee0bSAxel Dörfler	return fTruncation;
44695fdee0bSAxel Dörfler}
44795fdee0bSAxel Dörfler
44895fdee0bSAxel Dörfler
44989208c77SStephan AßmusBHandler*
450bee420ffSJohn ScipioneBStringView::ResolveSpecifier(BMessage* message, int32 index,
45189208c77SStephan Aßmus	BMessage* specifier, int32 form, const char* property)
45252a38012Sejakowatz{
453bee420ffSJohn Scipione	BPropertyInfo propInfo(sPropertyList);
454bee420ffSJohn Scipione	if (propInfo.FindMatch(message, 0, specifier, form, property) >= B_OK)
455bee420ffSJohn Scipione		return this;
456bee420ffSJohn Scipione
457bee420ffSJohn Scipione	return BView::ResolveSpecifier(message, index, specifier, form, property);
45852a38012Sejakowatz}
459f9776157SAxel Dörfler
460f9776157SAxel Dörfler
461f9776157SAxel Dörflerstatus_t
462bee420ffSJohn ScipioneBStringView::GetSupportedSuites(BMessage* data)
46352a38012Sejakowatz{
464bee420ffSJohn Scipione	if (data == NULL)
465bee420ffSJohn Scipione		return B_BAD_VALUE;
466bee420ffSJohn Scipione
467bee420ffSJohn Scipione	status_t status = data->AddString("suites", "suite/vnd.Be-string-view");
468bee420ffSJohn Scipione	if (status != B_OK)
469bee420ffSJohn Scipione		return status;
470bee420ffSJohn Scipione
471bee420ffSJohn Scipione	BPropertyInfo propertyInfo(sPropertyList);
472bee420ffSJohn Scipione	status = data->AddFlat("messages", &propertyInfo);
473bee420ffSJohn Scipione	if (status != B_OK)
474bee420ffSJohn Scipione		return status;
475bee420ffSJohn Scipione
476bee420ffSJohn Scipione	return BView::GetSupportedSuites(data);
47752a38012Sejakowatz}
478f9776157SAxel Dörfler
479f9776157SAxel Dörfler
480e87506afSStephan Aßmusvoid
481e87506afSStephan AßmusBStringView::SetFont(const BFont* font, uint32 mask)
482e87506afSStephan Aßmus{
483e87506afSStephan Aßmus	BView::SetFont(font, mask);
484e87506afSStephan Aßmus
485800e6fe4SKacper Kasper	fPreferredSize.width = _StringWidth(fText);
4867ae97406SPhilippe Houdoin
4871370f1b6SStephan Aßmus	Invalidate();
488e87506afSStephan Aßmus	InvalidateLayout();
489e87506afSStephan Aßmus}
490e87506afSStephan Aßmus
491e87506afSStephan Aßmus
492eee4243dSAlex Wilsonvoid
493eee4243dSAlex WilsonBStringView::LayoutInvalidated(bool descendants)
494eee4243dSAlex Wilson{
495eee4243dSAlex Wilson	// invalidate cached preferred size
49695fdee0bSAxel Dörfler	fPreferredSize.height = -1;
497eee4243dSAlex Wilson}
498eee4243dSAlex Wilson
499eee4243dSAlex Wilson
5005ae0cde3SJohn Scipione// #pragma mark - Perform
5019ecf9d1cSIngo Weinhold
5029ecf9d1cSIngo Weinhold
503f9776157SAxel Dörflerstatus_t
50439fbf550SOliver TappeBStringView::Perform(perform_code code, void* _data)
50539fbf550SOliver Tappe{
50639fbf550SOliver Tappe	switch (code) {
50739fbf550SOliver Tappe		case PERFORM_CODE_MIN_SIZE:
50839fbf550SOliver Tappe			((perform_data_min_size*)_data)->return_value
50939fbf550SOliver Tappe				= BStringView::MinSize();
51039fbf550SOliver Tappe			return B_OK;
5115ae0cde3SJohn Scipione
51239fbf550SOliver Tappe		case PERFORM_CODE_MAX_SIZE:
51339fbf550SOliver Tappe			((perform_data_max_size*)_data)->return_value
51439fbf550SOliver Tappe				= BStringView::MaxSize();
51539fbf550SOliver Tappe			return B_OK;
5165ae0cde3SJohn Scipione
51739fbf550SOliver Tappe		case PERFORM_CODE_PREFERRED_SIZE:
51839fbf550SOliver Tappe			((perform_data_preferred_size*)_data)->return_value
51939fbf550SOliver Tappe				= BStringView::PreferredSize();
52039fbf550SOliver Tappe			return B_OK;
5215ae0cde3SJohn Scipione
52239fbf550SOliver Tappe		case PERFORM_CODE_LAYOUT_ALIGNMENT:
52339fbf550SOliver Tappe			((perform_data_layout_alignment*)_data)->return_value
52439fbf550SOliver Tappe				= BStringView::LayoutAlignment();
52539fbf550SOliver Tappe			return B_OK;
5265ae0cde3SJohn Scipione
52739fbf550SOliver Tappe		case PERFORM_CODE_HAS_HEIGHT_FOR_WIDTH:
52839fbf550SOliver Tappe			((perform_data_has_height_for_width*)_data)->return_value
52939fbf550SOliver Tappe				= BStringView::HasHeightForWidth();
53039fbf550SOliver Tappe			return B_OK;
5315ae0cde3SJohn Scipione
53239fbf550SOliver Tappe		case PERFORM_CODE_GET_HEIGHT_FOR_WIDTH:
53339fbf550SOliver Tappe		{
53439fbf550SOliver Tappe			perform_data_get_height_for_width* data
53539fbf550SOliver Tappe				= (perform_data_get_height_for_width*)_data;
53639fbf550SOliver Tappe			BStringView::GetHeightForWidth(data->width, &data->min, &data->max,
53739fbf550SOliver Tappe				&data->preferred);
53839fbf550SOliver Tappe			return B_OK;
539b10020deSStephan Aßmus		}
5405ae0cde3SJohn Scipione
54139fbf550SOliver Tappe		case PERFORM_CODE_SET_LAYOUT:
54239fbf550SOliver Tappe		{
54339fbf550SOliver Tappe			perform_data_set_layout* data = (perform_data_set_layout*)_data;
54439fbf550SOliver Tappe			BStringView::SetLayout(data->layout);
54539fbf550SOliver Tappe			return B_OK;
54639fbf550SOliver Tappe		}
5475ae0cde3SJohn Scipione
548eee4243dSAlex Wilson		case PERFORM_CODE_LAYOUT_INVALIDATED:
54939fbf550SOliver Tappe		{
550eee4243dSAlex Wilson			perform_data_layout_invalidated* data
551eee4243dSAlex Wilson				= (perform_data_layout_invalidated*)_data;
552eee4243dSAlex Wilson			BStringView::LayoutInvalidated(data->descendants);
55339fbf550SOliver Tappe			return B_OK;
55439fbf550SOliver Tappe		}
5555ae0cde3SJohn Scipione
55639fbf550SOliver Tappe		case PERFORM_CODE_DO_LAYOUT:
55739fbf550SOliver Tappe		{
55839fbf550SOliver Tappe			BStringView::DoLayout();
55939fbf550SOliver Tappe			return B_OK;
56039fbf550SOliver Tappe		}
56139fbf550SOliver Tappe	}
56239fbf550SOliver Tappe
56339fbf550SOliver Tappe	return BView::Perform(code, _data);
56452a38012Sejakowatz}
565f9776157SAxel Dörfler
566f9776157SAxel Dörfler
5675ae0cde3SJohn Scipione// #pragma mark - FBC padding methods
5685ae0cde3SJohn Scipione
56939fbf550SOliver Tappe
570f9776157SAxel Dörflervoid BStringView::_ReservedStringView1() {}
571f9776157SAxel Dörflervoid BStringView::_ReservedStringView2() {}
572f9776157SAxel Dörflervoid BStringView::_ReservedStringView3() {}
573f9776157SAxel Dörfler
574f9776157SAxel Dörfler
5755ae0cde3SJohn Scipione// #pragma mark - Private methods
5765ae0cde3SJohn Scipione
5775ae0cde3SJohn Scipione
578f9776157SAxel DörflerBStringView&
579f9776157SAxel DörflerBStringView::operator=(const BStringView&)
58052a38012Sejakowatz{
581f9776157SAxel Dörfler	// Assignment not allowed (private)
58252a38012Sejakowatz	return *this;
58352a38012Sejakowatz}
584d3fe87ceSStephan Aßmus
58589208c77SStephan Aßmus
586d3fe87ceSStephan AßmusBSize
587d3fe87ceSStephan AßmusBStringView::_ValidatePreferredSize()
588d3fe87ceSStephan Aßmus{
58995fdee0bSAxel Dörfler	if (fPreferredSize.height < 0) {
590d3fe87ceSStephan Aßmus		// height
591d3fe87ceSStephan Aßmus		font_height fontHeight;
592d3fe87ceSStephan Aßmus		GetFontHeight(&fontHeight);
5937ae97406SPhilippe Houdoin
594a4ba4323SAdrien Destugues		int32 lines = 1;
595a4ba4323SAdrien Destugues		char* temp = fText ? strchr(fText, '\n') : NULL;
59635a074e0SKacper Kasper		while (temp != NULL) {
597800e6fe4SKacper Kasper			temp = strchr(temp + 1, '\n');
598800e6fe4SKacper Kasper			lines++;
59935a074e0SKacper Kasper		};
600800e6fe4SKacper Kasper
6017ae97406SPhilippe Houdoin		fPreferredSize.height = ceilf(fontHeight.ascent + fontHeight.descent
602800e6fe4SKacper Kasper			+ fontHeight.leading) * lines;
603c944d11fSStephan Aßmus
604c944d11fSStephan Aßmus		ResetLayoutInvalidation();
605d3fe87ceSStephan Aßmus	}
606d3fe87ceSStephan Aßmus
607d3fe87ceSStephan Aßmus	return fPreferredSize;
608d3fe87ceSStephan Aßmus}
609d3fe87ceSStephan Aßmus
610466f2b8fSRene Gollent
611800e6fe4SKacper Kasperfloat
612800e6fe4SKacper KasperBStringView::_StringWidth(const char* text)
613800e6fe4SKacper Kasper{
614800e6fe4SKacper Kasper	if(text == NULL)
615800e6fe4SKacper Kasper		return 0.0f;
616800e6fe4SKacper Kasper
617800e6fe4SKacper Kasper	float maxWidth = 0.0f;
618800e6fe4SKacper Kasper	BStringList lines;
619800e6fe4SKacper Kasper	BString(fText).Split("\n", false, lines);
620800e6fe4SKacper Kasper	for (int i = 0; i < lines.CountStrings(); i++) {
621800e6fe4SKacper Kasper		float width = StringWidth(lines.StringAt(i));
622800e6fe4SKacper Kasper		if (maxWidth < width)
623800e6fe4SKacper Kasper			maxWidth = width;
624800e6fe4SKacper Kasper	}
625800e6fe4SKacper Kasper	return maxWidth;
626800e6fe4SKacper Kasper}
627800e6fe4SKacper Kasper
628800e6fe4SKacper Kasper
629466f2b8fSRene Gollentextern "C" void
6308adaa6c5SJerome DuvalB_IF_GCC_2(InvalidateLayout__11BStringViewb,
6318adaa6c5SJerome Duval	_ZN11BStringView16InvalidateLayoutEb)(BView* view, bool descendants)
632466f2b8fSRene Gollent{
633f6c8d242SRene Gollent	perform_data_layout_invalidated data;
634f6c8d242SRene Gollent	data.descendants = descendants;
635f6c8d242SRene Gollent
636f6c8d242SRene Gollent	view->Perform(PERFORM_CODE_LAYOUT_INVALIDATED, &data);
637466f2b8fSRene Gollent}
638