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