home *** CD-ROM | disk | FTP | other *** search
/ Otherware / Otherware_1_SB_Development.iso / amiga / misc / vcb10a.lha / vcxclass.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-10-29  |  10.4 KB  |  398 lines

  1. /*
  2.  *    COPYRIGHT
  3.  *        The material published in this distribution is Freeware.
  4.  *        Copyright ⌐ 1992 remains at the author, Stefan Reisner.
  5.  *        
  6.  *        It may only be passed on unmodified and in its present
  7.  *        composition. In particular, this copyright notice must be
  8.  *        included and must be intact.
  9.  */
  10. #include <intuition/intuition.h>
  11. #include <intuition/cghooks.h>
  12. #include <intuition/classes.h>
  13. #include <intuition/classusr.h>
  14. #include <intuition/gadgetclass.h>
  15. #include <intuition/icclass.h>
  16. #include <intuition/imageclass.h>
  17. #include <libraries/gadtools.h>
  18. #include <functions.h>
  19. #include "vcx_private.h"
  20.  
  21. /***************************** private section **************************/
  22.  
  23. /*
  24.  *    create the objects that the scroll bar is made of:
  25.  *    -    the proportional gadget
  26.  *    -    the two buttons
  27.  *    -    the images for the buttons
  28.  *    return false (0) on failure.
  29.  */
  30. static int create_subgadgets( Class *class, Object *object,
  31.     struct DrawInfo *drawinfo, ULONG imagesize )
  32. {
  33.     struct VCX *vcx = INST_DATA( class, object );
  34.     struct Gadget *gadget = (struct Gadget *)object;
  35.     int success = 0;
  36.  
  37.     if( !drawinfo )
  38.         goto terminate;
  39.     vcx->more_image = NewObject( NULL, "sysiclass",
  40.         SYSIA_Which, ( vcx->freedom == FREEHORIZ ) ? RIGHTIMAGE : DOWNIMAGE,
  41.         SYSIA_DrawInfo, drawinfo,
  42.         SYSIA_Size, imagesize,
  43.         TAG_DONE );
  44.     if( !vcx->more_image )
  45.         goto terminate;
  46.     vcx->more = NewObject( NULL, "buttongclass",
  47.         GA_Image, (ULONG)vcx->more_image,
  48.         GA_ID, MORE_ID,
  49.         ( vcx->freedom == FREEHORIZ ) ?
  50.         (
  51.             ( ( gadget->Flags & GFLG_RELRIGHT ) || ( gadget->Flags & GFLG_RELWIDTH ) ) ?
  52.                 GA_RelRight
  53.             :
  54.                 GA_Left
  55.         )
  56.         :
  57.         (
  58.             ( gadget->Flags & GFLG_RELRIGHT ) ?
  59.                 GA_RelRight
  60.             :
  61.                 GA_Left
  62.         ),
  63.         ( vcx->freedom == FREEHORIZ ) ?
  64.             gadget->LeftEdge + gadget->Width - ((struct Image *)vcx->more_image)->Width
  65.         :
  66.             gadget->LeftEdge,
  67.         ( vcx->freedom == FREEVERT ) ?
  68.         (
  69.             ( ( gadget->Flags & GFLG_RELBOTTOM ) || ( gadget->Flags & GFLG_RELHEIGHT ) ) ?
  70.                 GA_RelBottom
  71.             :
  72.                 GA_Top
  73.         )
  74.         :
  75.         (
  76.             ( gadget->Flags & GFLG_RELBOTTOM ) ?
  77.                 GA_RelBottom
  78.             :
  79.                 GA_Top
  80.         ),
  81.         ( vcx->freedom == FREEVERT ) ?
  82.             gadget->TopEdge + gadget->Height - ((struct Image *)vcx->more_image)->Height
  83.         :
  84.             gadget->TopEdge,
  85.         GA_Previous, (ULONG)gadget,
  86.         ICA_TARGET, (ULONG)object,
  87.         TAG_DONE );
  88.     if( !vcx->more )
  89.         goto terminate;
  90.     vcx->less_image = NewObject( NULL, "sysiclass",
  91.         SYSIA_Which, ( vcx->freedom == FREEHORIZ ) ? LEFTIMAGE : UPIMAGE,
  92.         SYSIA_DrawInfo, drawinfo,
  93.         SYSIA_Size, imagesize,
  94.         TAG_DONE );
  95.     if( !vcx->less_image )
  96.         goto terminate;
  97.     vcx->less = NewObject( NULL, "buttongclass",
  98.         GA_Image, (ULONG)vcx->less_image,
  99.         GA_ID, LESS_ID,
  100.         ( vcx->freedom == FREEHORIZ ) ?
  101.         (
  102.             ( ( gadget->Flags & GFLG_RELRIGHT ) || ( gadget->Flags & GFLG_RELWIDTH ) ) ?
  103.                 GA_RelRight
  104.             :
  105.                 GA_Left
  106.         )
  107.         :
  108.         (
  109.             ( gadget->Flags & GFLG_RELRIGHT ) ?
  110.                 GA_RelRight
  111.             :
  112.                 GA_Left
  113.         ),
  114.         ( vcx->freedom == FREEHORIZ ) ?
  115.             gadget->LeftEdge + gadget->Width -
  116.             ((struct Gadget *)vcx->more)->Width -
  117.             ((struct Image *)vcx->less_image)->Width
  118.         :
  119.             gadget->LeftEdge,
  120.         ( vcx->freedom == FREEVERT ) ?
  121.         (
  122.             ( ( gadget->Flags & GFLG_RELBOTTOM ) || ( gadget->Flags & GFLG_RELHEIGHT ) ) ?
  123.                 GA_RelBottom
  124.             :
  125.                 GA_Top
  126.         )
  127.         :
  128.         (
  129.             ( gadget->Flags & GFLG_RELBOTTOM ) ?
  130.                 GA_RelBottom
  131.             :
  132.                 GA_Top
  133.         ),
  134.         ( vcx->freedom == FREEVERT ) ?
  135.             gadget->TopEdge + gadget->Height -
  136.             ((struct Gadget *)vcx->more)->Height -
  137.             ((struct Image *)vcx->less_image)->Height
  138.         :
  139.             gadget->TopEdge,
  140.         GA_Previous, (ULONG)vcx->more,
  141.         ICA_TARGET, (ULONG)object,
  142.         TAG_DONE );
  143.     if( !vcx->less )
  144.         goto terminate;
  145.     vcx->prop = NewObject( NULL, "propgclass",
  146.         PGA_Freedom, vcx->freedom,
  147.         ( gadget->Flags & GFLG_RELRIGHT ) ? GA_RelRight : GA_Left,
  148.         gadget->LeftEdge + ( ( vcx->freedom == FREEHORIZ ) ? 1 : 4 ),
  149.         ( gadget->Flags & GFLG_RELBOTTOM ) ? GA_RelBottom : GA_Top,
  150.         gadget->TopEdge + ( ( vcx->freedom == FREEHORIZ ) ? 2 : 1 ),
  151.         ( vcx->freedom == FREEHORIZ ) ?
  152.         (
  153.             ( gadget->Flags & GFLG_RELWIDTH ) ?
  154.                 GA_RelWidth
  155.             :
  156.                 GA_Width
  157.         )
  158.         :
  159.             GA_Width,
  160.         ( vcx->freedom == FREEHORIZ ) ?
  161.             gadget->Width -
  162.             ((struct Gadget *)vcx->more)->Width -
  163.             ((struct Gadget *)vcx->less)->Width - 4
  164.         :
  165.             ((struct Gadget *)vcx->less)->Width - 8,
  166.         ( vcx->freedom == FREEVERT ) ?
  167.         (
  168.             ( gadget->Flags & GFLG_RELHEIGHT ) ?
  169.                 GA_RelHeight
  170.             :
  171.                 GA_Height
  172.         )
  173.         :
  174.             GA_Height,
  175.         ( vcx->freedom == FREEVERT ) ?
  176.             gadget->Height -
  177.             ((struct Gadget *)vcx->more)->Height -
  178.             ((struct Gadget *)vcx->less)->Height - 3
  179.         :
  180.             ((struct Gadget *)vcx->less)->Height - 4,
  181.         GA_Previous, (ULONG)vcx->less,
  182.         PGA_Total, vcx->total,
  183.         PGA_Top, vcx->top,
  184.         PGA_Visible, vcx->visible,
  185.         PGA_NewLook, 1,
  186.         ICA_TARGET, (ULONG)object,
  187.         TAG_DONE );
  188.     if( !vcx->prop )
  189.         goto terminate;
  190.     success = 1;
  191. terminate:
  192.     return success;
  193. }
  194.  
  195. /*
  196.  *    delete the objects created by create_subgadgets()
  197.  */
  198. static void delete_subgadgets( struct VCX *vcx )
  199. {
  200.     if( vcx->prop )
  201.         DisposeObject( vcx->prop );
  202.     if( vcx->less )
  203.         DisposeObject( vcx->less );
  204.     if( vcx->less_image )
  205.         DisposeObject( vcx->less_image );
  206.     if( vcx->more )
  207.         DisposeObject( vcx->more );
  208.     if( vcx->more_image )
  209.         DisposeObject( vcx->more_image );
  210. }
  211.  
  212. /*
  213.  *    create a new instance of the VCX class.
  214.  */
  215. static ULONG newVCX( Class *class, Object *object, struct opSet *ops )
  216. {
  217.     APTR new;
  218.     struct VCX *vcx;
  219.     struct DrawInfo *drawinfo;
  220.     ULONG imagesize;
  221.  
  222.     if( new = (APTR)DoSuperMethodA( class, object, (Msg)ops ) )
  223.     {
  224.         struct Gadget *gadget = (struct Gadget *)new;
  225.         vcx = INST_DATA( class, new );
  226.         vcx->total = GetTagData( PGA_Total, 2, ops->ops_AttrList );
  227.         vcx->top = GetTagData( PGA_Top, 0, ops->ops_AttrList );
  228.         vcx->visible = GetTagData( PGA_Visible, 0, ops->ops_AttrList );
  229.         vcx->freedom = GetTagData( PGA_Freedom, FREEVERT, ops->ops_AttrList );
  230.         drawinfo = (struct DrawInfo *)GetTagData( SYSIA_DrawInfo, 0, ops->ops_AttrList );
  231.         imagesize = GetTagData( SYSIA_Size, SYSISIZE_MEDRES, ops->ops_AttrList );
  232.         if( create_subgadgets( class, new, drawinfo, imagesize ) )
  233.         {
  234.             if( vcx->freedom == FREEHORIZ )
  235.                 gadget->Height = ((struct Gadget *)vcx->prop)->Height;
  236.             else
  237.                 gadget->Width = ((struct Gadget *)vcx->prop)->Width;
  238.             return (ULONG)new;
  239.         }
  240.         delete_subgadgets( vcx );
  241.         DoSuperMethod( class, object, OM_DISPOSE );
  242.     }
  243.     return 0;
  244. }
  245.  
  246. /*
  247.  *    destroy an instance of the VCX class.
  248.  */
  249. static ULONG disposeVCX( Class *class, Object *object, Msg msg )
  250. {
  251.     struct VCX *vcx = INST_DATA( class, object );
  252.  
  253.     delete_subgadgets( vcx );
  254.     DoSuperMethodA( class, object, msg );
  255. }
  256.  
  257. /*
  258.  *    change attributes of an instance.
  259.  *
  260.  *    I prefer to keep copies of Total, Top and Visible in the instance
  261.  *    data structure, rather than calling GetAttr() each time I need them.
  262.  */
  263. static ULONG setVCX( Class *class, Object *object, struct opSet *ops )
  264. {
  265.     struct VCX *vcx = INST_DATA( class, object );
  266. #ifdef DEBUG
  267.     kprintf( "setVCX : GadgetInfo %08lx, window %08lx, req %08lx\n",
  268.         ops->ops_GInfo, ops->ops_GInfo->gi_Window, ops->ops_GInfo->gi_Requester );
  269. #endif
  270.     DoSuperMethodA( class, object, (Msg)ops );
  271.     vcx->total = GetTagData( PGA_Total, vcx->total, ops->ops_AttrList );
  272.     vcx->top = GetTagData( PGA_Top, vcx->top, ops->ops_AttrList );
  273.     vcx->visible = GetTagData( PGA_Visible, vcx->visible, ops->ops_AttrList );
  274. #ifdef DEBUG
  275.     kprintf( "setVCX : new total %ld top %ld visible %ld\n",
  276.         vcx->total, vcx->top, vcx->visible );
  277. #endif
  278.     return SetGadgetAttrs( (struct Gadget *)vcx->prop,
  279.         ops->ops_GInfo->gi_Window, ops->ops_GInfo->gi_Requester,
  280.         PGA_Total, vcx->total,
  281.         PGA_Top, vcx->top,
  282.         PGA_Visible, vcx->visible,
  283.         TAG_DONE );
  284. }
  285.  
  286. /*
  287.  *    send the current gadget ID and Top value to the target object as an OM_UPDATE method.
  288.  */
  289. static void update_target( Class *class, Object *object, struct GadgetInfo *gi, ULONG flags )
  290. {
  291.     struct Gadget *gadget = (struct Gadget *)object;
  292.     struct VCX *vcx = INST_DATA( class, object );
  293.     static struct TagItem attr_list[] = { { GA_ID }, { PGA_Top }, { TAG_DONE } };
  294.  
  295.     attr_list[0].ti_Data = gadget->GadgetID;
  296.     attr_list[1].ti_Data = vcx->top;
  297.     DoSuperMethod( class, object, OM_NOTIFY, attr_list, gi, flags );
  298. }
  299.  
  300. static ULONG updateVCX( Class *class, Object *object, struct opUpdate *opu )
  301. {
  302.     struct VCX *vcx = INST_DATA( class, object );
  303.     struct TagItem *ti, *tstate = opu->opu_AttrList;
  304.  
  305.     /* DoSuperMethodA( class, object, (Msg)opu );    we overload this completely */
  306.     while( ti = NextTagItem( &tstate ) )
  307.     {
  308.         switch( ti->ti_Tag )
  309.         {
  310.         case GA_ID:
  311.             switch( ti->ti_Data )
  312.             {
  313.             case LESS_ID:
  314.                 if( vcx->top && ( opu->opu_Flags & OPUF_INTERIM ) )
  315.                 {
  316.                     vcx->top--;
  317.                     SetGadgetAttrs( (struct Gadget *)vcx->prop,
  318.                         opu->opu_GInfo->gi_Window, opu->opu_GInfo->gi_Requester,
  319.                         PGA_Top, vcx->top, TAG_DONE );
  320.                 }
  321.                 update_target( class, object, opu->opu_GInfo, opu->opu_Flags );
  322.                 break;
  323.             case MORE_ID:
  324.                 if( ( vcx->top < vcx->total - vcx->visible ) &&
  325.                     ( opu->opu_Flags & OPUF_INTERIM ) )
  326.                 {
  327.                     vcx->top++;
  328.                     SetGadgetAttrs( (struct Gadget *)vcx->prop,
  329.                         opu->opu_GInfo->gi_Window, opu->opu_GInfo->gi_Requester,
  330.                         PGA_Top, vcx->top, TAG_DONE );
  331.                     update_target( class, object, opu->opu_GInfo, opu->opu_Flags );
  332.                 }
  333.                 update_target( class, object, opu->opu_GInfo, opu->opu_Flags );
  334.                 break;
  335.             }
  336.             break;
  337.         case PGA_Top:
  338.             vcx->top = ti->ti_Data;
  339.             update_target( class, object, opu->opu_GInfo, opu->opu_Flags );
  340.             break;
  341.         }
  342.     }
  343.     return 1;
  344. }
  345.  
  346. static ULONG dispatchVCX( Class *class, Object *object, Msg msg )
  347. {
  348. #ifdef DEBUG
  349.     kprintf( "dispatchVCX : MethodID %08lx\n", msg->MethodID );
  350. #endif
  351.     switch( msg->MethodID )
  352.     {
  353.     case OM_NEW:
  354.         return newVCX( class, object, (struct opSet *)msg );
  355.     case OM_SET:
  356.         return setVCX( class, object, (struct opSet *)msg );
  357.     case OM_UPDATE:
  358.         return updateVCX( class, object, (struct opUpdate *)msg );
  359.     case OM_DISPOSE:
  360.         return disposeVCX( class, object, msg );
  361.     case GM_HITTEST:
  362.         return 0;            /* never be hit */
  363.     case GM_GOACTIVE:
  364.         return GMR_NOREUSE;    /* never go active, never process input */
  365.     case GM_HANDLEINPUT:
  366.         return GMR_NOREUSE;    /* never go active, never process input */
  367.     default:
  368.         return DoSuperMethodA( class, object, msg );
  369.     }
  370. }
  371.  
  372. /***************************** public section **************************/
  373.  
  374. /*
  375.  *    initVCXClass() and freeVCXClass() do the obvious.
  376.  *    These are the only targets to public reference within this module.
  377.  *    Everything else is private (static) stuff.
  378.  */
  379. Class *initVCXClass( void )
  380. {
  381.     Class *class;
  382.  
  383.     if( class = MakeClass( NULL, "gadgetclass", NULL, sizeof( struct VCX ), 0 ) )
  384.     {
  385.         SetupHook( &class->cl_Dispatcher, dispatchVCX, NULL );
  386.         class->cl_UserData = 0;
  387.         return class;
  388.     }
  389.     return NULL;
  390. }
  391.  
  392. int freeVCXClass( Class *class )
  393. {
  394.     if( FreeClass( class ) )
  395.         return 1;
  396.     return 0;
  397. }
  398.