2004-01-17 21:37:57 +03:00
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
// Copyright (c) 2001-2002, OpenBeOS
|
|
|
|
//
|
|
|
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
|
|
|
// copy of this software and associated documentation files (the "Software"),
|
|
|
|
// to deal in the Software without restriction, including without limitation
|
|
|
|
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
|
|
// and/or sell copies of the Software, and to permit persons to whom the
|
|
|
|
// Software is furnished to do so, subject to the following conditions:
|
|
|
|
//
|
|
|
|
// The above copyright notice and this permission notice shall be included in
|
|
|
|
// all copies or substantial portions of the Software.
|
|
|
|
//
|
|
|
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
|
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
|
|
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
|
|
// DEALINGS IN THE SOFTWARE.
|
|
|
|
//
|
|
|
|
// File Name: Workspace.cpp
|
|
|
|
// Author: Adi Oanca <adioanca@myrealbox.com>
|
|
|
|
// Description: Tracks workspaces
|
|
|
|
//
|
|
|
|
//------------------------------------------------------------------------------
|
2004-01-12 01:12:55 +03:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <Window.h>
|
|
|
|
|
|
|
|
#include "Workspace.h"
|
|
|
|
#include "Layer.h"
|
|
|
|
#include "WinBorder.h"
|
|
|
|
#include "ServerWindow.h"
|
2004-01-13 04:03:29 +03:00
|
|
|
#include "ServerApp.h"
|
2004-01-12 01:12:55 +03:00
|
|
|
#include "RGBColor.h"
|
|
|
|
#include "Globals.h"
|
|
|
|
#include "FMWList.h"
|
|
|
|
#include "RootLayer.h"
|
|
|
|
#include "Desktop.h"
|
|
|
|
|
2004-01-21 05:58:39 +03:00
|
|
|
//#define DEBUG_WORKSPACE
|
2004-01-12 01:12:55 +03:00
|
|
|
|
|
|
|
#ifdef DEBUG_WORKSPACE
|
|
|
|
# include <stdio.h>
|
|
|
|
# define STRACE(x) printf x
|
|
|
|
#else
|
|
|
|
# define STRACE(x) ;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef DEBUG_WORKSPACE
|
|
|
|
# include <stdio.h>
|
|
|
|
# define STRACESTREAM() PrintToStream()
|
|
|
|
#else
|
|
|
|
# define STRACESTREAM() ;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
2004-01-13 04:03:29 +03:00
|
|
|
Workspace::Workspace(const uint32 colorspace, int32 ID, const RGBColor& BGColor, RootLayer* owner){
|
2004-01-12 01:12:55 +03:00
|
|
|
fID = ID;
|
|
|
|
fSpace = colorspace;
|
|
|
|
fBGColor = BGColor;
|
2004-01-13 04:03:29 +03:00
|
|
|
|
|
|
|
fOwner = owner;
|
2004-01-12 01:12:55 +03:00
|
|
|
|
|
|
|
fBottomItem = NULL;
|
|
|
|
fTopItem = NULL;
|
|
|
|
fCurrentItem= NULL;
|
|
|
|
fFocusItem = NULL;
|
|
|
|
fFrontItem = NULL;
|
|
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
Workspace::~Workspace(){
|
|
|
|
//printf("~Workspace( %ld )\n", fID);
|
|
|
|
ListData *toast;
|
|
|
|
while(fBottomItem){
|
|
|
|
toast = fBottomItem;
|
|
|
|
fBottomItem = fBottomItem->upperItem;
|
|
|
|
|
|
|
|
delete toast;
|
|
|
|
}
|
|
|
|
fBottomItem = NULL;
|
|
|
|
fTopItem = NULL;
|
|
|
|
fCurrentItem = NULL;
|
|
|
|
fFocusItem = NULL;
|
|
|
|
fFrontItem = NULL;
|
|
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
/* Adds layer ptr to workspace's list of WinBorders. After the item is added
|
|
|
|
* a *smart* search is performed to set the new front WinBorder. Of course,
|
|
|
|
* the first candidate is 'layer', but if it is hidden or it has the
|
|
|
|
* B_AVOID_FRONT flag, surely it won't get that status.
|
2004-01-13 04:03:29 +03:00
|
|
|
* This method also calls SearchAndSetNewFocus witch searches for a WinBorder,
|
2004-01-12 01:12:55 +03:00
|
|
|
* to give focus to, having as preferred 'layer'.
|
|
|
|
* Remember, some windows having B_AVOID_FOCUS can't have the focus state.
|
|
|
|
*/
|
|
|
|
bool Workspace::AddLayerPtr(WinBorder* layer){
|
|
|
|
// allocate a new item
|
|
|
|
ListData *item;
|
|
|
|
item = new ListData;
|
|
|
|
|
|
|
|
item->layerPtr = layer;
|
|
|
|
item->upperItem = NULL;
|
|
|
|
item->lowerItem = NULL;
|
|
|
|
|
2004-01-14 03:26:15 +03:00
|
|
|
opLock.Lock();
|
2004-01-12 01:12:55 +03:00
|
|
|
// insert 'item' at the end. It doesn't matter where we add it,
|
|
|
|
// it will be placed correctly by SearchAndSetNewFront(item->layerPtr);
|
|
|
|
InsertItem(item, NULL);
|
2004-01-14 03:26:15 +03:00
|
|
|
opLock.Unlock();
|
2004-01-13 04:03:29 +03:00
|
|
|
|
2004-01-12 01:12:55 +03:00
|
|
|
STRACE(("\n*AddLayerPtr(%s) -", layer->GetName()));
|
2004-01-14 18:55:10 +03:00
|
|
|
|
|
|
|
// this may happen in case of subset windows.
|
|
|
|
if(!(layer->IsHidden())){
|
|
|
|
// do a *smart* search and set the new 'front'
|
|
|
|
SearchAndSetNewFront(layer);
|
|
|
|
// do a *smart* search and set the new 'focus' + a redraw
|
|
|
|
SetFocusLayer(layer);
|
|
|
|
}
|
2004-01-14 03:26:15 +03:00
|
|
|
|
2004-01-12 01:12:55 +03:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
/* Removes a WinBorder from workspace's list. It DOES NOT delete it!
|
|
|
|
* If this window was the front/focus one it calls SearchAndSetNew(Front/Focus)
|
|
|
|
* to give the respective state to the window below her.
|
|
|
|
*/
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
bool Workspace::RemoveLayerPtr(WinBorder* layer){
|
|
|
|
if (!layer)
|
|
|
|
return false;
|
2004-01-17 19:33:22 +03:00
|
|
|
STRACE(("\n*Workspace(%ld)::RemoveLayerPtr(%s)\n", ID(), layer->GetName()));
|
2004-01-13 04:03:29 +03:00
|
|
|
STRACE(("BEFORE ANY opperation:\n"));
|
|
|
|
STRACESTREAM();
|
2004-01-12 01:12:55 +03:00
|
|
|
// search to see if this workspace has WinBorder's pointer in its list
|
|
|
|
ListData *item = NULL;
|
2004-01-14 03:26:15 +03:00
|
|
|
|
|
|
|
opLock.Lock();
|
2004-01-12 01:12:55 +03:00
|
|
|
if ((item = HasItem(layer))){
|
2004-01-17 19:33:22 +03:00
|
|
|
ListData *nextItem = NULL;
|
|
|
|
bool wasFront = false;
|
|
|
|
bool wasFocus = false;
|
|
|
|
|
|
|
|
wasFront = FrontLayer() == layer;
|
|
|
|
wasFocus = FocusLayer() == layer;
|
2004-01-12 01:12:55 +03:00
|
|
|
|
|
|
|
// prepare to set new front/focus if this layer was front/focus
|
|
|
|
nextItem = item->upperItem;
|
|
|
|
|
2004-01-17 19:33:22 +03:00
|
|
|
if (wasFront)
|
|
|
|
SearchAndSetNewFront(nextItem? nextItem->layerPtr: NULL);
|
2004-01-12 01:12:55 +03:00
|
|
|
|
2004-01-17 19:33:22 +03:00
|
|
|
// remove some windows.
|
|
|
|
if (item && item->layerPtr->_level == B_NORMAL_FEEL)
|
|
|
|
{
|
|
|
|
ListData *listItem = item->lowerItem;
|
|
|
|
while(listItem && (listItem->layerPtr->_level == B_FLOATING_SUBSET_FEEL
|
|
|
|
|| listItem->layerPtr->_level == B_FLOATING_APP_FEEL
|
|
|
|
|| listItem->layerPtr->_level == B_MODAL_SUBSET_FEEL))
|
|
|
|
{
|
|
|
|
// *carefuly* remove the item from the list
|
|
|
|
ListData *itemX = listItem;
|
|
|
|
listItem = listItem->lowerItem;
|
|
|
|
RemoveItem(itemX);
|
|
|
|
delete itemX;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
RemoveItem(item);
|
|
|
|
delete item;
|
2004-01-21 05:58:39 +03:00
|
|
|
STRACESTREAM();
|
2004-01-14 03:26:15 +03:00
|
|
|
opLock.Unlock();
|
|
|
|
|
2004-01-12 01:12:55 +03:00
|
|
|
// reset some internal variables
|
|
|
|
layer->SetMainWinBorder(NULL);
|
|
|
|
// its RootLayer is set to NULL by Layer::RemoveChild(layer);
|
2004-01-17 19:33:22 +03:00
|
|
|
|
2004-01-21 05:58:39 +03:00
|
|
|
STRACE(("Layer %s found and removed from Workspace No %ld\n", layer->GetName(), ID()));
|
2004-01-13 04:03:29 +03:00
|
|
|
|
2004-01-17 19:33:22 +03:00
|
|
|
if (wasFocus)
|
2004-01-14 03:26:15 +03:00
|
|
|
SetFocusLayer(nextItem? nextItem->layerPtr: NULL);
|
2004-01-17 19:33:22 +03:00
|
|
|
else
|
|
|
|
Invalidate();
|
2004-01-14 03:26:15 +03:00
|
|
|
|
2004-01-12 01:12:55 +03:00
|
|
|
return true;
|
|
|
|
}
|
2004-01-13 04:03:29 +03:00
|
|
|
else{
|
2004-01-21 05:58:39 +03:00
|
|
|
STRACE(("Layer %s NOT found in Workspace No %ld\n", layer->GetName(), ID()));
|
2004-01-14 03:26:15 +03:00
|
|
|
opLock.Unlock();
|
2004-01-12 01:12:55 +03:00
|
|
|
return false;
|
2004-01-13 04:03:29 +03:00
|
|
|
}
|
2004-01-12 01:12:55 +03:00
|
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
2004-01-17 19:33:22 +03:00
|
|
|
bool Workspace::HideSubsetWindows(WinBorder* layer){
|
|
|
|
if (!layer)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
// search to see if this workspace has WinBorder's pointer in its list
|
|
|
|
ListData *item = NULL;
|
|
|
|
|
|
|
|
opLock.Lock();
|
|
|
|
if ((item = HasItem(layer))){
|
|
|
|
ListData *nextItem = NULL;
|
|
|
|
|
|
|
|
// prepare to set new front/focus if this layer was front/focus
|
|
|
|
nextItem = item->upperItem;
|
|
|
|
|
|
|
|
SearchAndSetNewFront(nextItem? nextItem->layerPtr: NULL);
|
|
|
|
// we don't care bout focus in this method!!!
|
|
|
|
//SearchAndSetNewFocus(nextItem? nextItem->layerPtr: NULL);
|
|
|
|
|
|
|
|
// remove some windows.
|
|
|
|
if (item && item->layerPtr->_level == B_NORMAL_FEEL)
|
|
|
|
{
|
|
|
|
ListData *listItem = item->lowerItem;
|
|
|
|
while(listItem && (listItem->layerPtr->_level == B_FLOATING_SUBSET_FEEL
|
|
|
|
|| listItem->layerPtr->_level == B_FLOATING_APP_FEEL
|
|
|
|
|| listItem->layerPtr->_level == B_MODAL_SUBSET_FEEL))
|
|
|
|
{
|
|
|
|
// *carefuly* remove the item from the list
|
|
|
|
ListData *itemX = listItem;
|
|
|
|
listItem = listItem->lowerItem;
|
|
|
|
RemoveItem(itemX);
|
|
|
|
delete itemX;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
opLock.Unlock();
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
else{
|
|
|
|
opLock.Unlock();
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
2004-01-13 04:03:29 +03:00
|
|
|
WinBorder* Workspace::SetFocusLayer(WinBorder* layer){
|
2004-01-14 03:26:15 +03:00
|
|
|
STRACE(("\n@Workspace(%ld)::SetFOCUSLayer( %s )\n", ID(), layer? layer->GetName(): "NULL"));
|
2004-01-14 18:55:10 +03:00
|
|
|
|
|
|
|
if(!(desktop->fGeneralLock.IsLocked()))
|
|
|
|
debugger("Workspace::SetFocusLayer - desktop->fGeneralLock must be LOCKED!\n");
|
|
|
|
|
|
|
|
WinBorder *previousFocus = FocusLayer();
|
|
|
|
|
2004-01-12 01:12:55 +03:00
|
|
|
SearchAndSetNewFocus(layer);
|
2004-01-14 18:55:10 +03:00
|
|
|
|
|
|
|
if (previousFocus != FocusLayer()){
|
|
|
|
if (previousFocus)
|
2004-02-24 14:56:43 +03:00
|
|
|
previousFocus->HighlightDecorator(false);
|
2004-01-14 18:55:10 +03:00
|
|
|
|
|
|
|
if (FocusLayer()){
|
2004-02-24 14:56:43 +03:00
|
|
|
FocusLayer()->HighlightDecorator(true);
|
2004-01-14 18:55:10 +03:00
|
|
|
}
|
|
|
|
|
2004-01-14 03:26:15 +03:00
|
|
|
// TODO: there had to be a Invalidate() vresion witch takes a BRegion parameter
|
2004-01-16 19:09:36 +03:00
|
|
|
STRACESTREAM();
|
2004-01-14 18:55:10 +03:00
|
|
|
Invalidate();
|
|
|
|
}
|
|
|
|
else{
|
|
|
|
// Do nothing!
|
|
|
|
}
|
|
|
|
|
|
|
|
STRACE(("\n#Workspace(%ld)::SetFOCUSLayer( %s ) ENDED\n", ID(), layer? layer->GetName(): "NULL"));
|
2004-01-14 03:26:15 +03:00
|
|
|
|
2004-01-14 18:55:10 +03:00
|
|
|
return FocusLayer();
|
2004-01-12 01:12:55 +03:00
|
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
WinBorder* Workspace::FocusLayer() const{
|
|
|
|
return fFocusItem ? fFocusItem->layerPtr : NULL;
|
|
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
2004-01-13 04:03:29 +03:00
|
|
|
WinBorder* Workspace::SetFrontLayer(WinBorder* layer){
|
|
|
|
STRACE(("\n@Workspace(%ld)::SetFrontLayer( %s )\n", ID(), layer? layer->GetName(): "NULL"));
|
2004-01-14 18:55:10 +03:00
|
|
|
|
|
|
|
if(!(desktop->fGeneralLock.IsLocked()))
|
|
|
|
debugger("Workspace::SetFRONTLayer - desktop->fGeneralLock must be LOCKED!\n");
|
|
|
|
|
2004-01-12 01:12:55 +03:00
|
|
|
SearchAndSetNewFront(layer);
|
2004-01-14 03:26:15 +03:00
|
|
|
STRACESTREAM();
|
|
|
|
// TODO: there had to be a Invalidate() vresion witch takes a BRegion parameter
|
|
|
|
Invalidate();
|
2004-01-13 04:03:29 +03:00
|
|
|
|
|
|
|
return fFrontItem? fFrontItem->layerPtr: NULL;;
|
2004-01-12 01:12:55 +03:00
|
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
WinBorder* Workspace::FrontLayer() const{
|
|
|
|
return fFrontItem? fFrontItem->layerPtr: NULL;
|
|
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
WinBorder* Workspace::GoToBottomItem(){
|
|
|
|
fCurrentItem = fBottomItem;
|
|
|
|
return fCurrentItem ? fCurrentItem->layerPtr : NULL;
|
|
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
WinBorder* Workspace::GoToUpperItem(){
|
|
|
|
if (fCurrentItem){
|
|
|
|
fCurrentItem = fCurrentItem->upperItem;
|
|
|
|
return fCurrentItem ? fCurrentItem->layerPtr : NULL;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
WinBorder* Workspace::GoToTopItem(){
|
|
|
|
fCurrentItem = fTopItem;
|
|
|
|
return fCurrentItem ? fCurrentItem->layerPtr : NULL;
|
|
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
WinBorder* Workspace::GoToLowerItem(){
|
|
|
|
if (fCurrentItem){
|
|
|
|
fCurrentItem = fCurrentItem->lowerItem;
|
|
|
|
return fCurrentItem ? fCurrentItem->layerPtr : NULL;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
bool Workspace::GoToItem(WinBorder* layer){
|
|
|
|
if (!layer)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
if (fCurrentItem && fCurrentItem->layerPtr == layer){
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
for( ListData *item = fBottomItem; item != NULL; item = item->upperItem){
|
|
|
|
if (item->layerPtr == layer){
|
|
|
|
fCurrentItem = item;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
2004-02-24 14:56:43 +03:00
|
|
|
WinBorder* Workspace::SearchWinBorder(BPoint pt){
|
|
|
|
// TODO: implement correctly once you have clipping code working
|
2004-01-13 04:03:29 +03:00
|
|
|
// For the moment, take windows from front to back and see in witch one 'pt' falls
|
|
|
|
WinBorder *target = NULL;
|
|
|
|
opLock.Lock();
|
2004-01-21 05:58:39 +03:00
|
|
|
STRACE(("Searching (%f,%f) in...\n", pt.x, pt.y));
|
2004-01-13 04:03:29 +03:00
|
|
|
for( WinBorder *wb = GoToBottomItem(); wb; wb = GoToUpperItem()){
|
2004-01-21 05:58:39 +03:00
|
|
|
// wb->PrintToStream();
|
2004-01-13 04:03:29 +03:00
|
|
|
if (!wb->IsHidden() && wb->HasPoint(pt)){
|
2004-01-21 05:58:39 +03:00
|
|
|
STRACE(("%s - SELECTED!\n", wb->GetName()));
|
2004-01-13 04:03:29 +03:00
|
|
|
target = wb;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
opLock.Unlock();
|
|
|
|
return target;
|
|
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
2004-01-14 03:26:15 +03:00
|
|
|
void Workspace::Invalidate(){
|
|
|
|
//TODO: *****!*!*!*!*!*!*!**!***REMOVE this! For Test purposes only!
|
2004-01-17 19:33:22 +03:00
|
|
|
opLock.Lock();
|
2004-01-14 03:26:15 +03:00
|
|
|
if(fOwner->ActiveWorkspace() == this)
|
2004-02-24 14:56:43 +03:00
|
|
|
fOwner->FullInvalidate(fOwner->Bounds());
|
2004-01-17 19:33:22 +03:00
|
|
|
opLock.Unlock();
|
2004-01-14 03:26:15 +03:00
|
|
|
//----------------
|
|
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
2004-01-12 01:12:55 +03:00
|
|
|
void Workspace::InsertItem(ListData* item, ListData* before){
|
|
|
|
// insert before one other item;
|
|
|
|
if (before){
|
|
|
|
if (before->upperItem)
|
|
|
|
before->upperItem->lowerItem = item;
|
|
|
|
item->upperItem = before->upperItem;
|
|
|
|
before->upperItem = item;
|
|
|
|
item->lowerItem = before;
|
|
|
|
|
|
|
|
// if we're inserting at top of the stack, change it accordingly.
|
|
|
|
if(fTopItem == before)
|
|
|
|
fTopItem = item;
|
|
|
|
}
|
|
|
|
// insert item at bottom.
|
|
|
|
else{
|
|
|
|
item->upperItem = fBottomItem;
|
|
|
|
if (fBottomItem)
|
|
|
|
fBottomItem->lowerItem = item;
|
|
|
|
|
|
|
|
fBottomItem = item;
|
|
|
|
|
|
|
|
if (!fTopItem)
|
|
|
|
fTopItem = item;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
void Workspace::RemoveItem(ListData* item){
|
|
|
|
if (!item)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (fBottomItem == item){
|
|
|
|
fBottomItem = item->upperItem;
|
|
|
|
}
|
|
|
|
else{
|
|
|
|
item->lowerItem->upperItem = item->upperItem;
|
|
|
|
}
|
|
|
|
if (fTopItem == item){
|
|
|
|
fTopItem = item->lowerItem;
|
|
|
|
}
|
|
|
|
else{
|
|
|
|
item->upperItem->lowerItem = item->lowerItem;
|
|
|
|
}
|
|
|
|
|
|
|
|
// set all these to NULL to avoid confusion later.
|
|
|
|
|
|
|
|
item->upperItem = NULL;
|
|
|
|
item->lowerItem = NULL;
|
|
|
|
|
2004-01-16 19:09:36 +03:00
|
|
|
if (fFocusItem == item){
|
2004-02-24 14:56:43 +03:00
|
|
|
fFocusItem->layerPtr->HighlightDecorator(false);
|
2004-01-12 01:12:55 +03:00
|
|
|
fFocusItem = NULL;
|
2004-01-16 19:09:36 +03:00
|
|
|
}
|
2004-01-12 01:12:55 +03:00
|
|
|
if (fFrontItem == item)
|
|
|
|
fFrontItem = NULL;
|
|
|
|
if (fCurrentItem == item)
|
|
|
|
fCurrentItem = NULL;
|
|
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
ListData* Workspace::HasItem(ListData* item){
|
|
|
|
for (ListData *itemX = fBottomItem; itemX != NULL; itemX = itemX->upperItem){
|
|
|
|
if (item == itemX){
|
|
|
|
return itemX;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
ListData* Workspace::HasItem(WinBorder* layer){
|
|
|
|
for (ListData *item = fBottomItem; item != NULL; item = item->upperItem){
|
|
|
|
if (item->layerPtr == layer){
|
|
|
|
return item;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
/* This, also is a "smart" method. Firstly this funtionality was in
|
|
|
|
* SearchAndSetNewFront, but I've split it for reasons of clarity. Anyway,
|
|
|
|
* what is to be noticed is that those 2 methods work hand-in-hand.
|
|
|
|
* What FindPlace() litelaly does, is *place* the 'pref' item into its
|
|
|
|
* >right< place! If 'pref->layerPtr'(the WinBorder in ListData structure)
|
|
|
|
* does not meet some conditions a search for another, valid, WinBorder is
|
|
|
|
* being made.
|
|
|
|
*
|
|
|
|
* NOTE: Do NOT be confussed! This method places the preferred window *ONLY*!
|
|
|
|
* Other windows that need to be placed before it, *WILL* be placed by almost
|
|
|
|
* all code found in SearchAndSetNewFront
|
|
|
|
*/
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
ListData* Workspace::FindPlace(ListData* pref){
|
|
|
|
// if we received a NULL value, we stil have to give 'front' state to some window...
|
|
|
|
if (!pref)
|
2004-01-17 19:33:22 +03:00
|
|
|
pref = HasItem(fBottomItem);
|
|
|
|
else
|
|
|
|
pref = HasItem(pref);
|
2004-01-12 01:12:55 +03:00
|
|
|
|
|
|
|
ListData *item = NULL;
|
|
|
|
|
|
|
|
// search a window that is not hidden and does *not* have B_AVOID_FRONT flag.
|
|
|
|
item = pref;
|
2004-01-13 04:03:29 +03:00
|
|
|
while(pref && item->lowerItem != pref && (pref->upperItem || pref->lowerItem)){
|
|
|
|
if ( !(item->layerPtr->Window()->Flags() & B_AVOID_FRONT) && !(item->layerPtr->IsHidden()) )
|
2004-01-12 01:12:55 +03:00
|
|
|
break;
|
2004-01-21 05:58:39 +03:00
|
|
|
STRACE(("item: %s - pref: %s\n", item->layerPtr->GetName(), pref->layerPtr->GetName()));
|
2004-01-12 01:12:55 +03:00
|
|
|
if (item == fTopItem)
|
|
|
|
item = fBottomItem;
|
|
|
|
else
|
|
|
|
item = item->upperItem;
|
|
|
|
}
|
2004-01-13 04:03:29 +03:00
|
|
|
|
|
|
|
// if true, it means we have windows with B_AVOID_FRONT flag *only*,
|
|
|
|
// or they are all hidden. Pick one, if you can.
|
2004-01-12 01:12:55 +03:00
|
|
|
if (pref && item->lowerItem == pref){
|
|
|
|
for (item = fBottomItem; item; item = item->upperItem){
|
|
|
|
if ( !(item->layerPtr->IsHidden()) )
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// if the search took place or not...
|
|
|
|
pref = item;
|
|
|
|
|
|
|
|
// we have exhausted all possibilities to make pref a vaid pointer... so... exit now.
|
|
|
|
if (!pref)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
// temporally remove 'pref' to reinsert it later in the *right* place
|
|
|
|
RemoveItem(pref);
|
|
|
|
|
|
|
|
// we start searching its place
|
|
|
|
ListData *cursor = fBottomItem;
|
2004-01-13 04:03:29 +03:00
|
|
|
int32 feel = pref->layerPtr->Window()->Feel();
|
2004-01-12 01:12:55 +03:00
|
|
|
|
|
|
|
switch(feel){
|
|
|
|
case B_NORMAL_WINDOW_FEEL:{
|
2004-01-13 04:03:29 +03:00
|
|
|
while(cursor && cursor->layerPtr->_level > B_MODAL_APP_FEEL){
|
2004-01-12 01:12:55 +03:00
|
|
|
cursor = cursor->upperItem;
|
|
|
|
}
|
|
|
|
InsertItem(pref, cursor? cursor->lowerItem: NULL);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case B_SYSTEM_LAST:{
|
2004-01-13 04:03:29 +03:00
|
|
|
while(cursor && cursor->layerPtr->_level > pref->layerPtr->_level){
|
2004-01-12 01:12:55 +03:00
|
|
|
cursor = cursor->upperItem;
|
|
|
|
}
|
|
|
|
InsertItem(pref, cursor? cursor->lowerItem: fTopItem);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case B_SYSTEM_FIRST:
|
|
|
|
case B_FLOATING_ALL_WINDOW_FEEL:
|
|
|
|
case B_MODAL_ALL_WINDOW_FEEL:
|
|
|
|
case B_MODAL_APP_WINDOW_FEEL:{
|
2004-01-13 04:03:29 +03:00
|
|
|
while(cursor && cursor->layerPtr->_level > pref->layerPtr->_level){
|
2004-01-12 01:12:55 +03:00
|
|
|
cursor = cursor->upperItem;
|
|
|
|
}
|
|
|
|
InsertItem(pref, cursor? cursor->lowerItem: NULL);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
// place in front of: its main window, other subset windows and in front
|
|
|
|
// of other application's floating windows.
|
|
|
|
// NOTE that this happens only if its main window is the front most one.
|
|
|
|
case B_FLOATING_SUBSET_WINDOW_FEEL:{
|
|
|
|
for(cursor = fBottomItem; cursor; cursor = cursor->upperItem){
|
2004-01-13 04:03:29 +03:00
|
|
|
if (cursor->layerPtr->_level <= pref->layerPtr->_level
|
2004-01-12 01:12:55 +03:00
|
|
|
&& (cursor->layerPtr == pref->layerPtr->MainWinBorder()
|
|
|
|
|| cursor->layerPtr->MainWinBorder() == pref->layerPtr->MainWinBorder())
|
|
|
|
)
|
|
|
|
{ break; }
|
2004-01-13 04:03:29 +03:00
|
|
|
else if(pref->layerPtr->_level == B_FLOATING_SUBSET_FEEL
|
|
|
|
&& cursor->layerPtr->_level == B_FLOATING_APP_FEEL)
|
2004-01-12 01:12:55 +03:00
|
|
|
{ break; }
|
|
|
|
}
|
|
|
|
if (cursor)
|
|
|
|
InsertItem(pref, cursor? cursor->lowerItem: NULL);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
// place this SUBSET_MODAL behind APP_MODAL ones if they belong
|
|
|
|
// to the same application OR, in front of all MODAL/NORMAL if
|
|
|
|
// it belongs to another application
|
|
|
|
case B_MODAL_SUBSET_WINDOW_FEEL:{
|
|
|
|
for(cursor = fBottomItem; cursor; cursor = cursor->upperItem){
|
2004-01-13 04:03:29 +03:00
|
|
|
if (cursor->layerPtr->_level <= pref->layerPtr->_level)
|
2004-01-12 01:12:55 +03:00
|
|
|
break;
|
2004-01-13 04:03:29 +03:00
|
|
|
else if(pref->layerPtr->_level == B_MODAL_SUBSET_FEEL
|
|
|
|
&& cursor->layerPtr->_level == B_MODAL_APP_FEEL
|
|
|
|
&& pref->layerPtr->Window()->ClientTeamID()
|
|
|
|
!= cursor->layerPtr->Window()->ClientTeamID())
|
2004-01-12 01:12:55 +03:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (cursor)
|
|
|
|
InsertItem(pref, cursor? cursor->lowerItem: NULL);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
// place in front of: its main window, other floating windows
|
|
|
|
// NOTE that this happens only if its main window is the front most one.
|
|
|
|
case B_FLOATING_APP_WINDOW_FEEL:{
|
|
|
|
for(cursor = fBottomItem; cursor; cursor = cursor->upperItem){
|
2004-01-13 04:03:29 +03:00
|
|
|
if (cursor->layerPtr->_level <= pref->layerPtr->_level
|
|
|
|
&& pref->layerPtr->Window()->ClientTeamID() ==
|
|
|
|
cursor->layerPtr->Window()->ClientTeamID())
|
2004-01-12 01:12:55 +03:00
|
|
|
{ break; }
|
|
|
|
}
|
|
|
|
|
|
|
|
if (cursor)
|
|
|
|
InsertItem(pref, cursor? cursor->lowerItem: NULL);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return pref;
|
|
|
|
}
|
|
|
|
/* This method is the key to correct window arangement!!!
|
|
|
|
* With the help of FindPlace it correctly aranges windows. FindPlace, only
|
|
|
|
* inserted the window in the correct place, this method also brings all
|
|
|
|
* other windows that are supposed to be in front of her - I'm talking here
|
|
|
|
* about floating and modal windows.
|
|
|
|
* It also clerverly selects the new FINAL front window.
|
|
|
|
*/
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
void Workspace::SearchAndSetNewFront(WinBorder* preferred){
|
2004-01-13 04:03:29 +03:00
|
|
|
STRACE(("*WS(%ld)::SASNF(%s)\n", ID(), preferred? preferred->GetName(): "NULL"));
|
|
|
|
opLock.Lock();
|
2004-01-12 01:12:55 +03:00
|
|
|
// the new front must not be the same as the previous one.
|
2004-01-13 04:03:29 +03:00
|
|
|
if (fFrontItem && fFrontItem->layerPtr == preferred && !(preferred->IsHidden())){
|
|
|
|
STRACE(("-WS(%ld)::SASNF(%s) - opperation not needed! Workspace data:",
|
|
|
|
ID(), preferred? preferred->GetName(): "NULL"));
|
|
|
|
STRACESTREAM();
|
|
|
|
STRACE(("#WS(%ld)::SASNF(%s) ENDED 1\n", ID(), preferred? preferred->GetName(): "NULL"));
|
|
|
|
opLock.Unlock();
|
2004-01-12 01:12:55 +03:00
|
|
|
return;
|
2004-01-13 04:03:29 +03:00
|
|
|
}
|
2004-01-12 01:12:55 +03:00
|
|
|
|
|
|
|
// properly place this 'preferred' WinBorder.
|
|
|
|
ListData *lastInserted;
|
|
|
|
lastInserted = FindPlace(HasItem(preferred));
|
|
|
|
preferred = lastInserted? lastInserted->layerPtr: NULL;
|
2004-01-14 03:26:15 +03:00
|
|
|
STRACE(("-WS(%ld)::SASNF(%s) - after FindPlace...", ID(), preferred? preferred->GetName(): "NULL"));
|
|
|
|
STRACESTREAM();
|
2004-01-12 01:12:55 +03:00
|
|
|
|
|
|
|
// if the new front layer is the same... there is no point continuing
|
2004-01-13 04:03:29 +03:00
|
|
|
if(fFrontItem == lastInserted){
|
|
|
|
STRACE(("-WS(%ld)::SASNF(%s) - new front layer is the same as the old one. Stop!", ID(), preferred? preferred->GetName(): "NULL"));
|
|
|
|
STRACESTREAM();
|
|
|
|
STRACE(("#WS(%ld)::SASNF(%s) ENDED 2\n", ID(), preferred? preferred->GetName(): "NULL"));
|
|
|
|
opLock.Unlock();
|
2004-01-12 01:12:55 +03:00
|
|
|
return;
|
2004-01-13 04:03:29 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
if(!lastInserted){
|
2004-01-21 05:58:39 +03:00
|
|
|
STRACE(("PAAAAANIC: Workspace::SASNF(): 'lastInserted' IS NULL\n"));
|
2004-01-13 04:03:29 +03:00
|
|
|
}
|
|
|
|
else{
|
2004-01-21 05:58:39 +03:00
|
|
|
STRACE(("\n&&&&Processing for: %s\n", lastInserted->layerPtr->GetName()));
|
2004-01-13 04:03:29 +03:00
|
|
|
}
|
2004-01-12 01:12:55 +03:00
|
|
|
|
|
|
|
if (lastInserted && !(lastInserted->layerPtr->IsHidden())){
|
2004-01-13 04:03:29 +03:00
|
|
|
int32 prefFeel = preferred->Window()->Feel();
|
2004-01-12 01:12:55 +03:00
|
|
|
|
|
|
|
if (prefFeel == B_NORMAL_WINDOW_FEEL){
|
2004-01-13 04:03:29 +03:00
|
|
|
STRACE((" NORMAL Window '%s' -", preferred? preferred->GetName(): "NULL"));
|
2004-01-12 01:12:55 +03:00
|
|
|
if (fFrontItem){
|
|
|
|
// if they are in the same team...
|
2004-01-13 04:03:29 +03:00
|
|
|
if (preferred->Window()->ClientTeamID() == fFrontItem->layerPtr->Window()->ClientTeamID()){
|
2004-01-12 01:12:55 +03:00
|
|
|
STRACE((" SAME TeamID\n"));
|
|
|
|
// collect subset windows that are common to application's windows...
|
|
|
|
// NOTE: A subset window *can* be added to more than just one window.
|
|
|
|
FMWList commonFMW;
|
|
|
|
FMWList appFMW;
|
|
|
|
FMWList finalFMWList;
|
|
|
|
int32 count, i;
|
|
|
|
// collect floating and modal windows spread across the workspace only if
|
|
|
|
// they are in our window's subset
|
|
|
|
// * also remove them, for repositioning, later.
|
|
|
|
ListData *listItem = fTopItem;
|
|
|
|
while(listItem){
|
2004-01-13 04:03:29 +03:00
|
|
|
int32 feel = listItem->layerPtr->Window()->Feel();
|
2004-01-12 01:12:55 +03:00
|
|
|
if (feel == B_FLOATING_SUBSET_WINDOW_FEEL || feel == B_MODAL_SUBSET_WINDOW_FEEL){
|
2004-01-13 04:03:29 +03:00
|
|
|
if(preferred->Window()->fWinFMWList.HasItem(listItem->layerPtr)){
|
2004-01-12 01:12:55 +03:00
|
|
|
commonFMW.AddItem(listItem->layerPtr);
|
|
|
|
// *carefully* remove the item from the list
|
|
|
|
ListData *item = listItem;
|
|
|
|
listItem = listItem->lowerItem;
|
|
|
|
RemoveItem(item);
|
|
|
|
}
|
|
|
|
// also remove floating windows. Those, SURELY belong to
|
|
|
|
// 'fFrontItem' - this being the *old* front window.
|
|
|
|
else if (feel == B_FLOATING_SUBSET_WINDOW_FEEL){
|
|
|
|
// *carefully* remove the item from the list
|
|
|
|
ListData *item = listItem;
|
|
|
|
listItem = listItem->lowerItem;
|
|
|
|
RemoveItem(item);
|
|
|
|
}
|
2004-01-17 19:33:22 +03:00
|
|
|
else{
|
2004-01-12 01:12:55 +03:00
|
|
|
listItem = listItem->lowerItem;
|
2004-01-17 19:33:22 +03:00
|
|
|
}
|
2004-01-12 01:12:55 +03:00
|
|
|
}
|
|
|
|
// ALSO collect application's floating and modal windows,
|
|
|
|
// for reinsertion, later.
|
|
|
|
else if (feel == B_FLOATING_APP_WINDOW_FEEL || feel == B_MODAL_APP_WINDOW_FEEL){
|
2004-01-13 04:03:29 +03:00
|
|
|
if(listItem->layerPtr->Window()->ClientTeamID() ==
|
|
|
|
preferred->Window()->ClientTeamID())
|
2004-01-12 01:12:55 +03:00
|
|
|
{
|
|
|
|
appFMW.AddItem(listItem->layerPtr);
|
|
|
|
// *carefully* remove the item from the list
|
|
|
|
ListData *item = listItem;
|
|
|
|
listItem = listItem->lowerItem;
|
|
|
|
RemoveItem(item);
|
|
|
|
}
|
2004-01-14 03:26:15 +03:00
|
|
|
else
|
|
|
|
listItem = listItem->lowerItem;
|
2004-01-12 01:12:55 +03:00
|
|
|
}
|
|
|
|
else
|
|
|
|
listItem = listItem->lowerItem;
|
|
|
|
}
|
2004-01-13 04:03:29 +03:00
|
|
|
|
2004-01-12 01:12:55 +03:00
|
|
|
// put in the final list, items that are not found in the common list
|
2004-01-13 04:03:29 +03:00
|
|
|
count = preferred->Window()->fWinFMWList.CountItems();
|
2004-01-12 01:12:55 +03:00
|
|
|
for (i=0; i<count; i++){
|
2004-01-13 04:03:29 +03:00
|
|
|
void *item = preferred->Window()->fWinFMWList.ItemAt(i);
|
2004-01-17 19:33:22 +03:00
|
|
|
if (commonFMW.HasItem(item)){
|
|
|
|
}
|
2004-01-12 01:12:55 +03:00
|
|
|
else
|
|
|
|
finalFMWList.AddItem(item);
|
|
|
|
}
|
2004-01-14 03:26:15 +03:00
|
|
|
|
2004-01-12 01:12:55 +03:00
|
|
|
// colapse the 2 lists
|
|
|
|
finalFMWList.AddFMWList(&commonFMW);
|
|
|
|
finalFMWList.AddFMWList(&appFMW);
|
|
|
|
|
|
|
|
// insert windows found in 'finalFMWList' in Workspace's list.
|
|
|
|
// IF *one* modal is found, do not add floating ones!
|
|
|
|
|
|
|
|
// see if the last WinBorder in the list is a modal window.
|
|
|
|
// OR if the last one in Workspace's list is a modal window...
|
|
|
|
WinBorder *wb = (WinBorder*)finalFMWList.LastItem();
|
|
|
|
bool lastIsModal = false;
|
|
|
|
if ( (wb &&
|
2004-01-13 04:03:29 +03:00
|
|
|
(wb->Window()->Feel() == B_MODAL_SUBSET_WINDOW_FEEL
|
|
|
|
|| wb->Window()->Feel() == B_MODAL_APP_WINDOW_FEEL))
|
2004-01-12 01:12:55 +03:00
|
|
|
|| (fBottomItem &&
|
2004-01-13 04:03:29 +03:00
|
|
|
(fBottomItem->layerPtr->Window()->Feel() == B_MODAL_ALL_WINDOW_FEEL
|
|
|
|
|| fBottomItem->layerPtr->Window()->Feel() == B_SYSTEM_FIRST))
|
2004-01-12 01:12:55 +03:00
|
|
|
)
|
|
|
|
{ lastIsModal = true; }
|
|
|
|
|
|
|
|
// this variable will help us in deciding the new front WinBorder.
|
|
|
|
WinBorder *finalPreferred = preferred;
|
|
|
|
// now insert items found in finalFMWList into Workspace
|
|
|
|
count = finalFMWList.CountItems();
|
|
|
|
for(i=0; i<count; i++){
|
|
|
|
WinBorder *wb = (WinBorder*)finalFMWList.ItemAt(i);
|
2004-01-13 04:03:29 +03:00
|
|
|
if(wb->Window()->Feel() == B_FLOATING_SUBSET_WINDOW_FEEL
|
|
|
|
|| wb->Window()->Feel() == B_FLOATING_APP_WINDOW_FEEL)
|
2004-01-12 01:12:55 +03:00
|
|
|
{
|
|
|
|
// set its new MainWinBorder
|
2004-01-13 04:03:29 +03:00
|
|
|
if(wb->Window()->Feel() == B_FLOATING_SUBSET_WINDOW_FEEL)
|
2004-01-12 01:12:55 +03:00
|
|
|
wb->SetMainWinBorder(preferred);
|
|
|
|
// don't add if the last WinBorder is a modal one.
|
|
|
|
if (lastIsModal)
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
else{
|
2004-01-13 04:03:29 +03:00
|
|
|
if(wb->Window()->Feel() == B_MODAL_SUBSET_WINDOW_FEEL)
|
2004-01-12 01:12:55 +03:00
|
|
|
wb->SetMainWinBorder(preferred);
|
|
|
|
// if this modal window is not hidden, give it the front status.
|
|
|
|
if (!(wb->IsHidden()))
|
|
|
|
finalPreferred = wb;
|
|
|
|
}
|
|
|
|
|
|
|
|
// insert item just after the last inserted one.
|
|
|
|
ListData *newItem = new ListData();
|
|
|
|
newItem->layerPtr = wb;
|
|
|
|
newItem->lowerItem = lastInserted->lowerItem;
|
|
|
|
newItem->upperItem = lastInserted;
|
|
|
|
if (lastInserted->lowerItem)
|
|
|
|
lastInserted->lowerItem->upperItem = newItem;
|
|
|
|
lastInserted->lowerItem = newItem;
|
|
|
|
|
|
|
|
if(lastInserted == fBottomItem)
|
|
|
|
fBottomItem = newItem;
|
|
|
|
|
|
|
|
lastInserted = newItem;
|
|
|
|
}
|
|
|
|
preferred = finalPreferred;
|
|
|
|
}
|
|
|
|
else{
|
|
|
|
STRACE((" DIFERRENT TeamID\n"));
|
|
|
|
// remove front window's floating(_SUBSET_/_APP_) windows, if any.
|
|
|
|
ListData *listItem = fFrontItem->lowerItem;
|
2004-01-13 04:03:29 +03:00
|
|
|
while(listItem && (listItem->layerPtr->_level == B_FLOATING_SUBSET_FEEL
|
|
|
|
|| listItem->layerPtr->_level == B_FLOATING_APP_FEEL))
|
2004-01-12 01:12:55 +03:00
|
|
|
{ // *carefully* remove the item from the list
|
|
|
|
ListData *item = listItem;
|
|
|
|
listItem = listItem->lowerItem;
|
|
|
|
RemoveItem(item);
|
|
|
|
}
|
|
|
|
// now, jump to et1: to make a 'clean' selecting of
|
|
|
|
// windows to be inserted
|
|
|
|
fFrontItem = NULL;
|
|
|
|
goto et1;
|
2004-01-16 19:09:36 +03:00
|
|
|
} // END: else - if diferrent ClientTeamID()s.
|
2004-01-12 01:12:55 +03:00
|
|
|
} // if (fFrontItem) && NORMAL_WINDOW
|
|
|
|
else{
|
|
|
|
STRACE((" NO previous FRONT Item\n"));
|
|
|
|
et1:
|
|
|
|
FMWList finalFMWList;
|
|
|
|
int32 count, i;
|
|
|
|
ListData *listItem = fTopItem;
|
|
|
|
// remove window's subset and application's *modal* windows spread
|
|
|
|
// across Workspace's list, to be insert later, in the corect order.
|
|
|
|
while(listItem){
|
2004-01-13 04:03:29 +03:00
|
|
|
int32 feel = listItem->layerPtr->Window()->Feel();
|
2004-01-12 01:12:55 +03:00
|
|
|
if ((feel == B_MODAL_SUBSET_WINDOW_FEEL
|
2004-01-13 04:03:29 +03:00
|
|
|
&& preferred->Window()->fWinFMWList.HasItem(listItem->layerPtr))
|
2004-01-12 01:12:55 +03:00
|
|
|
|| (feel == B_MODAL_APP_WINDOW_FEEL
|
2004-01-13 04:03:29 +03:00
|
|
|
&& preferred->Window()->ClientTeamID() ==
|
|
|
|
listItem->layerPtr->Window()->ClientTeamID()
|
2004-01-12 01:12:55 +03:00
|
|
|
))
|
|
|
|
{
|
|
|
|
// *carefully* remove the item from the list
|
|
|
|
ListData *item = listItem;
|
|
|
|
listItem = listItem->lowerItem;
|
|
|
|
RemoveItem(item);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
listItem = listItem->lowerItem;
|
|
|
|
}
|
|
|
|
// add to the final list window's subset windows. (..._SUBSET_...)
|
2004-01-13 04:03:29 +03:00
|
|
|
finalFMWList.AddFMWList(&(preferred->Window()->fWinFMWList));
|
2004-01-12 01:12:55 +03:00
|
|
|
// also add application's ones. (..._APP_...)
|
2004-01-13 04:03:29 +03:00
|
|
|
finalFMWList.AddFMWList(&(preferred->Window()->App()->fAppFMWList));
|
2004-01-12 01:12:55 +03:00
|
|
|
// insert windows found in 'finalFMWList' in Workspace's list.
|
|
|
|
// IF *one* modal is found, do not add floating ones!
|
|
|
|
|
|
|
|
// see if the last WinBorder in the list is a modal window.
|
|
|
|
WinBorder *wb = (WinBorder*)finalFMWList.LastItem();
|
|
|
|
bool lastIsModal = false;
|
|
|
|
if ( (wb &&
|
2004-01-13 04:03:29 +03:00
|
|
|
(wb->Window()->Feel() == B_MODAL_SUBSET_WINDOW_FEEL
|
|
|
|
|| wb->Window()->Feel() == B_MODAL_APP_WINDOW_FEEL))
|
2004-01-12 01:12:55 +03:00
|
|
|
|| (fBottomItem &&
|
2004-01-13 04:03:29 +03:00
|
|
|
(fBottomItem->layerPtr->Window()->Feel() == B_MODAL_ALL_WINDOW_FEEL
|
|
|
|
|| fBottomItem->layerPtr->Window()->Feel() == B_SYSTEM_FIRST))
|
2004-01-12 01:12:55 +03:00
|
|
|
)
|
|
|
|
{ lastIsModal = true; }
|
|
|
|
|
|
|
|
// this variable will help us in deciding the new front WinBorder.
|
|
|
|
WinBorder *finalPreferred = preferred;
|
|
|
|
// now insert items found in finalFMWList into Workspace
|
|
|
|
count = finalFMWList.CountItems();
|
|
|
|
for(i=0; i<count; i++){
|
|
|
|
WinBorder *wb = (WinBorder*)finalFMWList.ItemAt(i);
|
|
|
|
// do not insert floating windows if the last is a modal one.
|
2004-01-13 04:03:29 +03:00
|
|
|
if(wb->Window()->Feel() == B_FLOATING_SUBSET_WINDOW_FEEL
|
|
|
|
|| wb->Window()->Feel() == B_FLOATING_APP_WINDOW_FEEL)
|
2004-01-12 01:12:55 +03:00
|
|
|
{
|
|
|
|
// set its new MainWinBorder
|
2004-01-13 04:03:29 +03:00
|
|
|
if(wb->Window()->Feel() == B_FLOATING_SUBSET_WINDOW_FEEL)
|
2004-01-12 01:12:55 +03:00
|
|
|
wb->SetMainWinBorder(preferred);
|
|
|
|
// don't add if the last WinBorder is a modal one.
|
|
|
|
if (lastIsModal)
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
else{
|
2004-01-13 04:03:29 +03:00
|
|
|
if(wb->Window()->Feel() == B_MODAL_SUBSET_WINDOW_FEEL)
|
2004-01-12 01:12:55 +03:00
|
|
|
wb->SetMainWinBorder(preferred);
|
|
|
|
// if this modal window is not hidden, give it the front status.
|
|
|
|
if (!(wb->IsHidden()))
|
|
|
|
finalPreferred = wb;
|
|
|
|
}
|
|
|
|
// insert item just after the last inserted one.
|
|
|
|
ListData *newItem = new ListData();
|
|
|
|
newItem->layerPtr = wb;
|
|
|
|
newItem->lowerItem = lastInserted->lowerItem;
|
|
|
|
newItem->upperItem = lastInserted;
|
|
|
|
if (lastInserted->lowerItem)
|
|
|
|
lastInserted->lowerItem->upperItem = newItem;
|
|
|
|
lastInserted->lowerItem = newItem;
|
|
|
|
|
|
|
|
if(lastInserted == fBottomItem)
|
|
|
|
fBottomItem = newItem;
|
|
|
|
|
|
|
|
lastInserted = newItem;
|
|
|
|
}
|
|
|
|
preferred = finalPreferred;
|
|
|
|
} // else - if(fFrontItem);
|
|
|
|
} // END: if _NORMAL_ window.
|
|
|
|
else if( prefFeel == B_FLOATING_SUBSET_WINDOW_FEEL
|
|
|
|
|| prefFeel == B_FLOATING_APP_WINDOW_FEEL
|
|
|
|
|| prefFeel == B_FLOATING_ALL_WINDOW_FEEL)
|
|
|
|
{
|
2004-01-13 04:03:29 +03:00
|
|
|
STRACE((" FLOATING Window '%s'\n", preferred? preferred->GetName(): "NULL"));
|
2004-01-12 01:12:55 +03:00
|
|
|
// Do nothing! FindPlace() was called and it has corectly placed our window
|
|
|
|
// We don't have to do noting here.
|
|
|
|
}
|
|
|
|
else if( prefFeel == B_MODAL_SUBSET_WINDOW_FEEL
|
|
|
|
|| prefFeel == B_MODAL_APP_WINDOW_FEEL)
|
|
|
|
{
|
2004-01-13 04:03:29 +03:00
|
|
|
STRACE((" MODAL_APP/SUBSET Window '%s'\n", preferred? preferred->GetName(): "NULL"));
|
2004-01-12 01:12:55 +03:00
|
|
|
FMWList finalMWList;
|
2004-01-13 04:03:29 +03:00
|
|
|
int32 count = 0, i;
|
|
|
|
int32 prefIndex = -1;
|
2004-01-12 01:12:55 +03:00
|
|
|
|
2004-01-13 04:03:29 +03:00
|
|
|
if (fFrontItem && fFrontItem->layerPtr->_level == B_NORMAL_FEEL)
|
2004-01-12 01:12:55 +03:00
|
|
|
{
|
|
|
|
// remove front window's floating(_SUBSET_/_APP_) windows, if any.
|
|
|
|
ListData *listItem = fFrontItem->lowerItem;
|
2004-01-13 04:03:29 +03:00
|
|
|
while(listItem && (listItem->layerPtr->_level == B_FLOATING_SUBSET_FEEL
|
|
|
|
|| listItem->layerPtr->_level == B_FLOATING_APP_FEEL))
|
2004-01-12 01:12:55 +03:00
|
|
|
{ // *carefully* remove the item from the list
|
|
|
|
ListData *item = listItem;
|
|
|
|
listItem = listItem->lowerItem;
|
|
|
|
RemoveItem(item);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// If this is a MODAL_SUBSET window, search it's place in its MainWinBorder
|
|
|
|
// window subset, and then take all modals after it; then continue talking
|
|
|
|
// modal windoes *only*, from application's set.
|
|
|
|
// If it is a MODAL_APP only search an take windows in/from application's set
|
|
|
|
if (prefFeel == B_MODAL_SUBSET_WINDOW_FEEL){
|
2004-01-13 04:03:29 +03:00
|
|
|
prefIndex = preferred->MainWinBorder()->Window()->fWinFMWList.IndexOf(preferred);
|
|
|
|
count = preferred->MainWinBorder()->Window()->fWinFMWList.CountItems();
|
2004-01-12 01:12:55 +03:00
|
|
|
if (prefIndex >= 0){
|
|
|
|
WinBorder *wb = NULL;
|
|
|
|
// add modal windows from its main window subset - windows that are
|
|
|
|
// positioned after 'preferred'.
|
2004-01-13 04:03:29 +03:00
|
|
|
FMWList *listPtr = &(preferred->MainWinBorder()->Window()->fWinFMWList);
|
2004-01-12 01:12:55 +03:00
|
|
|
for(i = prefIndex+1; i < count; i++){
|
|
|
|
// they *all* are modal windows.
|
|
|
|
wb = (WinBorder*)listPtr->ItemAt(i);
|
|
|
|
wb->SetMainWinBorder(preferred);
|
|
|
|
finalMWList.AddItem(wb);
|
|
|
|
// remove those windows(if in there), for correct re-insertion later.
|
|
|
|
ListData *ld = NULL;
|
|
|
|
if((ld = HasItem(wb)))
|
|
|
|
RemoveItem(ld);
|
|
|
|
}
|
|
|
|
// add modal windows that are found in application's subset
|
2004-01-13 04:03:29 +03:00
|
|
|
count = preferred->Window()->App()->fAppFMWList.CountItems();
|
|
|
|
listPtr = &(preferred->Window()->App()->fAppFMWList);
|
2004-01-12 01:12:55 +03:00
|
|
|
for(i = 0; i < count; i++){
|
|
|
|
wb = (WinBorder*)listPtr->ItemAt(i);
|
2004-01-13 04:03:29 +03:00
|
|
|
if (wb->Window()->Feel() == B_MODAL_APP_WINDOW_FEEL){
|
2004-01-12 01:12:55 +03:00
|
|
|
finalMWList.AddItem(wb);
|
|
|
|
// remove those windows(if in there), for correct re-insertion later.
|
|
|
|
ListData *ld = NULL;
|
|
|
|
if((ld = HasItem(wb)))
|
|
|
|
RemoveItem(ld);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if(prefFeel == B_MODAL_APP_WINDOW_FEEL){
|
2004-01-13 04:03:29 +03:00
|
|
|
prefIndex = preferred->Window()->App()->fAppFMWList.IndexOf(preferred);
|
|
|
|
count = preferred->Window()->App()->fAppFMWList.CountItems();
|
2004-01-12 01:12:55 +03:00
|
|
|
if (prefIndex >= 0){
|
|
|
|
WinBorder *wb = NULL;
|
|
|
|
// add modal windows from application's subset - windows that are
|
|
|
|
// positioned after 'preferred'.
|
2004-01-13 04:03:29 +03:00
|
|
|
FMWList *listPtr = &(preferred->Window()->App()->fAppFMWList);
|
2004-01-12 01:12:55 +03:00
|
|
|
for(i = prefIndex+1; i < count; i++){
|
|
|
|
wb = (WinBorder*)listPtr->ItemAt(i);
|
|
|
|
// they *all* are modal windows.
|
|
|
|
finalMWList.AddItem(wb);
|
|
|
|
// remove those windows(if in there), for correct re-insertion later.
|
|
|
|
ListData *ld = NULL;
|
|
|
|
if((ld = HasItem(wb)))
|
|
|
|
RemoveItem(ld);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// insert windows found in 'finalMWList' in Workspace's list, after "preferred"
|
|
|
|
count = finalMWList.CountItems();
|
|
|
|
// this varable will help us designate the future front.
|
|
|
|
WinBorder *finalPreferred = preferred;
|
|
|
|
for(i=0; i<count; i++){
|
|
|
|
WinBorder *wb = (WinBorder*)finalMWList.ItemAt(i);
|
|
|
|
// wb is surely a modal so... ATM make it the front one.
|
|
|
|
if(!(wb->IsHidden()))
|
|
|
|
finalPreferred = wb;
|
|
|
|
|
|
|
|
// insert item just after the last inserted one.
|
|
|
|
ListData *newItem = new ListData();
|
|
|
|
newItem->layerPtr = wb;
|
|
|
|
newItem->lowerItem = lastInserted->lowerItem;
|
|
|
|
newItem->upperItem = lastInserted;
|
|
|
|
if (lastInserted->lowerItem)
|
|
|
|
lastInserted->lowerItem->upperItem = newItem;
|
|
|
|
lastInserted->lowerItem = newItem;
|
|
|
|
|
|
|
|
if(lastInserted == fBottomItem){
|
|
|
|
fBottomItem = newItem;
|
|
|
|
}
|
|
|
|
|
|
|
|
lastInserted = newItem;
|
|
|
|
}
|
|
|
|
preferred = finalPreferred;
|
|
|
|
}
|
|
|
|
else if(prefFeel == B_MODAL_ALL_WINDOW_FEEL
|
|
|
|
|| prefFeel == B_SYSTEM_FIRST)
|
|
|
|
{
|
2004-01-13 04:03:29 +03:00
|
|
|
STRACE((" MODAL ALL/SYSTEM FIRST Window '%s'\n", preferred? preferred->GetName(): "NULL"));
|
2004-01-12 01:12:55 +03:00
|
|
|
// remove all application's floating windows.
|
2004-01-13 04:03:29 +03:00
|
|
|
if (fFrontItem && fFrontItem->layerPtr->_level == B_NORMAL_FEEL)
|
2004-01-12 01:12:55 +03:00
|
|
|
{
|
|
|
|
ListData *listItem = fFrontItem->lowerItem;
|
|
|
|
while(listItem &&
|
2004-01-13 04:03:29 +03:00
|
|
|
(listItem->layerPtr->_level == B_FLOATING_SUBSET_FEEL
|
|
|
|
|| listItem->layerPtr->_level == B_FLOATING_APP_FEEL))
|
2004-01-12 01:12:55 +03:00
|
|
|
{
|
|
|
|
// *carefully* remove the item from the list
|
|
|
|
ListData *item = listItem;
|
|
|
|
listItem = listItem->lowerItem;
|
|
|
|
RemoveItem(item);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if(prefFeel == B_SYSTEM_LAST){
|
|
|
|
; // Do Nothing.
|
|
|
|
}
|
|
|
|
else{
|
|
|
|
// We ***should NOT*** reach this point!
|
2004-01-21 05:58:39 +03:00
|
|
|
STRACE(("SERVER: PANIC: \"%s\": What kind of window is this???\n", preferred? preferred->GetName(): "NULL"));
|
2004-01-12 01:12:55 +03:00
|
|
|
}
|
|
|
|
}
|
2004-01-13 04:03:29 +03:00
|
|
|
else
|
|
|
|
STRACE((" The window IS Hidden\n"));
|
2004-01-12 01:12:55 +03:00
|
|
|
|
2004-01-16 19:09:36 +03:00
|
|
|
ListData *exFrontItem = fFrontItem;
|
|
|
|
ListData *newFrontItem = NULL;
|
2004-01-17 19:33:22 +03:00
|
|
|
if(preferred && fBottomItem){
|
2004-01-13 04:03:29 +03:00
|
|
|
int32 feel = fBottomItem->layerPtr->Window()->Feel();
|
2004-01-12 01:12:55 +03:00
|
|
|
|
|
|
|
// if preferred is one of these *don't* give front state to it!
|
2004-01-13 04:03:29 +03:00
|
|
|
if(preferred->_level == B_FLOATING_SUBSET_FEEL
|
|
|
|
|| preferred->_level == B_FLOATING_APP_FEEL
|
|
|
|
|| preferred->_level == B_FLOATING_ALL_FEEL)
|
2004-01-16 19:09:36 +03:00
|
|
|
{
|
|
|
|
newFrontItem = exFrontItem;
|
|
|
|
}
|
2004-01-12 01:12:55 +03:00
|
|
|
// if the last in workspace's list is one of these, GIVE focus to it!
|
2004-01-13 04:03:29 +03:00
|
|
|
else if((feel == B_SYSTEM_FIRST || feel == B_MODAL_ALL_WINDOW_FEEL)
|
|
|
|
&& !(fBottomItem->layerPtr->IsHidden()) )
|
|
|
|
{
|
|
|
|
newFrontItem = fBottomItem;
|
2004-01-12 01:12:55 +03:00
|
|
|
}
|
|
|
|
// the SYSTEM_LAST will get the front status, only if it's the only
|
|
|
|
// WinBorder in this workspace.
|
2004-01-13 04:03:29 +03:00
|
|
|
else if (preferred->_level == B_SYSTEM_LAST
|
|
|
|
&& !(preferred->IsHidden()) )
|
|
|
|
{
|
2004-01-12 01:12:55 +03:00
|
|
|
if(fBottomItem->layerPtr == preferred)
|
2004-01-13 04:03:29 +03:00
|
|
|
newFrontItem = HasItem(preferred);
|
2004-01-12 01:12:55 +03:00
|
|
|
}
|
|
|
|
// this is in case of MODAL[APP/SUBSET] and NORMAL windows
|
2004-01-13 04:03:29 +03:00
|
|
|
else if ( !(preferred->IsHidden()) ){
|
|
|
|
newFrontItem = HasItem(preferred);
|
|
|
|
}
|
2004-01-12 01:12:55 +03:00
|
|
|
else{
|
2004-01-13 04:03:29 +03:00
|
|
|
newFrontItem = NULL;
|
2004-01-12 01:12:55 +03:00
|
|
|
}
|
|
|
|
}
|
2004-01-13 04:03:29 +03:00
|
|
|
else{ newFrontItem = NULL; }
|
|
|
|
|
|
|
|
if (fFrontItem != newFrontItem){
|
|
|
|
fFrontItem = newFrontItem;
|
|
|
|
// TODO: call a method like... WinBorder::MakeFront(true);
|
|
|
|
}
|
|
|
|
opLock.Unlock();
|
|
|
|
STRACE(("#WS(%ld)::SASNF(%s) ENDED! Workspace data...", ID(), preferred? preferred->GetName(): "NULL"));
|
|
|
|
STRACESTREAM();
|
2004-01-12 01:12:55 +03:00
|
|
|
}
|
|
|
|
/* This method performs a simple opperation. It searched the new focus window
|
|
|
|
* by walking from front to back, cheking for some things, until all variables
|
|
|
|
* correspond.
|
|
|
|
*/
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
void Workspace::SearchAndSetNewFocus(WinBorder* preferred){
|
2004-01-17 19:33:22 +03:00
|
|
|
STRACE(("*WS(%ld)::SASNFocus(%s)\n", ID(), preferred? preferred->GetName(): "NULL"));
|
2004-01-13 04:03:29 +03:00
|
|
|
opLock.Lock();
|
|
|
|
|
|
|
|
if(!preferred)
|
|
|
|
preferred = fBottomItem? fBottomItem->layerPtr : NULL;
|
|
|
|
|
|
|
|
bool selectOthers = false;
|
2004-01-12 01:12:55 +03:00
|
|
|
ListData *item = NULL;
|
2004-01-14 03:26:15 +03:00
|
|
|
|
2004-01-12 01:12:55 +03:00
|
|
|
for(item = fBottomItem; item != NULL; item = item->upperItem){
|
|
|
|
// if this WinBorder doesn't want to have focus... get to the next one
|
2004-01-13 04:03:29 +03:00
|
|
|
if (item->layerPtr->Window()->Flags() & B_AVOID_FOCUS)
|
2004-01-12 01:12:55 +03:00
|
|
|
continue;
|
2004-01-13 04:03:29 +03:00
|
|
|
|
2004-01-14 03:26:15 +03:00
|
|
|
if (preferred && item->layerPtr == preferred){
|
2004-01-13 04:03:29 +03:00
|
|
|
// our preffered one is hidden so... select another one
|
|
|
|
if (preferred && preferred->IsHidden()){
|
|
|
|
selectOthers = true;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
else{
|
|
|
|
break;
|
|
|
|
}
|
2004-01-14 03:26:15 +03:00
|
|
|
}
|
2004-01-13 04:03:29 +03:00
|
|
|
|
2004-01-14 03:26:15 +03:00
|
|
|
if (item->layerPtr->_level == B_SYSTEM_FIRST || item->layerPtr->_level == B_MODAL_ALL_FEEL)
|
|
|
|
{
|
2004-01-12 01:12:55 +03:00
|
|
|
break;
|
2004-01-14 03:26:15 +03:00
|
|
|
}
|
2004-01-13 04:03:29 +03:00
|
|
|
|
2004-01-14 03:26:15 +03:00
|
|
|
if (item->layerPtr->_level == B_MODAL_APP_FEEL
|
|
|
|
&& (preferred && preferred->Window()->ClientTeamID() == item->layerPtr->Window()->ClientTeamID()))
|
2004-01-12 01:12:55 +03:00
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
2004-01-14 03:26:15 +03:00
|
|
|
|
|
|
|
if (item->layerPtr->_level == B_MODAL_SUBSET_FEEL
|
|
|
|
&& (preferred && item->layerPtr->MainWinBorder() == preferred))
|
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
// select one window, other than a system_last one!
|
|
|
|
if (selectOthers && item->layerPtr->_level != B_SYSTEM_LAST){
|
|
|
|
break;
|
|
|
|
}
|
2004-01-12 01:12:55 +03:00
|
|
|
}
|
2004-01-13 04:03:29 +03:00
|
|
|
|
|
|
|
// there are no windows below us to select. take the one from above us.
|
|
|
|
if(selectOthers && !item){
|
2004-01-14 03:26:15 +03:00
|
|
|
// there HAS to be valid
|
2004-01-13 04:03:29 +03:00
|
|
|
item = HasItem(preferred);
|
|
|
|
if (item)
|
|
|
|
item= item->lowerItem;
|
|
|
|
}
|
|
|
|
|
|
|
|
// there are NO windows in front of us, and no regular window below us
|
|
|
|
// maybe there is a system_last window...
|
|
|
|
if(!item){
|
|
|
|
item = fTopItem;
|
|
|
|
}
|
2004-01-12 01:12:55 +03:00
|
|
|
|
|
|
|
if (item != fFocusItem){
|
|
|
|
// TODO: item->ColorTabInGrey & send message to client
|
|
|
|
// TODO: item->ColorTabInYellow & send message to client
|
|
|
|
// TODO: Rebuild & Redraw.
|
|
|
|
fFocusItem = item;
|
|
|
|
}
|
2004-01-13 04:03:29 +03:00
|
|
|
|
|
|
|
opLock.Unlock();
|
2004-01-12 01:12:55 +03:00
|
|
|
}
|
2004-01-17 19:33:22 +03:00
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
void Workspace::BringToFrontANormalWindow(WinBorder* layer){
|
|
|
|
switch (layer->Window()->Feel()){
|
|
|
|
case B_FLOATING_SUBSET_WINDOW_FEEL:
|
|
|
|
case B_MODAL_SUBSET_WINDOW_FEEL:{
|
|
|
|
SearchAndSetNewFront(layer->MainWinBorder());
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case B_FLOATING_APP_WINDOW_FEEL:
|
|
|
|
case B_MODAL_APP_WINDOW_FEEL:{
|
|
|
|
opLock.Lock();
|
|
|
|
ListData *item = fBottomItem;
|
|
|
|
team_id tid = layer->Window()->ClientTeamID();
|
|
|
|
while(item){
|
|
|
|
if(item->layerPtr->Window()->ClientTeamID() == tid
|
|
|
|
&& item->layerPtr->Window()->Feel() == B_NORMAL_WINDOW_FEEL)
|
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
item = item->upperItem;
|
|
|
|
}
|
|
|
|
if(item){
|
|
|
|
SearchAndSetNewFront(item->layerPtr);
|
|
|
|
}
|
|
|
|
opLock.Unlock();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
default:{
|
|
|
|
// in case of MODAL/FLOATING_ALL or _NORMAL_ or SYSTEM_FIRST/LAST do nothing!
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2004-01-12 01:12:55 +03:00
|
|
|
/* The method moves a window to the back of its subset.
|
|
|
|
*/
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
void Workspace::MoveToBack(WinBorder* newLast){
|
|
|
|
STRACE(("\n!MoveToBack(%s) -", newLast? newLast->GetName(): "NULL"));
|
|
|
|
// does the list have this element?
|
|
|
|
ListData *item = HasItem(newLast);
|
|
|
|
if(item){
|
|
|
|
ListData *listItem = NULL;
|
|
|
|
|
2004-01-13 04:03:29 +03:00
|
|
|
switch(item->layerPtr->_level){
|
2004-01-12 01:12:55 +03:00
|
|
|
case B_FLOATING_ALL_FEEL:{
|
|
|
|
STRACE((" B_FLOATING_ALL_FEEL window\n"));
|
|
|
|
// search the place where we should insert it later
|
|
|
|
listItem = item->upperItem;
|
2004-01-13 04:03:29 +03:00
|
|
|
while(listItem && (listItem->layerPtr->_level == item->layerPtr->_level))
|
2004-01-12 01:12:55 +03:00
|
|
|
listItem = listItem->upperItem;
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
// those 2 flags form a 'virtual' set, so even if FLOATING_APP
|
|
|
|
// has a greater priority than FLOATING_SUBSET, it is still moved
|
|
|
|
// behind FLOATING_SUBSET.
|
|
|
|
case B_FLOATING_SUBSET_FEEL:
|
|
|
|
case B_FLOATING_APP_FEEL:{
|
|
|
|
STRACE((" B_FLOATING_SUBSET_FEEL/B_FLOATING_APP_FEEL window\n"));
|
|
|
|
// search the place where we should insert it later
|
|
|
|
listItem = item->upperItem;
|
|
|
|
while(listItem &&
|
2004-01-13 04:03:29 +03:00
|
|
|
(listItem->layerPtr->_level == B_FLOATING_SUBSET_FEEL
|
|
|
|
|| listItem->layerPtr->_level == B_FLOATING_APP_FEEL))
|
2004-01-12 01:12:55 +03:00
|
|
|
listItem = listItem->upperItem;
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
// the same like with floating window. Those 2 and NORMAL form a'virtual' set.
|
|
|
|
case B_MODAL_SUBSET_FEEL:
|
|
|
|
case B_MODAL_APP_FEEL:{
|
|
|
|
STRACE((" B_MODAL_SUBSET_FEEL/B_MODAL_APP_FEEL window\n"));
|
|
|
|
// search the place where we should insert it later
|
|
|
|
listItem = item->upperItem;
|
|
|
|
while(listItem &&
|
2004-01-13 04:03:29 +03:00
|
|
|
(listItem->layerPtr->_level == B_MODAL_SUBSET_FEEL
|
|
|
|
|| listItem->layerPtr->_level == B_MODAL_APP_FEEL
|
|
|
|
|| listItem->layerPtr->_level == B_NORMAL_FEEL))
|
2004-01-12 01:12:55 +03:00
|
|
|
listItem = listItem->upperItem;
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
// here is the simplest, we use the priority levels.
|
|
|
|
case B_NORMAL_FEEL:{
|
|
|
|
STRACE((" B_NORMAL_FEEL window\n"));
|
|
|
|
listItem = item->upperItem;
|
2004-01-13 04:03:29 +03:00
|
|
|
while(listItem && (listItem->layerPtr->_level >= item->layerPtr->_level)){
|
2004-01-12 01:12:55 +03:00
|
|
|
listItem = listItem->upperItem;
|
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((listItem && item->lowerItem == listItem->lowerItem)
|
|
|
|
|| (listItem == NULL && item == fTopItem))
|
|
|
|
{
|
|
|
|
// do nothing! The window will be in the same position it is now.
|
|
|
|
}
|
|
|
|
else{
|
|
|
|
// if it's a normal window, first remove any floating windows,
|
|
|
|
// it or its application has
|
2004-01-13 04:03:29 +03:00
|
|
|
if(newLast->_level == B_NORMAL_FEEL && fFrontItem->layerPtr == newLast){
|
2004-01-12 01:12:55 +03:00
|
|
|
ListData *iter = item->lowerItem;
|
|
|
|
while(iter &&
|
2004-01-13 04:03:29 +03:00
|
|
|
(iter->layerPtr->_level == B_FLOATING_SUBSET_FEEL
|
|
|
|
|| iter->layerPtr->_level == B_FLOATING_APP_FEEL))
|
2004-01-12 01:12:55 +03:00
|
|
|
{
|
|
|
|
// *carefully* remove the item from the list
|
|
|
|
ListData *itemX = iter;
|
|
|
|
iter = iter->lowerItem;
|
|
|
|
RemoveItem(itemX);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
WinBorder *nextPreferred = item->upperItem? item->upperItem->layerPtr: NULL;
|
|
|
|
bool wasFront = fFrontItem->layerPtr == newLast;
|
|
|
|
bool wasFocus = fFocusItem->layerPtr == newLast;
|
|
|
|
// remove item
|
|
|
|
RemoveItem(item);
|
|
|
|
// insert in the new, right' position.
|
|
|
|
InsertItem(item, listItem? listItem->lowerItem: fTopItem);
|
|
|
|
|
|
|
|
if (wasFront)
|
|
|
|
SearchAndSetNewFront(nextPreferred);
|
|
|
|
if (wasFocus)
|
|
|
|
SearchAndSetNewFocus(nextPreferred);
|
|
|
|
}
|
|
|
|
STRACESTREAM();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
STRACE((" this operation was not needed\n"));
|
|
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
void Workspace::SetLocalSpace(const uint32 colorspace){
|
|
|
|
fSpace = colorspace;
|
|
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
uint32 Workspace::LocalSpace() const{
|
|
|
|
return fSpace;
|
|
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
void Workspace::SetBGColor(const RGBColor &c){
|
|
|
|
fBGColor = c;
|
|
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
RGBColor Workspace::BGColor(void) const{
|
|
|
|
return fBGColor;
|
|
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
// Debug methods!!!
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
void Workspace::PrintToStream() const{
|
2004-01-13 04:03:29 +03:00
|
|
|
printf("\nWorkspace %ld hierarchy shown from back to front:\n", fID);
|
2004-01-12 01:12:55 +03:00
|
|
|
for (ListData *item = fTopItem; item != NULL; item = item->lowerItem){
|
|
|
|
WinBorder *wb = (WinBorder*)item->layerPtr;
|
|
|
|
printf("\tName: %s\t%s", wb->GetName(), wb->IsHidden()?"Hidden\t": "NOT Hidden");
|
2004-01-13 04:03:29 +03:00
|
|
|
if (wb->Window()->Feel() == B_FLOATING_SUBSET_WINDOW_FEEL)
|
2004-01-12 01:12:55 +03:00
|
|
|
printf("\t%s\n", "B_FLOATING_SUBSET_WINDOW_FEEL");
|
2004-01-13 04:03:29 +03:00
|
|
|
if (wb->Window()->Feel() == B_FLOATING_APP_WINDOW_FEEL)
|
2004-01-12 01:12:55 +03:00
|
|
|
printf("\t%s\n", "B_FLOATING_APP_WINDOW_FEEL");
|
2004-01-13 04:03:29 +03:00
|
|
|
if (wb->Window()->Feel() == B_FLOATING_ALL_WINDOW_FEEL)
|
2004-01-12 01:12:55 +03:00
|
|
|
printf("\t%s\n", "B_FLOATING_ALL_WINDOW_FEEL");
|
2004-01-13 04:03:29 +03:00
|
|
|
if (wb->Window()->Feel() == B_MODAL_SUBSET_WINDOW_FEEL)
|
2004-01-12 01:12:55 +03:00
|
|
|
printf("\t%s\n", "B_MODAL_SUBSET_WINDOW_FEEL");
|
2004-01-13 04:03:29 +03:00
|
|
|
if (wb->Window()->Feel() == B_MODAL_APP_WINDOW_FEEL)
|
2004-01-12 01:12:55 +03:00
|
|
|
printf("\t%s\n", "B_MODAL_APP_WINDOW_FEEL");
|
2004-01-13 04:03:29 +03:00
|
|
|
if (wb->Window()->Feel() == B_MODAL_ALL_WINDOW_FEEL)
|
2004-01-12 01:12:55 +03:00
|
|
|
printf("\t%s\n", "B_MODAL_ALL_WINDOW_FEEL");
|
2004-01-13 04:03:29 +03:00
|
|
|
if (wb->Window()->Feel() == B_NORMAL_WINDOW_FEEL)
|
2004-01-12 01:12:55 +03:00
|
|
|
printf("\t%s\n", "B_NORMAL_WINDOW_FEEL");
|
2004-01-13 04:03:29 +03:00
|
|
|
if (wb->Window()->Feel() == B_SYSTEM_LAST)
|
2004-01-12 01:12:55 +03:00
|
|
|
printf("\t%s\n", "B_SYSTEM_LAST");
|
2004-01-13 04:03:29 +03:00
|
|
|
if (wb->Window()->Feel() == B_SYSTEM_FIRST)
|
2004-01-12 01:12:55 +03:00
|
|
|
printf("\t%s\n", "B_SYSTEM_FIRST");
|
|
|
|
}
|
|
|
|
printf("Focus Layer:\t%s\n", fFocusItem? fFocusItem->layerPtr->GetName(): "NULL");
|
|
|
|
printf("Front Layer:\t%s\n", fFrontItem? fFrontItem->layerPtr->GetName(): "NULL");
|
|
|
|
// printf("Current Layer:\t%s\n", fCurrentItem? fCurrentItem->layerPtr->GetName(): "NULL");
|
|
|
|
// printf("Top Layer:\t%s\n", fTopItem? fTopItem->layerPtr->GetName(): "NULL");
|
|
|
|
// printf("Bottom Layer:\t%s\n", fBottomItem? fBottomItem->layerPtr->GetName(): "NULL");
|
|
|
|
}
|
2004-01-13 04:03:29 +03:00
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
void Workspace::PrintItem(ListData *item) const{
|
|
|
|
printf("ListData members:\n");
|
|
|
|
if (item){
|
|
|
|
printf("WinBorder:\t%s\n", item->layerPtr? item->layerPtr->GetName(): "NULL");
|
|
|
|
printf("UpperItem:\t%s\n", item->upperItem? item->upperItem->layerPtr->GetName(): "NULL");
|
|
|
|
printf("LowerItem:\t%s\n", item->lowerItem? item->lowerItem->layerPtr->GetName(): "NULL");
|
|
|
|
}
|
|
|
|
else{
|
|
|
|
printf("NULL item!!!\n");
|
|
|
|
}
|
|
|
|
}
|