Let BALM::{X|Y}Tabs be in multiple BALMLayouts, if they are friendly.
This commit is contained in:
@@ -151,6 +151,17 @@ private:
|
||||
BALMLayout(const BALMLayout&);
|
||||
void operator =(const BALMLayout&);
|
||||
|
||||
struct XTabRemover;
|
||||
struct XTabRemoverFunc;
|
||||
|
||||
struct YTabRemover;
|
||||
struct YTabRemoverFunc;
|
||||
|
||||
friend struct XTabRemover;
|
||||
friend struct XTabRemoverFunc;
|
||||
|
||||
friend struct YTabRemover;
|
||||
friend struct YTabRemoverFunc;
|
||||
|
||||
friend class XTab;
|
||||
friend class YTab;
|
||||
@@ -159,6 +170,9 @@ private:
|
||||
float InsetForTab(XTab* tab) const;
|
||||
float InsetForTab(YTab* tab) const;
|
||||
|
||||
void _RemoveSelfFromTab(XTab* tab);
|
||||
void _RemoveSelfFromTab(YTab* tab);
|
||||
|
||||
BLayoutItem* _LayoutItemToAdd(BView* view);
|
||||
|
||||
void _UpdateAreaConstraints();
|
||||
|
||||
+14
-2
@@ -29,7 +29,14 @@ protected:
|
||||
XTab(BALMLayout* layout);
|
||||
|
||||
private:
|
||||
BALMLayout* fALMLayout;
|
||||
struct BALMLayoutList;
|
||||
|
||||
bool IsInLayout(BALMLayout* layout);
|
||||
bool AddedToLayout(BALMLayout* layout);
|
||||
void LayoutLeaving(BALMLayout* layout);
|
||||
bool IsSuitableFor(BALMLayout* layout);
|
||||
|
||||
BALMLayoutList* fLayouts;
|
||||
|
||||
uint32 _reserved[2];
|
||||
};
|
||||
@@ -44,7 +51,12 @@ protected:
|
||||
YTab(BALMLayout* layout);
|
||||
|
||||
private:
|
||||
BALMLayout* fALMLayout;
|
||||
bool IsInLayout(BALMLayout* layout);
|
||||
bool AddedToLayout(BALMLayout* layout);
|
||||
void LayoutLeaving(BALMLayout* layout);
|
||||
bool IsSuitableFor(BALMLayout* layout);
|
||||
|
||||
XTab::BALMLayoutList* fLayouts;
|
||||
|
||||
uint32 _reserved[2];
|
||||
};
|
||||
|
||||
+117
-3
@@ -11,18 +11,70 @@
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <AutoDeleter.h>
|
||||
#include <ControlLook.h>
|
||||
|
||||
#include "RowColumnManager.h"
|
||||
#include "ViewLayoutItem.h"
|
||||
|
||||
|
||||
using BPrivate::AutoDeleter;
|
||||
using namespace LinearProgramming;
|
||||
|
||||
|
||||
const BSize kUnsetSize(B_SIZE_UNSET, B_SIZE_UNSET);
|
||||
|
||||
|
||||
struct BALMLayout::XTabRemoverFunc {
|
||||
void operator()(XTab* tab)
|
||||
{
|
||||
if (tab)
|
||||
layout->_RemoveSelfFromTab(tab);
|
||||
}
|
||||
|
||||
BALMLayout* layout;
|
||||
};
|
||||
|
||||
|
||||
struct BALMLayout::XTabRemover
|
||||
: public AutoDeleter<XTab, BALMLayout::XTabRemoverFunc> {
|
||||
|
||||
typedef AutoDeleter<XTab, BALMLayout::XTabRemoverFunc> Base;
|
||||
|
||||
XTabRemover(BALMLayout* layout, XTab* tab = NULL)
|
||||
:
|
||||
Base(tab)
|
||||
{
|
||||
fDelete.layout = layout;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct BALMLayout::YTabRemoverFunc {
|
||||
void operator()(YTab* tab)
|
||||
{
|
||||
if (tab)
|
||||
layout->_RemoveSelfFromTab(tab);
|
||||
}
|
||||
|
||||
BALMLayout* layout;
|
||||
};
|
||||
|
||||
|
||||
struct BALMLayout::YTabRemover
|
||||
: public AutoDeleter<YTab, BALMLayout::YTabRemoverFunc> {
|
||||
|
||||
typedef AutoDeleter<YTab, BALMLayout::YTabRemoverFunc> Base;
|
||||
|
||||
YTabRemover(BALMLayout* layout, YTab* tab = NULL)
|
||||
:
|
||||
Base(tab)
|
||||
{
|
||||
fDelete.layout = layout;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
BALM::BALMLayout::BadLayoutPolicy::~BadLayoutPolicy()
|
||||
{
|
||||
}
|
||||
@@ -105,6 +157,10 @@ BALMLayout::AddXTab()
|
||||
return NULL;
|
||||
|
||||
fXTabList.AddItem(tab);
|
||||
if (!tab->AddedToLayout(this)) {
|
||||
fXTabList.RemoveItem(tab);
|
||||
return NULL;
|
||||
}
|
||||
return tab;
|
||||
}
|
||||
|
||||
@@ -140,6 +196,10 @@ BALMLayout::AddYTab()
|
||||
return NULL;
|
||||
|
||||
fYTabList.AddItem(tab);
|
||||
if (!tab->AddedToLayout(this)) {
|
||||
fYTabList.RemoveItem(tab);
|
||||
return NULL;
|
||||
}
|
||||
return tab;
|
||||
}
|
||||
|
||||
@@ -480,6 +540,11 @@ Area*
|
||||
BALMLayout::AddItem(BLayoutItem* item, XTab* left, YTab* top, XTab* _right,
|
||||
YTab* _bottom)
|
||||
{
|
||||
if (!left->IsSuitableFor(this) || !top->IsSuitableFor(this)
|
||||
|| (_right && !_right->IsSuitableFor(this))
|
||||
|| (_bottom && !_bottom->IsSuitableFor(this)))
|
||||
debugger("Tab added to unfriendly layout!");
|
||||
|
||||
BReference<XTab> right = _right;
|
||||
if (right.Get() == NULL)
|
||||
right = AddXTab();
|
||||
@@ -487,16 +552,51 @@ BALMLayout::AddItem(BLayoutItem* item, XTab* left, YTab* top, XTab* _right,
|
||||
if (bottom.Get() == NULL)
|
||||
bottom = AddYTab();
|
||||
|
||||
// Area is added int ItemAdded
|
||||
// TODO: make sure all tabs get into the lists
|
||||
XTabRemover leftRemover(this);
|
||||
if (!left->IsInLayout(this)) {
|
||||
if (!left->AddedToLayout(this))
|
||||
return NULL;
|
||||
leftRemover.SetTo(left);
|
||||
}
|
||||
|
||||
YTabRemover topRemover(this);
|
||||
if (!top->IsInLayout(this)) {
|
||||
if (!top->AddedToLayout(this))
|
||||
return NULL;
|
||||
topRemover.SetTo(top);
|
||||
}
|
||||
|
||||
XTabRemover rightRemover(this);
|
||||
if (_right != NULL && !right->IsInLayout(this)) {
|
||||
if (!right->AddedToLayout(this))
|
||||
return NULL;
|
||||
rightRemover.SetTo(right);
|
||||
}
|
||||
|
||||
YTabRemover bottomRemover(this);
|
||||
if (_bottom != NULL && !bottom->IsInLayout(this)) {
|
||||
if (!bottom->AddedToLayout(this))
|
||||
return NULL;
|
||||
bottomRemover.SetTo(bottom);
|
||||
}
|
||||
|
||||
// Area is added in ItemAdded
|
||||
if (!BAbstractLayout::AddItem(-1, item))
|
||||
return NULL;
|
||||
Area* area = AreaFor(item);
|
||||
if (!area)
|
||||
if (!area) {
|
||||
RemoveItem(item);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
area->_Init(fSolver, left, top, right, bottom, fRowColumnManager);
|
||||
|
||||
fRowColumnManager->AddArea(area);
|
||||
|
||||
leftRemover.Detach();
|
||||
rightRemover.Detach();
|
||||
topRemover.Detach();
|
||||
bottomRemover.Detach();
|
||||
return area;
|
||||
}
|
||||
|
||||
@@ -907,6 +1007,20 @@ BALMLayout::InsetForTab(YTab* tab) const
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BALMLayout::_RemoveSelfFromTab(XTab* tab)
|
||||
{
|
||||
tab->LayoutLeaving(this);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BALMLayout::_RemoveSelfFromTab(YTab* tab)
|
||||
{
|
||||
tab->LayoutLeaving(this);
|
||||
}
|
||||
|
||||
|
||||
BLayoutItem*
|
||||
BALMLayout::_LayoutItemToAdd(BView* view)
|
||||
{
|
||||
|
||||
+119
-4
@@ -10,29 +10,144 @@
|
||||
#include <ALMLayout.h>
|
||||
|
||||
|
||||
using std::nothrow;
|
||||
|
||||
|
||||
struct XTab::BALMLayoutList {
|
||||
BALMLayoutList(BALMLayout* _layout, BALMLayoutList* _next = NULL)
|
||||
:
|
||||
next(_next),
|
||||
layout(_layout)
|
||||
{
|
||||
}
|
||||
|
||||
~BALMLayoutList()
|
||||
{
|
||||
delete next;
|
||||
}
|
||||
|
||||
bool HasLayout(BALMLayout* search)
|
||||
{
|
||||
if (layout == search)
|
||||
return true;
|
||||
return next ? next->HasLayout(search) : false;
|
||||
}
|
||||
|
||||
BALMLayoutList* Remove(BALMLayout* remove)
|
||||
{
|
||||
if (layout == remove) {
|
||||
BALMLayoutList* _next = next;
|
||||
delete this;
|
||||
return _next;
|
||||
}
|
||||
if (next)
|
||||
next = next->Remove(remove);
|
||||
return this;
|
||||
}
|
||||
|
||||
BALMLayoutList* next;
|
||||
BALMLayout* layout;
|
||||
};
|
||||
|
||||
|
||||
XTab::XTab(BALMLayout* layout)
|
||||
:
|
||||
Variable(layout->Solver()),
|
||||
fALMLayout(layout)
|
||||
fLayouts(new BALMLayoutList(layout))
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
XTab::~XTab()
|
||||
{
|
||||
fALMLayout->fXTabList.RemoveItem(this);
|
||||
BALMLayoutList* layouts = fLayouts;
|
||||
while (layouts) {
|
||||
layouts->layout->fXTabList.RemoveItem(this);
|
||||
layouts = layouts->next;
|
||||
}
|
||||
delete fLayouts;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
XTab::IsInLayout(BALMLayout* layout)
|
||||
{
|
||||
return fLayouts->HasLayout(layout);
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
XTab::AddedToLayout(BALMLayout* layout)
|
||||
{
|
||||
BALMLayoutList* newHead = new (nothrow) BALMLayoutList(layout, fLayouts);
|
||||
if (newHead == NULL)
|
||||
return false;
|
||||
fLayouts = newHead;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
XTab::LayoutLeaving(BALMLayout* layout)
|
||||
{
|
||||
fLayouts = fLayouts->Remove(layout);
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
XTab::IsSuitableFor(BALMLayout* layout)
|
||||
{
|
||||
return (fLayouts->layout->Solver() == layout->Solver());
|
||||
}
|
||||
|
||||
|
||||
YTab::YTab(BALMLayout* layout)
|
||||
:
|
||||
Variable(layout->Solver()),
|
||||
fALMLayout(layout)
|
||||
fLayouts(new XTab::BALMLayoutList(layout))
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
YTab::~YTab()
|
||||
{
|
||||
fALMLayout->fYTabList.RemoveItem(this);
|
||||
XTab::BALMLayoutList* layouts = fLayouts;
|
||||
while (layouts) {
|
||||
layouts->layout->fYTabList.RemoveItem(this);
|
||||
layouts = layouts->next;
|
||||
}
|
||||
delete fLayouts;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
YTab::IsInLayout(BALMLayout* layout)
|
||||
{
|
||||
return fLayouts->HasLayout(layout);
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
YTab::AddedToLayout(BALMLayout* layout)
|
||||
{
|
||||
XTab::BALMLayoutList* newHead
|
||||
= new (nothrow) XTab::BALMLayoutList(layout, fLayouts);
|
||||
if (newHead == NULL)
|
||||
return false;
|
||||
fLayouts = newHead;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
YTab::LayoutLeaving(BALMLayout* layout)
|
||||
{
|
||||
fLayouts = fLayouts->Remove(layout);
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
YTab::IsSuitableFor(BALMLayout* layout)
|
||||
{
|
||||
return (fLayouts->layout->Solver() == layout->Solver());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user