CHAPTER 6 


XADD REFERENCE 


This document is a beta version and may be subject to change. 


This chapter describes the changes and additions that have been made to the XADD library as a result of the introduction 
of the Siena and Series 3c machines into the SIBO range. 


It documents the new abstract classes GRIDWIN and MATCHWIN which may be subclassed to provide a tabular grid format 
for the display of data. The MATCHWIN class provides highlighted rows, rather than individual cells, and optional 
incremental matching on a chosen column. 


Precursors 
Familiarity with the following topics will aid the understanding of this chapter: 
e the wIN class described in the Windows chapter of the HWIM Reference manual 


e the List View of the Siena or Series 3c Data application which is an example of a MATCHWIN derived class 


Class diagram 


matchwin > 


GRIDWIN 


wn_calc_position 
wn_connect 
wn_dodraw 


wn_emphasise 


gw_get_cell_rect 
gw_draw_cells 
gw_get_curent 
gw_move_to 
gw_set_col_width 
gw_set_row_height 
gw_zoom 
gw_highlight 


gw_get_data 


6 XADD REFERENCE 


The GRIDWIN class provides a means of displaying data in a tabular form, for example: 


GRIDWIN provides for the display of: 


data in left aligned columns and rows, clipped to the nearest whole character horizontally and, optionally, 
clipped to the nearest whole row vertically 


a highlight showing the currently selected cell 
optionally, dotted gridlines separating rows and columns 


optionally, a variable width scroll bar showing the current position relative to the overall height of the grid and the 
size of the currently displayed visible portion relative to the overall height of the grid 


optionally, one or more locked topmost columns which are not vertically scrolled 


optionally, one of more locked leftmost columns which are not horizontally scrolled 


GRIDWIN also provides an extremely efficient intelligent redraw mechanism whereby only grid cells that fall within the 
redraw region are actually drawn and data is only requested for those cells. This can yield massive savings in both 
drawing and data retrieval times especially for applications where actually obtaining the data to display is the limiting 
factor in execution speed. 


The GRIDWIN class provides a deferred method - the gw_get_data method - which must be replaced by any subclass to 
create a fully-functioning grid window. 


Class definition 


Defined in the sub-category file gridwin.cl (generated header file gridwin.g). 


SIENA/SERIES 3C UPGRADE 


CLASS gridwin bwin 


{ 
REPLACE 


REPLACE 
REPLACE 
REPLACE 
REPLACE 
REPLACE 
REPLACE 
REPLACE 


destroy 
wn_init 
wn_redraw 
wn_draw 
wn_key 
wn_set 
wn_sense 
wn_emphasise 


ADD gw_get_cell_rect 
ADD gw_draw_cells 
ADD gw_move_to 

ADD gw_set_col_width 
ADD gw_set_row_height 
ADD gw_get_current 
ADD gw_zoom 

ADD gw_highlight 
DEFER gw_get_data 


CONSTANTS 


TYPES 


{ 


PR_GRIDWIN_MIN_COL_WIDTH 


PR_GRIDWIN_CELL_HGAP 
PR_GRIDWIN_CELL_LGAP 
PR_GRIDWIN_BORDER_WIDTH 
PR_GRIDWIN_SCROLL_SMALL 
PR_GRIDWIN_SCROLL_LARGE 
PR_GRIDWIN_SCROLL_ARROW 
PR_GRIDWIN_PLOT_X 
PR_GRIDWIN_PLOT_Y 


PR_GRIDWIN_COMPLETE_ONLY 


PR_GRIDWIN_GRIDLINES 
PR_GRIDWIN_FREE_SIZES 


PR_GRIDWIN_GRID_SIZE 
PR_GRIDWIN_LOCK 
PR_GRIDWIN_SIZES 
PR_GRIDWIN_FLAGS 
PR_GRIDWIN_XPLANE 
PR_GRIDWIN_YPLANE 
PR_GRIDWIN_ZOOMBASE 
PR_GRIDWIN_SCROLL 


} 


{ 
typedef struct 


{ 

INT locked; 
INT anchor; 
INT current; 
INT visible; 
UBYTE clipped; 
UBYTE full; 
INT total; 
INT *psize; 
INT defsize; 
INT numspec; 
INT scroll; 
INT gutter; 
INT max; 

INT plot; 
UWORD flags; 
VOID *ptr; 

} GRID_PLANE; 


OODRNNSA 


Number of locked cells (unscrollable) 
Lowest visible unlocked cell 

Currently selected cell 

Highest number visible 

Whether visible is clipped 

Whether entire plane fits in display area 
Total number of cells in plane 

Pointer to cell size array 

Default size for any unspecified cells 
Number having individually specified size 
Scroll bar size 

Width of area beyond cell area 

Maximum co-ordinate to draw cells to 
Physical direction to plot plane 

Various flags 

For use by subclasses 


6 XADD REFERENCE 


typedef struct 


{ 
GRID_PLANE xplane; Plane defining the grid columns 
GRID_PLANE yplane; Plane defining the grid rows 
INT zoombase; Zoom base font 
INT zoom; Zoom state 
UWORD flags; Mask flags 
} IN_GRIDWIN; 
} 
PROPERTY 
{ 
IN_GRIDWIN params; Current parameters 
P_EXTENT wextent; The full window extent 
UWORD fascent; Ascent of current display font 
UBYTE fstyle; Style used for text display 
} 
} 
Property 


gridwin.params 


gridwin.wextent 


gridwin.fascent 


gridwin.fstyle 


Grid Planes 


A pointer to an IN_GRIDWIN struct whose members are described below. This is a copy of the 
IN_GRIDWIN struct passed to the WN_INIT and WN_SET methods. 


xplane 


yp lane 


zoombase 


zoom 


flags 


A GRID_PLANE struct that defines the x-plane (or columns) of the grid. The fields 
of GRID_PLANE struct are described separately below. 


A GRID_PLANE struct that defines the y-plane (or rows) of the grid 


The font ID of the smallest font used to display data in the grid. This must be 
specified on initialisation. 


A numerical value that is adjusted as the grid is zoomed. This value is added onto 
zoombase to give the font ID used to display data in the grid. 


Defines which parts of the IN_GRIDWIN params struct to look at when calling 
WN_SET (the whole struct is examined on WN_INIT): 


PR_GRIDWIN_XPLANE Look at the xplane member of the IN_GRIDWIN struct 
PR_GRIDWIN_YPLANE Look at the xplane member of the IN_GRIDWIN struct 


PR_GRIDWIN_GRID_SIZE —_ Look at the total member of the specified planes 


PR_GRIDWIN_LOCK Look at locked members 

PR_GRIDWIN_SIZES Look at the psize, defsize and numspec members 
PR_GRIDWIN_SCROLL Look at the scroll members 

PR_GRIDWIN_FLAGS Look at the flags members 

PR_GRIDWIN_ZOOMBASE Look at the zoombase member of the IN_GRIDWIN struct 


A pointer to a P_EXTENT struct. This holds the current position and size of the grid window. 
This is a copy of the P_EXTENT struct passed to the WN_INIT and wN_SET methods. 


The ascent of the current display font. This is used to offset the position of text within a cell 
from the top of the cell. 


The current font style used to display data within the grid. 


Grid planes describe the properties of a range of cells in a particular physical direction (x or y). They are specified using 
the GRID_PLANE structure described below. Cells in a plane are referred to by index numbers, with the first cell 

numbered zero. Each cell in a plane has a size in that physical direction (x or y), measured in pixels, which may or may 
not be individually specified. 


SIENA/SERIES 3C UPGRADE 


GRIDWIN uses two grid planes; gridwin.params.xplane and gridwin.params.yplane to define the grid columns and 
rows respectively. The intersection of these two planes forms the grid. 


6 XADD REFERENCE 


The IN_GRIDWIN struct that is used to initialise or set the grid contains these x and y planes. Unless otherwise specified, it 
should be assumed that the fields described below must be filled on initialisation. 


SIENA/SERIES 3C UPGRADE 


Locked 


anchor 
current 


visible 


clipped 


full 


total 


psize 


defsize 


numspec 


scroll 


gutter 


max 


plot 


The number of locked cells in the plane. Cells in the plane with indexes 0 to 
locked - 1 will be locked. Locked cells are not scrolled with other cells in the plane and are 
always at the start of the plane. They can be used for column or row headings, for instance. 


The lowest indexed cell in the plane that is both visible and not locked. 

The cell in the plane that is currently selected (highlighted). 

The highest indexed cell in the plane that is currently visible (on screen). 

This value is calculated at run-time and need not be specified on initialisation. 


Specifies whether the entirety of cell visible is currently visible or if it is clipped to the edge 
of the screen. Contains 1 if visible is clipped, 0 otherwise. The index of the highest 
indexed, fully visible cell can thus be obtained by subtracting clipped from visible. 


This value is calculated at run-time and need not be specified on initialisation. 


TRUE if the whole of the plane currently fits into the display area. Used to calculate whether a 
scroll-bar is necessary. 


This value is calculated at run-time and need not be specified on initialisation. 
The total number of cells in the plane. 


A pointer to an array of INTs specifying the size of cells in the plane. psize may be NULL in 
which case an appropriate amount of memory is allocated to store column widths. If GRIDWIN 
itself has to allocate memory, it also frees it on destruction. 


The default size of cells for which no specific size is specified. If numspec is less than total, 
i.e. there are some non-specified size cells, then defsize must be specified. 


Specifies the number of cells which have an individually specified, and therefore variable, size. 
Cells with indexes above numspec - 1 are assumed to have size defsize and cannot be 
adjusted at runtime. If numspec is non-zero, and psize is not NULL, psize should point to an 
array witha size of at least numspec * sizeof(INT). 


The requested width for the scroll-bar. The scroll-bar will only be displayed if full is FALSE. 
When the scroll bar is being displayed, the value of scroll will be copied to gutter. 


Any scroll-bar width may be specified but it is recommended that either the set value of 
PR_GRIDWIN_SCROLL_SMALL or PR_GRIDWIN_SCROLL_LARGE be used. 


GRIDWIN will use small scroll-bar arrows if scroll is less than PR_GRIDWIN_SCROLL_LARGE 
otherwise large arrows will be used. 


GRIDWIN does not support scroll bars for horizontally plotted planes. 


Note: Although a vertical scroll bar represents the position within the grid vertically, it is drawn 
in a horizontal plane and is defined by the scroll member of the horizontal GRID_PLANE 
opposed to the one which it represents. 


The width of the area beyond the cell display area. The value of scroll is copied here when 
the scroll bar is displayed. 


This value is calculated at run-time and need not be specified on initialisation. 


The maximum co-ordinate that the plane can draw cells to. This is calculated by subtracting 
PR_GRIDWIN_BORDER_WIDTH and gutter from gridwin.wextent.width. 


This value is calculated at run-time and need not be specified on initialisation. 


The physical direction to plot the plane on screen. GRIDWIN recognises values of 
PR_GRIDWIN_PLOT_X for a horizontal direction and PR_GRIDWIN_PLOT_Y for a vertical direction. 
GRIDWIN sets the appropriate value for gridwin.params.xplane and gridwin.params.yplane 
on initialisation so this need not be specified. 


Various flags controlling properties of the grid: 


PR_GRIDWIN_COMPLETE_ONLY Specifies that only fully visible cells are drawn. GRIDWIN does 


6 XADD REFERENCE 


not recognise this flag for horizontal planes 


PR_GRIDWIN_GRIDLINES Draw a dotted dividing line at the furthest edge of each cell in 
the plane. 


Solid dividing lines are always drawn at the end of the last 
locked cell, irrespective of this flag. 


PR_GRIDWIN_FREE_SIZES Used internally to record the fact that GRIDWIN itself allocated 
the memory used for the cell size array and that it must be freed 
on destruction of the window. 


ptr A VOID pointer not used by GRIDWIN but provided for use by subclasses which may, for 
instance, provide additional structs that specify additional plane properties. 


GRIDWIN methods 


© DESTROY Destroy 
VOID destroy(VOID); 
Destroy the window. 


Frees the memory used by gridwin.xplane.psize and gridwin.yplane.psize if gridwin.xplane. flags and/or 
gridwin.yplane. flags, respectively, contain PR_GRIDWIN_FREE_SIZES. 


Supersends a DESTROY message. 


WN_INIT Initialise grid 
VOID wn_init(PR_WIN *parent, P_EXTENT *wextent, IN_GRIDWIN *init); 
Create and intialise the grid window according to *parent, *wextent and *init. 


Creates the grid window as a child of *parent with the position and size specified by *wextent. If the window is to bea 
root window, *parent should be NULL. 


The grid is created with the inital parameters specified in *init. The number of locked rows and columns, etc., can 
therefore be set when the grid window is created. For a full description of the the IN_GRIDWIN structure, refer to the 
Property section above. 


The supplied wN_INIT method may leave with E_GEN_ARG if certain illegal values are passed. 


WN_SET Reset grid parameters 
VOID wn_set(P_EXTENT *wextent, IN_GRIDWIN *pnew); 

Reset the window to position and size *wextent and/or change one or more GRIDWIN parameters. 

The wextent parameter may be NULL. 


WN_SET will only look at those fields in *pnew specified by pnew->flags.. The number of locked rows and columns, 
etc., can therefore be reset. Fora full description, refer to the Property section above. 


WN_SET cannot be used to change the current anchor cell or current select cell; Gw_MOVE_TO must be used for this purpose. 


SIENA/SERIES 3C UPGRADE 


WN_SENSE Get current grid parameters 
INT wn_sense(IN_GRIDWIN *pparams); 


Write the current grid parameters to *pparams. This method does nothing more than copy the contents of 
gridwin.params to *pparams. 


Note: A convenience method, gw_get_current, is provided for returning the currently selected cell. 


WN_KEY Handle key input 


INT wn_key(INT keycode, INT modifiers); 
Handle keypresses passed to the window. 
If keycode is W_KEY_LEFT: 


e If modifiers does not contain W_SHIFT_MODIFIER, make current the first cell before 
gridwin.params.xplane.current, in the plane gridwin.params.xplane, that has non-zero size and is not 
locked. 


e =If modifiers does contain W_SHIFT_MODIFIER but does not contain W_CTRL_MODIFIER, reduce the width of the 
currently selected column (gridwin.params.xplane.current) by one width unit. A width unit is definined to 
be two thirds of the width of the widest character in the current display font. 


e If modifiers contains both w_SHIFT_MODIFIER and W_CTRL_MODIFIER, reduce the width of the currently 
selected column by 8 width units. 


If keycode is W_KEY_RIGHT: 


e If modifiers does not contain W_SHIFT_MODIFIER, make current the next cell after 
gridwin.params.xplane.current, in the plane gridwin.params.xplane, that has non-zero size 


e =If modifiers does contain W_SHIFT_MODIFIER but does not contain Ww_CTRL_MODIFIER, increase the width of the 
currently selected column (gridwin.params.xplane.current) by one width unit. A width unit is definined to 
be two thirds of the width of the widest character in the current display font. 


e If modifiers contains both w_SHIFT_MODIFIER and W_CTRL_MODIFIER, increase the width of the currently 
selected column by 8 width units. 


If keycode is W_KEY_HOME: 

e = Make current the first cell in the plane gridwin.params.xplane, that has non-zero size and is not locked. 
If keycode is W_KEY_END: 

e = Make current the last cell in the plane gridwin. params .xplane, that has non-zero size. 


If keycode is W_KEY_UP: 


e Make current the first cell before gridwin.params.yplane.current, in the plane gridwin.params.yplane, that 
has non-zero size and is not locked. 


If keycode is W_KEY_DOWN: 


e = Make current the next cell after gridwin.params.yplane.current, in the plane gridwin. params. yplane, that 
has non-zero size. 


6 XADD REFERENCE 


If keycode is W_KEY_PAGE_UP: 


e If modifiers does not contain W_CTRL_MODIFIER, decrement gridwin.params.yplane. anchor by the number of 
unlocked cells that are currently fully visible in the plane gridwin.params.yplane. Also, unless the first row is 
already visible, decrement gridwin.params.yplane.current to keep the current position within the page 
constant, i.e. ensure that the value of gridwin.params.yplane.current - gridwin.params.yplane.anchor is 
constant. 


e If modifiers does contain Ww_CTRL_MODIFIER, make current the first cell in the plane gridwin. params. yplane 
that is not locked and has non-zero size. 


If keycode is W_KEY_PAGE_DOWN: 


e If modifiers does not contain W_CTRL_MODIFIER, increment gridwin.params.yplane. anchor by the number of 
unlocked cells that are currently fully visible in the plane gridwin.params.yplane. Also, unless the last row is 
already visible, increment gridwin.params.yplane.current to keep the current position within the page 
constant, i.e. ensure that the value of gridwin.params.yplane.current - gridwin.params.yplane.anchor is 
constant. 


e If modifiers does contain w_CTRL_MODIFIER, make current the last cell in the plane gridwin.params.yplane 
that has non-zero size. 


All movement operations are performed from wN_KEY by sending Gw_MoveE_TO which does much of the validation of the 
new anchor and current positions. 


However, a WN_KEY method must ensure the following before passing new values for the current cell and/or anchor cell to 
GW_MOVE_TO: 


e the new anchor cell actually exists 
e the new current cell actually exists 
e — the new current cell does not have a zero width 


Gw_MOVE_TO performs the rest of the validation and will scroll the screen and adjust the values as necessary if, for 
instance, the new current cell is not currently visible or if the new anchor cell has zero size. 


All adjustments of column width are performed from wN_KEY by sending Gw_SET_COL_WIDTH which does all of the 
validation of the new values. 


This method returns WN_KEY_CHANGED if it receives any of the keypresses above, otherwise WN_KEY_NO_CHANGE. 


WN_REDRAW Handle partial redraw 


VOID wn_redraw(P_RECT *prect); 
Validate the area *prect for redrawing and draw the necessary sections of the window. 


Sends itself a WN_DRAW message, passing prect. 


WN_DRAW Perform intelligent draw 


VOID wn_draw(P_RECT *prect); 
Draw all sections of the window that occupy positions in the region specified by *prect. 


The supplied method calculates which cells are in the co-ordinate range specified in *prect and then calls 
GW_DRAW_CELLS to draw those cells. 


This provides for an extremely efficient drawing mechanism in that: 


e — only those areas of the window that need redrawing are validated and drawn to giving large savings in drawing 
time. 


e the Gw_GET_DATA method only has to obtain data for those areas that actually need to be drawn. This can give 
massive savings in applications where obtaining the data is relatively slow. 


All other screen components such as the scroll bar are drawn if the area they occupy falls with in *prect. 


SIENA/SERIES 3C UPGRADE 


WN_EMPHASISE Set window highlight 


VOID wn_emphasise(UINT flag); 


Set or clear the PR_WIN_EMPHASISED bit in win. flags according to flag. Highlight the current selection if flag is TRUE 
else remove the window highlight. 


GRIDWIN sets or removes the highlight by calling Gw_HIGHLIGHT as indicated in the following code: 
if (flag != (self->win.flags & PR_WIN_EMPHASISED) ) 


self->win.flags “= PR_WIN_EMPHASISED; 
gCreateTempGCO(self->win.id); 
p_send2(self, O_GW_HIGHLIGHT); 
gFreeTempGC(); 


z 


GW_GET_CELL_RECT Get screen rectangle for cell 


INT gw_get_cell_rect(P_POINT *cell, P_RECT *rect); 


Write the screen co-ordinates of the rectangle occupied by the cell *ce11 into *rect. 
Returns TRUE if the cell is currently visible, FALSE if it is not. 


Note: If the cell has zero size in either plane, this method will write the cell rectangle to *rect although it will return 
FALSE. In all other circumstances where the cell is not visible, this method will return FALSE immediately. 


GW_DRAW_CELLS Draw a range of cells 


VOID gw_draw_cells(P_RECT *abs_range); 
Draw the cells with indexes specified in the range *abs_range. 


The supplied method performs drawing on a row or partial row basis. 

For each row specified in *abs_range, it first checks whether it is currently visible and, if so, calls Gw_GET_DATA under 
the protection of p_entersend to obtain the data for that row or section thereof. The method then checks each cell in the 
row and draws it if visible. If GW_GET_DATA called p_leave or returned non-zero, the cells are drawn empty. Grid lines 
are drawn if specified in gridwin.xplane and/or gridwin.yplane. 


For further discussion of the operation of the supplied Gw_DRAW_CELLS, refer to the description of Gw_GET_DATA. 
Note: The supplied method may write to *abs_range. 


Since all drawing of cells is performed by calling Gw_DRAW_CELLS, a subclass that replaces this method can draw 
whatever it wishes in each cell. A subclass, may for instance wish to draw bitmaps in each cell rather than text. 


GW_GET_CURRENT Return current selection 
VOID gw_get_current(P_POINT *ppos); 
Write the absolute coordinates of the currently selected cell to *ppos. 


This method does nothing more than copy the contents of gridwin.params.xplane.current and 
gridwin.params.yplane.current to ppos->x and ppos->y, respectively. 


GW_MOVE_TO Move to a specific cell 


VOID gw_move_to(P_POINT *ppoint, P_POINT *ptl); 


Make the cell at coordinates *ppoint the current cell and/or make the cell at coordinates *pt1 the anchor cell in the 
respective planes. 


Redraw the screen as necessary. 


Either ppoint or pt1l can be NULL. 


0-12 


6 XADD REFERENCE 


This method will adjust the currently selected cell if the postion of the new top-left cell causes the current selection to be 
invisible. 


This method will use the nearest cell to that at *pt1 if *pt1 is a cell that has zero size (i.e. is in a row with no height 
and/or a column with nowidth). 


Usually, only a subclass that alters the manner in which the grid is scrolled will use the pt1 parameter. 


Subclasses should not normally replace this method. 


GW_SET COL WIDTH Set the width of a column 


INT gw_set_col_width(UINT col, INT new_width); 


Set absolute column col to width new_width. 
If the column is currently visible, scroll and redraw the screen as necessary. 


Any column may be adjusted with this method, including locked columns and columns that are not currently visible. 
The new_width parameter may be zero for non-locked columns. 


Returns TRUE if the column was successfully adjusted, otherwise FALSE if any of the following conditions are met: 
e the column does not exist 


e the column is locked and new_width < PR_GRIDWIN_MIN_COL_WIDTH 


e the column already has width new_width 


e the column cannot have an individually specified width, i.e. 
col >= gridwin.params.xplane.numspec 


¢ —new_width is zero and all other non-locked columns have zero width. 


GW_SET_ROW_HEIGHT Set the height of a row 
VOID gw_set_row_height(UINT row, INT new_height); 
Set the absolute row row to height new_height . 


The supplied method does nothing and is provided for subclasses which may, for instance, wish to provide for user 
alteration of column heights. 


GW_ZOOM Zoom the grid 


VOID gw_zoom(INT direction); 


If direction is TRUE, increase the size of the current display font, otherwise decrease it. Adjust the height of all rows 
accordingly. 


The current zoom level is held in gridwin.params.zoom and is in the range 0 to 3. The level is wrapped around above 
and below these limits. The ID of the current display font is obtained by adding gridwin.params.zoom to 
gridwin.params.zoombase. 


The grid rows are adjusted by calculating the difference between the character heights of the old and new display fonts 
and adding this to the height of each row in gridwin.params.yplane.psize and to gridwin.params.yplane.defsize. 


This method causes the whole window to be redrawn. 


A subclass that wishes to change the manner in which the grid zooms, e.g. to restrict the number of zooms levels 
available, should replace this method. 


GW_HIGHLIGHT Highlight current selection 
VOID gw_highlight(VOID); 


The supplied method inverts the area of the currently selected cell. 


SIENA/SERIES 3C UPGRADE 


GRIDWIN expects that the operation of a GW_HIGHLIGHT method to be reversible, i.e. calling it a second time removes the 
highlight. 


GRIDWIN will only call Gw_HIGHLIGHT whilst the grid window has the emphasis, i.e. the PR_WIN_EMPHASISED bit in 
win. flags is set. 


Deferred GRIDWIN methods 


GW_GET DATA Get data for cells 


INT gw_get_data(TEXT **cols, P_RECT *range); 
Get the data for the specified range of cells. 
This is the only method which a subclass need replace in order to create a fully functional grid window. 


This method is called by Gw_DRAW_CELLS to obtain the data to be displayed in a range of cells. 
As discussed above, the supplied gw_draw_cells method performs drawing on a row or partial row basis. 


The arguments passed to GW_GET_DATA by the supplied Gw_DRAW_CELLS method are as follows: 
range range->tl.y specifies the row for which data is being requested. 


range->t1.x specifies the first column index for which data is being requested, 
range->br.x specifies the last. 


range->br.y specifies the maximum row for which data will be requested for this redraw. This 
gives the subclass some opportunity to appropriately cache its retrieval of data if necessary. 


cols A pointer to an array of text pointers. The passed array is guaranteed to be exactly big enough to 
hold (range->br.x - range->tl.x) + 1 pointers. 
A subclass should set each element in this array to point to a zero-terminated string for each of 
the cells requested. 


The supplied Gw_DRAW_CELLS method calls GWw_GET_DATA under the protection of p_entersend. A GW_GET_DATA method is 
free to call p_leave or return non-zero at any time. In this case, the supplied Gw_DRAW_CELLS method will ignore *cols, 
draw empty cells for the entire row and proceed to the next row. Otherwise, a GW_GET_DATA method should return 0 to 
indicate that it has provided valid pointers in every element of the passed array. 


As there will always be a temporary graphics context in existence when Gw_GET_DATA is called, it is possible for a 
subclass to alter the appearance of the grid display on a row for row basis from within the Gw_GET_DATA method. 


A subclass may, for instance, wish to display the top line of the grid in a different font to the rest. In this case a subclass 
would set the temporary graphics context to that font and size when asked for data for that line. The subclass must also 
set gridwin. params.zoombase, gridwin.params.zoom, gridwin.fascent and gridwin.fstyle to the appropriate values 
to enable GRIDWIN to properly align the text in that font. The subclass must remember to reset the graphics context and 
gridwin property to their original values when asked for the next row of data. 


For any more substantial alteration of the display, for example using differing fonts between cells within rows, a subclass 
will need to provide its own Gw_DRAW_CELLS method. 


Since, gw_draw_celts is the only method to call gw_get_data, a subclass that replaces gw_draw_cel\s is free to use 
whatever arguments to gw_get_data it wishes and to get data for cells by whatever mechanism it wishes. A subclass 
may, for instance, call gw_get_data for each cell individually. 


MATCHWIN 


gw_get_cell_rect 
wn_calc_position i _ini gw_draw_cells 
wn_connect gw_get_curent 
wn_dodraw is gwomeve—te 
i gw_set_col_width 
wn_redraw gw_set_row_height 
wn_draw gw_zoom 


wn_emphasise gwhightight 


gw_get_data 


6 XADD REFERENCE 


MATCHWIN 


mw_start_match 
mw_stop_match 
mw_hit_maxlen 


The MATCHWIN class creates a grid display that is identical to that of the GRIDWIN class with the following changes: 


e the concept of a individually selected cell is abandoned in favour of the selection of an entire row. The 
currently selected cell in the x-plane is taken to be the anchor cell. The whole of the currently selected row is 


highlighted. 


¢ optionally, incremental matching can be preformed on one column whether or not that column is visible. 


The GRIDWIN class provides a deferred method - the gw_get_data method - which must be replaced by any subclass of 


MATCHWIN to create a fully-functioning incrementally matching grid window. 


Class definition 


Defined in the sub-category file matchwin.cl (generated header file matchwin.g). 


CLASS matchwin gridwin 
{ 
REPLACE wn_key 
REPLACE gw_highlight 
REPLACE gw_move_to 
ADD mw_start_match 
ADD mw_stop_match 
ADD mw_hit_maxlen 


CONSTANTS 


{ 
PR_MATCHWIN_UNSET (-1) 


} 


SIENA/SERIES 3C UPGRADE 


TYPES 
{ 
typedef struct 
{ 
PR_VAROOT *array; Pointer to array for VMATCHER 
UINT maxlen; Maximum length of match 
UWORD txtoff; Offset within array record 
UINT minrec; Minimum index within array to match 
UINT maxrec; Maximum index within array to match 
INT offset; Offsets the index returned from matcher 
UINT column; Column for matching 
INT position; Which row for matched record or _UNSET 
} IN_MATCHWIN; 
} 
PROPERTY 1 
{ 
PR_VMATCHER *matcher; Pointer to incremental matcher 
IN_MATCHWIN params; Current parameters 
UBYTE matchlen; Current match length 
UBYTE filler; 
} 
} 
Property 
matchwin.matcher A pointer to a VMATCHER incremental matcher object or NULL if no incremental 
matcher is currently in use. 
matchwin. params A pointer to an IN_MATCHWIN struct. This is a copy of the IN_MATCHWIN struct 


passed to the MW_START_MATCH method. 


For a full description of the IN_MATCHWIN struct, see the description of the 
MW_START_MATCH method below. 


matchwin.matchlen — Holds the current length of the match string. The address of matchwin.matchlen 
is passed to matchwin.matcher when it is initialised. 


MATCHWIN methods 


WN_KEY Handle key input 


INT wn_key(INT keycode, INT modifiers); 
The MATCHWIN wn_key method performs two functions over and above the GRIDWIN method: 


e it intercepts the unmodified keycodes w_KEY_LEFT, W_KEY_RIGHT, W_KEY_HOME and W_KEY_END to alter the 
horizontal scrolling behaviour as discussed above. This involves altering the anchor cell rather than the current 
cell on horizontal movement. For MATCHWIN, the current cell will always be the anchor cell in the x-plane. 
Any other movement or cell adjustment keypresses are sent to the GRIDWIN wn_key method. 


e it passes any remaining unprocessed keypresses to the incremental matcher if there is one and adjusts the 
highlight position and/or current row depending on the value returned from the matcher. 


GW_HIGHLIGHT Highlight current selection 


VOID gw_highlight(VOID); 


The MATCHWIN gw_highlight method highlights as much as is visible of the currently selected row and positions the 
incremental matcher cursor if incremental matching is active and the cursor is visible. 


6 XADD REFERENCE 


GW_MOVE_TO Move to a specific cell 
VOID gw_move_to(P_POINT *ppoint, P_POINT *ptl); 


MATCHWIN subclasses this method in order to detect any change in the currently selected row and reset the incremental 
matcher accordingly. 


This is done by simply recording the value of gridwin.params.yplane.current and comparing it with the value after 
supersending GW_MOVE_TO to GRIDWIN. If the value is altered and a matcher is present, the matcher is reset to the new 
current record. 


This procedure enables subclasses to freely navigate around the grid by calling Gw_mMove_To without interferring with the 
operation of the matcher. 


MW_START_MATCH Start incremental match 
VOID mw_start_match(IN_MATCHWIN *match); 

Start incremental matching based on the parameters in *match and copy *match to matchwin. params. 

The members of the IN_MATCHWIN struct are as follows: 


array A pointer to a VA_ROOT array object (or subclass thereof) that the incremental matching is to 
be performed on. 


max len The maximum string length to match. 

txtoff The byte offset from the beginning of items in array to perform incremental matching from. 
minrec The index of the first item in array to match. 

maxrec The index of the last item in array to match. 

offset A value that is added onto the value returned from the matcher’s IM_SENSE_VAL method to 


offset the grid row to jump to. This removes the need for a exact correlation between 
indexes in array to lines in the grid. 


column The column in the grid that array corresponds to, i.e. the column that incremental matching 
is being performed on. 


position The number of rows below the last locked row to position the matched row, i.e. after a match, 
gridwin.params.yplane.anchor will be set to matched row - position. 
position may also be set to PR_MATCHWIN_UNSET, in which case the matched row is navigated 
to in such a way as to require the minimum possible screen redrawing. 


The matcher is created and initialised with the following code: 


self->matchwin.matcher = f_newsend(CAT_XADD_HWIM, C_VMATCHER, O_IM_INIT, 
&self->matchwin.matchlen, match->maxlen, match->array); 


p_send5(self->matchwin.matcher, O_IM_SET_RANGE, match->minrec, match->maxrec, 
match->txtoff); 


Returns immediately if matching is already active. 


MW_STOP_MATCH Stop incremental match 
VOID mw_stop_match(VOID); 

Stop incremental matching by destroying the incremental matcher and erasing the flashing text cursor. 

Sets matchwin.matcher to NULL. 


This method does nothing if incremental matching is not active, i.e. if matchwin.matcher is NULL. 


SIENA/SERIES 3C UPGRADE 


MW_HIT MAXLEN Maximum characters matched 


VOID mw_hit_maxlen(VOID); 


This method is called when the incremental matcher has been unable to match the most recent keypress because 
matchwin.matchlen has reached matchwin.params.maxlen (as opposed to when no strings in the array match). 


A subclass may, for instance, wish to perform further matching by some other mechanism or display some message to the 
user. 


