Amulet provides a full set of widgets, including buttons, menus, scroll bars, and text input fields. Eventually, these will display themselves in different looks, corresponding to the various platforms. The built-in widgets have a large number of parameters to allow programmers to customize them, and the programmer can also create new kinds of widgets by writing new methods.
The intent of the Amulet Widget set is to supply several frequently used objects that can be easily customized by the designer. By importing these pre-constructed objects into a larger Amulet interface, the designer is able to specify in detail the desired appearance and behavoir of the interface, while avoiding the programming that this specification would otherwise entail.
This document is a guide to using Amulet's Widgets. The objects were constructed using the complete Amulet system, and their descriptions assume that the reader has some knowledge of the components of this system: Opal, Interactors, and ORE.
All of the widgets (except the Am_Selection_Widget) are set up to operate with the left mouse button, and ignore the modifier keys. Thus, clicking on a scroll bar with SHIFT_CONTROL_LEFT_DOWN does the same as regular left down. The default widget start character is exported as Am_Default_Widget_Start_Char.
Am_Border_Rectangle
: a rectangle with a raised (or lowered) edge, but no interaction.
Am_Button
: a single button
Am_Button_Panel
: a panel consisting of multiple buttons with the labels inside the buttons.
Am_Checkbox_Panel
: a panel of toggle checkboxes with the labels next to the checkboxes.
Am_Radio_Button_Panel
: a panel of mutually exclusively selectable radio buttons with the labels next to the radio buttons.
Am_Menu
: a menu panel
Am_Menu_Bar
: a menu bar used to select from several different menu panels
Am_Vertical_Scroll_Bar
:
scroll bar for choosing a value from a range of values.
Am_Horizontal_Scroll_Bar
: scroll bar for choosing a value from a range of values.
Am_Scrolling_Group
: an Amulet group with (optional) vertical and horizontal scrollbars
Am_Text_Input_Widget
: a field to accept text input, like for a filename.
Am_Graphics_Set_Property_Command
: to set the color, line style or other property of the selected objects.
Am_Graphics_Clear_Command
: delete the selected objects (``Clear'')
Am_Graphics_Clear_All_Command
: ``Clear all''
Am_Graphics_Copy_Command
: Copy to the clipboard.
Am_Graphics_Cut_Command
: Copy objects to the clipboard and then delete them
Am_Graphics_Paste_Command
: Paste a copy of the objects in the clipboard.
Am_Undo_Command
: Perform a single undo.
Am_Redo_Command
: Perform a single redo.
Am_Graphics_To_Bottom_Command
: Make the selected objects be covered by all other objects.
Am_Graphics_To_Top_Command
: Make the selected objects be covered by no other objects.
Am_Graphics_Duplicate_Command
: Duplicate the selected objects.
Am_Graphics_Group_Command
: Make a group out of the selected objects.
Am_Graphics_Ungroup_Command:
Ungroup the selected objects.
The visual appearance and the functionality of a widget is affected by values set in its slots. When instances of widgets are created, the instances inherit all of the slots and slot values from the prototype object. The designer can then change the values of these slots to customize the widget. Instances of the custom widget will inherit the customized values. The slot values in a widget prototype can be considered ``default'' values for the instances.
widgets.h
for the widget object definitions, and standard_slots.h
for the widget slot definitions. These files are included in amulet.h
, providing a simple way to make sure all needed files are included. Programmers who are designing their own custom widget objects will also need widgets_advanced.h
. For a complete description of Amulet header files and how to use them most effectively in your project, see Section 1.6 in the Overview chapter.
Widgets are standard Amulet objects, and are created and modified in the same way as any other Amulet object. The following sample code creates an instance of
Am_Button
, and changes the values of a few of its slots.Am_Object my_button = Am_Button.Create("My Button")
.Set (Am_LEFT, 10)
// set the position of the button
.Set (Am_TOP, 10)
.Set (Am_COMMAND,"Push Me");
// a string in the Am_COMMAND slot specifies the button's label: see below
6.1.4 Application Interface
Like interactors, widgets interface to application code through command objects added as parts of the widgets. Please see Section 5.6 on Commands in the Interactor's chapter. In summary, instead of executing a call-back procedure as in other toolkits, Amulet widgets call the Am_DO_METHOD
of the command object stored as the Am_COMMAND
part of the widget.
6.1.4.1 Accessing and Setting Widget Values
In addition to the Am_DO_METHOD
, each command also contains the other typical slots of command objects. In particular, the Am_VALUE
slot of the command object is normally set with the result of the widget. Of course, the type of this value is dependent on the type of the widget. For scroll bars, the value will be a number, and for a checkbox panel, it will be a list of the selected items.Am_VALUE
slot of the widget if you want the value shown by the widget to track a slot of another object. Am_VALUE
slot. This constraint can perform side effects like updating an external data base or even setting slots in Amulet objects or creating or destroying new objects. Other times, the programmer will need to write an Am_DO_METHOD which will typically access the value in the command's Am_VALUE slot. An example of each of these methods can be found below. Of course, if you write your own Am_DO_METHOD
and you want the widget to be undo-able, you will also need to write a corresponding Am_UNDO_METHOD
, etc. See Section 5.6 in the Interactors chapter on commands for more information.
6.1.4.2 Commands in Widgets
All of the widgets are designed so the command objects are completely replaceable. Thus, you can put the commands from the library or your new commands into any widget. Alternatively, you can get the default commands in the widgets (which has all blank methods) and override the methods. For example: vscroll = Am_Vertical_Scroll_Bar.Create()
.Set(Am_LEFT, 450)
.Set(Am_TOP, 80)
;
vscroll.Get_Part(Am_COMMAND)
.Set(Am_DO_METHOD, my_do)
.Set(Am_UNDO_METHOD, my_undo)
;
6.1.4.3 Undoing Widgets
Internally, each widget is implemented using graphical objects and interactors. Each internal interactor has its own associated command objects, but these are normally irrelevant to the programmer, since the internal command objects will call the top-level widget command object automatically. This is achieved because the internal commands have their Am_IMPLEMENTATION_PARENT slot of the internal command objects to be the widget's command object, and then Amulet automatically does the right thing.6.2 The Standard Widget Objects
This section describes the widgets in detail. Each object contains customizable slots, but the designer may choose to ignore many of them in any given application. Any slots not explicitly set by the application are inherited from the widget's prototype.6.2.1 Slots Common to All Widgets
There are several slots the programmer can set which are used by all widgets in a similar way:
Am_TOP, Am_LEFT
: As with all graphical objects, these slots describe the location of the widget, in coordinates relative to the object's parent's location. Default values are 0 for both top and left.
true
.
Am_WIDGET_LOOK
: The value of this slot tells Amulet how you want your widgets to look when drawn on the screen. Possible values are Am_MOTIF_LOOK, Am_WINDOWS_LOOK
, or Am_MACINTOSH_LOOK
. Any look will eventually be available on any platform, but currently only Am_MOTIF_LOOK
is implemented.
Am_FILL_STYLE
: This slot determines the color of the widget. Amulet automatically figures out appropriate foreground, background, shadow, and highlight colors given a fill color. Acceptable values are any Am_Style
, and the default is Am_Amulet_Purple
. The only part of the style used is the color of the style. On a black and white screen, a default set of stipples are used to make sure the widgets are visible.
Am_ACTIVE_2
: This slot turns off interaction with the widget without turning it grey. This is mainly aimed at interactive tools like Interface Builders that want to allow users to select and move widgets around. It might also be useful in a multi-user situation where users who do not have the ``floor'' should not have their widgets responding. For a widget to operate, both Am_ACTIVE_2
and Am_ACTIVE
must be true
. The default value is true.
Am_ACTIVE
: This slot in the command is used to determine whether the widget is enabled or not (greyed out). Often, this slot will contain a formula dependent on some system state. The default value is true
. (Actually, the widget itself also contains an Am_ACTIVE
slot, but this one should not normally be used. The widget-level slot contains a constraint that depends on the Am_ACTIVE
slot of the command object part of the widget.)
Am_VALUE
: This slot is set to the current value of the widget. Do not set this slot in the command object to try to change the widget's value (see the Am_VALUE of the widget instead).
Am_DO_METHOD
: The method to be called when the widget executes. This procedure takes one parameter: the command object.
Am_Border_Rectangle
has a raised or lowered edge of a lighter or darker shade of the Am_FILL_STYLE. It ignores the Am_LINE_STYLE. It looks pressed in if Am_SELECTED is true, and sticking out of the screen if Am_SELECTED is false. This widget has no interaction or response to the mouse.
For a single, stand-alone button, the Am_COMMAND slot can either be the string or object to display in the button, or it can be an Am_COMMAND object, in which case, the label of the widget is determined by the
Am_LABEL
slot of the Am_COMMAND part of the widget, which itself should be a string or object, as described below.The various panel objects (that display a set of buttons) and the menus (that display a set of buttons) all take an
Am_ITEMS
slot which must contain an Am_VALUE_LIST
. The items in this value list can be:
char*
), in which case this string is displayed as the label,
Am_LABEL
field of the command object is used as the item's label. The Am_LABEL
field itself can contain either a C string or a graphical object.
Am_DO_METHOD
of this command does the important work of the item. This would typically be how menus of operations like Cut, Copy, and Paste would be implemented.
Am_ITEMS
slot of the widget contains an Am_VALUE_LIST
of strings. In this case, the top-level command object's Am_DO_METHOD will be called, and it typically will look in its Am_VALUE
slot to determine which item was selected. This method is most appropriate when the panel or menu is a list of values, like colors or fonts, and you do not want to create a command for each item.
Am_Value_List
that contains some commands and some strings.
Am_LABEL
: This slot can contain a string or a graphical object, which will be drawn as the label for this item.
Am_ID
: Normally, buttons set the Am_VALUE
slot to the Am_LABEL
of the command. However, this typically requires doing string matching. Therefore, if the Am_ID
field is non-zero, then the Am_VALUE
slot is set with the value of the Am_ID
slot instead of the Am_LABEL slot. The Am_ID slot can contain any type of value.
Am_ACTIVE
: This controls whether the widget is active or not (greyed out). If the Am_ACTIVE
slot of the top-level command in a panel or menu is set to false, then all the items are greyed out. More typically, the Am_ACTIVE
slot of the command associated with a single item will be false
, signaling that just that one item should be greyed out.
Am_VALUE
: This slot is set by the widget with the label(s) or ID(s) of currently the selected button(s). In a single button, this contains 0 if the button is not selected, or the button's label or ID if it is selected. Thus, you can use Valid() to determine if the button is pressed. If multiple items can be selected, as in a check box panel or for a button panel if you set Am_HOW_SET
to be Am_CHOICE_LIST_TOGGLE
, then this slot will always contain an Am_Value_List
with the labels or IDs of the selected items. If no items are selected, then the list will be empty. Note: the value of the Am_VALUE
slot will not be 0; it will be a list that is empty, so you cannot use Valid() since an empty Am_Value_List is still valid. For panels where only a single item can be selected, such as a radio button panel or button panels with Am_HOW_SET
set to be Am_CHOICE_SET
, the Am_VALUE
slot is set to the single button's label or ID, or 0 if nothing is selected.
The interface to the accelerator lists for windows is available in widget_advanced.h through the functions Am_Add_Accelerator_Command_To_Window and Am_Remove_Accelerator_Command_From_Window, which take the window and command object.
6.2.3.3 Am_Menu_Line_Command
Am_Menu_Line_Command
is a special purpose type of command object provided by Amulet to draw horizontal dividing lines in menus. To add a horizontal line in a menu, simply include an instance of Am_Menu_Line_Command
in the menu's Am_ITEMS
list. An example of this can be found in section 6.2.3.7. Am_Menu_Line_Command
has no customizable slots, and it is an inactive menu item.6.2.3.4 Am_Button
The Am_Button
object is a single stand-alone button. A button can have a text label, or can contain an arbitrary graphical object when drawn.Am_BUTTON
s are:
Am_WIDTH, Am_HEIGHT
: By default, the width and height of the button are automatically calculated by formulas in these slots. A button is made big enough to contain its text label or graphical object, including borders, and offset pixels (see below). A user can replace the width and height formulas by setting these slots directly. Once the values are set with new values or formulas, the formulas will be removed.
Am_ITEM_OFFSET
: The string or object displayed inside the button is set away from the border of the button by Am_ITEM_OFFSET
pixels, in both the horizontal and vertical directions. The default is 5.
Am_FONT
: The button's text label (if any) is drawn in this font. Acceptable values are any Am_Font
, and the default is Am_Default_Font
.
Am_FINAL_FEEDBACK_WANTED
: This determines if the button should be drawn as if it is still selected, even after user interaction has stopped. This is useful if you want to use the button to show whether it is selected or not. The default is false
.
Am_Button_Panel
is a panel of Am_Buttons
, with a single interactor in charge of all the buttons. Since an Am_Button_Panel
's prototype object is a Am_Map
, all the slots that Am_Map
uses are also used by Am_Button_Panel
. See the Opal chapter for a description of Am_Map
. Some Am_Map
slots are described below along with slots specific to Am_Button_Panel
.
Special slots of Am_Button_Panel are:
Am_FONT
: The font used for the button labels.
Am_FINAL_FEEDBACK_WANTED
: Whether to show which item is selected or not. The default is false.
Am_WIDTH, Am_HEIGHT
: The width and height slots contain the standard Amulet formulas Am_Width_Of_Parts
and Am_Height_Of_Parts
, respectively. If these slots are set to specific values by the designer, those values replace the formulas, and the panel will no longer resize itself if its contents change.
Am_FIXED_WIDTH
: This slot determines how the buttons in a panel get their width. An integer value of 0, or a boolean value of false
, means each button is as wide as its calculated width based on the contents. Thus, each button will be a different size. An integer value of 1, or a boolean value of true
, means that all the buttons in the panel are set to be as wide as the calculated width of the widest button in the panel. An integer value greater than 1 sets the width of all buttons in the panel to that specific value. The default is true.
Am_FIXED_HEIGHT
: This slot determines the height of buttons in a panel. It acts the same way as Am_FIXED_WIDTH
. The default is false.
Am_HOW_SET
: This slot determines whether single or multiple buttons can be selected. Its default value is Am_CHOICE_SET
, which allows a single selection. Changing this to Am_CHOICE_TOGGLE
will allow the selected item to be turned off by clicking it again. Am_CHOICE_LIST_TOGGLE
allows there to be multiple selections. See the Interactors manual for a complete description of the legal values.
Am_LAYOUT
: This specifies a function determining how the button panel should be arranged. A more complete description of the slot can be found in section 4.7.2. Am_Vertical_Layout
is the default, and Am_Horizontal_Layout
is another good value.
Am_H_ALIGN
: In a vertically arranged button panel with variable width buttons, this determines how the buttons should be arranged in the panel. The default is Am_LEFT_ALIGN
, and other possible values are Am_CENTER_ALIGN
and Am_RIGHT_ALIGN
.
Am_V_ALIGN
: This slot works like Am_H_ALIGN
, except is only used in horizontally arranged panels width variable height buttons. Possible values are Am_TOP_ALIGN
, Am_CENTER_ALIGN
, and Am_BOTTOM_ALIGN
.
Am_ITEMS
: This slot specifies the items which are to be put in the button panel. An Am_Value_List
should be used to specify specific items to add to the panel. See section 6.2.3.1 for a complete description. In summary, elements of the value list can be either strings, graphical objects, or command objects. A string value is used as the label for the button in the panel. A graphical object is displayed in the button. A command object is used to specify a custom command for that particular button in the panel. For commands, the button's string label or graphical object is taken from the command object's Am_LABEL
slot.
Am_COMMAND
: This slot contains an Am_Command
object. See section 6.2.3.1 for a complete description.
Am_Value_List
in the Am_ITEMS
slot tells the button panel what to put inside each button. If a string is specified, it is used as the button's label. If a graphical object is specified, it is drawn in the button. If a command object is specified, that command object's Am_DO_METHOD
method is called each time the button is pressed, and the button's label or graphical object is obtained from the command object's Am_LABEL
slot. The following code specifies a button panel with three buttons in it.
// a graphical object and custom do action, defined elsewhere:
extern Am_Object My_Graphical_Object;
extern void My_Custom_Do_METHOD (Am_Object command_obj);
Am_Object my_command;
// my button panel:
Am_Object My_Button_Panel = Am_Button_Panel.Create ("My Button Panel")
.Set (Am_ITEMS,
Am_Value_List ()
.Add ("Push me.")
.Add (My_Graphical_Object)
.Add (my_command = Am_Command.Create()
.Set (Am_LABEL, "Push me too.")
.Set (Am_DO_METHOD, My_Custom_Do_Method)));The first button in the panel is drawn with the text label ``Push me.'' and does not have its own command object. The second button in the panel is drawn containing
My_Graphical_Object
drawn inside it, and also does not have its own command. The third button in the panel is drawn with the text label ``Push me too.'' and has its own command object associated with it.When the third button is pressed, My_Custom_Do_Method is called, with the button's command object (
my_command
) as an argument. The command object's Am_VALUE
slot will already have been set with either 0, if the button was not selected, or ``Push me too.'' if the button was selected. We assume that this command is not undoable since there is no custom Undo action to go with My_Custom_Do_Method.If any of the other buttons in the panel are pressed, the do action of
My_Button_Panel
's command object (in its Am_COMMAND
slot) will be called, with the command object as an argument. The Am_VALUE
of the command object is set with the labels or objects corresponding to the currently selected buttons.If you wanted the button panel's command to be invoked when the third button was pressed, you would have to set the third button's command object's
Am_IMPLEMENTATION_PARENT
slot to contain the button panel's command object. For example, after executing the following code, My_Other_Custom_Do_Method
in the panel will be called when any of the buttons are selected.
Am_Object panel_command = My_Button_Panel.Get(Am_COMMAND);
panel_command.Set (Am_DO_METHOD, My_Other_Custom_Do_Method);
my_command.Set (Am_IMPLEMENTATION_PARENT, panel_command);
An
Am_Radio_Button_Panel
is essentially the same as an Am_Button_Panel
, with a few exceptions. There are a few new slots, and some of the defaults of the other slots are different. All other slots not listed below act the same way as in an Am_Button_Panel
. Since radio buttons always only allow a single selection, the Am_VALUE
slot of the top-level Am_COMMAND
is always set with either 0 or the ID or label of the selected item.
Am_BOX_HEIGHT, Am_BOX_WIDTH
: These specify the size in pixels of the small radio button box that is drawn next to the item in the button. The defaults are 15 for each.
Am_BOX_ON_LEFT
: This boolean determines whether the radio box should be drawn to the left of the item, or to the right. If true
, the box is drawn on the left, and if false,
it is drawn on the right. The default is true
.
Am_H_ALIGN
: This slot contains a formula which evaluates to Am_LEFT_ALIGN
if the Am_BOX_ON_LEFT
is true
, or Am_RIGHT_ALIGN
if it is false
.
Am_FIXED_WIDTH
: The default is false
for this slot in a radio button panel.
Am_FINAL_FEEDBACK_WANTED
: The default is true
for this slot in a radio button panel. This makes sure the user selected button stays selected after interaction is complete.
Am_HOW_SET
: Since radio buttons are only allowed to have a single selection, this slot defaults to Am_CHOICE_SET
. However, if you want to allow the user to turn off the current selection by clicking on it again, you can set this slot to be Am_CHOICE_TOGGLE
. It would be wrong to use Am_CHOICE_LIST_TOGGLE
.
An
Am_Checkbox_Panel
is essentially the same as an Am_Radio_Button_Panel
. It is drawn slightly differently, and the following slot is different:
Am_HOW_SET
: The default for a checkbox panel is Am_CHOICE_LIST_TOGGLE
, which allows multiple items to be selected at the same time.
Am_Checkbox_Panel
, the Am_VALUE
slot of the top-level Am_COMMAND
contains an Am_VALUE_LIST
of the labels or IDs of the selected items.
Am_Menu
is a single menu panel, implemented as another form of Am_Button_Panel
. A menu panel has a background rectangle behind it, and the items are drawn differently than in Am_Buttons
.The following slots of an
Am_Menu
differ from those in an Am_Button_Panel
:
Am_WIDTH, Am_HEIGHT
: The default formulas in these slots calculate the width and height of the menu's items, and add enough width and height to contain the menu's outer border.
Am_HOW_SET
: The default for a menu is Am_CHOICE_SET
.
Am_X_OFFSET, Am_Y_OFFSET
: These slots cause the menu items to be offset from the upper left corner of the menu. The defaults are 2 for X and Y, to make room for the outer border around the menu.
Am_V_SPACING
: This creates extra space between the items in a menu. The default value is -2
, which pushes the menu items vertically closer together in the menu.
Am_TEXT_OFFSET
: This offset is used only in the horizontal direction when a text label is being displayed in the menu item (as opposed to a graphical object). This allows greater horizontal spacing for text, while keeping the standard vertical spacing. The default value is 2 pixels.
Am_Menu
object.
Am_Object my_menu = Am_Menu.Create("my_menu")
.Set (Am_LEFT, 150)
.Set (Am_TOP, 200)
.Set (Am_ITEMS, Am_Value_List()
.Add ("Menu item")
.Add (Am_Menu_Line_Command.Create("my menu line"))
.Add (Am_Command.Create("item2")
.Set(Am_ACTIVE, false)
.Set(Am_LABEL, "Not active"))
.Add (Am_Command.Create("item2")
.Set(Am_LABEL, ("Active item"))
.Set(Am_ACCELERATOR, "CONTROL_a"));
my_window.Add_Part(my_menu);The menu has three menu items with a line between the first and second items. The first item appears as ``Menu item'' in the menu, and has no corresponding command object. If that item is selected by the user, the do action of my_menu's command object will be called with ``Menu item'' in its
Am_VALUE
slot. Since there is no command object associated with the first menu item, there is no way to make it inactive without making the whole menu inactive.The second menu item appears in the menu as ``Not active''. It will be grayed out, because the
Am_ACTIVE
slot of its corresponding button command object is set to false. This item cannot be chosen from the menu because it is inactive.The third menu item appears in the menu as ``Active item ^a''. It does have a command object associated with it, so if it is selected by the user, that command's do action will be executed, and the widget's top level command will not be executed. The widget's top level command object is not called unless you set the individual button command object's
Am_IMPLEMENTATION_PARENT
slot to point to it. This command has an accelerator, so if the user hits control-a in my_window, the command will be executed.
Am_Menu_Bar
is a menubar like you might find at the top of a window that has a horizontal row of items you can select, and each one pops down a menu of further options. Sometimes it is called a pull-down menu. Amulet's menu bar currently supports a single level of sub-menus (no pull-outs from the pull-downs). However, any menu item (either at the top level or a sublevel) can be an abitrary Amulet object, just like with other button-type objects.The interface to menu bars is similar to other button widgets: the
Am_ITEMS
slot of the menu_bar object should contain an Am_Value_List
. However, unlike other objects, the list must contain command objects. The label field of this command object serves as the top-level menubar item. In the command object should be an Am_ITEMS
slot containing an Am_Value_List
of the sub-menu items. This list can contain command objects, strings or Amulet objects, as with other menus and button panels. For example:
my_menu_bar = Am_Menu_Bar.Create()
.Set(Am_ITEMS, Am_Value_List ()
.Add (Am_Command.Create("File_Command")
.Set(Am_LABEL, "File")
.Set(Am_DO_METHOD, my_file_do)
.Set(Am_ITEMS, Am_Value_List ()
.Add ("Open...")
.Add ("Save As...")
.Add (Am_Command.Create("Quit_Command")
.Set(Am_DO_METHOD, my_quit)
.Set(Am_LABEL, "Quit")
.Set(Am_ACCELERATOR, "^q"))
)
)
.Add (Am_Command.Create("Edit_Command")
.Set(Am_LABEL, "Edit")
.Set(Am_DO_METHOD, my_edit_do)
.Set(Am_ITEMS, Am_Value_List ()
.Add (undo_command.Create())
.Add ("Cut")
.Add ("Copy")
.Add ("Paste")
.Add (Am_Menu_Line_Command.Create("my menu line"))
.Add ("Find...")
)
)
)If a sub-menu item has a command (like Quit or Undo above), then its
Am_DO_METHOD
is called when the item is chosen by the user. If it does not have a command object (like Cut and Paste above), then the command object of the main item is used (here, the do method called my_edit_do
in the command object named Edit_Command
will be called for Cut and Paste, and the Am_VALUE
slot of the Edit_Command
will be set to the string of the particular item selected). Note that because the first level value list must contain command objects, the command object stored in the menu_bar object itself will never be used unless the programmer explicitly sets the Am_IMPLEMENTATION_PARENT
slot of a command to the menu_bar's command object. The Am_VALUE
of whatever command object is executed will be set to the label or ID of the selected item. Menu bars can also contain accelerators, as shown by the Quit command in the example.
Am_Menu_Bars
allow the top level item to be chosen (unlike, say the Macintosh), in which case its command object is called with its own label or ID as the Am_VALUE
. The programmer should ignore this selection if, as usually is the case, pressing and releasing on a top-level item should do nothing.Individual items can be made unselectable by simply setting the
Am_ACTIVE
field of the command object for that item to false. If the Am_ACTIVE
field of a top-level command object is false, then the entire sub-menu is greyed out, although it will still pop up so the user can see what's in it.Unlike regular menus and panels, the Am_Menu_Bar will not show the selected value after user lets up with the mouse. That is, you cannot have Am_FINAL_FEEDBACK_WANTED as true.
Slots that behave different for the Am_Menu_Bar are:
Am_HOW_SET
must stay Am_CHOICE_SET.
Am_Vertical_Scroll_Bar
and Am_Horizontal_Scroll_Bar
are widget objects that allow the selection of a single value from a specified range of values, either as a int
or a float
(see section 6.2.4.1). You specify a minimum and maximum legal value, and the scroll bar allows the user to pick any number in between. The user can click on the indicator and drag it to set the value. As the indicator is dragged, the value is updated continuously. If the user clicks on the arrows, in the scroll bar, the scroll bar increments or decrements the current value by Am_SMALL_INCREMENT
. If the user clicks above or below the scroll bar, the value jumps by Am_LARGE_INCREMENT
. Unfortunately, auto-repeat (repeatedly incrementing while the mouse button is held down) is not implemented yet. You can also adjust the indicator's size to show what percent of the entire contents is visible.Like all other widgets, the Am_Vertical_Scroll_Bar and Am_Horizontal_Scroll_Bar store the value in the Am_VALUE slot of the widget and in the Am_VALUE slot of the Am_COMMAND object. As the value is changed by the user, the
Am_DO_METHOD
of the command is also continuously called. The Am_VALUE
slot of the widget can also be set by a program to adjust the position of the scroll bar indicator.The
Am_Scrolling_Group
provides a convenient interface for a scrollable area. It operates similarly to a regular Am_Group
(see the Opal chapter), except that it optionally displays two scroll bars which the user can use to see different parts.
Am_VALUE_1, Am_VALUE_2, Am_SMALL_INCREMENT
, and Am_LARGE_INCREMENT
. If all of these slots hold values of type integer, then the result stored into the Am_VALUE
slot will also be an integer. If any of these values is a float, however, then the result will be a float. The default values are 0, 100, 1 and 10, so the default result is an integer. Note that the Inspector and cout
display floats without decimal parts as integers, but the scroll bar still treats them as floats.
Am_VALUE
slot.
Am_ACTIVE
: This determines whether the scroll bar is active or not. Inactive scroll bars do not respond to user input. However, in the default Motif look and feel, they are not drawn any differently.
Am_VALUE
: This holds the currently selected value on the scroll bar. As discussed above, it will either be an integer or float value.
Am_VALUE
slot and the displayed value to the previous value. However, most applications do not allow scrolling operations to be undone, in which case, you should make sure that the scrolling command is not queued on the undo list (see the section on Undo in the Interactors manual).For scrolling groups, the default is not to be undoable. If you want the scrolling group commands to be queued for undoing, set the Am_COMMAND slot of the scrolling group to be NULL.
Here is a description of the customizable slots of a scroll bar:
Am_WIDTH
: This determines the width of the scroll bar. This includes the height of the arrows at the ends of horizontal scroll bars. The default is 20 for vertical bars, and 200 for horizontal bars.
Am_HEIGHT
: This determines the height of the scroll bar. This includes the height of the arrows at the ends of vertical scroll bars. The default is 200 for vertical bars, and 20 for horizontal bars.
Am_VALUE_1
: This is the value selected in the scroll bar when the indicator is at the top (for vertical scroll bars) or left (for horizontal) end of the scroll bar. The default type is an int, but it can also be a float. The default is 0. Note that Am_VALUE_1
is not required to be less than Am_VALUE_2
, in case you want the bigger value to be at the top or left.
Am_VALUE_2
: This is the value selected in the scroll bar when the indicator is at the bottom (for vertical scroll bars) or right (for horizontal) end of the scroll bar. The defauls type is an int, but it can also hold a float. The default is 100. Note that Am_VALUE_2
is not required to be bigger than Am_VALUE_1.
Am_SMALL_INCREMENT
: This is the amount the value is changed when the user clicks on the arrows at the end of the scroll bar. The default value is 1 of type int. The slot can contain either an int or a float.
Am_LARGE_INCREMENT
: This is the amount the value is changed when the user clicks on the scroll area on either side of scroll handle. The default value is 10 of type int. The slot can contain either an int or a float.
Am_PERCENT_VISIBLE
: This slot specifies how large the indicator will be with respect to the region it is dragged back and forth in. The slot should hold a float between 0.0 and 1.0, and the default is 0.2. If this value determines a thumb smaller than 6 pixels long, a 6 pixel thumb is drawn instead.
Am_Scrolling_Group
just like a regular group, but the user will be able to scroll around using the optional vertical and horizontal scrollbars.A scrolling group has two distinct rectangular regions. One is the region that is drawn on the screen, and contains scroll bars, and a rectangle with a visible portion of the group. This region is defined by the
Am_LEFT, Am_TOP, Am_WIDTH
and Am_HEIGHT
of the Am_Scrolling_Group
itself. The other region is called the inner region which is the size of all the objects, some of which might not be visible. This area is controlled by the Am_INNER_WIDTH
and Am_INNER_HEIGHT
slots.By default, the
Am_ACTIVE
slots of the scroll bars are calculated based on whether the scroll bars are needed (whether any of the group is hidden in that direction). The percent-visible is also calculated based on the amount of the group that is visible. The Am_H_LARGE_INCREMENT
and Am_V_LARGE_INCREMENT
are also calculated based on the screen size.
Am_INNER_WIDTH
and Am_INNER_HEIGHT
slots, such as Am_Width_Of_Parts
and Am_Height_Of_Parts.
). However, when enumerating the parts of a Am_Scrolling_Group
, do not use a Am_Part_Iterator
, since this will also list the scroll bars. Instead, use the Am_Value_List
stored in the Am_GRAPHICAL_PARTS
slot of the group, which will only contain the objects you added. The Am_GRAPHICAL_PARTS
slot can also be used for normal groups (instances of Am_Group
and Am_Map
), so you can write code that will operate on either scrolling groups or regular groups.
Am_WIDTH
, Am_HEIGHT
: These default to 150 in a scrolling group. The width and height determine the size of the group's graphical appearance on the screen, including space for scroll bars.
Am_Y_OFFSET
: These are the coordinates of the visual region, in relation to the origin of the inner region. The slots always contain a nonnegative integer, with 0 corresponding to no offset (meaning that the scrollable region's top and left are the same at the top, left of the visible area). The default is 0 for both X and Y offset. You may also Get or Set these slots, and the slots can even contain formulas. Getting the slot gives you the current scrollbar position, and setting the slot changes the current scrollbar position and scrolls the area.
Am_FILL_STYLE
: The filling style (color) used to draw the scroll bars (and the background of the window if Am_INNER_FILL_STYLE
is 0).
Am_INNER_FILL_STYLE
: This determines what the background fill of the group will be. If it is an Am_Style
, that style is used. If it contains 0, the Am_FILL_STYLE
slot is used.
Am_LINE_STYLE
: This determines what the border of the scrolling region. The default is Am_Thin_Line. The size of the scrolling area is adjusted inward to make room for the specified line thickness. If 0, then no line is drawn.
Am_V_SCROLL_BAR
: These booleans determine whether the group will have vertical and/or horizontal scroll bars. These slots default to true.
Am_H_SCROLL_BAR_ON_TOP, Am_V_SCROLL_BAR_ON_LEFT
: These booleans determine which side of the group the scroll bars appear on. The defaults are false for both, which puts the horizontal scroll bar at the bottom of the group, and the vertical scroll bar at the right of the group as on most standard windows.
Am_H_SMALL_INCREMENT, Am_V_SMALL_INCREMENT
: This is the small increment in pixels of the horizontal and vertical scroll bars. The value determines how much the scrolling group is moved when the user clicks on the scroll arrows. The default is 10 pixels.
Am_H_LARGE_INCREMENT, Am_V_LARGE_INCREMENT
: This is the large increment, in pixels, of the horizontal and vertical scroll bars. The value determines how much the scrolling group is moved when the user clicks on the scroll areas beside the scroll indicators. The default is calculated by a formula to jump one visible screen full.
Am_INNER_WIDTH, Am_INNER_HEIGHT
: This is the size of the entire group, not just the visible portion. The defaults are 400 for both. This will usually be calculated by a formula based on the contents of the scrolling group (e.g., Am_Width_Of_Parts
and Am_Height_Of_Parts
). It is OK if these are smaller than the scrolling group's Am_WIDTH
and Am_HEIGHT
: this just means that the entire area is visible, and so the appropriate scroll bars will be disabled.
Am_Scrolling_Group
, simply create an instance of it, customize the Am_TOP, Am_LEFT
, Am_WIDTH
, and Am_HEIGHT
slots of the group to define its size, set the Am_INNER_WIDTH
and Am_INNER_HEIGHT
based on the contents, and add graphical parts to the group.
my_scrolling_group = Am_Scrolling_Group.Create("scroll_group")
.Set(Am_LEFT, 10)
.Set(Am_TOP, 10)
.Set(Am_WIDTH, 200)
.Set(Am_HEIGHT, 300))
.Add_Part(Am_Rectangle.Create()
.Set(Am_LEFT, 0)
.Set(Am_TOP, 0)
.Set(Am_WIDTH, 15)
.Set(Am_HEIGHT, 15)
.Set(Am_FILL_STYLE, Am_Blue)
);
my_window.Add_Part(my_scrolling_group);This creates a scrolling group with an area of 200 by 300 pixels, and an internal region 400 by 400 pixels (the default values are inherited since none were specified). The scrolling group is displayed at location 10,10 in
my_window
. It contains a single object, a blue square 15 pixels on a side, in the upper left corner of the inner region. The scrolling group will have a vertical scroll bar on the right side of the group, and a horizontal scroll bar on the bottom of the group, as specified by the defaults.
Am_Text_Input_Widget
is used to get a single line of text input from the user, for example for filenames.The widget has an optional label to the left of a text type-in field. The label is the value of the
Am_LABEL
field of the command object (and can be a string or arbitrary Amulet graphical object, or an empty string for no label). The user can click the mouse button in the field, and then type in a new value. The Am_VALUE
of the command in the Am_COMMAND
slot is set to the new string, and the command's Am_DO_METHOD
is called. The command's default Am_UNDO_METHOD
restores the Am_VALUE
and the displayed string to its previous value. As the user types, if the string gets too long to be displayed, it scrolls left and right as appropriate so the cursor is always visible. The user can finish the typing by typing return on the keyboard, or by clicking outside the text input field.The text input widget could also be used as an output-only text display by setting the Am_ACTIVE_2 slot (see Section 6.2.1) to false, which will disable the interactors.
The special slots of the
Am_Text_Input_Widget
are:
Am_WIDTH
- unlike most widgets, the default width is a constant (150) since the widget scrolls the text to fit. You will probably want to set the width to some other constant or formula.
Am_HEIGHT
- the default formula for the height uses the maximum of the height of the label and the height of the string.
Am_FONT
- this slot holds the font of the string that the user edits, and the default is the regular default font.
Am_LABEL_FONT
- this slot holds the font used for the label if the label is a string (the label comes from the Am_LABEL
slot of the command object in the widget). The default is a bold font.
Am_FILL_STYLE
- the color used for the user type-in field.
Am_LABEL
of the command in the Am_Text_Input_Widget
is used as the label of the input field, so if you do not want a label, make the slot be the null string "". The Am_VALUE
of the widget is set with the value the user types, and the Am_DO_METHOD
is called.
If you add an instance of the Am_Tab_To_Next_Widget_Interactor to a window or group, then by default, hitting the TAB key will move from the one Am_Text_Input_Widget to the next, and SHIFT_TAB will move backwards. As the cursor is moved to the Am_Text_Input_Widget, a box is drawn around the widget to show it is selected, and the widget is started with the old contents of the widget selected in ``pending-delete'' mode, so that if the next character typed is a normal printing character, it will replace the old string. If another widget was operating when the TAB key was hit, then that widget is stopped, which will call its DO_METHOD. There is no way to distinguish leaving a Am_Text_Input_Widget because the user hit RETURN to confirm the value, versus clicking outside, versus hitting TAB to go to the next field. Therefore, it is recommended that you do not use the DO_METHOD of the command in the widget to anything if you are using the Am_Tab_To_Next_Widget_Interactor. The command used by this interactor is not undoable, so moving from field to field is not queued on the undo history.
Note: In toolkits such as Motif and MS Windows, you can TAB to other widgets besides text input widgets, for example to use the arrow keys to select which button to press. This is not yet supported in Amulet, so the TAB interactor just goes from text widget to text widget, skipping all other kinds of widgets.
The Am_Tab_To_Next_Widget_Interactor has a number of slots that can be used to customize the behavior:
Most graphical applications need to have "selection handles," which are small squares that show which object(s) are selected and which allow the objects to be moved and changed size. Surprisingly, most toolkits require each application to reimplement this basic functionality. Amulet supplies this behavior through the supplied Am_Selection_Widget object, which you simply can add to your application, and then its objects will be selectable and manipulatable
Slots that control the Am_Selection_Widget are:
//scroller is the top-level scrolling group to put things in
scroller = Am_Scrolling_Group.Create("scroller")
.Set (Am_LEFT, 55)
.Set (Am_TOP, 40)
.Set (Am_INNER_WIDTH, 1000)
.Set (Am_INNER_HEIGHT, 1000)
.Set (Am_INNER_FILL_STYLE, Am_White)
.Set (Am_WIDTH, scroll_width_formula) //width and height will be
.Set (Am_HEIGHT, scroll_height_formula) // based on window's
;
//all objects that will be created and that can be selected and moved will be put into created_objs
created_objs = Am_Group.Create("created_objs")
.Set (Am_LEFT, 0)
.Set (Am_TOP, 0)
.Set (Am_WIDTH, 1000)
.Set (Am_HEIGHT, 1000)
;
//the selection widget operates on the group created_objs
my_selection = Am_Selection_Widget.Create("my_selection")
.Set(Am_OPERATES_ON, created_objs)
//put the scroller in the window
my_window.Add_Part(scroller);
//put the selection widget and the created_objs as parts of the scrolling group
scroller.Add_Part(created_objs);scroller.Add_Part(my_selection);
As mentioned above, you can access the list of selected objects in the Am_VALUE slot of the Am_Selection_Widget. You can also set this slot to change the set of selected objects. Be sure to only set this slot to an Am_Value_List, even if you want no objects or a single object selected. For example, to clear the selection, use:
my_selection.Set(Am_VALUE, Am_Value_List());There are also two command objects you can use to monitor the selection widget's activities. The Am_COMMAND part is used when the selection changes. The
Am_VALUE
of the Am_COMMAND object is set with the current selection, and its Am_DO_METHOD is called whenever the selection changes. The Am_IMPLEMENTATION_PARENT of this command is Am_NOT_USUALLY_UNDONE by default, since normally changing the selection is not undoable. If you want the selections to be undoable, set the Am_IMPLEMENTATION_PARENT slot of the Am_COMMAND of the selection widget to be NULL. This is done automatically by the undo dialog box (see Section 5.6.2.3.2) when the user clicks on the undo selections check box.
The other command is used when the user moves or grows an object. This command is in the Am_MOVE_GROW_COMMAND named part. You should probably not replace this command, because it has a built-in formula to make the label be correct based on the operation, but it is fine to override the various DO and UNDO methods. By default, the move and grow operations are undoable, if there is an undo handler attached to the window the selection widgets are in.
6.2.6.2 User Interface to Am_Selection_Widget
The selection widget operates in the standard way of the selection handles on the Macintosh and Windows. The user can click with the specified button (usually the left button) over an object to select it. Holding down the shift key while clicking will add or remove the object under the mouse to the selected set. Thus, to select multiple objects, you can click on them with the shift key held down. If you click in the background, all objects will be de-selected. Unfortunately, selecting objects by dragging out a region is not yet supported.6.3 Dialog boxes
Amulet provides three standard dialog box widgets with different appearances but similar operation to be used for simple messages and queries. We also provide several functions to make the dialog boxes easier to use. The dialog boxes are:
void Am_Show_Alert_Dialog (Am_Value_List alert_texts, int x = 100,
int y = 100, bool modal = false)This routine brings up an alert dialog box at the location (x, y) on the main screen, and waits for the user to close it by clicking the "OK" button. The list alert_texts is a list of char* or Am_String values which will be displayed, one per line, above the "Okay" button. If modal is true, the dialog box will be run modally, otherwise it will be run non-modally. This routine does not return until the user clicks on either OK or Cancel.
Am_Value Am_Get_Choice_From_Dialog (Am_Value_List prompt_texts,
int x = 100, int y = 100, bool modal = false);This routine brings up a choice dialog box at the location (x, y) on the main screen, and waits for the user to close it by clicking either the "OK" or "Cancel" button. The list prompt_texts is a list of char* or Am_String values which will be displayed, one per line, above the buttons. If modal is true, the dialog box will be run modally, otherwise it will be run non-modally. The return value will be a string, either "OK" or "Cancel" depending on which button the user pressed.
Am_Value Am_Get_Input_From_Dialog (Am_Value_List prompt_texts,
Am_String initial_value = "",
int x = 100, int y = 100,
bool modal = false)This routine brings up an input dialog box at the location (x, y) on the main screen, and waits for the user to close it by clicking either the "OK" or "Cancel" button. The list prompt_texts is a list of char* or Am_String values which will be displayed, one per line, above the text input line and buttons. If modal is true, the dialog box will be run modally, otherwise it will be run non-modally. The return value will be a string, the value of the text widget, if the user clicks "OK" or presses RETURN to close the dialog box. The routine returns Am_No_Value if the user clicks "Cancel."
Am_Value Am_Show_Dialog_And_Wait (Am_Object the_dialog,
bool modal = false)This routine displays a preconfigured dialog box, waits for the user to complete interaction with it, and then returns its value. The only slots the dialog box changes before displaying the dialog box are its command's Am_DO_METHOD and Am_ABORT_METHOD. This routine is useful for reusing a commonly displayed dialog box without the overhead of reallocating and reinitializing the dialog box each time it is displayed. The dialog is added to Am_Screen if it is not already there, but it is not removed when the routine is finished.
Most of these commands operate on the currently selected objects, so they require that you pass in an instance of a selection widget (Section 6.2.6) in the Am_SELECTION_WIDGET slot of the command object. If you implement your own selection handles and do not use the selection widget, you still may be able to use the following commands, if your selection handles object provides the set of selected objects in the Am_VALUE slot, and allows that slot to be set to change the selection.
The supplied command objects are as follows. See the tables in the Summary chapter, Section 11.7 for a list of the slots to be set in each.
Am_Graphics_Clear_Command
: delete the selected objects. The label is ``Clear'' and the accelerator is ``DELETE''. Must be passed a Am_SELECTION_WIDGET.
Am_Graphics_Clear_All_Command
: The label is ``Select All'' and the accelerator is ``CONTROL_a''. Must be passed a Am_SELECTION_WIDGET.
Am_Graphics_Copy_Command
: Copy to the clipboard. The label is ``Copy'' and the accelerator is ``CONTROL_c''. Must be passed a Am_SELECTION_WIDGET.
Am_Graphics_Cut_Command
: Copy objects to the clipboard and then delete them. The label is ``Cut'' and the accelerator is ``CONTROL_x''. Must be passed a Am_SELECTION_WIDGET.
Am_Graphics_Paste_Command
: Paste a copy of the objects in the clipboard. The label is ``Paste'' and the accelerator is ``CONTROL_v''. Must be passed a Am_SELECTION_WIDGET.
Am_Graphics_To_Bottom_Command
: Make the selected objects be covered by all other objects. The label is ``To Bottom'' and the accelerator is ``CONTROL_<''. Must be passed a Am_SELECTION_WIDGET.
Am_Graphics_To_Top_Command
: Make the selected objects be covered by no other objects. The label is ``To Top'' and the accelerator is ``CONTROL_>''. Must be passed a Am_SELECTION_WIDGET.
Am_Graphics_Duplicate_Command
: Duplicate the selected objects. The label is ``Duplicate'' and the accelerator is ``CONTROL_d''. Must be passed a Am_SELECTION_WIDGET.
Am_Graphics_Group_Command
: Make a group out of the selected objects. Creates an instance of Am_Resize_Parts_Group (see Section 4.7.3 in the Opal chapter) and adds the selected objects to it. The new group has its Am_CREATED_GROUP slot set to true, which is used by ungroup and change property. The label of the command is ``Group'' and the accelerator is ``CONTROL_p''. (We would have made it ^G, but that is used for aborting all interactors and widgets). Must be passed a Am_SELECTION_WIDGET.
Am_Graphics_Ungroup_Command
: Ungroup the selected objects. This will only operate on objects that have the Am_CREATED_GROUP slot set to true, which are typically those groups created by the Am_Graphics_Group_Command
. The label is ``Select All'' and the accelerator is ``CONTROL_h''. Must be passed a Am_SELECTION_WIDGET.
Am_Undo_Command
: Perform a single undo. The label is ``Undo'' and the accelerator is ``CONTROL_z''. This finds the undo handler by looking for the window of the object in the Am_SELECTION_WIDGET slot (which can be any object whose Am_WINDOW is the window containing the undo handler--for this command, this slot doesn't have to contain a selection widget). If the Am_SELECTION_WIDGET slot is null, then gets the window from the widget the command is attached to, and looks for that window's undo handler.
Am_Redo_Command
: Perform a single redo. The label is ``Redo'' and the accelerator is ``CONTROL_SHIFT_Z''. Looks for an undo handler the same way as Am_Undo_Command.
Am_Graphics_Set_Property_Command
: to set the color, line style or other property of the selected objects. This has a slightly more complicated interface, as described in Section 6.4.2. Must be passed a Am_SELECTION_WIDGET.
menu_bar = Am_Menu_Bar.Create(``menu_bar'')
.Set(Am_ITEMS, Am_Value_List ()
.Add (Am_Command.Create(``File_Command'')
.Set(Am_IMPLEMENTATION_PARENT, true) //top command not queued for undo
.Set(Am_LABEL, ``File'')
.Set(Am_ITEMS, Am_Value_List ()
.Add (Am_Quit_No_Ask_Command.Create())
)
)
.Add (Am_Command.Create(``Edit_Command'')
.Set(Am_LABEL, ``Edit'')
.Set(Am_IMPLEMENTATION_PARENT, true) //top command not queued for undo
.Set(Am_ITEMS, Am_Value_List ()
.Add (Am_Undo_Command.Create()) //these get the undo_handler from
.Add (Am_Redo_Command.Create()) // menubar's window
.Add (Am_Show_Undo_Dialog_Box_Command.Create()
.Set(Am_UNDO_DIALOG_BOX, my_undo_dialog))
.Add (Am_Menu_Line_Command.Create())
.Add (Am_Graphics_Cut_Command.Create()
.Set(Am_SELECTION_WIDGET, my_selection))
.Add (Am_Graphics_Copy_Command.Create()
.Set(Am_SELECTION_WIDGET, my_selection))
.Add (Am_Graphics_Paste_Command.Create()
.Set(Am_SELECTION_WIDGET, my_selection))
.Add (Am_Graphics_Clear_Command.Create()
.Set(Am_SELECTION_WIDGET, my_selection))
.Add (Am_Graphics_Clear_All_Command.Create()
.Set(Am_SELECTION_WIDGET, my_selection))
.Add (Am_Menu_Line_Command.Create())
.Add (Am_Graphics_Duplicate_Command.Create()
.Set(Am_SELECTION_WIDGET, my_selection))
.Add (Am_Selection_Widget_Select_All_Command.Create()
.Set(Am_SELECTION_WIDGET, my_selection))
)
)
.Add (Am_Command.Create(``Arrange_Command'')
.Set(Am_LABEL, ``Arrange'')
.Set(Am_DO_METHOD, my_do)
.Set(Am_IMPLEMENTATION_PARENT, true) //top command not queued for undo
.Set(Am_ITEMS, Am_Value_List ()
.Add (Am_Graphics_To_Top_Command.Create()
.Set(Am_SELECTION_WIDGET, my_selection))
.Add (Am_Graphics_To_Bottom_Command.Create()
.Set(Am_SELECTION_WIDGET, my_selection))
.Add (Am_Menu_Line_Command.Create())
.Add (Am_Graphics_Group_Command.Create()
.Set(Am_SELECTION_WIDGET, my_selection))
.Add (Am_Graphics_Ungroup_Command.Create()
.Set(Am_SELECTION_WIDGET, my_selection))
)
)
)
;
Am_Graphics_Group_Command
), then the Am_Graphics_Set_Property_Command will recursively change the property of all of its parts. Of course, the Am_Graphics_Set_Property_Command is fully undoable and repeatable.Because the command does not necessarily know how to get the correct value out of the palette or menu or how to update and read the property from the graphical object, a number of methods can be overridden in the command to control how the command gets and sets the value from the palette and from the graphical object. The slots that control the Am_Graphics_Set_Property_Command are:
Am_Define_Method_Type(Am_Get_Widget_Property_Value_Method, void,
(Am_Object command_obj, Am_Value &new_value));
Am_Define_Method_Type(Am_Get_Object_Property_Value_Method, void,
(Am_Object command_obj, Am_Object object,
Am_Value &old_value));
Am_Define_Method_Type(Am_Set_Object_Property_Value_Method, void,
(Am_Object command_obj, Am_Object object,
Am_Value new_value));
extern void Am_Start_Widget(Am_Object widget,
Am_Value initial_value = Am_No_Value);Explicitly start a widget running. If already running, does nothing. If an initial value is provided, then the widget is started with this as its value. It is up to the programmer to make sure the initial_value is legal for the type of widget. If no initial_value is supplied, the widget is started with its current value, if any.
extern void Am_Abort_Widget(Am_Object widget_or_inter_or_command);Explicitly abort a widget, interactor or command object. Often, this will be called with a command object, and the system will then find the associated widget or interactor and abort it. If that widget or Interactor is not running, then this does nothing. The function tries to make sure the command object passed in (or the command object associated with the widget or Interactor) is not entered into the command history.
extern void Am_Stop_Widget(Am_Object widget,
Am_Value final_value = Am_No_Value);Explicitly stop a widget. If not running, raises an error. If final_value is supplied, then this is the value used as the value of the widget. If final_value is not supplied, the widget uses its current value. Commands associated with the widget will be invoked just as if the widget had completed normally.