home *** CD-ROM | disk | FTP | other *** search
- // **********************************************
- // ScrollingPopUpMenu (c) 1989 Blue Ribbon Bakery
- // Provided Lattice 5.01 Code in Amiga + December/January 1989
- // Greatly Modified for C++ by
- // Kent L. Brown, K & M Technology, BIX - KentBrown
- // public domain with above notice
-
- // SET TAB to 3
- // Compiles with LC options -csw -abd
- //
- // NOTE -- if you can tell me why I get a warning on LC about
- // statement has no effect I would appreciate it. I figured
- // this out once on another program but now I can't get rid
- // of this warning message.
- // BIX - KentBrown
- // C++ Version 1.0 Lattice Version 4.01
-
-
-
- PopUpList::PopUpList()
- { // Open message and IO port for sending fake gadget up
- // I put it here because it would crash sometimes when
- // opening and closing. This happen when then device
- // was opened and closed each time the object was called
- openflag = 1;
- ioport = new StdPort();
- if (!ioport) openflag = 0;
-
- Pevent = new struct InputEvent[sizeof(struct InputEvent)];
- if (Pevent)
- {
- Pevent->ie_NextEvent = 0;
- Pevent->ie_Class = IECLASS_RAWMOUSE;
- Pevent->ie_X = 0;
- Pevent->ie_Y = 0;
- Pevent->ie_Code = IECODE_LBUTTON|IECODE_UP_PREFIX;
- }
- else openflag = 0;
- ioreq = new IOStdReq();
- if (ioreq)
- {
- ioreq->open("input.device",0,0);
- ioreq->io_Command = IND_WRITEEVENT;
- ioreq->io_Flags = 0;
- ioreq->io_Length = sizeof (struct InputEvent);
- ioreq->io_Data = Pevent;
- }
- else openflag = 0;
-
-
-
- } // End Method
-
- PopUpList::~PopUpList()
- {
- if (ioreq) ioreq->close();
- if (ioport) delete ioport;
- if (ioreq) delete ioreq;
- if (Pevent) delete Pevent;
- }
-
- void PopUpList::draw_list(struct ListNode *plist)
- {
- WORD y = 10;
- UWORD index;
- for ( index = 0;index < count; index++) {
- SetAPen(rastport,1);
- SetBPen(rastport,1);
- SetOPen(rastport,1);
- SetDrMd(rastport,JAM2);
- RectFill(rastport,2,y,itemwidth-3,y+itemheight-1);
- if (plist) {
- displayroutine(rastport,plist,y);
- plist = plist->next;
- }
- y += itemheight;
- }
- }
-
- void PopUpList::complement_item()
- {
- if (position < 0) return;
- UWORD cposition = position;
- cposition = (cposition * itemheight) + 10;
- BNDRYOFF(rastport);
- SetDrMd(rastport,COMPLEMENT);
- SetAPen(rastport,1);
- RectFill(rastport,2,cposition,itemwidth-3,cposition+itemheight-1);
- }
-
-
- // Generic list handling routine to return the length of a list.
- LONG PopUpList::list_len(struct ListNode *mtop)
- {
- ULONG i;
- for(i=0;mtop;mtop = mtop->next) i++;
- return (LONG)i;
- }
-
-
- // Generic list handling routine to return the item at index.
- struct ListNode *PopUpList::item_in_list(struct ListNode *mtop,LONG index)
- {
- for (; index && mtop; index--)
- mtop = mtop->next;
- return mtop;
- }
-
- // Send a Mouse up event to fool intuition
- // This is used to force intuition into reading mouse events
- // with the left button down, this pops up the menu while the
- // left button is pressed
- // NOTE -- if you can tell me why I get a warning on LC about
- // statement has no effect I would appreciate it. I figured
- // this out once on another program but now I can't get rid
- // of this warning message .... BIX - KentBrown
-
- void PopUpList::sendfalse()
- {
- if (ioport && ioreq)
- ioreq->do_io(ioport);
- }
-
-
- void PopUpList::draw_arrows()
- {
- static UWORD arrowdown[] =
- { 0x1c00,0x1c00,0xdd80,0x7f00,0x3e00,0x1c00,0x800 };
- static struct Image arrowdownimage = {0,0,9,7,1,&arrowdown[0],1,0x00,NULL,};
- static UWORD arrowup[] =
- { 0x800,0x1c00,0x3e00,0x7f00,0xdd80,0x1c00,0x1c00 };
- static struct Image arrowupimage = {0,0,9,7,1,&arrowup[0],1,0x00,NULL,};
- WORD center = itemwidth >> 1;
- DrawImage(rastport,&arrowupimage,center - 5,3);
- DrawImage(rastport,&arrowdownimage,center - 5,height - 10);
- }
-
- // itemcount is max items in the list
- struct ListNode *PopUpList::ScrollingPopUpMenu(struct Screen *screen,struct ListNode *tlist,WORD Aitemheight,WORD Aitemwidth,WORD itemcount)
- {
- static struct NewWindow scrollNewWindowStructure =
- {
- 0,0,10,10,0,1,
- MOUSEBUTTONS+MOUSEMOVE+INTUITICKS,
- ACTIVATE+NOCAREREFRESH+REPORTMOUSE,
- 0,0,0,0,0,5,5,-1,-1,CUSTOMSCREEN
- };
-
- list = tlist;
- struct IntuiMessage *message;
- Window *window;
- struct ListNode *topdisplay = tlist;
- struct ListNode *activeitem;
- count = itemcount; // assign class publics
- itemheight = Aitemheight;
- itemwidth = Aitemwidth; //
- LONG iclass, code;
- WORD newposition;
- WORD mousex, mousey;
- WORD indent = 0;
- WORD scrolling = 0;
- WORD left, top;
- arrowflag = 1;
- if (!list) return NULL;
- if (!list->next) return list;
- WORD tempct = this->list_len(list); // get length of list
- if (tempct <= count) arrowflag = 0; // do not display arrows if list is
- // not bigger than window
- if (tempct < count) count = this->list_len(list);
- height = (itemheight * count) + 20;
-
- // make sure the list window is not bigger than the screen
- top = screen->MouseY - (height >> 1);
- if (top < 0) top = 0;
- else if ((top + height) > screen->Height)
- top = screen->Height - height;
- left = screen->MouseX - (itemwidth >> 1);
- if (left < 0) left = 0;
- else if ((left + itemwidth) > screen->Width)
- left = screen->Width - itemwidth;
- scrollNewWindowStructure.Width = itemwidth;
- scrollNewWindowStructure.Height = height;
- scrollNewWindowStructure.TopEdge = top;
- scrollNewWindowStructure.LeftEdge = left;
- scrollNewWindowStructure.Screen = screen;
- this->sendfalse();
- window = new Window(&scrollNewWindowStructure);
- if (window) {
- rastport = window->RPort;
- position = window->MouseY - 10;
- position = position / itemheight;
- // assign current active item
- activeitem = (struct ListNode *) this->item_in_list(topdisplay,position);
- this->draw_list(topdisplay); //draw list from the top
- this->complement_item();
- if (arrowflag) // if list is not larger than display do not display arrows
- this->draw_arrows();
- for (;;) {
- message = 0;
- while (!message)
- {
- WaitPort(window->UserPort);
- message = (struct IntuiMessage *) GetMsg(window->UserPort);
- }
- iclass = message->Class;
- code = message->Code;
- mousex = message->MouseX;
- mousey = message->MouseY;
- ReplyMsg(message);
- if (iclass == MOUSEMOVE) { // moved out of window
- if ((mousex < 0) || (mousex > itemwidth) || (mousey < 0) || (mousey > height) )
- {
- activeitem = 0;
- break;
- }
- if (mousey < 10 )
- { // top arrow
- if (activeitem)
- {
- this->complement_item(); // turn item off
- activeitem = 0;
- position = -1; // keeps complement_item from working
- }
- scrolling = 1;
- }
- else if (mousey > (height - 10) ) { // bottom arrow
- if (activeitem) {
- this->complement_item(); // turn item off
- activeitem = 0;
- position = -1;
- }
- scrolling = 2;
- }
- else {
- scrolling = 0;
- newposition = (mousey - 10) / itemheight;
- if ((newposition != position) && (newposition < count) && (newposition >= 0))
- {
- this->complement_item(); // turn off highlight
- activeitem = (struct ListNode *)this->item_in_list(topdisplay,newposition);
- position = newposition;
- this->complement_item(); // highlight
- }
- }
- }
- else if (iclass == MOUSEBUTTONS) {
- break;
- }
- else if (iclass == INTUITICKS) {
- if (scrolling == 1) {
- if (indent) {
- indent--;
- topdisplay = this->item_in_list(list,indent);
- this->draw_list(topdisplay);
- }
- }
- else if (scrolling == 2) {
- if (this->list_len(topdisplay) > count) {
- indent++;
- topdisplay = topdisplay->next;
- this->draw_list(topdisplay);
- }
- }
- }
- }
- if (window) delete window;
- }
- return activeitem;
- }
-