home *** CD-ROM | disk | FTP | other *** search
- /* GadTools layout toolkit
- **
- ** Copyright © 1993-1995 by Olaf `Olsen' Barthel
- ** Freely distributable.
- **
- ** :ts=4
- */
-
- #include "gtlayout_global.h"
-
- //#define DB(x) x
- #define DB(x) ;
-
- #if defined(DO_POPUP_KIND) && defined(DO_BOOPSI_KIND)
-
- #define PIF_SingleActive (1 << 0)
- #define PIF_ArrowUp (1 << 1)
- #define PIF_ArrowDown (1 << 2)
- /* // Intuition ghosts images all by itself
- STATIC VOID __regargs
- DrawDisabled(struct RastPort *RPort,UWORD Left,UWORD Top,UWORD Width,UWORD Height,UWORD *Pens)
- {
- SetAPen(RPort,Pens[BLOCKPEN]);
- SetDrMd(RPort,JAM1);
-
- SetAfPt(RPort,(UWORD *)&ghostingPat,1);
- RectFill(RPort,Left,Top,Left + Width - 1,Top + Height - 1);
- SetAfPt(RPort,NULL,0);
- }
- */
- STATIC VOID __regargs
- DrawArrow(struct RastPort *RPort,UWORD Left,UWORD Top,LONG ArrowWidth,LONG ArrowHeight,WORD Dir)
- {
- if(Dir < 0)
- {
- LONG i,Width,Start;
-
- for(i = 0 ; i < ArrowHeight ; i++)
- {
- Width = ((ArrowWidth * (i + 1)) / ArrowHeight) & ~1;
-
- if(Width < ArrowWidth)
- Width++;
-
- Start = Left + (ArrowWidth - Width) / 2;
-
- Move(RPort,Start,Top + i);
- Draw(RPort,Start + Width - 1,Top + i);
- }
- }
- else
- {
- LONG i,Width,Start;
-
- for(i = 0 ; i < ArrowHeight ; i++)
- {
- Width = ((ArrowWidth * (i + 1)) / ArrowHeight) & ~1;
-
- if(Width < ArrowWidth)
- Width++;
-
- Start = Left + (ArrowWidth - Width) / 2;
-
- Move(RPort,Start,Top + ArrowHeight - 1 - i);
- Draw(RPort,Start + Width - 1,Top + ArrowHeight - 1 - i);
- }
- }
- }
-
- STATIC VOID __regargs
- DrawContainer(struct RastPort *RPort,UWORD Left,UWORD Top,UWORD Width,UWORD Height,struct GadgetInfo *GadgetInfo,PopInfo *Info,BOOL Highlight,BOOL Disabled)
- {
- UWORD Shine,Shadow,Txt,Fill;
- UWORD *Pens;
-
- Pens = GadgetInfo->gi_DrInfo->dri_Pens;
-
- if(Highlight)
- {
- Shine = Pens[SHADOWPEN];
- Shadow = Pens[SHINEPEN];
- Txt = Pens[FILLTEXTPEN];
- Fill = Pens[FILLPEN];
- }
- else
- {
- Shine = Pens[SHINEPEN];
- Shadow = Pens[SHADOWPEN];
- Txt = Pens[TEXTPEN];
- Fill = Pens[BACKGROUNDPEN];
- }
-
- SetDrMd(RPort,JAM1);
-
- SetAPen(RPort,Fill);
- RectFill(RPort,Left + 2,Top + 1,Left + Width - 3,Top + Height - 2);
-
- SetAPen(RPort,Shine);
- Move(RPort,Left + 1,Top + 1);
- Draw(RPort,Left + 1,Top + Height - 2);
- Draw(RPort,Left,Top + Height - 1);
- Draw(RPort,Left,Top);
- Draw(RPort,Left + Width - 2,Top);
-
- SetAPen(RPort,Shadow);
- Move(RPort,Left + Width - 2,Top + Height - 2);
- Draw(RPort,Left + Width - 2,Top + 1);
- Draw(RPort,Left + Width - 1,Top);
- Draw(RPort,Left + Width - 1,Top + Height - 1);
- Draw(RPort,Left + 1,Top + Height - 1);
-
- SetAPen(RPort,Pens[SHADOWPEN]);
- Move(RPort,Left + Info->MarkLeft,Top + 2);
- Draw(RPort,Left + Info->MarkLeft,Top + Height - 3);
-
- SetAPen(RPort,Pens[SHINEPEN]);
- Move(RPort,Left + Info->MarkLeft + 1,Top + 2);
- Draw(RPort,Left + Info->MarkLeft + 1,Top + Height - 3);
-
- SetFont(RPort,Info->Font);
- SetAPen(RPort,Txt);
-
- DrawArrow(RPort,Left + 4,Top + Info->ArrowTop,Info->ArrowWidth,Info->ArrowHeight,1);
-
- Move(RPort,Left + Info->LabelLeft,Top + Info->LabelBase);
- Text(RPort,Info->Labels[Info->Active],Info->ActiveLen);
- /* // Intuition ghosts images all by itself
- if(Disabled)
- DrawDisabled(RPort,Left,Top,Width,Height,Pens);
- */
- }
-
- STATIC VOID __regargs
- DrawOneBox(PopInfo *Info,UWORD Top,STRPTR Label)
- {
- struct RastPort *RPort;
- LONG Len;
-
- RPort = Info->Window->RPort;
-
- if((Len = strlen(Label)) > Info->MaxLen)
- Len = Info->MaxLen;
-
- Move(RPort,6,Top + Info->LineBase);
- Text(RPort,Label,Len);
- }
-
- STATIC VOID __regargs
- DrawOneGlyph(PopInfo *Info,UWORD Top,WORD Dir,UWORD *Pens)
- {
- struct RastPort *RPort;
-
- RPort = Info->Window->RPort;
-
- if(Pens)
- {
- SetAPen(RPort,Info->MenuBack);
- RectFill(RPort,4,Top,4 + Info->SingleWidth - 1,Top + Info->SingleHeight - 1);
- SetAPen(RPort,Info->MenuText);
- }
-
- DrawArrow(RPort,6,Top + Info->ArrowTop,Info->ArrowWidth,Info->ArrowHeight,Dir);
- }
-
- STATIC VOID __regargs
- BoxRender(PopInfo *Info,UWORD *Pens,LONG Active,BOOL FullRefresh,BOOL Highlight,WORD Dir)
- {
- struct RastPort *RPort = Info->Window->RPort;
-
- if(FullRefresh)
- {
- LONG Index,Top,Width,Height;
-
- SetAPen(RPort,Info->MenuBack);
- SetDrMd(RPort,JAM1);
-
- Width = Info->Window->Width;
- Height = Info->Window->Height;
-
- RectFill(RPort,2,1,Width - 3,Height - 2);
-
- SetAPen(RPort,Info->MenuText);
-
- Move(RPort,1,1);
- Draw(RPort,1,Height - 2);
- Draw(RPort,0,Height - 2);
- Draw(RPort,0,0);
- Draw(RPort,Width - 1,0);
-
- Move(RPort,0,Height - 1);
- Draw(RPort,Width - 1,Height - 1);
- Draw(RPort,Width - 1,1);
- Draw(RPort,Width - 2,1);
- Draw(RPort,Width - 2,Height - 2);
-
- Index = Info->TopMost;
- Top = 2;
- Height = Info->BoxHeight;
-
- Info->Flags &= ~(PIF_ArrowUp | PIF_ArrowDown);
-
- if(Info->TopMost > 0 && Active != Info->TopMost && Info->BoxLines > 2)
- {
- Info->Flags |= PIF_ArrowUp;
-
- Index += 1;
- Top += Info->SingleHeight;
- Height -= Info->SingleHeight;
- }
-
- if(Info->TopMost + Info->BoxLines < Info->NumLabels && Active != Info->TopMost + Info->BoxLines - 1 && Info->BoxLines > 2)
- {
- Info->Flags |= PIF_ArrowDown;
-
- Height -= Info->SingleHeight;
- }
-
- for( ; Index < Info->NumLabels && Height > 0 ; Index++, Top += Info->SingleHeight, Height -= Info->SingleHeight)
- {
- if(Index == Active)
- {
- SetAPen(RPort,Info->MenuBackSelect);
- RectFill(RPort,4,Top,4 + Info->SingleWidth - 1,Top + Info->SingleHeight - 1);
-
- SetAPen(RPort,Info->MenuTextSelect);
- DrawOneBox(Info,Top,Info->Labels[Index]);
-
- SetAPen(RPort,Info->MenuText);
- }
- else
- DrawOneBox(Info,Top,Info->Labels[Index]);
- }
-
- if(Info->Flags & PIF_ArrowUp)
- DrawOneGlyph(Info,2,-1,NULL);
-
- if(Info->Flags & PIF_ArrowDown)
- DrawOneGlyph(Info,2 + (Info->BoxLines - 1) * Info->SingleHeight,1,NULL);
-
- Info->LastDrawn = 2 + (Active - Info->TopMost) * Info->SingleHeight;
- Info->LastLabelDrawn = Info->Labels[Active];
- }
- else
- {
- if(Info->LastLabelDrawn)
- {
- LONG Top = Info->LastDrawn;
-
- SetDrMd(RPort,JAM1);
-
- SetAPen(RPort,Info->MenuBack);
- RectFill(RPort,4,Top,4 + Info->SingleWidth - 1,Top + Info->SingleHeight - 1);
-
- SetAPen(RPort,Info->MenuText);
- DrawOneBox(Info,Top,Info->LastLabelDrawn);
- }
-
- Info->LastDrawn = -1;
- Info->LastLabelDrawn = NULL;
-
- if(Active >= 0)
- {
- LONG Top,NewActive;
-
- NewActive = Active - Info->TopMost;
- Top = 2 + NewActive * Info->SingleHeight;
-
- if(Top >= 2 && Top < Info->BoxHeight + 2)
- {
- UWORD Pen;
-
- if(Dir != 0)
- Highlight = FALSE;
-
- if(Highlight)
- {
- Pen = Info->MenuBackSelect;
-
- Info->LastDrawn = Top;
- Info->LastLabelDrawn = Info->Labels[Active];
- }
- else
- Pen = Info->MenuBack;
-
- SetDrMd(RPort,JAM1);
-
- SetAPen(RPort,Pen);
- RectFill(RPort,4,Top,4 + Info->SingleWidth - 1,Top + Info->SingleHeight - 1);
-
- if(Highlight)
- Pen = Info->MenuTextSelect;
- else
- Pen = Info->MenuText;
-
- SetAPen(RPort,Pen);
-
- if(Dir == 0)
- DrawOneBox(Info,Top,Info->Labels[Active]);
- else
- DrawOneGlyph(Info,Top,Dir,NULL);
- }
- }
- }
- }
-
- STATIC ULONG __regargs
- InputMethod(struct IClass *class,struct Gadget *gadget,struct gpInput *InputInfo)
- {
- PopInfo *Info = INST_DATA(class,gadget);
- ULONG Result = GMR_MEACTIVE;
- BOOL Done = FALSE;
-
- if(InputInfo->gpi_IEvent->ie_Class == IECLASS_RAWMOUSE)
- {
- UWORD Code = InputInfo->gpi_IEvent->ie_Code;
-
- if(Code == MENUDOWN)
- {
- Result = GMR_NOREUSE;
- Done = TRUE;
-
- Info->Active = Info->InitialActive;
- }
- else
- {
- if(Code == SELECTUP)
- {
- Done = TRUE;
-
- if(Info->Active < 0)
- {
- Result = GMR_NOREUSE;
-
- Info->Active = Info->InitialActive;
- }
- else
- {
- LONG Len;
-
- Result = GMR_REUSE | GMR_VERIFY;
-
- if(Info->Flags & PIF_SingleActive)
- {
- UWORD Width,Height;
- WORD x,y;
-
- x = InputInfo->gpi_Mouse . X;
- y = InputInfo->gpi_Mouse . Y;
-
- Width = gadget->Width;
- Height = gadget->Height;
-
- if(x >= 0 && y >= 0 && x < Width && y < Height)
- {
- if(InputInfo->gpi_IEvent->ie_Qualifier & (IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT))
- Info->Active--;
- else
- Info->Active++;
-
- if(Info->Active >= Info->NumLabels)
- Info->Active = 0;
- else
- {
- if(Info->Active < 0)
- Info->Active = Info->NumLabels - 1;
- }
- }
- else
- {
- Result = GMR_NOREUSE;
-
- Info->Active = Info->InitialActive;
- }
- }
-
- Len = strlen(Info->Labels[Info->Active]);
-
- if(Len > Info->MaxLen)
- Len = Info->MaxLen;
-
- Info->ActiveLen = Len;
-
- *InputInfo->gpi_Termination = Info->Active;
- }
- }
- else
- {
- if(Info->Flags & PIF_SingleActive)
- {
- UWORD Left,Top,Width,Height;
- WORD x,y;
-
- x = InputInfo->gpi_Mouse . X;
- y = InputInfo->gpi_Mouse . Y;
-
- Left = gadget->LeftEdge;
- Top = gadget->TopEdge;
- Width = gadget->Width;
- Height = gadget->Height;
-
- if(x < 0 || y < 0 || x >= Width || y >= Height)
- {
- if(gadget->Flags & GFLG_SELECTED)
- {
- struct RastPort *RPort;
-
- if(RPort = ObtainGIRPort(InputInfo->gpi_GInfo))
- {
- DrawContainer(RPort,Left,Top,Width,Height,InputInfo->gpi_GInfo,Info,FALSE,FALSE);
-
- gadget->Flags &= ~GFLG_SELECTED;
-
- ReleaseGIRPort(RPort);
- }
- }
- }
- else
- {
- if(!(gadget->Flags & GFLG_SELECTED))
- {
- struct RastPort *RPort;
-
- if(RPort = ObtainGIRPort(InputInfo->gpi_GInfo))
- {
- DrawContainer(RPort,Left,Top,Width,Height,InputInfo->gpi_GInfo,Info,TRUE,FALSE);
-
- gadget->Flags |= GFLG_SELECTED;
-
- ReleaseGIRPort(RPort);
- }
- }
- }
- }
- }
- }
-
- if(Done)
- {
- struct RastPort *RPort;
-
- if(RPort = ObtainGIRPort(InputInfo->gpi_GInfo))
- {
- DrawContainer(RPort,gadget->LeftEdge,gadget->TopEdge,gadget->Width,gadget->Height,InputInfo->gpi_GInfo,Info,FALSE,FALSE);
-
- ReleaseGIRPort(RPort);
- }
-
- if(Info->Window)
- {
- CloseWindow(Info->Window);
- Info->Window = NULL;
- }
-
- Info->Flags &= ~PIF_SingleActive;
- }
- }
-
- if(!Done && Info->Window)
- {
- LONG NewActive = 0;
- WORD x,y;
- WORD Dir = 0;
- UWORD From,To;
-
- x = InputInfo->gpi_GInfo->gi_Screen->MouseX - Info->BoxLeft;
- y = InputInfo->gpi_GInfo->gi_Screen->MouseY - Info->BoxTop;
-
- if(x < 0 || x >= Info->BoxWidth)
- NewActive = -1;
- else
- {
- UWORD Margin;
-
- if(Info->Flags & (PIF_ArrowUp | PIF_ArrowDown))
- Margin = Info->SingleHeight;
- else
- Margin = (Info->SingleHeight + 3) / 4;
-
- // Scroll up?
-
- if(y < Margin)
- {
- if(y < 0)
- NewActive = -1;
- else
- {
- // Topmost line concealed?
-
- if(Info->TopMost > 0)
- {
- Info->TopMost--;
-
- From = 2;
- To = 2 + Info->BoxHeight - 1;
-
- Dir = -Info->SingleHeight;
- }
- }
- }
- else
- {
- LONG Last;
-
- Last = Info->NumLabels - Info->TopMost;
-
- if(Last < Info->BoxLines)
- Last = Last * Info->SingleHeight;
- else
- Last = Info->BoxHeight;
-
- // Scroll up?
-
- if(y >= Last - Margin)
- {
- if(y >= Last)
- NewActive = -1;
- else
- {
- // Last line concealed?
-
- if(Info->TopMost + Info->BoxLines < Info->NumLabels)
- {
- Info->TopMost++;
-
- From = 2;
- To = 2 + Info->BoxHeight - 1;
-
- Dir = Info->SingleHeight;
- }
- }
- }
- }
-
- if(NewActive != -1)
- {
- NewActive = Info->TopMost + y / Info->SingleHeight;
-
- if(NewActive < 0)
- NewActive = 0;
- else
- {
- if(NewActive >= Info->NumLabels)
- NewActive = Info->NumLabels - 1;
- }
- }
- }
-
- if(NewActive != Info->Active || Dir != 0)
- {
- WORD Arrow;
- UWORD *Pens = InputInfo->gpi_GInfo->gi_DrInfo->dri_Pens;
-
- if(Dir != 0)
- {
- struct RastPort *RPort = Info->Window->RPort;
-
- Arrow = (NewActive == Info->TopMost) ? -1 : 1;
-
- BoxRender(Info,Pens,-1,FALSE,FALSE,0);
-
- if(Info->Flags & PIF_ArrowUp)
- From += Info->SingleHeight;
-
- if(Info->Flags & PIF_ArrowDown)
- To -= Info->SingleHeight;
-
- SetBPen(RPort,Pens[BACKGROUNDPEN]);
- ScrollRaster(RPort,0,Dir,4,From,4 + Info->BoxWidth - 1,To);
-
- if(Dir < 0)
- BoxRender(Info,Pens,Info->TopMost + 1,FALSE,FALSE,0);
- else
- BoxRender(Info,Pens,Info->TopMost + Info->BoxLines - 2,FALSE,FALSE,0);
-
- if(!Info->TopMost || Info->BoxLines < 3)
- {
- Info->Flags &= ~PIF_ArrowUp;
-
- Arrow = 0;
- }
- else
- {
- if(!(Info->Flags & PIF_ArrowUp))
- {
- Info->Flags |= PIF_ArrowUp;
-
- DrawOneGlyph(Info,2,-1,Pens);
- }
- }
-
- if(Info->TopMost + Info->BoxLines >= Info->NumLabels || Info->BoxLines < 3)
- {
- Info->Flags &= ~PIF_ArrowDown;
-
- Arrow = 0;
- }
- else
- {
- if(!(Info->Flags & PIF_ArrowDown))
- {
- Info->Flags |= PIF_ArrowDown;
-
- DrawOneGlyph(Info,2 + (Info->BoxLines - 1) * Info->SingleHeight,1,Pens);
- }
- }
- }
- else
- Arrow = 0;
-
- Info->Active = NewActive;
-
- BoxRender(Info,Pens,NewActive,FALSE,TRUE,Arrow);
- }
- }
-
- return(Result);
- }
-
- STATIC ULONG __regargs
- SetMethod(struct IClass *class,struct Gadget *gadget,struct opSet *SetInfo)
- {
- PopInfo *Info = INST_DATA(class,gadget);
- struct TagItem *This;
- LONG NewActive;
- STRPTR *NewLabels;
- ULONG Result;
- UWORD Flags = gadget -> Flags;
- BOOL NeedRefresh = FALSE;
-
- DB(kprintf("%s %ld\n",__FUNC__,__LINE__));
-
- Result = DoSuperMethodA(class,(Object *)gadget,(Msg)SetInfo);
-
- if(This = FindTagItem(GA_Disabled,SetInfo->ops_AttrList))
- {
- if(This -> ti_Data && !(Flags & GFLG_DISABLED) || !This -> ti_Data && (Flags & GFLG_DISABLED))
- NeedRefresh = TRUE;
- }
-
- NewLabels = (STRPTR *)GetTagData(PIA_Labels,NULL,SetInfo->ops_AttrList);
-
- if(This = FindTagItem(PIA_Active,SetInfo->ops_AttrList))
- {
- LONG NumLabels = Info->NumLabels;
-
- if(NewLabels)
- for(NumLabels = 0 ; NewLabels[NumLabels] ; NumLabels++);
-
- NewActive = (LONG)This->ti_Data;
-
- if(NewActive < 0)
- NewActive = 0;
- else
- {
- if(NewActive >= NumLabels)
- NewActive = NumLabels - 1;
- }
- }
- else
- NewActive = -1;
-
- if((NewActive != Info->Active && NewActive != -1) || NewLabels)
- {
- struct RastPort *RPort;
-
- if(RPort = ObtainGIRPort(SetInfo->ops_GInfo))
- {
- UWORD Left,Top,Width;
- LONG Len;
- STRPTR *Labels;
- LONG NumLabels,MaxLen,ActiveLen;
- UWORD *Pens;
-
- if(NewLabels)
- {
- struct TextExtent Extent;
-
- for(NumLabels = MaxLen = 0 ; NewLabels[NumLabels] ; NumLabels++)
- {
- Len = TextFit(RPort,NewLabels[NumLabels],strlen(NewLabels[NumLabels]),&Extent,NULL,1,Info->MaxWidth,32767);
-
- if(Len > MaxLen)
- MaxLen = Len;
- }
-
- Labels = NewLabels;
- }
- else
- {
- Labels = Info->Labels;
- NumLabels = Info->NumLabels;
- MaxLen = Info->MaxLen;
- }
-
- if(NewActive == -1)
- NewActive = Info->Active;
-
- if(NewActive >= NumLabels)
- NewActive = NumLabels - 1;
-
- Pens = SetInfo->ops_GInfo->gi_DrInfo->dri_Pens;
- Left = gadget -> LeftEdge;
- Top = gadget -> TopEdge;
-
- SetFont(RPort,Info->Font);
-
- Len = strlen(Labels[NewActive]);
-
- if(Len > MaxLen)
- Len = MaxLen;
-
- ActiveLen = Len;
-
- Width = TextLength(RPort,Labels[NewActive],ActiveLen);
-
- SetDrMd(RPort,JAM2);
-
- if(Width < Info->MaxWidth)
- {
- SetAPen(RPort,Pens[BACKGROUNDPEN]);
- RectFill(RPort,Left + Info->LabelLeft + Width,Top + Info->LabelTop,Left + Info->LabelLeft + Info->MaxWidth - 1,Top + Info->LabelTop + RPort->TxHeight - 1);
- }
-
- SetAPen(RPort,Pens[TEXTPEN]);
- SetBPen(RPort,Pens[BACKGROUNDPEN]);
-
- Move(RPort,Left + Info->LabelLeft,Top + Info->LabelBase);
- Text(RPort,Labels[NewActive],ActiveLen);
-
- Info->Active = NewActive;
- Info->ActiveLen = ActiveLen;
-
- if(NewLabels)
- {
- Info->Labels = Labels;
- Info->NumLabels = NumLabels;
- Info->MaxLen = MaxLen;
- }
- /* // Intuition ghosts images all by itself
- if(((struct Gadget *)object) -> Flags & GFLG_DISABLED)
- {
- UWORD Height;
-
- Width = ((struct Gadget *)object) -> Width;
- Height = ((struct Gadget *)object) -> Height;
-
- DrawDisabled(RPort,Left,Top,Width,Height,Pens);
- }
- */
- NeedRefresh = FALSE;
-
- ReleaseGIRPort(RPort);
- }
- }
-
- if(!(gadget -> Flags & GFLG_DISABLED) && (This = FindTagItem(PIA_Highlight,SetInfo->ops_AttrList)))
- {
- struct RastPort *RPort;
-
- if(RPort = ObtainGIRPort(SetInfo->ops_GInfo))
- {
- DrawContainer(RPort,gadget->LeftEdge,gadget->TopEdge,gadget->Width,gadget->Height,SetInfo->ops_GInfo,Info,This->ti_Data,FALSE);
-
- NeedRefresh = FALSE;
-
- ReleaseGIRPort(RPort);
- }
- }
-
- if(NeedRefresh)
- {
- struct RastPort *RPort;
-
- if(RPort = ObtainGIRPort(SetInfo->ops_GInfo))
- {
- DrawContainer(RPort,gadget->LeftEdge,gadget->TopEdge,gadget->Width,gadget->Height,SetInfo->ops_GInfo,Info,FALSE,gadget -> Flags & GFLG_DISABLED);
-
- ReleaseGIRPort(RPort);
- }
- }
-
- return(Result);
- }
-
- STATIC ULONG __regargs
- RenderMethod(struct IClass *class,struct Gadget *gadget,struct gpRender *RenderInfo)
- {
- PopInfo *Info = INST_DATA(class,gadget);
-
- DB(kprintf("%s %ld\n",__FUNC__,__LINE__));
-
- DrawContainer(RenderInfo->gpr_RPort,gadget->LeftEdge,gadget->TopEdge,gadget->Width,gadget->Height,RenderInfo->gpr_GInfo,Info,gadget->Flags & GFLG_SELECTED,gadget->Flags & GFLG_DISABLED);
-
- return(TRUE);
- }
-
- STATIC ULONG __regargs
- DisposeMethod(struct IClass *class,Object *object,Msg msg)
- {
- PopInfo *Info = INST_DATA(class,object);
-
- DB(kprintf("%s %ld\n",__FUNC__,__LINE__));
-
- if(Info->Font)
- {
- CloseFont(Info->Font);
- Info->Font = NULL;
- }
-
- if(Info->Window)
- {
- CloseWindow(Info->Window);
- Info->Window = NULL;
- }
-
- return(DoSuperMethodA(class,object,msg));
- }
-
- STATIC ULONG __regargs
- NewMethod(struct IClass *class,Object *object,struct opSet *SetInfo)
- {
- DB(kprintf("%s %ld\n",__FUNC__,__LINE__));
-
- if(object = (Object *)DoSuperMethodA(class,object,(Msg)SetInfo))
- {
- PopInfo *Info = INST_DATA(class,object);
- struct TagItem *Item,*TagList = SetInfo -> ops_AttrList;
- struct TextAttr *Font;
- LONG Width,Height;
-
- Width = Height = 0;
- Font = NULL;
-
- memset(Info,0,sizeof(PopInfo));
-
- while(Item = NextTagItem(&TagList))
- {
- switch(Item->ti_Tag)
- {
- case GA_Width:
- Width = Item->ti_Data;
- break;
-
- case GA_Height:
- Height = Item->ti_Data;
- break;
-
- case PIA_Labels:
- Info->Labels = (STRPTR *)Item->ti_Data;
- break;
-
- case PIA_Active:
- Info->Active = (LONG)Item->ti_Data;
- break;
-
- case PIA_Font:
- Font = (struct TextAttr *)Item->ti_Data;
- break;
- }
- }
-
- if(Font && Info->Labels && Width && Height)
- {
- while(Info->Labels[Info->NumLabels])
- Info->NumLabels++;
-
- if(Info->NumLabels)
- {
- if(Info->Font = OpenFont(Font))
- {
- struct RastPort __aligned RPort;
-
- if(Info->Active < 0)
- Info->Active = 0;
- else
- {
- if(Info->Active >= Info->NumLabels)
- Info->Active = Info->NumLabels - 1;
- }
-
- InitRastPort(&RPort);
- SetFont(&RPort,Info->Font);
-
- Info->ArrowWidth = (TextLength(&RPort,"M",1) & ~1) + 1;
- Info->ArrowHeight = (2 * RPort.TxHeight) / 3;
- Info->ArrowTop = (Height - Info->ArrowHeight) / 2;
-
- Info->MarkLeft = 4 + Info->ArrowWidth + 2;
- Info->MarkWidth = Info->MarkLeft + 4;
-
- Info->PopLeft = Info->MarkWidth - 6;
- Info->PopWidth = Width - Info->PopLeft;
-
- Info->LabelTop = (Height - RPort.TxHeight) / 2;
- Info->LabelLeft = Info->MarkWidth;
- Info->LabelBase = Info->LabelTop + RPort.TxBaseline;
-
- Width -= 6 + Info->MarkWidth + 6;
- Height -= 2 + RPort.TxHeight + 2;
-
- if(Width > 0 && Height >= 0)
- {
- struct TextExtent Extent;
- LONG i,Len,MaxLen;
-
- for(i = MaxLen = 0 ; i < Info->NumLabels ; i++)
- {
- Len = TextFit(&RPort,Info->Labels[i],strlen(Info->Labels[i]),&Extent,NULL,1,Width,32767);
-
- if(Len > MaxLen)
- MaxLen = Len;
- }
-
- if(MaxLen)
- {
- Len = strlen(Info->Labels[Info->Active]);
-
- if(Len > MaxLen)
- Len = MaxLen;
-
- Info->ActiveLen = Len;
-
- Info->MaxLen = MaxLen;
- Info->MaxWidth = Width;
-
- return((ULONG)object);
- }
- }
-
- CloseFont(Info->Font);
- Info->Font = NULL;
- }
- }
- }
-
- CoerceMethod(class,object,OM_DISPOSE);
- }
-
- return(0);
- }
-
- STATIC ULONG __regargs
- ActiveMethod(struct IClass *class,struct Gadget *gadget,struct gpInput *InputInfo)
- {
- PopInfo *Info = INST_DATA(class,gadget);
- struct RastPort *RPort;
-
- DB(kprintf("%s %ld\n",__FUNC__,__LINE__));
-
- if(RPort = ObtainGIRPort(InputInfo->gpi_GInfo))
- {
- LONG Left,Top;
-
- Left = gadget->LeftEdge;
- Top = gadget->TopEdge;
-
- Info->Window = NULL;
-
- if(Info->NumLabels > 2 && InputInfo->gpi_Mouse.X >= Info->MarkLeft)
- {
- UWORD SingleHeight,ScreenHeight,Width,Height;
-
- Info->Flags &= ~PIF_SingleActive;
- Info->Window = NULL;
-
- SetFont(RPort,Info->Font);
-
- SingleHeight = gadget->Height;
- ScreenHeight = InputInfo->gpi_GInfo->gi_Screen->Height;
-
- Info->LineTop = (SingleHeight - RPort->TxHeight) / 2;
- Info->LineBase = Info->LineTop + RPort->TxBaseline;
-
- Width = Info->PopWidth;
- Height = 2 + SingleHeight * Info->NumLabels + 2;
-
- while(Height > SingleHeight && Height > ScreenHeight)
- Height -= SingleHeight;
-
- if(Height > SingleHeight)
- {
- LONG LeftEdge,TopEdge,TopMost;
-
- LeftEdge = InputInfo->gpi_GInfo->gi_Window->LeftEdge + Left + Info->PopLeft;
- TopEdge = InputInfo->gpi_GInfo->gi_Window->TopEdge + Top + Info->LabelTop - (2 + Info->LineTop + Info->Active * SingleHeight);
- TopMost = 0;
-
- while(TopEdge < 0 && TopMost < Info->NumLabels)
- {
- TopEdge += SingleHeight;
- TopMost += 1;
- }
-
- if(TopEdge >= 0 && TopMost < Info->NumLabels)
- {
- while(Height > SingleHeight && TopEdge + Height > ScreenHeight)
- Height -= SingleHeight;
-
- if(Height > SingleHeight && TopEdge + Height <= ScreenHeight)
- {
- ReleaseGIRPort(RPort);
-
- if(Info->Window = OpenWindowTags(NULL,
- WA_Left, LeftEdge,
- WA_Top, TopEdge,
- WA_Width, Width,
- WA_Height, Height,
- WA_SimpleRefresh, TRUE,
- WA_NoCareRefresh, TRUE,
- WA_AutoAdjust, FALSE,
- WA_CustomScreen, InputInfo->gpi_GInfo->gi_Screen,
- WA_Borderless, TRUE,
-
- V39 ? WA_BackFill : TAG_IGNORE,LAYERS_NOBACKFILL,
- TAG_DONE))
- {
- UWORD *Pens = InputInfo->gpi_GInfo->gi_DrInfo->dri_Pens;
-
- Info->TopMost = TopMost;
-
- Info->BoxLeft = LeftEdge + 4;
- Info->BoxTop = TopEdge + 2;
- Info->BoxWidth = Width - 8;
- Info->BoxHeight = Height - 4;
-
- Info->BoxLines = Info->BoxHeight / SingleHeight;
-
- Info->SingleWidth = Width - 8;
- Info->SingleHeight = SingleHeight;
-
- if(V39)
- {
- STATIC BYTE RenderPens[] =
- {
- BACKGROUNDPEN,
- FILLPEN,
- TEXTPEN,
- FILLTEXTPEN,
- SHADOWPEN,
- SHINEPEN,
- BARDETAILPEN,
- BARBLOCKPEN
- -1
- };
-
- UWORD i,Pen,Max = 0;
-
- Info->MenuText = Pens[BARDETAILPEN];
- Info->MenuBack = Pens[BARBLOCKPEN];
- Info->MenuTextSelect = Pens[BARBLOCKPEN];
- Info->MenuBackSelect = Pens[BARDETAILPEN];
-
- for(i = 0 ; RenderPens[i] != -1 ; i++)
- {
- if((Pen = Pens[RenderPens[i]]) > Max)
- Max = Pen;
- }
-
- SetMaxPen(Info->Window->RPort,Max);
- }
- else
- {
- Info->MenuText = Pens[DETAILPEN];
- Info->MenuBack = Pens[BLOCKPEN];
- Info->MenuTextSelect = ~Pens[DETAILPEN];
- Info->MenuBackSelect = ~Pens[BLOCKPEN];
- }
-
- SetFont(Info->Window->RPort,Info->Font);
- }
-
- if(!(RPort = ObtainGIRPort(InputInfo->gpi_GInfo)))
- {
- if(Info->Window)
- {
- CloseWindow(Info->Window);
- Info->Window = NULL;
- }
- }
- }
- }
- }
- }
-
- if(!Info->Window)
- Info->Flags |= PIF_SingleActive;
-
- if(((Info->Flags & PIF_SingleActive) || Info->Window) && RPort)
- {
- UWORD Width,Height;
-
- Info->InitialActive = Info->Active;
-
- Width = gadget->Width;
- Height = gadget->Height;
-
- DrawContainer(RPort,Left,Top,Width,Height,InputInfo->gpi_GInfo,Info,TRUE,FALSE);
-
- ReleaseGIRPort(RPort);
-
- if(Info->Window)
- BoxRender(Info,InputInfo->gpi_GInfo->gi_DrInfo->dri_Pens,Info->Active,TRUE,TRUE,0);
-
- return(GMR_MEACTIVE);
- }
-
- if(RPort)
- ReleaseGIRPort(RPort);
- }
-
- return(GMR_NOREUSE);
- }
-
- STATIC ULONG __regargs
- InactiveMethod(struct IClass *class,struct Gadget *gadget,struct gpGoInactive *InactiveInfo)
- {
- PopInfo *Info = INST_DATA(class,gadget);
-
- DB(kprintf("%s %ld\n",__FUNC__,__LINE__));
-
- if(Info->Window || (Info->Flags & PIF_SingleActive))
- {
- struct RastPort *RPort;
-
- if(RPort = ObtainGIRPort(InactiveInfo->gpgi_GInfo))
- {
- DrawContainer(RPort,gadget->LeftEdge,gadget->TopEdge,gadget->Width,gadget->Height,InactiveInfo->gpgi_GInfo,Info,FALSE,FALSE);
-
- ReleaseGIRPort(RPort);
- }
-
- if(Info->Window)
- {
- CloseWindow(Info->Window);
- Info->Window = NULL;
- }
-
- Info->Flags &= ~PIF_SingleActive;
- }
-
- return(0);
- }
-
- ULONG __saveds __asm
- LTP_PopupClassDispatcher(register __a0 struct IClass *class,register __a2 Object *object,register __a1 Msg msg)
- {
- switch(msg->MethodID)
- {
- case OM_NEW:
- return(NewMethod(class,object,(struct opSet *)msg));
-
- case OM_UPDATE:
- case OM_SET:
- return(SetMethod(class,(struct Gadget *)object,(struct opSet *)msg));
-
- case OM_DISPOSE:
- return(DisposeMethod(class,object,msg));
-
- case GM_RENDER:
- return(RenderMethod(class,(struct Gadget *)object,(struct gpRender *)msg));
-
- case GM_HITTEST:
- return(GMR_GADGETHIT);
-
- case GM_GOINACTIVE:
- return(InactiveMethod(class,(struct Gadget *)object,(struct gpGoInactive *)msg));
-
- case GM_GOACTIVE:
- return(ActiveMethod(class,(struct Gadget *)object,(struct gpInput *)msg));
-
- case GM_HANDLEINPUT:
- return(InputMethod(class,(struct Gadget *)object,(struct gpInput *)msg));
-
- default:
- return(DoSuperMethodA(class,object,msg));
- }
- }
-
- #endif // defined(DO_POPUP_KIND) && defined(DO_BOOPSI_KIND)
-