home *** CD-ROM | disk | FTP | other *** search
/ ARM Club 1 / ARM_CLUB_CD.iso / contents / apps / languages / progs / shell / Sources / c / GFX < prev    next >
Encoding:
Text File  |  1994-06-25  |  7.8 KB  |  337 lines

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <time.h>
  4.  
  5. #include "DeskLib:GFX.h"
  6. #include "DeskLib:Coord.h"
  7. #include "DeskLib:WimpSWIs.h"
  8. #include "DeskLib:Error.h"
  9. #include "DeskLib:Window.h"
  10. #include "DeskLib:Event.h"
  11.  
  12. #include "Shell.Extra.h"
  13. #include "Shell.SafeAlloc.h"
  14. #include "Shell.PlotIcon.h"
  15. #include "Shell.Redraw2.h"
  16.  
  17.  
  18.  
  19. Shell_windblock    Shell_windows[ Shell_MAXWINDS];
  20. int Shell_numwinds = 0;
  21.  
  22.  
  23.  
  24.  
  25.  
  26.  
  27.  
  28.  
  29. void Shell_WindRedraw2( wimp_rect *workrect, Shell_convertpoint convert, Shell_windblock *wind)
  30.     /* This takes a workarea rectangle and redraws     */
  31.     /* any shell-rectangles in Shell window 'wind'    */
  32.     /* which overlap with it.            */
  33. {
  34. Shell_rectblock *rectblock;
  35.  
  36. for    (
  37.     rectblock = LinkList_FirstItem( &wind->anchor);
  38.     rectblock;
  39.     rectblock = LinkList_NextItem( &rectblock->header)
  40.     )
  41.  
  42.     {
  43.     if ( rectblock->plot_icon)    {
  44.         /* The rect should be plotted as an icon - e.g. for a border, and a     */
  45.         /* background colour. Also, we will set the grapics colour to the icon    */
  46.         /* foreground colour here.                        */
  47.  
  48.         if ( Coord_RectsOverlap( workrect, &rectblock->icon.workarearect))
  49.             Shell_PlotIcon( &rectblock->icon, convert);
  50.             /* Shell_PlotIcon is identical to Wimp_PlotIcon, but         */
  51.             /* only sends 16 bit coors to Wimp_PlotIcon, so arbitarily    */
  52.             /* sized icons can be plotted                    */
  53.  
  54.         Wimp_SetColour( rectblock->icon.flags.data.foreground);
  55.  
  56.         }
  57.  
  58.     if ( Coord_RectsOverlap( workrect, &rectblock->rect))    {
  59.  
  60.         /* Set things up so the redrawer only has to work in coors relative     */
  61.         /* to this rectblock's origin.                        */
  62.  
  63.         Shell_convertpoint    localconvert;
  64.         wimp_rect        localredrawrect;
  65.         wimp_point        localsize;
  66.  
  67.         localsize.x = rectblock->rect.max.x - rectblock->rect.min.x;
  68.         localsize.y = rectblock->rect.max.y - rectblock->rect.min.y;
  69.  
  70.         localconvert.x = convert.x + rectblock->rect.min.x;
  71.         localconvert.y = convert.y + rectblock->rect.min.y;
  72.  
  73.         localredrawrect.min.x = workrect->min.x - rectblock->rect.min.x;
  74.         localredrawrect.max.x = workrect->max.x - rectblock->rect.min.x;
  75.         localredrawrect.min.y = workrect->min.y - rectblock->rect.min.y;
  76.         localredrawrect.max.y = workrect->max.y - rectblock->rect.min.y;
  77.  
  78.         (*rectblock->redrawer)
  79.             (
  80.             localconvert,
  81.             localsize,
  82.             rectblock->reference,
  83.             &localredrawrect
  84.             );
  85.         }
  86.     }
  87.  
  88. return;
  89.        }
  90.  
  91.  
  92.  
  93.  
  94.  
  95.  
  96.  
  97.  
  98.  
  99.  
  100.  
  101.  
  102.  
  103.  
  104. static BOOL    Shell_WindRedraw( event_pollblock *event, void *reference)
  105.  
  106. {    Shell_windblock        *info    = (Shell_windblock *) reference;
  107.     Shell_convertpoint    convert;
  108.     wimp_rect        workrect;
  109.     window_redrawblock    redrawblock;
  110.     BOOL            more;
  111.  
  112. redrawblock.window = event->data.openblock.window;
  113. Wimp_RedrawWindow( &redrawblock, &more);
  114.  
  115. convert.x = redrawblock.rect.min.x - redrawblock.scroll.x;
  116. convert.y = redrawblock.rect.max.y - redrawblock.scroll.y;
  117.  
  118. for    (
  119.     ;
  120.     more;
  121.     Wimp_GetRectangle( &redrawblock, &more)
  122.     )
  123.  
  124.     {
  125.     workrect = redrawblock.cliprect;
  126.     Shell_ConvertRectToWorkarea( &workrect, convert);
  127.  
  128.     Shell_WindRedraw2( &workrect, convert, info);
  129.         /* Most of the work is in this separate fn so that it can be called     */
  130.         /* independantly within a fn which temporaraly redirects output to a     */
  131.         /* sprite - see PlainRect.c                        */
  132.  
  133.     }
  134.  
  135. return TRUE;
  136. }
  137.  
  138.  
  139.  
  140.  
  141.  
  142.  
  143.  
  144.  
  145.  
  146. Shell_windblock    *Shell_OpenWindow( void)
  147. {
  148.     Shell_windblock    *info;
  149.  
  150. if ( Shell_numwinds == Shell_MAXWINDS) Error_ReportFatal( 1, Error_PLACE "Too many GFX windows");
  151.     /* Should change the window storage to use a linked list (like each window's rect-list.    */
  152.  
  153. Shell_numwinds++;
  154. info = &Shell_windows[Shell_numwinds-1];
  155. info->window = Window_CreateAndShow( "ShellWindow", /*maxtitlesize*/ 0, open_NEARLAST);
  156.  
  157. if ( info->window == 0)
  158.     Error_ReportFatal( 0, Error_PLACE "Shell_OpenGFXWindow -couldn't find 'ShellWindow' in templates");
  159.     /* This error-detection doesn't work - Window_CreateShow returns a non-zero window    */
  160.     /* handle even if the templates don't have the window. This can cause problems!        */
  161.  
  162. info->numrects = 0;
  163. LinkList_Init( &info->anchor);
  164.  
  165. Event_Claim( event_REDRAW, info->window, event_ANY, Shell_WindRedraw, (void *) info);
  166.  
  167. return info;
  168. }
  169.  
  170.  
  171.  
  172.  
  173.  
  174.  
  175.  
  176. Shell_rectblock    *Shell_AddRectangle(
  177.     Shell_windblock    *w,
  178.     const wimp_rect    *rect,
  179.     Shell_redrawer    redrawfn,
  180.     const void    *reference
  181.     )
  182. /* This creates a 'plain' rectangle in a window - it has no border, and the background colour    */
  183. /* will be the same as the background of the window. To give the rect a border and back/fore-    */
  184. /* colours, use Shell_MakeRectIcon.                                */
  185.  
  186. {
  187.     Shell_rectblock    *r;
  188.  
  189. if ( (w-Shell_windows >= Shell_MAXWINDS) || (w-Shell_windows < 0))
  190.     Error_ReportFatal( 1, Error_PLACE "Invalid Shell_windblock in Shell_AddRectangle, '%p'", w);
  191.  
  192. w->numrects++;
  193. r = Shell_SafeMalloc( sizeof( Shell_rectblock));
  194. LinkList_AddToTail( &w->anchor, &r->header);
  195.  
  196. r->update_time        = 0;        /* minimum time between rect redraws        */
  197. r->last_update        = 0;
  198. r->rect            = *rect;    /* rectangle which encloses the rect's data    */
  199. r->icon.workarearect    = *rect;    /* border around the rect.            */
  200. r->redrawer        = redrawfn;
  201. r->saver        = NULL;        /* NULL or a valid rect saver            */
  202. r->ramsaver        = NULL;        /* NULL or a valid rect ramsaver        */
  203. r->filetype        = 0xfff;    /* Default filetype is text.            */
  204. r->reference        = (void *) reference;
  205. r->window        = w->window;
  206. r->plot_icon        = FALSE;    /* This is a plain rect.            */
  207.  
  208.  
  209. Shell_CheckWindSizeAndRedraw( w->window, &r->rect);
  210.     /* This resizes the window if nesesary so that it contains the     */
  211.     /* rectangle. Hence the window automatically expands to contain    */
  212.     /* any rects added to it.                    */
  213.  
  214. return r;
  215. }
  216.  
  217.  
  218.  
  219.  
  220.  
  221. Shell_rectblock    *Shell_AddRectangle2(
  222.     Shell_windblock *w,
  223.     int xmin, int ymin, int xmax, int ymax,
  224.     Shell_redrawer redrawfn,
  225.     const void *reference
  226.     )
  227. {
  228.     wimp_rect rect;
  229.  
  230. rect.min.x = xmin; rect.min.y = ymin;
  231. rect.max.x = xmax; rect.max.y = ymax;
  232. return Shell_AddRectangle( w, &rect, redrawfn, reference);
  233. }
  234.  
  235.  
  236.  
  237.  
  238. Shell_rectblock    *Shell_AddRectangle3(
  239.     Shell_windblock *w,
  240.     int xmin, int ymin,
  241.     int xsize, int ysize,
  242.     Shell_redrawer redrawfn,
  243.     const void *reference
  244.     )
  245. {
  246.     wimp_rect rect;
  247.  
  248. rect.min.x = xmin;    rect.max.x = xmin + xsize;
  249. rect.min.y = ymin;    rect.max.y = ymin + ysize;
  250. return Shell_AddRectangle( w, &rect, redrawfn, reference);
  251. }
  252.  
  253.  
  254.  
  255.  
  256.  
  257.  
  258. void    Shell_ForceRectRedraw( Shell_rectblock *r)
  259. {    window_redrawblock block;
  260. r->last_update    = clock();
  261. block.window    = r->window;
  262. block.rect    = r->rect;
  263. Wimp_ForceRedraw( &block);    /* The actual redraw will be done when the Wimp sends     */
  264.                 /* event_REDRAW on the next Shell/Event_Poll.        */
  265. return;
  266. }
  267.  
  268.  
  269. void    Shell_ForceRectRedrawSlow( Shell_rectblock *r)
  270. /*    This only ForceRedraws a rectangle if the    */
  271. /*    last redraw was a sufficiently long time ago    */
  272. {
  273.     clock_t    t    = clock();
  274. if ( t - r->last_update >= r->update_time)    {
  275.     r->last_update    = t;
  276.     Shell_ForceRectRedraw( r);
  277.     }
  278. return;
  279. }
  280.  
  281.  
  282.  
  283.  
  284.  
  285. void Shell_ForceRectUpdate( Shell_rectblock *r)
  286. /*    This routine redraws a rectangle without clearing it    */
  287. /*    to the background colour. Use for animation etc.    */
  288. /*    The redraw loop occurs imediately, without polling    */
  289. /*    the Wimp.                        */
  290. {
  291.     window_redrawblock    redrawblock;
  292.     Shell_convertpoint    convert;
  293.     wimp_rect        workrect;
  294.     BOOL            more;
  295.     wimp_point        rectsize;
  296.  
  297. rectsize.x = r->rect.max.x - r->rect.min.x;
  298. rectsize.y = r->rect.max.y - r->rect.min.y;
  299.  
  300. redrawblock.window    = r->window;
  301. redrawblock.rect    = r->rect;
  302.  
  303. Wimp_UpdateWindow( &redrawblock, &more);
  304.  
  305. convert.x = redrawblock.rect.min.x - redrawblock.scroll.x + r->rect.min.x;
  306. convert.y = redrawblock.rect.max.y - redrawblock.scroll.y + r->rect.min.y;
  307.  
  308.  
  309. for    (
  310.     ;
  311.     more;
  312.     Wimp_GetRectangle( &redrawblock, &more)
  313.     )
  314.  
  315.     {
  316.     workrect.max.x = redrawblock.cliprect.max.x - convert.x;
  317.     workrect.min.x = redrawblock.cliprect.min.x - convert.x;
  318.     workrect.max.y = redrawblock.cliprect.max.y - convert.y;
  319.     workrect.min.y = redrawblock.cliprect.min.y - convert.y;
  320.  
  321.     ( *(r->redrawer) ) ( convert, rectsize, r->reference, &workrect);
  322.     /* Call the redrawing function for the rectangle */
  323.  
  324.     }
  325. }
  326.  
  327.  
  328.  
  329.  
  330.  
  331. void Shell_SetWindowTitle( window_handle window, char *text)
  332.     /* There used to be code here, but DeskLib 2.04 has a function built in which actually    */
  333.     /* works properly!                                    */
  334. {
  335. Window_SetTitle( window, text);
  336. }
  337.