xref: /haiku/src/tests/kits/device/stickit_BJoystick/JoystickWindow.cpp (revision 7a74a5df454197933bc6e80a542102362ee98703)
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(BJoystick *stick, BRect rect)
28 	: BWindow(rect, "StickIt", B_TITLED_WINDOW,
29 	B_NOT_RESIZABLE|B_NOT_ZOOMABLE)
30 {
31 	fView = new JoystickView(Bounds(), stick);
32 	fView->SetViewColor(rgb_grey);
33 	fView->SetLowColor(rgb_grey);
34 	ResizeTo(fView->Bounds().Width(), fView->Bounds().Height());
35 	AddChild(fView);
36 	SetPulseRate(100000.0);
37 }
38 
39 
40 bool
41 JoystickWindow::QuitRequested(void) {
42 	be_app->PostMessage(B_QUIT_REQUESTED);
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 void
68 JoystickView::Pulse(void) {
69 	Window()->Lock();
70 	Draw(Bounds());
71 	Window()->Unlock();
72 }
73 
74 
75 void
76 JoystickView::Draw(BRect updateRect)
77 {
78 	int32 numButtons = fStick->CountButtons();
79 	int32 numHats = fStick->CountHats();
80 	int32 numAxes = fStick->CountAxes();
81 	bool *buttons = (bool *) malloc(sizeof(bool) * numButtons);
82 	int16 *axes = (int16 *) malloc(sizeof(int16) * numAxes);
83 	uint8 *hats = (uint8 *) malloc(numHats);
84 	fStick->Update();
85 
86 	// Buttons first
87 	BRect r(105, 50, 115, 60);
88 	fStick->GetButtonValues(buttons);
89 	for (int32 i = 0; i < numButtons; i++) {
90 		if (buttons[i]) {
91 			FillRect(r, B_SOLID_HIGH);
92 		} else {
93 			r.InsetBy(1, 1);
94 			FillRect(r, B_SOLID_LOW);
95 			r.InsetBy(-1, -1);
96 			StrokeRect(r, B_SOLID_HIGH);
97 		}
98 		r.top += 18;
99 		r.bottom += 18;
100 	}
101 
102 	// Now hats
103 	fStick->GetHatValues(hats);
104 	r.top += 15;
105 	r.bottom = r.top + 30;
106 	r.left = 105;
107 	r.right = r.left + 30;
108 	BRect curHatRect;
109 	for (int32 i = 0; i < numHats; i++) {
110 		BeginLineArray(8);
111 		AddLine(r.LeftTop(), r.RightTop(), rgb_black);
112 		AddLine(r.LeftTop(), r.LeftBottom(), rgb_black);
113 		AddLine(r.RightTop(), r.RightBottom(), rgb_black);
114 		AddLine(r.LeftBottom(), r.RightBottom(), rgb_black);
115 		AddLine(BPoint(r.left+10, r.top), BPoint(r.left+10, r.bottom),
116 			rgb_black);
117 		AddLine(BPoint(r.left+20, r.top), BPoint(r.left+20, r.bottom),
118 			rgb_black);
119 		AddLine(BPoint(r.left, r.top+10), BPoint(r.right, r.top+10),
120 			rgb_black);
121 		AddLine(BPoint(r.left, r.top+20), BPoint(r.right, r.top+20),
122 			rgb_black);
123 		EndLineArray();
124 		curHatRect.Set(r.left, r.top, r.left+10, r.top+10);
125 		curHatRect.OffsetBy(hatX[hats[i]], hatY[hats[i]]);
126 		fLastHatRect.InsetBy(1, 1);
127 		FillRect(fLastHatRect, B_SOLID_LOW);
128 		fLastHatRect = curHatRect;
129 		fLastHatRect.InsetBy(1, 1);
130 		FillRect(fLastHatRect, B_SOLID_HIGH);
131 		fLastHatRect.InsetBy(-1, -1);
132 		r.top += 20;
133 		r.bottom += 20;
134 	}
135 
136 	// Now the joystick
137 	r.Set(200, 50, 350, 200);
138 	FillRect(r, B_SOLID_HIGH);
139 	fStick->GetAxisValues(axes);
140 	float x = axes[0];
141 	float y = axes[1];
142 	SetHighColor(rgb_red);
143 	x += 32768;
144 	y -= 32768;
145 	x *= 0.0021362304;
146 	y *= 0.0021362304;
147 	x += 205;
148 	y += 195;
149 	FillEllipse(BPoint(x,y), 5, 5);
150 	SetHighColor(rgb_black);
151 
152 	// Finally, other axes
153 	r.Set(200, 220, 350, 234);
154 	for (int32 i = 2; i < numAxes; i++) {
155 		FillRect(r, B_SOLID_HIGH);
156 		x = axes[i];
157 		x += 32768;
158 		x *= 0.0021362304;
159 		x += 205;
160 		BRect thumbRect(x - 3, r.top, x + 3, r.bottom);
161 		SetHighColor(rgb_red);
162 		FillRoundRect(thumbRect, 3, 3);
163 		SetHighColor(rgb_black);
164 		r.top += 20;
165 		r.bottom += 20;
166 	}
167 	free(buttons);
168 	free(axes);
169 	free(hats);
170 }
171 
172 //----------------------- Pragma mark ------------------------------------//
173 
174 BRect
175 JoystickView::_BuildButtons(BJoystick *stick)
176 {
177 	BString name;
178 	int32 numButtons = stick->CountButtons();
179 	BRect rect(5, 50, 100, 64);
180 	for (int32 i = 0; i < numButtons; i++) {
181 		stick->GetButtonNameAt(i, &name);
182 		rect = _BuildString(name, "buttonlabel", 18, rect);
183 	}
184 	return rect;
185 }
186 
187 
188 BRect
189 JoystickView::_BuildHats(BJoystick *stick, BRect rect)
190 {
191 	BString name;
192 	int32 numHats = stick->CountHats();
193 	for (int32 i = 0; i < numHats; i++) {
194 		stick->GetHatNameAt(i, &name);
195 		rect = _BuildString(name, "hatlabel", 40, rect);
196 	}
197 	return rect;
198 }
199 
200 
201 BRect
202 JoystickView::_BuildString(BString name, const char* strName, int number,
203 	BRect rect)
204 {
205 	name.Append(":");
206 	BStringView *sview = new BStringView(rect, strName, name.String());
207 	sview->SetAlignment(B_ALIGN_RIGHT);
208 	sview->SetFont(be_bold_font);
209 	AddChild(sview);
210 	rect.top += number;
211 	rect.bottom += number;
212 	return rect;
213 }
214 
215 
216 void
217 JoystickView::_BuildAxes(BJoystick *stick, BRect rect)
218 {
219 	float col1bot = rect.bottom - 30;
220 	int32 numAxes = stick->CountAxes();
221 	// We assume that the first two axes are the x and y axes.
222 	rect.Set(130, 50, 195, 64);
223 	BStringView *sview = new BStringView(rect, "sticklabel", "Stick:");
224 	sview->SetFont(be_bold_font);
225 	sview->SetAlignment(B_ALIGN_RIGHT);
226 	AddChild(sview);
227 
228 	BString name;
229 	int32 i;
230 	// Now make labels for all the solitary axes
231 	rect.Set(130, 200, 195, 234);
232 	for (i = 2; i < numAxes; i++) {
233 		stick->GetAxisNameAt(i, &name);
234 		rect = _BuildString(name, "hatlabel", 20, rect);
235 	}
236 
237 	fLastHatRect.Set(0, 0, 0, 0);
238 	if (rect.bottom-10 > col1bot) {
239 		if (i == 2) {
240 			col1bot = 205;
241 		} else {
242 			col1bot = rect.bottom - 10;
243 		}
244 	}
245 	ResizeTo(355, col1bot);
246 }
247