# Introduction to CommandObjects

The V `CommandObject` structure is used to define the contents of vDialogs and vCommandPanes. Each element of a `CommandObject` defines a control (such as a Button or Scroll Bar) of a particular `CmdType` with an associated string and attributes, including size and position within the dialog.

This section is intended to be a complete reference for `CommandObjects`. It is organized into the following sections:

- CommandObject - The description of the `CommandObject` structure.
- Commands - The various commands or controls supported by V.
- CmdAttribute - Various attributes used to define `CommandObjects`.
- Predefined ItemVals - Predefined values useful for defining `CommandObjects`.

# CommandObject

Used to define commands to dialogs and command panes.

## Synopsis

Header:
  `<v/v_defs.h>`
Type name:
  CommandObject
Part of:
  vDialog, vCommandPane

## Description

This structure is used to define command items in dialogs and command panes. You will define a static array of `CommandObject` items. This array is then passed to the `AddDialogCmds` method of a dialog class such as `vDialog` or `vModalDialog`, or the constructor of a `vCommandPane` object, or more typically, a class derived from one of those.

## Definition

    typedef struct CommandObject
      {
        CmdType cmdType;    // what kind of item is this
        ItemVal cmdId;      // unique id for the item
        ItemVal retVal;     // initial value of object
        char* title;        // string
        void* itemList;     // used when cmd needs a list
        CmdAttribute attrs; // list of attributes
        int Sensitive;      // if item is sensitive or not
        ItemVal cFrame;     // Frame used for an item
        ItemVal cRightOf;   // Item placed left of this id
        ItemVal cBelow;     // Item placed below this one
        int size;           // Used for size information
        char* tip;          // ToolTip string
      } CommandObject;

## Structure Members

`CmdType cmdType`
This value determines what kind of command item this is. The types of commands are explained in the section Commands.

`ItemVal cmdId`
This unique id for the command defined by the programmer. Each command item belonging to a dialog should have a unique id, and it is advisable to use some scheme to be sure the ids are unique. The V system does not do anything to check for duplicate ids, and the behavior is undefined for duplicate ids. The id for a command is passed to the `DialogCommand` method of the dialog, as well as being used for calls to the various `SetX` and `GetX` methods. There are many predefined values that can be used for ids as described in the section Standard V Values.

The values you use for your id in menus and controls should be limited to being less than 30,000. The predefined V values are all above 30,000, and are reserved. There is no enforcement of this policy. It is up to you to pick reasonable values.

The type `ItemVal` exists for historical reasons, and is equivalent to an int, and will remain so. Thus, the easiest way to assign and maintain unique ids for your controls is to use a C++ `enum`. As many as possible examples in this manual will use `enums`, but examples using the old style `const` `ItemVal` declarations may continue to exist. There is more discussion of assigning ids in the following example.

`int retVal`
The use of this value depends on the type of command. For buttons, for example, this value will be passed (along with the `cmdId`) to the `DialogCommand` method. The `retVal` is also used for the initial on/off state of check boxes and radio buttons. For some commands, `retVal` is unused. Note that the static storage provided in the declaration is not used to hold the value internally. You should use `GetValue` to retrieve the current value of a command object.

`char* title`
This is used for the label or text string used for command items.

`void* itemList`
This is used to pass values to commands that need lists or strings. The ListCmd is an example. Note the `void *` to allow arbitrary lists.

`CmdAttribute attrs`
Some command items use attributes to describe their behavior. These attributes are summarized in the `CmdAttribute` section.

`int Sensitive`
This is used to determine if an item is sensitive or not. Note that the static storage provided in the declaration is used by the V system to track the value, and should be changed by the `SetValue` method rather than directly. Thus dialogs sharing the same static declaration will all have the same value. This is usually desired behavior.

`ItemVal cFrame`
Command items may be placed within a frame. If this value is 0 (or better, the symbol `NoFrame`), the command will be placed in the main dialog area. If a value is supplied, then the command will be placed within the frame with the id `cFrame`.

`ItemVal cRightOf, ItemVal cBelow`
These are used to describe the placement of a command within a dialog. Ids of other commands in the same dialog are used to determine placement. The current command will be placed to the right of the command `cRightOf`, and below the command `cBelow`. The commands left and above don't necessarily have to be adjacent. By careful use of these values, you can design very attractive dialogs. You can control the width of command objects by padding the label with blanks. Thus, for example, you can design a dialog with all buttons the same size.

You can also use the `CA_Hidden` attribute to selectively hide command objects that occupy the same location in the dialog. Thus, you might have a button labeled `Hide` right of and below the same command object as another button labeled `UnHide`. By giving one of the two buttons the `CA_Hidden` attribute, only one will be displayed. Then you can use `SetValue` at runtime to switch which button is displayed in the same location. The bigger of the two command objects will control the spacing.

`int size`
The size parameter can be used for some command objects to specify size. For example, for labeled Button commands, the `size` specifies the minimum width in pixels of the button. It is also used in various other command objects as needed. A value of zero for `size` always means use the default size. Thus, you can take advantage of how C++ handles declarations and write `CommandObject` declarations that leave off the `size` values, which default to zero. Many of the examples in this reference do not specify these values.

`char* tip`
The tip parameter is used to specify an optional ToolTip string for use with a command object. If you provide a string here, that string will be automatically displayed after the user holds the mouse over that control. The exact delay before the tip is shown, and the format of the tip box is somewhat platform dependent, and all platforms might not support tool tips. (Currently, only OS/2 does not support tips.) Note that if you use a tip, you must be sure to include a value (usually 0) for the size parameter!

### Example

The following example defines a simple dialog with a message label on the top row, a check box on the second row, two buttons in a horizontally organized frame on the third row, and an OK button on the bottom row. The ids in this example are defined using an `enum`. Remember that your ids must be less than 30,000, and using 0 is not a good idea. Thus, the `enum` in this example gives the ids values from 101 to 106. An alternative used in V code prior to release 1.13 was to provide `const` declarations to define meaningful symbolic values for the ids. Many examples of this type of id declaration will likely persist.

It also helps to use a consistent naming convention for ids. The quick reference appendix lists suggested prefixes for each control type under the `CmdType` section. For example, use an id of the form `btnXXX` for buttons. Predefined ids follow the form `M_XXX`.

    enum {lbl1 = 101, frm1, btn1, btn2}
    static CommandObject Sample[] =
      {
        {C_Label, lbl1, 0,"Sample",NoList,CA_MainMsg,isSens,NoFrame,0,0},
        {C_Frame, frm1, 0, "", NoList,CA_None,isSens,NoFrame,0,lbl1},
        {C_Button, btn1, 0, "Button 1", NoList, CA_None, isSens,frm1,0,0,0,
             "Tip for Button 1"},
        {C_Button, btn2, 0, "Button 2", NoList, CA_None, isSens,frm1,btn1,0,0,
             "Tip for Button 2"},
        {C_Button, M_OK, M_OK, " OK ", NoList, CA_DefaultButton,
            isSens, NoFrame,0,frm1},
        {C_EndOfList,0,0,0,0,CA_None,0,0,0}
      };

# CommandObject Commands

This section describes how each of the command objects available in V is used to build dialogs.

V provides several different kinds of command items that are used in dialogs. The kind of command is specified in the `cmdType` field of the `CommandObject` structure when defining a dialog. This section describes current dialog commands available with V. They will be constructed by V to conform to the conventions of the host windowing system. Each command is named by the value used to define it in the `CommandObject` structure.

## List of commands

C_Blank, C_BoxedLabel, C_Button, C_CheckBox, C_ColorButton, C_ComboBox, C_EndOfList, C_Frame, C_Icon, C_IconButton, C_Label, C_ColorLabel, C_List, C_ProgressBar, C_RadioButton, C_Slider, C_Spinner, C_Text, C_TextIn, C_ToggleButton, C_ToggleFrame, C_ToggleIconButton

## Commands

#### C_Blank

A Blank can help you control the layout of your dialogs. The Blank object will occupy the space it would take if it were a `C_Label`, but nothing will be displayed. This is especially useful for leaving space between other command objects, and getting nice layouts with RightOfs and Belows. You control the size of the Blank by providing a string with an appropriate number of blanks for the `title` field.

#### C_BoxedLabel

This command object is just like a `C_Label`, but drawn with a surrounding box. See `C_Label`.

#### C_Button

A Button is one of the primary command input items used in dialog boxes. When the user clicks on a Button, the values set in the `cmdId` and `retVal` fields are passed to the `DialogCommand` method. In practice, the `retVal` field is not really used for buttons - the `cmdId` field is used in the `switch` statement of the `DialogCommand` method.

A button is defined in a `CommandObject` array. This is a typical definition:

     {C_Button, btnId, 0,"Save",NoList,CA_None,isSens,NoFrame,0,0}

The `retVal` field can be used to hold any value you wish. For example, the predefined color button frame (see `vColor`) uses the `cmdId` field to identify each color button, and uses the `retVal` field to hold the index into the standard V color array. If you don't need to use the `retVal`, a safe convention is to a 0 for the `retVal`. You can put any label you wish in the `title` field.

If you provide the attribute `CA_DefaultButton` to the `CmdAttribute` field, then this button will be considered the default button for the dialog. The default button will be visually different than other buttons (usually a different border), and pressing the Return key is the same as clicking on the button.

The size of the button in pixels can be controlled by using the `CommandObject` element `size`. By specifying the attribute `CA_Size` and providing a value for the `size` element, you can control the size of the button. Note the that the `size` element is the last one of a `CommandObject`, and can left out of a declaration, which results in the compiler generating a zero value.

You can change the label of a button with: `SetString(btnId,` `"New Label")`. You can change the sensitivity of a button with `SetValue(btnID, OnOrOff, Sensitive)`.

#### C_CheckBox

A CheckBox is usually used to set some option on or off. A CheckBox command item consists of a check box and an associated label. When the user clicks on the check box, the `DialogCommand` method is invoked with the `Id` set to the `cmdId` and the `Val` set to the current state of the CheckBox. The system takes care of checking and unchecking the displayed check box - the user code tracks the logical state of the check box.

A CheckBox is defined in a `CommandObject` array. This is a typical definition:

     {C_CheckBox, chkId, 1,"Show Details",NoList,CA_None,isSens,NoFrame,0,0}

The `retVal` is used to indicate the initial state of the check box. You should use the `GetValue` method to get the current state of a check box. You can also track the state dynamically in the `DialogCommand` method. You can put any label you wish in the `title` field.

You can change the label of a check box with: `SetString(chkId,` `"New Label")`. You can change the sensitivity of a check box with `SetValue(chkID, OnOrOff,Sensitive)`. You can change the checked state with `SetValue(chkID, OnOrOff, Checked)`.

If the user clicks the Cancel button and your code calls the default `DialogCommand` method, V will automatically reset any check boxes back to their original state, and call the `DialogCommand` method an additional time with the original value if the state has changed. Thus, your code can track the state of check boxes as the user checks them, yet rely on the behavior of the Cancel button to reset changed check boxes to the original state.

The source code for the V `vDebugDialog` class provides a good example of using check boxes (at least for the X version). It is found in `v/src/vdebug.cxx`.

#### C_ColorButton

A color command button. This works exactly the same as a `C_Button` except that the button may be colored. You use `C_ColorButton` for the `cmdType` field, and provide a pointer to a `vColor` structure in the `itemList` field using a `(void*)` cast. The label is optional.

The `retVal` field of a color button is not used. You can generate a square color button of a specified size by specifying an empty label (`""`) and a `size` value greater than 0. When you specify the `size` field, the color button will be a colored square `size` pixels per side. When used within a `CA_NoSpace` frame, this feature would allow you to build a palette of small, tightly spaced color buttons. In fact, V provides a couple of such palettes in `v/vcb2x4.h` and `v/vcb2x8.h`. These include files, as well as the other details of the `vColor` class are described in the section `vColor` in the Drawing chapter.

There are two ways to change to color of a button. The most direct way is to change each of the RGB values in three successive calls to `SetValue` using `Red`, `Green`, and finally `Blue` as the `ItemSetType` to change the RGB values. The call with `Blue` causes the color to be updated. I know this isn't the most elegant way to do this, but it fits with the `SetValue` model.

An alternate way is to change the value of the original `vColor` used to define the initial color of the control, and then call `SetValue` with the `ChangeColor` set type.

This is a short example of defining a red button, and then changing it.

        static vColor btncolor(255,0,0};  // define red
        ...

        // part of a CommandObject definition
        {C_ColorButton, cbt1, 0, "", (void*)&btncolor,
            CA_None, isSens, NoFrame, 0, btnXXX},

        ...
        // Code to change the color by some arbitrary values
        btncolor.Set(btncolor.r()+127, btncolor.g()+63, btncolor.b()+31);
    #ifdef ByColor    // by vColor after changing btncolor
        SetValue(cbt1,0,btncolor);
    #else          // by individual colors
        SetValue(cbt1,(ItemVal)btncolor.r(),Red);
        SetValue(cbt1,(ItemVal)btncolor.g(),Green);
        // This final call with Blue causes color to update in dialog
        SetValue(cbt1,(ItemVal)btncolor.b(),Blue);
    #endif
        ...

#### C_ComboBox

A combo box is a drop-down list. It normally appears as box with text accompanied by some kind of down arrow button. You pass a list of alternative text values in the `itemList` field of the `CommandObject` structure. You also must set the `retVal` field to the index (starting at 0) of the item in the list that is the default value for the combo box text title.

If the user clicks the arrow, a list pops up with a set of alternative text values for the combo box label. If the user picks one of the alternatives, the popup closes and the new value fills the text part of the combo box. V supports up to 32 items in the combo box list. You need to use a `C_List` if you need more than 32 items.

With default attributes, a combo box will send a message to `DialogCommand` whenever a user picks a selection from the combo box dialog. This can be useful for monitoring the item selected. If you define the combo box with the attribute `CA_NoNotify`, the dialog in not notified on each pick. You can use `GetValue` to retrieve the index of the item shown in the combo box text field.

You can preselect the value by using `SetValue`. You can change the contents of the combo list by using `vDialog::SetValue` with either `ChangeList` or `ChangeListPtr`. See `vDialog::SetValue` for more details.

### Example

The following is a simple example of using a combo box in a modal dialog. This example does not process items as they are clicked, and does not show code that would likely be in an overridden `DialogCommand` method. The code interface to a list and a combo box is very similar - the interaction with the user is different. This example will initially fill the combo box label with the text of `comboList[2]`.

    enum { cbxId = 300 };
    char* comboList[] =
      {
        "First 0",   // The first item in the list
         ...
        "Item N",    // The last item in the list
        0            // 0 terminates the list
      };
      ...
    CommandObject ComboList[] =
      {
        {C_ComboBox, cbxId, 2, "A Combo Box", (void*)comboList,
           CA_NoNotify,isSens,NoFrame,0,0},
        {C_Button, M_OK, M_OK, " OK ", NoList,
           CA_DefaultButton, isSens, NoFrame, 0, ListId},
        {C_EndOfList,0,0,0,0,CA_None,0,0,0}
      };
        ...
        vModalDialog cd(this);    // create list dialog
        int cid, cval;
        ...
        cd.AddDialogCmds(comboList);   // Add commands to dialog
        cid = ld.ShowModalDialog("",cval);  // Wait for OK
        cval = ld.GetValue(cbxId);  // Retrieve the item selected

#### C_EndOfList

This is not really a command, but is used to denote end of the command list when defining a `CommandObject` structure.

#### C_Frame

The frame is a line around a related group of dialog command items. The dialog window itself can be considered to be the outermost frame. Just as the placement of commands within the dialog can be controlled with the `cRightOf` and `cBelow` fields, the placement of controls within the frame use the same fields. You then specify the id of the frame with the `cFrame` field, and then relative position within that frame.

The `title` field of a frame is not used.

You may supply the `CA_NoBorder` attribute to any frame, which will cause the frame to be drawn without a border. This can be used as a layout tool, and is especially useful to force buttons to line up in vertical columns.

See the section CommandObject for an example of defining a frame.

#### C_Icon

A display only icon. This works exactly the same as a `C_Label` except that an icon is displayed instead of text. You use `C_Icon` for the `cmdType` field, and provide a pointer to the `vIcon` object in the `itemList` field using a `(void*)` cast. You should also provide a meaningful label for the `title` field since some versions of V may not support icons.

You can't dynamically change the icon.

#### C_IconButton

A command button Icon. This works exactly the same as a `C_Button` except that an icon is displayed for the button instead of text. You use `C_IconButton` for the `cmdType` field, and provide a pointer to the `vIcon` object in the `itemList` field using a `(void*)` cast. You should also provide a meaningful label for the `title` field since some versions of V may not support icons.

You can't dynamically change the icon. The button will be sized to fit the icon. Note that the `v/icons` directory contains quite a few icons suitable for using on command bars.

#### C_Label

#### C_ColorLabel

This places a label in a dialog. A label is defined in a `CommandObject` array. This is a typical definition:

     {C_Label, lblId,0,"Select Options",NoList,CA_None,isSens,NoFrame,0,0, 0,0}

While the value of a label can be changed with `SetString(lblId,` `"New Label")`, they are usually static items. If the label is defined with the `CA_MainMsg` attribute, then that label position will be used to fill the the message provided to the `ShowDialog` method.

A `C_ColorLabel` is a label that uses the List parameter of the `CommandObject` array to specify a `vColor`. You can specify the color and change the color in the same fashion as described in the `C_ColorButton` command.

#### C_List

A list is a scrollable window of text items. The list can be made up of any number of items, but only a limited number are displayed in the list scroll box. The default will show eight items at a time. The number of rows can be controlled as explained later.

The user uses the scroll bar to show various parts of the list. Normally, when the user clicks on a list item, the `DialogCommand` is invoked with the id of the List command in the `Id` parameter, and the index into the list of the item selected in the `Val` parameter. This value may be less than zero, which means the user has unselected an item, and your code should properly handle this situation. This only means the user has selected the given item, but not that the selection is final. There usually must be a command Button such as OK to indicate final selection of the list item.

If the List is defined with the attribute `CA_NoNotify`, `DialogCommand` is not called with each pick. You must then use `GetValue` to get which item in the list was selected.

It is possible to preselect a given list item with the `SetValue` method. Use the `GetValue` to retrieve the selected item's index after the OK button is selected. A value less than zero means no item was selected.

The number of rows displayed can be controlled by using the `CommandObject` element `size`. By specifying the attribute `CA_Size` and providing a value for the `size` element, you can specify how many rows to show. If you don't specify a size, 8 rows will be displayed. Vwill support between 1 and 32 rows. Note the that the `size` element is the last one of a `CommandObject`, and can left out of a declaration, which results in the compiler generating a zero value, giving the default 8 rows.

The width in pixels (approximately) of the list can be controlled by specifying the `CA_ListWidth` attribute and providing a value to the `retVal` parameter, which is otherwise unused for a list object. This implementation isn't perfect - you may have to play with the interaction between the width you specify, and the font used in a list control.

Change the contents of the list with `vDialog::SetValue` using either `ChangeList` or `ChangeListPtr`. See `vDialog::SetValue` for more details.

The `vSList` class provides a very useful set of utilities for working with `C_List` lists.

### Example

The following is a simple example of using a list box in a modal dialog. This example does not process items as they are clicked. This list will be displayed in 12 rows.

    enum {lstId = 200 };
    char* testList[] =
      {
        "First 0",   // The first item in the list
         ...
        "Item N",    // The last item in the list
        0            // 0 terminates the list
      };
      ...
    CommandObject ListList[] =
      {
        {C_List, lstId, 0, "A List", (void*)testList,
           CA_NoNotify | CA_Size,isSens,NoFrame,0,0,12},
        {C_Button, M_OK, M_OK, " OK ", NoList,
           CA_DefaultButton, isSens, NoFrame, 0, lstId},
        {C_EndOfList,0,0,0,0,CA_None,0,0,0}
      };
        ...
        vModalDialog ld(this);    // create list dialog
        int lid, lval;
        ...
        ld.AddDialogCmds(ListList);   // Add commands to dialog
        ld.SetValue(lstId,8,Value);  // pre-select 8th item
        lid = ld.ShowModalDialog("",lval);  // Wait for OK
        lval = ld.GetValue(lstId);  // Retrieve the item selected

#### C_ProgressBar

Bar to show progress. Used with `CA_Vertical` or `CA_Horizontal` attributes to control orientation. You change the value of the progress bar with `SetValue(ProgID, val, Value)`, where `val` is a value between 0 and 100, inclusive. Normally, the progress bar will show both a graphical indication of the value, and a text indication of the value between 0 and 100.

If you don't want the text value (for example, your value represents something other than 0 to 100), then define the progress bar with the `CA_NoLabel` attribute. Use the `CA_Percent` attribute to have a % added to the displayed value. You can also use `CA_Small` or `CA_Large` to make the progress bar smaller or larger than normal. If you need a text value display for ranges other than 0 to 100, you can build a `CA_NoSpace` frame with a progress bar and a text label that you modify yourself.

### Example

The following shows how to define a progress bar, and how to set its value.

    enum{frm1 = 200, lbl1, pbrH, pbrV, ... };
      static CommandObject Cmds[] =
      {
        ...
        // Progress Bar in a frame
        {C_Frame, frm1, 0, "",NoList,CA_None,isSens,NoFrame, 0,0},
        {C_Label, lbl1, 0, "Progress",NoList,CA_None,isSens,frm1,0,0},
        {C_ProgressBar, pbrH, 50, "", NoList,
            CA_Horizontal,isSens,frm1, 0, lbl1},  // Horiz, with label

        {C_ProgressBar, pbrV, 50, "", NoList,  // Vertical, no value
          CA_Vertical | CA_Small, isSens,NoFrame, 0, frm1},
        ...
      };
      ...
      // Set the values of both bars to same
      SetValue(pbrH,retval,Value);    // The horizontal bar
      SetValue(pbrV,retval,Value);    // The vertical bar

#### C_RadioButton

Radio buttons are used to select one and only one item from a group. When the user clicks on one button of the group, the currently set button is turned off, and the new button is turned on. Note that for each radio button press, two events are generated. One a call to `DialogCommand` with the id of the button being turned off, and the other a call with the id of the button being turned on. The order of these two events is not guaranteed. The `retVal` field indicates the initial on or off state, and only one radio button in a group should be on.

Radio buttons are grouped by frame. You will typically put a group of radio buttons together in a frame. Any buttons not in a frame (in other words, those just in the dialog window) are grouped together.

Radio buttons are handled very much like check boxes. Your code should dynamically monitor the state of each radio button with the `DialogCommand` method. Selecting Cancel will automatically generate calls to `DialogCommand` to restore the each of the buttons to the original state.

You can use `SetValue` with a `Value` parameter to change the settings of the buttons at runtime. `SetValue` will enforce a single button on at a time.

### Example

The following example of defining and using radio buttons was extracted from the sample file `v/examp/mydialog.cpp`. It starts with the button `RB1` pushed.

    enum {
        frmV1 = 200, rdb1, rdb2, rdb3, ...
    ...
      };
    ...
    static CommandObject DefaultCmds[] =
      {
        {C_Frame, frmV1, 0,"Radios",NoList,CA_Vertical,isSens,NoFrame,0,0},
        {C_RadioButton, rdb1, 1, "KOB",  NoList,CA_None,isSens, fmV1,0,0},
        {C_RadioButton, rdb2, 0, "KOAT", NoList,CA_None, isSens,frmV1,0,0},
        {C_RadioButton, rdb3, 0, "KRQE", NoList,CA_None, isSens,frmV1,0,0},
        {C_Button, M_Cancel,M_Cancel,"Cancel",NoList,CA_None,
            isSens, NoFrame, 0, frmV1},
        {C_Button, M_OK, M_OK, " OK ", NoList, CA_DefaultButton,
            isSens, NoFrame, M_Cancel, frmV1},
        {C_EndOfList,0,0,0,0,CA_None,0,0,0}
      };
    ...
    void myDialog::DialogCommand(ItemVal Id, ItemVal Val, CmdType Ctype)
      {
        switch (Id)              // switch on command id
          {
            case rdb1:            // Radio Button KOB
                // do something useful - current state is in retval
                break;
            ...
            // cases for other radio buttons

          }
        // let the super class handle M_Cancel and M_OK
        vDialog::DialogCommand(id,retval,ctype);
      }

#### C_Slider

Used to enter a value with a slider handle. The slider will provide your program with a value between 0 and 100, inclusive. Your program can then scale that value to whatever it needs.

V will draw sliders in one of three sizes. Use `CA_Small` for a small slider (which may not be big enough to return all values between 0 and 100 on all platforms), `CA_Large` to get a larger than normal slider, and no attribute to get a standard size slider that will return all values between 0 and 100. Use the `CA_Vertical` and `CA_Horizontal` attributes to specify orientation of the slider.

When the user changes the value of the slider, the `DialogCommand` method is called with the id of the slider for the `Id` value, and the current value of the slider for the `Retval` value. You can use `SetVal` to set a value for the slider.

### Example

The following example shows the definition line of a slider, and a code fragment from an overridden `DialogCommand` method to get the value of the dialog and update a `C_Text` item with the current value of the slider. The slider starts with a value of 50.

    enum { frm1 = 80, sld1, txt1 };
    CommandObject Commands[] =
      {
        ...
        {C_Frame, frm1, 0, "",NoList,CA_None,isSens,NoFrame,0,0},
        {C_Slider, sld1, 50, "",NoList,CA_Horizontal,isSens,frm1,0,0},
        {C_Text, txt1, 0, "", "50",CA_None,isSens, frm1, sld1, 0},
        ...
      };
      ...
    void testDialog::DialogCommand(ItemVal id,
      ItemVal retval, CmdType ctype)
      {
        ...
        switch (id)     // Which dialog command item?
          {
            ...
            case sld1:    // The slider
              {
                char buff[20];
                sprintf(buff,"%d",retval);  // To string
                SetString(txt1,buff);      // Show value
              }
            ...
          }
        ...
      }

#### C_Spinner

This command item is used to provide an easy way for the user to enter a value from a list of possible values, or in a range of values. Depending on the attributes supplied to the `CommandObject` definition, the user will be able to select from a short list of text values, from a range of integers, or starting with some initial integer value. As the user presses either the up or down arrow, the value changes to the next permissible value. The `retVal` field specifies the initial value of the integer, or the index of the initial item of the text list. You use the `GetValue` method to retrieve the final value from the `C_Spinner`.

You can change the contents of the spinner list by using `vDialog::SetValue` with either `ChangeList` or `ChangeListPtr`. See `vDialog::SetValue` for more details.

The size of the spin value field in pixels can be controlled by using the `CommandObject` element `size`. By specifying the attribute `CA_Size` and providing a value for the `size` element, you can control the size of the value field . Note the that the `size` element is the last one of a `CommandObject`, and can left out of a declaration, which results in the compiler generating a zero value.

### Example

This example shows how to setup the `C_Spinner` to select a value from a text list (when supplied with a list and the `CA_Text` attribute), from a range of integers (when supplied a range list), or from a starting value (when no list is provided). The definitions of the rest of the dialog are not included.

      static char* spinList[] =    // a list of colors
        {
          "Red","Green","Blue", 0
        };
      static int minMaxStep[3] =  // specify range of
        {                         // -10 to 10
          -10, 10, 2              // in steps of 2
        };
      enum { spnColor = 300, spnMinMax, spnInt, ... };
      CommandObject SpinDialog[] =
        {
          ...
          {C_Spinner,spnColor,0,"Vbox", // A text list.
            (void*)spinList,CA_Text,     // the list is CA_Text
            isSens,NoFrame, 0,0},
          {C_Spinner,spnMinMax,0,"Vbox", // a range -10 to 10
            (void*)minMaxStep,CA_None,  // by 2's starting at 0
            isSens,NoFrame, 0,0},
          {C_Spinner,spnInt,32,"Vbox",  // int values step by 1
            NoList,CA_None,             // starting at 32
            isSens,NoFrame, 0,0},
          ...
        };

#### C_Text

This draws boxed text. It is intended for displaying information that might be changed, unlike a label, which is usually constant. The text may be multi-line by using a `'\n``. The `retVal` and `title` fields are not used. The text to display is passed in the `itemList` field.

You can use the `CA_NoBorder` attribute to suppress the border.

A definition of a `C_Text` item in a `CommandObject` definition would look like:

     {C_Text, txtId, 0, "", "This is an example\nof a two line text.",
              CA_None,isSens,NoFrame, 0, 0, 0,0},

You can change the label of text box with: `SetString(txtId,` `"New text` `to show.")`.

#### C_TextIn

This command is used for text entry from the user. The text input command item will typically be boxed field that the user can use to enter text.

The strategy for using a TextIn command item is similar to the List command item. You need an OK button, and then retrieve the text after the dialog has been closed.

You can provide a default string in the `title` field which will be displayed in the TextIn field. The user will be able to edit the default string. Use an empty string to get a blank text entry field. The `retVal` field is not used.

There are two ways to control the size of the TextIn control. If you specify `CA_None`, you will get a TextIn useful form most simple input commands. Using `CA_Large` gets a wider TextIn, while `CA_Small` gets a smaller TextIn. You can also use the `size` field of the `CommandObject` to explicitly specify a width in characters. When you specify a size, that number of characters will fit in the TextIn, but the control does not enforce that size as a limit.

If you specify the attribute `CA_Password`, then the user's input will either be echoed as asterisks (MS-Windows), or not echoed (X).

If you specify the attribute `CA_TextInNotify`, then the `DialogCommand` method for the dialog or tool bar will be called with the ID of the TextIn, and a value of either `M_TextInChange` or `M_TextInLeaveFocus` whenever the contents of the TextIn changes, or when the TextIn control loses focus. This capability is useful for validating the value in a TextIn.

### Example

The following example demonstrates how to use a TextIn.

    CommandObject textInList[] =
      {
        ...
        {C_TextIn, txiId,0,"",NoList,CA_None,isSens,NoFrame,0,0},
        ...
        {C_EndOfList,0,0,0,0,CA_None,0,0,0}
      };
     ...
        vModalDialog md(this);      /// make a dialog
        int ans, val;
        char text_buff[255];        // get text back to this buffer
     ...
        md.AddDialogCmds(textInList);  // add commands
        ans = md.ShowModalDialog("Enter text.", val);  // Show it
        text_buff[0] = 0;          // make an empty string
        (void) md.GetTextIn(txiId, text_buff, 254); // get the string
     ...

#### C_ToggleButton

A `C_ToggleButton` is a combination of a button and a checkbox. When the toggle button is pressed, the `vCmdWindow::WindowCommand` method is called, just as with a regular command button. However, the system will change the look of the toggle button to indicate it has been pressed. Each click on a `C_ToggleButton` will cause the button to appear pressed in or pressed out.

The `retVal` field of the `CommandObject` definition is used to indicate the initial state of the toggle.

The behavior of a toggle button is like a check box, and not a radio button. This is more flexible, but if you need exclusive radio button like selection, you will have to enforce it yourself using `SetValue(toggleId,val,Value)`.

     // Define a toggle button with id tbtToggle and
     // an initial state of 1, which means pressed in
     {C_ToggleButton,tbtToggle, 1,"", NoList,CA_None,
         isSens, NoFrame, 0, 0},
     ...

     // The case in WindowCommand should be like this:

        case tbtToggle:
          {
    	// Always safest to retrieve current value
            ItemVal curval = GetValue(tbtToggle);
            // Now, do whatever you need to
            if (curval)
               ... it is pressed
            else
               ... it is not pressed
            break;
          }

#### C_ToggleFrame

A `C_ToggleFrame` is V's answer to the Windows Tab control. While Vdoesn't have real Tab controls, using a combination of `C_ToggleFrames` and either radio buttons or toggle buttons, you can design very nice multi-frame dialogs.

A Toggle Frame works just like a regular `C_Frame` except that you can use `SetValue` with a type `Value` to hide or make visible all controls contained or nested in the toggle frame. (Note: setting the `Value` of a toggle frame is not the same as setting its `Hidden` attribute.)

The strategy for using toggle frames follows. First, you will usually use two or more toggle frames together. In the dialog `CommandObject` definition, you first define one radio button or one toggle button for each toggle frame used in the dialog. You then define a regular bordered `C_Frame` positioned below the radio/toggle buttons. Then place `CA_NoBorder` toggle frames inside that outer frame. The outer frame will be the border for all the toggle frames. Inside each toggle frame, you define controls in the normal way.

You must select just one of the toggle frames to be initially visible. This will correspond to the checked radio button or pressed toggle button. The remaining toggle frames and their controls should all be defined using the `CA_Hidden` attribute.

You then hide and unhide toggle frames by responding to the `vDialog::DialogCommand` messages generated when a radio button or toggle button is pressed. You `SetValue(togID, 1, Value)` to show a toggle pane and all its controls, and `SetValue(togID, 0, Value)` to hide all its controls.

The following example shows how to define and control toggle frames:

        enum {lbl1 = 400, tbt1, tbt2, tbt3, frm1, tfr1, tfr2,
              btnA1, btnB1, btnA2, btnB2 };
        static CommandObject DefaultCmds[] =
          {
            // A label, then 2 toggle buttons to select toggle frames
            {C_Label,lbl1,0,"Tab Frame Demo",NoList,CA_None,isSens,
                     NoFrame,0,0},
            {C_ToggleButton,tbt1,1,"Tab 1",NoList, CA_None, isSens,
                     lbl1, 0, 0},
            {C_ToggleButton,tbt2,0,"Tab 2",NoList, CA_None, isSens,
                     lbl1, tbt, 0},
            {C_ToggleButton,tbt3,0,"Tab 3",NoList, CA_None, isSens,
                     lbl1, tbt2 0},

            // A Master frame to give uniform border to toggle frames
            {C_Frame,frm1,0, "", NoList,CA_None,isSens,lbl1,0,tbt1},

            // Toggle Frame 1 - default frame on
            {C_ToggleFrame, tfr1,1,"",NoList, CA_NoBorder,isSens,frm1,0,0},
            {C_Button,btnA1,0,"Button A(1)",NoList,CA_None,isSens,tfr1,0,0},
            {C_Button,btnB1,0,"Button B(1)",NoList,CA_None,isSens,tfr1,
                      0,btnA1},

            // Toggle Frame 2 - default off (CA_Hidden!)
            {C_ToggleFrame,tfr2,0,"",NoList,CA_NoBorder | CA_Hidden,
                    isSens,frm1,0,0},
            {C_Button,btnA2,0,"Button A(2)",NoList,CA_Hidden,isSens,tfr2,0,0},
            {C_Button,btnB2,0,"Button B(2)",NoList,CA_Hidden,isSens,tfr2,
                      btnA2,0},

            {C_EndOfList,0,0,0,0,CA_None,0,0,0}
          };

        ...

        // In the DialogCommand method:

        switch (id)         // We will do some things depending on value
          {
            case tbt1:       // For toggle buttons, assume toggle to ON
              {
                SetValue(id,1,Value);     // turn on toggle button
                SetValue(tbt2,0,Value);    // other one off
                SetValue(tfr2,0,Value);    // Toggle other frame off
                SetValue(tfr1,1,Value);    // and ours on
                break;
              }

            case tbt2:       // Toggle 2
              {
                SetValue(id,1,Value);     // turn on toggle button
                SetValue(tbt1,0,Value);    // other off
                SetValue(tfr1,0,Value);    // Toggle other off
    	    SetValue(tfr2,1,Value);    // and ours on
                break;
              }

          }
        // All commands should also route through the parent handler
        vDialog::DialogCommand(id,retval,ctype);
      }

#### C_ToggleIconButton

A `C_ToggleIconButton` is a combination of an icon button and a checkbox. When the toggle icon button is pressed, the `vCmdWindow::WindowCommand` method is called, just as with a regular icon button. However, the system will change the look of the toggle icon button to indicate it has been pressed. This is useful for good looking icon based interfaces to indicate to a user that some option has been selected. An additional press will change the appearance back to a normal icon button. The `retVal` field of the `CommandObject` definition is used to indicate the initial state of the toggle.

The behavior of a toggle icon button is like a check box, and not a radio button. This is more flexible, but if you need exclusive radio button like selection, you will have to enforce it yourself using `SetValue(toggleId,val,Value)`.

     // Define a toggle icon button with id tibToggle and
     // an initial state of 1, which means pressed
     {C_ToggleIconButton,tibToggle, 1,"", &anIcon,CA_None,
         isSens, NoFrame, 0, 0},
     ...

     // The case in WindowCommand should be like this:

        case tibToggle:
          {
            // Always safest to retrieve current value
            ItemVal curval = GetValue(tibToggle);
            // Now, do whatever you need to
            if (curval)
               ... it is pressed
            else
               ... it is not pressed
            break;
          }

# CmdAttribute

These attributes are used when defining command items. They are used to modify default behavior. These attributes are bit values, and some can be combined with an OR operation. Note that not all attributes can be used with all commands.

## Attributes

`CA_DefaultButton` | Used with a `C_Button` to indicate that this button will be the default button. The user can activate the default button by pressing the Enter key as well as using the mouse. It will most often be associated with the OK button.
`CA_Hidden` | Sometimes you may find it useful to have a command object that is not displayed at first. By using the `CA_Hidden` attribute, the command object will not be displayed. The space it will require in the dialog or dialog pane will still be allocated, but the command will not be displayed. You can then unhide (or hide) the command using the `SetValue` method: `SetValue(CmdID, TrueOrFalse, Hidden)` .
`CA_Horizontal` | Command will have horizontal orientation. This attribute is used with Sliders and Progress Bars.
`CA_Large` | The object should be larger than usual. It can be used with Lists, Progress Bars, Sliders, Text Ins, and Value Boxes.
`CA_MainMsg` | Used with a `C_Label` to indicate that its string will be replaced with the message supplied to the `ShowDialog` method.
`CA_NoBorder` | `CA_NoBorder` specifies that the object is to be displayed with no border.
`CA_NoLabel` | Used for progress bars to suppress display of the value label.
`CA_NoNotify` | Used for combo boxes and lists. When specified, the program will not be notified for each selection of a combo box item or a list item. When specified, the program is notified only when the combo box button is pressed, and must then use `GetValue` to retrieve the item selected in the combo box list. For lists, you will need another command button in the dialog to indicate list selection is done.
`CA_NoSpace` | Used for frames, this attribute causes the command objects within the frame to be spaced together as tightly as possible. Normally, command objects have a space of several pixels between them when laid out in a dialog. The CA_NoSpace attribute is especially useful for producing a tightly spaced set of command buttons.
`CA_None` | No special attributes. Used as a symbolic filler when defining items, and is really zero.
`CA_Percent` | Used with progress bars to add a % to the value label.
`CA_Size` | The `size` element of the `CommandObject` is being used to specify a size for the control. This is used with buttons, spin controls, and lists.
`CA_Small` | The object should be smaller than usual. It can be used with Progress Bars and Text Ins. On Progress Bars, `CA_Small` means that the text value box will not be shown.
`CA_Text` | Used for Spinners to specify that a text list of possible values has been supplied.
`CA_TextInNotify` | Used for Text Ins. When used, the DialogCommand method will be called with the id of the TextIn, and an attribute of either M_TextInChange or M_TextInLeaveFocus . This allows your program to validate TextIn input values.
`CA_Vertical` | Command will have vertical orientation. This attribute is used with Sliders and Progress Bars.

# Predefined ItemVals

A useful collection of predefined values. Most are useful for defining dialogs, buttons, and menus.

When defining dialogs, menus, and command bars, you are required to provide an id for each item. There are many common operations used in GUI designs, and V provides various predefined values for building your programs. The natural interpretation of most of these values should be obvious, and the descriptions are kept to a minimum. Most of the definitions describe the accepted practice for menu or button items with the given title. While these `ItemVal`s can be used anywhere, some have ``standard'' usage.

## Control Values

M_About | Shows an informative message about current application.
M_All | Select all.
M_Cancel | Cancel. Usually used with a dialog. V will automatically reset dialog commands to their original state when a `M_Cancel` is selected from a `vDialog` descended object.
M_Clear | Used to clear a screen.
M_Close | Used to close a file. The user is usually prompted to save or ignore changes if any were made to the file. This is usually not used to close a menu.
M_Copy | Copy the highlighted text or item, and save into the clipboard.
M_Cut | Cut the highlighted text or item from the file, and usually save into the clipboard.
M_Delete | Delete the selected item or text - usually does not copy into the clipboard.
M_Done | Done with operation.
M_Edit | Typically a menu bar button to pulldown an edit menu.
M_Exit | Exit from the program - checking to see if files need to be saved, of course.
M_File | Typically a menu bar button to pulldown a file menu.
M_Find | Find a pattern.
M_FindAgain | Find pattern again.
M_Font | Typically a menu bar button to pulldown a font menu.
M_FontSelect | Select a font. (This is different from the M_Font value in that M_Font is intended as a main menu bar item, while this one is for a pulldown menu.
M_Format | Typically a menu bar button to pulldown a format menu, which allows the user to select formatting options.
M_Help | Show help.
M_Insert | Typically a menu bar button to pulldown an insert menu.
M_Line | M_Line is one of a few of these values that gets special treatment by the system. It is required for defining line separators in menus.
M_New | Used to create a new file.
M_No | Answer No.
M_None | Select none.
M_OK | OK, accept operation or information. Causes return from dialog.
M_Open | Used to open an existing file.
M_Options | Typically a menu bar button to pulldown an options menu.
M_Paste | Paste the contents of the clipboard into the insertion point of the current file or item.
M_Preferences | Set preferences.
M_Print | Print current file.
M_PrintPreview | On screen preview how the current file would look if printed.
M_Replace | Replace pattern.
M_Save | Used to save current file in its current name.
M_SaveAs | Save current file under new name.
M_Search | Typically a menu bar button to pulldown a search menu.
M_SetDebug | Set debug stuff.
M_Test | Typically a menu bar button to pulldown a test menu.
M_Tools | Typically a menu bar button to pulldown a tools menu.
M_UnDo | Undo the last action.
M_View | Typically a menu bar button to pulldown a view menu, which allows the user to select different views of the document.
M_Window | Typically a menu bar button to pulldown a window menu, which lets the user select different windows.
M_Yes | Answer Yes.

## See Also

vCmdWindow, vDialog, vCommandPanes

## Footnotes:

1 This is necessary keep things as `chars` and still allow a possible 256 entries, since 256 is 28+1, and a color map with 0 entries doesn't make sense.