/* Project CADshell Mechanical Design Research Lab Mechanical Engineering - Engineering Mechanics Dept. Michigan Technological University Copyright (C) 2001. All Rights Reserved. FILE: controls.h MODULE: CADshell REQUIRES LIBRARIES: libXm, libXt, libX11 AUTHOR(S): Bernie Bettig OVERVIEW ======== Class declarations for sh_Event, sh_MessageBox, sh_Control, sh_CompositeControl (sh_Control), sh_Form (sh_CompositeControl), sh_FramedControl (sh_CompositeControl), sh_Dialog (sh_FramedControl), sh_FileDialog (sh_FramedControl), sh_Button (sh_Control), sh_OnOffButton (sh_Button), sh_OkButton (sh_Button), sh_CancelButton (sh_Button), sh_ApplyButton (sh_Button), sh_OkApplyCancel (sh_Form), sh_OkCancel (sh_Form), sh_CheckBox (sh_Control), sh_Label (sh_Control), sh_Bitmap, sh_LabeledControl (sh_CompositeControl), sh_Partition (sh_Control), sh_TextInput (sh_Control), sh_TextInput_DynAlloc (sh_Control), sh_TextListInput (sh_Control), sh_OptionSelect (sh_Control), sh_Canvas (sh_Control). sh_IntInput (sh_Control), sh_DoubleInput (sh_Control), sh_DoubleInputWithUnits (sh_Control), sh_ExpressionInput (sh_Control), sh_Slider (sh_Control), sh_Scrollbar (sh_Control), sh_Vec3dInput (sh_Form). Summary: This file contains declarations for the most commonly used windows "control" classes. See the file "controls_main.h" for windows classes that are required to initialize the application. The sh_MessageBox class is used to popup a messagebox which contains a line of text, an (optional) icon and response buttons such as "Ok", "Cancel", etc. When a message box is popped up, the function does not return until the user has pressed one of the buttons. The return value of the function indicates which button was pressed. The control (sh_Control) objects allow the user to directly change the values of variables, since they are constructed by passing a pointer to the variable which they control. Many types of controls are available. These are either composite, containing other controls, (and derived from sh_CompositeControl) or single (not derived from sh_CompositeControl). Controls either come with a frame (derived from sh_FramedControl) or do not (not derived from sh_FramedControl). Controls with frames can be popped up and dragged and re-sized by the user. The sh_Dialog class, which is derived from sh_FramedControl, is commonly used to pop up a dialog box in which the user can enter information. To accomplish event handling, sh_Control objects have pointers to sh_EventHandler objects that are notified of any control events. The sh_EventHandler objects pointers are passed to controls in the sh_Control constructors. */ #if !defined(__controls_h) #define __controls_h #include #include #include "vmath.h" /* ------------------------------------------------------------------------------ sh_Event class declaration Purpose: Objects of this class are used to pass information about control events from sh_Control objects to sh_EventHandler objects, or between sh_EventHandler objects. Functions: sh_Event() - constructor, sender passes in the message. GetClassName() - to identify object class IsA() - to identify object class GetMessage() - reciever checks the message -------------------------------------------------------------------------------------- */ class sh_Event { public: sh_Event(const char *msg) { message = strdup(msg); } virtual const char *GetClassName() { return "sh_Event"; } virtual bool IsA(const char *type) { return !strcmp(type,"sh_Event"); } virtual const char *GetMessage() { return message; } protected: char *message; }; class sh_Control; class sh_CompositeControl; class sh_Viewer; /* ------------------------------------------------------------------------------ sh_EventHandler class declaration Purpose: New classes are derived from sh_EventHandler to handle control events. Functions: ControlEvent() - windowing types of events. Apply() - "Ok" or "Apply" button has been pressed in Dialog box. PointerEvent() - message from sh_Viewer. Events are defined in viewer.h. PointerEvent3d() - same as above, but pointer coordinates are in 3d. KeyboardEvent() - viewer has focus and a key was pressed or released. KeyPressed() - returns key presses as char's. GetMenuButton() - called by menu control if specialized menu button is required. GetControlBarButton() - called by control bar control if specialized button is required. -------------------------------------------------------------------------------------- */ class sh_EventHandler { public: // Dialog Box Input virtual void ControlEvent(sh_Control *, sh_Event &) {} virtual void Apply() {} // Viewer Input virtual void PointerEvent(sh_Viewer *view, int event, int modKeys, unsigned int x, unsigned int y); virtual void PointerEvent3d(sh_Viewer *view, int event, int modKeys, sh_Point& point); virtual void KeyboardEvent(sh_Viewer *view, int event, int modKeys, unsigned int keysym); virtual void KeyPressed(sh_Viewer *view, char c); // Special Menu & Control Bar Buttons virtual sh_Control *GetMenuButton(sh_CompositeControl *parent, const char *label, char key); virtual sh_Control *GetControlBarButton(sh_CompositeControl *parent, const char *label); }; /* ------------------------------------------------------------------------------ sh_MessageBox class declaration Summary: the sh_MessageBox pops up a window with a message, an (optional) icon and some buttons. When the messagebox is popped up, it does not return until the user has pressed one of the buttons. The simplest way to use the sh_MessageBox class is through the static Message() function. The format for using it is: int response; response = sh_MessageBox::Message("Are you sure?", "Warning", MB_OK | MB_ICONWARNING); // - use the appropriate MB_button and MB_ICONxxx separated // by | to set the required buttons and icon. // the return value is one of the IDxx values defined below. ------------------------------------------------------------------------------ */ // flags - type of buttons to use #define MB_OK 16 #define MB_CANCEL 32 #define MB_YES 64 #define MB_NO 128 #define MB_HELP 256 #define MB_YESNOCANCEL 224 // flags - type of icon to use #define MB_ICONEXCLAMATION 5 #define MB_ICONERROR 0 #define MB_ICONINFORMATION 1 #define MB_ICONMESSAGE 2 #define MB_ICONQUESTION 3 #define MB_ICONTEMPLATE 4 #define MB_ICONWARNING 5 #define MB_ICONWORKING 6 // return value - which button was pressed #define IDOK 1 #define IDCANCEL 2 #define IDYES 3 #define IDNO 4 // sh_MessageBox class class sh_MessageBox { public: static int Message(const char *message, const char *title = 0, int flags = 0); sh_MessageBox(const char *message, const char *title = 0, int flags = 0); ~sh_MessageBox(); virtual void Create(); // Modeless: program execution continues while message box is left up virtual int Execute(); // Modal: returns IDXXX only after a button is pressed virtual void Ok(); virtual void Cancel(); virtual void Yes(); virtual void No(); virtual Widget GetWidget() { return dialogWidget; }; private: Widget dialogWidget; int dialogReply; bool autoDelete; friend void MBunmap(Widget, XtPointer mb, XtPointer); }; /* ------------------------------------------------------------------------------ sh_Control class declaration Summary: is an abstract base class for control objects in dialog windows. Functions: Is/Has...() - is used to position the control in the dialog box. GetWidget() - is used to get the underlying Widget. GetEventHandler() - is used to get a pointer to the event handler GetParent() - is used to get a pointer to the parent control Hide/ShowControl() - is used to make the control show or not show (without deleting the control object). TransferToControl() - displays the value from the variable in the control Widget. TransferFromControl() - if the value in the Widget has been changed, reads this value into the variable. Start() - is called after controls have been made visible, This function may be re-defined in sub-classes. ControlEvent() - resets the "valueChanged" flag and notifies the sh_EventHandler event handler. GetNextControl() - returns pointer to next control contained in parent. GetName() - returns label or name of control. This is usually the text displayed on the control. HasValueChanged() - returns whether the value held by the control has been changed by the user since the last TransferTo/ FromControl() call. Note that the valueChanged flag is only reset when Transfer..() is called for the control's parent. Events: "ControlClosed" - control being shutdown. "ValueChanged" - the value held by this control or a child control has been changed. "Apply" - the variable being controlled now has a new value and "Apply" or "Ok" was pressed. ------------------------------------------------------------------------------ */ #define REGSTRLEN 30 // max characters for text input control (w/o units) #define UNITSSTRLEN 20 // max characters for units // sh_Control callback functions void sh_ControlEventCB(Widget, XtPointer control, XtPointer ); void sh_ControlTransferFromCB(Widget, XtPointer control, XtPointer ); class sh_CompositeControl; class sh_Control { public: sh_Control(sh_CompositeControl *aparent, sh_EventHandler *event_handler = NULL); virtual ~sh_Control(); virtual void HasXPosition(int x); virtual void HasYPosition(int y); virtual void HasWidth(int width); virtual void HasHeight(int height); virtual void IsAbove(sh_Control *c = 0, int gap = 5); virtual void IsBelow(sh_Control *c = 0, int gap = 5); virtual void IsLeftOf(sh_Control *c = 0, int gap = 5); virtual void IsRightOf(sh_Control *c = 0, int gap = 5); virtual void HasSameTopAs(sh_Control *c = 0, int gap = 0); virtual void HasSameBottomAs(sh_Control *c = 0, int gap = 0); virtual void HasSameLeftAs(sh_Control *c = 0, int gap = 0); virtual void HasSameRightAs(sh_Control *c = 0, int gap = 0); virtual void HasTopPosition(int percent); virtual void HasBottomPosition(int percent); virtual void HasLeftPosition(int percent); virtual void HasRightPosition(int percent); virtual Widget GetWidget() { return widget; } virtual sh_EventHandler *GetEventHandler() { return m_event_handler; } virtual sh_CompositeControl* GetParent() { return parent; } virtual void HideControl(); virtual void ShowControl(); virtual void TransferToControl() {} virtual void TransferFromControl() {} virtual void Start() {} virtual void ControlEvent(sh_Control *c = NULL); virtual sh_Control *GetNextControl() { return nextControl; } virtual char *GetName(); virtual bool HasValueChanged() { return valueChanged; } protected: Widget widget; sh_EventHandler *m_event_handler; sh_Control *nextControl; sh_CompositeControl *parent; bool valueChanged; friend class sh_CompositeControl; }; /* ------------------------------------------------------------------------------ sh_CompositeControl class declaration Summary: The sh_CompositeControl class encapsulates functionality required for a control to contain other controls. ------------------------------------------------------------------------------ */ class sh_CompositeControl : public sh_Control { public: sh_CompositeControl(sh_CompositeControl *aparent, sh_EventHandler *event_handler = NULL); virtual ~sh_CompositeControl(); virtual void AddControl(sh_Control *c); virtual void RemoveControl(sh_Control *c); virtual void Ok(); virtual void Cancel(); virtual void Yes(); virtual void No(); virtual void Apply(); virtual void TransferToControl(); virtual void TransferFromControl(); virtual void Start(); protected: sh_Control *firstControl, *lastControl; }; /* ------------------------------------------------------------------------------ sh_Form class declaration Summary: sh_Form allows grouping a set of controls as a single control so they can be positioned as one. ------------------------------------------------------------------------------ */ class sh_Form : public sh_CompositeControl { public: sh_Form(sh_CompositeControl *aparent, sh_EventHandler *event_handler = NULL); }; class sh_FramedControl : public sh_CompositeControl { public: sh_FramedControl(sh_EventHandler *event_handler = NULL); virtual void Create(); // Modeless: program execution continues while message box is left up virtual int Execute(); // Modal: returns IDXXX only after the dialog is closed virtual void Ok(); virtual void Cancel(); virtual void Yes(); virtual void No(); virtual void Apply(); virtual void SetWidth(int width) { HasWidth(width); } virtual void SetHeight(int height) { HasHeight(height); } protected: int dialogReply; bool autoDelete; friend void sh_FramedControlUnmap(Widget, XtPointer, XtPointer); }; /* ------------------------------------------------------------------------------ sh_Dialog class declaration Summary: sh_Dialog controls are controls that pop up and allow the user to see and input information in thier child controls. sh_Dialog objects should only be created using new and should never be deleted since they delete themselves when they are closed. The format for using sh_Dialog objects is: sh_Dialog *d; SomeControl *c; d = new sh_Dialog("dialog name", m_event_handler); // - "dialog name" is the caption // - specify m_event_handler if you want m_event_handler->apply() to be // called when "ok" or "apply" is pressed in the dialog. c = new SomeControl(d, ...); // - controls are automatically added to the dialog specified d->Create(); // - Create() is for modeless dialogs // - if you want to halt the program until the // dialog has been closed use d->Execute() // - Execute() will return one of the IDXX values // IDOK, IDCANCEL, IDYES, IDNO // depending on which button was pressed. ------------------------------------------------------------------------------ */ class sh_Dialog : public sh_FramedControl { public: sh_Dialog(const char *title, sh_EventHandler *event_handler = NULL); }; /* ------------------------------------------------------------------------------ sh_FileDialog class declaration Summary: the sh_FileDialog class provides a dialog box in which the user can search through directories and select a filename. As with sh_Dialog Create() or Execute() can be called for modeless and modal dialogs, respectively. As with the sh_Dialog class, always use new to create an sh_FileDialog and never delete it since it gets deleted automatically when the dialog is closed. The format for using sh_FileDialog objects is: sh_FileDialog *d; char *filename = 0; // memory gets allocated automatically // Could also use: char *filename = strdup("untitled"); d = new sh_FileDialog("dialog name", &filename); // - "dialog name" will appear as the caption. // - filename will contain name of file. // - can also control directory // - can also control mask to filter displayed files. if (d->Execute() == IDOK) { // do something with filename } if (filename) free (filename) // memory must always be freed ------------------------------------------------------------------------------ */ class sh_FileDialog : public sh_FramedControl { public: sh_FileDialog(const char *title, char **pfilename = 0, char **pdir = 0, char **pmask = 0, sh_EventHandler *event_handler = NULL); void SetSelectionLabel(const char *); // Not implemented yet. // void SetFileName(char *afilename); // char *GetFileName(); // void SetDirectory(char *adir); // char *GetDirectory(); // void SetFilter(char *amask); // char *GetFilter(); virtual void TransferFromControl(); protected: char **pfilename, **pdir, **pmask; }; /* -------------------------------------------------------------------------------------- Button Controls Summary: The constructors for these controls require a pointer to the parent control as well as the text to be displayed on the button. Buttons can also display bitmaps using the SetPixmap() function. sh_OnOffButtons can appear in the depressed or released condition. The sh_Ok and sh_Cancel buttons will cause a dialog box to close. The sh_Ok and sh_Apply buttons will cause TransferFromControl() to be called for all controls of the dialog box that have had their values changed. The sh_OkApplyCancel control is a composite control that draws a horizontal partition with Ok, Apply and Cancel buttons below it. Similary sh_OkCancel has Ok and Cancel buttons. The sh_CheckBox control is used to control the value of a boolean variable. Variables : label - text to display on button. event_handler - the sh_EventHandler object that is to be used for event handling. enabled - if not enabled, the button will be greyed out. mnemonicKey - a letter that can be pressed on the keyboard in the absence of a mouse. boolVariable - a pointer to the boolean variable being controlled by the checkbox. pixmapFileName - name of file containing bitmap. Can use "Icon Editor" program to generate this file. Events: "ButtonPressed" - the button was pressed. "ValueChanged" - the value held by a checkbox was changed. -------------------------------------------------------------------------------------- */ class sh_Button : public sh_Control { public: sh_Button(sh_CompositeControl *aparent, const char *label, sh_EventHandler *event_handler = NULL, bool enabled = true, char mnemonicKey = 0); sh_Button(sh_CompositeControl *aparent, sh_EventHandler *event_handler = NULL) : sh_Control(aparent, event_handler) {} // doesn't create a widget virtual bool SetPixmap(const char *pixmapFileName); virtual bool SetText(const char *label); virtual void ControlEvent(sh_Control *c = NULL); }; class sh_OnOffButton : public sh_Button { public: sh_OnOffButton(sh_CompositeControl *aparent, const char *label, sh_EventHandler *event_handler = NULL, bool enabled = true, char mnemonicKey = 0); }; class sh_OkButton : public sh_Button { public: sh_OkButton(sh_CompositeControl *aparent, const char *label = " OK ", sh_EventHandler *event_handler = NULL, bool enabled = true, char mnemonicKey = 0) : sh_Button(aparent, label, event_handler, enabled, mnemonicKey) {} void ControlEvent(sh_Control *); }; class sh_CancelButton : public sh_Button { public: sh_CancelButton(sh_CompositeControl *aparent, const char *label = " Cancel ", sh_EventHandler *event_handler = NULL, bool enabled = true, char mnemonicKey = 0) : sh_Button(aparent, label, event_handler, enabled, mnemonicKey) {} void ControlEvent(sh_Control *); }; class sh_ApplyButton : public sh_Button { public: sh_ApplyButton(sh_CompositeControl *aparent, const char *label = " Apply ", sh_EventHandler *event_handler = NULL, bool enabled = true, char mnemonicKey = 0) : sh_Button(aparent, label, event_handler, enabled, mnemonicKey) {} void ControlEvent(sh_Control *); }; class sh_OkApplyCancel : public sh_Form { public: sh_OkApplyCancel(sh_CompositeControl *aparent, sh_EventHandler *event_handler = NULL); }; class sh_OkCancel : public sh_Form { public: sh_OkCancel(sh_CompositeControl *aparent, sh_EventHandler *event_handler = NULL); }; class sh_CheckBox : public sh_Control { public: sh_CheckBox(sh_CompositeControl *aparent, const char *label, bool *boolVariable, sh_EventHandler *event_handler = NULL, bool enabled = true); virtual void TransferToControl(); virtual void TransferFromControl(); virtual void ControlEvent(sh_Control *c = NULL); protected: bool *p; }; /* -------------------------------------------------------------------------------------- Text and Labels Summary: The Label constructor requires a pointer to the dialog object as well as the text. The sh_Bitmap objects hold bitmaps loaded from the file specified in the constructor. The file can be generated by the Icon_Editor program usually found with other desktop applications. sh_Bitmap objects are not controls. The LabeledControl class is used to minimize the work of positioning a label and then an input control. It's constructor requires a pointer to the parent control and the label text. The input control(s) must then be created with the sh_LabeledControl as a parent. The PositionControls() function must then be called. The Partition class is used to draw a horizontal line. The TextLineInput class is used to input a line of text. It's constructor requires a pointer to the dialog box, a pointer to the string and the number of characters that the string can hold. sh_TextInput_DynAlloc does the same thing, however it dynamically allocates memory for strings, so that it is not necessary to prescribe a text length limit beforehand. If memory is allocated, it must be freed by the application using free(). If no memory is allocated, the char * will have a value of NULL. The TextListInput and OptionSelect allow the user to select one item from a list. The list items may be added in the constructor using an array of strings or by using the AddListItem()/AddOption() functions. Depending on which constructor or AddListItem()/AddOption() function is used, it is possible to associate each list item with a pointer. Depending on which constructor is used, these controls can be used to control an int variable giving the index of the selected item (pos_ptr/optionNo_ptr), a char pointer, holding a pointer to the text of the selected item (optionString_ptr) or a pointer holding the pointer associated with the selected list item (pointer_ptr/optionPointer_ptr). The selected item can also be retrieved using the GetSelected..() functions. In the sh_OptionSelect class, an event "OptionSelected" is generated when a new option is selected. The Canvas class allows the application to draw graphics using XWindows drawing commands. Variables: bitmapFile - name of file of where to get bitmap. When using CADshell it will also try looking in the resource directory. x/y_hotspot - for cursors, gives the actual point that is being used for pointing. fullwidth - partition should be constained to be full width of parent. allocatedCharString - fixed-size char array used to hold input, given by program. maxChars - size of allocatedCharString array. singleLine - User is only allowed to input a single line. readOnly - The user can not change the displayed string. I think must be false for program to work. str_ptr - pointer to a char *. This char * must equal NULL or point to memory that can be freed using free(). pos_ptr/optionNo_ptr - pointer to int variable holding index of item selected from list. pointer_ptr/optionPointer_ptr - pointer to a pointer variable. See text above. optionString_ptr - pointer to a char *. It will be assigned a pointer to the text of the selected list item. textlist/optionlist - list of char strings holding the text for each item. pointerlist/optionPointerList - list of pointers to associate with each item. numItems/numOptions - number of items in list. -------------------------------------------------------------------------------------- */ class sh_Label : public sh_Control { public: sh_Label(sh_CompositeControl *aparent, const char *label); }; class sh_Bitmap { public: sh_Bitmap(const char *bitmapFile, int x_hotspot = 0, int y_hotspot = 0); ~sh_Bitmap(); Pixmap GetBitmap() { return bitmap; } unsigned int width() { return _width; } unsigned int height() { return _height; } int x_hotspot() { return _x_hotspot; } int y_hotspot() { return _y_hotspot; } protected: Pixmap bitmap; unsigned int _width, _height, _x_hotspot, _y_hotspot; sh_Control *parent; }; class sh_LabeledControls : public sh_Form { public: sh_LabeledControls(sh_CompositeControl *aparent, const char* label, sh_EventHandler *event_handler = NULL); virtual void PositionControls(); }; class sh_Partition : public sh_Control { public: sh_Partition(sh_CompositeControl *aparent, bool fullWidth = true); }; class sh_TextInput : public sh_Control { public: sh_TextInput(sh_CompositeControl *aparent, char *allocatedCharString, int maxChars, bool singleLine = false, bool readOnly = false, sh_EventHandler *event_handler = NULL); // Note that 'allocatedCharString' must already be allocated and be at least 'maxChars' long virtual void SetText(const char *s); virtual void SetNumRows(int num_rows); virtual void SetNumColumns(int num_columns); virtual void TransferToControl(); virtual void TransferFromControl(); protected: char *p; int maxChars; }; class sh_TextInput_DynAlloc : public sh_Control { public: sh_TextInput_DynAlloc(sh_CompositeControl *aparent, char **str_ptr, bool SingleLine = false, bool ReadOnly = false, sh_EventHandler *event_handler = NULL); // Note that str_ptr must point to an existing, non-const 'char *s' // but 'char *s' can initially be zero (no string), // e.g.: char *string = 0; // ... // sh_TextInput_DynAlloc *textControl = new sh_TextInput_DynAlloc(d, &string); // ... // free(string); virtual void SetText(const char *s); virtual void SetNumRows(int num_rows); virtual void SetNumColumns(int num_columns); virtual void TransferToControl(); virtual void TransferFromControl(); protected: char **p; }; class sh_TextListInput : public sh_Control { public: sh_TextListInput(sh_CompositeControl *aparent, int *pos_ptr = 0, char **textlist = NULL, int numLines = 0, sh_EventHandler *event_handler = NULL); sh_TextListInput(sh_CompositeControl *aparent, void **pointer_ptr, char **textlist = NULL, void **pointerlist = NULL, int numItems = 0, sh_EventHandler *event_handler = NULL); virtual ~sh_TextListInput(); virtual void AddListItem(const char *item, int pos = -1); // starting at 0; pos == -1 adds to end of list virtual void ReplaceListItem(const char *item, int pos); // starting at 0 virtual void AddListItem(const char *item, void *pointer, int pos = -1); // pointer corresponds to text item virtual void ReplaceListItem(const char *item, void *pointer, int pos); virtual void RemoveListItem(int pos = -1); // starting at 0; pos == -1 removes last entry virtual void RemoveListItem(void *pointer); virtual void ClearAllListItems(); virtual void TransferToControl(); virtual void TransferFromControl(); int GetSelectedPos() { return selectedPos; } // starting at 0; selectedPos == -1 for no selection, *pos == selectedPos void *GetSelectedPointer() { return selectedPointer; } // *pointer_pos == selectedPointer int GetNumItems() { return numLines; } int GetPos(void *pointer); protected: void Create(sh_CompositeControl *aparent, int *pos, void **pointer_pos, char **textlist, void **pointerlist, int numLines); friend void sh_TextListInputlistSelectCB(Widget w, XtPointer userData, XtPointer callbackData); int *pos; int numLines, selectedPos; void **pointer_pos, *selectedPointer, **pointerlist; Widget list; }; class sh_OptionSelect : public sh_Control { public: sh_OptionSelect(sh_CompositeControl *aparent, const char *label, int *optionNo_ptr = 0, char **optionlist = NULL, int numOptions = 0, sh_EventHandler *event_handler = NULL); sh_OptionSelect(sh_CompositeControl *aparent, const char *label, void **optionPointer_ptr, char **optionlist = NULL, void **optionPointerlist = NULL, int numOptions = 0, sh_EventHandler *event_handler = NULL); sh_OptionSelect(sh_CompositeControl *aparent, const char *label, char **optionString_ptr, char **optionlist = NULL, int numOptions = 0, sh_EventHandler *event_handler = NULL); ~sh_OptionSelect(); virtual void AddOption(const char *item); virtual void AddOption(const char *item, void *pointer); virtual void TransferToControl(); virtual void TransferFromControl(); int GetSelectedOptionNo() { return selectedOptionNo; } // starting at 0; selectedOptionPos == -1 for no selection, *optionNo == selectedOptionNo void *GetSelectedOptionPointer() { return selectedOptionPointer; } // *optionPointer == selectedOptionPointer int GetNumOptions() { return numOptions; } int GetOptionNo(void *optionPointer); protected: void Create(sh_CompositeControl *aparent, const char *label, int *optionNo, void **optionPointer, char **optionString, char **optionList, void **optionPointerlist, int numOptions); friend void sh_OptionSelectCB(Widget w, XtPointer userData, XtPointer callbackData); int *optionNo; int numOptions, selectedOptionNo; void **optionPointer, *selectedOptionPointer, **optionPointerList; char **optionString; Widget option_menu, *buttonList; }; class sh_Canvas : public sh_Control { public: sh_Canvas(sh_CompositeControl *aparent, sh_EventHandler *event_handler = 0); }; /* -------------------------------------------------------------------------------------- Value input Summary: The constructor for most of these controls requires a pointer to the parent control and a pointer to the input variable. For controls with unit conversion, a string giving the correct consistent metric units is required and the output can be made to display in metric or imperial units. "Correct consistent metric units" means units in the kilogram-meter-second system. These are listed below in this file, with the unit conversion functions. Note that the user can choose to type in units other than those displayed. If they cannot be converted to the units given in the constructor, an error message will pop-up. The slider and scroll bar controls work the same way as the other value input controls, as far as the application is concerned, except that the range of values is between 0 and 1. The sh_EventHandler object is also notified when the control is moved. sh_ExpressionInput is used to input a mathematical expression. Events: "SliderSlid" - the value indicated by the slider control was changed. "ScrollbarSlid" - the value indicated by the scrollbar control was changed. -------------------------------------------------------------------------------------- */ class sh_IntInput : public sh_Control { public: sh_IntInput(sh_CompositeControl *aparent, int *i, sh_EventHandler *event_handler = NULL); virtual void TransferToControl(); virtual void TransferFromControl(); protected: int *p; }; class sh_DoubleInput : public sh_Control { public: sh_DoubleInput(sh_CompositeControl *aparent, double *f, sh_EventHandler *event_handler = NULL); virtual void TransferToControl(); virtual void TransferFromControl(); protected: double *p; }; class sh_DoubleInputWithUnits : public sh_Control { public: sh_DoubleInputWithUnits(sh_CompositeControl *aparent, double *f, const char *units = 0, bool metric = true, sh_EventHandler *too = NULL); // units may point to a string holding the units of f // (in the kg-m-s system) // metric indicates the displayed units // returned units are always KMS metric virtual void TransferToControl(); virtual void TransferFromControl(); protected: double *p; bool metric; char units[UNITSSTRLEN]; }; class sh_ExpressionInput : public sh_Control { public: sh_ExpressionInput(sh_CompositeControl *aparent, char **expression, const char *units = 0, bool metric = true, sh_EventHandler *event_handler = NULL); // units may point to a string holding the units of expression // (in the kg-m-s system) // metric indicates the displayed units // returned units are always KMS metric virtual void TransferToControl(); virtual void TransferFromControl(); protected: char **expression; bool metric; char units[UNITSSTRLEN]; }; class sh_Slider : public sh_Control { public: sh_Slider(sh_CompositeControl *aparent, double *f, bool vert = false, bool autoUpdate = true, sh_EventHandler *event_handler = NULL); virtual void TransferToControl(); virtual void TransferFromControl(); virtual void ControlEvent(sh_Control *c = NULL); protected: double *p; }; class sh_Scrollbar : public sh_Control { public: sh_Scrollbar(sh_CompositeControl *aparent, double *f, bool vert = false, bool autoUpdate = true, sh_EventHandler *event_handler = NULL); virtual void TransferToControl(); virtual void TransferFromControl(); virtual void ControlEvent(sh_Control *c = NULL); protected: double *p; }; /* -------------------------------------------------------------------------------------- Inventor Field input Summary: similar to Value Input above, but for vector of 3 values. Not recently used. -------------------------------------------------------------------------------------- */ class sh_Vec3dInput : public sh_Form { public: sh_Vec3dInput(sh_CompositeControl *aparent, double *v, sh_EventHandler *event_handler = NULL); }; // ------------------------- // Unit conversion functions // ------------------------- // these functions convert values to the kilogram-meter-second convention: // // angle unit is radians // distance meters // mass kilogram // time second // force Newton // temperature degrees Kelvin // // the functions return FALSE if no or unrecognizable // units are given. // KMS() performs the conversion, new units are passed back in unit parameter. // KMS2() performs the conversion, gives MessageBox if units are not recognized; // calls CommonMetric if requested. // CommonMetric() - converts to more common units if value is within range normally // used. E.g. using mm instead of m for small sizes, degrees instead of radians, etc. bool KMS(double *val, char *unit); bool KMS2(double *val, char *unit, bool Common = FALSE); void CommonMetric(double *val, char *unit); // these functions convert values to the Imperial system // // returns FALSE if no or unrecognizable // units are given. // // angle unit is radians // distance feet // mass slug // time second // force pound force // temperature degrees Rankine bool Imp(double *val, char *unit); // performs the conversion bool Imp2(double *val, char *unit, bool Common = FALSE); // performs the conversion, gives MessageBox if units are not recognized void CommonImp(double *val, char *unit); // converts to more common units if value is within range where normally used // -------------------- // String copy function // -------------------- char *linecpy(char *dest, const char *src, size_t maxlen); char *linencpy(char *dest, const char *src, size_t maxlen); int stricmp(const char *, const char *); #endif