home *** CD-ROM | disk | FTP | other *** search
- #include <classes/BOOPSI/gadgets.h>
- #include <classes/BOOPSI/boopsilib.h>
-
- #pragma -
- #include <pragma/utility_lib.h>
- #include <clib/alib_protos.h>
- #include <pragma/intuition_lib.h>
- #include <pragma/graphics_lib.h>
- #pragma +
- #include <graphics/gfxmacros.h>
- #include <string.h>
-
- struct InstanceData {
- struct TextAttr *tattr;
- struct TextFont *font;
- ULONG labelsplace;
- STRPTR *labels;
- ULONG labelscount;
- WORD leftborder;
- WORD rightborder;
- WORD topborder;
- WORD bottomborder;
- ULONG active;
- UWORD lineheight;
- WORD spacing;
- UBYTE labelmark;
- struct LabelText *label;
- };
-
- RadioClass::RadioClass()
- : BoopsiClass(sizeof(struct InstanceData),(ULONG (*)()) &dispatcher,GADGETCLASS,NULL)
- {
- }
-
- ULONG RadioClass::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);
- data->tattr = NULL;
- data->font = NULL;
- data->labelsplace = RD_LabelsRight;
- data->labels = NULL;
- data->leftborder = 0;
- data->rightborder = 0;
- data->topborder = 0;
- data->bottomborder = 0;
- data->active = 0;
- data->spacing = 0;
- data->labelmark = '_';
- TagItemCursorC tic(((struct opSet *) msg)->ops_AttrList);
- while (!tic.isDone()) {
- /* register */ ULONG ticData = tic.itemData();
- switch (tic.itemTag())
- {
- case RDA_Font:
- data->tattr = (struct TextAttr *) ticData;
- break;
- case RDA_LabelsPlace:
- data->labelsplace = (ULONG) ticData;
- break;
- case RDA_Labels:
- data->labels = (STRPTR *) ticData;
- break;
- case RDA_Active:
- data->active = (ULONG) ticData;
- break;
- case RDA_Spacing:
- data->spacing = (WORD) ticData;
- break;
- case RDA_LabelMark:
- data->labelmark = (UBYTE) ticData;
- break;
- default:
- break;
- };
- tic.next();
- };
- if (data->tattr)
- {
- data->font = OpenFont(data->tattr);
- };
- data->label = AllocLText(
- (STRPTR) ((struct Gadget *) object)->GadgetText,
- data->tattr,1,0,JAM2,data->labelmark);
- data->labelscount = countLabels(data->labels);
- calcBorders(cl,(struct Gadget *) object,data);
- retval = (ULONG) object;
- };
- break;
- };
- case OM_DISPOSE:
- {
- data = (struct InstanceData *) INST_DATA(cl,o);
- 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 RDA_Font:
- *(((struct opGet *) msg)->opg_Storage) = (ULONG) data->tattr;
- retval = TRUE;
- break;
- case RDA_LabelsPlace:
- *(((struct opGet *) msg)->opg_Storage) = (ULONG) data->labelsplace;
- retval = TRUE;
- break;
- case RDA_Labels:
- *(((struct opGet *) msg)->opg_Storage) = (ULONG) data->labels;
- retval = TRUE;
- break;
- case RDA_LeftBorder:
- *(((struct opGet *) msg)->opg_Storage) = (ULONG) data->leftborder;
- retval = TRUE;
- break;
- case RDA_RightBorder:
- *(((struct opGet *) msg)->opg_Storage) = (ULONG) data->rightborder;
- retval = TRUE;
- break;
- case RDA_TopBorder:
- *(((struct opGet *) msg)->opg_Storage) = (ULONG) data->topborder;
- retval = TRUE;
- break;
- case RDA_BottomBorder:
- *(((struct opGet *) msg)->opg_Storage) = (ULONG) data->bottomborder;
- retval = TRUE;
- break;
- case RDA_AutoWidth:
- *(((struct opGet *) msg)->opg_Storage) =
- (ULONG) calcWidth(cl,(struct Gadget *) o, data);
- retval = TRUE;
- break;
- case RDA_AutoHeight:
- *(((struct opGet *) msg)->opg_Storage) =
- (ULONG) calcHeight(cl,(struct Gadget *) o, data);
- retval = TRUE;
- break;
- case RDA_Active:
- *(((struct opGet *) msg)->opg_Storage) = (ULONG) data->active;
- retval = TRUE;
- break;
- case RDA_Spacing:
- *(((struct opGet *) msg)->opg_Storage) = (ULONG) data->spacing;
- retval = TRUE;
- break;
- case RDA_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 renderIt = FALSE;
- TagItemCursorC tic(((struct opSet *) msg)->ops_AttrList);
- while (!tic.isDone()) {
- /* register */ ULONG ticData = tic.itemData();
- switch (tic.itemTag())
- {
- case RDA_Font:
- data->tattr = (struct TextAttr *) ticData;
- if (data->font)
- {
- CloseFont(data->font);
- data->font = NULL;
- };
- if (data->tattr)
- data->font = OpenFont(data->tattr);
- ChangeLTextFont(data->label,data->tattr);
- calcBorders(cl,(struct Gadget *) o,data);
- break;
- case RDA_Active:
- data->active = (ULONG) ticData;
- renderIt = TRUE;
- break;
- case RDA_Next:
- (data->active)++;
- if (data->active >= data->labelscount)
- data->active = 0;
- renderIt = TRUE;
- break;
- case RDA_Prev:
- if (data->active == 0)
- data->active = data->labelscount - 1
- else
- (data->active)--;
- renderIt = TRUE;
- break;
- default:
- break;
- };
- tic.next();
- };
- retval = DoSuperMethodA(cl,o,msg);
- if (renderIt)
- render(cl,(struct Gadget *) o,(struct gpRender *) msg,data);
- break;
- };
- case GM_RENDER:
- {
- data = (struct InstanceData *) INST_DATA(cl,o);
- retval = render(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;
- if (data->labelscount > 0)
- {
- struct gpInput *gpi = (struct gpInput *) msg;
- UWORD pixelheight = ((struct Gadget *) o)->Height / data->labelscount;
- data->active = gpi->gpi_Mouse.Y / pixelheight
- };
- render(cl,(struct Gadget *) o,
- (struct gpRender *) msg,data);
- retval = GMR_NOREUSE;
- }
- else
- retval = GMR_NOREUSE;
- break;
- };
- case GM_GOINACTIVE:
- {
- data = (struct InstanceData *) INST_DATA(cl,o);
- ((struct Gadget *) o)->Flags &= ~GFLG_SELECTED;
- render(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 (mouseOverGadget)
- {
- if (!(((struct Gadget *) o)->Flags & GFLG_SELECTED))
- {
- ((struct Gadget *) o)->Flags |= GFLG_SELECTED;
- render(cl,(struct Gadget *) o,
- (struct gpRender *) msg,data);
- };
- };
- else {
- if (((struct Gadget *) o)->Flags & GFLG_SELECTED)
- {
- ((struct Gadget *) o)->Flags &= ~GFLG_SELECTED;
- render(cl,(struct Gadget *) o,
- (struct gpRender *) msg,data);
- };
- };
- switch (ie->ie_Class)
- {
- case IECLASS_RAWMOUSE:
- {
- switch (ie->ie_Code)
- {
- case SELECTUP:
- if (mouseOverGadget)
- {
- 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 RadioClass::render(Class *cl, struct Gadget *g,
- struct gpRender *msg, struct InstanceData *data)
- {
- 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)
- {
- if (data->labelscount > 0 && data->font)
- {
- UWORD pixelheight = g->Height / data->labelscount;
- Object *button = (Object *) NewObject(NULL,SYSICLASS,
- SYSIA_DrawInfo,ginfo->gi_DrInfo,
- SYSIA_ReferenceFont,data->font,
- SYSIA_Size,SYSISIZE_HIRES,
- SYSIA_Which,MXIMAGE,
- IA_Top,0,
- IA_Left,0,
- IA_Width,g->Width > 18 ? g->Width - 2 : g->Width,
- IA_Height,pixelheight > 10 ? pixelheight - 2 : pixelheight,
- TAG_END);
- if (button)
- {
- ChangeLTextPens(data->label,pens[TEXTPEN],pens[BACKGROUNDPEN],JAM2);
- PrintLText(rp,data->label,
- g->LeftEdge - data->leftborder, g->TopEdge - data->topborder,
- g->Width + data->rightborder, data->topborder - 4,
- STADJUST_Center);
- STRPTR *labels = data->labels;
- WORD y = g->TopEdge;
- ULONG i = 0;
- while (*labels != NULL)
- {
- DrawImageState(rp,(struct Image *) button,
- g->LeftEdge,y,
- i == data->active ? IDS_SELECTED : IDS_NORMAL,
- ginfo->gi_DrInfo);
- SetAPen(rp,pens[TEXTPEN]);
- SetBPen(rp,pens[BACKGROUNDPEN]);
- SetDrMd(rp,JAM2);
- SetFont(rp,data->font);
- switch (data->labelsplace)
- {
- case RD_LabelsLeft:
- Move(rp,g->LeftEdge - data->leftborder,
- y + (pixelheight - data->font->tf_YSize + 1) / 2 +
- data->font->tf_Baseline);
- Text(rp,*labels,strlen(*labels));
- break;
- case RD_LabelsRight:
- Move(rp,g->LeftEdge + g->Width + 4,
- y + (pixelheight - data->font->tf_YSize + 1) / 2 +
- data->font->tf_Baseline);
- Text(rp,*labels,strlen(*labels));
- break;
- };
- y += pixelheight;
- labels++;
- i++;
- };
- DisposeObject(button);
- };
- };
- if (msg->MethodID != GM_RENDER)
- ReleaseGIRPort(rp);
- return TRUE;
- };
- return FALSE;
- }
-
- VOID RadioClass::calcBorders(Class *cl, struct Gadget *g,
- struct InstanceData *data)
- {
- data->leftborder = 0;
- data->rightborder = 0;
- data->bottomborder = 0;
- data->topborder = 0;
- if (data->tattr && data->labelscount > 0)
- {
- STRPTR *labels = data->labels;
- LONG maxwidth = 0;
- struct IntuiText it;
- it.ITextFont = data->tattr;
- while (*labels != NULL)
- {
- it.IText = *labels;
- LONG width = IntuiTextLength(&it);
- if (width > maxwidth)
- maxwidth = width;
- labels++;
- };
- maxwidth += 4;
- if (g->GadgetText)
- {
- data->topborder = data->tattr->ta_YSize + 4;
- LONG width = MeasureLText(data->label);
- if (width - 17 > maxwidth)
- maxwidth = width;
- };
- switch (data->labelsplace)
- {
- case RD_LabelsLeft:
- data->leftborder = maxwidth;
- break;
- case RD_LabelsRight:
- data->rightborder = maxwidth;
- break;
- };
- };
- }
-
- ULONG RadioClass::countLabels(STRPTR *labels)
- {
- if (!labels)
- return 0;
- ULONG retval = 0;
- while (*labels != NULL)
- {
- labels++;
- retval++;
- };
- return retval;
- }
-
- WORD RadioClass::calcWidth(Class *cl, struct Gadget *g,
- struct InstanceData *data)
- {
- if (data->tattr)
- {
- WORD w = (data->tattr->ta_YSize * 17 / 9);
- return w > 17 ? w : 17;
- };
- return 17;
- }
-
- WORD RadioClass::calcHeight(Class *cl, struct Gadget *g,
- struct InstanceData *data)
- {
- if (data->tattr)
- {
- WORD h = data->tattr->ta_YSize * data->labelscount;
- return h > 9 ? h : 9;
- };
- return 9 * data->labelscount;
- }
-
- // *************************************************************
-
- RadioClass BRadioC::rc;
-
- // *************************************************************
-
-