home *** CD-ROM | disk | FTP | other *** search
- #include <classes/BOOPSI/gadgets.h>
- #include <classes/BOOPSI/boopsilib.h>
-
- #include <intuition/imageclass.h>
- #include <classes/boopsi/popupmenuclass.h>
- #include <string.h>
- #include <exec/memory.h>
-
- #pragma -
- #include <pragma/utility_lib.h>
- #include <clib/alib_protos.h>
- #include <pragma/intuition_lib.h>
- #include <pragma/graphics_lib.h>
- #include <pragma/layers_lib.h>
- #include <pragma/exec_lib.h>
- #include <graphics/gfxmacros.h>
- #pragma +
-
- struct InstanceData {
- STRPTR *labels;
- UWORD active;
- struct TextAttr *tattr;
- ULONG minmenu;
- ULONG columns;
- ULONG labelplace;
- UBYTE labelmark;
- UBYTE pad;
- // private:
- Object *frame;
- Object *menu;
- struct TextFont *font;
- BOOL menushown;
- UWORD labelCount;
- WORD leftborder;
- WORD rightborder;
- WORD bottomborder;
- WORD topborder;
- struct LabelText *label;
- };
-
- #define MENULEFT 21
-
- CycleClass::CycleClass()
- : BoopsiClass(sizeof(struct InstanceData),(ULONG (*)()) &dispatcher,GADGETCLASS,NULL)
- {
- }
-
- ULONG CycleClass::dispatcher(Class *cl, Object *o, Msg msg)
- {
- struct InstanceData *data;
- ULONG retval = FALSE;
- switch (msg->MethodID)
- {
- case OM_NEW:
- {
- Object *object;
- if (object = (Object *) DoSuperMethodA(cl,o,msg))
- {
- data = (struct InstanceData *) INST_DATA(cl,object);
- LONG oleft = 0;
- LONG owidth = 1;
- LONG otop = 0;
- LONG oheight = 1;
- data->labels = NULL;
- data->active = 0;
- data->tattr = NULL;
- data->minmenu = 3;
- data->font = NULL;
- data->labelCount = 0;
- data->columns = 0;
- data->labelplace = CY_LabelLeft;
- data->labelmark = '_';
- TagItemCursorC tic(((struct opSet *) msg)->ops_AttrList);
- while (!tic.isDone()) {
- /* register */ ULONG ticData = tic.itemData();
- switch (tic.itemTag())
- {
- case GA_Left:
- oleft = ticData;
- break;
- case GA_Width:
- owidth = ticData;
- break;
- case GA_Top:
- otop = ticData;
- break;
- case GA_Height:
- oheight = ticData;
- break;
- case CYA_Labels:
- data->labels = (STRPTR *) ticData;
- break;
- case CYA_Active:
- data->active = (UWORD) ticData;
- break;
- case CYA_Font:
- data->tattr = (struct TextAttr *) ticData;
- break;
- case CYA_MinMenu:
- data->minmenu = (ULONG) ticData;
- break;
- case CYA_Columns:
- data->columns = (ULONG) ticData;
- break;
- case CYA_LabelPlace:
- data->labelplace = (ULONG) ticData;
- break;
- case CYA_LabelMark:
- data->labelmark = (UBYTE) ticData;
- break;
- default:
- break;
- };
- tic.next();
- };
- data->frame = (Object *) NewObject(NULL,FRAMEICLASS,
- IA_Left, oleft,
- IA_Top, otop,
- IA_Width, owidth,
- IA_Height, oheight,
- IA_EdgesOnly, FALSE,
- IA_Recessed, FALSE,
- IA_FrameType, FRAME_BUTTON,
- TAG_END);
- data->menu = (Object *) NewObject(
- BPopupMenuC::boopsiclass()->boopsiclass(),NULL,
- GA_Left, oleft + MENULEFT,
- GA_Top, otop,
- GA_Width, owidth - MENULEFT,
- GA_Height, oheight,
- MA_Labels, data->labels,
- MA_Font, data->tattr,
- TAG_END);
- if (data->tattr)
- {
- data->font = OpenFont(data->tattr);
- };
- if (data->labels)
- {
- int i = 0;
- while (data->labels[i]) {
- i++;
- };
- data->labelCount = i;
- };
- if (data->active >= data->labelCount)
- {
- data->active = 0;
- };
- data->label = AllocLText(
- (STRPTR) ((struct Gadget *) object)->GadgetText,
- data->tattr,1,0,JAM2,data->labelmark);
- calcBorders(cl,(struct Gadget *) object, data);
- retval = (ULONG) object;
- };
- break;
- };
- case OM_DISPOSE:
- {
- data = (struct InstanceData *) INST_DATA(cl,o);
- if (data->frame)
- {
- DisposeObject(data->frame);
- };
- if (data->font)
- {
- CloseFont(data->font);
- };
- FreeLText(data->label);
- retval = DoSuperMethodA(cl,o,msg);
- break;
- };
- case OM_GET:
- {
- data = (struct InstanceData *) INST_DATA(cl,o);
- switch (((struct opGet *) msg)->opg_AttrID)
- {
- case GA_Left:
- *(((struct opGet *) msg)->opg_Storage) = ((struct Gadget *) o)->LeftEdge;
- retval = TRUE;
- break;
- case GA_Top:
- *(((struct opGet *) msg)->opg_Storage) = ((struct Gadget *) o)->TopEdge;
- retval = TRUE;
- break;
- case GA_Width:
- *(((struct opGet *) msg)->opg_Storage) = ((struct Gadget *) o)->Width;
- retval = TRUE;
- break;
- case GA_Height:
- *(((struct opGet *) msg)->opg_Storage) = ((struct Gadget *) o)->Height;
- retval = TRUE;
- break;
- case CYA_Font:
- *(((struct opGet *) msg)->opg_Storage) = (ULONG) data->tattr;
- retval = TRUE;
- break;
- case CYA_Labels:
- *(((struct opGet *) msg)->opg_Storage) = (ULONG) data->labels;
- retval = TRUE;
- break;
- case CYA_Active:
- *(((struct opGet *) msg)->opg_Storage) = (ULONG) data->active;
- retval = TRUE;
- break;
- case CYA_LeftBorder:
- *(((struct opGet *) msg)->opg_Storage) = (ULONG) data->leftborder;
- retval = TRUE;
- break;
- case CYA_RightBorder:
- *(((struct opGet *) msg)->opg_Storage) = (ULONG) data->rightborder;
- retval = TRUE;
- break;
- case CYA_TopBorder:
- *(((struct opGet *) msg)->opg_Storage) = (ULONG) data->topborder;
- retval = TRUE;
- break;
- case CYA_BottomBorder:
- *(((struct opGet *) msg)->opg_Storage) = (ULONG) data->bottomborder;
- retval = TRUE;
- break;
- case CYA_AutoWidth:
- *(((struct opGet *) msg)->opg_Storage) =
- calcWidth(cl,(struct Gadget *) o,data);
- retval = TRUE;
- break;
- case CYA_AutoHeight:
- *(((struct opGet *) msg)->opg_Storage) =
- calcHeight(cl,(struct Gadget *) o,data);
- retval = TRUE;
- break;
- case CYA_Columns:
- *(((struct opGet *) msg)->opg_Storage) = (ULONG) data->columns;
- retval = TRUE;
- break;
- case CYA_MinMenu:
- *(((struct opGet *) msg)->opg_Storage) = (ULONG) data->minmenu;
- retval = TRUE;
- break;
- case CYA_LabelPlace:
- *(((struct opGet *) msg)->opg_Storage) = (ULONG) data->labelplace;
- retval = TRUE;
- break;
- case CYA_LabelMark:
- *(((struct opGet *) msg)->opg_Storage) = (ULONG) data->labelmark;
- retval = TRUE;
- break;
- default:
- retval = DoSuperMethodA(cl,o,msg);
- break;
- };
- break;
- };
- case OM_SET:
- {
- data = (struct InstanceData *) INST_DATA(cl,o);
- BOOL needsRendering = FALSE;
- TagItemCursorC tic(((struct opSet *) msg)->ops_AttrList);
- while (!tic.isDone()) {
- /* register */ ULONG ticData = tic.itemData();
- switch (tic.itemTag())
- {
- case GA_Left:
- if (data->menu)
- SetAttrs(data->menu,GA_Left,ticData+MENULEFT,TAG_END);
- break;
- case GA_Top:
- if (data->menu)
- SetAttrs(data->menu,GA_Top,ticData,TAG_END);
- break;
- case GA_Width:
- if (data->menu)
- SetAttrs(data->menu,GA_Width,ticData-MENULEFT,TAG_END);
- break;
- case GA_Height:
- if (data->menu)
- SetAttrs(data->menu,GA_Height,ticData,TAG_END);
- break;
- case CYA_Font:
- if (data->font)
- {
- CloseFont(data->font);
- data->font = NULL;
- };
- data->tattr = (struct TextAttr *) ticData;
- if (data->menu)
- SetAttrs(data->menu,MA_Font,ticData,TAG_END);
- if (data->tattr)
- {
- data->font = OpenFont(data->tattr);
- };
- ChangeLTextFont(data->label,data->tattr);
- calcBorders(cl,(struct Gadget *) o, data);
- break;
- case CYA_Labels:
- data->labels = (STRPTR *) ticData;
- if (data->menu)
- SetAttrs(data->menu,MA_Labels,ticData,TAG_END);
- if (data->labels)
- {
- int i = 0;
- while (data->labels[i]) {
- i++;
- };
- data->labelCount = i;
- }
- else {
- data->labelCount = 0;
- };
- needsRendering = TRUE;
- break;
- case CYA_Active:
- data->active = (UWORD) ticData;
- needsRendering = TRUE;
- break;
- case CYA_MinMenu:
- data->minmenu = (ULONG) ticData;
- break;
- case CYA_Columns:
- data->columns = (ULONG) ticData;
- break;
- case CYA_Next:
- (data->active)++;
- if (data->active >= data->labelCount)
- data->active = 0;
- needsRendering = TRUE;
- break;
- case CYA_Prev:
- if (data->active == 0)
- data->active = data->labelCount - 1
- else
- (data->active)--;
- needsRendering = TRUE;
- break;
- default:
- break;
- };
- tic.next();
- };
- retval = DoSuperMethodA(cl,o,msg);
- if (data->active >= data->labelCount)
- {
- data->active = 0;
- };
- if (needsRendering)
- {
- renderCycle(cl,(struct Gadget *) o,
- (struct gpRender *) msg,data);
- };
- break;
- };
- case GM_RENDER:
- {
- data = (struct InstanceData *) INST_DATA(cl,o);
- retval = renderCycle(cl,(struct Gadget *) o,
- (struct gpRender *) msg,data);
- break;
- };
- case GM_HITTEST:
- {
- retval = GMR_GADGETHIT;
- break;
- };
- case GM_GOACTIVE:
- {
- data = (struct InstanceData *) INST_DATA(cl,o);
- if (((struct gpInput *) msg)->gpi_IEvent)
- {
- ((struct Gadget *) o)->Flags |= GFLG_SELECTED;
- renderCycle(cl,(struct Gadget *) o,
- (struct gpRender *) msg,data);
- if (((struct gpInput *) msg)->gpi_Mouse.X >= 21
- && data->minmenu <= data->labelCount)
- {
- if (data->menu)
- {
- ((struct gpInput *) msg)->gpi_Mouse.X -= MENULEFT;
- struct InputEvent *ie = ((struct gpInput *) msg)->gpi_IEvent;
- ((struct gpInput *) msg)->gpi_IEvent = NULL;
- retval = DoMethodA(data->menu,msg);
- ((struct gpInput *) msg)->gpi_IEvent = ie;
- }
- else
- retval = GMR_NOREUSE;
- data->menushown = TRUE;
- }
- else {
- data->menushown = FALSE;
- retval = GMR_MEACTIVE;
- };
- }
- else
- retval = GMR_NOREUSE;
- break;
- };
- case GM_GOINACTIVE:
- {
- data = (struct InstanceData *) INST_DATA(cl,o);
- if (data->menushown)
- {
- if (data->menu)
- {
- ULONG active;
- DoMethodA(data->menu,msg);
- GetAttr(MA_Active,data->menu,&active);
- data->active = active;
- };
- data->menushown = FALSE;
- };
- ((struct Gadget *) o)->Flags &= ~GFLG_SELECTED;
- renderCycle(cl,(struct Gadget *) o,
- (struct gpRender *) msg,data);
- break;
- };
- case GM_HANDLEINPUT:
- {
- data = (struct InstanceData *) INST_DATA(cl,o);
- struct gpInput *gpi = (struct gpInput *) msg;
- struct InputEvent *ie = gpi->gpi_IEvent;
- BOOL mouseOverGadget = ((gpi->gpi_Mouse.X >= 0) &&
- (gpi->gpi_Mouse.X < ((struct Gadget *) o)->Width) &&
- (gpi->gpi_Mouse.Y >= 0) &&
- (gpi->gpi_Mouse.Y < ((struct Gadget *) o)->Height));
- if (data->menushown)
- {
- if (data->menu)
- {
- ((struct gpInput *) msg)->gpi_Mouse.X -= MENULEFT;
- retval = DoMethodA(data->menu,msg);
- }
- else
- retval = GMR_NOREUSE;
- }
- else {
- if (mouseOverGadget)
- {
- if (!(((struct Gadget *) o)->Flags & GFLG_SELECTED))
- {
- ((struct Gadget *) o)->Flags |= GFLG_SELECTED;
- renderCycle(cl,(struct Gadget *) o,
- (struct gpRender *) msg,data);
- };
- };
- else {
- if (((struct Gadget *) o)->Flags & GFLG_SELECTED)
- {
- ((struct Gadget *) o)->Flags &= ~GFLG_SELECTED;
- renderCycle(cl,(struct Gadget *) o,
- (struct gpRender *) msg,data);
- };
- };
- switch (ie->ie_Class)
- {
- case IECLASS_RAWMOUSE:
- switch (ie->ie_Code)
- {
- case SELECTUP:
- if (mouseOverGadget)
- {
- if (ie->ie_Qualifier &
- (IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT))
- {
- if (data->active > 0)
- (data->active)--;
- else
- data->active = data->labelCount-1;
- };
- else {
- if (data->active < data->labelCount-1)
- (data->active)++;
- else
- data->active = 0;
- };
- retval = GMR_NOREUSE | GMR_VERIFY;
- }
- else {
- retval = GMR_NOREUSE;
- };
- break;
- case MENUDOWN:
- retval = GMR_REUSE;
- break;
- default:
- retval = GMR_MEACTIVE;
- break;
- };
- break;
- default:
- retval = GMR_MEACTIVE;
- break;
- };
- };
- break;
- };
- default:
- {
- retval = DoSuperMethodA(cl,o,msg);
- break;
- };
- };
- return retval;
- }
-
- ULONG CycleClass::renderCycle(Class *cl, struct Gadget *g,
- struct gpRender *msg, struct InstanceData *data)
- {
- static UWORD ditherData[] = { 0x1111,0x4444 };
-
- struct RastPort *rp;
- struct GadgetInfo *ginfo;
- if (msg->MethodID == OM_SET || msg->MethodID == OM_UPDATE)
- ginfo = ((struct opSet *) msg)->ops_GInfo
- else
- ginfo = msg->gpr_GInfo;
- if (!ginfo)
- return TRUE;
- UWORD *pens = ginfo->gi_DrInfo->dri_Pens;
- if (msg->MethodID == GM_RENDER)
- rp = msg->gpr_RPort
- else
- rp = ObtainGIRPort(ginfo);
- if (rp)
- {
- UWORD shine = pens[SHINEPEN];
- UWORD shadow = pens[SHADOWPEN];
- if (data->frame)
- {
- SetAttrs(data->frame,
- IA_Left,g->LeftEdge,
- IA_Top,g->TopEdge,
- IA_Width,g->Width,
- IA_Height,g->Height,
- TAG_END);
- if (g->Flags & GFLG_SELECTED)
- {
- DrawImageState(rp,(struct Image *) data->frame,0,0,
- IDS_SELECTED,ginfo->gi_DrInfo);
- UWORD x = shine;
- shine = shadow;
- shadow = x;
- }
- else {
- DrawImageState(rp,(struct Image *) data->frame,0,0,
- IDS_NORMAL,ginfo->gi_DrInfo);
- };
- };
- UWORD l = g->LeftEdge;
- UWORD t = g->TopEdge;
- UWORD h = g->Height;
-
- if (g->GadgetText && data->font)
- {
- SetAPen(rp,pens[TEXTPEN]);
- SetBPen(rp,pens[BACKGROUNDPEN]);
- SetDrMd(rp,JAM2);
- ChangeLTextPens(data->label,pens[TEXTPEN],pens[BACKGROUNDPEN],JAM2);
- switch (data->labelplace)
- {
- case CY_LabelLeft:
- PrintLText(rp,data->label,
- g->LeftEdge - data->leftborder, g->TopEdge,
- data->leftborder, g->Height);
- break;
- case CY_LabelRight:
- PrintLText(rp,data->label,
- g->LeftEdge + g->Width, g->TopEdge,
- data->rightborder, g->Height,
- STADJUST_Right);
- break;
- };
- };
-
- if (data->font && g->Width > 25 && h >= 12 && h >= data->font->tf_YSize+4)
- {
- SetAPen(rp,pens[TEXTPEN]); // Cycle Image
- SetDrMd(rp,JAM1);
- Move(rp,l+6,t+3);
- Draw(rp,l+6,t+h-5);
- Move(rp,l+7,t+3);
- Draw(rp,l+7,t+h-5);
- Move(rp,l+7,t+2);
- Draw(rp,l+13,t+2);
- Move(rp,l+7,t+h-4);
- Draw(rp,l+13,t+h-4);
- WritePixel(rp,l+13,t+3);
- WritePixel(rp,l+14,t+3);
- Move(rp,l+11,t+4);
- Draw(rp,l+16,t+4);
- Move(rp,l+12,t+5);
- Draw(rp,l+15,t+5);
- WritePixel(rp,l+13,t+6);
- WritePixel(rp,l+14,t+6);
- WritePixel(rp,l+13,t+h-5);
- WritePixel(rp,l+14,t+h-5);
-
- SetAPen(rp,shadow); // Trennstrich
- Move(rp,l+20,t+2);
- Draw(rp,l+20,t+h-3);
- SetAPen(rp,shine);
- Move(rp,l+21,t+2);
- Draw(rp,l+21,t+h-3);
-
- UWORD textwidth = g->Width - 30;
- if (data->labels)
- {
- STRPTR label = data->labels[data->active];
- if (label)
- {
- TextExtent extent;
- SetFont(rp,data->font);
- ULONG c = TextFit(rp,label,strlen(label),&extent,NULL,
- 1,textwidth,h-2);
- if (c > 0)
- {
- SetAPen(rp,pens[TEXTPEN]);
- SetDrMd(rp,JAM1);
- Move(rp,l+25+extent.te_Extent.MinX+
- ((g->Width - 30 - extent.te_Extent.MinX - extent.te_Width) >> 1),
- t+((h - extent.te_Height) >> 1)- extent.te_Extent.MinY);
- Text(rp,label,c);
- };
- };
- };
- };
-
- if (g->Flags & GFLG_DISABLED)
- {
- SetDrMd(rp,JAM1);
- SetAPen(rp,pens[TEXTPEN]);
- SetAfPt(rp,ditherData,1);
- RectFill(rp,g->LeftEdge, g->TopEdge,
- g->LeftEdge + g->Width - 1, g->TopEdge + g->Height - 1);
- SetAfPt(rp,NULL,0);
- };
-
- if (msg->MethodID != GM_RENDER)
- ReleaseGIRPort(rp);
- return TRUE;
- };
- return FALSE;
- }
-
- ULONG CycleClass::calcWidth(Class *cl, struct Gadget *, struct InstanceData *data)
- {
- if (!data->tattr)
- return 54;
- ULONG width = 0;
- if (data->columns != 0)
- {
- struct IntuiText it = { 0,0,0,0,0,NULL,NULL,NULL };
- it.ITextFont = data->tattr;
- it.IText = "0";
- width = data->columns*IntuiTextLength(&it);
- }
- else {
- STRPTR *labels = data->labels;
- if (labels == NULL || *labels == NULL)
- {
- struct IntuiText it = { 0,0,0,0,0,NULL,NULL,NULL };
- it.ITextFont = data->tattr;
- it.IText = "0";
- width = 15*IntuiTextLength(&it);
- }
- else {
- while (*labels != NULL)
- {
- struct IntuiText it = { 0,0,0,0,0,NULL,NULL,NULL };
- it.ITextFont = data->tattr;
- it.IText = *labels;
- LONG w = IntuiTextLength(&it);
- if (w > width)
- width = w;
- labels++;
- };
- };
- };
- if (width < 24)
- width = 24;
- return width + 38;
- }
-
- ULONG CycleClass::calcHeight(Class *cl, struct Gadget *, struct InstanceData *data)
- {
- if (!data->tattr)
- return 12;
- return data->tattr->ta_YSize + 6;
- }
-
- VOID CycleClass::calcBorders(Class *cl, struct Gadget *g,
- struct InstanceData *data)
- {
- data->leftborder = 0;
- data->rightborder = 0;
- data->topborder = 0;
- data->bottomborder = 0;
-
- if (data->tattr && g->GadgetText)
- {
- switch (data->labelplace)
- {
- case CY_LabelLeft:
- data->leftborder = MeasureLText(data->label) + 4;
- break;
- case CY_LabelRight:
- data->rightborder = MeasureLText(data->label) + 4;
- break;
- };
- };
- }
-
- // *************************************************************
-
- BCycleC::BCycleC(GadgetEventC *ev, WindowC &w, stringarray &l, Tag tag1type, ...)
- : BGadgetC(ev,pmc.boopsiclass(),NULL,w,(struct TagItem *) &tag1type),
- GCycleC(),
- labels(l)
- {
- setAttrs(CYA_Labels,labels.strings(),TAG_END);
- }
-
- BCycleC::BCycleC(GadgetEventC *ev,WindowC &w, stringarray &l, struct TagItem *tags)
- : BGadgetC(ev,pmc.boopsiclass(),NULL,w,tags),
- GCycleC(),
- labels(l)
- {
- setAttrs(CYA_Labels,labels.strings(),TAG_END);
- }
-
- VOID BCycleC::setLabels(STRPTR *l)
- {
- labels = stringarray(l);
- setAttrs(CYA_Labels,labels.strings(),TAG_END);
- }
-
- VOID BCycleC::setLabels(STRPTR label1, ...)
- {
- labels = stringarray(&label1);
- setAttrs(CYA_Labels,labels.strings(),TAG_END);
- }
-
- STRPTR *BCycleC::getLabels()
- {
- return labels.strings();
- }
-
- ULONG BCycleC::labelsCount()
- {
- return labels.length();
- }
-
- UWORD BCycleC::addLabel(STRPTR label)
- {
- UWORD c = labels.length();
- labels.addTail(label);
- setAttrs(CYA_Labels,labels.strings(),TAG_END);
- return c;
- }
-
- VOID BCycleC::remLabel(UWORD count)
- {
- labels.remove(count);
- setAttrs(CYA_Labels,labels.strings(),TAG_END);
- }
-
- CycleClass BCycleC::pmc;
-
- // *************************************************************
-
-