- If there is no SATWindow because of lack of memory try to create a SATWindow when asking for it.
- Add untested code to save a SATGroup and to restore a SATGroup. - Splitting of a SATGroup is now triggered from the WindowArea destructor. This make it easier to restore S&T groups when windows in a group are missing. A group decays automatically in multiple groups when the missing window connected multiple windows. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@39461 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -9,13 +9,19 @@
|
||||
|
||||
#include "SATGroup.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <Debug.h>
|
||||
#include <Message.h>
|
||||
|
||||
#include "SATWindow.h"
|
||||
#include "StackAndTile.h"
|
||||
#include "Window.h"
|
||||
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
||||
WindowArea::WindowArea(Crossing* leftTop, Crossing* rightTop,
|
||||
Crossing* leftBottom, Crossing* rightBottom)
|
||||
:
|
||||
@@ -46,6 +52,9 @@ WindowArea::SetGroup(SATGroup* group)
|
||||
|
||||
WindowArea::~WindowArea()
|
||||
{
|
||||
if (fGroup)
|
||||
fGroup->WindowAreaRemoved(this);
|
||||
|
||||
_CleanupCorners();
|
||||
SetGroup(NULL);
|
||||
}
|
||||
@@ -706,8 +715,6 @@ SATGroup::RemoveWindow(SATWindow* window)
|
||||
if (!fSATWindowList.RemoveItem(window))
|
||||
return false;
|
||||
|
||||
_SplitGroupIfNecessary(window);
|
||||
|
||||
WindowArea* area = window->GetWindowArea();
|
||||
if (area)
|
||||
area->_RemoveWindow(window);
|
||||
@@ -784,6 +791,119 @@ SATGroup::AdjustWindows(SATWindow* triggerWindow)
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
SATGroup::WindowAreaRemoved(WindowArea* area)
|
||||
{
|
||||
_SplitGroupIfNecessary(area);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
SATGroup::RestoreGroup(const BMessage& archive, StackAndTile* sat)
|
||||
{
|
||||
// create new group
|
||||
SATGroup* group = new (std::nothrow)SATGroup;
|
||||
if (!group)
|
||||
return B_NO_MEMORY;
|
||||
BReference<SATGroup> groupRef;
|
||||
groupRef.SetTo(group, true);
|
||||
|
||||
int32 nHTabs, nVTabs;
|
||||
status_t status;
|
||||
status = archive.FindInt32("htab_count", &nHTabs);
|
||||
if (status != B_OK)
|
||||
return status;
|
||||
status = archive.FindInt32("vtab_count", &nVTabs);
|
||||
if (status != B_OK)
|
||||
return status;
|
||||
|
||||
vector<BReference<Tab> > tempHTabs;
|
||||
for (int i = 0; i < nHTabs; i++) {
|
||||
BReference<Tab> tab = group->_AddHorizontalTab();
|
||||
if (!tab)
|
||||
return B_NO_MEMORY;
|
||||
tempHTabs.push_back(tab);
|
||||
}
|
||||
vector<BReference<Tab> > tempVTabs;
|
||||
for (int i = 0; i < nVTabs; i++) {
|
||||
BReference<Tab> tab = group->_AddVerticalTab();
|
||||
if (!tab)
|
||||
return B_NO_MEMORY;
|
||||
tempVTabs.push_back(tab);
|
||||
}
|
||||
|
||||
BMessage areaArchive;
|
||||
for (int32 i = 0; archive.FindMessage("area", i, &areaArchive) == B_OK;
|
||||
i++) {
|
||||
uint32 leftTab, rightTab, topTab, bottomTab;
|
||||
if (areaArchive.FindInt32("left_tab", (int32*)&leftTab) != B_OK
|
||||
|| areaArchive.FindInt32("right_tab", (int32*)&rightTab) != B_OK
|
||||
|| areaArchive.FindInt32("top_tab", (int32*)&topTab) != B_OK
|
||||
|| areaArchive.FindInt32("bottom_tab", (int32*)&bottomTab) != B_OK)
|
||||
return B_ERROR;
|
||||
|
||||
if (leftTab >= tempVTabs.size() || rightTab >= tempVTabs.size())
|
||||
return B_BAD_VALUE;
|
||||
if (topTab >= tempHTabs.size() || bottomTab >= tempHTabs.size())
|
||||
return B_BAD_VALUE;
|
||||
|
||||
Tab* left = tempVTabs[leftTab];
|
||||
Tab* right = tempVTabs[rightTab];
|
||||
Tab* top = tempHTabs[topTab];
|
||||
Tab* bottom = tempHTabs[bottomTab];
|
||||
|
||||
// adding windows to area
|
||||
int64 windowId;
|
||||
WindowArea* area = NULL;
|
||||
for (int32 i = 0;
|
||||
areaArchive.FindInt64("window", i, &windowId) == B_OK; i++) {
|
||||
SATWindow* window = sat->FindSATWindow(windowId);
|
||||
if (!window)
|
||||
continue;
|
||||
|
||||
if (area == NULL) {
|
||||
if (!group->AddWindow(window, left, top, right, bottom))
|
||||
return B_ERROR;
|
||||
area = window->GetWindowArea();
|
||||
} else {
|
||||
if (!group->AddWindow(window, area))
|
||||
return B_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
SATGroup::ArchiveGroup(BMessage& archive)
|
||||
{
|
||||
archive.AddInt32("htab_count", fHorizontalTabs.CountItems());
|
||||
archive.AddInt32("vtab_count", fVerticalTabs.CountItems());
|
||||
|
||||
for (int i = 0; i < fWindowAreaList.CountItems(); i++) {
|
||||
WindowArea* area = fWindowAreaList.ItemAt(i);
|
||||
int32 leftTab = fVerticalTabs.IndexOf(area->LeftTab());
|
||||
int32 rightTab = fVerticalTabs.IndexOf(area->RightTab());
|
||||
int32 topTab = fHorizontalTabs.IndexOf(area->TopTab());
|
||||
int32 bottomTab = fHorizontalTabs.IndexOf(area->BottomTab());
|
||||
|
||||
BMessage areaMessage;
|
||||
areaMessage.AddInt32("left_tab", leftTab);
|
||||
areaMessage.AddInt32("right_tab", rightTab);
|
||||
areaMessage.AddInt32("top_tab", topTab);
|
||||
areaMessage.AddInt32("bottom_tab", bottomTab);
|
||||
|
||||
const SATWindowList& windowList = area->WindowList();
|
||||
for (int a = 0; a < windowList.CountItems(); a++)
|
||||
areaMessage.AddInt64("window", windowList.ItemAt(a)->Id());
|
||||
|
||||
archive.AddMessage("area", &areaMessage);
|
||||
}
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
BReference<Tab>
|
||||
SATGroup::_AddHorizontalTab(float position)
|
||||
{
|
||||
@@ -860,20 +980,19 @@ SATGroup::_FindTab(const TabList& list, float position)
|
||||
|
||||
|
||||
void
|
||||
SATGroup::_SplitGroupIfNecessary(SATWindow* removedWindow)
|
||||
SATGroup::_SplitGroupIfNecessary(WindowArea* removedArea)
|
||||
{
|
||||
// if there are windows stacked in the area we don't need to split
|
||||
WindowArea* area = removedWindow->GetWindowArea();
|
||||
if (!area || area->WindowList().CountItems() > 1)
|
||||
if (!removedArea || removedArea->WindowList().CountItems() > 1)
|
||||
return;
|
||||
|
||||
WindowAreaList neighbourWindows;
|
||||
|
||||
_FillNeighbourList(neighbourWindows, removedWindow->GetWindowArea());
|
||||
_FillNeighbourList(neighbourWindows, removedArea);
|
||||
|
||||
bool ownGroupProcessed = false;
|
||||
WindowAreaList newGroup;
|
||||
while (_FindConnectedGroup(neighbourWindows, removedWindow, newGroup)) {
|
||||
while (_FindConnectedGroup(neighbourWindows, removedArea, newGroup)) {
|
||||
STRACE_SAT("Connected group found; %i windows:\n",
|
||||
(int)newGroup.CountItems());
|
||||
for (int i = 0; i < newGroup.CountItems(); i++) {
|
||||
@@ -903,8 +1022,6 @@ void
|
||||
SATGroup::_FillNeighbourList(WindowAreaList& neighbourWindows,
|
||||
WindowArea* area)
|
||||
{
|
||||
if (!area)
|
||||
return;
|
||||
_LeftNeighbours(neighbourWindows, area);
|
||||
_RightNeighbours(neighbourWindows, area);
|
||||
_TopNeighbours(neighbourWindows, area);
|
||||
@@ -1018,19 +1135,16 @@ SATGroup::_BottomNeighbours(WindowAreaList& neighbourWindows,
|
||||
|
||||
|
||||
bool
|
||||
SATGroup::_FindConnectedGroup(WindowAreaList& seedList,
|
||||
SATWindow* removedWindow, WindowAreaList& newGroup)
|
||||
SATGroup::_FindConnectedGroup(WindowAreaList& seedList, WindowArea* removedArea,
|
||||
WindowAreaList& newGroup)
|
||||
{
|
||||
if (seedList.CountItems() == 0)
|
||||
return false;
|
||||
WindowArea* vetoArea = removedWindow->GetWindowArea();
|
||||
if (!vetoArea)
|
||||
return false;
|
||||
|
||||
WindowArea* area = seedList.RemoveItemAt(0);
|
||||
newGroup.AddItem(area);
|
||||
|
||||
_FollowSeed(area, vetoArea, seedList, newGroup);
|
||||
_FollowSeed(area, removedArea, seedList, newGroup);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -133,7 +133,7 @@ public:
|
||||
Crossing* rightBottom);
|
||||
~WindowArea();
|
||||
|
||||
bool SetGroup(SATGroup* group);
|
||||
bool SetGroup(SATGroup* group);
|
||||
|
||||
const SATWindowList& WindowList() { return fWindowList; }
|
||||
const SATWindowList& LayerOrder() { return fWindowLayerOrder; }
|
||||
@@ -200,6 +200,9 @@ private:
|
||||
typedef BObjectList<WindowArea> WindowAreaList;
|
||||
typedef BObjectList<Tab> TabList;
|
||||
|
||||
class BMessage;
|
||||
class StackAndTile;
|
||||
|
||||
|
||||
class SATGroup : public BReferenceable {
|
||||
public:
|
||||
@@ -233,6 +236,12 @@ public:
|
||||
Tab* FindHorizontalTab(float position);
|
||||
Tab* FindVerticalTab(float position);
|
||||
|
||||
void WindowAreaRemoved(WindowArea* area);
|
||||
|
||||
static status_t RestoreGroup(const BMessage& archive,
|
||||
StackAndTile* sat);
|
||||
status_t ArchiveGroup(BMessage& archive);
|
||||
|
||||
private:
|
||||
BReference<Tab> _AddHorizontalTab(float position = 0);
|
||||
BReference<Tab> _AddVerticalTab(float position = 0);
|
||||
@@ -243,7 +252,7 @@ private:
|
||||
Tab* _FindTab(const TabList& list, float position);
|
||||
|
||||
void _SplitGroupIfNecessary(
|
||||
SATWindow* removedWindow);
|
||||
WindowArea* removedArea);
|
||||
void _FillNeighbourList(
|
||||
WindowAreaList& neighbourWindows,
|
||||
WindowArea* area);
|
||||
@@ -260,7 +269,7 @@ private:
|
||||
WindowAreaList& neighbourWindows,
|
||||
WindowArea* window);
|
||||
bool _FindConnectedGroup(WindowAreaList& seedList,
|
||||
SATWindow* removedWindow,
|
||||
WindowArea* removedArea,
|
||||
WindowAreaList& newGroup);
|
||||
void _FollowSeed(WindowArea* area, WindowArea* veto,
|
||||
WindowAreaList& seedList,
|
||||
|
||||
@@ -289,6 +289,8 @@ SATWindow::SATWindow(StackAndTile* sat, Window* window)
|
||||
fSATTiling(this),
|
||||
fShutdown(false)
|
||||
{
|
||||
fId = _GenerateId();
|
||||
|
||||
fDesktop = fWindow->Desktop();
|
||||
|
||||
fGroupCookie = &fOwnGroupCookie;
|
||||
@@ -680,6 +682,29 @@ SATWindow::TabLocationMoved(float location, bool shifting)
|
||||
}
|
||||
|
||||
|
||||
uint64
|
||||
SATWindow::Id()
|
||||
{
|
||||
return fId;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
SATWindow::SetSettings(const BMessage& message)
|
||||
{
|
||||
if (message.FindInt64("window_id", (int64*)&fId) != B_OK)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
SATWindow::GetSettings(BMessage& message)
|
||||
{
|
||||
message.AddInt64("window_id", fId);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
SATWindow::_InitGroup()
|
||||
{
|
||||
@@ -744,3 +769,13 @@ SATWindow::_UpdateSizeLimits()
|
||||
fGroupCookie->SetSizeLimits(minWidth, B_SIZE_UNLIMITED, minHeight,
|
||||
B_SIZE_UNLIMITED);
|
||||
}
|
||||
|
||||
|
||||
uint64
|
||||
SATWindow::_GenerateId()
|
||||
{
|
||||
bigtime_t time = real_time_clock_usecs();
|
||||
srand(time);
|
||||
int16 randNumber = rand();
|
||||
return (time & ~0xFFFF) | randNumber;
|
||||
}
|
||||
|
||||
@@ -128,9 +128,14 @@ public:
|
||||
bool SetStackedTabMoving(bool moving = true);
|
||||
void TabLocationMoved(float location, bool shifting);
|
||||
|
||||
uint64 Id();
|
||||
|
||||
bool SetSettings(const BMessage& message);
|
||||
void GetSettings(BMessage& message);
|
||||
private:
|
||||
void _InitGroup();
|
||||
void _UpdateSizeLimits();
|
||||
uint64 _GenerateId();
|
||||
|
||||
Window* fWindow;
|
||||
StackAndTile* fStackAndTile;
|
||||
@@ -158,6 +163,8 @@ private:
|
||||
|
||||
float fOriginalWidth;
|
||||
float fOriginalHeight;
|
||||
|
||||
uint64 fId;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -334,8 +334,7 @@ StackAndTile::SetDecoratorSettings(Window* window, const BMessage& settings)
|
||||
if (!satWindow)
|
||||
return false;
|
||||
|
||||
//return satWindow->SetSettings(settings);
|
||||
return false;
|
||||
return satWindow->SetSettings(settings);
|
||||
}
|
||||
|
||||
|
||||
@@ -346,7 +345,7 @@ StackAndTile::GetDecoratorSettings(Window* window, BMessage& settings)
|
||||
if (!satWindow)
|
||||
return;
|
||||
|
||||
//satWindow->GetSettings(&settings);
|
||||
satWindow->GetSettings(settings);
|
||||
}
|
||||
|
||||
|
||||
@@ -358,16 +357,26 @@ StackAndTile::GetSATWindow(Window* window)
|
||||
if (it != fSATWindowMap.end())
|
||||
return it->second;
|
||||
|
||||
// for now don't create window on the fly
|
||||
return NULL;
|
||||
// If we don't know this window, memory allocation might has been failed
|
||||
// previously. Try to add window now
|
||||
/* SATWindow* satWindow = new (std::nothrow)SATWindow(
|
||||
window, this);
|
||||
// previously. Try to add the window now.
|
||||
SATWindow* satWindow = new (std::nothrow)SATWindow(this, window);
|
||||
if (satWindow)
|
||||
fSATWindowMap[window] = satWindow;
|
||||
|
||||
return satWindow;*/
|
||||
return satWindow;
|
||||
}
|
||||
|
||||
|
||||
SATWindow*
|
||||
StackAndTile::FindSATWindow(uint64 id)
|
||||
{
|
||||
for (SATWindowMap::const_iterator it = fSATWindowMap.begin();
|
||||
it != fSATWindowMap.end(); it++) {
|
||||
SATWindow* window = it->second;
|
||||
if (window->Id() == id)
|
||||
return window;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -89,6 +89,7 @@ public:
|
||||
{ return fSATKeyPressed; }
|
||||
|
||||
SATWindow* GetSATWindow(Window* window);
|
||||
SATWindow* FindSATWindow(uint64 id);
|
||||
|
||||
private:
|
||||
void _StartSAT();
|
||||
|
||||
Reference in New Issue
Block a user