First, we have to create a data structure that we will attach to the window using DataAttach(). Here it is:
typedef struct { char *buffer; /* address of text */ char **line; /* table of each lines */ int maxline; /* number of line */ int wchar,hchar; /* size of a character */ } TEXT;We suppose that we are able to load a text in memory and that each line of the text is terminated by a null-byte.
The variables xpos and ypos of the window descriptor represent the position of data inside the window. In this case, xpos is the first displayed column and ypos the first displayed line. The variable w_u and h_u give the width and the height in pixel to shift when scrolling the window. These values are the width and the height of a character (the font used to display the text is supposed non-proportional). These values are also used to compute the size of the sliders.
Now, write the function creating a text window:
WINDOW *OpenText( TEXT *text) { WINDOW *win; int attrib[10]; win = WindCreate( WAT_ALL, app.x, app.y, app.w, app.h); EvntAttach( win, WM_REDRAW, draw_text); DataAttach( win, 'TEXT', text); /* Maximal lenght of a line */ win -> xpos_max = 255; /* Number of line */ win -> ypos_max = text->maxline; vqt_attributes( app.handle, attrib); /* Height of a cell character */ win -> w_u = attrib[8]; /* Width of a cell character */ win -> h_u = attrib[9]; /* Height of a character */ text-> wchar = attrib[6]; /* Width of a character */ text-> hchar = attrib[7]; /* Open the window */ WindOpen( win, app.x, app.y, app.w, app.h); /* Update the size and position of sliders */ WindSlider( win, HSLIDER|VSLIDER); return win; }We write now the redraw function. The algorithm is:
void draw_text( WINDOW *win) { int x,y,w,h; int hcell, hcar; int i, attr[10]; TEXT *ptext = (TEXT *)DataSearch( win, 'TEXT'); /* Get some usefull information */ WindGet( win, WF_WORKXYWH, &x, &y, &w, &h); w += x-1; vqt_attributes( win->graf.handle, attr); hcell = attr[9]; hcar = attr[7]; /* Background */ WindClear( win); /* Foreground */ vswr_mode( win->graf.handle, MD_TRANS); /* vertical offset for a nice text drawing */ h = hcell - hcar; /* from the first line visible to the end ... * Convention: we have always 0 <= win->ypos < win->yposmax */ for( i=win->ypos; i<win->ypos_max ; i++) { y += hcell; /* If the line is upper the clipped zone? */ if( y < clip.g_y) continue; /* line inside the window ? */ if( strlen( ptext->line[ i]) > win->xpos) v_gtext(win->graf.handle, x, y - h, ptext->line[i] + win->xpos); /* End if the line is downer the clipped zone */ if (y > min( w, clip.g_y + clip.g_h-1)) break; } }As EvntWindom() clips all screen output using the AES rectangle list, we just have to use the WinDom global variable clip. This variable (a GRECT structure) containts the coordinate of the zone clipped by EvntWindom()) during a redraw event. This variable allows you to decrease the complexity of the redraw function.
This case illustrates a common case of sliders use. Some cases are more complex (for example a window displaying icons like the ideal window of the GEM desktop). The (!url [sliders] [Window sliders]) section is a detailed description of sliders use.