Merge from layout management branch.

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@18649 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold
2006-08-26 16:21:15 +00:00
parent 01595708f3
commit 9ecf9d1c1d
277 changed files with 45889 additions and 747 deletions
+397 -18
View File
@@ -6,6 +6,7 @@
* Adrian Oanca <[email protected]>
* Axel Dörfler, [email protected]
* Stephan Aßmus <[email protected]>
* Ingo Weinhold <[email protected]>
*/
@@ -24,6 +25,9 @@
#include <Cursor.h>
#include <File.h>
#include <InterfaceDefs.h>
#include <Layout.h>
#include <LayoutContext.h>
#include <LayoutUtils.h>
#include <MenuBar.h>
#include <Message.h>
#include <MessageQueue.h>
@@ -310,6 +314,43 @@ ViewState::UpdateFrom(BPrivate::PortLink &link)
// #pragma mark -
struct BView::LayoutData {
LayoutData()
: fMinSize(),
fMaxSize(),
fPreferredSize(),
fAlignment(),
fLayoutInvalidationDisabled(0),
fLayout(NULL),
fLayoutContext(NULL),
fLayoutValid(true), // <- TODO: Rethink this!
fLayoutInProgress(false),
fNeedsRelayout(true)
{
}
BSize fMinSize;
BSize fMaxSize;
BSize fPreferredSize;
BAlignment fAlignment;
int fLayoutInvalidationDisabled;
BLayout* fLayout;
BLayoutContext* fLayoutContext;
bool fLayoutValid;
bool fLayoutInProgress;
bool fNeedsRelayout;
};
BView::BView(const char* name, uint32 flags, BLayout* layout)
{
_InitData(BRect(0, 0, 0, 0), name, B_FOLLOW_NONE,
flags | B_SUPPORTS_LAYOUT);
SetLayout(layout);
}
BView::BView(BRect frame, const char *name, uint32 resizingMode, uint32 flags)
: BHandler(name)
{
@@ -531,7 +572,7 @@ BView::~BView()
RemoveSelf();
// TODO: see about BShelf! must I delete it here? is it deleted by the window?
// we also delete all our children
BView *child = fFirstChild;
@@ -542,6 +583,10 @@ BView::~BView()
child = nextChild;
}
// delete the layout and the layout data
delete fLayoutData->fLayout;
delete fLayoutData;
if (fVerScroller)
fVerScroller->SetTarget((BView*)NULL);
if (fHorScroller)
@@ -837,6 +882,9 @@ BView::Hide()
fOwner->fLink->StartMessage(AS_LAYER_HIDE);
}
fShowLevel++;
if (fShowLevel == 1 && fParent)
fParent->InvalidateLayout();
}
@@ -848,6 +896,9 @@ BView::Show()
check_lock();
fOwner->fLink->StartMessage(AS_LAYER_SHOW);
}
if (fShowLevel == 0 && fParent)
fParent->InvalidateLayout();
}
@@ -3255,11 +3306,34 @@ BView::AddChild(BView *child, BView *before)
child && child->Name() ? child->Name(): "NULL",
before && before->Name() ? before->Name(): "NULL"));
if (!child)
if (!_AddChild(child, before))
return;
if (child->fParent != NULL)
if (fLayoutData->fLayout)
fLayoutData->fLayout->AddView(child);
}
bool
BView::AddChild(BLayoutItem* child)
{
if (!fLayoutData->fLayout)
return false;
return fLayoutData->fLayout->AddItem(child);
}
bool
BView::_AddChild(BView *child, BView *before)
{
if (!child)
return false;
if (child->fParent != NULL) {
printf("BView::_AddChild(): child %p already has parent %p\n", child , child->fParent);
debugger("AddChild failed - the view already has a parent.");
return false;
}
bool lockedOwner = false;
if (fOwner && !fOwner->IsLocked()) {
@@ -3267,8 +3341,12 @@ BView::AddChild(BView *child, BView *before)
lockedOwner = true;
}
if (!_AddChildToList(child, before))
debugger("AddChild failed!");
if (!_AddChildToList(child, before)) {
debugger("AddChild failed!");
if (lockedOwner)
fOwner->Unlock();
return false;
}
if (fOwner) {
check_lock();
@@ -3280,6 +3358,10 @@ BView::AddChild(BView *child, BView *before)
if (lockedOwner)
fOwner->Unlock();
}
InvalidateLayout();
return true;
}
@@ -3294,7 +3376,6 @@ BView::RemoveChild(BView *child)
return child->RemoveSelf();
}
int32
BView::CountChildren() const
{
@@ -3342,6 +3423,16 @@ BView::PreviousSibling() const
bool
BView::RemoveSelf()
{
if (fParent && fParent->fLayoutData->fLayout)
return fParent->fLayoutData->fLayout->RemoveView(this);
else
return _RemoveSelf();
}
bool
BView::_RemoveSelf()
{
STRACE(("BView(%s)::RemoveSelf()...\n", Name()));
@@ -3355,7 +3446,8 @@ BView::RemoveSelf()
_Detach();
}
if (!fParent || !fParent->_RemoveChildFromList(this))
BView* parent = fParent;
if (!parent || !parent->_RemoveChildFromList(this))
return false;
if (owner != NULL && !fTopLevelView) {
@@ -3364,6 +3456,8 @@ BView::RemoveSelf()
owner->fLink->Attach<int32>(_get_object_token_(this));
}
parent->InvalidateLayout();
STRACE(("DONE: BView(%s)::RemoveSelf()\n", Name()));
return true;
@@ -3725,6 +3819,285 @@ BView::Perform(perform_code d, void* arg)
}
// #pragma mark - Layout Functions
BSize
BView::MinSize()
{
// TODO: make sure this works correctly when some methods are overridden
float width, height;
GetPreferredSize(&width, &height);
return BLayoutUtils::ComposeSize(fLayoutData->fMinSize,
(fLayoutData->fLayout ? fLayoutData->fLayout->MinSize()
: BSize(width, height)));
}
BSize
BView::MaxSize()
{
return BLayoutUtils::ComposeSize(fLayoutData->fMaxSize,
(fLayoutData->fLayout ? fLayoutData->fLayout->MaxSize()
: BSize(B_SIZE_UNLIMITED, B_SIZE_UNLIMITED)));
}
BSize
BView::PreferredSize()
{
// TODO: make sure this works correctly when some methods are overridden
float width, height;
GetPreferredSize(&width, &height);
return BLayoutUtils::ComposeSize(fLayoutData->fPreferredSize,
(fLayoutData->fLayout ? fLayoutData->fLayout->PreferredSize()
: BSize(width, height)));
}
BAlignment
BView::Alignment()
{
return BLayoutUtils::ComposeAlignment(fLayoutData->fAlignment,
(fLayoutData->fLayout ? fLayoutData->fLayout->Alignment()
: BAlignment(B_ALIGN_HORIZONTAL_CENTER, B_ALIGN_VERTICAL_CENTER)));
}
void
BView::SetExplicitMinSize(BSize size)
{
fLayoutData->fMinSize = size;
InvalidateLayout();
}
void
BView::SetExplicitMaxSize(BSize size)
{
fLayoutData->fMaxSize = size;
InvalidateLayout();
}
void
BView::SetExplicitPreferredSize(BSize size)
{
fLayoutData->fPreferredSize = size;
InvalidateLayout();
}
void
BView::SetExplicitAlignment(BAlignment alignment)
{
fLayoutData->fAlignment = alignment;
InvalidateLayout();
}
BSize
BView::ExplicitMinSize() const
{
return fLayoutData->fMinSize;
}
BSize
BView::ExplicitMaxSize() const
{
return fLayoutData->fMaxSize;
}
BSize
BView::ExplicitPreferredSize() const
{
return fLayoutData->fPreferredSize;
}
BAlignment
BView::ExplicitAlignment() const
{
return fLayoutData->fAlignment;
}
bool
BView::HasHeightForWidth()
{
return (fLayoutData->fLayout
? fLayoutData->fLayout->HasHeightForWidth() : false);
}
void
BView::GetHeightForWidth(float width, float* min, float* max, float* preferred)
{
if (fLayoutData->fLayout)
fLayoutData->fLayout->GetHeightForWidth(width, min, max, preferred);
}
void
BView::SetLayout(BLayout* layout)
{
if (layout == fLayoutData->fLayout)
return;
fFlags |= B_SUPPORTS_LAYOUT;
// unset and delete the old layout
if (fLayoutData->fLayout) {
fLayoutData->fLayout->SetView(NULL);
delete fLayoutData->fLayout;
}
fLayoutData->fLayout = layout;
if (fLayoutData->fLayout) {
fLayoutData->fLayout->SetView(this);
// add all children
int count = CountChildren();
for (int i = 0; i < count; i++)
fLayoutData->fLayout->AddView(ChildAt(i));
}
InvalidateLayout();
}
BLayout*
BView::GetLayout() const
{
return fLayoutData->fLayout;
}
void
BView::InvalidateLayout(bool descendants)
{
if (fLayoutData->fLayoutValid && !fLayoutData->fLayoutInProgress
&& fLayoutData->fLayoutInvalidationDisabled == 0) {
if (fParent && fParent->fLayoutData->fLayoutValid)
fParent->InvalidateLayout(false);
fLayoutData->fLayoutValid = false;
if (fLayoutData->fLayout)
fLayoutData->fLayout->InvalidateLayout();
if (descendants) {
int count = CountChildren();
for (int i = 0; i < count; i++)
ChildAt(i)->InvalidateLayout(descendants);
}
if (fTopLevelView) {
// trigger layout process
if (fOwner)
fOwner->PostMessage(B_LAYOUT_WINDOW);
}
}
}
void
BView::EnableLayoutInvalidation()
{
if (fLayoutData->fLayoutInvalidationDisabled > 0)
fLayoutData->fLayoutInvalidationDisabled--;
}
void
BView::DisableLayoutInvalidation()
{
fLayoutData->fLayoutInvalidationDisabled++;
}
BLayoutContext*
BView::LayoutContext() const
{
return fLayoutData->fLayoutContext;
}
void
BView::Layout(bool force)
{
BLayoutContext context;
_Layout(force, &context);
}
void
BView::Relayout()
{
if (fLayoutData->fLayoutValid && !fLayoutData->fLayoutInProgress) {
fLayoutData->fNeedsRelayout = true;
// Layout() is recursive, that is if the parent view is currently laid
// out, we don't call layout() on this view, but wait for the parent's
// Layout() to do that for us.
if (!fParent || !fParent->fLayoutData->fLayoutInProgress)
Layout(false);
}
}
void
BView::DoLayout()
{
if (fLayoutData->fLayout)
fLayoutData->fLayout->LayoutView();
}
void
BView::_Layout(bool force, BLayoutContext* context)
{
//printf("%p->BView::_Layout(%d, %p)\n", this, force, context);
//printf(" fNeedsRelayout: %d, fLayoutValid: %d, fLayoutInProgress: %d\n",
//fLayoutData->fNeedsRelayout, fLayoutData->fLayoutValid, fLayoutData->fLayoutInProgress);
if (fLayoutData->fNeedsRelayout || !fLayoutData->fLayoutValid || force) {
fLayoutData->fLayoutValid = false;
if (fLayoutData->fLayoutInProgress)
return;
BLayoutContext* oldContext = fLayoutData->fLayoutContext;
fLayoutData->fLayoutContext = context;
fLayoutData->fLayoutInProgress = true;
DoLayout();
fLayoutData->fLayoutInProgress = false;
fLayoutData->fLayoutValid = true;
fLayoutData->fNeedsRelayout = false;
// layout children
int32 childCount = CountChildren();
for (int32 i = 0; i < childCount; i++) {
BView* child = ChildAt(i);
if (!child->IsHidden(child))
child->_Layout(force, context);
}
fLayoutData->fLayoutContext = oldContext;
// invalidate the drawn content, if requested
if (fFlags & B_INVALIDATE_AFTER_LAYOUT)
Invalidate();
}
}
// #pragma mark -
// Private Functions
@@ -3772,6 +4145,8 @@ BView::_InitData(BRect frame, const char *name, uint32 resizingMode, uint32 flag
fEventMask = 0;
fEventOptions = 0;
fLayoutData = new LayoutData;
}
@@ -4010,8 +4385,12 @@ BView::_ResizeBy(int32 deltaWidth, int32 deltaHeight)
}
// layout the children
for (BView* child = fFirstChild; child; child = child->fNextSibling)
child->_ParentResizedBy(deltaWidth, deltaHeight);
if (fFlags & B_SUPPORTS_LAYOUT) {
Relayout();
} else {
for (BView* child = fFirstChild; child; child = child->fNextSibling)
child->_ParentResizedBy(deltaWidth, deltaHeight);
}
if (fFlags & B_FRAME_EVENTS) {
BMessage resized(B_VIEW_RESIZED);
@@ -4383,15 +4762,15 @@ BView::do_owner_check_no_pick() const
}
}
void BView::_ReservedView2(){}
void BView::_ReservedView3(){}
void BView::_ReservedView4(){}
void BView::_ReservedView5(){}
void BView::_ReservedView6(){}
void BView::_ReservedView7(){}
void BView::_ReservedView8(){}
void BView::_ReservedView9(){}
extern "C" void _ReservedView1__5BView() {}
extern "C" void _ReservedView2__5BView() {}
extern "C" void _ReservedView3__5BView() {}
extern "C" void _ReservedView4__5BView() {}
extern "C" void _ReservedView5__5BView() {}
extern "C" void _ReservedView6__5BView() {}
extern "C" void _ReservedView7__5BView() {}
extern "C" void _ReservedView8__5BView() {}
extern "C" void _ReservedView9__5BView() {}
void BView::_ReservedView10(){}
void BView::_ReservedView11(){}
void BView::_ReservedView12(){}