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