6 #include <Application.h>
13 #include <ColorControl.h>
18 #include <MenuField.h>
20 #include <PopUpMenu.h>
21 #include <ScrollBar.h>
22 #include <ScrollView.h>
25 #include <RadioButton.h>
28 #include <TextControl.h>
31 #include "ObjectView.h"
32 #include "ObjectWindow.h"
34 //#include "StatusView.h"
37 #undef B_TRANSLATION_CONTEXT
38 #define B_TRANSLATION_CONTEXT "Playground"
41 MSG_SET_OBJECT_TYPE
= 'stot',
42 MSG_SET_FILL_OR_STROKE
= 'stfs',
43 MSG_SET_COLOR
= 'stcl',
44 MSG_SET_PEN_SIZE
= 'stps',
45 MSG_SET_DRAWING_MODE
= 'stdm',
47 MSG_NEW_OBJECT
= 'nobj',
54 MSG_OBJECT_SELECTED
= 'obsl',
55 MSG_REMOVE_OBJECT
= 'rmob',
59 class ObjectItem
: public BStringItem
{
61 ObjectItem(const char* name
, State
* object
)
75 class ObjectListView
: public BListView
{
77 ObjectListView(BRect frame
, const char* name
, list_view_type listType
)
78 : BListView(frame
, name
, listType
)
82 virtual void KeyDown(const char* bytes
, int32 numBytes
)
86 Window()->PostMessage(MSG_REMOVE_OBJECT
);
89 BListView::KeyDown(bytes
, numBytes
);
93 virtual bool InitiateDrag(BPoint point
, int32 itemIndex
, bool wasSelected
)
95 printf("InitiateDrag(BPoint(%.1f, %.1f), itemIndex: %" B_PRId32
96 ", wasSelected: %d)\n", point
.x
, point
.y
, itemIndex
,
98 SwapItems(itemIndex
, itemIndex
+ 1);
102 virtual void SelectionChanged()
104 // printf("SelectionChanged() - first selected: %ld\n", CurrentSelection(0));
110 class TestView
: public BView
{
112 TestView(BRect frame
, const char* name
, uint32 resizeMode
, uint32 flags
)
113 : BView(frame
, name
, resizeMode
, flags
)
117 void AttachedToWindow()
119 SetViewColor(255, 0, 0);
124 ObjectWindow::ObjectWindow(BRect frame
, const char* name
)
125 : BWindow(frame
, name
, B_DOCUMENT_WINDOW_LOOK
, B_NORMAL_WINDOW_FEEL
,
126 B_ASYNCHRONOUS_CONTROLS
| B_NOT_ZOOMABLE
)
130 b
.bottom
= b
.top
+ 8;
131 BMenuBar
* menuBar
= new BMenuBar(b
, "menu bar");
134 BMenu
* menu
= new BMenu(B_TRANSLATE("File"));
135 menuBar
->AddItem(menu
);
137 menu
->AddItem(new BMenu(B_TRANSLATE("Submenu")));
139 BMenuItem
* menuItem
= new BMenuItem(B_TRANSLATE("Quit"), new BMessage(B_QUIT_REQUESTED
),
141 menu
->AddItem(menuItem
);
144 b
.top
= menuBar
->Bounds().bottom
+ 1;
145 b
.right
= ceilf((b
.left
+ b
.right
) / 2.0);
146 BBox
* bg
= new BBox(b
, "bg box", B_FOLLOW_TOP_BOTTOM
, B_WILL_DRAW
,
150 bg
->SetViewUIColor(B_PANEL_BACKGROUND_COLOR
);
152 // object view occupies the right side of the window
153 b
.left
= b
.right
+ 1.0;
154 b
.right
= Bounds().right
- B_V_SCROLL_BAR_WIDTH
;
155 b
.bottom
-= B_H_SCROLL_BAR_HEIGHT
;
156 fObjectView
= new ObjectView(b
, "object view", B_FOLLOW_ALL
,
157 B_WILL_DRAW
| B_FULL_UPDATE_ON_RESIZE
);
158 // wrap a scroll view around the object view
159 BScrollView
* scrollView
= new BScrollView("object scroller", fObjectView
,
160 B_FOLLOW_ALL
, 0, true, true, B_NO_BORDER
);
162 if (BScrollBar
* scrollBar
= fObjectView
->ScrollBar(B_VERTICAL
)) {
163 scrollBar
->SetRange(0.0, fObjectView
->Bounds().Height());
164 scrollBar
->SetProportion(0.5);
166 if (BScrollBar
* scrollBar
= fObjectView
->ScrollBar(B_HORIZONTAL
)) {
167 scrollBar
->SetRange(0.0, fObjectView
->Bounds().Width());
168 scrollBar
->SetProportion(0.5);
170 AddChild(scrollView
);
173 // controls occupy the left side of the window
175 BBox
* controlGroup
= new BBox(b
, "controls box",
176 B_FOLLOW_LEFT
| B_FOLLOW_TOP_BOTTOM
, B_WILL_DRAW
, B_FANCY_BORDER
);
178 controlGroup
->SetLabel(B_TRANSLATE("Controls"));
179 bg
->AddChild(controlGroup
);
181 b
= controlGroup
->Bounds();
182 b
.top
+= controlGroup
->InnerFrame().top
;
183 b
.bottom
= b
.top
+ 25.0;
184 b
.InsetBy(10.0, 10.0);
185 b
.right
= b
.left
+ b
.Width() / 2.0 - 5.0;
188 fNewB
= new BButton(b
, "new button", B_TRANSLATE("New object"),
189 new BMessage(MSG_NEW_OBJECT
));
190 controlGroup
->AddChild(fNewB
);
191 SetDefaultButton(fNewB
);
194 b
.OffsetBy(0, fNewB
->Bounds().Height() + 5.0);
195 fClearB
= new BButton(b
, "clear button", B_TRANSLATE("Clear"), new BMessage(MSG_CLEAR
));
196 controlGroup
->AddChild(fClearB
);
198 // object type radio buttons
200 BRadioButton
* radioButton
;
202 b
.OffsetBy(0, fClearB
->Bounds().Height() + 5.0);
203 message
= new BMessage(MSG_SET_OBJECT_TYPE
);
204 message
->AddInt32("type", OBJECT_LINE
);
205 radioButton
= new BRadioButton(b
, "radio 1", B_TRANSLATE("Line"), message
);
206 controlGroup
->AddChild(radioButton
);
208 radioButton
->SetValue(B_CONTROL_ON
);
210 b
.OffsetBy(0, radioButton
->Bounds().Height() + 5.0);
211 message
= new BMessage(MSG_SET_OBJECT_TYPE
);
212 message
->AddInt32("type", OBJECT_RECT
);
213 radioButton
= new BRadioButton(b
, "radio 2", B_TRANSLATE("Rect"), message
);
214 controlGroup
->AddChild(radioButton
);
216 b
.OffsetBy(0, radioButton
->Bounds().Height() + 5.0);
217 message
= new BMessage(MSG_SET_OBJECT_TYPE
);
218 message
->AddInt32("type", OBJECT_ROUND_RECT
);
219 radioButton
= new BRadioButton(b
, "radio 3", B_TRANSLATE("Round rect"), message
);
220 controlGroup
->AddChild(radioButton
);
222 b
.OffsetBy(0, radioButton
->Bounds().Height() + 5.0);
223 message
= new BMessage(MSG_SET_OBJECT_TYPE
);
224 message
->AddInt32("type", OBJECT_ELLIPSE
);
225 radioButton
= new BRadioButton(b
, "radio 4", B_TRANSLATE("Ellipse"), message
);
226 controlGroup
->AddChild(radioButton
);
229 BPopUpMenu
* popupMenu
= new BPopUpMenu(B_TRANSLATE("<pick>"));
231 message
= new BMessage(MSG_SET_DRAWING_MODE
);
232 message
->AddInt32("mode", B_OP_COPY
);
233 popupMenu
->AddItem(new BMenuItem(B_TRANSLATE("Copy"), message
));
235 message
= new BMessage(MSG_SET_DRAWING_MODE
);
236 message
->AddInt32("mode", B_OP_OVER
);
237 popupMenu
->AddItem(new BMenuItem(B_TRANSLATE("Over"), message
));
239 message
= new BMessage(MSG_SET_DRAWING_MODE
);
240 message
->AddInt32("mode", B_OP_INVERT
);
241 popupMenu
->AddItem(new BMenuItem(B_TRANSLATE("Invert"), message
));
243 message
= new BMessage(MSG_SET_DRAWING_MODE
);
244 message
->AddInt32("mode", B_OP_BLEND
);
245 popupMenu
->AddItem(new BMenuItem(B_TRANSLATE("Blend"), message
));
247 message
= new BMessage(MSG_SET_DRAWING_MODE
);
248 message
->AddInt32("mode", B_OP_SELECT
);
249 popupMenu
->AddItem(new BMenuItem(B_TRANSLATE("Select"), message
));
251 message
= new BMessage(MSG_SET_DRAWING_MODE
);
252 message
->AddInt32("mode", B_OP_ERASE
);
253 popupMenu
->AddItem(new BMenuItem(B_TRANSLATE("Erase"), message
));
255 message
= new BMessage(MSG_SET_DRAWING_MODE
);
256 message
->AddInt32("mode", B_OP_ADD
);
257 popupMenu
->AddItem(new BMenuItem(B_TRANSLATE("Add"), message
));
259 message
= new BMessage(MSG_SET_DRAWING_MODE
);
260 message
->AddInt32("mode", B_OP_SUBTRACT
);
261 popupMenu
->AddItem(new BMenuItem(B_TRANSLATE("Subtract"), message
));
263 message
= new BMessage(MSG_SET_DRAWING_MODE
);
264 message
->AddInt32("mode", B_OP_MIN
);
265 popupMenu
->AddItem(new BMenuItem(B_TRANSLATE("Min"), message
));
267 message
= new BMessage(MSG_SET_DRAWING_MODE
);
268 message
->AddInt32("mode", B_OP_MAX
);
269 popupMenu
->AddItem(new BMenuItem(B_TRANSLATE("Max"), message
));
271 message
= new BMessage(MSG_SET_DRAWING_MODE
);
272 message
->AddInt32("mode", B_OP_ALPHA
);
273 BMenuItem
* item
= new BMenuItem(B_TRANSLATE("Alpha"), message
);
274 item
->SetMarked(true);
275 popupMenu
->AddItem(item
);
277 b
.OffsetBy(0, radioButton
->Bounds().Height() + 10.0);
278 fDrawingModeMF
= new BMenuField(b
, "drawing mode field", B_TRANSLATE("Mode:"),
281 controlGroup
->AddChild(fDrawingModeMF
);
283 fDrawingModeMF
->SetDivider(fDrawingModeMF
->StringWidth(
284 fDrawingModeMF
->Label()) + 10.0);
287 b
.OffsetBy(0, fDrawingModeMF
->Bounds().Height() + 10.0);
288 fColorControl
= new BColorControl(b
.LeftTop(), B_CELLS_16x16
, 8,
289 "color control", new BMessage(MSG_SET_COLOR
));
290 controlGroup
->AddChild(fColorControl
);
292 // alpha text control
293 b
.OffsetBy(0, fColorControl
-> Bounds().Height() + 5.0);
294 fAlphaTC
= new BTextControl(b
, "alpha text control", B_TRANSLATE("Alpha:"), "",
295 new BMessage(MSG_SET_COLOR
));
296 controlGroup
->AddChild(fAlphaTC
);
298 // divide text controls the same
299 float mWidth
= fDrawingModeMF
->StringWidth(fDrawingModeMF
->Label());
300 float aWidth
= fAlphaTC
->StringWidth(fAlphaTC
->Label());
302 float width
= max_c(mWidth
, aWidth
) + 20.0;
303 fDrawingModeMF
->SetDivider(width
);
304 fAlphaTC
->SetDivider(width
);
307 b
.OffsetBy(0, fAlphaTC
->Bounds().Height() + 5.0);
308 fFillCB
= new BCheckBox(b
, "fill check box", B_TRANSLATE("Fill"),
309 new BMessage(MSG_SET_FILL_OR_STROKE
));
310 controlGroup
->AddChild(fFillCB
);
312 // pen size text control
313 b
.OffsetBy(0, radioButton
->Bounds().Height() + 5.0);
314 b
.bottom
= b
.top
+ 10.0;//35;
315 fPenSizeS
= new BSlider(b
, "width slider", B_TRANSLATE("Width:"), NULL
, 1, 100,
317 fPenSizeS
->SetLimitLabels("1", "100");
318 fPenSizeS
->SetModificationMessage(new BMessage(MSG_SET_PEN_SIZE
));
319 fPenSizeS
->SetHashMarks(B_HASH_MARKS_BOTTOM
);
320 fPenSizeS
->SetHashMarkCount(10);
322 controlGroup
->AddChild(fPenSizeS
);
324 // list view with objects
325 b
= controlGroup
->Bounds();
326 b
.top
+= controlGroup
->InnerFrame().top
;
327 b
.InsetBy(10.0, 10.0);
328 b
.left
= b
.left
+ b
.Width() / 2.0 + 6.0;
329 b
.right
-= B_V_SCROLL_BAR_WIDTH
;
330 b
.bottom
= fDrawingModeMF
->Frame().top
- 10.0;
332 fObjectLV
= new ObjectListView(b
, "object list", B_SINGLE_SELECTION_LIST
);
333 fObjectLV
->SetSelectionMessage(new BMessage(MSG_OBJECT_SELECTED
));
335 // wrap a scroll view around the list view
336 scrollView
= new BScrollView("list scroller", fObjectLV
,
337 B_FOLLOW_NONE
, 0, false, true, B_FANCY_BORDER
);
338 controlGroup
->AddChild(scrollView
);
340 // enforce some size limits
341 float minWidth
= controlGroup
->Frame().Width() + 30.0;
342 float minHeight
= fPenSizeS
->Frame().bottom
343 + menuBar
->Bounds().Height() + 15.0;
344 float maxWidth
= minWidth
* 4.0;
345 float maxHeight
= minHeight
+ 100;
346 SetSizeLimits(minWidth
, maxWidth
, minHeight
, maxHeight
);
348 ResizeTo(max_c(frame
.Width(), minWidth
), max_c(frame
.Height(), minHeight
));
354 ObjectWindow::~ObjectWindow()
360 ObjectWindow::QuitRequested()
362 be_app
->PostMessage(B_QUIT_REQUESTED
);
368 ObjectWindow::MessageReceived(BMessage
* message
)
370 switch (message
->what
) {
371 case MSG_SET_OBJECT_TYPE
: {
373 if (message
->FindInt32("type", &type
) >= B_OK
) {
374 fObjectView
->SetObjectType(type
);
375 fFillCB
->SetEnabled(type
!= OBJECT_LINE
);
376 if (!fFillCB
->IsEnabled())
377 fPenSizeS
->SetEnabled(true);
379 fPenSizeS
->SetEnabled(fFillCB
->Value() == B_CONTROL_OFF
);
383 case MSG_SET_FILL_OR_STROKE
: {
385 if (message
->FindInt32("be:value", &value
) >= B_OK
) {
386 fObjectView
->SetStateFill(value
);
387 fPenSizeS
->SetEnabled(value
== B_CONTROL_OFF
);
392 fObjectView
->SetStateColor(_GetColor());
393 _UpdateColorControls();
395 case MSG_OBJECT_ADDED
: {
397 if (message
->FindPointer("object", (void**)&object
) >= B_OK
) {
398 fObjectLV
->AddItem(new ObjectItem("Object", object
));
402 case MSG_OBJECT_COUNT_CHANGED
:
403 fClearB
->SetEnabled(fObjectView
->CountObjects() > 0);
405 case MSG_OBJECT_SELECTED
:
406 if (ObjectItem
* item
= (ObjectItem
*)fObjectLV
->ItemAt(fObjectLV
->CurrentSelection(0))) {
407 fObjectView
->SetState(item
->Object());
408 fObjectView
->SetStateColor(item
->Object()->Color());
411 fObjectView
->SetState(NULL
);
413 case MSG_REMOVE_OBJECT
:
414 while (ObjectItem
* item
= (ObjectItem
*)fObjectLV
->ItemAt(fObjectLV
->CurrentSelection(0))) {
415 fObjectView
->RemoveObject(item
->Object());
416 fObjectLV
->RemoveItem(item
);
421 fObjectView
->SetState(NULL
);
424 BAlert
*alert
= new BAlert("Playground",
425 B_TRANSLATE("Clear all drawing objects?"),
426 B_TRANSLATE("Cancel"), B_TRANSLATE("Clear"));
427 alert
->SetShortcut(0, B_ESCAPE
);
428 if (alert
->Go() == 1) {
429 fObjectView
->MakeEmpty();
430 fObjectLV
->MakeEmpty();
434 case MSG_SET_PEN_SIZE
:
435 fObjectView
->SetStatePenSize((float)fPenSizeS
->Value());
437 case MSG_SET_DRAWING_MODE
: {
439 if (message
->FindInt32("mode", (int32
*)&mode
) >= B_OK
) {
440 fObjectView
->SetStateDrawingMode(mode
);
445 BWindow::MessageReceived(message
);
451 ObjectWindow::_UpdateControls() const
453 _UpdateColorControls();
456 fClearB
->SetEnabled(fObjectView
->CountObjects() > 0);
458 fFillCB
->SetEnabled(fObjectView
->ObjectType() != OBJECT_LINE
);
461 fPenSizeS
->SetValue((int32
)fObjectView
->StatePenSize());
463 // disable penSize if fill is on
464 if (!fFillCB
->IsEnabled())
465 fPenSizeS
->SetEnabled(true);
467 fPenSizeS
->SetEnabled(fFillCB
->Value() == B_CONTROL_OFF
);
470 // _UpdateColorControls
472 ObjectWindow::_UpdateColorControls() const
475 rgb_color c
= fObjectView
->StateColor();
478 sprintf(string
, "%d", c
.alpha
);
479 fAlphaTC
->SetText(string
);
481 fColorControl
->SetValue(c
);
486 ObjectWindow::_GetColor() const
490 c
= fColorControl
->ValueAsColor();
491 c
.alpha
= max_c(0, min_c(255, atoi(fAlphaTC
->Text())));