2 * Copyright 2011, Axel Dörfler, axeld@pinc-software.de.
3 * Distributed under the terms of the MIT License.
7 #include "WindowsView.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"
24 static const uint32 kMsgActivateWindow
= 'AcWn';
27 class WindowModel
: public GroupListModel
{
29 WindowModel(team_id team
)
35 // TODO: more than one team via signature!
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
)) {
46 fWorkspaces
|= info
->workspaces
;
47 fWindows
.AddItem(info
);
51 for (uint32 i
= 0; i
< 32; i
++) {
52 if ((fWorkspaces
& (1UL << i
)) != 0)
56 fWindows
.SortItems(&_CompareWindowInfo
);
59 virtual ~WindowModel()
63 void BringToFront(int32 index
)
65 client_window_info
* info
= fWindows
.ItemAt(index
);
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
);
79 BMessenger::Private(window
).SetTo(info
->team
, info
->client_port
,
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);
111 bool _WindowShouldBeListed(client_window_info
* info
)
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) {
130 static int _CompareWindowInfo(const client_window_info
* a
,
131 const client_window_info
* b
)
133 return strcasecmp(a
->name
, b
->name
);
137 BObjectList
<client_window_info
> fWindows
;
139 int32 fWorkspaceCount
;
143 class StringItemRenderer
: public ListItemRenderer
{
149 virtual ~StringItemRenderer()
153 void SetText(BView
* owner
, const BString
& 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
);
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
)
175 virtual void SetHeight(int32 height
)
180 virtual void SetBaselineOffset(int32 offset
)
182 fBaselineOffset
= offset
;
185 const BString
& Text() const
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
);
216 int32 fBaselineOffset
;
220 class WorkspaceRenderer
: public StringItemRenderer
{
222 virtual void SetTo(BView
* owner
, void* item
)
224 fWorkspace
= (uint32
)item
;
226 if ((uint32
)current_workspace() == fWorkspace
- 1)
227 SetText(owner
, "Current workspace");
229 BString
text("Workspace ");
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);
246 class WindowRenderer
: public StringItemRenderer
{
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);
263 StringItemRenderer::Draw(owner
, frame
, index
, selected
);
267 client_window_info
* fInfo
;
274 WindowsView::WindowsView(team_id team
, uint32 location
)
279 be_roster
->GetRunningAppInfo(team
, &info
);
281 LaunchButton
* launchButton
= new LaunchButton(info
.signature
, NULL
, NULL
,
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)
303 .Add(fListView
, 2, 0);
305 BLayoutBuilder::Grid
<>(this)
306 .Add(launchButton
, 0, 0)
308 .Add(fListView
, 0, 1, 2);
313 WindowsView::~WindowsView()
319 WindowsView::AttachedToWindow()
321 fListView
->SetSelectionMessage(new BMessage(kMsgActivateWindow
), this);
326 WindowsView::MessageReceived(BMessage
* message
)
328 switch (message
->what
) {
329 case kMsgActivateWindow
:
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
)
339 model
->BringToFront(index
);
345 BGridView::MessageReceived(message
);
352 WindowsView::_Orientation(uint32 location
)
354 return (location
& (kTopEdge
| kBottomEdge
)) != 0
355 ? B_HORIZONTAL
: B_VERTICAL
;