// // The author of this software is abiSoft. Inc. // Copyright (c) 1998 abiSoft. Inc. // Permission to use, copy, modify, and distribute this software for any // purpose without fee is hereby granted, provided that this entire notice // is included in all copies of any software which is or includes a copy // or modification of this software and in all copies of the supporting // documentation for such software. // THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED // WARRANTY. IN PARTICULAR, THE AUTHOR DOES NOT MAKE ANY // REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY // OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. // #include "DemoApp.h" #include "ButtonWindow.h" #include "Util.h" DemoApp::DemoApp() : BApplication(signature) { float ButtonHeight = 128; float ButtonWidth = 80; //create some dummy labels for three buttons -- in this demo, the leftmost //and rightmost buttons will be arrows char *label1[] = {"", " Quit"}; //this chicanery overcomes automatic centering char *label2[] = {"", "", "This is a", "Toggle", "Button"}; char *label3[] = {"", "Press Me"}; //The definition for ButtonStruct is in abisoftButtonBox.h //The concept is freely borrowed from Dan Heller's Motif Programmer's Manual, //Volume 6 of the series on X Windows Programming from O'Reilly & Associates // struct ButtonStruct {char **labels; // array of strings to display // // centered in button // int argc; //the number of strings in array // int32 type; // see the enum in abisoftButton.h // char *pictureName; //file name in Images directory (see abisoftButton.h) // _or_ full path main picture to display // uint32 what; //what is sent in the message when the button is pressed // char **togglelabels; //array of strings to display if the button toggles labels // int argc2; //number of strings in the toggle string array // char *picture2Name; //same as pictureName, for toggle picture // //}; //initializing structs is _easier_ in c++ than in c ButtonStruct BStruct[] = { //labels argc type picturename what tlabels argc2 p2name {NULL, 0, A_LEFT_ARROW}, {NULL, 0, A_STRING, "chair.tga", B_ABOUT_REQUESTED}, {label1, 2, A_STRING, "klee.tga", B_QUIT_REQUESTED}, {label2, 5, A_TWO_STRING, "pixel1.jpg", NULL, label3, 2, "ford2.jpg"}, {NULL, 0, A_RIGHT_ARROW} }; int32 NelBStruct = sizeof(BStruct) / sizeof(ButtonStruct); orientation Layout = B_HORIZONTAL; //uncomment the next line to set to vertical layout //Layout = B_VERTICAL; int32 NumHorizButtons = NelBStruct; //default set for horizontal int32 NumVertButtons = 1; //default set for horizontal if (Layout == B_VERTICAL) { NumHorizButtons = 1; NumVertButtons = NelBStruct; } //create a BRect with its top left point at (50,50) //tall enough to hold the NumVertButtons buttons, //and wide enough to hold NumHorizButtons buttons //BUT we only allow one dimensional button arrays! BRect aRect(50.0, 50.0, 50.0 + (ButtonWidth * NumHorizButtons), 50.0 + (ButtonHeight * NumVertButtons)) ; //for a vertical layout of buttons, create the BRect wide enough //to hold 1 button and tall enough for five buttons ButtonWindow *tWindow = new ButtonWindow (aRect, "aButtons!", B_TITLED_WINDOW, B_NOT_RESIZABLE); //the abisoftButtonBox will be a child of the ButtonWindow //we want the abisoftButtonBox to start at (0,0) in the //ButtonWindow aRect.OffsetTo(B_ORIGIN); //create the abisoftButtonBox object //it's possible to create a vertical or a horizontal layout for the buttons //the last argument to abisoftButtonBox is B_VERTICAL or B_HORIZONTAL //depending on whether the number of vertical buttons is greater than one abisoftButtonBox *abox = new abisoftButtonBox(aRect, "test", B_FOLLOW_ALL, BStruct, NelBStruct, (NumVertButtons > 1) ? B_VERTICAL : B_HORIZONTAL); //make the abisoftuttonBox (which inherits from BView) a child of the window //set some colors //the names of the colors are from rgbtab.h in the Xpm distribution, abox->SetABackgroundColor(BeRgbColorFromName("Yellow"), 0); abox->SetABackgroundColor(BeRgbColorFromName("Red"), 3); abox->SetABackgroundColor(BeRgbColorFromName("linen"), 4); abox->SetABackgroundColor(BeRgbColorFromName("SteelBlue"), 2); //set font size of the Fourth button //abox->SetAFontSize(3, 14); //button numbers start with zero //set the font of the Third button BFont newFont; newFont.SetSize(20); //using wired in names is bad, but this is a demo newFont.SetFamilyAndStyle("Swis721 BT", "Bold Italic"); //abox->SetALabelFont(2, newFont); tWindow->AddChild(abox); //start the window thread tWindow->Show(); } //this is a stub function //run the program from a terminal window to see that messages are actually received //an exercise for the reader: save information from the color and font messsages //using libpreferences.so //a finished application, of course, would do something with these messages void DemoApp::MessageReceived(BMessage *msg) { switch(msg->what) { case SAVE_COLOR : printf("save color in message received\n"); break; case SAVE_FONT: printf("save font in message received\n"); break; default: printf ("default\n"); } } const char aboutMessage[] = { "The author of this software is abiSoft. Inc. \ .P\ \tCopyright (c) 1998 abiSoft. Inc.\ .P\ Permission to use, copy, modify, and distribute this software for any \ purpose without fee is hereby granted, provided that this entire notice \ is included in all copies of any software which is or includes a copy \ or modification of this software and in all copies of the supporting \ documentation for such software. \ In addition if any portion of this code is included in a program \ that does not include source credit must be given to the AbiSoft, Inc. \ .P\ .P\ THIS SOFTWARE IS BEING PROVIDED \"AS IS\", WITHOUT ANY EXPRESS OR IMPLIED \ WARRANTY. IN PARTICULAR, THE AUTHOR DOES NOT MAKE ANY \ REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY \ OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE."}; void DemoApp::AboutRequested(void) { BAlert *alert = new BAlert("About abiSoftButtons", "", "Docs", "Updates", "Dismiss", B_WIDTH_FROM_WIDEST); //resize the alert window bigger float NewWidth = 300.0; //arbitrary width float NewHeight = NewWidth * .80; // //remove the textview and make a child of a scrolled view BTextView *aboutView = alert->TextView(); aboutView->SetStylable(true); aboutView->SetAlignment(B_ALIGN_LEFT); aboutView->SetWordWrap(true); //aboutView->ResizeTo(aboutView->Bounds().Width()-10, aboutView->Bounds().Height()); //parse the aboutMessage to change \n to ' ' to we can wordwrap //use a .P at the start of the line to force a line break char *buf = strdup(aboutMessage); int32 length = strlen(aboutMessage); for (int32 i = 0; i < length; i++) { if (buf[i] == '.' && buf[i+1] == 'P' && buf[i+2] == '\n') { buf[i] = ' '; buf[i+1] = ' '; buf[i+2] = '\n'; i+= 2; } else if (buf[i] == '\n') buf[i] = ' '; } aboutView->SetText(buf); free (buf); BWindow *w = aboutView->Window(); BView *fView = w->ChildAt(0); fView->RemoveChild(aboutView); //now create our scrolled view BScrollView *scroll = new BScrollView( "licenseScroll", aboutView, B_FOLLOW_ALL, (ulong) 0, false, true); fView->AddChild(scroll); //resize the window alert->ResizeTo(NewWidth, NewHeight); scroll->MoveBy(-7,0); //reposition the buttons -- why should they all be together flush right? BButton *but = alert->ButtonAt(0); BRect f = but->Frame(); but->MoveTo(aboutView->Frame().left + 30.0, f.top); //now put the middle button in the middle float bLeft = but->Frame().right; but = alert->ButtonAt(2); float bRight = but->Frame().left; but = alert->ButtonAt(1); float x, y; but->GetPreferredSize(&x, &y); but->MoveTo( bLeft + (bRight - bLeft) * .5 - x * .5, f.top); //now, launch the popup int32 choice = alert->Go(); //choice returns 0, 1, or 2 //0 is the first button, 1 the 2nd 2 the 3rd if(choice == 0) { //Launch netpositive with docs BMessage msg(B_ARGV_RECEIVED); //they chose button # 1 //Create a BMessage that we are going to send //to NetPositive. If it is running we use a messenger //to send it there otherwise we launch it using the //be_roster //assume that we installed the html documents in Docs directory, within the //directory in which the application lives app_info ai; GetAppInfo(&ai); //now get the parent directory BEntry Entry(&ai.ref); BPath path; Entry.GetPath(&path); BPath parentPath; path.GetParent(&parentPath); char buf[B_FILE_NAME_LENGTH +1]; sprintf(buf, "file://%s/%s/index.html", parentPath.Path(), "Docs"); //now create the argv for Net+ msg.AddString("argv", "NetPositive"); msg.AddString("argv", buf); msg.AddInt32("argc", 2); BMessenger messenger("application/x-vnd.Be-NPOS", -1, NULL); if (messenger.IsValid()) messenger.SendMessage( &msg ); else be_roster->Launch("application/x-vnd.Be-NPOS", &msg); } else if(choice == 1) { //Launch netpositive with abisoft page looking for updates BMessage msg(B_ARGV_RECEIVED); msg.AddString("argv", "NetPositive"); msg.AddString("argv", "http://www.abisoft.com/Buttons/"); msg.AddInt32("argc", 2); BMessenger messenger("application/x-vnd.Be-NPOS", -1, NULL); if (messenger.IsValid()) messenger.SendMessage( &msg ); else be_roster->Launch("application/x-vnd.Be-NPOS", &msg); } }