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
14const BPoint kInvalidWindowPosition = BPoint(INFINITY, INFINITY);
15
16
17window_anchor::window_anchor()
18	 :
19	 next(NULL),
20	 previous(NULL),
21	 position(kInvalidWindowPosition)
22{
23}
24
25
26//	#pragma mark -
27
28
29WindowList::WindowList(int32 index)
30	:
31	fIndex(index),
32	fFirstWindow(NULL),
33	fLastWindow(NULL)
34{
35}
36
37
38WindowList::~WindowList()
39{
40}
41
42
43void
44WindowList::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*/
54void
55WindowList::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
90void
91WindowList::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
119bool
120WindowList::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*/
136bool
137WindowList::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
149int32
150WindowList::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