home *** CD-ROM | disk | FTP | other *** search
/ 17 Bit Software 3: The Continuation / 17-Bit_The_Continuation_Disc.iso / files / nz18.dms / nz18.adf / Prop.Gadgets / PropDemo.c < prev    next >
C/C++ Source or Header  |  1993-12-03  |  19KB  |  459 lines

  1. /*
  2.  | PropDemo.c :  Experimenting with proportional gadgets
  3.  |               Written 11/88 by Mike Christie
  4.  |
  5.  |     *** This is a Public Domain program, use it as you wish! ***
  6.  |
  7.  | This program is a fairly straight-forward example of using a vertical
  8.  | proportional gadget as used in applications such as word-processors.
  9.  | As well as using the normal Intuition-supplied proportional gadget,
  10.  | I also created two image gadgets, (the scroll-up and scroll-down arrows 
  11.  | above and below the proportional slider gagdet.) which scrolls one line
  12.  | at a time as opposed to the gadget 'slider' which scrolls by pages.
  13.  | When you start experimenting with the gadgets you will get the following
  14.  | diagnostics displayed as the window title:
  15.  |   o VertPot  - The current position of the slider in the gadget box.  
  16.  |   o VertBody - The size of the slider gadget in relation to the entire
  17.  |                slider box.
  18.  |   o First    - First line of text on screen.
  19.  |   o Last     - Last text line on screen.
  20.  |
  21.  | I have tried to made this demo program as simple as possible so it
  22.  | is understandable to someone trying to nut out proporiotnal gadgets
  23.  | for the first time.  WARNING: Trying to use Intuition in your programs
  24.  | without the aid of an Intuition manual is a serious health risk!!
  25.  | 
  26.  | USAGE: PropDemo <Max Lines> <Page Size>
  27.  | There are two optional command line arguments with this program. 
  28.  | If we liken it to a word-processor then the first argument determines the
  29.  | number of lines in the document.  This can be between 2 and 1000 but will
  30.  | default to 100 if either an invalid number or no argument is supplied
  31.  | The second argument specifies how many lines of text to display on the 
  32.  | screen each time the 'slider' is clicked or dragged. (eg: 'Page size' in 
  33.  | our theoretical word-processor).  This argument should be between 1 and
  34.  | 30 and will default to 20.
  35.  | To get a better idea of these arguments, try running the program the 
  36.  | first time with no arguments.
  37.  |
  38.  | PropDemo.c was compiled under Lattice V4.0 using 
  39.  | 'lc -Lcdn -ccw -v -oRAM: ram:PropDemo.c'
  40.  | If you have any FAST ram (expansion memory) then you will need to run 
  41.  | FixHunk over the executable, so the image data will load into CHIP ram
  42.  | at execution time. (Remember the graphics chip can only access 512K.)
  43.  |
  44.  | If you have any questions (or criticisms?) you can drop me a line or 
  45.  | give me a ring.  My address and phone number (no modem sorry!) is:
  46.  |    Mike Christie
  47.  |    25 Oak Avenue
  48.  |    Paremata  (Wellington)
  49.  |    Phone 331-651 (After 6PM)
  50. */
  51.  
  52. #include "stdio.h"
  53. #include "string.h"
  54. #include "exec/types.h"
  55. #include "graphics/gfxbase.h"
  56. #include "graphics/text.h"
  57. #include "intuition/intuition.h"
  58.  
  59. struct Window        *OpenWindow();
  60. struct IntuiMessage  *GetMsg();
  61.  
  62. /* Gadget I.D's.  When you use a gadget, Intuition returns the gadget 
  63.    number in the Intuition message. */
  64. #define  PROP_GADG    1
  65. #define  SCROLL_UP    2
  66. #define  SCROLL_DOWN  3
  67.  
  68. /* This is the data which makes up the up- and down-arrow imagery */
  69. USHORT UpArrowData[] = {
  70.    0xFFFF,
  71.    0xFE7F,
  72.    0xF81F,
  73.    0xE007,
  74.    0xC003,
  75.    0xFC3F,
  76.    0xFC3F,
  77.    0xFC3F,
  78.    0xFC3F,
  79.    0xFC3F,
  80.    0xFC3F,
  81.    0xFFFF  };
  82.    
  83. USHORT DownArrowData[] = {
  84.    0xFFFF,
  85.    0xFC3F,
  86.    0xFC3F,
  87.    0xFC3F,
  88.    0xFC3F,
  89.    0xFC3F,
  90.    0xFC3F,
  91.    0xC003,
  92.    0xE007,
  93.    0xF81F,
  94.    0xFE7F,
  95.    0xFFFF   
  96. };
  97.    
  98. /* 
  99.  | This structure holds the initial values for the proportional gadget.
  100.  | AUTOKNOB specifies that Intuition is to supply the entire gadget.  
  101.  | FREEVERT tells Intuition to allow free vertical sliding of the gadget.
  102.  | HorizPot and VertPot are given values once MaxLines & PageSize are set.
  103.  | HorizBody is always 0 for vertical proportional gadgets, and VertBody is
  104.  | set to 0xffff (decimal 65535) to represent the gadget's total size. 
  105. */
  106. struct PropInfo PropGadgSInfo = {
  107.    AUTOKNOB + FREEVERT,                /* Flags                 */
  108.    0, 0,                               /* HorizPot, VertPot     */
  109.    0, 0xffff                           /* HorizBody, VertBody   */
  110. };
  111.  
  112. /*
  113.  | This is the image of the 'slider' gagdet.  
  114.  | Note that the 'pointer to ImageData' is null, this is because we are
  115.  | asking Intuition to supply it's standard proportional gadget.  If we 
  116.  | use our own image for the slider, then this field would point to the
  117.  | 'Image' structure and the AUTOKNOB flag in the PropInfo structure 
  118.  | (above) would be omitted.
  119. */
  120. struct Image PropImage = {
  121.    0, 0,                               /* XY origin             */
  122.    7, 45,                              /* Image width & height  */
  123.    0,                                  /* No. of bitplanes      */
  124.    NULL,                               /* pointer to ImageData  */
  125.    0x0000, 0x0000,                     /* PlanePick, PlaneOnOff */
  126.    NULL                                /* Next image structure  */
  127. };
  128.  
  129. /*
  130.  | These two structures below tell Intuition to create gadgets using my
  131.  | own custom images, and the 'pointer to ImageData' is therefore
  132.  | appropriately set to point to the data which makes up the image.
  133. */
  134. struct Image UpArrow = {
  135.    0, 0,                               /* XY origin             */
  136.    16, 12,                             /* Image width & height  */
  137.    1,                                  /* No. of bitplanes      */
  138.    &UpArrowData[0],                    /* pointer to ImageData  */
  139.    0x0001, 0x0000,                     /* PlanePick, PlaneOnOff */
  140.    NULL                                /* Next image structure  */
  141. };
  142.  
  143. struct Image DownArrow = {
  144.    0, 0,                               /* XY origin             */
  145.    16, 12,                             /* Image width & height  */
  146.    1,                                  /* No. of bitplanes      */
  147.    &DownArrowData[0],                  /* pointer to ImageData  */
  148.    0x0001, 0x0000,                     /* PlanePick, PlaneOnOff */
  149.    NULL                                /* Next image structure  */
  150. };
  151.  
  152. /* 
  153.  | This is the main proportional gadget structure.
  154.  | The GRELRIGHT & GRELHEIGHT flags specify that the proportional gadget
  155.  | is sized in relation to the right side of the window, and to the height
  156.  | of the window.  So, if the window is resized in either width or height 
  157.  | the gadget will resize itself accordingly and even adjust the slider
  158.  | size so it still represents the correct amount of data!
  159.  | Because the gadget is sized this way, the LeftEdge field has a value of
  160.  | -15 which means the gadget slider box always starts 15 pixels from the
  161.  | right edge of the screen.  The same goes for the Height. ie: The gadget
  162.  | is always 45 pixels shorter than the window height.  (Try running the
  163.  | program and resizing the window to see what I mean.)
  164. */
  165. struct Gadget PropGadg = {
  166.    NULL,                               /* No next gadget             */
  167.    -15, 23,                            /* LeftEdge, TopEdge          */
  168.    16, -45,                            /* hit box width and height   */
  169.    GADGHCOMP + GRELRIGHT + GRELHEIGHT, /* gadget flags               */
  170.    RELVERIFY + GADGIMMEDIATE,          /* other flags                */
  171.    PROPGADGET,                         /* gadget type (Proporiotnal) */
  172.    (APTR)&PropImage,                   /* gadget border/image        */ 
  173.    NULL,                               /* alternate imagery          */
  174.    NULL,                               /* first IntuiText structure  */
  175.    NULL,                               /* gadget mutual-exclude      */
  176.    (APTR)&PropGadgSInfo,               /* SpecialInfo structure      */
  177.    PROP_GADG,                          /* gadget number as #define'd */
  178.    NULL                                /* pointer to user data       */
  179. };
  180.  
  181. /* Gadget to scroll down by one line */
  182. struct Gadget ScrollDown = {
  183.    &PropGadg,                          /* next gadget                */
  184.    -15, -21,                           /* LeftEdge, TopEdge          */
  185.    16, 12,                             /* hit box width and height   */
  186.    GADGIMAGE + GRELRIGHT + GRELBOTTOM, /* gadget flags               */
  187.    RELVERIFY + GADGIMMEDIATE,          /* other flags                */
  188.    BOOLGADGET,                         /* gadget type                */
  189.    (APTR)&DownArrow,                   /* gadget border/image        */ 
  190.    NULL,                               /* alternate imagery          */
  191.    NULL,                               /* first IntuiText structure  */
  192.    NULL,                               /* gadget mutual-exclude      */
  193.    NULL,                               /* SpecialInfo structure      */
  194.    SCROLL_DOWN,                        /* user-defined gadget number */
  195.    NULL                                /* pointer to user data       */
  196. };
  197.  
  198. /* Gadget to scroll up by one line */
  199. struct Gadget ScrollUp = {
  200.    &ScrollDown,                        /* next gadget                */
  201.    -15, 11,                            /* LeftEdge, TopEdge          */
  202.    16, 12,                             /* hit box width and height   */
  203.    GADGIMAGE + GRELRIGHT,              /* gadget flags               */
  204.    RELVERIFY + GADGIMMEDIATE,          /* other flags                */
  205.    BOOLGADGET,                         /* gadget type                */
  206.    (APTR)&UpArrow,                     /* gadget border/image        */ 
  207.    NULL,                               /* alternate imagery          */
  208.    NULL,                               /* first IntuiText structure  */
  209.    NULL,                               /* gadget mutual-exclude      */
  210.    NULL,                               /* SpecialInfo structure      */
  211.    SCROLL_UP,                          /* user-defined gadget number */
  212.    NULL                                /* pointer to user data       */
  213. };
  214.  
  215.  
  216. struct NewWindow newwindow = {
  217.    0, 0,                               /* LeftEdge, TopEdge        */
  218.    640, 255,                           /* window width and height  */
  219.    0, 1,                               /* detail and block pens    */
  220.    REFRESHWINDOW + MOUSEBUTTONS + GADGETUP + GADGETDOWN + CLOSEWINDOW,
  221.    WINDOWSIZING + WINDOWDRAG + WINDOWDEPTH + WINDOWCLOSE + SMART_REFRESH +
  222.    SIZEBBOTTOM + ACTIVATE,             /* other window flags       */
  223.    &ScrollUp,                          /* first gadget             */
  224.    NULL,                               /* custom CHECKMARK imagery */
  225.    " Proportional Gadget Demo by Mike Christie ",       /* window name     */
  226.    NULL,                               /* custom screen            */
  227.    NULL,                               /* custom bitmap            */
  228.    125, 50,                            /* minimum width and height */
  229.    640, 255,                           /* maximum width and height */
  230.    WBENCHSCREEN                        /* destination screen type  */
  231. };
  232.  
  233. struct Window         *window;
  234. struct GfxBase        *GfxBase;
  235. struct IntuitionBase  *IntuitionBase;
  236.  
  237. #define  rp  window->RPort             /* Define RastPort             */
  238.  
  239. char   data[1000][15];                 /* Array to hold text          */ 
  240. char   title[60];                      /* Title for SetWindowTitles() */
  241. SHORT  first, last, i;
  242. int    MaxLines = 100, PageSize = 20;  /* Command line argument defaults */
  243.  
  244. /* Display a line of text in the window */ 
  245. Display(x, y, text)
  246. USHORT x, y;
  247. char *text;
  248. {
  249.    Move(rp, x, y);                     /* Move to x,y pixel position  */
  250.    Text(rp, text, strlen(text));       /* Put the text here...        */
  251. }
  252.  
  253. /* Display a page of data on the window */
  254. show_text(start, finish)
  255. SHORT start, finish;
  256. {
  257.    int y = 20;          /* y position in window for first line of text */
  258.  
  259.    for (i = first; i < (last+1); i++, y+=8)
  260.       Display(10, y, data[i]);
  261. }
  262.  
  263.  
  264. /* ------------------------ MAINLINE -----------------------*/
  265. main(argc, argv)
  266. int  argc;
  267. char **argv;
  268. {
  269.    struct  IntuiMessage *message;      /* Message which Intuition returns */
  270.    ULONG   Mclass;                     /* Class of message     */
  271.    USHORT  Mcode;                      /* Message identifier   */
  272.    SHORT   Mmx, Mmy;                   /* mouse x & y position */
  273.    int     len = 0;                    /* return from stcd_i   */
  274.    char    buf[10];
  275.  
  276.    /* argv[1]: Number of text lines (1 - 1000) or default to 100 */
  277.    if (argv[1])
  278.    {
  279.       /* stcd_i() converts an ascii numeric string to an integer */
  280.       len = stcd_i(argv[1], &MaxLines);
  281.       if (MaxLines < 1 || MaxLines > 1000)
  282.          MaxLines = 100; 
  283.    }
  284.  
  285.    /* argv[2]: Number of text lines per screen (1 - 30), default to 20 */ 
  286.    if (argv[2])
  287.    {
  288.       len = stcd_i(argv[2], &PageSize);
  289.       if (PageSize < 2 || PageSize > 30)
  290.          PageSize = 20;
  291.    }
  292.  
  293.    if (MaxLines < PageSize)
  294.       Cleanup("PageSize must be less than MaxLines\n");
  295.  
  296.    /* Open graphics and Intuition libraries */
  297.    GfxBase = (struct GfxBase *) OpenLibrary("graphics.library",1);
  298.    if (GfxBase == NULL)
  299.       Cleanup("Can't open graphics.library\n");
  300.  
  301.    IntuitionBase = (struct IntutionBase *) OpenLibrary("intuition.library",1);
  302.    if (IntuitionBase == NULL)
  303.       Cleanup("Can't open intuition.library\n");
  304.  
  305.    /* Attempt to open window */
  306.    window = (OpenWindow(&newwindow));
  307.    if (window == NULL)
  308.       Cleanup("Can't open window\n");
  309.  
  310.    SetAPen(rp, 1);                     /* Foreground pen */
  311.  
  312.    sprintf(title, " MaxLines: %d, PageSize: %d ",MaxLines,PageSize);
  313.    SetWindowTitles(window, title, -1);
  314.  
  315.    /* fill text array to use as data */
  316.    for (i = 0; i < MaxLines; i++)
  317.       sprintf(data[i], "record # %3d",i);
  318.  
  319.    /* Set the size of the slider so it represents one page 
  320.       of text (PageSize lines) out of the total text (MaxLines). 
  321.       Note that the total size of the gadget is always 65535 (Hex FFFF). */     
  322.    PropGadgSInfo.VertBody = 0xffff/(MaxLines/PageSize);
  323.    ModifyProp(&PropGadg, window, NULL, PropGadgSInfo.Flags,
  324.               PropGadgSInfo.HorizPot,  PropGadgSInfo.VertPot, 
  325.               PropGadgSInfo.HorizBody, PropGadgSInfo.VertBody);
  326.  
  327.    first = 0;              
  328.    last = PageSize - 1; 
  329.    show_text(first, last);             /* Display first page to begin */
  330.  
  331.    /* Start a loop which polls for Intuition 'messages' (eg: when gadget
  332.       is selected.)  Loop is terminated when user hits close-window gadget. */
  333.    for(;;)
  334.    {
  335.       Wait ( 1 << window->UserPort->mp_SigBit);
  336.       while (message = GetMsg(window->UserPort))
  337.       {
  338.          Mclass = message->Class;
  339.          Mcode  = message->Code;
  340.          Mmx    = message->MouseX;
  341.          Mmy    = message->MouseY;
  342.          ReplyMsg(message);    /* Tell Intuition we have received the message 
  343.                                   so it can wait for the next one. */
  344.                                   
  345.          /* Intuition only sends messages to us for events declared in the
  346.             'Intuition flags' in the window structure.   */
  347.          switch(Mclass)
  348.          {
  349.             case CLOSEWINDOW:          /* User has hit close-window gadget */
  350.                Cleanup(NULL);
  351.                break;
  352.                    
  353.             case GADGETUP:             /* Proportional gadget selected     */
  354.                do_gadgets(message, window);
  355.                break;
  356.          }
  357.       }
  358.    }
  359. }
  360.  
  361. /* 
  362.  | This routine handles the gadgets. (updating, resizing etc) 
  363.  | Note that I am sending the address of the window where the gadget
  364.  | resides to the routine.  This is not really necessary unless you have 
  365.  | opened multiple windows in your application.
  366. */
  367. do_gadgets(message, window)
  368. struct IntuiMessage *message;
  369. struct Window       *window;
  370. {
  371.    struct Gadget *igad;
  372.    USHORT gadget_ID;
  373.    LONG   vp, vb;                      /* VertPot & VertBody */ 
  374.  
  375.    /* Get the ID of the selected gadget from the Intuition message */
  376.    igad = (struct Gadget *)message->IAddress;
  377.    gadget_ID = igad->GadgetID;
  378.  
  379.    switch (gadget_ID)
  380.    {
  381.       case PROP_GADG:
  382.          /* Get the current 'slider' position */
  383.          vp = PropGadgSInfo.VertPot;
  384.          vb = PropGadgSInfo.VertBody;
  385.          
  386.          /* Calculate the first and last lines of text to display 
  387.             on screen in relation to the 'slider' position.       */
  388.          first = ((MaxLines - PageSize) * vp) / 0xffff;
  389.          last  = first + PageSize - 1; 
  390.  
  391.          /* Display current gadget variables */
  392.          sprintf(title, " VertPot: %d, VertBody: %d, First: %d, Last: %d ",
  393.                           vp, vb, first, last);
  394.          SetWindowTitles(window, title, -1);
  395.  
  396.          /* Display the relevant page of text on screen */
  397.          show_text(first, last);
  398.          break;
  399.  
  400.       case SCROLL_UP:                  /* Scroll text up one line */
  401.          if (first > 0)
  402.             first--;
  403.          else
  404.             first = 0;                
  405.          last = first + (PageSize - 1);
  406.          
  407.          /* Calculate and set the current slider position */
  408.          vp = (first * 0xffff) / (MaxLines - PageSize);
  409.          PropGadgSInfo.VertPot = vp;
  410.          vb = PropGadgSInfo.VertBody;         
  411.  
  412.          sprintf(title, " VertPot: %d, VertBody: %d, First: %d, Last: %d ",
  413.                           vp, vb, first, last);
  414.          SetWindowTitles(window, title, -1);
  415.          show_text(first, last);
  416.  
  417.          /* Modify the gadget so the slider is at the right place */
  418.          ModifyProp(&PropGadg, window, NULL, PropGadgSInfo.Flags,
  419.                      PropGadgSInfo.HorizPot,  PropGadgSInfo.VertPot, 
  420.                      PropGadgSInfo.HorizBody, PropGadgSInfo.VertBody);
  421.          break;
  422.  
  423.       case SCROLL_DOWN:                /* Scroll text down one line      */
  424.          if (last >= MaxLines-1)       /* Ensure we don't scroll too far */
  425.             last = MaxLines - 1;
  426.          else
  427.             last++;
  428.          first = last - (PageSize - 1);
  429.          
  430.          /* Calculate the slider position in relation to 'first' */
  431.          vp = (first * 0xffff) / (MaxLines - PageSize);
  432.          PropGadgSInfo.VertPot = vp;
  433.          vb = PropGadgSInfo.VertBody;
  434.  
  435.          sprintf(title, " VertPot: %d, VertBody: %d, First: %d, Last: %d ",
  436.                           vp, vb, first, last);
  437.          SetWindowTitles(window, title, -1);
  438.          show_text(first, last);
  439.          ModifyProp(&PropGadg, window, NULL, PropGadgSInfo.Flags,
  440.                      PropGadgSInfo.HorizPot,  PropGadgSInfo.VertPot, 
  441.                      PropGadgSInfo.HorizBody, PropGadgSInfo.VertBody);
  442.          break;
  443.    }
  444. }
  445.  
  446.  
  447. Cleanup(exit_text)
  448. char *exit_text;
  449. {
  450.    if (window)         CloseWindow(window);
  451.    if (GfxBase)        CloseLibrary(GfxBase);  
  452.    if (IntuitionBase)  CloseLibrary(IntuitionBase);
  453.    if (exit_text)
  454.       puts(exit_text);
  455.    exit(0);
  456. }
  457.  
  458. void MemCleanup() {}
  459.