Tag Archives: Controls

The VALUES and VALUE properties

When working with ListBox and ComboBox controls it can sometimes be a chore to derive an “internal” value from list of visible items.  In many cases this involves creating an associated array of internal values, storing them in the MISC property (or a custom “@” property), and then extracting this array and the SELPOS property at runtime to arrive at the required data.

For example:

// Set up a LIST and internal items
colorNames = "Red"    : @fm : "Green"  : @fm : "Blue"
colorVals  = 0x0000FF : @fm : 0x00FF00 : @fm : 0xFF0000

call set_Property_Only( @window : ".LIST_1", "LIST", colorNames )
call set_Property_Only( @window : ".LIST_1", "MISC", colorVals )

... 

// Then at runtime to access the currently selected internal value
colorVals = get_Property( @window : ".LIST_1", "MISC" )
selPos    = get_Property( @window : ".LIST_1", "SELPOS" )

colorVal  = colorVals<selPos>

...

// Or even more long-winded, find an internal value from the external one:
colorNames = get_Property( @window : ".LIST_1", "LIST" )
colorVals  = get_Property( @window : ".LIST_1", "MISC" )

locate "Green" in colorNames using @fm setting pos then
   greenVal = colorVals<pos>
end

...

// or perhaps setting the currently selected item from an internal code:
colorNames = get_Property( @window : ".LIST_1", "LIST" )
colorVals  = get_Property( @window : ".LIST_1", "MISC" )

locate 0x00FF00 in colorVals using @fm setting pos then
   greenName = colorNames<pos>
   call set_Property_Only( @window : ".LIST_1", "TEXT", greenName )
end

To make this style of coding somewhat cleaner, OpenInsight 10 introduces the new VALUES property, which allows you to set an “internal” value for each item in the control, along with property indexing support.  There is also a new VALUE property, which is the counterpart to the standard TEXT property, and provides access to the currently selected item via it’s internal value.

Here’s the above examples rewritten to use VALUES and VALUE instead:

// Set up a LIST and internal items
colorNames = "Red"    : @fm : "Green"  : @fm : "Blue"
colorVals  = 0x0000FF : @fm : 0x00FF00 : @fm : 0xFF0000

call set_Property_Only( @window : ".LIST_1", "LIST", colorNames )
call set_Property_Only( @window : ".LIST_1", "VALUES", colorVals )

... 

// Then at runtime to access the currently selected internal value
colorVal = get_Property( @window : ".LIST_1", "VALUE" )
...

// Find an internal value from the external one:
greenVal = get_Property( @window : ".LIST_1", "VALUES", "Green" )

// or by position
greenVal = get_Property( @window : ".LIST_1", "VALUES", 2 )

...

// or perhaps setting the currently selected item from an internal code:
call set_Property_Only( @window : ".LIST_1", "VALUE", 0x00FF00 )

VALUES and VALUE apply to both ListBox and ComboBox controls.

(Disclaimer: This article is based on preliminary information and may be subject to change in the final release version of OpenInsight 10).

Sorting in EditTables

In previous versions of OpenInsight, EditTable sorting has been implemented by the SORTEDCOL property, which simply performs a Quicksort on a single column and then only on the visible text contained in each cell.  This latter trait is particularly sub-optimal because it pays no attention to the actual type of data represented in the cell itself; for example, if you wish to sort on a column containing dates, you usually have to write code to convert the data to a numeric format first, and then pass the results onto the V119 sort function, all of which gets tedious very quickly.

In OpenInsight 10 the SORTEDCOL property has been deprecated and has been replaced by the new SORT method detailed below:

The SORT method

This method allows you to perform a multi-column sort on an EditTable, along with the ability to convert the data to an appropriate format before the sort takes place.

Call Exec_Method( CtrlEntID, "SORT", SortCriteria, SortOptions )

The method takes two parameters.  The first, SortCriteria, which is a dynamic array structured as follows:

<0,1> @svm'd list of column numbers to sort by
<0,2> @svm'd list of sorting directions/justifications for each column 
      passed in field <0,1>.  Available values are:

         0 - Descending Left
         1 - Ascending Left
         2 - Descending Right
         3 - Ascending Right

<0,3> @svm'd list of ICONV patterns used to convert the column data to its
      internal format before the sort takes place.

The default ICONV pattern used for sorting a column is taken from it’s VALID property.  This means that you can flag a column as a date (e.g. “DE”) in the Form Designer, and have it sort properly in a numeric fashion without any extra coding needed.

The second parameter, SortOptions, is a dynamic array structured as follows:

<1> If TRUE$ then perform a trim operation before the sort takes place, or
    FALSE$ to prevent the trim. If this field is null then the SORTTRIM 
    property is used to decide if a trim operation takes place.

(A trim operation is the removal of “blank” rows from the EditTable control.  A description of trim functionality will appear in a future post).

Using the SORT method triggers a new event called SORTED:

The SORTED event

This event takes the same parameters as passed to the SORT method described above.  This event is fired before any sorting takes place, thereby giving you the chance to modify the criteria or options, or even prevent it by using the Set_EventStatus() function.  All event script and QuickEvent handlers are processed before sorting.

The COLHEADERSORTINGMODE property

This is another new property for EditTable controls and can be set to one of the following values:

  • 0 (Disabled – this is the default value)
  • 1 (Sort on single-click)
  • 2 (Sort double-click)

When set to to 1 or 2, clicking or double-clicking on a column header will automatically sort the contents of the control by that column, in a similar manner to Popup entity sorting.  The SORTED event is still raised in the manner described above however, so you may still intercept and modify the process if you wish.

The SORTTRIM property

When set to TRUE a sort operation automatically performs a trim operation before sorting.  This property can be overridden by passing a flag in the SORT method SortOptions parameter described above.

We hope these improvements make sorting in EditTables a little less onerous.

 

[EDIT: 27 Sep 15, Updated for SortOptions argument and SORTTRIM property]

[EDIT: 17 Nov 15, Updated for COLHEADERSORTINGMODE property]

(Disclaimer: This article is based on preliminary information and may be subject to change in the final release version of OpenInsight 10).

 

 

 

 

 

Size and Position

In previous versions of OpenInsight the position of a Window or control has always been determined by its SIZE property – an @fm-delimited array comprised of the Left, Top, Width and Height values.  This means, of course, that all of these values have to be processed together at the same time.

For example, if you only want to update a control’s Top attribute then you first have to get the current SIZE property, update the second field, and then set the entire array again like so:

ctrlSize    = get_Property( ctrlID, "SIZE" )
ctrlSize<2> = 100
call set_Property_Only( ctrlID, "SIZE", ctrlSize )

This can become tedious to write and it is also inefficient.

For version 10 we’ve exposed each of the SIZE fields as separate properties so you can now access them directly.  The new properties are:

  • LEFT
  • TOP
  • WIDTH
  • HEIGHT

Here’s the previous example updated to use the TOP property:

call set_Property_Only( ctrlID, "TOP", 100 )

Positioning using rectangle (RECT) coordinates

Those of you used to working with the Windows API will know that many API functions don’t use Width and Height values when dealing with positioning: they work with a “RECT” structure that uses Left, Top, Right and Bottom values to define an object’s position instead (i.e. the coordinates of the top-left corner and the bottom-right corner).

In some cases being able to update a position using Right and Bottom instead of Width and Height can actually be more efficient because it can mean less calculations needed in your own code, and so a new RECT property has been added to enable this functionality.

The new RECT property works in exactly the same way as the current SIZE property except that the Width and Height fields have been replaced by the Right and Bottom fields like so:

* // RECT property structure
* // 
* //   <1> Left
* //   <2> Top
* //   <3> Right
* //   <4> Bottom

As with the SIZE property we’ve also exposed the  individual fields as separate properties so there are two new properties to complement RECT which are:

  • RIGHT
  • BOTTOM

 

 SIZE, RECT and “stealth mode”

As you may know, when using the SIZE property with the Set_Property function you can set a “visible” attribute in the 5th field that can control the visibility of the object when it is moved. For example, setting the SIZE of an invisible WINDOW makes it visible by default unless you set this visible flag to “-1”.  This is still the case in version 10 and it also applies to the new RECT property as well.

However, we have also added a new 6th field that can contain a “Suppress Change Notification” flag.  When this flag is set to TRUE$ the object that has been moved receives no internal notification from Windows that it has been updated, so this will stop any MOVE and SIZE events from begin raised as well as preventing any autosize processing.  This is sometimes necessary when you have complex positioning requirements.

* // Full SIZE property structure when used with Set_Property
* // 
* //   <1> Left
* //   <2> Top
* //   <3> Width
* //   <4> Height
* //   <5> Visibility
* //   <6> Suppress Change Notification
* // Full RECT property structure when used with Set_Property
* // 
* //   <1> Left
* //   <2> Top
* //   <3> Right
* //   <4> Bottom
* //   <5> Visibility
* //   <6> Suppress Change Notification

(Disclaimer: This article is based on preliminary information and may be subject to change in the final release version of OpenInsight 10).

A last word on EditLines (for now)

We’ve taken a look over the last few posts at some of the new features we’ve added to EditLine controls, but before we leave them we’ll mention a few miscellaneous new properties that you might find useful:

  • AUTOSELECT
  • CUEBANNER
  • EXITCHARS
  • VALIDCHARS

 

AUTOSELECT Property

This is a simple boolean property.  When set to TRUE all text in the control will be selected when the EditLine is given focus.

CUEBANNER Property

This is a string property that contains the text to display when an EditLine has no data.  The text is normally displayed in a faded style to differentiate it from “real” text.  It is intended primarily to give the user a simple hint on the purpose of the EditLine, or on the format of the data it should contain.

EXITCHARS property

This property allows you to specify one or more characters as “Exit” characters, which means that if a user types any of them into the control the focus is automatically moved to the next control in tab-order as though they had hit the Tab key. This property is a simple string containing the Exit characters.

// Move to the next control if the user enters a "." or a space
exitChars = ". "
call set_Property( @window : ".EDL_IP1", "EXITCHARS", exitChars )

Note this property does not work if the PASSWORDSTYLE property is TRUE.

VALIDCHARS Property

This property allows you to specify one or more characters that are “Valid” characters, which means that the user can only enter these characters into the control. This property is a simple string containing the characters that are allowed.

// Only allow numeric characters in EDL_NUMBER
validChars = "0123456789"
call set_Property( @window : ".EDL_NUMBER", "VALIDCHARS", validChars )

Note this property does not work if the EDITMASK property is set or the PASSWORDSTYLE property is TRUE.

 

(Disclaimer: This article is based on preliminary information and may be subject to change in the final release version of OpenInsight 10).

 

Edit controls and the Image API

In a previous post we mentioned that the EditLine control now supports the Glyph API, we’ve also extended the Image API to both EditLines and EditBoxes, along with gradient background colors and translucency.  Here are a few examples showing the results:

Gradient BACKCOLOR

EDIT Control with Gradient BACKCOLOR

EDIT Control with Gradient BACKCOLOR

TRANSLUCENCY Property

EDIT Control with TRANSLUCENCY of 50

EDIT Control with TRANSLUCENCY of 50

IMAGE Property

EDIT Control with background image

EDIT Control with background image

IMAGETRANSLUCENCY Property

EDIT Control with translucent background image

EDIT Control with translucent background image

 

(Disclaimer: This article is based on preliminary information and may be subject to change in the final release version of OpenInsight 10).

EditLines and the Glyph API

As you know some controls in OpenInsight support a set of properties called the Glyph API, and this has now been extended to EditLine controls as well.  Of course it’s not the full API (see the supported properties below), as that wouldn’t make sense, but it does allow you to insert an image to the left or right of your text:

EditLine GLYPH

EditLine GLYPH with CueBanner

So now you can insert a handy search icon into your control, or perhaps a warning icon if the data in the control is invalid.

The following Glyph API properties are supported for EditLines:

  • GLYPH (similar to the BITMAP or IMAGE property)
  • GLYPHALIGN (Vertical and center settings are ignored)
  • GLYPHCOLORKEY
  • GLYPHCOUNT
  • GLYPHFRAMECOUNT
  • GLYPHFRAMENUMBER
  • GLYPHOFFSET
  • GLYPHORIGIN
  • GLYPHSIZE
  • GLYPHTRANSLUCENCY

 

(Disclaimer: This article is based on preliminary information and may be subject to change in the final release version of OpenInsight 10).

EditLines and EditMasks

The ability to apply VALID and CONV properties to an EditLine control is a very powerful way to validate and format data entered in your applications, but this commonly relies on the user knowing how the data should be input without any visual clues being provided by the UI. Some formats like dates are fairly obvious, but others are not, and this can lead to user frustration when they are presented with a message box containing some cryptic and obscure error text from the depths of a custom Iconv() routine like this:

Cryptic IConv Message

Cryptic IConv Message

In order to improve this situation the EditLine control now supports a new property called EDITMASK, which allows you to specify the input format of the data in a visual manner, along with the type of character that may be entered at each character position, thus reducing the probability of typing errors and thereby leading to a smoother user experience.  For example here are two EditLine controls with an EDITMASK set for a phone number and a date respectively:

EDITMASK example

EDITMASK Phone and Date example

EDITMASK Property

This property is a dynamic array composed of three fields:

<1> The Input Mask
<2> The Format Mask
<3> The Default Character

The Input Mask is what the user sees in the control when no data has been entered.  The characters that they may edit are denoted by the “_” character, which is used as a placeholder. So, for a date the input mask could be “__/__/____”, meaning that they are allowed to edit the first two characters, the fourth and fifth character, and the last four characters. They will not be able to change either of the “\” characters.

The Format Mask controls the type of character that may be entered at each position where there is a placeholder “_” in the Input Mask. There should be one type specifier for each “_” character in the Input Mask, and a space character for the non-editable characters. The type specifiers are:

  • “D” – A digit
  • “d” – A digit or a space
  • “C” – An alpha character
  • “c” – An alpha character or space
  • “A” – an alphanumeric character
  • “a” – an alphanumeric character or space
  • “X” – a hexadecimal character
  • “x” – a hexadecimal character or space
  • “*” – any printable character
  • “+” – a “+” character, a “-” character, or space

So, for our date example we could have “dd dd dddd”. Note that the Format Mask must always be the same length as the Input Mask, otherwise the EDITMASK property will not work.

The Default Character is the character used for each invalid character in the user input. This defaults to an underscore (“_”).

To create the phone and date examples shown above you would set the following EDITMASK properties like so:

phoneMask =       " ddd ddd dddd"    |
          : @fm : "(___) ___-____"   |
          : @fm : "_"

dateMask  =       "Dd Dd dddd"        |
          : @fm : "__/__/____"        |
          : @fm : "_"

objxArray =        @window : ".EDL_PHONE"
propArray =        "EDITMASK"
dataArray =        phoneMask

objxArray := @rm : @window : ".EDL_DATE"
propArray := @rm : "EDITMASK"
dataArray := @rm : dateMask

call set_Property( objxArray, propArray, dataArray )

There are also some other supporting properties that can be used with the EDITMASK property:

  • GETMASKEDCHARSONLY
  • SETMASKEDCHARSONLY
  • MASKEDTEXT

GETMASKEDCHARSONLY property

This is a boolean property that affects how the TEXT property works when an EDITMASK property is applied.  When set to TRUE getting the TEXT property only returns the characters that can be entered by the user, ignoring any of the non-placeholder characters in the Format Mask.  By default this property is FALSE.

SETMASKEDCHARSONLY property

This is a boolean property that affects how the TEXT property works when an EDITMASK property is applied.  When set to TRUE setting the TEXT property only updates the characters that can be entered by the user, ignoring any of the non-placeholder characters in the Format Mask.  By default this property is FALSE.

MASKEDTEXT property

This property is essentially a wrapper around the normal TEXT property, behaves as if both GETMASKEDCHARSONLY and SETMASKEDCHARSONLY were set to TRUE, so in effect it is a “shorthand” way of accessing and updating the text that can be edited.

In the example below the EditLines on the right contain the MASKEDTEXT property of the EditLines on the left:

MASKEDTEXT example

MASKEDTEXT example

(EDIT: 21 Aug 15 – Corrected EDITMASK member positions)

(Disclaimer: This article is based on preliminary information and may be subject to change in the final release version of OpenInsight 10).