xref: /haiku/src/tests/servers/app/playground/ObjectWindow.cpp (revision 78c1c29bafd2f660098f4b5ed54f5e7e76c65ff0)
1*78c1c29bSStephan Aßmus // main.cpp
2*78c1c29bSStephan Aßmus 
3*78c1c29bSStephan Aßmus #include <stdio.h>
4*78c1c29bSStephan Aßmus #include <stdlib.h>
5*78c1c29bSStephan Aßmus 
6*78c1c29bSStephan Aßmus #include <Application.h>
7*78c1c29bSStephan Aßmus #include <Box.h>
8*78c1c29bSStephan Aßmus #include <Button.h>
9*78c1c29bSStephan Aßmus #include <CheckBox.h>
10*78c1c29bSStephan Aßmus #include <Menu.h>
11*78c1c29bSStephan Aßmus #include <MenuBar.h>
12*78c1c29bSStephan Aßmus #include <MenuItem.h>
13*78c1c29bSStephan Aßmus #include <String.h>
14*78c1c29bSStephan Aßmus #include <RadioButton.h>
15*78c1c29bSStephan Aßmus #include <TextControl.h>
16*78c1c29bSStephan Aßmus #include <TextView.h>
17*78c1c29bSStephan Aßmus 
18*78c1c29bSStephan Aßmus #include "ObjectView.h"
19*78c1c29bSStephan Aßmus #include "States.h"
20*78c1c29bSStephan Aßmus 
21*78c1c29bSStephan Aßmus #include "ObjectWindow.h"
22*78c1c29bSStephan Aßmus 
23*78c1c29bSStephan Aßmus enum {
24*78c1c29bSStephan Aßmus 	MSG_SET_OBJECT_TYPE		= 'stot',
25*78c1c29bSStephan Aßmus 	MSG_SET_FILL_OR_STROKE	= 'stfs',
26*78c1c29bSStephan Aßmus 	MSG_SET_COLOR			= 'stcl',
27*78c1c29bSStephan Aßmus 	MSG_SET_PEN_SIZE		= 'stps',
28*78c1c29bSStephan Aßmus 
29*78c1c29bSStephan Aßmus 	MSG_NEW_OBJECT			= 'nobj',
30*78c1c29bSStephan Aßmus 
31*78c1c29bSStephan Aßmus 	MSG_UNDO				= 'undo',
32*78c1c29bSStephan Aßmus 	MSG_REDO				= 'redo',
33*78c1c29bSStephan Aßmus 
34*78c1c29bSStephan Aßmus 	MSG_CLEAR				= 'clir',
35*78c1c29bSStephan Aßmus };
36*78c1c29bSStephan Aßmus 
37*78c1c29bSStephan Aßmus // constructor
38*78c1c29bSStephan Aßmus ObjectWindow::ObjectWindow(BRect frame, const char* name)
39*78c1c29bSStephan Aßmus 	: BWindow(frame, name, B_TITLED_WINDOW, B_ASYNCHRONOUS_CONTROLS)
40*78c1c29bSStephan Aßmus {
41*78c1c29bSStephan Aßmus 	BRect b(Bounds());
42*78c1c29bSStephan Aßmus 
43*78c1c29bSStephan Aßmus 	b.bottom = b.top + 8;
44*78c1c29bSStephan Aßmus 	BMenuBar* menuBar = new BMenuBar(b, "menu bar");
45*78c1c29bSStephan Aßmus 	AddChild(menuBar);
46*78c1c29bSStephan Aßmus 
47*78c1c29bSStephan Aßmus 	BMenu* menu = new BMenu("Menus");
48*78c1c29bSStephan Aßmus 	menuBar->AddItem(menu);
49*78c1c29bSStephan Aßmus 
50*78c1c29bSStephan Aßmus 	BMenuItem* menuItem = new BMenuItem("Quit", NULL, 'Q');
51*78c1c29bSStephan Aßmus 	menu->AddItem(menuItem);
52*78c1c29bSStephan Aßmus 
53*78c1c29bSStephan Aßmus 	menuBar->AddItem(new BMenu("don't"));
54*78c1c29bSStephan Aßmus 	menuBar->AddItem(new BMenu("work!"));
55*78c1c29bSStephan Aßmus 	menuBar->AddItem(new BMenu("(yet)"));
56*78c1c29bSStephan Aßmus 
57*78c1c29bSStephan Aßmus 	b = Bounds();
58*78c1c29bSStephan Aßmus 	b.top = menuBar->Bounds().bottom + 1;
59*78c1c29bSStephan Aßmus 	BBox* bg = new BBox(b, "bg box", B_FOLLOW_ALL, B_WILL_DRAW, B_PLAIN_BORDER);
60*78c1c29bSStephan Aßmus 
61*78c1c29bSStephan Aßmus 	AddChild(bg);
62*78c1c29bSStephan Aßmus 	bg->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
63*78c1c29bSStephan Aßmus 
64*78c1c29bSStephan Aßmus 	b = bg->Bounds();
65*78c1c29bSStephan Aßmus 	// object views occupies the right side of the window
66*78c1c29bSStephan Aßmus 	b.Set(ceilf((b.left + b.right) / 3.0) + 3.0, b.top + 5.0, b.right - 5.0, b.bottom - 5.0);
67*78c1c29bSStephan Aßmus 	fObjectView = new ObjectView(b, "object view", B_FOLLOW_ALL,
68*78c1c29bSStephan Aßmus 								 B_WILL_DRAW | B_FULL_UPDATE_ON_RESIZE);
69*78c1c29bSStephan Aßmus 
70*78c1c29bSStephan Aßmus 	bg->AddChild(fObjectView);
71*78c1c29bSStephan Aßmus 
72*78c1c29bSStephan Aßmus 	b = bg->Bounds();
73*78c1c29bSStephan Aßmus 	// controls occupy the left side of the window
74*78c1c29bSStephan Aßmus 	b.Set(b.left + 5.0, b.top + 5.0, ceilf((b.left + b.right) / 3.0) - 2.0, b.bottom - 5.0);
75*78c1c29bSStephan Aßmus 	BBox* controlGroup = new BBox(b, "controls box", B_FOLLOW_LEFT | B_FOLLOW_TOP_BOTTOM,
76*78c1c29bSStephan Aßmus 								  B_WILL_DRAW, B_FANCY_BORDER);
77*78c1c29bSStephan Aßmus 
78*78c1c29bSStephan Aßmus 	controlGroup->SetLabel("Controls");
79*78c1c29bSStephan Aßmus 	bg->AddChild(controlGroup);
80*78c1c29bSStephan Aßmus 
81*78c1c29bSStephan Aßmus 	b = controlGroup->Bounds();
82*78c1c29bSStephan Aßmus 	b.top += 10.0;
83*78c1c29bSStephan Aßmus 	b.bottom = b.top + 25.0;
84*78c1c29bSStephan Aßmus 	b.InsetBy(5.0, 5.0);
85*78c1c29bSStephan Aßmus 
86*78c1c29bSStephan Aßmus 	// new button
87*78c1c29bSStephan Aßmus 	fNewB = new BButton(b, "new button", "New Object", new BMessage(MSG_NEW_OBJECT));
88*78c1c29bSStephan Aßmus 	controlGroup->AddChild(fNewB);
89*78c1c29bSStephan Aßmus 
90*78c1c29bSStephan Aßmus 	// clear button
91*78c1c29bSStephan Aßmus 	b.OffsetBy(0, fNewB->Bounds().Height() + 5.0);
92*78c1c29bSStephan Aßmus 	fClearB = new BButton(b, "clear button", "Clear", new BMessage(MSG_CLEAR));
93*78c1c29bSStephan Aßmus 	controlGroup->AddChild(fClearB);
94*78c1c29bSStephan Aßmus 
95*78c1c29bSStephan Aßmus 	// object type radio buttons
96*78c1c29bSStephan Aßmus 	BMessage* message;
97*78c1c29bSStephan Aßmus 	BRadioButton* radioButton;
98*78c1c29bSStephan Aßmus 
99*78c1c29bSStephan Aßmus 	b.OffsetBy(0, fClearB->Bounds().Height() + 5.0);
100*78c1c29bSStephan Aßmus 	message = new BMessage(MSG_SET_OBJECT_TYPE);
101*78c1c29bSStephan Aßmus 	message->AddInt32("type", OBJECT_LINE);
102*78c1c29bSStephan Aßmus 	radioButton = new BRadioButton(b, "radio 1", "Line", message);
103*78c1c29bSStephan Aßmus 	controlGroup->AddChild(radioButton);
104*78c1c29bSStephan Aßmus 
105*78c1c29bSStephan Aßmus 	radioButton->SetValue(B_CONTROL_ON);
106*78c1c29bSStephan Aßmus 
107*78c1c29bSStephan Aßmus 	b.OffsetBy(0, radioButton->Bounds().Height() + 5.0);
108*78c1c29bSStephan Aßmus 	message = new BMessage(MSG_SET_OBJECT_TYPE);
109*78c1c29bSStephan Aßmus 	message->AddInt32("type", OBJECT_RECT);
110*78c1c29bSStephan Aßmus 	radioButton = new BRadioButton(b, "radio 2", "Rect", message);
111*78c1c29bSStephan Aßmus 	controlGroup->AddChild(radioButton);
112*78c1c29bSStephan Aßmus 
113*78c1c29bSStephan Aßmus 	b.OffsetBy(0, radioButton->Bounds().Height() + 5.0);
114*78c1c29bSStephan Aßmus 	message = new BMessage(MSG_SET_OBJECT_TYPE);
115*78c1c29bSStephan Aßmus 	message->AddInt32("type", OBJECT_ROUND_RECT);
116*78c1c29bSStephan Aßmus 	radioButton = new BRadioButton(b, "radio 3", "Round Rect", message);
117*78c1c29bSStephan Aßmus 	controlGroup->AddChild(radioButton);
118*78c1c29bSStephan Aßmus 
119*78c1c29bSStephan Aßmus 	b.OffsetBy(0, radioButton->Bounds().Height() + 5.0);
120*78c1c29bSStephan Aßmus 	message = new BMessage(MSG_SET_OBJECT_TYPE);
121*78c1c29bSStephan Aßmus 	message->AddInt32("type", OBJECT_ELLIPSE);
122*78c1c29bSStephan Aßmus 	radioButton = new BRadioButton(b, "radio 4", "Ellipse", message);
123*78c1c29bSStephan Aßmus 	controlGroup->AddChild(radioButton);
124*78c1c29bSStephan Aßmus 
125*78c1c29bSStephan Aßmus 	// red text control
126*78c1c29bSStephan Aßmus 	b.OffsetBy(0, radioButton->Bounds().Height() + 5.0);
127*78c1c29bSStephan Aßmus 	fRedTC = new BTextControl(b, "red text control", "Red", "",
128*78c1c29bSStephan Aßmus 							  new BMessage(MSG_SET_COLOR));
129*78c1c29bSStephan Aßmus 	controlGroup->AddChild(fRedTC);
130*78c1c29bSStephan Aßmus 
131*78c1c29bSStephan Aßmus 	// green text control
132*78c1c29bSStephan Aßmus 	b.OffsetBy(0, fRedTC->Bounds().Height() + 5.0);
133*78c1c29bSStephan Aßmus 	fGreenTC = new BTextControl(b, "green text control", "Green", "",
134*78c1c29bSStephan Aßmus 								new BMessage(MSG_SET_COLOR));
135*78c1c29bSStephan Aßmus 	controlGroup->AddChild(fGreenTC);
136*78c1c29bSStephan Aßmus 
137*78c1c29bSStephan Aßmus 	// blue text control
138*78c1c29bSStephan Aßmus 	b.OffsetBy(0, fGreenTC->Bounds().Height() + 5.0);
139*78c1c29bSStephan Aßmus 	fBlueTC = new BTextControl(b, "blue text control", "Blue", "",
140*78c1c29bSStephan Aßmus 							   new BMessage(MSG_SET_COLOR));
141*78c1c29bSStephan Aßmus 	controlGroup->AddChild(fBlueTC);
142*78c1c29bSStephan Aßmus 
143*78c1c29bSStephan Aßmus 	// alpha text control
144*78c1c29bSStephan Aßmus 	b.OffsetBy(0, fBlueTC->Bounds().Height() + 5.0);
145*78c1c29bSStephan Aßmus 	fAlphaTC = new BTextControl(b, "alpha text control", "Alpha", "",
146*78c1c29bSStephan Aßmus 								new BMessage(MSG_SET_COLOR));
147*78c1c29bSStephan Aßmus 	controlGroup->AddChild(fAlphaTC);
148*78c1c29bSStephan Aßmus /*
149*78c1c29bSStephan Aßmus // TODO: while this block of code works in the Haiku app_server running under R5,
150*78c1c29bSStephan Aßmus // it crashes pretty badly under Haiku. I have no idea why this happens, because
151*78c1c29bSStephan Aßmus // I was doing the same thing before at other places.
152*78c1c29bSStephan Aßmus 	// divide text controls the same
153*78c1c29bSStephan Aßmus 	float rWidth = fRedTC->StringWidth(fRedTC->Label());
154*78c1c29bSStephan Aßmus 	float gWidth = fGreenTC->StringWidth(fGreenTC->Label());
155*78c1c29bSStephan Aßmus 	float bWidth = fBlueTC->StringWidth(fBlueTC->Label());
156*78c1c29bSStephan Aßmus 	float aWidth = fAlphaTC->StringWidth(fAlphaTC->Label());
157*78c1c29bSStephan Aßmus 
158*78c1c29bSStephan Aßmus 	float width = max_c(rWidth, max_c(gWidth, max_c(bWidth, aWidth))) + 10.0;
159*78c1c29bSStephan Aßmus 	fRedTC->SetDivider(width);
160*78c1c29bSStephan Aßmus 	fGreenTC->SetDivider(width);
161*78c1c29bSStephan Aßmus 	fBlueTC->SetDivider(width);
162*78c1c29bSStephan Aßmus 	fAlphaTC->SetDivider(width);*/
163*78c1c29bSStephan Aßmus 
164*78c1c29bSStephan Aßmus 	// fill check box
165*78c1c29bSStephan Aßmus 	b.OffsetBy(0, fAlphaTC->Bounds().Height() + 5.0);
166*78c1c29bSStephan Aßmus 	fFillCB = new BCheckBox(b, "fill check box", "Fill",
167*78c1c29bSStephan Aßmus 							new BMessage(MSG_SET_FILL_OR_STROKE));
168*78c1c29bSStephan Aßmus 	controlGroup->AddChild(fFillCB);
169*78c1c29bSStephan Aßmus 
170*78c1c29bSStephan Aßmus 	// pen size text control
171*78c1c29bSStephan Aßmus 	b.OffsetBy(0, radioButton->Bounds().Height() + 5.0);
172*78c1c29bSStephan Aßmus 	fPenSizeTC = new BTextControl(b, "width text control", "Width", "",
173*78c1c29bSStephan Aßmus 								  new BMessage(MSG_SET_PEN_SIZE));
174*78c1c29bSStephan Aßmus 	controlGroup->AddChild(fPenSizeTC);
175*78c1c29bSStephan Aßmus 
176*78c1c29bSStephan Aßmus 	_UpdateControls();
177*78c1c29bSStephan Aßmus }
178*78c1c29bSStephan Aßmus 
179*78c1c29bSStephan Aßmus // destructor
180*78c1c29bSStephan Aßmus ObjectWindow::~ObjectWindow()
181*78c1c29bSStephan Aßmus {
182*78c1c29bSStephan Aßmus }
183*78c1c29bSStephan Aßmus 
184*78c1c29bSStephan Aßmus // QuitRequested
185*78c1c29bSStephan Aßmus bool
186*78c1c29bSStephan Aßmus ObjectWindow::QuitRequested()
187*78c1c29bSStephan Aßmus {
188*78c1c29bSStephan Aßmus 	be_app->PostMessage(B_QUIT_REQUESTED);
189*78c1c29bSStephan Aßmus 	return true;
190*78c1c29bSStephan Aßmus }
191*78c1c29bSStephan Aßmus 
192*78c1c29bSStephan Aßmus // MessageReceived
193*78c1c29bSStephan Aßmus void
194*78c1c29bSStephan Aßmus ObjectWindow::MessageReceived(BMessage* message)
195*78c1c29bSStephan Aßmus {
196*78c1c29bSStephan Aßmus 	switch (message->what) {
197*78c1c29bSStephan Aßmus 		case MSG_SET_OBJECT_TYPE: {
198*78c1c29bSStephan Aßmus 			int32 type;
199*78c1c29bSStephan Aßmus 			if (message->FindInt32("type", &type) >= B_OK) {
200*78c1c29bSStephan Aßmus 				fObjectView->SetObjectType(type);
201*78c1c29bSStephan Aßmus 				fFillCB->SetEnabled(type != OBJECT_LINE);
202*78c1c29bSStephan Aßmus 			}
203*78c1c29bSStephan Aßmus 			break;
204*78c1c29bSStephan Aßmus 		}
205*78c1c29bSStephan Aßmus 		case MSG_SET_FILL_OR_STROKE: {
206*78c1c29bSStephan Aßmus 			int32 value;
207*78c1c29bSStephan Aßmus 			if (message->FindInt32("be:value", &value) >= B_OK) {
208*78c1c29bSStephan Aßmus 				fObjectView->SetStateFill(value);
209*78c1c29bSStephan Aßmus 				fPenSizeTC->SetEnabled(value == B_CONTROL_OFF);
210*78c1c29bSStephan Aßmus 			}
211*78c1c29bSStephan Aßmus 			break;
212*78c1c29bSStephan Aßmus 		}
213*78c1c29bSStephan Aßmus 		case MSG_SET_COLOR:
214*78c1c29bSStephan Aßmus 			fObjectView->SetStateColor(_GetColor());
215*78c1c29bSStephan Aßmus 			break;
216*78c1c29bSStephan Aßmus 		case MSG_OBJECT_COUNT_CHANGED:
217*78c1c29bSStephan Aßmus 			fClearB->SetEnabled(fObjectView->CountObjects() > 0);
218*78c1c29bSStephan Aßmus 			break;
219*78c1c29bSStephan Aßmus 		case MSG_NEW_OBJECT:
220*78c1c29bSStephan Aßmus 			fObjectView->SetState(NULL);
221*78c1c29bSStephan Aßmus 			break;
222*78c1c29bSStephan Aßmus 		case MSG_CLEAR:
223*78c1c29bSStephan Aßmus 			fObjectView->MakeEmpty();
224*78c1c29bSStephan Aßmus 			break;
225*78c1c29bSStephan Aßmus 		case MSG_SET_PEN_SIZE:
226*78c1c29bSStephan Aßmus 			fObjectView->SetStatePenSize(atof(fPenSizeTC->Text()));
227*78c1c29bSStephan Aßmus 			break;
228*78c1c29bSStephan Aßmus 		default:
229*78c1c29bSStephan Aßmus 			BWindow::MessageReceived(message);
230*78c1c29bSStephan Aßmus 	}
231*78c1c29bSStephan Aßmus }
232*78c1c29bSStephan Aßmus 
233*78c1c29bSStephan Aßmus // _UpdateControls
234*78c1c29bSStephan Aßmus void
235*78c1c29bSStephan Aßmus ObjectWindow::_UpdateControls() const
236*78c1c29bSStephan Aßmus {
237*78c1c29bSStephan Aßmus 	// update color
238*78c1c29bSStephan Aßmus 	rgb_color c = fObjectView->StateColor();
239*78c1c29bSStephan Aßmus 	char string[32];
240*78c1c29bSStephan Aßmus 
241*78c1c29bSStephan Aßmus 	sprintf(string, "%d", c.red);
242*78c1c29bSStephan Aßmus 	fRedTC->SetText(string);
243*78c1c29bSStephan Aßmus 
244*78c1c29bSStephan Aßmus 	sprintf(string, "%d", c.green);
245*78c1c29bSStephan Aßmus 	fGreenTC->SetText(string);
246*78c1c29bSStephan Aßmus 
247*78c1c29bSStephan Aßmus 	sprintf(string, "%d", c.blue);
248*78c1c29bSStephan Aßmus 	fBlueTC->SetText(string);
249*78c1c29bSStephan Aßmus 
250*78c1c29bSStephan Aßmus 	sprintf(string, "%d", c.alpha);
251*78c1c29bSStephan Aßmus 	fAlphaTC->SetText(string);
252*78c1c29bSStephan Aßmus 
253*78c1c29bSStephan Aßmus 
254*78c1c29bSStephan Aßmus 	// update buttons
255*78c1c29bSStephan Aßmus 	fClearB->SetEnabled(fObjectView->CountObjects() > 0);
256*78c1c29bSStephan Aßmus 
257*78c1c29bSStephan Aßmus 	fFillCB->SetEnabled(fObjectView->ObjectType() != OBJECT_LINE);
258*78c1c29bSStephan Aßmus 
259*78c1c29bSStephan Aßmus 	// disable penSize if fill is on
260*78c1c29bSStephan Aßmus 	sprintf(string, "%.1f", fObjectView->StatePenSize());
261*78c1c29bSStephan Aßmus 	fPenSizeTC->SetText(string);
262*78c1c29bSStephan Aßmus 	fPenSizeTC->SetEnabled(!fFillCB->IsEnabled());
263*78c1c29bSStephan Aßmus }
264*78c1c29bSStephan Aßmus 
265*78c1c29bSStephan Aßmus // _GetColor
266*78c1c29bSStephan Aßmus rgb_color
267*78c1c29bSStephan Aßmus ObjectWindow::_GetColor() const
268*78c1c29bSStephan Aßmus {
269*78c1c29bSStephan Aßmus 	rgb_color c;
270*78c1c29bSStephan Aßmus 	c.red	= max_c(0, min_c(255, atoi(fRedTC->Text())));
271*78c1c29bSStephan Aßmus 	c.green	= max_c(0, min_c(255, atoi(fGreenTC->Text())));
272*78c1c29bSStephan Aßmus 	c.blue	= max_c(0, min_c(255, atoi(fBlueTC->Text())));
273*78c1c29bSStephan Aßmus 	c.alpha	= max_c(0, min_c(255, atoi(fAlphaTC->Text())));
274*78c1c29bSStephan Aßmus 
275*78c1c29bSStephan Aßmus 	return c;
276*78c1c29bSStephan Aßmus }
277*78c1c29bSStephan Aßmus 
278