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