xref: /haiku/src/apps/deskbar/WindowMenu.cpp (revision 3be9edf8da228afd9fec0390f408c964766122aa)
1 /*
2 Open Tracker License
3 
4 Terms and Conditions
5 
6 Copyright (c) 1991-2000, Be Incorporated. All rights reserved.
7 
8 Permission is hereby granted, free of charge, to any person obtaining a copy of
9 this software and associated documentation files (the "Software"), to deal in
10 the Software without restriction, including without limitation the rights to
11 use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
12 of the Software, and to permit persons to whom the Software is furnished to do
13 so, subject to the following conditions:
14 
15 The above copyright notice and this permission notice applies to all licensees
16 and shall be included in all copies or substantial portions of the Software.
17 
18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF TITLE, MERCHANTABILITY,
20 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 BE INCORPORATED BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
22 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF, OR IN CONNECTION
23 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 
25 Except as contained in this notice, the name of Be Incorporated shall not be
26 used in advertising or otherwise to promote the sale, use or other dealings in
27 this Software without prior written authorization from Be Incorporated.
28 
29 Tracker(TM), Be(R), BeOS(R), and BeIA(TM) are trademarks or registered trademarks
30 of Be Incorporated in the United States and other countries. Other brand product
31 names are registered trademarks or trademarks of their respective holders.
32 All rights reserved.
33 */
34 
35 #include <malloc.h>
36 #include <stdio.h>
37 #include <string.h>
38 #include <Window.h>
39 
40 #include "BarApp.h"
41 #include "BarView.h"
42 #include "ExpandoMenuBar.h"
43 #include "ShowHideMenuItem.h"
44 #include "TeamMenu.h"
45 #include "TeamMenuItem.h"
46 #include "WindowMenuItem.h"
47 #include "WindowMenu.h"
48 
49 #include "tracker_private.h"
50 
51 
52 const int32 kDesktopWindow = 1024;
53 const int32 kMenuWindow	= 1025;
54 const uint32 kWindowScreen = 1026;
55 const uint32 kNormalWindow = 0;
56 const int32 kTeamFloater = 4;
57 const int32 kListFloater = 5;
58 const int32 kSystemFloater = 6;
59 
60 
61 bool
62 TWindowMenu::WindowShouldBeListed(uint32 behavior)
63 {
64 	if (behavior == kNormalWindow || behavior == kWindowScreen)
65 		return true;
66 
67 	return false;
68 }
69 
70 
71 TWindowMenu::TWindowMenu(const BList* team, const char* signature)
72 	: BMenu("Deskbar Team Menu"),
73 	fTeam(team),
74 	fApplicationSignature(signature),
75 	fExpanded(false),
76 	fExpandedIndex(0)
77 {
78 	SetItemMargins(0.0f, 0.0f, 0.0f, 0.0f);
79 }
80 
81 
82 void
83 TWindowMenu::AttachedToWindow()
84 {
85 	SetFont(be_plain_font);
86 
87 	RemoveItems(0, CountItems(), true);
88 
89 	int32 miniCount = 0;
90 
91 	bool dragging = false;
92 	TBarView* barview =(static_cast<TBarApp*>(be_app))->BarView();
93 	if (barview && barview->LockLooper()) {
94 		//	'dragging' mode set in BarView::CacheDragData
95 		//		invoke in MouseEnter in ExpandoMenuBar
96 		dragging = barview->Dragging();
97 		if (dragging) {
98 			// We don't want to show the menu when dragging, but it's not
99 			// possible to remove a submenu once it exists, so we simply hide it
100 			// Don't call BMenu::Hide(), it causes the menu to pop up every now
101 			// and then.
102 			Window()->Hide();
103 			//	if in expando (horizontal or vertical)
104 			if (barview->Expando()) {
105 				SetTrackingHook(barview->MenuTrackingHook,
106 					barview->GetTrackingHookData());
107 			}
108 			barview->DragStart();
109 		}
110 		barview->UnlockLooper();
111 	}
112 
113 	int32 parentMenuItems = 0;
114 
115 	int32 numTeams = fTeam->CountItems();
116 	for (int32 i = 0; i < numTeams; i++) {
117 		team_id	theTeam = (team_id)fTeam->ItemAt(i);
118 		int32 count = 0;
119 		int32* tokens = get_token_list(theTeam, &count);
120 
121 		for (int32 j = 0; j < count; j++) {
122 			client_window_info* wInfo = get_window_info(tokens[j]);
123 			if (wInfo == NULL)
124 				continue;
125 
126 			if (WindowShouldBeListed(wInfo->feel)
127 				&& (wInfo->show_hide_level <= 0 || wInfo->is_mini)) {
128 				// Don't add new items if we're expanded. We've already done
129 				// this, they've just been moved.
130 				int32 numItems = CountItems();
131 				int32 addIndex = 0;
132 				for (; addIndex < numItems; addIndex++)
133 					if (strcasecmp(ItemAt(addIndex)->Label(), wInfo->name) > 0)
134 						break;
135 
136 				if (!fExpanded) {
137 					TWindowMenuItem* item = new TWindowMenuItem(wInfo->name,
138 						wInfo->server_token, wInfo->is_mini,
139 						((1 << current_workspace()) & wInfo->workspaces) != 0,
140 						dragging);
141 
142 					// disable app's window dropping for now
143 					if (dragging)
144 						item->SetEnabled(false);
145 
146 					AddItem(item,
147 						TWindowMenuItem::InsertIndexFor(this, 0, item));
148 				} else {
149 					TTeamMenuItem* parentItem
150 						= static_cast<TTeamMenuItem*>(Superitem());
151 					if (parentItem->ExpandedWindowItem(wInfo->server_token)) {
152 						TWindowMenuItem* item = parentItem->ExpandedWindowItem(
153 							wInfo->server_token);
154 						if (item == NULL)
155 							continue;
156 
157 						item->SetTo(wInfo->name, wInfo->server_token,
158 							wInfo->is_mini,
159 							((1 << current_workspace()) & wInfo->workspaces)
160 								!= 0, dragging);
161 						parentMenuItems++;
162 					}
163 				}
164 
165 				if (wInfo->is_mini)
166 					miniCount++;
167 			}
168 			free(wInfo);
169 		}
170 		free(tokens);
171 	}
172 
173 	int32 itemCount = CountItems() + parentMenuItems;
174 	if (itemCount < 1) {
175 		TWindowMenuItem* noWindowsItem =
176  			new TWindowMenuItem("No Windows", -1, false, false);
177 
178 		noWindowsItem->SetEnabled(false);
179 
180 		AddItem(noWindowsItem);
181 
182 		// if an application has no windows, this feature makes it easy to quit
183 		// it. (but we only add this option if the application is not Tracker.)
184  		if (fApplicationSignature.ICompare(kTrackerSignature) != 0) {
185 			AddSeparatorItem();
186 			AddItem(new TShowHideMenuItem("Quit Application", fTeam,
187 				B_QUIT_REQUESTED));
188  		}
189 	} else {
190 		//	if we are in drag mode, then don't add the window controls
191 		//	to the menu
192 		if (!dragging) {
193 			TShowHideMenuItem* hide =
194 				new TShowHideMenuItem("Hide All", fTeam, B_MINIMIZE_WINDOW);
195 			TShowHideMenuItem* show =
196 				new TShowHideMenuItem("Show All", fTeam, B_BRING_TO_FRONT);
197 			TShowHideMenuItem* close =
198 				new TShowHideMenuItem("Close All", fTeam, B_QUIT_REQUESTED);
199 
200 			if (miniCount == itemCount)
201 				hide->SetEnabled(false);
202 			else if (miniCount == 0)
203 				show->SetEnabled(false);
204 
205 			if (!parentMenuItems)
206 				AddSeparatorItem();
207 			AddItem(hide);
208 			AddItem(show);
209 			AddItem(close);
210 		}
211 	}
212 
213 	BMenu::AttachedToWindow();
214 }
215 
216 
217 void
218 TWindowMenu::DetachedFromWindow()
219 {
220 	// in expando mode the teammenu will not call DragStop,
221 	// thus, it needs to be called from here
222 	TBarView* barview = (dynamic_cast<TBarApp*>(be_app))->BarView();
223 	if (barview && barview->Expando() && barview->Dragging()
224 		&& barview->LockLooper()) {
225 		// We changed the show level in AttachedToWindow().  Undo it.
226 		Window()->Show();
227 		barview->DragStop();
228 		barview->UnlockLooper();
229 	}
230 
231 	BMenu::DetachedFromWindow();
232 }
233 
234 
235 BPoint
236 TWindowMenu::ScreenLocation()
237 {
238 	return BMenu::ScreenLocation();
239 }
240 
241 
242 void
243 TWindowMenu::SetExpanded(bool status, int lastIndex)
244 {
245 	fExpanded = status;
246 	fExpandedIndex = lastIndex;
247 }
248 
249