BTRFS: Implement BTree::Path and change _Find.
[haiku.git] / src / apps / switcher / WindowsView.cpp
blob2ecc499ca41a48314f8942e4e055482317c30477
1 /*
2 * Copyright 2011, Axel Dörfler, axeld@pinc-software.de.
3 * Distributed under the terms of the MIT License.
4 */
7 #include "WindowsView.h"
9 #include <stdlib.h>
11 #include <LayoutBuilder.h>
12 #include <ObjectList.h>
13 #include <StringView.h>
15 #include <MessengerPrivate.h>
16 #include <WindowInfo.h>
17 #include <WindowPrivate.h>
19 #include "GroupListView.h"
20 #include "LaunchButton.h"
21 #include "Switcher.h"
24 static const uint32 kMsgActivateWindow = 'AcWn';
27 class WindowModel : public GroupListModel {
28 public:
29 WindowModel(team_id team)
31 fWindows(true),
32 fWorkspaces(0),
33 fWorkspaceCount(0)
35 // TODO: more than one team via signature!
36 int32 count;
37 int32* tokens = get_token_list(team, &count);
39 for (int32 i = 0; i < count; i++) {
40 client_window_info* info = get_window_info(tokens[i]);
41 if (!_WindowShouldBeListed(info)) {
42 free(info);
43 continue;
46 fWorkspaces |= info->workspaces;
47 fWindows.AddItem(info);
49 free(tokens);
51 for (uint32 i = 0; i < 32; i++) {
52 if ((fWorkspaces & (1UL << i)) != 0)
53 fWorkspaceCount++;
56 fWindows.SortItems(&_CompareWindowInfo);
59 virtual ~WindowModel()
63 void BringToFront(int32 index)
65 client_window_info* info = fWindows.ItemAt(index);
66 if (info == NULL)
67 return;
69 do_window_action(info->server_token, B_BRING_TO_FRONT, BRect(), false);
72 void Close(int32 index)
74 client_window_info* info = fWindows.ItemAt(index);
75 if (info == NULL)
76 return;
78 BMessenger window;
79 BMessenger::Private(window).SetTo(info->team, info->client_port,
80 info->client_token);
81 window.SendMessage(B_QUIT_REQUESTED);
84 virtual int32 CountItems()
86 return fWindows.CountItems();
89 virtual void* ItemAt(int32 index)
91 return fWindows.ItemAt(index);
94 virtual int32 CountGroups()
96 return fWorkspaceCount;
99 virtual void* GroupAt(int32 index)
101 return (void*)(_NthSetBit(index, fWorkspaces) + 1);
104 virtual void* GroupForItemAt(int32 index)
106 client_window_info* info = fWindows.ItemAt(index);
107 return (void*)(_NthSetBit(0, info->workspaces) + 1);
110 private:
111 bool _WindowShouldBeListed(client_window_info* info)
113 return info != NULL
114 && (info->feel == B_NORMAL_WINDOW_FEEL
115 || info->feel == kWindowScreenFeel)
116 && (info->show_hide_level <= 0 || info->is_mini);
119 int32 _NthSetBit(int32 index, uint32 mask)
121 for (uint32 i = 0; i < 32; i++) {
122 if ((mask & (1UL << i)) != 0) {
123 if (index-- == 0)
124 return i;
127 return 0;
130 static int _CompareWindowInfo(const client_window_info* a,
131 const client_window_info* b)
133 return strcasecmp(a->name, b->name);
136 private:
137 BObjectList<client_window_info> fWindows;
138 uint32 fWorkspaces;
139 int32 fWorkspaceCount;
143 class StringItemRenderer : public ListItemRenderer {
144 public:
145 StringItemRenderer()
149 virtual ~StringItemRenderer()
153 void SetText(BView* owner, const BString& text)
155 fText = text;
156 owner->TruncateString(&fText, B_TRUNCATE_MIDDLE, 200);
157 SetWidth((int32)ceilf(owner->StringWidth(fText.String())));
159 font_height fontHeight;
160 owner->GetFontHeight(&fontHeight);
162 SetBaselineOffset(
163 2 + (int32)ceilf(fontHeight.ascent + fontHeight.leading / 2));
165 SetHeight((int32)ceilf(fontHeight.ascent)
166 + (int32)ceilf(fontHeight.descent)
167 + (int32)ceilf(fontHeight.leading) + 4);
170 virtual void SetWidth(int32 width)
172 fWidth = width;
175 virtual void SetHeight(int32 height)
177 fHeight = height;
180 virtual void SetBaselineOffset(int32 offset)
182 fBaselineOffset = offset;
185 const BString& Text() const
187 return fText;
190 virtual BSize MinSize()
192 return BSize(fWidth, fHeight);
195 virtual BSize MaxSize()
197 return BSize(B_SIZE_UNLIMITED, fHeight);
200 virtual BSize PreferredSize()
202 return BSize(fWidth, fHeight);
205 virtual void Draw(BView* owner, BRect frame, int32 index, bool selected)
207 owner->SetLowColor(owner->ViewColor());
208 owner->MovePenTo(frame.left, frame.top + fBaselineOffset);
209 owner->DrawString(fText);
212 private:
213 BString fText;
214 int32 fWidth;
215 int32 fHeight;
216 int32 fBaselineOffset;
220 class WorkspaceRenderer : public StringItemRenderer {
221 public:
222 virtual void SetTo(BView* owner, void* item)
224 fWorkspace = (uint32)item;
226 if ((uint32)current_workspace() == fWorkspace - 1)
227 SetText(owner, "Current workspace");
228 else {
229 BString text("Workspace ");
230 text << fWorkspace;
231 SetText(owner, text);
235 virtual void Draw(BView* owner, BRect frame, int32 index, bool selected)
237 owner->SetHighColor(tint_color(owner->ViewColor(), B_DARKEN_2_TINT));
238 StringItemRenderer::Draw(owner, frame, index, false);
241 private:
242 uint32 fWorkspace;
246 class WindowRenderer : public StringItemRenderer {
247 public:
248 virtual void SetTo(BView* owner, void* item)
250 fInfo = (client_window_info*)item;
251 SetText(owner, fInfo->name);
254 virtual void SetWidth(int32 width)
256 StringItemRenderer::SetWidth(width + 20);
259 virtual void Draw(BView* owner, BRect frame, int32 index, bool selected)
261 owner->SetHighColor(0, 0, 0);
262 frame.left += 20;
263 StringItemRenderer::Draw(owner, frame, index, selected);
266 private:
267 client_window_info* fInfo;
271 // #pragma mark -
274 WindowsView::WindowsView(team_id team, uint32 location)
276 BGridView("windows")
278 app_info info;
279 be_roster->GetRunningAppInfo(team, &info);
281 LaunchButton* launchButton = new LaunchButton(info.signature, NULL, NULL,
282 this);
283 launchButton->SetTo(&info.ref);
285 BStringView* nameView = new BStringView("name", info.ref.name);
286 BFont font(be_plain_font);
287 font.SetSize(font.Size() * 2);
288 font.SetFace(B_BOLD_FACE);
289 nameView->SetFont(&font);
291 fListView = new GroupListView("list", new WindowModel(team),
292 _Orientation(location));
293 fListView->SetItemRenderer(new WindowRenderer());
294 fListView->SetGroupRenderer(new WorkspaceRenderer());
296 GridLayout()->SetInsets(B_USE_DEFAULT_SPACING, B_USE_DEFAULT_SPACING,
297 B_USE_DEFAULT_SPACING, B_USE_DEFAULT_SPACING);
299 if (_Orientation(location) == B_HORIZONTAL) {
300 BLayoutBuilder::Grid<>(this)
301 .Add(launchButton, 0, 0)
302 .Add(nameView, 1, 0)
303 .Add(fListView, 2, 0);
304 } else {
305 BLayoutBuilder::Grid<>(this)
306 .Add(launchButton, 0, 0)
307 .Add(nameView, 1, 0)
308 .Add(fListView, 0, 1, 2);
313 WindowsView::~WindowsView()
318 void
319 WindowsView::AttachedToWindow()
321 fListView->SetSelectionMessage(new BMessage(kMsgActivateWindow), this);
325 void
326 WindowsView::MessageReceived(BMessage* message)
328 switch (message->what) {
329 case kMsgActivateWindow:
331 int32 index;
332 if (message->FindInt32("index", &index) == B_OK
333 && message->HasPointer("item")) {
334 WindowModel* model = (WindowModel*)fListView->Model();
336 if (message->FindInt32("buttons") == B_SECONDARY_MOUSE_BUTTON)
337 model->Close(index);
338 else
339 model->BringToFront(index);
341 break;
344 default:
345 BGridView::MessageReceived(message);
346 break;
351 orientation
352 WindowsView::_Orientation(uint32 location)
354 return (location & (kTopEdge | kBottomEdge)) != 0
355 ? B_HORIZONTAL : B_VERTICAL;