Tag Archives: Controls

The EDITSTATECHANGED event

One of the requirements we needed when developing the new IDE was the ability to detect when the state of a control changed in such a fashion that might affect the operations that could be performed on it.

A classic example of this is highlighting text in an edit control so that it can be cut or copied, or perhaps replaced with a paste operation: At this point an item like a Cut or a Paste button might need enabling so the UI is in sync with the state of the control.

To enable this functionality several controls now support a new event called EDITSTATECHANGED, which is fired when the “edit state” is changed.  The edit state is defined as one of the following operations:

  • Undo
  • Redo
  • Cut
  • Copy
  • Paste
  • Select All

So, if a user takes an action in the control that enables or disables one of these options you can respond to it via the EDITSTATECHANGED event.

The EDITSTATECHANGED event passes a single parameter called “NewEditState“, which is a dynamic array of Boolean flags with the following structure:

<1> CanUndo      : TRUE$ if the control allows an UNDO operation
<2> CanRedo      : TRUE$ if the control allows a REDO operation
<3> CanCut       : TRUE$ if the control allows a CUT operation
<4> CanCopy      : TRUE$ if the control allows a COPY operation
<5> CanPaste     : TRUE$ if the control allows a PASTE operation
<6> CanSelectAll : TRUE$ if the control allows a SELECTALL 
                 : operation

(You may notice that these flags closely follow the items in a standard “Edit” menu).

Here’s a simple example to set the state of some Cut/Copy/Paste buttons:

   objxArray =        @window : ".BTN_CUT"
   propArray =        "ENABLED"
   dataArray =        newEditState<3>

   objxArray := @rm : @window : ".BTN_COPY"
   propArray := @rm : "ENABLED"
   dataArray := @rm : newEditState<4>
   
   objxArray := @rm : @window : ".BTN_PASTE"
   propArray := @rm : "ENABLED"
   dataArray := @rm : newEditState<5>

   call Set_Property_Only( objxArray, propArray, dataArray )

The following controls support the EDITSTATECHANGED event:

  • COMBOBOX
  • EDITLINE
  • EDITBOX
  • EDITTABLE
  • LISTBOX
  • PROPERTYGRID

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

 

The FILEPREVIEW control

One of the new controls added to version 10 is the FILEPREVIEW control, which taps into the Windows Shell interface to expose the same  functionality provided by the Windows Explorer when previewing the contents of files, as per the example below:

explorer_preview

Windows Explorer PowerPoint preview

Using the FILEPREVIEW control is quite easy – simply set the FILENAME property with the name and path of the file you want to preview, and if the OS has handlers installed for that file type then the control will render them.

Here’s an example of previewing a PowerPoint file:

  fileName = get_Property( @window : ".EDL_FILENAME", "TEXT" )
  if bLen( fileName ) then
     call set_Property_Only( @window : ".FPV_VIEWER", "FILENAME", |
                             fileName )
  end
filepreview

FILEPREVIEW control example

The devil of course is in the details – your OS must have the correct handler DLLs installed for you to view the preview of the file, and this may rely on third party software being installed as well.  For example, to preview Word and Excel documents you must have Office installed, to preview PDF files you must have something like Adobe Reader installed and so on.  You can test for this at runtime by using the PREVIEWHANDLER method, which returns a GUID identifying the preview handler DLL if it is installed.  You simply pass the extension you wish to look up and check for a returned GUID like so:

  handlerGUID = exec_Method( previewCtrl, "PREVIEWHANDLER", "pdf" )
  if bLen( handlerGUID ) then
    // We have a PDF preview viewer on the workstation ...
    call set_Property_Only( previewCtrl, "FILENAME", "c:\temp\test.pdf" )
  end 

The control also supports an ACTIVE property which returns TRUE$ if the control currently has a file loaded for previewing.

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

 

 

The AUTODROPDOWN property

One of the areas in which dropdown comboboxes have always been lacking is the ability to fully control when the list is populated in a visually pleasing manner.  Under most circumstances the contents are loaded well before the dropdown button is clicked, and this is fine, but in situations where the items are context -sensitive it is necessary to load them just before the list is shown, and in previous versions this can look a little messy.

You can see an example of this in the OI9 System Editor++: there is a very handy pair of dropdowns at the top if the form that allow you to navigate your source code using inserts and labels, but when you use them you see the list contents loaded just after it has been dropped; this looks somewhat jarring and usually causes issues with the vertical scrollbar too.

Of course, the reason for this is that OpenInsight events are normally fired in an asynchronous manner, and the DROPDOWN event won’t run until after the list has been shown.  While you do have the ability to fire events in a synchronous fashion, this can introduce other complications and is something that should be avoided whenever possible.

So, in order to fix this, OpenInsight 10 provides a new property called AUTODROPDOWN that allows the list to be loaded during the DROPDOWN event and then displayed precisely when needed.

AUTODROPDOWN is a boolean property and is set to TRUE$ by default.

  • When set to TRUE$ the combobox behaves in exactly the same way as previous versions.
  • When set to FALSE$, the list is not shown until you explicitly set the DROPDOWN property to TRUE$. This gives you ability to load the list contents and then show them when ready.

Here’s an example of loading a list of STPROC repository items in a DROPDOWN event when AUTODROPDOWN is FALSE$

  // Get a list of items
  reposIDs = get_Repos_Entities( "", "STPROC", "", FALSE$, |
                                 TRUE$, FALSE$, "" )
  
  // Load them into the combobox LIST property
  call set_Property_Only( ctrlEntID, "LIST", reposIDs )

  // Now show the list
  call set_Property_Only( ctrlEntID, "DROPDOWN", TRUE$ )

Comboboxes as options buttons?

Another area where AUTODROPDOWN may help is for systems that use comboboxes as a combined edit and options control, where clicking the dropdown button loads a dialog box or popup instead of dropping a list.  Again, in previous versions this tends to look a little crude because the combobox shows a very shallow list even though it is empty, but with AUTODROPDOWN set to FALSE$ the list is never shown, and consequently looks much better.

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

Listboxes and ToolTips

Following on from our previous post on the new TOOLTIP property, this time we’re going to look at the new tooltip functionality added to Listbox controls, namely tracking and in-place item tooltips.

Tracking tooltips are small popup windows that appear when a user hovers over a partially obscured item in the control: they display the full item text string instead, and thereby avoid the need for horizontal scrolling, which is always a preferable user experience.

listbox_tracking_tooltips

Offset tracking tooltip

In-place tooltips operate in a similar manner, but rather than appearing at an offset to the cursor position they actually appear over the item itself, hence the term “in-place”:

listbox_inplace_tooltips

In-place tracking tooltip

This behaviour is controlled by the new SHOWITEMTOOLTIPS property which can be set to one of the following values:

  "0" - Disabled : Item tooltips are not displayed
  "1" - Offset   : Item tooltips are displayed at an offset to the cursor
  "2" - In-place : Item tooltips are displayed over the item itself.

When set to “1” (Offset) or “2” (In-place) the SHOWITEMTOOLTIPS property overrides the normal TOOLTIP property, so a “normal” tooltip will not be displayed.

Displaying alternative item text

Sometimes it is desirable to display a different text string in the tooltip rather than the item text itself.  In this case you can set the new SHOWVALUESASTOOLTIPS property to specify that the tooltip should display the contents of the item’s VALUE property instead.

SHOWVALUESASTOOLTIPS is a simple boolean property of TRUE$ or FALSE$.

listbox_tracking_value_tooltips

Displaying the Value property as a tooltip

Note in this case the tooltip is always displayed at an offset, and is triggered regardess of whether or not the item is clipped.

 

Combobox and TreeListbox controls

Both new properties described here also apply to simple Combobox and TreeListbox controls.

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

 

TOOLTIP is the new HELPTEXT

A tooltip is a small pop-up window that describes a control being pointed to, usually referred to as a “tool”, and they are commonly used to provide labelling for controls that only display an image, such as toolbar buttons.

Simple tooltip

Simple tooltip

Earlier versions of OpenInsight supported some basic tooltip functionality for a very limited set of controls via the HELPTEXT property, but for version 10 the name HELPTEXT has been deprecated for all standard controls (i.e. for objects other than menu items) and renamed to TOOLTIP instead, thereby bringing it in line with standard Windows terminology.  The name HELPTEXT can still be used however, to preserve backwards compatibility with your existing code.

Unlike in previous versions the new TOOLTIP property is not a single string, because there are more attributes that can be set – It is now an @fm-delimited dynamic array structured as follows:

   <1> Text
   <2> Title
   <3> Icon
   <4> Large Icon
   <5> Balloon Style
   <6> Centered

Text

This is the text to display.  Multiple lines are delimited by @tm.  This attribute is required for the tooltip to be displayed.

Tooltip with multiple lines

Tooltip with multiple lines

Title

This is the title to display in the tooltip. This is an optional attribute.

Tooltip with title

Tooltip with title

Icon

This attribute is only valid if the Title attribute is set.  It should contain the name of an icon file or resource to display in the tooltip (as per the usual ICON property).  Alternatively you can pass one of the following special characters to use a standard Windows icon instead (in a similar manner to the Msg() function):

  • “*” – Use the standard Information icon
  • “!” – Use the standard Warning icon
  • “H” – Use the standard Error icon
Tooltip with icon

Tooltip with icon

Large Icon

Normally the tooltip uses a 16×16 pixel size icon.  When this attribute is set to TRUE$ the tooltip will use a 32×32 pixel size one instead.  The default value is FALSE$.

Tooltip with large icon

Tooltip with large icon

Balloon Style

Standard tooltips use a rectangle shape when they are displayed. When this attribute is set to TRUE$ a “balloon” shape is used instead, with a stem pointing to the owning tool.  The default value is FALSE$.

Balloon style tooltip

Balloon style tooltip

Centered

Tooltips normally display themselves at an offset to their tool – when this attribute is set to TRUE$ the tooltip is centered underneath the tool instead.  The default value is FALSE$.

Tooltip with center-style

Tooltip with center-style

Basic+ example:

   // Example: display a multiline balloon tooltip containing a warning icon 
   // and title for a static control called TXT_ALERT

   declare function rti_ErrorText
   $insert ps_Tooltip_Equates
   $insert logical

   tooltip = ""
   tooltip<PS_TOOLTIP_POS_TEXT$>    = rti_ErrorText( "SP", errorCodes )
   tooltip<PS_TOOLTIP_POS_TITLE$>   = "Woeful tidings"
   tooltip<PS_TOOLTIP_POS_ICON$>    = PS_TOOLTIP_ICON_WARNING$  ; // "!"
   tooltip<PS_TOOLTIP_POS_BALLOON$> = TRUE$

   call set_Property_Only( @window : ".TXT_ALERT", "TOOLTIP", tooltip )

The TOOLTIP property applies to all controls except OLE controls, as these usually provide their own tooltips.  Some controls, such as List Box and Toolbar controls, also support different types of tooltips such as in-place and tracking, and these will be described in a future post.

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

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).