/* Project CADshell Mechanical Design Research Lab Mechanical Engineering - Engineering Mechanics Dept. Michigan Technological University Copyright (C) 2001. All Rights Reserved. FILE: controls_main.cc MODULE: CADshell REQUIRES LIBRARIES: libXm, libXt, libX11 AUTHOR(S): Bernie Bettig OVERVIEW ======== Source for sh_MainWindow (sh_FramedControl), sh_MenuBar (sh_CompositeControl), sh_PulldownMenu (sh_CompositeControl), sh_ToolBox (sh_CompositeControl), sh_StatusBar (sh_CompositeControl). */ #include "controls_main.h" #include #if defined (CADSHELL) #include #endif #if !defined (MAXPATH) #define MAXPATH 160 #endif #include #include #include #include #include #include #include #include // functions for this file only void EvCommandCB(Widget w, XtPointer tool, XtPointer); /* -------------------------------------------------------------------------------------- sh_MainWindow -------------------------------------------------------------------------------------- */ static Atom close_main_window_atom; sh_MainWindow::sh_MainWindow(const char *caption, sh_Tool *atool) : sh_FramedControl(atool) { the_mainWindow = this; int argc = 0; char *argv[2]; topWidget = XtVaAppInitialize( &app, "Motif", NULL, 0, &argc, argv, NULL, NULL ); widget = XtVaCreateManagedWidget(caption, xmFormWidgetClass, topWidget, XmNfractionBase, 100, NULL); // capture window close from frame close_main_window_atom = XInternAtom( XtDisplay( topWidget ), "WM_DELETE_WINDOW", True ); XmAddWMProtocols( topWidget, &close_main_window_atom, 1 ); XmSetWMProtocolHooks( topWidget, close_main_window_atom, NULL, NULL, MainWindowCloseCB, NULL ); SetCaption(caption); } sh_MainWindow *sh_MainWindow::the_mainWindow = 0; void sh_MainWindow::Run() { Realize(); MainLoop(); } void sh_MainWindow::SetCaption(const char *title) { XtVaSetValues(topWidget, XmNtitle, title, NULL); } void sh_MainWindow::Realize() { XtRealizeWidget( topWidget ); TransferToControl(); } void sh_MainWindow::MainLoop() { XtAppMainLoop( app ); } void sh_MainWindow::ProcessNextEvent() { XEvent event; XtAppNextEvent(app, &event); XtDispatchEvent(&event); } void sh_MainWindow::FlushDisplay() { XFlush(XtDisplay(topWidget)); } /* Callback function to quit the program. */ void sh_MainWindow::MainWindowCloseCB(Widget, XtPointer, XtPointer call_data ) { XClientMessageEvent *cm = &((XmAnyCallbackStruct *)call_data)->event->xclient; if ( cm->data.l[0] == close_main_window_atom ) { sh_MainWindow *main_win = GetMainWindow(); main_win->stopClose = False; if (main_win->tool) { sh_Event ev("AboutToCloseProgram"); main_win->tool->ControlEvent(main_win, ev); } if (!main_win->stopClose) { XtDestroyWidget( main_win->GetTopWidget() ); exit( 0 ); } } } /* -------------------------------------------------------------------------------------- sh_MenuBar -------------------------------------------------------------------------------------- */ sh_MenuBar::sh_MenuBar(sh_CompositeControl *aparent, sh_Tool *atool) : sh_CompositeControl(aparent, atool) { widget = XmCreateMenuBar( parent->GetWidget(), "menubar", NULL, 0 ); XtManageChild( widget ); menuWidgets = 0; menuTools = 0; numMenuWidgets = 0; } sh_MenuBar::~sh_MenuBar() { if (menuWidgets) free(menuWidgets); if (menuTools) free(menuTools); } sh_PulldownMenu *sh_MenuBar::AddPulldownMenu(const char *label, char key, sh_CompositeControl *aparent) { if (!aparent) aparent = this; return new sh_PulldownMenu(aparent, label, key); } void sh_MenuBar::AddMenuButton(sh_CompositeControl *aparent, sh_Tool *atool, const char *label, char key) { sh_Control *c = atool->GetMenuButton(aparent, label, key); if (!c) c = new sh_Button(aparent, label, NULL, True, key); Widget w = c->GetWidget(); XtAddCallback(w, XmNactivateCallback, EvCommandCB, atool); menuTools = (sh_Tool **)realloc(menuTools, (numMenuWidgets+1)*sizeof(sh_Tool*)); menuWidgets = (Widget *)realloc(menuWidgets, (numMenuWidgets+1)*sizeof(Widget)); menuTools[numMenuWidgets] = atool; menuWidgets[numMenuWidgets] = w; numMenuWidgets++; } Widget sh_MenuBar::GetMenuWidget(sh_Tool *t) { for (int i=0; iGetResourceDir(), menuFile); #else sprintf(s, "./%s", menuFile); #endif file = fopen(s, "r"); if (!file) { #if defined (CADSHELL) if (sh_CADshell::GetShell()->GetDebugStream()) *sh_CADshell::GetShell()->GetDebugStream() << "Could not open menu file: " << s << endl << flush; #endif return; } fscanf(file, "%s", s); while(!feof(file) && strcmp(s, menuFile)) fscanf(file, "%s", s); parseMenu(file, this); fclose(file); } void sh_MenuBar::parseMenu(FILE *file, sh_CompositeControl *aparent) { char s[MAXPATH], label[40], key, toolName[40], *p1, *p2; sh_Tool *atool; sh_PulldownMenu *w; fscanf(file, "%s", s); while(!feof(file) && strcmp(s, "BEGIN")) fscanf(file, "%s", s); while(!feof(file) && strcmp(s, "END")) { if (!strcmp(s, "POPUP")) { fgets(s, MAXPATH, file); p1 = strchr(s, 34); // 34 is double quotes if (!p1) break; p1++; p2 = strchr(p1, 34); if (!p2) break; *p2 = 0; strcpy(label, p1); p2++; p1 = p2; p1 = strchr(p1, 39); // 39 is single quote if (!p1) break; p1++; key = *p1; w = AddPulldownMenu(label, key, aparent); parseMenu(file, w); } else if (!strcmp(s, "MENUITEM")) { fgets(s, MAXPATH, file); p1 = strchr(s, 34); // 34 is double quotes if (!p1) break; p1++; p2 = strchr(p1, 34); if (!p2) break; *p2 = 0; strcpy(label, p1); p2++; p1 = p2; p1 = strchr(p1, 39); // 39 is single quote if (!p1) break; p1++; key = *p1; p1 = strchr(p1, ','); if (!p1) break; p1++; #if defined (CADSHELL) sscanf(p1, "%s", toolName); atool = sh_CADshell::GetShell()->GetToolByName(toolName); if (atool) AddMenuButton(aparent, atool, label, key); #endif } else if (!strncmp(s, "//", 2)) // use '//' at beginning of line for comments fgets(s, MAXPATH, file); fscanf(file, "%s", s); } } sh_PulldownMenu::sh_PulldownMenu(sh_CompositeControl *aparent, const char *label, char key) : sh_CompositeControl(aparent, NULL) { if (aparent) { Widget w = XtVaCreateManagedWidget( label, xmCascadeButtonWidgetClass, aparent->GetWidget(), XmNmnemonic, key, NULL); widget = XmCreatePulldownMenu(aparent->GetWidget(), (char *)label, NULL, 0); XtVaSetValues(w, XmNsubMenuId, widget, NULL); } } /* -------------------------------------------------------------------------------------- sh_ToolBox -------------------------------------------------------------------------------------- */ sh_ToolBox::sh_ToolBox(sh_CompositeControl *aparent, Bool vertical) : sh_CompositeControl(aparent) { widget = XtVaCreateManagedWidget("controlBar", xmRowColumnWidgetClass, parent->GetWidget(), XmNorientation, vertical?XmVERTICAL:XmHORIZONTAL, NULL); XtManageChild( widget ); toolBoxWidgets = 0; toolBoxTools = 0; numToolBoxWidgets = 0; #if defined (CADSHELL) sh_CADshell::GetShell()->AddToolbar(this); #endif } sh_ToolBox::~sh_ToolBox() { #if defined (CADSHELL) sh_CADshell::GetShell()->RemoveToolbar(this); #endif if (toolBoxWidgets) free(toolBoxWidgets); if (toolBoxTools) free(toolBoxTools); } void sh_ToolBox::AddToolBoxButton(sh_Tool *atool, const char *label) { sh_Control *c = atool->GetControlBarButton(this, label); if (!c) { char s[MAXPATH]; sh_Button *b; #if defined (CADSHELL) if (atool->IsCommandInputImplemented() || atool->IsDialogInputImplemented() || atool->IsFramelessControlAvailable()) b = new sh_Button(this, label); else b = new sh_OnOffButton(this, "ControlBarButton"); sprintf(s, "%s/ICON_%s", sh_CADshell::GetShell()->GetResourceDir(), atool->GetName()); if (!b->SetPixmap(s)) if (label) { sprintf(s, "%s/%s", sh_CADshell::GetShell()->GetResourceDir(), label); if (!b->SetPixmap(s)) b->SetText(label); } #else if (label) { sprintf(s, "./%s", label); if (!b->SetPixmap(s)) b->SetText(label); } #endif c = b; } Widget w = c->GetWidget(); XtAddCallback(w, XmNactivateCallback, EvCommandCB, atool); toolBoxTools = (sh_Tool **)realloc(toolBoxTools, (numToolBoxWidgets+1)*sizeof(sh_Tool*)); toolBoxWidgets = (Widget *)realloc(toolBoxWidgets, (numToolBoxWidgets+1)*sizeof(Widget)); toolBoxTools[numToolBoxWidgets] = atool; toolBoxWidgets[numToolBoxWidgets] = w; numToolBoxWidgets++; } void sh_ToolBox::ConstructToolBox(const char *fileName) { FILE *file; char s[MAXPATH], label[40], toolName[40]; sh_Tool *atool; int n; #if defined (CADSHELL) sprintf(s, "%s/%s", sh_CADshell::GetShell()->GetResourceDir(), fileName); #else sprintf(s, "./%s", fileName); #endif file = fopen(s, "r"); if (!file) { char ss[110]; sprintf(ss, "Could not find toolbox resource file: %.80s", s); sh_MessageBox::Message(ss); return; } #if defined (CADSHELL) fscanf(file, "%s", s); while(!feof(file) && strcmp(s, fileName)) fscanf(file, "%s", s); fscanf(file, "%s", s); while(!feof(file) && strcmp(s, "BEGIN")) fscanf(file, "%s", s); while(!feof(file) && strcmp(s, "END")) { if (!strcmp(s, "TOOLBOXITEM")) { fgets(s, MAXPATH, file); n = sscanf(s, "%s%s", toolName, label); if (n) { atool = sh_CADshell::GetShell()->GetToolByName(toolName); if (atool) { if (n<2) strcpy(label, ""); AddToolBoxButton(atool, label); } else if (sh_CADshell::GetShell()->GetDebugStream()) *sh_CADshell::GetShell()->GetDebugStream() << "Warning: Toolbox::ConstructToolBox(): no " << toolName << " in CADshell\n" << flush; } } fscanf(file, "%s", s); } #endif } void sh_ToolBox::SetButton(sh_Tool *atool) { if (!atool) return; for (int i=0; iGetWidget(), XmNeditable, False, XmNcursorPositionVisible, False, XmNleftAttachment, XmATTACH_FORM, XmNrightAttachment, XmATTACH_FORM, XmNbottomAttachment, XmATTACH_FORM, NULL); XtManageChild( widget ); } void sh_StatusBar::SetProcessStatusText(const char *text) { if (text && text[0]) XmTextSetString(widget, (char *)text); else XmTextSetString(widget, commandText?commandText:""); } void sh_StatusBar::SetCommandText(const char *text) { if (commandText) { free (commandText); commandText = 0; } if (text) { commandText = strdup(text); XmTextSetString(widget, (char *)text); } else XmTextSetString(widget, ""); } // other functions void EvCommandCB(Widget, XtPointer tool, XtPointer) { #if defined (CADSHELL) sh_CADshell::GetShell()->SelectTool((sh_Tool *)tool); #endif }