xref: /haiku/src/servers/app/WindowList.cpp (revision d689f4578d9eacc7a45260e7d223e7fca53f1d7c)
1 /*
2  * Copyright (c) 2005-2008, Haiku, Inc.
3  * Distributed under the terms of the MIT license.
4  *
5  * Authors:
6  *		Axel Dörfler, axeld@pinc-software.de
7  */
8 
9 
10 #include "DesktopSettings.h"
11 #include "Window.h"
12 
13 
14 const BPoint kInvalidWindowPosition = BPoint(INFINITY, INFINITY);
15 
16 
window_anchor()17 window_anchor::window_anchor()
18 	 :
19 	 next(NULL),
20 	 previous(NULL),
21 	 position(kInvalidWindowPosition)
22 {
23 }
24 
25 
26 //	#pragma mark -
27 
28 
WindowList(int32 index)29 WindowList::WindowList(int32 index)
30 	:
31 	fIndex(index),
32 	fFirstWindow(NULL),
33 	fLastWindow(NULL)
34 {
35 }
36 
37 
~WindowList()38 WindowList::~WindowList()
39 {
40 }
41 
42 
43 void
SetIndex(int32 index)44 WindowList::SetIndex(int32 index)
45 {
46 	fIndex = index;
47 }
48 
49 
50 /*!
51 	Adds the \a window to the end of the list. If \a before is
52 	given, it will be inserted right before that window.
53 */
54 void
AddWindow(Window * window,Window * before)55 WindowList::AddWindow(Window* window, Window* before)
56 {
57 	window_anchor& windowAnchor = window->Anchor(fIndex);
58 
59 	if (before != NULL) {
60 		window_anchor& beforeAnchor = before->Anchor(fIndex);
61 
62 		// add view before this one
63 		windowAnchor.next = before;
64 		windowAnchor.previous = beforeAnchor.previous;
65 		if (windowAnchor.previous != NULL)
66 			windowAnchor.previous->Anchor(fIndex).next = window;
67 
68 		beforeAnchor.previous = window;
69 		if (fFirstWindow == before)
70 			fFirstWindow = window;
71 	} else {
72 		// add view to the end of the list
73 		if (fLastWindow != NULL) {
74 			fLastWindow->Anchor(fIndex).next = window;
75 			windowAnchor.previous = fLastWindow;
76 		} else {
77 			fFirstWindow = window;
78 			windowAnchor.previous = NULL;
79 		}
80 
81 		windowAnchor.next = NULL;
82 		fLastWindow = window;
83 	}
84 
85 	if (fIndex < kMaxWorkspaces)
86 		window->SetWorkspaces(window->Workspaces() | (1UL << fIndex));
87 }
88 
89 
90 void
RemoveWindow(Window * window)91 WindowList::RemoveWindow(Window* window)
92 {
93 	window_anchor& windowAnchor = window->Anchor(fIndex);
94 
95 	if (fFirstWindow == window) {
96 		// it's the first child
97 		fFirstWindow = windowAnchor.next;
98 	} else {
99 		// it must have a previous sibling, then
100 		windowAnchor.previous->Anchor(fIndex).next = windowAnchor.next;
101 	}
102 
103 	if (fLastWindow == window) {
104 		// it's the last child
105 		fLastWindow = windowAnchor.previous;
106 	} else {
107 		// then it must have a next sibling
108 		windowAnchor.next->Anchor(fIndex).previous = windowAnchor.previous;
109 	}
110 
111 	if (fIndex < kMaxWorkspaces)
112 		window->SetWorkspaces(window->Workspaces() & ~(1UL << fIndex));
113 
114 	windowAnchor.previous = NULL;
115 	windowAnchor.next = NULL;
116 }
117 
118 
119 bool
HasWindow(Window * window) const120 WindowList::HasWindow(Window* window) const
121 {
122 	if (window == NULL)
123 		return false;
124 
125 	return window->Anchor(fIndex).next != NULL
126 		|| window->Anchor(fIndex).previous != NULL
127 		|| fFirstWindow == window
128 		|| fLastWindow == window;
129 }
130 
131 
132 /*!	Unlike HasWindow(), this will not reference the window pointer. You
133 	can use this method to check whether or not a window is still part
134 	of a list (when it's possible that the window is already gone).
135 */
136 bool
ValidateWindow(Window * validateWindow) const137 WindowList::ValidateWindow(Window* validateWindow) const
138 {
139 	for (Window *window = FirstWindow(); window != NULL;
140 			window = window->NextWindow(fIndex)) {
141 		if (window == validateWindow)
142 			return true;
143 	}
144 
145 	return false;
146 }
147 
148 
149 int32
Count() const150 WindowList::Count() const
151 {
152 	int32 count = 0;
153 
154 	for (Window *window = FirstWindow(); window != NULL;
155 			window = window->NextWindow(fIndex)) {
156 		count++;
157 	}
158 
159 	return count;
160 }
161