home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 324.lha / Gone / gone.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-12-12  |  22.6 KB  |  608 lines

  1. /*      GONE WITH THE WINDOWS
  2.  
  3.         by Melissa Jordan Grey and Todor Fay
  4.  
  5.         (c) 1989 Blue Ribbon Bakery
  6.  
  7.     Compile with Lattice or Aztec...
  8.     Lattice: link with _main.o to avoid the extra console window
  9.     Aztec: cc +L gone.c
  10.            ln +C gone.o -lc32
  11.            also make IntuitionBase global not extern! (see note below)
  12. */
  13. #include <intuition/intuition.h>
  14. #include <intuition/intuitionbase.h>
  15. #include <graphics/gfxmacros.h>
  16. #include <devices/input.h>
  17. #include <devices/inputevent.h>
  18.  
  19. /* Power Windows generated definition of main window. */
  20. static USHORT wImageData1[] = {
  21.         0xFFFF,0xFFF9,0xFFFF,0xFFFF,0xFFFF,0xFFCF,0xFFFF,0xFF80,
  22.         0xFFFF,0xFFF9,0xFFFF,0xFFFF,0xFFFF,0xFFCF,0xFFFF,0xFF80,
  23.         0xC000,0x0019,0x8004,0x003E,0x0010,0x80CC,0x0000,0x0180,
  24.         0xFFFF,0xFFF9,0x8004,0x103E,0x0410,0x00CF,0xFFFF,0xFF80,
  25.         0xC000,0x0019,0x8844,0x003E,0x0010,0x00CC,0x0000,0x0180,
  26.         0xFFFF,0xFFF9,0x8004,0x00BE,0x7F90,0x08CF,0xFFFF,0xFF80,
  27.         0xC000,0x0019,0x8084,0x003E,0x1FD0,0x00CC,0x0000,0x0180,
  28.         0xFFFF,0xFFF9,0x8004,0x103E,0x07D7,0x00CF,0xFFFF,0xFF80,
  29.         0xC000,0x0019,0x8004,0x003E,0x03D7,0xC0CC,0x0000,0x0180,
  30.         0xFFFF,0xFFF9,0x8004,0x003E,0x0010,0x00CF,0xFFFF,0xFF80,
  31.         0xC000,0x0019,0xFFFF,0xFFFF,0xFFFF,0xFFCC,0x0000,0x0180,
  32.         0xFFFF,0xFFF9,0x8004,0x003E,0x0010,0x00CF,0xFFFF,0xFF80,
  33.         0xC000,0x0019,0x8024,0x00BE,0x0057,0xF8CC,0x0000,0x0180,
  34.         0xFFFF,0xFFF9,0x8004,0x203E,0x0057,0xFCCF,0xFFFF,0xFF80,
  35.         0xC000,0x0019,0x9004,0x003E,0x1057,0xFCCC,0x0000,0x0180,
  36.         0xFFFF,0xFFF9,0x8004,0x003E,0x0057,0xFCCF,0xFFFF,0xFF80,
  37.         0xC000,0x0019,0x8104,0x403E,0x0257,0xFCCC,0x0000,0x0180,
  38.         0xFFFF,0xFFF9,0x8004,0x003E,0x0057,0xF8CF,0xFFFF,0xFF80,
  39.         0xC000,0x0019,0x8004,0x013E,0x0010,0x00CC,0x0000,0x0180,
  40.         0xFFFF,0xFFF9,0xFFFF,0xFFFF,0xFFFF,0xFFCF,0xFFFF,0xFF80,
  41.         0xC000,0x0019,0x8004,0x003E,0x0010,0x00CC,0x0000,0x0180,
  42.         0xFFFF,0xFFF9,0x8085,0x003E,0x03D7,0xC0CF,0xFFFF,0xFF80,
  43.         0xC000,0x0019,0x8004,0x013E,0x07D7,0x08CC,0x0000,0x0180,
  44.         0xFFFF,0xFFF9,0x8404,0x003E,0x1FD0,0x00CF,0xFFFF,0xFF80,
  45.         0xC000,0x0019,0x8004,0x003E,0x7F90,0x00CC,0x0000,0x0180,
  46.         0xFFFF,0xFFF9,0x8404,0x043E,0x0011,0x08CF,0xFFFF,0xFF80,
  47.         0xC000,0x0019,0x8024,0x403E,0x0010,0x00CC,0x0000,0x0180,
  48.         0xFFFF,0xFFF9,0x8004,0x003E,0x2010,0x00CF,0xFFFF,0xFF80,
  49.         0xC000,0x0019,0xFFFF,0xFFFF,0xFFFF,0xFFCC,0x0000,0x0180,
  50.         0xFFFF,0xFFF9,0xFFFF,0xFFFF,0xFFFF,0xFFCF,0xFFFF,0xFF80,
  51.         0xFFFF,0xFFF9,0xFFFF,0xFFFF,0xFFFF,0xFFCF,0xFFFF,0xFF80,
  52.         0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  53.         0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  54.         0x0000,0x0000,0x7FFB,0xFFC1,0xFFEF,0x7F00,0x0000,0x0000,
  55.         0x0000,0x0006,0x7FFB,0xEFC1,0xFBEF,0xFF30,0x0000,0x0000,
  56.         0x0000,0x0006,0x77BB,0xFFC1,0xFFEF,0xFF30,0x0000,0x0000,
  57.         0x0000,0x0000,0x7FFB,0xFF41,0x806F,0xF700,0x0000,0x0000,
  58.         0x0000,0x0000,0x7F7B,0xFFC1,0xE02F,0xFF00,0x0000,0x0000,
  59.         0x0000,0x0000,0x7FFB,0xEFC1,0xF828,0xFF00,0x0000,0x0000,
  60.         0x0000,0x0000,0x7FFB,0xFFC1,0xFC28,0x3F00,0x0000,0x0000,
  61.         0x0000,0x0000,0x7FFB,0xFFC1,0xFFEF,0xFF00,0x0000,0x0000,
  62.         0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  63.         0x0000,0x0000,0x7FFB,0xFFC1,0xFFEF,0xFF00,0x0000,0x0000,
  64.         0x0000,0x0000,0x7FDB,0xFF41,0xFFA8,0x0700,0x0000,0x0000,
  65.         0x0000,0x0000,0x7FFB,0xDFC1,0xFFA8,0x0300,0x0000,0x0000,
  66.         0x0000,0x0000,0x6FFB,0xFFC1,0xEFA8,0x0300,0x0000,0x0000,
  67.         0x0000,0x0000,0x7FFB,0xFFC1,0xFFA8,0x0300,0x0000,0x0000,
  68.         0x0000,0x0000,0x7EFB,0xBFC1,0xFDA8,0x0300,0x0000,0x0000,
  69.         0x0000,0x0000,0x7FFB,0xFFC1,0xFFA8,0x0700,0x0000,0x0000,
  70.         0x0000,0x0000,0x7FFB,0xFEC1,0xFFEF,0xFF00,0x0000,0x0000,
  71.         0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  72.         0x0000,0x0000,0x7FFB,0xFFC1,0xFFEF,0xFF00,0x0000,0x0000,
  73.         0x0000,0x0000,0x7F7A,0xFFC1,0xFC28,0x3F00,0x0000,0x0000,
  74.         0x0000,0x0000,0x7FFB,0xFEC1,0xF828,0xF700,0x0000,0x0000,
  75.         0x0000,0x0000,0x7BFB,0xFFC1,0xE02F,0xFF00,0x0000,0x0000,
  76.         0x0000,0x0000,0x7FFB,0xFFC1,0x806F,0xFF00,0x0000,0x0000,
  77.         0x0000,0x0006,0x7BFB,0xFBC1,0xFFEE,0xF730,0x0000,0x0000,
  78.         0x0000,0x0006,0x7FDB,0xBFC1,0xFFEF,0xFF30,0x0000,0x0000,
  79.         0x0000,0x0000,0x7FFB,0xFFC1,0xDFEF,0xFF00,0x0000,0x0000,
  80.         0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  81.         0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  82.         0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000
  83. };
  84.  
  85. static struct Image wImage1 = {
  86.         0,0,
  87.         121,31,
  88.         2,
  89.         wImageData1,
  90.         0x0003,0x0000,
  91.         NULL
  92. };
  93.  
  94. static struct Gadget wGadget2 = {
  95.         NULL,
  96.         148,15,
  97.         121,31,
  98.         GADGHBOX+GADGHIMAGE+GADGIMAGE,
  99.         RELVERIFY+GADGIMMEDIATE,
  100.         BOOLGADGET,
  101.         (APTR)&wImage1,
  102.         NULL,
  103.         NULL,
  104.         NULL,
  105.         NULL,
  106.         2,
  107.         NULL
  108. };
  109.  
  110. static USHORT wImageData2[] = {
  111.         0xFFFF,0xFFF9,0xFFFF,0xFFFF,0xFFFF,0xFFCF,0xFFFF,0xFF80,
  112.         0xFFFF,0xFFF9,0xFFFF,0xFFFF,0xFFFF,0xFFCF,0xFFFF,0xFF80,
  113.         0xC000,0x0019,0xFFFF,0xFE3E,0x0010,0x00CC,0x0000,0x0180,
  114.         0xFFFF,0xFFF9,0xFFFF,0xFE3F,0xFFFE,0x00CF,0xFFFF,0xFF80,
  115.         0xC000,0x0019,0xFFFF,0xFE3E,0x0010,0x00CC,0x0000,0x0180,
  116.         0xFFFF,0xFFF9,0xFFFF,0xFE3E,0x0010,0x00CF,0xFFFF,0xFF80,
  117.         0xC000,0x0019,0xFFFF,0xFC3F,0xFF90,0x00CC,0x0000,0x0180,
  118.         0xFFFF,0xFFF9,0xFFFF,0xFC3E,0x007E,0x00CF,0xFFFF,0xFF80,
  119.         0xC000,0x0019,0xFFFF,0xF83E,0x0010,0x00CC,0x0000,0x0180,
  120.         0xFFFF,0xFFF9,0xFFFF,0xE03F,0xF010,0x00CF,0xFFFF,0xFF80,
  121.         0xC000,0x0019,0xFFFF,0xFFFF,0xFFFF,0xFFCC,0x0000,0x0180,
  122.         0xFFFF,0xFFF9,0xFFFC,0x003E,0x0070,0x00CF,0xFFFF,0xFF80,
  123.         0xC000,0x0019,0xFFC4,0x003F,0xC010,0x00CC,0x0000,0x0180,
  124.         0xFFFF,0xFFF9,0x8004,0x0C3E,0x3810,0x00CF,0xFFFF,0xFF80,
  125.         0xC000,0x0019,0x8005,0x833E,0x0610,0x00CC,0x0000,0x0180,
  126.         0xFFFF,0xFFF9,0x9864,0xC0FE,0x0010,0x00CF,0xFFFF,0xFF80,
  127.         0xC000,0x0019,0x9864,0x603E,0x0010,0x00CC,0x0000,0x0180,
  128.         0xFFFF,0xFFF9,0x9834,0x303E,0x0010,0x00CF,0xFFFF,0xFF80,
  129.         0xC000,0x0019,0x9834,0x183E,0x0010,0x00CC,0x0000,0x0180,
  130.         0xFFFF,0xFFF9,0xFFFF,0xFFFF,0xFFFF,0xFFCF,0xFFFF,0xFF80,
  131.         0xC000,0x0019,0x981C,0x063E,0x0010,0x00CC,0x0000,0x0180,
  132.         0xFFFF,0xFFF9,0x980C,0x003E,0x0010,0x00CF,0xFFFF,0xFF80,
  133.         0xC000,0x0019,0x9804,0x003E,0x0010,0x00CC,0x0000,0x0180,
  134.         0xFFFF,0xFFF9,0x8004,0x003E,0x0010,0x00CF,0xFFFF,0xFF80,
  135.         0xC000,0x0019,0x8004,0x003E,0x0010,0x00CC,0x0000,0x0180,
  136.         0xFFFF,0xFFF9,0x8004,0x003E,0x0010,0x00CF,0xFFFF,0xFF80,
  137.         0xC000,0x0019,0x8004,0x003E,0x0010,0x00CC,0x0000,0x0180,
  138.         0xFFFF,0xFFF9,0x8004,0x003E,0x0010,0x00CF,0xFFFF,0xFF80,
  139.         0xC000,0x0019,0xFFFF,0xFFFF,0xFFFF,0xFFCC,0x0000,0x0180,
  140.         0xFFFF,0xFFF9,0xFFFF,0xFFFF,0xFFFF,0xFFCF,0xFFFF,0xFF80,
  141.         0xFFFF,0xFFF9,0xFFFF,0xFFFF,0xFFFF,0xFFCF,0xFFFF,0xFF80,
  142.         0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  143.         0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  144.         0x0000,0x0000,0x7FFB,0xFE00,0x0000,0x0000,0x0000,0x0000,
  145.         0x0000,0x0006,0x7FFB,0xFE01,0xFFEE,0x0030,0x0000,0x0000,
  146.         0x0000,0x0006,0x7FFB,0xFE00,0x0000,0x0030,0x0000,0x0000,
  147.         0x0000,0x0000,0x7FFB,0xFE00,0x0000,0x0000,0x0000,0x0000,
  148.         0x0000,0x0000,0x7FFB,0xFC01,0xFF80,0x0000,0x0000,0x0000,
  149.         0x0000,0x0000,0x7FFB,0xFC00,0x006E,0x0000,0x0000,0x0000,
  150.         0x0000,0x0000,0x7FFB,0xF800,0x0000,0x0000,0x0000,0x0000,
  151.         0x0000,0x0000,0x7FFB,0xE001,0xF000,0x0000,0x0000,0x0000,
  152.         0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  153.         0x0000,0x0000,0x7FF8,0x0000,0x0060,0x0000,0x0000,0x0000,
  154.         0x0000,0x0000,0x7FC0,0x0001,0xC000,0x0000,0x0000,0x0000,
  155.         0x0000,0x0000,0x0000,0x0C00,0x3800,0x0000,0x0000,0x0000,
  156.         0x0000,0x0000,0x0001,0x8300,0x0600,0x0000,0x0000,0x0000,
  157.         0x0000,0x0000,0x1860,0xC0C0,0x0000,0x0000,0x0000,0x0000,
  158.         0x0000,0x0000,0x1860,0x6000,0x0000,0x0000,0x0000,0x0000,
  159.         0x0000,0x0000,0x1830,0x3000,0x0000,0x0000,0x0000,0x0000,
  160.         0x0000,0x0000,0x1830,0x1800,0x0000,0x0000,0x0000,0x0000,
  161.         0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  162.         0x0000,0x0000,0x1818,0x0600,0x0000,0x0000,0x0000,0x0000,
  163.         0x0000,0x0000,0x1808,0x0000,0x0000,0x0000,0x0000,0x0000,
  164.         0x0000,0x0000,0x1800,0x0000,0x0000,0x0000,0x0000,0x0000,
  165.         0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  166.         0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  167.         0x0000,0x0006,0x0000,0x0000,0x0000,0x0030,0x0000,0x0000,
  168.         0x0000,0x0006,0x0000,0x0000,0x0000,0x0030,0x0000,0x0000,
  169.         0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  170.         0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  171.         0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  172.         0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000
  173. };
  174.  
  175. static struct Image wImage2 = {
  176.         0,0,
  177.         121,31,
  178.         2,
  179.         wImageData2,
  180.         0x0003,0x0000,
  181.         NULL
  182. };
  183.  
  184. static struct Gadget wGadget1 = {
  185.         &wGadget2,
  186.         16,15,
  187.         121,31,
  188.         GADGHBOX+GADGHIMAGE+GADGIMAGE,
  189.         RELVERIFY+GADGIMMEDIATE,
  190.         BOOLGADGET,
  191.         (APTR)&wImage2,
  192.         NULL,
  193.         NULL,
  194.         NULL,
  195.         NULL,
  196.         1,
  197.         NULL
  198. };
  199.  
  200. #define wGadgetList1 wGadget1
  201.  
  202. static struct NewWindow wNewWindowStructure1 = {
  203.         118,24,
  204.         284,52,
  205.         0,1,
  206.         GADGETDOWN+CLOSEWINDOW,
  207.         WINDOWDRAG+WINDOWDEPTH+WINDOWCLOSE+ACTIVATE+NOCAREREFRESH,
  208.         &wGadget1,
  209.         NULL,
  210.         "Gone With The Windows",
  211.         NULL,
  212.         NULL,
  213.         5,5,
  214.         -1,-1,
  215.         WBENCHSCREEN
  216. };
  217.  
  218.  
  219. /*      The Scrolling Pop Up Menu code starts here.  Feel free
  220.         to cut it out and install it in your own application.
  221.         Include the following copyright notice in your source code:
  222.  
  223.         ScrollingPopUpMenu (c) 1989 Blue Ribbon Bakery
  224. */
  225.  
  226. /*      For the Scrolling Pop Up Menu, we need a simple definition
  227.         of a generic linked list node.
  228. */
  229.  
  230. struct ListNode {
  231.     struct ListNode *next;
  232. };
  233.  
  234. static void draw_arrows(rastport,width,height)
  235.  
  236. /*      This routine prints the two arrows that appear at the
  237.         top and bottom of the menu.
  238. */
  239.  
  240. struct RastPort *rastport;
  241. short width, height;
  242.  
  243. {
  244.     static UWORD arrowdown[] =
  245.         { 0x1c00,0x1c00,0xdd80,0x7f00,0x3e00,0x1c00,0x800 };
  246.     static struct Image arrowdownimage = {0,0,9,7,1,&arrowdown[0],1,0x00,NULL,};
  247.     static UWORD arrowup[] =
  248.         { 0x800,0x1c00,0x3e00,0x7f00,0xdd80,0x1c00,0x1c00 };
  249.     static struct Image arrowupimage = {0,0,9,7,1,&arrowup[0],1,0x00,NULL,};
  250.     short center = width >> 1;
  251.     DrawImage(rastport,&arrowupimage,center - 5,3);
  252.     DrawImage(rastport,&arrowdownimage,center - 5,height - 10);
  253. }
  254.  
  255. static draw_list(rastport,list,displayroutine,itemheight,itemwidth,count)
  256.  
  257. /*      This draws the visible section of the list.  Since this
  258.         can not know what the elements of the list look like (this is
  259.         a generic list handler,) a routine is supplied by the calling
  260.         program that knows how to draw a given list item.  This
  261.         routine is passed in the variable displayroutine.
  262. */
  263.  
  264. struct RastPort *rastport;
  265. struct ListNode *list;
  266. void (*displayroutine)();
  267. short itemheight,itemwidth,count;
  268.  
  269. {
  270.     short y;
  271.     unsigned short index;
  272.     y = 10;
  273.     for (index = 0;index < count; index++) {
  274.         SetAPen(rastport,1);
  275.         SetBPen(rastport,1);
  276.         SetOPen(rastport,1);
  277.         SetDrMd(rastport,JAM2);
  278.         RectFill(rastport,2,y,itemwidth-3,y+itemheight-1);
  279.         if (list) {
  280.             (*displayroutine)(rastport,list,y);
  281.             list = list->next;
  282.         }
  283.         y += itemheight;
  284.     }
  285. }
  286.  
  287. static void complement_item(rastport,position,itemheight,itemwidth)
  288.  
  289. /*      This highlights a displayed list item by complementing all
  290.         of the bits in the rectangle that the item is displayed in.
  291.         To deselect, or remove the highlight, this routine is
  292.         called a second time, and the complement operation returns
  293.         the bits to normal.
  294. */
  295.  
  296. struct RastPort *rastport;
  297. short position, itemheight, itemwidth;
  298.  
  299. {
  300.     if (position < 0) return;
  301.     position = (position * itemheight) + 10;
  302.     BNDRYOFF(rastport);
  303.     SetDrMd(rastport,COMPLEMENT);
  304.     SetAPen(rastport,1);
  305.     RectFill(rastport,2,position,itemwidth-3,position+itemheight-1);
  306. }
  307.  
  308. list_len(top)
  309.  
  310. /*      Generic list handling rougine to return the length of a list.
  311. */
  312.  
  313. struct ListNode *top;
  314.  
  315. {
  316.     unsigned long i;
  317.     for(i=0;top;top = top->next) i++;
  318.     return((long)i);
  319. }
  320.  
  321. struct ListNode *item_in_list(top,index)
  322.  
  323. /*      Generic list handling rougine to return the item at index.
  324. */
  325.  
  326. struct ListNode *top;
  327. long index;
  328.  
  329. {
  330.     for (; index && top; index--) {
  331.         top = top->next;
  332.     }
  333.     return(top);
  334. }
  335.  
  336. static void send_false_button_up()
  337.  
  338. /*      This fools the input device into thinking a mouse button
  339.         up event has happened.  It does this by sending a mouse
  340.         up event into the input stream.
  341. */
  342.  
  343. {
  344.     struct IOStdReq *ioreq;
  345.     struct InputEvent event;
  346.     struct MsgPort *ioport;
  347.     ioport = (struct MsgPort *) CreatePort ("let's fool intuition",0);
  348.     if (ioport) {
  349.         ioreq = (struct IOStdReq *) CreateStdIO(ioport);
  350.         if (ioreq) {
  351.             if (!OpenDevice("input.device",0,ioreq,0)) {
  352.                 ioreq->io_Command = IND_WRITEEVENT;
  353.                 ioreq->io_Flags = 0;
  354.                 ioreq->io_Length = sizeof (struct InputEvent);
  355.                 ioreq->io_Data = (APTR) &event;
  356.                 event.ie_NextEvent = 0;
  357.                 event.ie_Class = IECLASS_RAWMOUSE;
  358.                 event.ie_X = 0;
  359.                 event.ie_Y = 0;
  360.                 event.ie_Code = IECODE_LBUTTON|IECODE_UP_PREFIX;
  361.                 DoIO(ioreq);
  362.                 CloseDevice(ioreq);
  363.             }
  364.             DeleteStdIO(ioreq);
  365.         }
  366.         DeletePort (ioport);
  367.     }
  368. }
  369.  
  370. struct ListNode *ScrollingPopUpMenu(screen,list,displayroutine,
  371.     itemheight,itemwidth,count)
  372.  
  373. /*      This is the biggy.  Open a window and draw the menu in it.
  374.         Wait for MOUSEMOVE, MOUSEBUTTONS and INTUITICKS events:
  375.  
  376. MOUSEMOVE. Read the position of the mouse and determine one of four scenarios:
  377.  
  378.         The mouse is outside the window.  Close the window down and leave,
  379.         returning a NULL, or 0, pointer.
  380.  
  381.         The mouse is over one of the arrows.  If it just moved there from
  382.         a highlighted item, deselect that item with the routine
  383.         complement_item().
  384.  
  385.         The mouse is over the same item it was over last time.  Do nothing.
  386.  
  387.         The mouse has moved over a new item.  Select that item with
  388.         the routine complement_item(). If it just moved there from
  389.         a highlighted item, deselect that item with the routine
  390.         complement_item().
  391.  
  392. MOUSEBUTTONS. The user has clicked on a mouse button.  Close the window and
  393.         return the currently selected item, if such exists, or NULL for
  394.         none selected (the mouse must be over an arrow.)
  395.  
  396. INTUITICKS. This message is only of importance if the mouse is over one
  397.         of the arrows.  There is a variable, topdisplay, that points to
  398.         the first item in the list that is displayed in the menu.  If
  399.         the mouse is over the up arrow, topdisplay is changed to point
  400.         to the item that precedes it in the list and the list is redrawn,
  401.         scrolling it down one with a new item at the top.  If the mouse
  402.         is over the down arrow, topdisplay is changed to point to the
  403.         next item after it in the list and the list is redrawn, scrolling
  404.         it up one with a new item at the bottom.
  405. */
  406.  
  407. struct Screen *screen;
  408. struct ListNode *list;
  409. void (*displayroutine)();
  410. short itemheight,itemwidth,count;
  411.  
  412. {
  413.     static struct NewWindow scrollNewWindowStructure = {
  414.         0,0,10,10,0,1,
  415.         MOUSEBUTTONS+MOUSEMOVE+INTUITICKS,
  416.         ACTIVATE+NOCAREREFRESH+REPORTMOUSE,
  417.         0,0,0,0,0,5,5,-1,-1,CUSTOMSCREEN
  418.     };
  419.     struct IntuiMessage *message;
  420.     struct Window *window;
  421.     struct ListNode *topdisplay = list;
  422.     struct ListNode *activeitem;
  423. /*    struct ListNode *item;*/
  424.     short height;
  425.     long class, code;
  426.     short position, newposition;
  427.     short mousex, mousey;
  428.     short indent = 0;
  429.     short scrolling = 0;
  430.     short left, top;
  431.     if (!list) return(0);
  432.     if (!list->next) return(list);
  433.     if (list_len(list) < count) count = list_len(list);
  434.     height = (itemheight * count) + 20;
  435.     top = screen->MouseY - (height >> 1);
  436.     if (top < 0) top = 0;
  437.     else if ((top + height) > screen->Height)
  438.         top = screen->Height - height;
  439.     left = screen->MouseX - (itemwidth >> 1);
  440.     if (left < 0) left = 0;
  441.     else if ((left + itemwidth) > screen->Width)
  442.         left = screen->Width - itemwidth;
  443.     scrollNewWindowStructure.Width = itemwidth;
  444.     scrollNewWindowStructure.Height = height;
  445.     scrollNewWindowStructure.TopEdge = top;
  446.     scrollNewWindowStructure.LeftEdge = left;
  447.     scrollNewWindowStructure.Screen = screen;
  448.     send_false_button_up();
  449.     window =(struct Window *) OpenWindow(&scrollNewWindowStructure);
  450.     if (window) {
  451.         position = window->MouseY - 10;
  452.         position = position / itemheight;
  453.         activeitem = (struct ListNode *) item_in_list(topdisplay,position);
  454.         draw_list(window->RPort,list,displayroutine,itemheight,itemwidth,count);
  455.         complement_item(window->RPort,position,itemheight,itemwidth);
  456.         draw_arrows(window->RPort,itemwidth,height);
  457.         for (;;) {
  458.             message = 0;
  459.             while (!message) {
  460.                 WaitPort(window->UserPort);
  461.                 message = (struct IntuiMessage *) GetMsg(window->UserPort);
  462.             }
  463.             class = message->Class;
  464.             code = message->Code;
  465.             mousex = message->MouseX;
  466.             mousey = message->MouseY;
  467.             ReplyMsg(message);
  468.             if (class == MOUSEMOVE) {
  469.                 if ((mousex < 0) || (mousex > itemwidth) ||
  470.                   (mousey < 0) || (mousey > height)) {
  471.                     activeitem = 0;
  472.                     break;
  473.                 }
  474.                 if (mousey < 10) {
  475.                     if (activeitem) {
  476.                         complement_item(window->RPort,position,itemheight,itemwidth);
  477.                         activeitem = 0;
  478.                         position = -1;
  479.                     }
  480.                     scrolling = 1;
  481.                 }
  482.                 else if (mousey > (height - 10)) {
  483.                     if (activeitem) {
  484.                         complement_item(window->RPort,position,itemheight,itemwidth);
  485.                         activeitem = 0;
  486.                         position = -1;
  487.                     }
  488.                     scrolling = 2;
  489.                 }
  490.                 else {
  491.                     scrolling = 0;
  492.                     newposition = (mousey - 10) / itemheight;
  493.                     if ((newposition != position) && (newposition < count)
  494.                         && (newposition >= 0)) {
  495.                         if (position >= 0)
  496.                             complement_item(window->RPort,position,
  497.                                 itemheight,itemwidth);
  498.                         activeitem = (struct ListNode *)
  499.                             item_in_list(topdisplay,newposition);
  500.                         position = newposition;
  501.                         complement_item(window->RPort,position,
  502.                             itemheight,itemwidth);
  503.                     }
  504.                 }
  505.             }
  506.             else if (class == MOUSEBUTTONS) {
  507.                 break;
  508.             }
  509.             else if (class == INTUITICKS) {
  510.                 if (scrolling == 1) {
  511.                     if (indent) {
  512.                         indent--;
  513.                         topdisplay = item_in_list(list,indent);
  514.                         draw_list(window->RPort,topdisplay,displayroutine,
  515.                             itemheight,itemwidth,count);
  516.                     }
  517.                 }
  518.                 else if (scrolling == 2) {
  519.                     if (list_len(topdisplay) > count) {
  520.                         indent++;
  521.                         topdisplay = topdisplay->next;
  522.                         draw_list(window->RPort,topdisplay,displayroutine,
  523.                             itemheight,itemwidth,count);
  524.                     }
  525.                 }
  526.             }
  527.         }
  528.         CloseWindow(window);
  529.     }
  530.     return(activeitem);
  531. }
  532.  
  533. /*      End of ScrollingPopUpMenu code.
  534. */
  535.  
  536. void draw_window_title(rastport,window,y)
  537.  
  538. /*      This is the routine supplied by Gone With The Windows
  539.         that draws one window's title into the menu.  This routine
  540.         is passed to ScrollingPopUpMenu() and used to draw the
  541.         menu items.
  542. */
  543.  
  544. struct RastPort *rastport;
  545. struct Window *window;
  546. short y;
  547.  
  548. {
  549.     if (window->Title) {
  550.         SetAPen(rastport,2);
  551.         Move(rastport,2,y+6);
  552.         Text(rastport,window->Title,strlen(window->Title));
  553.     }
  554. }
  555. /* Aztec users uncomment the following line, and comment the one after. */
  556. /* struct IntuitionBase *IntuitionBase; */
  557. extern struct IntuitionBase *IntuitionBase;
  558. long GfxBase;
  559.  
  560. main()
  561.  
  562. /*      The main program.  Open an Intuition window in Workbench
  563.         with two gadgets, one to send a window to the front, the
  564.         second to send it to the back.
  565.  
  566.         When a gadget is clicked on, call ScrollingPopUpMenu() and
  567.         pass it the list of Workbench windows.  If the user selects
  568.         one of the windows, either call WindowToFront(window) or
  569.         WindowToBack(window), depending on which gadget was clicked.
  570. */
  571.  
  572. {
  573.     struct IntuiMessage *message;
  574.     struct Window *window;
  575.     struct Window *selectwindow;
  576.     long class;  /* code*/
  577.     struct Gadget *gadget;
  578.     IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library",0);
  579.     GfxBase = OpenLibrary("graphics.library",0);
  580.     window =(struct Window *) OpenWindow(&wNewWindowStructure1);
  581.     if (window) {
  582.         for (;;) {
  583.             message = 0;
  584.             while (!message) {
  585.                 WaitPort(window->UserPort);
  586.                 message = (struct IntuiMessage *) GetMsg(window->UserPort);
  587.             }
  588.             class = message->Class;
  589.             gadget = (struct Gadget *) message->IAddress;
  590.             ReplyMsg(message);
  591.             if (class == CLOSEWINDOW) break;
  592.             else if (class == GADGETDOWN) {
  593.                 selectwindow = (struct Window *)
  594.                     ScrollingPopUpMenu(window->WScreen,
  595.                         window->WScreen->FirstWindow,
  596.                         draw_window_title,8,100,4);
  597.                 if (gadget->GadgetID == 1) {
  598.                     if (selectwindow) WindowToFront(selectwindow);
  599.                 }
  600.                 else if (gadget->GadgetID == 2) {
  601.                     if (selectwindow) WindowToBack(selectwindow);
  602.                 }
  603.             }
  604.         }
  605.         CloseWindow(window);
  606.     }
  607. }
  608.