home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format 74 / af074a.adf / archives / af74a3.lzx / Typeface / Source / gadget.c < prev    next >
C/C++ Source or Header  |  1995-06-08  |  22KB  |  844 lines

  1. /************************/
  2. /*            */
  3. /* Gadgets for Typeface */
  4. /*            */
  5. /************************/
  6.  
  7. #include "Typeface.h"
  8.  
  9. extern struct GfxBase *GfxBase;
  10.  
  11. /* For any gadget */
  12.  
  13. void Gadg_DrawBevel(struct RastPort *rp,ULONG x,ULONG y,ULONG w,ULONG h,
  14.   UBYTE pen1,UBYTE pen2)
  15. {
  16.   SetAPen(rp,pen1);
  17.   Move(rp,x+w-2,y);
  18.   Draw(rp,x,y);
  19.   Draw(rp,x,y+h-1);
  20.   Move(rp,1+x,y+h-2);
  21.   Draw(rp,1+x,1+y);
  22.  
  23.   SetAPen(rp,pen2);
  24.   Move(rp,1+x,y+h-1);
  25.   Draw(rp,x+w-1,y+h-1);
  26.   Draw(rp,x+w-1,y);
  27.   Move(rp,x+w-2,1+y);
  28.   Draw(rp,x+w-2,y+h-2);
  29. }
  30.  
  31. void Gadg_SetTag(struct TagItem *tag,ULONG id, ULONG data)
  32. {
  33.   tag->ti_Tag = id;
  34.   tag->ti_Data = data;
  35. }
  36.  
  37. /* character selection gadget */
  38.  
  39. #define CG_XOFFSET 6
  40. #define CG_YOFFSET 3
  41.  
  42. struct CharGadgData
  43. {
  44.   UWORD cg_CharWidth,cg_CharHeight;
  45.   WORD cg_FirstX,cg_FirstY;
  46.   struct TextFont *cg_TextFont;
  47.   ULONG cg_LastPressed,cg_Pos;
  48.   BOOL cg_Pressed;
  49. };
  50.  
  51. __geta4 ULONG DispatchCharGadg(__a0 Class *cl,__a2 Object *o,__a1 Msg msg);
  52. ULONG CharGadg_NEW(Class *cl,Object *o,struct opSet *ops);
  53. ULONG CharGadg_RENDER(Class *cl,struct Gadget *gadg,struct gpRender *gpr);
  54. ULONG CharGadg_GOACTIVE(Class *cl,struct Gadget *gadg,struct gpInput *gpi);
  55. ULONG CharGadg_HANDLEINPUT(Class *cl,struct Gadget *gadg,
  56.   struct gpInput *gpi);
  57. ULONG CharGadg_GOINACTIVE(Class *cl,struct Gadget *gadg,
  58.   struct gpGoInactive *gpgi);
  59. ULONG CharGadg_SET(Class *cl,struct Gadget *gadg,struct opSet *ops);
  60. ULONG CharGadg_GET(Class *cl,Object *o,struct opGet *opg);
  61. void CharGadg_DrawChar(struct RastPort *rp,struct GadgetInfo *gi,
  62.   BOOL selected,ULONG x,ULONG y,ULONG w,ULONG h,char gchar,BOOL lines);
  63. void CharGadg_DrawCurrent(struct GadgetInfo *gi,struct CharGadgData *cgd,
  64.   struct Gadget *gadg);
  65.  
  66. Class *InitCharGadgClass(void)
  67. {
  68. Class *super, *cl = NULL;
  69.  
  70.   if (super = BGUI_GetClassPtr(BGUI_BASE_GADGET))
  71.   {
  72.     cl = MakeClass(NULL,NULL,super,sizeof(struct CharGadgData),0);
  73.     if (cl) cl->cl_Dispatcher.h_Entry = DispatchCharGadg;
  74.   }
  75.   return cl;
  76. }
  77.  
  78. BOOL FreeCharGadgClass(Class *cl)
  79. {
  80.   return FreeClass(cl);
  81. }
  82.  
  83. ULONG GetCharGadgWidth(void)
  84. {
  85.   return (GfxBase->DefaultFont->tf_XSize+(CG_XOFFSET*2))*8;
  86. }
  87.  
  88. ULONG GetCharGadgHeight(void)
  89. {
  90.   return (GfxBase->DefaultFont->tf_YSize+(CG_YOFFSET*2))*8;
  91. }
  92.  
  93. __geta4 ULONG DispatchCharGadg(__a0 Class *cl,__a2 Object *o,__a1 Msg msg)
  94. {
  95. ULONG retval;
  96.  
  97.   switch (msg->MethodID)
  98.   {
  99.     case OM_NEW:
  100.       retval = CharGadg_NEW(cl,o,(struct opSet *)msg);
  101.       break;
  102.     case OM_SET:
  103.       retval = CharGadg_SET(cl,(struct Gadget *)o,(struct opSet *)msg);
  104.       break;
  105.     case OM_GET:
  106.       retval = CharGadg_GET(cl,o,(struct opGet *)msg);
  107.       break;
  108.     case GM_RENDER:
  109.       retval = CharGadg_RENDER(cl,(struct Gadget *)o,(struct gpRender *)msg);
  110.       break;
  111.     case GM_GOACTIVE:
  112.       retval = CharGadg_GOACTIVE(cl,(struct Gadget *)o,
  113.     (struct gpInput *)msg);
  114.       break;
  115.     case GM_HANDLEINPUT:
  116.       retval = CharGadg_HANDLEINPUT(cl,(struct Gadget *)o,
  117.     (struct gpInput *)msg);
  118.       break;
  119.     case GM_GOINACTIVE:
  120.       retval = CharGadg_GOINACTIVE(cl,(struct Gadget *)o,
  121.     (struct gpGoInactive *)msg);
  122.       break;
  123.     default:
  124.       retval = DoSuperMethodA(cl,o,(Msg *)msg);
  125.       break;
  126.   }
  127.   return retval;
  128. }
  129.  
  130. ULONG CharGadg_NEW(Class *cl,Object *o,struct opSet *ops)
  131. {
  132. ULONG retval = 0;
  133. struct CharGadgData *cgd;
  134.  
  135.   retval = (ULONG)DoSuperMethodA(cl,o,(Msg *)ops);
  136.   if (retval)
  137.   {
  138.     cgd = INST_DATA(cl,retval);
  139.     cgd->cg_TextFont = GfxBase->DefaultFont;
  140.     cgd->cg_CharWidth = cgd->cg_TextFont->tf_XSize+(CG_XOFFSET*2);
  141.     cgd->cg_CharHeight = cgd->cg_TextFont->tf_YSize+(CG_YOFFSET*2);
  142.     cgd->cg_Pressed = FALSE;
  143.     cgd->cg_LastPressed = ~0;
  144.   }
  145.   return retval;
  146. }
  147.  
  148. ULONG CharGadg_RENDER(Class *cl,struct Gadget *gadg,struct gpRender *gpr)
  149. {
  150. struct RastPort *rp;
  151. struct CharGadgData *cgd = INST_DATA(cl,(Object *)gadg);
  152. struct TextFont *old_tf = NULL;
  153. UWORD i,j;
  154.  
  155.   rp = gpr->gpr_RPort;
  156.   if (rp->Font != cgd->cg_TextFont)
  157.   {
  158.     old_tf = rp->Font;
  159.     SetFont(rp,cgd->cg_TextFont);
  160.   }
  161.   if ((gpr->gpr_Redraw==GREDRAW_REDRAW)||(gpr->gpr_Redraw==GREDRAW_UPDATE))
  162.   {
  163.     for (i = 0; i < 8; i++)
  164.     {
  165.       for (j = 0; j < 8; j++) CharGadg_DrawChar(rp,gpr->gpr_GInfo,FALSE,
  166.     (j*cgd->cg_CharWidth)+gadg->LeftEdge,
  167.     (i*cgd->cg_CharHeight)+gadg->TopEdge,
  168.     cgd->cg_CharWidth,cgd->cg_CharHeight,(cgd->cg_Pos*64)+(i*8)+j,
  169.     gpr->gpr_Redraw == GREDRAW_REDRAW);
  170.     }
  171.   }
  172.   if (old_tf) SetFont(rp,old_tf);
  173.   return 0;
  174. }
  175.  
  176. ULONG CharGadg_GOACTIVE(Class *cl,struct Gadget *gadg,struct gpInput *gpi)
  177. {
  178. struct CharGadgData *cgd = INST_DATA(cl,(Object *)gadg);
  179. struct GadgetInfo *gi;
  180. WORD i,j;
  181. ULONG retval = GMR_NOREUSE;
  182.  
  183.   DoSuperMethodA(cl,(Object *)gadg,(Msg *)gpi);
  184.   cgd->cg_FirstX = -1; cgd->cg_FirstY = -1; cgd->cg_Pressed = TRUE;
  185.   j = gpi->gpi_Mouse.X / cgd->cg_CharWidth;
  186.   i = gpi->gpi_Mouse.Y / cgd->cg_CharHeight;
  187.   if ((i >= 0) && (i < 8) && (j >= 0) && (j < 8))
  188.   {
  189.     cgd->cg_FirstX = j; cgd->cg_FirstY = i;
  190.     gi = gpi->gpi_GInfo;
  191.     CharGadg_DrawCurrent(gi,cgd,gadg);
  192.     retval = GMR_MEACTIVE;
  193.   }
  194.   return retval;
  195. }
  196.  
  197. ULONG CharGadg_HANDLEINPUT(Class *cl,struct Gadget *gadg,struct gpInput *gpi)
  198. {
  199. struct GadgetInfo *gi = gpi->gpi_GInfo;
  200. struct InputEvent *ie = gpi->gpi_IEvent;
  201. struct CharGadgData *cgd = INST_DATA(cl,(Object *)gadg);
  202. ULONG retval = GMR_MEACTIVE;
  203. WORD i,j;
  204.  
  205.   if (gi->gi_Window)
  206.   {
  207.     if ((gi->gi_Window->Flags & WFLG_WINDOWACTIVE) == 0) return GMR_NOREUSE;
  208.   }
  209.   while (ie && (retval == GMR_MEACTIVE))
  210.   {
  211.     if (ie->ie_Class == IECLASS_RAWMOUSE)
  212.     {
  213.       if (ie->ie_Code != SELECTUP)
  214.       {
  215.     j = gpi->gpi_Mouse.X / cgd->cg_CharWidth;
  216.     i = gpi->gpi_Mouse.Y / cgd->cg_CharHeight;
  217.     if ((i == cgd->cg_FirstY) && (j == cgd->cg_FirstX))
  218.     {
  219.       if (cgd->cg_Pressed == FALSE)
  220.       {
  221.         cgd->cg_Pressed = TRUE;
  222.         CharGadg_DrawCurrent(gi,cgd,gadg);
  223.       }
  224.     }
  225.     else
  226.     {
  227.       if (cgd->cg_Pressed == TRUE)
  228.       {
  229.         cgd->cg_Pressed = FALSE;
  230.         CharGadg_DrawCurrent(gi,cgd,gadg);
  231.       }
  232.     }
  233.       }
  234.       else retval = GMR_NOREUSE|GMR_VERIFY;
  235.     }
  236.     ie = ie->ie_NextEvent;
  237.   }
  238.   return retval;
  239. }
  240.  
  241. ULONG CharGadg_GOINACTIVE(Class *cl,struct Gadget *gadg,
  242.   struct gpGoInactive *gpgi)
  243. {
  244. struct CharGadgData *cgd = INST_DATA(cl,(Object *)gadg);
  245. struct GadgetInfo *gi;
  246. struct RastPort *rp;
  247. struct TextFont *old_tf = NULL;
  248. struct TagItem inactive;
  249. ULONG retval;
  250.  
  251.   retval = DoSuperMethodA(cl,(Object *)gadg,(Msg *)gpgi);
  252.   if ((cgd->cg_FirstX != -1) && (cgd->cg_FirstY != -1))
  253.   {
  254.     gi = gpgi->gpgi_GInfo;
  255.     if (cgd->cg_Pressed == TRUE)
  256.     {
  257.       if (rp = ObtainGIRPort(gi))
  258.       {
  259.     if (rp->Font != cgd->cg_TextFont)
  260.     {
  261.       old_tf = rp->Font;
  262.       SetFont(rp,cgd->cg_TextFont);
  263.     }
  264.     CharGadg_DrawChar(rp,gi,FALSE,
  265.       (cgd->cg_FirstX*cgd->cg_CharWidth)+gadg->LeftEdge,
  266.       (cgd->cg_FirstY*cgd->cg_CharHeight)+gadg->TopEdge,
  267.       cgd->cg_CharWidth,cgd->cg_CharHeight,
  268.       (cgd->cg_Pos*64)+(cgd->cg_FirstY*8)+cgd->cg_FirstX,TRUE);
  269.     if (old_tf) SetFont(rp,old_tf);
  270.     ReleaseGIRPort(rp);
  271.       }
  272.       cgd->cg_LastPressed =
  273.     (cgd->cg_Pos*64)+(cgd->cg_FirstY*8)+cgd->cg_FirstX;
  274.       Gadg_SetTag(&inactive,TAG_DONE,0);
  275.       DoMethod(gadg,OM_NOTIFY,&inactive,gi,0);
  276.     }
  277.   }
  278.   return retval;
  279. }
  280.  
  281. ULONG CharGadg_SET(Class *cl,struct Gadget *gadg,struct opSet *ops)
  282. {
  283. struct TagItem *tags, *tag;
  284. ULONG retval;
  285. struct CharGadgData *cgd = INST_DATA(cl,(Object *)gadg);
  286. struct RastPort *rp;
  287.  
  288.   retval = DoSuperMethodA(cl,(Object *)gadg,(Msg *)ops);
  289.   tags = ops->ops_AttrList;
  290.   if (tags)
  291.   {
  292.     if (tag = FindTagItem(CG_Pos,tags))
  293.     {
  294.       if ((tag->ti_Data >= 0) && (tag->ti_Data < 4))
  295.       {
  296.     if (cgd->cg_Pos != tag->ti_Data)
  297.     {
  298.       cgd->cg_Pos = tag->ti_Data;
  299.       if (rp = ObtainGIRPort(ops->ops_GInfo))
  300.       {
  301.         DoMethod(gadg,GM_RENDER,ops->ops_GInfo,rp,GREDRAW_UPDATE);
  302.         ReleaseGIRPort(rp);
  303.       }
  304.     }
  305.       }
  306.     }
  307.     if (tag = FindTagItem(CG_Pressed,tags))
  308.       cgd->cg_LastPressed = tag->ti_Data;
  309.   }
  310.   return retval;
  311. }
  312.  
  313. ULONG CharGadg_GET(Class *cl,Object *o,struct opGet *opg)
  314. {
  315. struct CharGadgData *cgd = INST_DATA(cl,o);
  316. ULONG retval = TRUE;
  317.  
  318.   switch (opg->opg_AttrID)
  319.   {
  320.     case CG_Pos:
  321.       *(opg->opg_Storage) = cgd->cg_Pos;
  322.       break;
  323.     case CG_Pressed:
  324.       *(opg->opg_Storage) = cgd->cg_LastPressed;
  325.       break;
  326.     default:
  327.       retval = DoSuperMethodA(cl,o,(Msg *)opg);
  328.       break;
  329.   }
  330.   return retval;
  331. }
  332.  
  333. void CharGadg_DrawChar(struct RastPort *rp,struct GadgetInfo *gi,
  334.   BOOL selected,ULONG x,ULONG y,ULONG w,ULONG h,char gchar, BOOL lines)
  335. {
  336. struct DrawInfo *dri = gi->gi_DrInfo;
  337. UBYTE pen1,pen2,pen3,pen4;
  338.  
  339.   if (selected)
  340.   {
  341.     pen1 = dri->dri_Pens[SHADOWPEN];
  342.     pen2 = dri->dri_Pens[SHINEPEN];
  343.     pen3 = dri->dri_Pens[FILLTEXTPEN];
  344.     pen4 = dri->dri_Pens[FILLPEN];
  345.   }
  346.   else
  347.   {
  348.     pen1 = dri->dri_Pens[SHINEPEN];
  349.     pen2 = dri->dri_Pens[SHADOWPEN];
  350.     pen3 = dri->dri_Pens[TEXTPEN];
  351.     pen4 = dri->dri_Pens[BACKGROUNDPEN];
  352.   }
  353.   SetAPen(rp,pen4);
  354.   if (lines)
  355.   {
  356.     RectFill(rp,x,y,x+w-1,y+h-1);
  357.     Gadg_DrawBevel(rp,x,y,w,h,pen1,pen2);
  358.   }
  359.   else RectFill(rp,x+2,y+1,x+w-5,y+h-3);
  360.   SetAPen(rp,pen3);
  361.   SetBPen(rp,pen4);
  362.   SetDrMd(rp,JAM2);
  363.   Move(rp,x+CG_XOFFSET,y+CG_YOFFSET+rp->Font->tf_Baseline);
  364.   Text(rp,&gchar,1);
  365. }
  366.  
  367. void CharGadg_DrawCurrent(struct GadgetInfo *gi,struct CharGadgData *cgd,
  368.   struct Gadget *gadg)
  369. {
  370. struct RastPort *rp;
  371. struct TextFont *old_tf = NULL;
  372.  
  373.   if (rp = ObtainGIRPort(gi))
  374.   {
  375.     if (rp->Font != cgd->cg_TextFont)
  376.     {
  377.       old_tf = rp->Font;
  378.       SetFont(rp,cgd->cg_TextFont);
  379.     }
  380.     CharGadg_DrawChar(rp,gi,cgd->cg_Pressed,
  381.       (cgd->cg_FirstX*cgd->cg_CharWidth)+gadg->LeftEdge,
  382.       (cgd->cg_FirstY*cgd->cg_CharHeight)+gadg->TopEdge,
  383.       cgd->cg_CharWidth,cgd->cg_CharHeight,
  384.       (cgd->cg_Pos*64)+(cgd->cg_FirstY*8)+cgd->cg_FirstX,TRUE);
  385.     if (old_tf) SetFont(rp,old_tf);
  386.     ReleaseGIRPort(rp);
  387.   }
  388. }
  389.  
  390. /* character editing gadget */
  391.  
  392. struct EditGadgData
  393. {
  394.   UWORD eg_PixelX,eg_PixelY;
  395.   struct Character *eg_Char;
  396.   UWORD eg_XOffset,eg_YOffset;
  397.   struct CharNode *eg_Node;
  398.   UWORD eg_Button, eg_PixelBorder;
  399. };
  400.  
  401. __geta4 ULONG DispatchEditGadg(__a0 Class *cl,__a2 Object *o,__a1 Msg msg);
  402. ULONG EditGadg_NEW(Class *cl,Object *o,struct opSet *ops);
  403. ULONG EditGadg_GET(Class *cl,Object *o,struct opGet *opg);
  404. ULONG EditGadg_SET(Class *cl,struct Gadget *gadg,struct opSet *ops);
  405. ULONG EditGadg_RENDER(Class *cl,struct Gadget *gadg,struct gpRender *gpr);
  406. ULONG EditGadg_GOACTIVE(Class *cl,struct Gadget *gadg,struct gpInput *gpi);
  407.  
  408. Class *InitEditGadgClass(void)
  409. {
  410. Class *super, *cl = NULL;
  411.  
  412.   if (super = BGUI_GetClassPtr(BGUI_BASE_GADGET))
  413.   {
  414.     cl = MakeClass(NULL,NULL,super,sizeof(struct EditGadgData),0);
  415.     if (cl) cl->cl_Dispatcher.h_Entry = DispatchEditGadg;
  416.   }
  417.   return cl;
  418. }
  419.  
  420. BOOL FreeEditGadgClass(Class *cl)
  421. {
  422.   return FreeClass(cl);
  423. }
  424.  
  425. void EditGadg_GetSize(struct EditGadgData *egd,UWORD w,UWORD h,
  426.   UWORD *ew_ptr, UWORD *eh_ptr)
  427. {
  428. struct Character *chr;
  429.  
  430.   *ew_ptr = (w-(2*EG_XOFFSET))/(egd->eg_PixelX);
  431.   *eh_ptr = (h-(2*EG_YOFFSET))/(egd->eg_PixelY);
  432.   if (chr = egd->eg_Char)
  433.   {
  434.     if (*ew_ptr > chr->chr_Width) *ew_ptr = chr->chr_Width;
  435.     if (*eh_ptr > chr->chr_Height) *eh_ptr = chr->chr_Height;
  436.   }
  437. }
  438.  
  439. void EditGadg_Draw(Object *o, struct GadgetInfo *gi,ULONG draw)
  440. {
  441. struct RastPort *rp;
  442.  
  443.   if (rp = ObtainGIRPort(gi))
  444.   {
  445.     DoMethod(o,GM_RENDER,gi,rp,draw);
  446.     ReleaseGIRPort(rp);
  447.   }
  448. }
  449.  
  450. __geta4 ULONG DispatchEditGadg(__a0 Class *cl,__a2 Object *o,__a1 Msg msg)
  451. {
  452. ULONG retval;
  453.  
  454.   switch (msg->MethodID)
  455.   {
  456.     case OM_NEW:
  457.       retval = EditGadg_NEW(cl,o,(struct opSet *)msg);
  458.       break;
  459.     case OM_GET:
  460.       retval = EditGadg_GET(cl,o,(struct opGet *)msg);
  461.       break;
  462.     case OM_SET:
  463.     case OM_UPDATE:
  464.       retval = EditGadg_SET(cl,(struct Gadget *)o,(struct opSet *)msg);
  465.       break;
  466.     case GM_RENDER:
  467.       retval = EditGadg_RENDER(cl,(struct Gadget *)o,(struct gpRender *)msg);
  468.       break;
  469.     case GM_GOACTIVE:
  470.       retval = EditGadg_GOACTIVE(cl,(struct Gadget *)o,
  471.     (struct gpInput *)msg);
  472.       break;
  473.     default:
  474.       retval = DoSuperMethodA(cl,o,(Msg *)msg);
  475.       break;
  476.   }
  477.   return retval;
  478. }
  479.  
  480. ULONG EditGadg_NEW(Class *cl,Object *o,struct opSet *ops)
  481. {
  482. ULONG retval = 0;
  483. struct EditGadgData *egd;
  484.  
  485.   retval = (ULONG)DoSuperMethodA(cl,o,(Msg *)ops);
  486.   if (retval)
  487.   {
  488.     egd = INST_DATA(cl,retval);
  489.     egd->eg_PixelX = GetTagData(EG_PixelX,32,ops->ops_AttrList);
  490.     egd->eg_PixelY = GetTagData(EG_PixelY,16,ops->ops_AttrList);
  491.     egd->eg_Char = (struct Character *)
  492.       GetTagData(EG_CharStruct,0,ops->ops_AttrList);
  493.     egd->eg_XOffset = 0;
  494.     egd->eg_YOffset = 0;
  495.     egd->eg_Node = (struct CharNode *)
  496.       GetTagData(EG_CharNode,0,ops->ops_AttrList);
  497.     egd->eg_Button = 0;
  498.     egd->eg_PixelBorder = GetTagData(EG_PixelBorder,1,ops->ops_AttrList);
  499.   }
  500.   return retval;
  501. }
  502.  
  503. ULONG EditGadg_RENDER(Class *cl,struct Gadget *gadg,struct gpRender *gpr)
  504. {
  505. struct RastPort *rp;
  506. struct EditGadgData *egd = INST_DATA(cl,(Object *)gadg);
  507. struct DrawInfo *dri = gpr->gpr_GInfo->gi_DrInfo;
  508. struct Character *chr;
  509. UBYTE pen1,pen2,pen3;
  510. UWORD ew,eh,i,j,x,y,w,h,p;
  511.  
  512.   rp = gpr->gpr_RPort;
  513.   if ((gpr->gpr_Redraw==GREDRAW_REDRAW)||(gpr->gpr_Redraw==GREDRAW_UPDATE))
  514.   {
  515.     if ((chr = egd->eg_Char) == NULL) return 0;
  516.     pen1 = dri->dri_Pens[SHINEPEN];
  517.     pen2 = dri->dri_Pens[SHADOWPEN];
  518.     pen3 = dri->dri_Pens[BACKGROUNDPEN];
  519.     SetAfPt(rp,NULL,0);
  520.     x = gadg->LeftEdge; y = gadg->TopEdge;
  521.     w = gadg->Width; h = gadg->Height;
  522.     if (gpr->gpr_Redraw == GREDRAW_REDRAW)
  523.     {
  524.       SetAPen(rp,pen3);
  525.       RectFill(rp,x,y,x+w-1,y+h-1);
  526.     }
  527.     EditGadg_GetSize(egd,w,h,&ew,&eh);
  528.     w = (ew*(egd->eg_PixelX))+(2*EG_XOFFSET);
  529.     h = (eh*(egd->eg_PixelY))+(2*EG_YOFFSET);
  530.     p = (egd->eg_PixelBorder != 0) ? 2 : 1;
  531.     Gadg_DrawBevel(rp,x,y,w,h,pen1,pen2);
  532.     if (chr->chr_Data)
  533.     {
  534.       for (i = 0; i < ew; i++)
  535.       {
  536.     for (j = 0; j < eh; j++)
  537.     {
  538.       SetAPen(rp,(*(chr->chr_Data+((j+egd->eg_YOffset)*chr->chr_Width)+
  539.         i+egd->eg_XOffset) != 0) ? pen2 : pen3);
  540.       RectFill(rp,(i*egd->eg_PixelX)+x+EG_XOFFSET,
  541.         (j*egd->eg_PixelY)+y+EG_YOFFSET,
  542.         ((i+1)*egd->eg_PixelX)+x+EG_XOFFSET-p,
  543.         ((j+1)*egd->eg_PixelY)+y+EG_YOFFSET-p);
  544.     }
  545.       }
  546.     }
  547.   }
  548.   return 0;
  549. }
  550.  
  551. ULONG EditGadg_GET(Class *cl,Object *o,struct opGet *opg)
  552. {
  553. struct EditGadgData *egd = INST_DATA(cl,o);
  554. ULONG retval = TRUE;
  555. UWORD ew,eh;
  556.  
  557.   switch (opg->opg_AttrID)
  558.   {
  559.     case EG_Width:
  560.       EditGadg_GetSize(egd,((struct Gadget *)o)->Width,
  561.     ((struct Gadget *)o)->Height,&ew,&eh);
  562.       *(opg->opg_Storage) = ew;
  563.       break;
  564.     case EG_Height:
  565.       EditGadg_GetSize(egd,((struct Gadget *)o)->Width,
  566.     ((struct Gadget *)o)->Height,&ew,&eh);
  567.       *(opg->opg_Storage) = eh;
  568.       break;
  569.     case EG_XOffset:
  570.       *(opg->opg_Storage) = egd->eg_XOffset;
  571.       break;
  572.     case EG_YOffset:
  573.       *(opg->opg_Storage) = egd->eg_YOffset;
  574.       break;
  575.     default:
  576.       retval = DoSuperMethodA(cl,o,(Msg *)opg);
  577.       break;
  578.   }
  579.   return retval;
  580. }
  581.  
  582. ULONG EditGadg_SET(Class *cl,struct Gadget *gadg,struct opSet *ops)
  583. {
  584. struct TagItem *tags, *tag;
  585. ULONG retval,pos;
  586. UWORD ew,eh;
  587. struct EditGadgData *egd = INST_DATA(cl,(Object *)gadg);
  588.  
  589.   retval = DoSuperMethodA(cl,(Object *)gadg,(Msg *)ops);
  590.   EditGadg_GetSize(egd,gadg->Width,gadg->Height,&ew,&eh);
  591.   tags = ops->ops_AttrList;
  592.   if (tags)
  593.   {
  594.     if (tag = FindTagItem(EG_Update,tags))
  595.     {
  596.       switch (tag->ti_Data)
  597.       {
  598.     case GADG_HORIZ:
  599.       if (egd->eg_Node)
  600.       {
  601.         GetAttr(PGA_Top,egd->eg_Node->chln_HorizGadg,&pos);
  602.         if (egd->eg_XOffset != pos)
  603.         {
  604.           egd->eg_XOffset = pos;
  605.           EditGadg_Draw(gadg,ops->ops_GInfo,GREDRAW_UPDATE);
  606.         }
  607.       }
  608.       break;
  609.     case GADG_VERT:
  610.       if (egd->eg_Node)
  611.       {
  612.         GetAttr(PGA_Top,egd->eg_Node->chln_VertGadg,&pos);
  613.         if (egd->eg_YOffset != pos)
  614.         {
  615.           egd->eg_YOffset = pos;
  616.           EditGadg_Draw(gadg,ops->ops_GInfo,GREDRAW_UPDATE);
  617.         }
  618.       }
  619.       break;
  620.     case GADG_LEFT:
  621.       if (egd->eg_XOffset > 0)
  622.       {
  623.         if ((egd->eg_Button = 1-egd->eg_Button) == 0)
  624.         {
  625.           egd->eg_XOffset--;
  626.           EditGadg_Draw(gadg,ops->ops_GInfo,GREDRAW_UPDATE);
  627.           SetGadgetAttrs(egd->eg_Node->chln_HorizGadg,
  628.         egd->eg_Node->chln_Window,NULL,PGA_Top,egd->eg_XOffset,
  629.         TAG_DONE);
  630.         }
  631.       }
  632.       break;
  633.     case GADG_RIGHT:
  634.       if (egd->eg_XOffset + ew < egd->eg_Char->chr_Width)
  635.       {
  636.         if ((egd->eg_Button = 1-egd->eg_Button) == 0)
  637.         {
  638.           egd->eg_XOffset++;
  639.           EditGadg_Draw(gadg,ops->ops_GInfo,GREDRAW_UPDATE);
  640.           SetGadgetAttrs(egd->eg_Node->chln_HorizGadg,
  641.         egd->eg_Node->chln_Window,NULL,PGA_Top,egd->eg_XOffset,
  642.         TAG_DONE);
  643.         }
  644.       }
  645.       break;
  646.     case GADG_UP:
  647.       if (egd->eg_YOffset > 0)
  648.       {
  649.         if ((egd->eg_Button = 1-egd->eg_Button) == 0)
  650.         {
  651.           egd->eg_YOffset--;
  652.           EditGadg_Draw(gadg,ops->ops_GInfo,GREDRAW_UPDATE);
  653.           SetGadgetAttrs(egd->eg_Node->chln_VertGadg,
  654.         egd->eg_Node->chln_Window,NULL,PGA_Top,egd->eg_YOffset,
  655.         TAG_DONE);
  656.         }
  657.       }
  658.       break;
  659.     case GADG_DOWN:
  660.       if (egd->eg_YOffset + eh < egd->eg_Char->chr_Height)
  661.       {
  662.         if ((egd->eg_Button = 1-egd->eg_Button) == 0)
  663.         {
  664.           egd->eg_YOffset++;
  665.           EditGadg_Draw(gadg,ops->ops_GInfo,GREDRAW_UPDATE);
  666.           SetGadgetAttrs(egd->eg_Node->chln_VertGadg,
  667.         egd->eg_Node->chln_Window,NULL,PGA_Top,egd->eg_YOffset,
  668.         TAG_DONE);
  669.         }
  670.       }
  671.       break;
  672.     case GADG_NONE:
  673.       egd->eg_XOffset = 0;
  674.       egd->eg_YOffset = 0;
  675.       EditGadg_Draw(gadg,ops->ops_GInfo,GREDRAW_REDRAW);
  676.       break;
  677.       }
  678.     }
  679.     if (tag = FindTagItem(EG_XOffset,tags))
  680.     {
  681.       if (egd->eg_XOffset != tag->ti_Data)
  682.       {
  683.     egd->eg_XOffset = tag->ti_Data;
  684.     EditGadg_Draw(gadg,ops->ops_GInfo,GREDRAW_UPDATE);
  685.       }
  686.     }
  687.     if (tag = FindTagItem(EG_YOffset,tags))
  688.     {
  689.       if (egd->eg_YOffset != tag->ti_Data)
  690.       {
  691.     egd->eg_YOffset = tag->ti_Data;
  692.     EditGadg_Draw(gadg,ops->ops_GInfo,GREDRAW_UPDATE);
  693.       }
  694.     }
  695.   }
  696.   return retval;
  697. }
  698.  
  699. ULONG EditGadg_GOACTIVE(Class *cl,struct Gadget *gadg,struct gpInput *gpi)
  700. {
  701. struct EditGadgData *egd = INST_DATA(cl,(Object *)gadg);
  702. struct DrawInfo *dri = gpi->gpi_GInfo->gi_DrInfo;
  703. struct RastPort *rp;
  704. struct Character *chr;
  705. UBYTE *pixel;
  706. WORD i,j;
  707. UWORD ew,eh,p;
  708. UBYTE pen1,pen2;
  709.  
  710.   DoSuperMethodA(cl,(Object *)gadg,(Msg *)gpi);
  711.   EditGadg_GetSize(egd,gadg->Width,gadg->Height,&ew,&eh);
  712.   i = (gpi->gpi_Mouse.X - EG_XOFFSET) / egd->eg_PixelX;
  713.   j = (gpi->gpi_Mouse.Y - EG_YOFFSET) / egd->eg_PixelY;
  714.   if ((i >= 0) && (i < ew) && (j >= 0) && (j < eh))
  715.   {
  716.     if ((chr = egd->eg_Char) == NULL) return GMR_NOREUSE;
  717.     if (chr->chr_Data == NULL)
  718.     {
  719.       if ((chr->chr_Data = AllocVec(chr->chr_Width*chr->chr_Height,
  720.     MEMF_CLEAR)) == NULL) return GMR_NOREUSE;
  721.     }
  722.     pixel =
  723.       chr->chr_Data+((j+egd->eg_YOffset)*chr->chr_Width)+i+egd->eg_XOffset;
  724.     if (rp = ObtainGIRPort(gpi->gpi_GInfo))
  725.     {
  726.       pen1 = dri->dri_Pens[SHADOWPEN];
  727.       pen2 = dri->dri_Pens[BACKGROUNDPEN];
  728.       p = (egd->eg_PixelBorder != 0) ? 2 : 1;
  729.       SetAfPt(rp,NULL,0);
  730.       *pixel = 1-(*pixel);
  731.       SetAPen(rp,*pixel == 1 ? pen1 : pen2);
  732.       RectFill(rp,(i*egd->eg_PixelX)+gadg->LeftEdge+EG_XOFFSET,
  733.     (j*egd->eg_PixelY)+gadg->TopEdge+EG_YOFFSET,
  734.     ((i+1)*egd->eg_PixelX)+gadg->LeftEdge+EG_XOFFSET-p,
  735.     ((j+1)*egd->eg_PixelY)+gadg->TopEdge+EG_YOFFSET-p);
  736.       ReleaseGIRPort(rp);
  737.     }
  738.   }
  739.   return GMR_NOREUSE;
  740. }
  741.  
  742. /* slider gadget subclass */
  743.  
  744. struct SlideGadgData
  745. {
  746.   ULONG sg_Total,sg_Visible;
  747. };
  748.  
  749. __geta4 ULONG DispatchSlideGadg(__a0 Class *cl,__a2 Object *o,__a1 Msg msg);
  750. ULONG SlideGadg_NOTIFY(Class *cl,Object *o,struct opUpdate *opu);
  751. ULONG SlideGadg_NEW(Class *cl,Object *o,struct opSet *ops);
  752. ULONG SlideGadg_SET(Class *cl,Object *o,struct opSet *ops);
  753.  
  754. Class *InitSlideGadgClass(void)
  755. {
  756. Class *super, *cl = NULL;
  757.  
  758.   if (super = BGUI_GetClassPtr(BGUI_PROP_GADGET))
  759.   {
  760.     cl = MakeClass(NULL,NULL,super,0,0);
  761.     if (cl) cl->cl_Dispatcher.h_Entry = DispatchSlideGadg;
  762.   }
  763.   return cl;
  764. }
  765.  
  766. BOOL FreeSlideGadgClass(Class *cl)
  767. {
  768.   return FreeClass(cl);
  769. }
  770.  
  771. __geta4 ULONG DispatchSlideGadg(__a0 Class *cl,__a2 Object *o,__a1 Msg msg)
  772. {
  773. ULONG retval;
  774.  
  775.   switch (msg->MethodID)
  776.   {
  777.     case OM_NEW:
  778.       retval = SlideGadg_NEW(cl,o,(struct opSet *)msg);
  779.       break;
  780.     case OM_SET:
  781.     case OM_UPDATE:
  782.       retval = SlideGadg_SET(cl,o,(struct opSet *)msg);
  783.       break;
  784.     case OM_NOTIFY:
  785.       retval = SlideGadg_NOTIFY(cl,o,(struct opUpdate *)msg);
  786.       break;
  787.     default:
  788.       retval = DoSuperMethodA(cl,o,(Msg *)msg);
  789.       break;
  790.   }
  791.   return retval;
  792. }
  793.  
  794. ULONG SlideGadg_NEW(Class *cl,Object *o,struct opSet *ops)
  795. {
  796. ULONG retval = 0;
  797. struct SlideGadgData *sgd;
  798.  
  799.   retval = (ULONG)DoSuperMethodA(cl,o,(Msg *)ops);
  800.   if (retval)
  801.   {
  802.     sgd = INST_DATA(cl,retval);
  803.     sgd->sg_Total = GetTagData(PGA_Total,0,ops->ops_AttrList);
  804.     sgd->sg_Visible = GetTagData(PGA_Visible,0,ops->ops_AttrList);
  805.   }
  806.   return retval;
  807. }
  808.  
  809. ULONG SlideGadg_SET(Class *cl,Object *o,struct opSet *ops)
  810. {
  811. struct SlideGadgData *sgd = INST_DATA(cl,o);
  812. struct GadgetInfo *gi = ops->ops_GInfo;
  813. struct TagItem *tags, *tag;
  814. struct TagItem inactive;
  815. ULONG retval;
  816.  
  817.   retval = DoSuperMethodA(cl,o,(Msg *)ops);
  818.   tags = ops->ops_AttrList;
  819.   if (tags)
  820.   {
  821.     if (tag = FindTagItem(PGA_Total,tags)) sgd->sg_Total = tag->ti_Data;
  822.     if (tag = FindTagItem(PGA_Visible,tags)) sgd->sg_Visible = tag->ti_Data;
  823.     Gadg_SetTag(&inactive,TAG_DONE,0);
  824.     DoMethod((struct Gadget *)o,OM_NOTIFY,&inactive,gi,0);
  825.   }
  826.   return retval;
  827. }
  828.  
  829. ULONG SlideGadg_NOTIFY(Class *cl,Object *o,struct opUpdate *opu)
  830. {
  831. struct SlideGadgData *sgd = INST_DATA(cl,o);
  832. struct TagItem tags[3];
  833. ULONG pos = 0;
  834.  
  835.   GetAttr(PGA_Top,o,&pos);
  836.   Gadg_SetTag(&tags[0],GA_ID,((struct Gadget *)o)->GadgetID);
  837.   Gadg_SetTag(&tags[1],SCRL_Right,sgd->sg_Total-sgd->sg_Visible-pos);
  838.   if (opu->opu_AttrList == NULL)
  839.     Gadg_SetTag(&tags[2],TAG_DONE,0);
  840.   else
  841.     Gadg_SetTag(&tags[2],TAG_MORE,(ULONG)opu->opu_AttrList);
  842.   return DoSuperMethod(cl,o,OM_NOTIFY,tags,opu->opu_GInfo,opu->opu_Flags);
  843. }
  844.