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

  1. //        **********************************************
  2. //        ScrollingPopUpMenu (c) 1989 Blue Ribbon Bakery
  3. //        Provided Lattice 5.01 Code in Amiga + December/January 1989
  4. //        Greatly Modified for C++ by
  5. //        Kent L. Brown, K & M Technology, BIX - KentBrown
  6. //        public domain with above notice
  7.  
  8. //        SET TAB to 3
  9. //        Compiles with LC options -csw -abd 
  10. //
  11. //       NOTE -- if you can tell me why I get a warning on LC about
  12. //       statement has no effect I would appreciate it.  I figured
  13. //       this out once on another program but now I can't get rid
  14. //       of this warning message.  
  15. //       BIX - KentBrown
  16. //       C++ Version 1.0 Lattice Version 4.01
  17.  
  18.  
  19.  
  20. PopUpList::PopUpList()
  21.     {     // Open message and IO port for sending fake gadget up
  22.           // I put it here because it would crash sometimes when
  23.          // opening and closing.  This happen when then device
  24.         // was opened and closed each time the object was called
  25.     openflag = 1;
  26.    ioport = new StdPort();
  27.     if (!ioport) openflag = 0;
  28.  
  29.     Pevent = new struct InputEvent[sizeof(struct InputEvent)];
  30.     if (Pevent)
  31.         {
  32.        Pevent->ie_NextEvent = 0;
  33.        Pevent->ie_Class = IECLASS_RAWMOUSE;
  34.        Pevent->ie_X = 0;
  35.        Pevent->ie_Y = 0;
  36.        Pevent->ie_Code = IECODE_LBUTTON|IECODE_UP_PREFIX;
  37.         }
  38.     else openflag = 0;
  39.     ioreq = new IOStdReq();
  40.     if (ioreq)
  41.         {
  42.         ioreq->open("input.device",0,0);
  43.        ioreq->io_Command = IND_WRITEEVENT;
  44.        ioreq->io_Flags = 0;
  45.        ioreq->io_Length = sizeof (struct InputEvent);
  46.        ioreq->io_Data = Pevent;
  47.         }
  48.     else openflag = 0;
  49.  
  50.  
  51.  
  52.     }  // End Method
  53.  
  54. PopUpList::~PopUpList()
  55.     {
  56.     if (ioreq) ioreq->close();
  57.     if (ioport) delete ioport;
  58.     if (ioreq) delete ioreq;
  59.     if (Pevent) delete Pevent;
  60.     }
  61.  
  62. void PopUpList::draw_list(struct ListNode *plist)
  63. {
  64.     WORD y = 10;
  65.     UWORD index;
  66.     for ( index = 0;index < count; index++) {
  67.         SetAPen(rastport,1);
  68.         SetBPen(rastport,1);
  69.         SetOPen(rastport,1);
  70.         SetDrMd(rastport,JAM2);
  71.         RectFill(rastport,2,y,itemwidth-3,y+itemheight-1);
  72.         if (plist) {
  73.             displayroutine(rastport,plist,y);
  74.             plist = plist->next;
  75.         }
  76.         y += itemheight;
  77.     }
  78. }
  79.  
  80. void PopUpList::complement_item()
  81.    {
  82.    if (position < 0) return;  
  83.    UWORD cposition = position;
  84.    cposition = (cposition * itemheight) + 10;
  85.    BNDRYOFF(rastport);
  86.    SetDrMd(rastport,COMPLEMENT);
  87.    SetAPen(rastport,1);
  88.    RectFill(rastport,2,cposition,itemwidth-3,cposition+itemheight-1);
  89.    }
  90.  
  91.  
  92. // Generic list handling routine to return the length of a list.
  93. LONG PopUpList::list_len(struct ListNode *mtop) 
  94.    {
  95.    ULONG i;
  96.    for(i=0;mtop;mtop = mtop->next) i++;
  97.    return (LONG)i;
  98.    }
  99.  
  100.  
  101. // Generic list handling routine to return the item at index.
  102. struct ListNode *PopUpList::item_in_list(struct ListNode *mtop,LONG index)
  103.    {
  104.    for (; index && mtop; index--) 
  105.       mtop = mtop->next;
  106.    return mtop;
  107.    }
  108.  
  109. // Send a Mouse up event to fool intuition
  110. // This is used to force intuition into reading mouse events
  111. // with the left button down, this pops up the menu while the
  112. // left button is pressed
  113. // NOTE -- if you can tell me why I get a warning on LC about
  114. // statement has no effect I would appreciate it.  I figured
  115. // this out once on another program but now I can't get rid
  116. // of this warning message  ....  BIX - KentBrown
  117.  
  118. void PopUpList::sendfalse()
  119. {
  120. if (ioport && ioreq)
  121.    ioreq->do_io(ioport);
  122. }
  123.  
  124.  
  125. void PopUpList::draw_arrows()
  126. {
  127.     static UWORD arrowdown[] =
  128.         { 0x1c00,0x1c00,0xdd80,0x7f00,0x3e00,0x1c00,0x800 };
  129.     static struct Image arrowdownimage = {0,0,9,7,1,&arrowdown[0],1,0x00,NULL,};
  130.     static UWORD arrowup[] =
  131.         { 0x800,0x1c00,0x3e00,0x7f00,0xdd80,0x1c00,0x1c00 };
  132.     static struct Image arrowupimage = {0,0,9,7,1,&arrowup[0],1,0x00,NULL,};
  133.     WORD center = itemwidth >> 1;
  134.     DrawImage(rastport,&arrowupimage,center - 5,3);
  135.     DrawImage(rastport,&arrowdownimage,center - 5,height - 10);
  136. }
  137.  
  138. // itemcount  is max items in the list
  139. struct ListNode *PopUpList::ScrollingPopUpMenu(struct Screen *screen,struct ListNode *tlist,WORD Aitemheight,WORD Aitemwidth,WORD itemcount)
  140. {
  141. static struct NewWindow scrollNewWindowStructure = 
  142.    {
  143.    0,0,10,10,0,1,
  144.    MOUSEBUTTONS+MOUSEMOVE+INTUITICKS,
  145.    ACTIVATE+NOCAREREFRESH+REPORTMOUSE,
  146.    0,0,0,0,0,5,5,-1,-1,CUSTOMSCREEN
  147.    };
  148.  
  149.     list = tlist;
  150.     struct IntuiMessage *message;
  151.     Window *window;
  152.     struct ListNode *topdisplay = tlist;
  153.     struct ListNode *activeitem;
  154.     count = itemcount;            // assign class publics
  155.     itemheight = Aitemheight;
  156.     itemwidth = Aitemwidth;      //
  157.     LONG iclass, code;
  158.     WORD newposition;
  159.     WORD mousex, mousey;
  160.     WORD indent = 0;
  161.     WORD scrolling = 0;
  162.     WORD left, top;
  163.     arrowflag = 1;
  164.     if (!list) return NULL;
  165.     if (!list->next) return list;
  166.     WORD tempct = this->list_len(list);  // get length of list
  167.      if (tempct <= count) arrowflag = 0; // do not display arrows if list is
  168.                                                      // not bigger than window    
  169.     if (tempct < count) count = this->list_len(list);
  170.     height = (itemheight * count) + 20;
  171.  
  172.     // make sure the list window is not bigger than the screen
  173.     top = screen->MouseY - (height >> 1);
  174.     if (top < 0) top = 0;
  175.     else if ((top + height) > screen->Height)
  176.         top = screen->Height - height;
  177.     left = screen->MouseX - (itemwidth >> 1);
  178.     if (left < 0) left = 0;
  179.     else if ((left + itemwidth) > screen->Width)
  180.         left = screen->Width - itemwidth;
  181.     scrollNewWindowStructure.Width = itemwidth;
  182.     scrollNewWindowStructure.Height = height;
  183.     scrollNewWindowStructure.TopEdge = top;
  184.     scrollNewWindowStructure.LeftEdge = left;
  185.     scrollNewWindowStructure.Screen = screen;
  186.     this->sendfalse();
  187.    window = new Window(&scrollNewWindowStructure); 
  188.       if (window) {
  189.           rastport = window->RPort;
  190.        position = window->MouseY - 10;
  191.         position = position / itemheight;
  192.        // assign current active item
  193.         activeitem = (struct ListNode *) this->item_in_list(topdisplay,position);        
  194.       this->draw_list(topdisplay);    //draw list from the top
  195.       this->complement_item();
  196.         if (arrowflag)  // if list is not larger than display do not display arrows
  197.           this->draw_arrows();
  198.       for (;;) {
  199.             message = 0;
  200.             while (!message) 
  201.                {
  202.                WaitPort(window->UserPort);
  203.                message = (struct IntuiMessage *) GetMsg(window->UserPort);
  204.                }
  205.             iclass = message->Class;
  206.             code = message->Code;
  207.             mousex = message->MouseX;
  208.             mousey = message->MouseY;
  209.             ReplyMsg(message);
  210.             if (iclass == MOUSEMOVE) {  // moved out of window
  211.                if ((mousex < 0) || (mousex > itemwidth) || (mousey < 0) || (mousey > height) ) 
  212.                   {
  213.                   activeitem = 0;
  214.                   break;
  215.                   }
  216.                 if (mousey < 10 ) 
  217.                   {  // top arrow
  218.                   if (activeitem) 
  219.                      {  
  220.                      this->complement_item(); // turn item off
  221.                      activeitem = 0;
  222.                      position = -1;  // keeps complement_item from working
  223.                      }
  224.                   scrolling = 1;
  225.                   }
  226.                 else if (mousey > (height - 10) ) {  // bottom arrow
  227.                     if (activeitem) {
  228.                         this->complement_item(); // turn item off
  229.                         activeitem = 0;
  230.                         position = -1;
  231.                     }
  232.                     scrolling = 2;
  233.                 }
  234.                 else {
  235.                     scrolling = 0;
  236.                     newposition = (mousey - 10) / itemheight;
  237.                     if ((newposition != position) && (newposition < count) && (newposition >= 0)) 
  238.                         {
  239.                         this->complement_item(); // turn off highlight
  240.                         activeitem = (struct ListNode *)this->item_in_list(topdisplay,newposition);
  241.                         position = newposition;
  242.                         this->complement_item(); // highlight
  243.                         }
  244.                 }
  245.             }
  246.             else if (iclass == MOUSEBUTTONS) {
  247.                 break;
  248.             }
  249.             else if (iclass == INTUITICKS) {
  250.                 if (scrolling == 1) {
  251.                     if (indent) {
  252.                         indent--;
  253.                         topdisplay = this->item_in_list(list,indent);
  254.                         this->draw_list(topdisplay);
  255.                     }
  256.                 }
  257.                 else if (scrolling == 2) {
  258.                     if (this->list_len(topdisplay) > count) {
  259.                         indent++;
  260.                         topdisplay = topdisplay->next;
  261.                         this->draw_list(topdisplay);
  262.                     }
  263.                 }
  264.             }
  265.         }
  266.      if (window) delete window;
  267.     }
  268. return activeitem;
  269. }
  270.