178c1c29bSStephan Aßmus // main.cpp 278c1c29bSStephan Aßmus 378c1c29bSStephan Aßmus #include <stdio.h> 478c1c29bSStephan Aßmus #include <stdlib.h> 578c1c29bSStephan Aßmus 678c1c29bSStephan Aßmus #include <Application.h> 7*4dfc2afbSAxel Dörfler #include <Alert.h> 878c1c29bSStephan Aßmus #include <Box.h> 978c1c29bSStephan Aßmus #include <Button.h> 1078c1c29bSStephan Aßmus #include <CheckBox.h> 1178c1c29bSStephan Aßmus #include <Menu.h> 1278c1c29bSStephan Aßmus #include <MenuBar.h> 1378c1c29bSStephan Aßmus #include <MenuItem.h> 1478c1c29bSStephan Aßmus #include <String.h> 1578c1c29bSStephan Aßmus #include <RadioButton.h> 1678c1c29bSStephan Aßmus #include <TextControl.h> 1778c1c29bSStephan Aßmus #include <TextView.h> 1878c1c29bSStephan Aßmus 1978c1c29bSStephan Aßmus #include "ObjectView.h" 2078c1c29bSStephan Aßmus #include "States.h" 2178c1c29bSStephan Aßmus 2278c1c29bSStephan Aßmus #include "ObjectWindow.h" 2378c1c29bSStephan Aßmus 2478c1c29bSStephan Aßmus enum { 2578c1c29bSStephan Aßmus MSG_SET_OBJECT_TYPE = 'stot', 2678c1c29bSStephan Aßmus MSG_SET_FILL_OR_STROKE = 'stfs', 2778c1c29bSStephan Aßmus MSG_SET_COLOR = 'stcl', 2878c1c29bSStephan Aßmus MSG_SET_PEN_SIZE = 'stps', 2978c1c29bSStephan Aßmus 3078c1c29bSStephan Aßmus MSG_NEW_OBJECT = 'nobj', 3178c1c29bSStephan Aßmus 3278c1c29bSStephan Aßmus MSG_UNDO = 'undo', 3378c1c29bSStephan Aßmus MSG_REDO = 'redo', 3478c1c29bSStephan Aßmus 3578c1c29bSStephan Aßmus MSG_CLEAR = 'clir', 3678c1c29bSStephan Aßmus }; 3778c1c29bSStephan Aßmus 3878c1c29bSStephan Aßmus // constructor 3978c1c29bSStephan Aßmus ObjectWindow::ObjectWindow(BRect frame, const char* name) 4078c1c29bSStephan Aßmus : BWindow(frame, name, B_TITLED_WINDOW, B_ASYNCHRONOUS_CONTROLS) 4178c1c29bSStephan Aßmus { 4278c1c29bSStephan Aßmus BRect b(Bounds()); 4378c1c29bSStephan Aßmus 4478c1c29bSStephan Aßmus b.bottom = b.top + 8; 4578c1c29bSStephan Aßmus BMenuBar* menuBar = new BMenuBar(b, "menu bar"); 4678c1c29bSStephan Aßmus AddChild(menuBar); 4778c1c29bSStephan Aßmus 4878c1c29bSStephan Aßmus BMenu* menu = new BMenu("Menus"); 4978c1c29bSStephan Aßmus menuBar->AddItem(menu); 5078c1c29bSStephan Aßmus 5178c1c29bSStephan Aßmus BMenuItem* menuItem = new BMenuItem("Quit", NULL, 'Q'); 5278c1c29bSStephan Aßmus menu->AddItem(menuItem); 5378c1c29bSStephan Aßmus 5478c1c29bSStephan Aßmus menuBar->AddItem(new BMenu("don't")); 5578c1c29bSStephan Aßmus menuBar->AddItem(new BMenu("work!")); 5678c1c29bSStephan Aßmus menuBar->AddItem(new BMenu("(yet)")); 5778c1c29bSStephan Aßmus 5878c1c29bSStephan Aßmus b = Bounds(); 5978c1c29bSStephan Aßmus b.top = menuBar->Bounds().bottom + 1; 6078c1c29bSStephan Aßmus BBox* bg = new BBox(b, "bg box", B_FOLLOW_ALL, B_WILL_DRAW, B_PLAIN_BORDER); 6178c1c29bSStephan Aßmus 6278c1c29bSStephan Aßmus AddChild(bg); 6378c1c29bSStephan Aßmus bg->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); 6478c1c29bSStephan Aßmus 6578c1c29bSStephan Aßmus b = bg->Bounds(); 6678c1c29bSStephan Aßmus // object views occupies the right side of the window 6778c1c29bSStephan 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); 6878c1c29bSStephan Aßmus fObjectView = new ObjectView(b, "object view", B_FOLLOW_ALL, 6978c1c29bSStephan Aßmus B_WILL_DRAW | B_FULL_UPDATE_ON_RESIZE); 7078c1c29bSStephan Aßmus 7178c1c29bSStephan Aßmus bg->AddChild(fObjectView); 7278c1c29bSStephan Aßmus 7378c1c29bSStephan Aßmus b = bg->Bounds(); 7478c1c29bSStephan Aßmus // controls occupy the left side of the window 7578c1c29bSStephan 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); 7678c1c29bSStephan Aßmus BBox* controlGroup = new BBox(b, "controls box", B_FOLLOW_LEFT | B_FOLLOW_TOP_BOTTOM, 7778c1c29bSStephan Aßmus B_WILL_DRAW, B_FANCY_BORDER); 7878c1c29bSStephan Aßmus 7978c1c29bSStephan Aßmus controlGroup->SetLabel("Controls"); 8078c1c29bSStephan Aßmus bg->AddChild(controlGroup); 8178c1c29bSStephan Aßmus 8278c1c29bSStephan Aßmus b = controlGroup->Bounds(); 8378c1c29bSStephan Aßmus b.top += 10.0; 8478c1c29bSStephan Aßmus b.bottom = b.top + 25.0; 8578c1c29bSStephan Aßmus b.InsetBy(5.0, 5.0); 8678c1c29bSStephan Aßmus 8778c1c29bSStephan Aßmus // new button 8878c1c29bSStephan Aßmus fNewB = new BButton(b, "new button", "New Object", new BMessage(MSG_NEW_OBJECT)); 8978c1c29bSStephan Aßmus controlGroup->AddChild(fNewB); 9078c1c29bSStephan Aßmus 9178c1c29bSStephan Aßmus // clear button 9278c1c29bSStephan Aßmus b.OffsetBy(0, fNewB->Bounds().Height() + 5.0); 9378c1c29bSStephan Aßmus fClearB = new BButton(b, "clear button", "Clear", new BMessage(MSG_CLEAR)); 9478c1c29bSStephan Aßmus controlGroup->AddChild(fClearB); 9578c1c29bSStephan Aßmus 9678c1c29bSStephan Aßmus // object type radio buttons 9778c1c29bSStephan Aßmus BMessage* message; 9878c1c29bSStephan Aßmus BRadioButton* radioButton; 9978c1c29bSStephan Aßmus 10078c1c29bSStephan Aßmus b.OffsetBy(0, fClearB->Bounds().Height() + 5.0); 10178c1c29bSStephan Aßmus message = new BMessage(MSG_SET_OBJECT_TYPE); 10278c1c29bSStephan Aßmus message->AddInt32("type", OBJECT_LINE); 10378c1c29bSStephan Aßmus radioButton = new BRadioButton(b, "radio 1", "Line", message); 10478c1c29bSStephan Aßmus controlGroup->AddChild(radioButton); 10578c1c29bSStephan Aßmus 10678c1c29bSStephan Aßmus radioButton->SetValue(B_CONTROL_ON); 10778c1c29bSStephan Aßmus 10878c1c29bSStephan Aßmus b.OffsetBy(0, radioButton->Bounds().Height() + 5.0); 10978c1c29bSStephan Aßmus message = new BMessage(MSG_SET_OBJECT_TYPE); 11078c1c29bSStephan Aßmus message->AddInt32("type", OBJECT_RECT); 11178c1c29bSStephan Aßmus radioButton = new BRadioButton(b, "radio 2", "Rect", message); 11278c1c29bSStephan Aßmus controlGroup->AddChild(radioButton); 11378c1c29bSStephan Aßmus 11478c1c29bSStephan Aßmus b.OffsetBy(0, radioButton->Bounds().Height() + 5.0); 11578c1c29bSStephan Aßmus message = new BMessage(MSG_SET_OBJECT_TYPE); 11678c1c29bSStephan Aßmus message->AddInt32("type", OBJECT_ROUND_RECT); 11778c1c29bSStephan Aßmus radioButton = new BRadioButton(b, "radio 3", "Round Rect", message); 11878c1c29bSStephan Aßmus controlGroup->AddChild(radioButton); 11978c1c29bSStephan Aßmus 12078c1c29bSStephan Aßmus b.OffsetBy(0, radioButton->Bounds().Height() + 5.0); 12178c1c29bSStephan Aßmus message = new BMessage(MSG_SET_OBJECT_TYPE); 12278c1c29bSStephan Aßmus message->AddInt32("type", OBJECT_ELLIPSE); 12378c1c29bSStephan Aßmus radioButton = new BRadioButton(b, "radio 4", "Ellipse", message); 12478c1c29bSStephan Aßmus controlGroup->AddChild(radioButton); 12578c1c29bSStephan Aßmus 12678c1c29bSStephan Aßmus // red text control 12778c1c29bSStephan Aßmus b.OffsetBy(0, radioButton->Bounds().Height() + 5.0); 12878c1c29bSStephan Aßmus fRedTC = new BTextControl(b, "red text control", "Red", "", 12978c1c29bSStephan Aßmus new BMessage(MSG_SET_COLOR)); 13078c1c29bSStephan Aßmus controlGroup->AddChild(fRedTC); 13178c1c29bSStephan Aßmus 13278c1c29bSStephan Aßmus // green text control 13378c1c29bSStephan Aßmus b.OffsetBy(0, fRedTC->Bounds().Height() + 5.0); 13478c1c29bSStephan Aßmus fGreenTC = new BTextControl(b, "green text control", "Green", "", 13578c1c29bSStephan Aßmus new BMessage(MSG_SET_COLOR)); 13678c1c29bSStephan Aßmus controlGroup->AddChild(fGreenTC); 13778c1c29bSStephan Aßmus 13878c1c29bSStephan Aßmus // blue text control 13978c1c29bSStephan Aßmus b.OffsetBy(0, fGreenTC->Bounds().Height() + 5.0); 14078c1c29bSStephan Aßmus fBlueTC = new BTextControl(b, "blue text control", "Blue", "", 14178c1c29bSStephan Aßmus new BMessage(MSG_SET_COLOR)); 14278c1c29bSStephan Aßmus controlGroup->AddChild(fBlueTC); 14378c1c29bSStephan Aßmus 14478c1c29bSStephan Aßmus // alpha text control 14578c1c29bSStephan Aßmus b.OffsetBy(0, fBlueTC->Bounds().Height() + 5.0); 14678c1c29bSStephan Aßmus fAlphaTC = new BTextControl(b, "alpha text control", "Alpha", "", 14778c1c29bSStephan Aßmus new BMessage(MSG_SET_COLOR)); 14878c1c29bSStephan Aßmus controlGroup->AddChild(fAlphaTC); 14978c1c29bSStephan Aßmus /* 15078c1c29bSStephan Aßmus // TODO: while this block of code works in the Haiku app_server running under R5, 15178c1c29bSStephan Aßmus // it crashes pretty badly under Haiku. I have no idea why this happens, because 15278c1c29bSStephan Aßmus // I was doing the same thing before at other places. 15378c1c29bSStephan Aßmus // divide text controls the same 15478c1c29bSStephan Aßmus float rWidth = fRedTC->StringWidth(fRedTC->Label()); 15578c1c29bSStephan Aßmus float gWidth = fGreenTC->StringWidth(fGreenTC->Label()); 15678c1c29bSStephan Aßmus float bWidth = fBlueTC->StringWidth(fBlueTC->Label()); 15778c1c29bSStephan Aßmus float aWidth = fAlphaTC->StringWidth(fAlphaTC->Label()); 15878c1c29bSStephan Aßmus 15978c1c29bSStephan Aßmus float width = max_c(rWidth, max_c(gWidth, max_c(bWidth, aWidth))) + 10.0; 16078c1c29bSStephan Aßmus fRedTC->SetDivider(width); 16178c1c29bSStephan Aßmus fGreenTC->SetDivider(width); 16278c1c29bSStephan Aßmus fBlueTC->SetDivider(width); 16378c1c29bSStephan Aßmus fAlphaTC->SetDivider(width);*/ 16478c1c29bSStephan Aßmus 16578c1c29bSStephan Aßmus // fill check box 16678c1c29bSStephan Aßmus b.OffsetBy(0, fAlphaTC->Bounds().Height() + 5.0); 16778c1c29bSStephan Aßmus fFillCB = new BCheckBox(b, "fill check box", "Fill", 16878c1c29bSStephan Aßmus new BMessage(MSG_SET_FILL_OR_STROKE)); 16978c1c29bSStephan Aßmus controlGroup->AddChild(fFillCB); 17078c1c29bSStephan Aßmus 17178c1c29bSStephan Aßmus // pen size text control 17278c1c29bSStephan Aßmus b.OffsetBy(0, radioButton->Bounds().Height() + 5.0); 17378c1c29bSStephan Aßmus fPenSizeTC = new BTextControl(b, "width text control", "Width", "", 17478c1c29bSStephan Aßmus new BMessage(MSG_SET_PEN_SIZE)); 17578c1c29bSStephan Aßmus controlGroup->AddChild(fPenSizeTC); 17678c1c29bSStephan Aßmus 17778c1c29bSStephan Aßmus _UpdateControls(); 17878c1c29bSStephan Aßmus } 17978c1c29bSStephan Aßmus 18078c1c29bSStephan Aßmus // destructor 18178c1c29bSStephan Aßmus ObjectWindow::~ObjectWindow() 18278c1c29bSStephan Aßmus { 18378c1c29bSStephan Aßmus } 18478c1c29bSStephan Aßmus 18578c1c29bSStephan Aßmus // QuitRequested 18678c1c29bSStephan Aßmus bool 18778c1c29bSStephan Aßmus ObjectWindow::QuitRequested() 18878c1c29bSStephan Aßmus { 18978c1c29bSStephan Aßmus be_app->PostMessage(B_QUIT_REQUESTED); 19078c1c29bSStephan Aßmus return true; 19178c1c29bSStephan Aßmus } 19278c1c29bSStephan Aßmus 19378c1c29bSStephan Aßmus // MessageReceived 19478c1c29bSStephan Aßmus void 19578c1c29bSStephan Aßmus ObjectWindow::MessageReceived(BMessage* message) 19678c1c29bSStephan Aßmus { 19778c1c29bSStephan Aßmus switch (message->what) { 19878c1c29bSStephan Aßmus case MSG_SET_OBJECT_TYPE: { 19978c1c29bSStephan Aßmus int32 type; 20078c1c29bSStephan Aßmus if (message->FindInt32("type", &type) >= B_OK) { 20178c1c29bSStephan Aßmus fObjectView->SetObjectType(type); 20278c1c29bSStephan Aßmus fFillCB->SetEnabled(type != OBJECT_LINE); 203e803c97cSStephan Aßmus if (!fFillCB->IsEnabled()) 204e803c97cSStephan Aßmus fPenSizeTC->SetEnabled(true); 205e803c97cSStephan Aßmus else 206e803c97cSStephan Aßmus fPenSizeTC->SetEnabled(fFillCB->Value() == B_CONTROL_OFF); 20778c1c29bSStephan Aßmus } 20878c1c29bSStephan Aßmus break; 20978c1c29bSStephan Aßmus } 21078c1c29bSStephan Aßmus case MSG_SET_FILL_OR_STROKE: { 21178c1c29bSStephan Aßmus int32 value; 21278c1c29bSStephan Aßmus if (message->FindInt32("be:value", &value) >= B_OK) { 21378c1c29bSStephan Aßmus fObjectView->SetStateFill(value); 21478c1c29bSStephan Aßmus fPenSizeTC->SetEnabled(value == B_CONTROL_OFF); 21578c1c29bSStephan Aßmus } 21678c1c29bSStephan Aßmus break; 21778c1c29bSStephan Aßmus } 21878c1c29bSStephan Aßmus case MSG_SET_COLOR: 21978c1c29bSStephan Aßmus fObjectView->SetStateColor(_GetColor()); 22078c1c29bSStephan Aßmus break; 22178c1c29bSStephan Aßmus case MSG_OBJECT_COUNT_CHANGED: 22278c1c29bSStephan Aßmus fClearB->SetEnabled(fObjectView->CountObjects() > 0); 22378c1c29bSStephan Aßmus break; 22478c1c29bSStephan Aßmus case MSG_NEW_OBJECT: 22578c1c29bSStephan Aßmus fObjectView->SetState(NULL); 22678c1c29bSStephan Aßmus break; 227*4dfc2afbSAxel Dörfler case MSG_CLEAR: { 228*4dfc2afbSAxel Dörfler BAlert *alert = new BAlert("Playground", "Do you really want to clear all drawing objects?", "No", "Yes"); 229*4dfc2afbSAxel Dörfler if (alert->Go() == 1) 23078c1c29bSStephan Aßmus fObjectView->MakeEmpty(); 23178c1c29bSStephan Aßmus break; 232*4dfc2afbSAxel Dörfler } 23378c1c29bSStephan Aßmus case MSG_SET_PEN_SIZE: 23478c1c29bSStephan Aßmus fObjectView->SetStatePenSize(atof(fPenSizeTC->Text())); 23578c1c29bSStephan Aßmus break; 23678c1c29bSStephan Aßmus default: 23778c1c29bSStephan Aßmus BWindow::MessageReceived(message); 23878c1c29bSStephan Aßmus } 23978c1c29bSStephan Aßmus } 24078c1c29bSStephan Aßmus 24178c1c29bSStephan Aßmus // _UpdateControls 24278c1c29bSStephan Aßmus void 24378c1c29bSStephan Aßmus ObjectWindow::_UpdateControls() const 24478c1c29bSStephan Aßmus { 24578c1c29bSStephan Aßmus // update color 24678c1c29bSStephan Aßmus rgb_color c = fObjectView->StateColor(); 24778c1c29bSStephan Aßmus char string[32]; 24878c1c29bSStephan Aßmus 24978c1c29bSStephan Aßmus sprintf(string, "%d", c.red); 25078c1c29bSStephan Aßmus fRedTC->SetText(string); 25178c1c29bSStephan Aßmus 25278c1c29bSStephan Aßmus sprintf(string, "%d", c.green); 25378c1c29bSStephan Aßmus fGreenTC->SetText(string); 25478c1c29bSStephan Aßmus 25578c1c29bSStephan Aßmus sprintf(string, "%d", c.blue); 25678c1c29bSStephan Aßmus fBlueTC->SetText(string); 25778c1c29bSStephan Aßmus 25878c1c29bSStephan Aßmus sprintf(string, "%d", c.alpha); 25978c1c29bSStephan Aßmus fAlphaTC->SetText(string); 26078c1c29bSStephan Aßmus 26178c1c29bSStephan Aßmus 26278c1c29bSStephan Aßmus // update buttons 26378c1c29bSStephan Aßmus fClearB->SetEnabled(fObjectView->CountObjects() > 0); 26478c1c29bSStephan Aßmus 26578c1c29bSStephan Aßmus fFillCB->SetEnabled(fObjectView->ObjectType() != OBJECT_LINE); 26678c1c29bSStephan Aßmus 26778c1c29bSStephan Aßmus // disable penSize if fill is on 26878c1c29bSStephan Aßmus sprintf(string, "%.1f", fObjectView->StatePenSize()); 26978c1c29bSStephan Aßmus fPenSizeTC->SetText(string); 270e803c97cSStephan Aßmus if (!fFillCB->IsEnabled()) 271e803c97cSStephan Aßmus fPenSizeTC->SetEnabled(true); 272e803c97cSStephan Aßmus else 273e803c97cSStephan Aßmus fPenSizeTC->SetEnabled(fFillCB->Value() == B_CONTROL_OFF); 27478c1c29bSStephan Aßmus } 27578c1c29bSStephan Aßmus 27678c1c29bSStephan Aßmus // _GetColor 27778c1c29bSStephan Aßmus rgb_color 27878c1c29bSStephan Aßmus ObjectWindow::_GetColor() const 27978c1c29bSStephan Aßmus { 28078c1c29bSStephan Aßmus rgb_color c; 28178c1c29bSStephan Aßmus c.red = max_c(0, min_c(255, atoi(fRedTC->Text()))); 28278c1c29bSStephan Aßmus c.green = max_c(0, min_c(255, atoi(fGreenTC->Text()))); 28378c1c29bSStephan Aßmus c.blue = max_c(0, min_c(255, atoi(fBlueTC->Text()))); 28478c1c29bSStephan Aßmus c.alpha = max_c(0, min_c(255, atoi(fAlphaTC->Text()))); 28578c1c29bSStephan Aßmus 28678c1c29bSStephan Aßmus return c; 28778c1c29bSStephan Aßmus } 28878c1c29bSStephan Aßmus 289