1 //
2 // StickIt
3 // File: JoystickWindow.cpp
4 // Joystick window.
5 // Sampel code used in "Getting a Grip on BJoystick" by Eric Shepherd
6 //
7
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <string.h>
11 #include <OS.h>
12
13 #include <Application.h>
14 #include <Joystick.h>
15 #include <String.h>
16 #include <StringView.h>
17
18 #include "JoystickWindow.h"
19
20 rgb_color rgb_black = {0, 0, 0, 255};
21 rgb_color rgb_red = {255, 0, 0, 255};
22 rgb_color rgb_grey = {216, 216, 216};
23
24 int32 hatX[9] = {10, 10, 20, 20, 20, 10, 0, 0, 0};
25 int32 hatY[9] = {10, 0, 0, 10, 20, 20, 20, 10, 0};
26
JoystickWindow(const char * deviceName,BJoystick * stick,BRect rect)27 JoystickWindow::JoystickWindow(const char *deviceName, BJoystick *stick,
28 BRect rect)
29 : BWindow(rect, deviceName, B_TITLED_WINDOW,
30 B_NOT_RESIZABLE|B_NOT_ZOOMABLE)
31 {
32 fView = new JoystickView(Bounds(), stick);
33 fView->SetViewColor(rgb_grey);
34 fView->SetLowColor(rgb_grey);
35 ResizeTo(fView->Bounds().Width(), fView->Bounds().Height());
36 AddChild(fView);
37 SetPulseRate(100000.0);
38 }
39
40
41 bool
QuitRequested(void)42 JoystickWindow::QuitRequested(void) {
43 return true;
44 }
45
46
JoystickView(BRect frame,BJoystick * stick)47 JoystickView::JoystickView(BRect frame, BJoystick *stick)
48 :BView(frame, "jview", B_FOLLOW_ALL_SIDES, B_WILL_DRAW|B_PULSE_NEEDED),
49 fStick(stick)
50 {
51 // Set up the controls
52 BString name;
53 fStick->GetControllerName(&name);
54 BRect rect(5, 5, 350, 25);
55 BStringView *stickName = new BStringView(rect, "stickname", name.String());
56 stickName->SetFontSize(18);
57 AddChild(stickName);
58
59 rect = _BuildButtons(stick);
60 rect.top += 15;
61 rect.bottom += 15;
62 rect = _BuildHats(stick, rect);
63 _BuildAxes(stick, rect);
64 }
65
66
~JoystickView()67 JoystickView::~JoystickView() {
68 delete fStick;
69 }
70
71
72 void
Pulse(void)73 JoystickView::Pulse(void) {
74 Window()->Lock();
75 Draw(Bounds());
76 Window()->Unlock();
77 }
78
79
80 void
Draw(BRect updateRect)81 JoystickView::Draw(BRect updateRect)
82 {
83 int32 numButtons = fStick->CountButtons();
84 int32 numHats = fStick->CountHats();
85 int32 numAxes = fStick->CountAxes();
86 bool *buttons = (bool *) malloc(sizeof(bool) * numButtons);
87 int16 *axes = (int16 *) malloc(sizeof(int16) * numAxes);
88 uint8 *hats = (uint8 *) malloc(numHats);
89 fStick->Update();
90
91 // Buttons first
92 BRect r(105, 50, 115, 60);
93 fStick->GetButtonValues(buttons);
94 for (int32 i = 0; i < numButtons; i++) {
95 if (buttons[i]) {
96 FillRect(r, B_SOLID_HIGH);
97 } else {
98 r.InsetBy(1, 1);
99 FillRect(r, B_SOLID_LOW);
100 r.InsetBy(-1, -1);
101 StrokeRect(r, B_SOLID_HIGH);
102 }
103 r.top += 18;
104 r.bottom += 18;
105 }
106
107 // Now hats
108 fStick->GetHatValues(hats);
109 r.top += 15;
110 r.bottom = r.top + 30;
111 r.left = 105;
112 r.right = r.left + 30;
113 BRect curHatRect;
114 for (int32 i = 0; i < numHats; i++) {
115 BeginLineArray(8);
116 AddLine(r.LeftTop(), r.RightTop(), rgb_black);
117 AddLine(r.LeftTop(), r.LeftBottom(), rgb_black);
118 AddLine(r.RightTop(), r.RightBottom(), rgb_black);
119 AddLine(r.LeftBottom(), r.RightBottom(), rgb_black);
120 AddLine(BPoint(r.left+10, r.top), BPoint(r.left+10, r.bottom),
121 rgb_black);
122 AddLine(BPoint(r.left+20, r.top), BPoint(r.left+20, r.bottom),
123 rgb_black);
124 AddLine(BPoint(r.left, r.top+10), BPoint(r.right, r.top+10),
125 rgb_black);
126 AddLine(BPoint(r.left, r.top+20), BPoint(r.right, r.top+20),
127 rgb_black);
128 EndLineArray();
129 curHatRect.Set(r.left, r.top, r.left+10, r.top+10);
130 curHatRect.OffsetBy(hatX[hats[i]], hatY[hats[i]]);
131 fLastHatRect.InsetBy(1, 1);
132 FillRect(fLastHatRect, B_SOLID_LOW);
133 fLastHatRect = curHatRect;
134 fLastHatRect.InsetBy(1, 1);
135 FillRect(fLastHatRect, B_SOLID_HIGH);
136 fLastHatRect.InsetBy(-1, -1);
137 r.top += 20;
138 r.bottom += 20;
139 }
140
141 // Now the joystick
142 r.Set(200, 50, 350, 200);
143 FillRect(r, B_SOLID_HIGH);
144 fStick->GetAxisValues(axes);
145 float x = axes[0];
146 float y = axes[1];
147 SetHighColor(rgb_red);
148 x += 32768;
149 y -= 32768;
150 x *= 0.0021362304;
151 y *= 0.0021362304;
152 x += 205;
153 y += 195;
154 FillEllipse(BPoint(x,y), 5, 5);
155 SetHighColor(rgb_black);
156
157 // Finally, other axes
158 r.Set(200, 220, 350, 234);
159 for (int32 i = 2; i < numAxes; i++) {
160 FillRect(r, B_SOLID_HIGH);
161 x = axes[i];
162 x += 32768;
163 x *= 0.0021362304;
164 x += 205;
165 BRect thumbRect(x - 3, r.top, x + 3, r.bottom);
166 SetHighColor(rgb_red);
167 FillRoundRect(thumbRect, 3, 3);
168 SetHighColor(rgb_black);
169 r.top += 20;
170 r.bottom += 20;
171 }
172 free(buttons);
173 free(axes);
174 free(hats);
175 }
176
177 //----------------------- Pragma mark ------------------------------------//
178
179 BRect
_BuildButtons(BJoystick * stick)180 JoystickView::_BuildButtons(BJoystick *stick)
181 {
182 BString name;
183 int32 numButtons = stick->CountButtons();
184 BRect rect(5, 50, 100, 64);
185 for (int32 i = 0; i < numButtons; i++) {
186 stick->GetButtonNameAt(i, &name);
187 rect = _BuildString(name, "buttonlabel", 18, rect);
188 }
189 return rect;
190 }
191
192
193 BRect
_BuildHats(BJoystick * stick,BRect rect)194 JoystickView::_BuildHats(BJoystick *stick, BRect rect)
195 {
196 BString name;
197 int32 numHats = stick->CountHats();
198 for (int32 i = 0; i < numHats; i++) {
199 stick->GetHatNameAt(i, &name);
200 rect = _BuildString(name, "hatlabel", 40, rect);
201 }
202 return rect;
203 }
204
205
206 BRect
_BuildString(BString name,const char * strName,int number,BRect rect)207 JoystickView::_BuildString(BString name, const char* strName, int number,
208 BRect rect)
209 {
210 name.Append(":");
211 BStringView *sview = new BStringView(rect, strName, name.String());
212 sview->SetAlignment(B_ALIGN_RIGHT);
213 sview->SetFont(be_bold_font);
214 AddChild(sview);
215 rect.top += number;
216 rect.bottom += number;
217 return rect;
218 }
219
220
221 void
_BuildAxes(BJoystick * stick,BRect rect)222 JoystickView::_BuildAxes(BJoystick *stick, BRect rect)
223 {
224 float col1bot = rect.bottom - 30;
225 int32 numAxes = stick->CountAxes();
226 // We assume that the first two axes are the x and y axes.
227 rect.Set(130, 50, 195, 64);
228 BStringView *sview = new BStringView(rect, "sticklabel", "Stick:");
229 sview->SetFont(be_bold_font);
230 sview->SetAlignment(B_ALIGN_RIGHT);
231 AddChild(sview);
232
233 BString name;
234 int32 i;
235 // Now make labels for all the solitary axes
236 rect.Set(130, 200, 195, 234);
237 for (i = 2; i < numAxes; i++) {
238 stick->GetAxisNameAt(i, &name);
239 rect = _BuildString(name, "hatlabel", 20, rect);
240 }
241
242 fLastHatRect.Set(0, 0, 0, 0);
243 if (rect.bottom-10 > col1bot) {
244 if (i == 2) {
245 col1bot = 205;
246 } else {
247 col1bot = rect.bottom - 10;
248 }
249 }
250 ResizeTo(355, col1bot);
251 }
252