xref: /haiku/src/tests/kits/device/stickit_BJoystick/JoystickWindow.cpp (revision a5a3b2d9a3d95cbae71eaf371708c73a1780ac0d)
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 
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
42 JoystickWindow::QuitRequested(void) {
43 	return true;
44 }
45 
46 
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 
67 JoystickView::~JoystickView() {
68 	delete fStick;
69 }
70 
71 
72 void
73 JoystickView::Pulse(void) {
74 	Window()->Lock();
75 	Draw(Bounds());
76 	Window()->Unlock();
77 }
78 
79 
80 void
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
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
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
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
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