19ecf9d1cSIngo Weinhold/*
24656e550SAxel Dörfler * Copyright 2010-2012, Haiku, Inc.
39ecf9d1cSIngo Weinhold * Copyright 2006, Ingo Weinhold <bonefish@cs.tu-berlin.de>.
49ecf9d1cSIngo Weinhold * All rights reserved. Distributed under the terms of the MIT License.
59ecf9d1cSIngo Weinhold */
69ecf9d1cSIngo Weinhold
74656e550SAxel Dörfler
89ecf9d1cSIngo Weinhold#include <LayoutItem.h>
99ecf9d1cSIngo Weinhold
109ecf9d1cSIngo Weinhold#include <Layout.h>
119ecf9d1cSIngo Weinhold#include <LayoutUtils.h>
121d6c7b6cSAlex Wilson#include <View.h>
13bd97b9adSAlex Wilson#include <ViewPrivate.h>
141d6c7b6cSAlex Wilson
151d6c7b6cSAlex Wilson#include <algorithm>
169ecf9d1cSIngo Weinhold
179ecf9d1cSIngo Weinhold
189ecf9d1cSIngo WeinholdBLayoutItem::BLayoutItem()
1927d84b48SAdrien Destugues	:
2027d84b48SAdrien Destugues	fLayout(NULL),
2127d84b48SAdrien Destugues	fLayoutData(NULL)
229ecf9d1cSIngo Weinhold{
239ecf9d1cSIngo Weinhold}
249ecf9d1cSIngo Weinhold
2527d84b48SAdrien Destugues
2627d84b48SAdrien DestuguesBLayoutItem::BLayoutItem(BMessage* from)
2727d84b48SAdrien Destugues	:
2827d84b48SAdrien Destugues	BArchivable(BUnarchiver::PrepareArchive(from)),
2927d84b48SAdrien Destugues	fLayout(NULL),
3027d84b48SAdrien Destugues	fLayoutData(NULL)
3127d84b48SAdrien Destugues{
3227d84b48SAdrien Destugues	BUnarchiver(from).Finish();
3327d84b48SAdrien Destugues}
3427d84b48SAdrien Destugues
3527d84b48SAdrien Destugues
369ecf9d1cSIngo WeinholdBLayoutItem::~BLayoutItem()
379ecf9d1cSIngo Weinhold{
38e837ee8bSMichael Lotz	if (fLayout != NULL) {
39e837ee8bSMichael Lotz		debugger("Deleting a BLayoutItem that is still attached to a layout. "
40e837ee8bSMichael Lotz			"Call RemoveSelf first.");
41e837ee8bSMichael Lotz	}
429ecf9d1cSIngo Weinhold}
439ecf9d1cSIngo Weinhold
4427d84b48SAdrien Destugues
459ecf9d1cSIngo WeinholdBLayout*
469ecf9d1cSIngo WeinholdBLayoutItem::Layout() const
479ecf9d1cSIngo Weinhold{
489ecf9d1cSIngo Weinhold	return fLayout;
499ecf9d1cSIngo Weinhold}
509ecf9d1cSIngo Weinhold
5127d84b48SAdrien Destugues
520cc8c71bSMichael Lotzbool
530cc8c71bSMichael LotzBLayoutItem::RemoveSelf()
540cc8c71bSMichael Lotz{
550cc8c71bSMichael Lotz	return Layout() != NULL && Layout()->RemoveItem(this);
560cc8c71bSMichael Lotz}
570cc8c71bSMichael Lotz
580cc8c71bSMichael Lotz
594656e550SAxel Dörflervoid
604656e550SAxel DörflerBLayoutItem::SetExplicitSize(BSize size)
614656e550SAxel Dörfler{
624656e550SAxel Dörfler	SetExplicitMinSize(size);
634656e550SAxel Dörfler	SetExplicitMaxSize(size);
644656e550SAxel Dörfler	SetExplicitPreferredSize(size);
654656e550SAxel Dörfler}
664656e550SAxel Dörfler
674656e550SAxel Dörfler
689ecf9d1cSIngo Weinholdbool
699ecf9d1cSIngo WeinholdBLayoutItem::HasHeightForWidth()
709ecf9d1cSIngo Weinhold{
719ecf9d1cSIngo Weinhold	// no "height for width" by default
729ecf9d1cSIngo Weinhold	return false;
739ecf9d1cSIngo Weinhold}
749ecf9d1cSIngo Weinhold
7527d84b48SAdrien Destugues
769ecf9d1cSIngo Weinholdvoid
779ecf9d1cSIngo WeinholdBLayoutItem::GetHeightForWidth(float width, float* min, float* max,
789ecf9d1cSIngo Weinhold	float* preferred)
799ecf9d1cSIngo Weinhold{
809ecf9d1cSIngo Weinhold	// no "height for width" by default
819ecf9d1cSIngo Weinhold}
829ecf9d1cSIngo Weinhold
8327d84b48SAdrien Destugues
849ecf9d1cSIngo WeinholdBView*
859ecf9d1cSIngo WeinholdBLayoutItem::View()
869ecf9d1cSIngo Weinhold{
879ecf9d1cSIngo Weinhold	return NULL;
889ecf9d1cSIngo Weinhold}
899ecf9d1cSIngo Weinhold
9027d84b48SAdrien Destugues
919ecf9d1cSIngo Weinholdvoid
921d6c7b6cSAlex WilsonBLayoutItem::InvalidateLayout(bool children)
939ecf9d1cSIngo Weinhold{
94c74faed4SAlex Wilson	LayoutInvalidated(children);
959ecf9d1cSIngo Weinhold	if (fLayout)
961d6c7b6cSAlex Wilson		fLayout->InvalidateLayout(children);
971d6c7b6cSAlex Wilson}
981d6c7b6cSAlex Wilson
991d6c7b6cSAlex Wilson
1001d6c7b6cSAlex Wilsonvoid
1011d6c7b6cSAlex WilsonBLayoutItem::Relayout(bool immediate)
1021d6c7b6cSAlex Wilson{
1031d6c7b6cSAlex Wilson	BView* view = View();
1041d6c7b6cSAlex Wilson	if (view && !immediate)
1051d6c7b6cSAlex Wilson		view->Relayout();
1061d6c7b6cSAlex Wilson	else if (view && immediate)
1071d6c7b6cSAlex Wilson		view->Layout(false);
1089ecf9d1cSIngo Weinhold}
1099ecf9d1cSIngo Weinhold
11027d84b48SAdrien Destugues
1119ecf9d1cSIngo Weinholdvoid*
1129ecf9d1cSIngo WeinholdBLayoutItem::LayoutData() const
1139ecf9d1cSIngo Weinhold{
1149ecf9d1cSIngo Weinhold	return fLayoutData;
1159ecf9d1cSIngo Weinhold}
1169ecf9d1cSIngo Weinhold
11727d84b48SAdrien Destugues
1189ecf9d1cSIngo Weinholdvoid
1199ecf9d1cSIngo WeinholdBLayoutItem::SetLayoutData(void* data)
1209ecf9d1cSIngo Weinhold{
1219ecf9d1cSIngo Weinhold	fLayoutData = data;
1229ecf9d1cSIngo Weinhold}
1239ecf9d1cSIngo Weinhold
12427d84b48SAdrien Destugues
1259ecf9d1cSIngo Weinholdvoid
1269ecf9d1cSIngo WeinholdBLayoutItem::AlignInFrame(BRect frame)
1279ecf9d1cSIngo Weinhold{
1289ecf9d1cSIngo Weinhold	BSize maxSize = MaxSize();
1299ecf9d1cSIngo Weinhold	BAlignment alignment = Alignment();
1309ecf9d1cSIngo Weinhold
1319ecf9d1cSIngo Weinhold	if (HasHeightForWidth()) {
1329ecf9d1cSIngo Weinhold		// The item has height for width, so we do the horizontal alignment
1339ecf9d1cSIngo Weinhold		// ourselves and restrict the height max constraint respectively.
1349ecf9d1cSIngo Weinhold		if (maxSize.width < frame.Width()
1359ecf9d1cSIngo Weinhold			&& alignment.horizontal != B_ALIGN_USE_FULL_WIDTH) {
1369ecf9d1cSIngo Weinhold			frame.left += (int)((frame.Width() - maxSize.width)
1379ecf9d1cSIngo Weinhold				* alignment.horizontal);
1389ecf9d1cSIngo Weinhold			frame.right = frame.left + maxSize.width;
1399ecf9d1cSIngo Weinhold		}
1409ecf9d1cSIngo Weinhold		alignment.horizontal = B_ALIGN_USE_FULL_WIDTH;
1419ecf9d1cSIngo Weinhold
1429ecf9d1cSIngo Weinhold		float minHeight;
1439ecf9d1cSIngo Weinhold		GetHeightForWidth(frame.Width(), &minHeight, NULL, NULL);
1444656e550SAxel Dörfler
1459ecf9d1cSIngo Weinhold		frame.bottom = frame.top + max_c(frame.Height(), minHeight);
1469ecf9d1cSIngo Weinhold		maxSize.height = minHeight;
1479ecf9d1cSIngo Weinhold	}
1489ecf9d1cSIngo Weinhold
1499ecf9d1cSIngo Weinhold	SetFrame(BLayoutUtils::AlignInFrame(frame, maxSize, alignment));
1509ecf9d1cSIngo Weinhold}
1519ecf9d1cSIngo Weinhold
15227d84b48SAdrien Destugues
15327d84b48SAdrien Destuguesstatus_t
15427d84b48SAdrien DestuguesBLayoutItem::Archive(BMessage* into, bool deep) const
15527d84b48SAdrien Destugues{
15627d84b48SAdrien Destugues	BArchiver archiver(into);
15727d84b48SAdrien Destugues	status_t err = BArchivable::Archive(into, deep);
15827d84b48SAdrien Destugues
15927d84b48SAdrien Destugues	if (err == B_OK)
16027d84b48SAdrien Destugues		err = archiver.Finish();
16127d84b48SAdrien Destugues
16227d84b48SAdrien Destugues	return err;
16327d84b48SAdrien Destugues}
16427d84b48SAdrien Destugues
16527d84b48SAdrien Destugues
16627d84b48SAdrien Destuguesstatus_t
16727d84b48SAdrien DestuguesBLayoutItem::AllArchived(BMessage* into) const
16827d84b48SAdrien Destugues{
16927d84b48SAdrien Destugues	BArchiver archiver(into);
17027d84b48SAdrien Destugues	return BArchivable::AllArchived(into);
17127d84b48SAdrien Destugues}
17227d84b48SAdrien Destugues
17327d84b48SAdrien Destugues
17427d84b48SAdrien Destuguesstatus_t
17527d84b48SAdrien DestuguesBLayoutItem::AllUnarchived(const BMessage* from)
17627d84b48SAdrien Destugues{
17727d84b48SAdrien Destugues	return BArchivable::AllUnarchived(from);
17827d84b48SAdrien Destugues}
17927d84b48SAdrien Destugues
18027d84b48SAdrien Destugues
1819ecf9d1cSIngo Weinholdvoid
1829ecf9d1cSIngo WeinholdBLayoutItem::SetLayout(BLayout* layout)
1839ecf9d1cSIngo Weinhold{
1841d6c7b6cSAlex Wilson	if (layout == fLayout)
1851d6c7b6cSAlex Wilson		return;
1861d6c7b6cSAlex Wilson
187cc1ca167SAlex Wilson	BLayout* oldLayout = fLayout;
188cc1ca167SAlex Wilson	fLayout = layout;
189cc1ca167SAlex Wilson
190cc1ca167SAlex Wilson	if (oldLayout)
191449f014bSAlex Wilson		DetachedFromLayout(oldLayout);
192bd97b9adSAlex Wilson
193bd97b9adSAlex Wilson	if (BView* view = View()) {
194cc1ca167SAlex Wilson		if (oldLayout && !fLayout) {
195bd97b9adSAlex Wilson			BView::Private(view).DeregisterLayoutItem(this);
196cc1ca167SAlex Wilson		} else if (fLayout && !oldLayout) {
197bd97b9adSAlex Wilson			BView::Private(view).RegisterLayoutItem(this);
198bd97b9adSAlex Wilson		}
199bd97b9adSAlex Wilson	}
2004656e550SAxel Dörfler
2011d6c7b6cSAlex Wilson	if (fLayout)
2021d6c7b6cSAlex Wilson		AttachedToLayout();
2031d6c7b6cSAlex Wilson}
2041d6c7b6cSAlex Wilson
2051d6c7b6cSAlex Wilson
206a851b3adSAlex Wilsonstatus_t
207a851b3adSAlex WilsonBLayoutItem::Perform(perform_code code, void* _data)
208a851b3adSAlex Wilson{
209a851b3adSAlex Wilson	return BArchivable::Perform(code, _data);
210a851b3adSAlex Wilson}
211a851b3adSAlex Wilson
212a851b3adSAlex Wilson
213c74faed4SAlex Wilsonvoid
214c74faed4SAlex WilsonBLayoutItem::LayoutInvalidated(bool children)
215c74faed4SAlex Wilson{
216c74faed4SAlex Wilson	// hook method
217c74faed4SAlex Wilson}
218c74faed4SAlex Wilson
219c74faed4SAlex Wilson
2201d6c7b6cSAlex Wilsonvoid
2211d6c7b6cSAlex WilsonBLayoutItem::AttachedToLayout()
2221d6c7b6cSAlex Wilson{
2231d6c7b6cSAlex Wilson	// hook method
2241d6c7b6cSAlex Wilson}
2251d6c7b6cSAlex Wilson
2261d6c7b6cSAlex Wilson
2271d6c7b6cSAlex Wilsonvoid
2281d6c7b6cSAlex WilsonBLayoutItem::DetachedFromLayout(BLayout* oldLayout)
2291d6c7b6cSAlex Wilson{
2301d6c7b6cSAlex Wilson	// hook method
2319ecf9d1cSIngo Weinhold}
2321d6c7b6cSAlex Wilson
2331d6c7b6cSAlex Wilson
2341d6c7b6cSAlex Wilsonvoid
2351d6c7b6cSAlex WilsonBLayoutItem::AncestorVisibilityChanged(bool shown)
2361d6c7b6cSAlex Wilson{
2371d6c7b6cSAlex Wilson	// hook method
2381d6c7b6cSAlex Wilson}
2391d6c7b6cSAlex Wilson
2408151838eSAlex Wilson
2418151838eSAlex Wilson// Binary compatibility stuff
2428151838eSAlex Wilson
2438151838eSAlex Wilson
2448151838eSAlex Wilsonvoid BLayoutItem::_ReservedLayoutItem1() {}
2458151838eSAlex Wilsonvoid BLayoutItem::_ReservedLayoutItem2() {}
2468151838eSAlex Wilsonvoid BLayoutItem::_ReservedLayoutItem3() {}
2478151838eSAlex Wilsonvoid BLayoutItem::_ReservedLayoutItem4() {}
2488151838eSAlex Wilsonvoid BLayoutItem::_ReservedLayoutItem5() {}
2498151838eSAlex Wilsonvoid BLayoutItem::_ReservedLayoutItem6() {}
2508151838eSAlex Wilsonvoid BLayoutItem::_ReservedLayoutItem7() {}
2518151838eSAlex Wilsonvoid BLayoutItem::_ReservedLayoutItem8() {}
2528151838eSAlex Wilsonvoid BLayoutItem::_ReservedLayoutItem9() {}
2538151838eSAlex Wilsonvoid BLayoutItem::_ReservedLayoutItem10() {}
2548151838eSAlex Wilson
255