home *** CD-ROM | disk | FTP | other *** search
/ Amiga ISO Collection / AmigaUtilCD2.iso / Programming / C / OTL-MC7.DMS / in.adf / classsource.lha / ClassSource / BOOPSI / gadgets / wbicondrop.c < prev   
Encoding:
C/C++ Source or Header  |  1995-02-12  |  11.7 KB  |  467 lines

  1. #include <classes/BOOPSI/gadgets.h>
  2. #include <classes/BOOPSI/boopsilib.h>
  3.  
  4. #include <classes/BOOPSI/imageclass.h>
  5. #include <exec/libraries.h>
  6.  
  7. #pragma -
  8. #include <pragma/utility_lib.h>
  9. #include <clib/alib_protos.h>
  10. #include <pragma/intuition_lib.h>
  11. #include <pragma/graphics_lib.h>
  12. #include <pragma/layers_lib.h>
  13. #include <pragma/icon_lib.h>
  14. #pragma +
  15.  
  16. extern struct Library *IntuitionBase;
  17.  
  18. struct InstanceData {
  19.     Object *frame;
  20.     struct DiskObject *diskobject;
  21.     BOOL dopriv;
  22.     struct TextAttr *tattr;
  23.     struct TextFont *font;
  24.     WORD topborder;
  25.     WORD autowidth;
  26.     WORD autoheight;
  27.     struct LabelText *label;
  28. };
  29.  
  30. WBIconDropClass::WBIconDropClass()
  31.     : BoopsiClass(sizeof(struct InstanceData),(ULONG (*)()) &dispatcher,GADGETCLASS,NULL)
  32. {
  33. }
  34.  
  35. ULONG WBIconDropClass::dispatcher(Class *cl, Object *o, Msg msg)
  36. {
  37.     struct InstanceData *data;
  38.     ULONG retval = FALSE;
  39.     switch (msg->MethodID)
  40.     {
  41.         case OM_NEW:
  42.         {
  43.             Object *object;
  44.             if (object = (Object *) DoSuperMethodA(cl,o,msg))
  45.             {
  46.                 data = (struct InstanceData *) INST_DATA(cl,object);
  47.                 data->diskobject = NULL;
  48.                 data->dopriv = FALSE;
  49.                 data->autowidth = 50;
  50.                 data->autoheight = 40;
  51.                 TagItemCursorC tic(((struct opSet *) msg)->ops_AttrList);
  52.                 while (!tic.isDone()) {
  53.                     /* register */ ULONG ticData = tic.itemData();
  54.                     switch (tic.itemTag())
  55.                     {
  56.                         case WBIDA_DiskObject:
  57.                             data->diskobject = (struct DiskObject *) ticData;
  58.                             data->dopriv = FALSE;
  59.                             break;
  60.                         case WBIDA_Name:
  61.                             data->diskobject = GetDiskObjectNew((STRPTR) ticData);
  62.                             data->dopriv = TRUE;
  63.                             break;
  64.                         case WBIDA_Font:
  65.                             data->tattr = (struct TextAttr *) ticData;
  66.                             break;
  67.                         default:
  68.                             break;
  69.                     };
  70.                     tic.next();
  71.                 };
  72.                 data->frame = (Object *) NewObject(NULL,FRAMEICLASS,
  73.                     IA_Left,((struct Gadget *) object)->LeftEdge,
  74.                     IA_Top,((struct Gadget *) object)->TopEdge,
  75.                     IA_Width,((struct Gadget *) object)->Width,
  76.                     IA_Height,((struct Gadget *) object)->Height,
  77.                     IA_EdgesOnly, FALSE,
  78.                     IA_FrameType, FRAME_ICONDROPBOX,
  79.                     IA_Recessed, IntuitionBase->lib_Version < 39,
  80.                     TAG_END);
  81.                 if (data->tattr)
  82.                 {
  83.                     data->font = OpenFont(data->tattr);
  84.                 };
  85.                 data->label = AllocLText(
  86.                     (STRPTR) ((struct Gadget *) object)->GadgetText,
  87.                     data->tattr,1,0,JAM2,0);
  88.                 data->topborder = calcTopBorder(cl,(struct Gadget *) object,data);
  89.                 struct DiskObject *dob = GetDefDiskObject(WBPROJECT);
  90.                 if (dob)
  91.                 {
  92.                     data->autowidth = dob->do_Gadget.Width + 24;
  93.                     data->autoheight = dob->do_Gadget.Height + 12;
  94.                     FreeDiskObject(dob);
  95.                 };
  96.                 retval = (ULONG) object;
  97.             };
  98.             break;
  99.         };
  100.         case OM_DISPOSE:
  101.         {
  102.             data = (struct InstanceData *) INST_DATA(cl,o);
  103.             if (data->dopriv && data->diskobject)
  104.                 FreeDiskObject(data->diskobject);
  105.             if (data->frame)
  106.                 DisposeObject(data->frame);
  107.             if (data->font)
  108.                 CloseFont(data->font);
  109.             FreeLText(data->label);
  110.             retval = DoSuperMethodA(cl,o,msg);
  111.             break;
  112.         };
  113.         case OM_GET:
  114.         {
  115.             data = (struct InstanceData *) INST_DATA(cl,o);
  116.             switch (((struct opGet *) msg)->opg_AttrID)
  117.             {
  118.                 case GA_Left:
  119.                     *(((struct opGet *) msg)->opg_Storage) = ((struct Gadget *) o)->LeftEdge;
  120.                     retval = TRUE;
  121.                     break;
  122.                 case GA_Top:
  123.                     *(((struct opGet *) msg)->opg_Storage) = ((struct Gadget *) o)->TopEdge;
  124.                     retval = TRUE;
  125.                     break;
  126.                 case GA_Width:
  127.                     *(((struct opGet *) msg)->opg_Storage) = ((struct Gadget *) o)->Width;
  128.                     retval = TRUE;
  129.                     break;
  130.                 case GA_Height:
  131.                     *(((struct opGet *) msg)->opg_Storage) = ((struct Gadget *) o)->Height;
  132.                     retval = TRUE;
  133.                     break;
  134.                 case WBIDA_DiskObject:
  135.                     *(((struct opGet *) msg)->opg_Storage) = (ULONG) data->diskobject;
  136.                     retval = TRUE;
  137.                     break;
  138.                 case WBIDA_Font:
  139.                     *(((struct opGet *) msg)->opg_Storage) = (ULONG) data->tattr;
  140.                     retval = TRUE;
  141.                     break;
  142.                 case WBIDA_LeftBorder:
  143.                     *(((struct opGet *) msg)->opg_Storage) = (ULONG) 0;
  144.                     retval = TRUE;
  145.                     break;
  146.                 case WBIDA_RightBorder:
  147.                     *(((struct opGet *) msg)->opg_Storage) = (ULONG) 0;
  148.                     retval = TRUE;
  149.                     break;
  150.                 case WBIDA_TopBorder:
  151.                     *(((struct opGet *) msg)->opg_Storage) = (ULONG) data->topborder;
  152.                     retval = TRUE;
  153.                     break;
  154.                 case WBIDA_BottomBorder:
  155.                     *(((struct opGet *) msg)->opg_Storage) = (ULONG) 0;
  156.                     retval = TRUE;
  157.                     break;
  158.                 case WBIDA_AutoWidth:
  159.                     *(((struct opGet *) msg)->opg_Storage) =
  160.                         (ULONG) calcWidth(cl,(struct Gadget *) o, data);
  161.                     retval = TRUE;
  162.                     break;
  163.                 case WBIDA_AutoHeight:
  164.                     *(((struct opGet *) msg)->opg_Storage) =
  165.                         (ULONG) calcHeight(cl,(struct Gadget *) o, data);
  166.                     retval = TRUE;
  167.                     break;
  168.                 default:
  169.                     retval = DoSuperMethodA(cl,o,msg);
  170.                     break;
  171.             };
  172.             break;
  173.         };
  174.         case OM_SET:
  175.         {
  176.             data = (struct InstanceData *) INST_DATA(cl,o);
  177.             BOOL renderIt = FALSE;
  178.             TagItemCursorC tic(((struct opSet *) msg)->ops_AttrList);
  179.             while (!tic.isDone()) {
  180.                 /* register */ ULONG ticData = tic.itemData();
  181.                 switch (tic.itemTag())
  182.                 {
  183.                     case GA_Top:
  184.                         if (data->frame)
  185.                             SetAttrs(data->frame,IA_Top,ticData,TAG_END);
  186.                         break;
  187.                     case GA_Left:
  188.                         if (data->frame)
  189.                             SetAttrs(data->frame,IA_Left,ticData,TAG_END);
  190.                         break;
  191.                     case GA_Width:
  192.                         if (data->frame)
  193.                             SetAttrs(data->frame,IA_Width,ticData,TAG_END);
  194.                         break;
  195.                     case GA_Height:
  196.                         if (data->frame)
  197.                             SetAttrs(data->frame,IA_Height,ticData,TAG_END);
  198.                         break;
  199.                     case WBIDA_DiskObject:
  200.                         if (data->dopriv && data->diskobject)
  201.                             FreeDiskObject(data->diskobject);
  202.                         data->diskobject = (struct DiskObject *) ticData;
  203.                         data->dopriv = FALSE;
  204.                         renderIt = TRUE;
  205.                         break;
  206.                     case WBIDA_Name:
  207.                         if (data->dopriv && data->diskobject)
  208.                             FreeDiskObject(data->diskobject);
  209.                         data->diskobject = GetDiskObjectNew((STRPTR) ticData);
  210.                         data->dopriv = TRUE;
  211.                         renderIt = TRUE;
  212.                         break;
  213.                     case WBIDA_Font:
  214.                         if (data->font)
  215.                         {
  216.                             CloseFont(data->font);
  217.                             data->font = NULL;
  218.                         };
  219.                         data->tattr = (struct TextAttr *) ticData;
  220.                         if (data->tattr)
  221.                         {
  222.                             data->font = OpenFont(data->tattr);
  223.                         };
  224.                         ChangeLTextFont(data->label,data->tattr);
  225.                         data->topborder = calcTopBorder(cl,(struct Gadget *) o,data);
  226.                         break;
  227.                     default:
  228.                         break;
  229.                 };
  230.                 tic.next();
  231.             };
  232.             retval = DoSuperMethodA(cl,o,msg);
  233.             if (renderIt)
  234.             {
  235.                 render(cl,(struct Gadget *) o, (struct gpRender *) msg,data);
  236.             };
  237.             break;
  238.         };
  239.         case GM_RENDER:
  240.         {
  241.             data = (struct InstanceData *) INST_DATA(cl,o);
  242.             retval = render(cl,(struct Gadget *) o,
  243.                 (struct gpRender *) msg,data);
  244.             break;
  245.         };
  246.         case GM_HITTEST:
  247.         {
  248.             retval = 0;
  249.             break;
  250.         };
  251.         case GM_GOACTIVE:
  252.         {
  253.             data = (struct InstanceData *) INST_DATA(cl,o);
  254.             if (((struct gpInput *) msg)->gpi_IEvent)
  255.             {
  256.                 ((struct Gadget *) msg)->Flags |= GFLG_SELECTED;
  257.                 render(cl,(struct Gadget *) o,
  258.                     (struct gpRender *) msg,data);
  259.                 retval = GMR_MEACTIVE;
  260.             }
  261.             else
  262.                 retval = GMR_NOREUSE;
  263.             break;
  264.         };
  265.         case GM_GOINACTIVE:
  266.         {
  267.             data = (struct InstanceData *) INST_DATA(cl,o);
  268.             ((struct Gadget *) o)->Flags &= ~GFLG_SELECTED;
  269.             render(cl,(struct Gadget *) o,
  270.                 (struct gpRender *) msg,data);
  271.             break;
  272.         };
  273.         case GM_HANDLEINPUT:
  274.         {
  275.             data = (struct InstanceData *) INST_DATA(cl,o);
  276.             struct gpInput *gpi = (struct gpInput *) msg;
  277.             struct InputEvent *ie = gpi->gpi_IEvent;
  278.             BOOL mouseOverGadget = ((gpi->gpi_Mouse.X >= 0) &&
  279.                     (gpi->gpi_Mouse.X < ((struct Gadget *) o)->Width) &&
  280.                     (gpi->gpi_Mouse.Y >= 0) &&
  281.                     (gpi->gpi_Mouse.Y < ((struct Gadget *) o)->Height));
  282.             if (mouseOverGadget)
  283.             {
  284.                 if (!(((struct Gadget *) o)->Flags & GFLG_SELECTED))
  285.                 {
  286.                     ((struct Gadget *) o)->Flags |= GFLG_SELECTED;
  287.                     render(cl,(struct Gadget *) o,
  288.                         (struct gpRender *) msg,data);
  289.                 };
  290.             };
  291.             else {
  292.                 if (((struct Gadget *) o)->Flags & GFLG_SELECTED)
  293.                 {
  294.                     ((struct Gadget *) o)->Flags &= ~GFLG_SELECTED;
  295.                     render(cl,(struct Gadget *) o,
  296.                         (struct gpRender *) msg,data);
  297.                 };
  298.             };
  299.             switch (ie->ie_Class)
  300.             {
  301.                 case IECLASS_RAWMOUSE:
  302.                 {
  303.                     switch (ie->ie_Code)
  304.                     {
  305.                         case SELECTUP:
  306.                             if (mouseOverGadget)
  307.                             {
  308.                                 retval = GMR_NOREUSE | GMR_VERIFY;
  309.                             }
  310.                             else {
  311.                                 retval = GMR_NOREUSE;
  312.                             };
  313.                             break;
  314.                         case MENUDOWN:
  315.                             retval = GMR_REUSE;
  316.                             break;
  317.                         default:
  318.                             retval = GMR_MEACTIVE;
  319.                             break;
  320.                     };
  321.                     break;
  322.                 };
  323.                 default:
  324.                     retval = GMR_MEACTIVE;
  325.                     break;
  326.             };
  327.             break;
  328.         };
  329.         default:
  330.         {
  331.             retval = DoSuperMethodA(cl,o,msg);
  332.             break;
  333.         };
  334.     };
  335.     return retval;
  336. }
  337.  
  338. ULONG WBIconDropClass::render(Class *cl, struct Gadget *g,
  339.     struct gpRender *msg, struct InstanceData *data)
  340. {
  341.     struct RastPort *rp;
  342.     struct GadgetInfo *ginfo;
  343.     if (msg->MethodID == OM_SET || msg->MethodID == OM_UPDATE)
  344.         ginfo = ((struct opSet *) msg)->ops_GInfo
  345.     else
  346.         ginfo = msg->gpr_GInfo;
  347.     if (!ginfo)
  348.         return FALSE;
  349.     UWORD *pens = ginfo->gi_DrInfo->dri_Pens;
  350.     if (msg->MethodID == GM_RENDER)
  351.         rp = msg->gpr_RPort
  352.     else
  353.         rp = ObtainGIRPort(ginfo);
  354.     if (rp)
  355.     {
  356.         if (data->frame)
  357.         {
  358.             DrawImageState(rp,(struct Image *) data->frame,
  359.                 0,0,IDS_NORMAL,ginfo->gi_DrInfo);
  360.         };
  361.         if (data->font && g->GadgetText && (g->Flags & GFLG_LABELSTRING))
  362.         {
  363.             PrintLText(rp,data->label,
  364.                 g->LeftEdge,g->TopEdge - data->topborder,g->Width,data->topborder,
  365.                 STADJUST_Center);
  366.         };
  367.         if (data->diskobject)
  368.         {
  369.             struct Image *im = (struct Image *) data->diskobject->do_Gadget.GadgetRender;
  370.             if (im)
  371.             {
  372.                 if ((im->Width > g->Width - 20) ||
  373.                     (im->Height > g->Height - 10))
  374.                 {
  375.                     struct Rectangle rectangle;
  376.                     struct Region *new_region = NewRegion();
  377.                     struct Region *old_region;
  378.                     if (new_region)
  379.                     {
  380.                         rectangle.MinX = g->LeftEdge + 10;
  381.                         rectangle.MinY = g->TopEdge + 5;
  382.                         rectangle.MaxX = g->LeftEdge + g->Width - 11;
  383.                         rectangle.MaxY = g->TopEdge + g->Height - 6;
  384.                         if (OrRectRegion(new_region,&rectangle))
  385.                         {
  386.                             old_region = InstallClipRegion(ginfo->gi_Window->WLayer,new_region);
  387.                             DrawImage(rp,im,
  388.                                 g->LeftEdge + (g->Width - im->Width) / 2,
  389.                                 g->TopEdge + (g->Height - im->Height) / 2);
  390.                             InstallClipRegion(ginfo->gi_Window->WLayer,old_region);
  391.                         };
  392.                         DisposeRegion(new_region);
  393.                     };
  394.                 }
  395.                 else {
  396.                     DrawImage(rp,im,
  397.                         g->LeftEdge + (g->Width - im->Width) / 2,
  398.                         g->TopEdge + (g->Height - im->Height) / 2);
  399.                 };
  400.             };
  401.         };
  402.         if (msg->MethodID != GM_RENDER)
  403.             ReleaseGIRPort(rp);
  404.         return TRUE;
  405.     };
  406.     return FALSE;
  407. }
  408.  
  409. LONG WBIconDropClass::calcWidth(Class *cl, struct Gadget *g,
  410.     struct InstanceData *data)
  411. {
  412.     WORD labelwidth = MeasureLText(data->label);
  413.     WORD dragwidth = data->autowidth;
  414.     if (data->diskobject)
  415.     {
  416.         dragwidth = data->diskobject->do_Gadget.Width + 24;
  417.     };
  418.     if (labelwidth > dragwidth)
  419.         return labelwidth;
  420.     return dragwidth;
  421. }
  422.  
  423. LONG WBIconDropClass::calcHeight(Class *cl, struct Gadget *g,
  424.     struct InstanceData *data)
  425. {
  426.     WORD dragheight = data->autoheight;
  427.     if (data->diskobject)
  428.     {
  429.         dragheight = data->diskobject->do_Gadget.Height + 12;
  430.     };
  431.     return dragheight;
  432. }
  433.  
  434. WORD WBIconDropClass::calcTopBorder(Class *cl, struct Gadget *g,
  435.     struct InstanceData *data)
  436. {
  437.     if (data->tattr && g->GadgetText && (g->Flags & GFLG_LABELSTRING))
  438.         return data->tattr->ta_YSize + 4;
  439.     return 0;
  440. }
  441.  
  442. // *************************************************************
  443.  
  444. WBIconDropClass BWBIconDropC::idc;
  445.  
  446. // *************************************************************
  447.  
  448. IconDropHandlerC::IconDropHandlerC(AppWindowC &w, BWBIconDropC &g)
  449.     : AppWindowHandlerC(w), aGadget(&g)
  450. {
  451. }
  452.  
  453. BOOL IconDropHandlerC::_forMe(AppMessageC &msg)
  454. {
  455.     if (AppWindowHandlerC::_forMe(msg))
  456.     {
  457.         BOOL b = (aGadget->left() <= msg.am_MouseX)
  458.             && (aGadget->left() + aGadget->width() > msg.am_MouseX)
  459.             && (aGadget->top() <= msg.am_MouseY)
  460.             && (aGadget->top() + aGadget->height() > msg.am_MouseY);
  461.         return b;
  462.     };
  463.     return FALSE;
  464. }
  465.  
  466. // *************************************************************
  467.