- 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 "SATGroup.h"
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include <Debug.h>
|
#include <Debug.h>
|
||||||
|
#include <Message.h>
|
||||||
|
|
||||||
#include "SATWindow.h"
|
#include "SATWindow.h"
|
||||||
#include "StackAndTile.h"
|
#include "StackAndTile.h"
|
||||||
#include "Window.h"
|
#include "Window.h"
|
||||||
|
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
|
||||||
WindowArea::WindowArea(Crossing* leftTop, Crossing* rightTop,
|
WindowArea::WindowArea(Crossing* leftTop, Crossing* rightTop,
|
||||||
Crossing* leftBottom, Crossing* rightBottom)
|
Crossing* leftBottom, Crossing* rightBottom)
|
||||||
:
|
:
|
||||||
@@ -46,6 +52,9 @@ WindowArea::SetGroup(SATGroup* group)
|
|||||||
|
|
||||||
WindowArea::~WindowArea()
|
WindowArea::~WindowArea()
|
||||||
{
|
{
|
||||||
|
if (fGroup)
|
||||||
|
fGroup->WindowAreaRemoved(this);
|
||||||
|
|
||||||
_CleanupCorners();
|
_CleanupCorners();
|
||||||
SetGroup(NULL);
|
SetGroup(NULL);
|
||||||
}
|
}
|
||||||
@@ -706,8 +715,6 @@ SATGroup::RemoveWindow(SATWindow* window)
|
|||||||
if (!fSATWindowList.RemoveItem(window))
|
if (!fSATWindowList.RemoveItem(window))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
_SplitGroupIfNecessary(window);
|
|
||||||
|
|
||||||
WindowArea* area = window->GetWindowArea();
|
WindowArea* area = window->GetWindowArea();
|
||||||
if (area)
|
if (area)
|
||||||
area->_RemoveWindow(window);
|
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>
|
BReference<Tab>
|
||||||
SATGroup::_AddHorizontalTab(float position)
|
SATGroup::_AddHorizontalTab(float position)
|
||||||
{
|
{
|
||||||
@@ -860,20 +980,19 @@ SATGroup::_FindTab(const TabList& list, float position)
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
SATGroup::_SplitGroupIfNecessary(SATWindow* removedWindow)
|
SATGroup::_SplitGroupIfNecessary(WindowArea* removedArea)
|
||||||
{
|
{
|
||||||
// if there are windows stacked in the area we don't need to split
|
// if there are windows stacked in the area we don't need to split
|
||||||
WindowArea* area = removedWindow->GetWindowArea();
|
if (!removedArea || removedArea->WindowList().CountItems() > 1)
|
||||||
if (!area || area->WindowList().CountItems() > 1)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
WindowAreaList neighbourWindows;
|
WindowAreaList neighbourWindows;
|
||||||
|
|
||||||
_FillNeighbourList(neighbourWindows, removedWindow->GetWindowArea());
|
_FillNeighbourList(neighbourWindows, removedArea);
|
||||||
|
|
||||||
bool ownGroupProcessed = false;
|
bool ownGroupProcessed = false;
|
||||||
WindowAreaList newGroup;
|
WindowAreaList newGroup;
|
||||||
while (_FindConnectedGroup(neighbourWindows, removedWindow, newGroup)) {
|
while (_FindConnectedGroup(neighbourWindows, removedArea, newGroup)) {
|
||||||
STRACE_SAT("Connected group found; %i windows:\n",
|
STRACE_SAT("Connected group found; %i windows:\n",
|
||||||
(int)newGroup.CountItems());
|
(int)newGroup.CountItems());
|
||||||
for (int i = 0; i < newGroup.CountItems(); i++) {
|
for (int i = 0; i < newGroup.CountItems(); i++) {
|
||||||
@@ -903,8 +1022,6 @@ void
|
|||||||
SATGroup::_FillNeighbourList(WindowAreaList& neighbourWindows,
|
SATGroup::_FillNeighbourList(WindowAreaList& neighbourWindows,
|
||||||
WindowArea* area)
|
WindowArea* area)
|
||||||
{
|
{
|
||||||
if (!area)
|
|
||||||
return;
|
|
||||||
_LeftNeighbours(neighbourWindows, area);
|
_LeftNeighbours(neighbourWindows, area);
|
||||||
_RightNeighbours(neighbourWindows, area);
|
_RightNeighbours(neighbourWindows, area);
|
||||||
_TopNeighbours(neighbourWindows, area);
|
_TopNeighbours(neighbourWindows, area);
|
||||||
@@ -1018,19 +1135,16 @@ SATGroup::_BottomNeighbours(WindowAreaList& neighbourWindows,
|
|||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
SATGroup::_FindConnectedGroup(WindowAreaList& seedList,
|
SATGroup::_FindConnectedGroup(WindowAreaList& seedList, WindowArea* removedArea,
|
||||||
SATWindow* removedWindow, WindowAreaList& newGroup)
|
WindowAreaList& newGroup)
|
||||||
{
|
{
|
||||||
if (seedList.CountItems() == 0)
|
if (seedList.CountItems() == 0)
|
||||||
return false;
|
return false;
|
||||||
WindowArea* vetoArea = removedWindow->GetWindowArea();
|
|
||||||
if (!vetoArea)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
WindowArea* area = seedList.RemoveItemAt(0);
|
WindowArea* area = seedList.RemoveItemAt(0);
|
||||||
newGroup.AddItem(area);
|
newGroup.AddItem(area);
|
||||||
|
|
||||||
_FollowSeed(area, vetoArea, seedList, newGroup);
|
_FollowSeed(area, removedArea, seedList, newGroup);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -133,7 +133,7 @@ public:
|
|||||||
Crossing* rightBottom);
|
Crossing* rightBottom);
|
||||||
~WindowArea();
|
~WindowArea();
|
||||||
|
|
||||||
bool SetGroup(SATGroup* group);
|
bool SetGroup(SATGroup* group);
|
||||||
|
|
||||||
const SATWindowList& WindowList() { return fWindowList; }
|
const SATWindowList& WindowList() { return fWindowList; }
|
||||||
const SATWindowList& LayerOrder() { return fWindowLayerOrder; }
|
const SATWindowList& LayerOrder() { return fWindowLayerOrder; }
|
||||||
@@ -200,6 +200,9 @@ private:
|
|||||||
typedef BObjectList<WindowArea> WindowAreaList;
|
typedef BObjectList<WindowArea> WindowAreaList;
|
||||||
typedef BObjectList<Tab> TabList;
|
typedef BObjectList<Tab> TabList;
|
||||||
|
|
||||||
|
class BMessage;
|
||||||
|
class StackAndTile;
|
||||||
|
|
||||||
|
|
||||||
class SATGroup : public BReferenceable {
|
class SATGroup : public BReferenceable {
|
||||||
public:
|
public:
|
||||||
@@ -233,6 +236,12 @@ public:
|
|||||||
Tab* FindHorizontalTab(float position);
|
Tab* FindHorizontalTab(float position);
|
||||||
Tab* FindVerticalTab(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:
|
private:
|
||||||
BReference<Tab> _AddHorizontalTab(float position = 0);
|
BReference<Tab> _AddHorizontalTab(float position = 0);
|
||||||
BReference<Tab> _AddVerticalTab(float position = 0);
|
BReference<Tab> _AddVerticalTab(float position = 0);
|
||||||
@@ -243,7 +252,7 @@ private:
|
|||||||
Tab* _FindTab(const TabList& list, float position);
|
Tab* _FindTab(const TabList& list, float position);
|
||||||
|
|
||||||
void _SplitGroupIfNecessary(
|
void _SplitGroupIfNecessary(
|
||||||
SATWindow* removedWindow);
|
WindowArea* removedArea);
|
||||||
void _FillNeighbourList(
|
void _FillNeighbourList(
|
||||||
WindowAreaList& neighbourWindows,
|
WindowAreaList& neighbourWindows,
|
||||||
WindowArea* area);
|
WindowArea* area);
|
||||||
@@ -260,7 +269,7 @@ private:
|
|||||||
WindowAreaList& neighbourWindows,
|
WindowAreaList& neighbourWindows,
|
||||||
WindowArea* window);
|
WindowArea* window);
|
||||||
bool _FindConnectedGroup(WindowAreaList& seedList,
|
bool _FindConnectedGroup(WindowAreaList& seedList,
|
||||||
SATWindow* removedWindow,
|
WindowArea* removedArea,
|
||||||
WindowAreaList& newGroup);
|
WindowAreaList& newGroup);
|
||||||
void _FollowSeed(WindowArea* area, WindowArea* veto,
|
void _FollowSeed(WindowArea* area, WindowArea* veto,
|
||||||
WindowAreaList& seedList,
|
WindowAreaList& seedList,
|
||||||
|
|||||||
@@ -289,6 +289,8 @@ SATWindow::SATWindow(StackAndTile* sat, Window* window)
|
|||||||
fSATTiling(this),
|
fSATTiling(this),
|
||||||
fShutdown(false)
|
fShutdown(false)
|
||||||
{
|
{
|
||||||
|
fId = _GenerateId();
|
||||||
|
|
||||||
fDesktop = fWindow->Desktop();
|
fDesktop = fWindow->Desktop();
|
||||||
|
|
||||||
fGroupCookie = &fOwnGroupCookie;
|
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
|
void
|
||||||
SATWindow::_InitGroup()
|
SATWindow::_InitGroup()
|
||||||
{
|
{
|
||||||
@@ -744,3 +769,13 @@ SATWindow::_UpdateSizeLimits()
|
|||||||
fGroupCookie->SetSizeLimits(minWidth, B_SIZE_UNLIMITED, minHeight,
|
fGroupCookie->SetSizeLimits(minWidth, B_SIZE_UNLIMITED, minHeight,
|
||||||
B_SIZE_UNLIMITED);
|
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);
|
bool SetStackedTabMoving(bool moving = true);
|
||||||
void TabLocationMoved(float location, bool shifting);
|
void TabLocationMoved(float location, bool shifting);
|
||||||
|
|
||||||
|
uint64 Id();
|
||||||
|
|
||||||
|
bool SetSettings(const BMessage& message);
|
||||||
|
void GetSettings(BMessage& message);
|
||||||
private:
|
private:
|
||||||
void _InitGroup();
|
void _InitGroup();
|
||||||
void _UpdateSizeLimits();
|
void _UpdateSizeLimits();
|
||||||
|
uint64 _GenerateId();
|
||||||
|
|
||||||
Window* fWindow;
|
Window* fWindow;
|
||||||
StackAndTile* fStackAndTile;
|
StackAndTile* fStackAndTile;
|
||||||
@@ -158,6 +163,8 @@ private:
|
|||||||
|
|
||||||
float fOriginalWidth;
|
float fOriginalWidth;
|
||||||
float fOriginalHeight;
|
float fOriginalHeight;
|
||||||
|
|
||||||
|
uint64 fId;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -334,8 +334,7 @@ StackAndTile::SetDecoratorSettings(Window* window, const BMessage& settings)
|
|||||||
if (!satWindow)
|
if (!satWindow)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
//return satWindow->SetSettings(settings);
|
return satWindow->SetSettings(settings);
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -346,7 +345,7 @@ StackAndTile::GetDecoratorSettings(Window* window, BMessage& settings)
|
|||||||
if (!satWindow)
|
if (!satWindow)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
//satWindow->GetSettings(&settings);
|
satWindow->GetSettings(settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -358,16 +357,26 @@ StackAndTile::GetSATWindow(Window* window)
|
|||||||
if (it != fSATWindowMap.end())
|
if (it != fSATWindowMap.end())
|
||||||
return it->second;
|
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
|
// If we don't know this window, memory allocation might has been failed
|
||||||
// previously. Try to add window now
|
// previously. Try to add the window now.
|
||||||
/* SATWindow* satWindow = new (std::nothrow)SATWindow(
|
SATWindow* satWindow = new (std::nothrow)SATWindow(this, window);
|
||||||
window, this);
|
|
||||||
if (satWindow)
|
if (satWindow)
|
||||||
fSATWindowMap[window] = 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; }
|
{ return fSATKeyPressed; }
|
||||||
|
|
||||||
SATWindow* GetSATWindow(Window* window);
|
SATWindow* GetSATWindow(Window* window);
|
||||||
|
SATWindow* FindSATWindow(uint64 id);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void _StartSAT();
|
void _StartSAT();
|
||||||
|
|||||||
Reference in New Issue
Block a user