|
||||||||||
Following on from our last post on colouring individual popup lines we move onto one of the holy grails of developers - the ability to add a button to a popup and launch our own program from it - interrogating the popup to display more information about the current row for example. Using the example we showed last time - note that we now have a button on the popup called "Display"
Clicking the button results in this To accomplish this we need to be familiar with
If you haven't yet read the last blog entry then you might like to before continuing. The fully qualified entity ids of the individual popup controls To add a display buttton to the popup we could add a new control to the popup on the fly but that is a lot more complicated than taking over a control that already exists. So the trick that we are going to use is to add a button on to the popup that we're not going to use for its stated purpose and change its display text to "Display" and its action to something more suited to our use. For this example I'm going to hijack the "Print" button so we need to add that to the popup definition. For your purposes you might want to use one of the other controls so for your convenience here's a list of them all :-
Returning to our timer event - the first thing that we're going to do is to modify the TEXT of the print button to make it read "Display".
printButton = "POPUP.CB_PRINT"
objxArray := @Rm : printButton propArray := @Rm : "TEXT" dataArray := @Rm : "Display" dataArray = set_Property( objxArray, propArray, dataArray ) With that done we need to go about modifying the action to take on the click. The use of Window Common To use Window Common you just have to add the following code to your subroutine.
winId = "POPUP"
$Insert oiwin_Comm_Init If you're not familiar with Window Common then where've you been for the past 15 years? The structure of the Window Common used for quick events Window Common was effectively documented in detail in Technical Bulletin #2 - Compiled Window Structures, available on an old Works CD. We only need a very limited subset however so we'll deal with that. Each control on the window has the events associated with it in the variable controlSemantics@. So we need to firstly find the control, then find the CLICK event associated with it and then remove the logic that is currently there and replace it with a call to OUR routine instead. The quickevent structure that we need is as follows :- quickEventInfo<0, 0, 0, 1 > = Code for type of event quickEventInfo<0, 0, 0, 2 > = The action to take quickEventInfo<0, 0, 0, 3> := The routine to call quickEventInfo<0, 0, 0, 4> = The parameters to pass So when the popup is originally launched the labelled common looks like this We want to modify it to look like this The code required to do this is as follows :-
Locate printButton In controlMap@ using @fm setting gotIt then
/* OK let's change the quickevent to call OUR program passing in the usual */ quickEventInfo = "R" : @Tm quickEventInfo := "EXECUTE" : @Tm quickEventInfo := @appId<1> : "*STPROCEXE**" : atSelf : @Tm quickEventInfo := "@SELF" : @stm : "@EVENT" : @stm : "@PARAM1" : | @stm : "@PARAM2" : @stm : "@PARAM3" : @stm : | "@PARAM4" : @stm : "@PARAM5" : @stm : "@PARAM6" : @tm quickEventInfo := @tm Locate "CLICK" In controlSemantics@< gotIt, 8 > using @svm setting gotClick then controlSemantics@< gotIt, 9, gotClick > = quickEventInfo end end So now all we need to do is to take whatever action we want in our commuter program when the CLICK event is triggered. Here's the code from earlier in this blog post.
onClick:
begin case case object = "POPUP.CB_PRINT" objxArray = "POPUP.ET_POPUP" propArray = "LIST" objxArray := @Rm : "POPUP.ET_POPUP" propArray := @Rm : "SELPOS" dataArray = get_Property( objxArray, propArray ) list = dataArray[1, @Rm] selPos = dataArray[col2()+1, @Rm] call Msg(@window, "Your cursor is on " : list< selPos<2>, 1>) end case return Hopefully this will give you ideas of your own to extend the power and flexibility of popups.
A recent Works forum posting posed the question "Is it possible to set the color for individual rows in a popup rather than odd/even row colors?". Received wisdom is that "you cannot change colors on specific rows using COLOR_BY_POS due to the modality of the popup". This set the folks in Sprezz Towers to thinking about how this could actually be accomplished. This blog posting reflects the fruits of the combined thoughts and efforts of both the UK and Philadelphia Sprezz offices.
Take as a simple example a gender popup :- It might be nice to render this as follows :- To achieve this we need to be familiar with
User Defined Properties The developer can add additional properties to any control within an OI app simply by setting a property name prefixed with an @. So call set_Property(@Window, "@SPREZZ", "FIDDLESTICKS") would set the @SPREZZ property of the current window to the value "FIDDLESTICKS". Any other process could retrieve this property using get_Property. The TIMER event The TIMER event is fired by OpenInsight as specified by the TIMER property regardless of whether the current dialog/popup/whatever is currently modal. The TIMER property The TIMER property tells the system when it should fire the TIMER event and at what intervals. The HANDLE property The HANDLE property provides a convenient shortcut to establish whether or not a control exists. If it exists it will have a handle. The COLOR_BY_POS message The COLOR_BY_POS message allows individual rows, columns or cells of an edit table to be set to a specific colour. The Window structure of a popup At its simplest a popup consists of an edit table (where the results are shown) and buttons for selection or cancelling. The edit table is always called POPUP.ET_POPUP. Implementation It might be easier before actually showing the mechanics of how to achieve the effect required, to describe in simple terms how it is achieved. The key is in the seemingly innocous comment above that "The TIMER event is fired by OpenInsight as specified by the TIMER property regardless of whether the current dialog/popup/whatever is currently modal". Within our program that calls the popup we are going to do the following :-
The OPTIONS event would look like this :-
onOptions:
objxArray = @Window propArray = "@ROWS" dataArray = 1 : @Fm : 2 objxArray := @Rm : @Window propArray := @Rm : "@COLOURS" dataArray := @Rm : BLUE$ : @Fm : PINK$ objxArray := @Rm : @Window propArray := @Rm : "TIMER" dataArray := @Rm : 50 dataArray = set_Property( objxArray, propArray, dataArray ) retVal = popup( @Window, "", "GENDER") objxArray = object propArray = "DEFPROP" dataArray = retval dataArray = set_Property( objxArray, propArray, dataArray ) return So we firstly indicate that we would like to change the colours of rows 1 and 2 of the popup. We then explain that we'd like them set to blue and pink (using some previously declared EQUATES). We then tell the TIMER event to kick off 50 milliseconds later and then we call the popup. On a successful return from the popup we accept the value and put it into the control that has just triggered this OPTIONS event. So the popup will display and within 50 milliseconds the TIMER event will kick in. This has the following code :-
onTimer:
objxArray = @Window propArray = "@ROWS" objxArray := @Rm : @Window propArray := @Rm : "@COLOURS" objxArray := @Rm : "POPUP" propArray := @Rm : "HANDLE" dataArray = get_Property( objxArray, propArray) rows = dataArray[ 1, @rm] colours = dataArray[ Col2() + 1, @Rm] handle = dataArray[ Col2() + 1, @Rm] if Len( handle ) then ptr1 = 1 ptr2 = 1 loop nextRow = rows[ ptr1, @Fm ] ptr1 = col2() + 1 while len( nextRow ) nextColour = colours[ ptr2, @Fm ] ptr2 = col2() + 1 call send_Message("POPUP.ET_POPUP", "COLOR_BY_POS", 1, nextRow, nextColour) repeat objxArray = @Window propArray = "TIMER" dataArray = "" dataArray = set_Property( objxArray, propArray, dataArray ) end Return In this code we retrieve the rows to colour and the colours to set them to. We also retrieve the HANDLE of the popup to ensure that it has been created successfully. If it has we use send_Message to colour the individual rows of the popup before setting the TIMER property to null to prevent it from being called again. In theory we ought to be able to set the TIMER property to 0 but there seems to be a bug in the 9.2.1 implementation which ignores the zero and continues calling the TIMER event. Thus we are able simply to modify the popup after it has been launched. In the next article in this series we will show how to add a button to the popup to call a user defined routine to display additional information about the current row in the popup. Labels: color_by_pos, options, Popup, timer |
||||||||||
| ||||||||||