1 /*
2 * Copyright 2011, Axel Dörfler, axeld@pinc-software.de.
3 * Distributed under the terms of the MIT License.
4 */
5
6
7 #include "PanelWindow.h"
8
9 #include <stdio.h>
10
11 #include <GroupLayout.h>
12 #include <MessageRunner.h>
13 #include <Screen.h>
14
15 #include "ApplicationsView.h"
16 #include "GroupListView.h"
17 #include "Switcher.h"
18 #include "WindowsView.h"
19
20
21 static const uint32 kMsgShow = 'SHOW';
22 static const uint32 kMsgHide = 'HIDE';
23
24 static const int32 kMinShowState = 0;
25 static const int32 kMaxShowState = 4;
26 static const bigtime_t kMoveDelay = 15000;
27 // 25 ms
28
29
PanelWindow(uint32 location,uint32 which,team_id team)30 PanelWindow::PanelWindow(uint32 location, uint32 which, team_id team)
31 :
32 BWindow(BRect(-16000, -16000, -15900, -15900), "panel",
33 B_BORDERED_WINDOW_LOOK, B_FLOATING_ALL_WINDOW_FEEL,
34 B_ASYNCHRONOUS_CONTROLS | B_AUTO_UPDATE_SIZE_LIMITS | B_AVOID_FOCUS,
35 B_ALL_WORKSPACES),
36 fLocation(location),
37 fShowState(kMinShowState)
38 {
39 SetLayout(new BGroupLayout(B_HORIZONTAL));
40
41 BView* child = _ViewFor(location, which, team);
42 if (child != NULL)
43 AddChild(child);
44
45 Run();
46 PostMessage(kMsgShow);
47 }
48
49
~PanelWindow()50 PanelWindow::~PanelWindow()
51 {
52 BMessage message(kMsgLocationFree);
53 message.AddInt32("location", fLocation);
54 be_app->PostMessage(&message);
55 }
56
57
58 void
MessageReceived(BMessage * message)59 PanelWindow::MessageReceived(BMessage* message)
60 {
61 switch (message->what) {
62 case kMsgShow:
63 case kMsgHide:
64 _UpdateShowState(message->what);
65 break;
66
67 default:
68 BWindow::MessageReceived(message);
69 break;
70 }
71 }
72
73
74 BView*
_ViewFor(uint32 location,uint32 which,team_id team) const75 PanelWindow::_ViewFor(uint32 location, uint32 which, team_id team) const
76 {
77 switch (which) {
78 case kShowApplications:
79 return new ApplicationsView(location);
80 case kShowApplicationWindows:
81 return new WindowsView(team, location);
82
83 default:
84 return NULL;
85 }
86 }
87
88
89 void
_UpdateShowState(uint32 how)90 PanelWindow::_UpdateShowState(uint32 how)
91 {
92 if ((how == kMsgShow && fShowState >= kMaxShowState)
93 || (how == kMsgHide && fShowState <= kMinShowState))
94 return;
95
96 fShowState += how == kMsgShow ? 1 : -1;
97
98 // Compute start and end position depending on the location
99 // TODO: multi-screen support
100 BScreen screen;
101 BRect screenFrame = screen.Frame();
102 BPoint from;
103 BPoint to;
104
105 switch (fLocation) {
106 case kLeftEdge:
107 case kRightEdge:
108 from.y = screenFrame.top
109 + (screenFrame.Height() - Bounds().Height()) / 2.f;
110 to.y = from.y;
111 break;
112 case kTopEdge:
113 case kBottomEdge:
114 from.x = screenFrame.left
115 + (screenFrame.Width() - Bounds().Width()) / 2.f;
116 to.x = from.x;
117 break;
118 }
119
120 switch (fLocation) {
121 case kLeftEdge:
122 from.x = screenFrame.left - Bounds().Width();
123 to.x = screenFrame.left;
124 break;
125 case kRightEdge:
126 from.x = screenFrame.right;
127 to.x = screenFrame.right - Bounds().Width();
128 break;
129 case kTopEdge:
130 from.y = screenFrame.top - Bounds().Height();
131 to.y = screenFrame.top;
132 break;
133 case kBottomEdge:
134 from.y = screenFrame.bottom;
135 to.y = screenFrame.bottom - Bounds().Height();
136 break;
137 }
138
139 MoveTo(from.x + _Factor() * (to.x - from.x),
140 from.y + _Factor() * (to.y - from.y));
141
142 if (kMsgShow && IsHidden())
143 Show();
144 else if (fShowState == 0 && kMsgHide && !IsHidden())
145 Quit();
146
147 if ((how == kMsgShow && fShowState < kMaxShowState)
148 || (how == kMsgHide && fShowState > kMinShowState)) {
149 BMessage move(how);
150 BMessageRunner::StartSending(this, &move, kMoveDelay, 1);
151 } else if (how == kMsgShow) {
152 // Hide the window once the mouse left its frame
153 BMessage hide(kMsgHideWhenMouseMovedOut);
154 hide.AddMessenger("target", this);
155 hide.AddInt32("what", kMsgHide);
156
157 // The window might not span over the whole screen, but one dimension
158 // should be ignored for the cursor movements
159 BRect frame = Frame();
160 switch (fLocation) {
161 case kLeftEdge:
162 case kRightEdge:
163 frame.top = screenFrame.top;
164 frame.bottom = screenFrame.bottom;
165 break;
166 case kTopEdge:
167 case kBottomEdge:
168 frame.left = screenFrame.left;
169 frame.right = screenFrame.right;
170 break;
171 }
172 hide.AddRect("frame", frame);
173 be_app->PostMessage(&hide);
174 }
175 }
176
177
178 float
_Factor()179 PanelWindow::_Factor()
180 {
181 float factor = 1.f * fShowState / kMaxShowState;
182 return 1 - (factor - 1) * (factor - 1);
183 }
184