home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 3 / AACD03.BIN / AACD / Programming / Triton / Source / classes / string.c < prev    next >
C/C++ Source or Header  |  1998-05-23  |  14KB  |  425 lines

  1. /*
  2.  *  OpenTriton -- A free release of the triton.library source code
  3.  *  Copyright (C) 1993-1998  Stefan Zeiger
  4.  *
  5.  *  This program is free software; you can redistribute it and/or modify
  6.  *  it under the terms of the GNU General Public License as published by
  7.  *  the Free Software Foundation; either version 2 of the License, or
  8.  *  (at your option) any later version.
  9.  *
  10.  *  This program is distributed in the hope that it will be useful,
  11.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.  *  GNU General Public License for more details.
  14.  *
  15.  *  You should have received a copy of the GNU General Public License
  16.  *  along with this program; if not, write to the Free Software
  17.  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18.  *
  19.  */
  20.  
  21.  
  22. /****** triton.library/class_String ******
  23. *
  24. *   NAME    
  25. *    class_String -- A GadTools string gadget
  26. *
  27. *   SUPERCLASS
  28. *    class_DisplayObject
  29. *
  30. *   SYNOPSIS
  31. *    TROB_String
  32. *
  33. *   ATTRIBUTES
  34. *    <Default>        : STRPTR string
  35. *                       [create, set, get]
  36. *    TRAT_Value       : UWORD maxchars (default: 64)
  37. *                       [create]
  38. *    TRST_Filter      : STRPTR filter: Only characters in this string will
  39. *                       be accepted if present, otherwise all characters
  40. *                       are allowed.
  41. *                       [create]
  42. *    TRAT_Flags       : ULONG flags
  43. *                       - TRST_INVISIBLE         : Invisible typing
  44. *                       - TRST_NORETURNBROADCAST : Don't broadcast <Return>
  45. *                                                  key presses to the window.
  46. *                       - TRST_FLOAT             : Only one "." or "," symbol
  47. *                                                  is accepted.
  48. *                       [create]
  49. *
  50. *   APPLICATION MESSAGES
  51. *    TRMS_NEWVALUE is sent when <Return> has been pressed in an activated
  52. *    string gadget. trm_Data contains a pointer to the new string and is
  53. *    only valid as long as the object exists. It is advised that you do not
  54. *    check for TRMS_NEWVALUE messages but instead read the current string
  55. *    using TR_GetAttribute() when you need it.
  56. *
  57. *   OBJECT MESSAGES
  58. *    TROM_ACTIVATE    : Activate the string gadget.
  59. *
  60. ******/
  61.  
  62.  
  63. /////////////////////////////////////////////////////////////////////////////////////////////////////////////
  64. //////////////////////////////////////////////////////////////////////////////////////// Include our stuff //
  65. /////////////////////////////////////////////////////////////////////////////////////////////////////////////
  66.  
  67. #define TR_THIS_IS_TRITON
  68. #define TR_EXTERNAL_ONLY
  69.  
  70. #include <intuition/sghooks.h>
  71. #include <libraries/triton.h>
  72. #include <clib/triton_protos.h>
  73. #include "/internal.h"
  74. #include "string.def"
  75. #include "/prefs/Triton.h"
  76.  
  77.  
  78. /////////////////////////////////////////////////////////////////////////////////////////////////////////////
  79. ////////////////////////////////////////////////////////////////////////////////////////////// Object data //
  80. /////////////////////////////////////////////////////////////////////////////////////////////////////////////
  81.  
  82. #define OBJECT (&(object->DO.O))
  83. #define DISPLAYOBJECT (&(object->DO))
  84. #define STRING object
  85.  
  86. static const char *nullstr="";
  87.  
  88.  
  89. /////////////////////////////////////////////////////////////////////////////////////////////////////////////
  90. //////////////////////////////////////////////////////////////////////////////////////////// The edit hook //
  91. /////////////////////////////////////////////////////////////////////////////////////////////////////////////
  92.  
  93. #define KEYB_SHORTCUT        1
  94. #define KEYB_POPUP            2
  95.  
  96. #ifndef RAWKEY_UP
  97. #define RAWKEY_UP                0x4C
  98. #define RAWKEY_DOWN            0x4D
  99. #endif
  100.  
  101. #define USERFLAG_UP_DOWN_ARROW            0x1
  102. #define USERFLAG_POPUP                        0x2
  103.  
  104. struct StrGadUserData { ULONG flags; };
  105.  
  106. struct CombStringInfo {
  107.     ULONG magic;
  108.     struct CombStringInfo *self;
  109.     struct StringInfo strinfo;
  110.     struct StringExtend strextend;
  111.     struct Hook edithook;
  112.     };
  113.  
  114. #define IEQUALIFIER_SHIFT        (IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT)
  115.  
  116. ULONG __asm __saveds TR_StrEditHookEntry(register __a0 struct Hook *hook,
  117.                      register __a2 struct SGWork *sgw,
  118.                      register __a1 ULONG *msg)
  119. {
  120.   //  struct StrGadUserData *userdata;
  121.   int qual, rawcode; //, uparrow;
  122.   struct TROD_String *object;
  123.   
  124.   if( msg[0] == SGH_KEY)
  125.     {
  126.       object=((struct TROD_String *)(sgw->Gadget->UserData));
  127.       rawcode = sgw->IEvent->ie_Code;
  128.       qual = sgw->IEvent->ie_Qualifier;
  129.  
  130.       /* Apply filter */
  131.       if(sgw->Code!=27)
  132.     if(sgw->EditOp == EO_INSERTCHAR || sgw->EditOp == EO_REPLACECHAR)
  133.       if(STRING->Filter)
  134.         if(TR_FirstOccurance(sgw->Code,STRING->Filter)==-1)
  135.     {
  136.       sgw->Actions &= ~(SGA_USE|SGA_REUSE);
  137.       sgw->Actions |= SGA_BEEP;
  138.       sgw->Code = 0;
  139.     }
  140.  
  141.       /* Float separator check */
  142.       if((sgw->Code=='.')||(sgw->Code==','))
  143.     if(sgw->EditOp == EO_INSERTCHAR || sgw->EditOp == EO_REPLACECHAR)
  144.       if(STRING->Flags&TRST_FLOAT)
  145.         if((TR_FirstOccurance(',',(((struct StringInfo *)
  146.                     (((struct Gadget *)
  147.                       DISPLAYOBJECT->PrivData)->SpecialInfo))->Buffer))!=-1)
  148.            || (TR_FirstOccurance('.',(((struct StringInfo *)
  149.                        (((struct Gadget *)
  150.                          DISPLAYOBJECT->PrivData)->SpecialInfo))->Buffer))!=-1))
  151.           {
  152.         sgw->Actions &= ~(SGA_USE|SGA_REUSE);
  153.         sgw->Actions |= SGA_BEEP;
  154.         sgw->Code = 0;
  155.           }
  156.  
  157.       if( sgw->EditOp == EO_INSERTCHAR ||
  158.       sgw->EditOp == EO_REPLACECHAR ||
  159.       sgw->EditOp == EO_BADFORMAT ||
  160.       ( sgw->EditOp == EO_NOOP &&
  161.         sgw->Actions == (SGA_USE|SGA_BEEP) &&
  162.         sgw->NumChars == (sgw->StringInfo->MaxChars - 1)
  163.         )
  164.       )
  165.     {
  166.       if ((qual & IEQUALIFIER_RCOMMAND) || (sgw->Code==27))
  167.         {
  168.           sgw->Actions &= ~(SGA_USE|SGA_BEEP|SGA_REDISPLAY);
  169.           sgw->IEvent->ie_Qualifier &= ~IEQUALIFIER_RCOMMAND;
  170.           if (!(qual & IEQUALIFIER_REPEAT))
  171.         {
  172.           sgw->Actions |= SGA_REUSE|SGA_END;
  173.           sgw->Code = KEYB_SHORTCUT;
  174.         }
  175.         }
  176.     }
  177.  
  178.       if( ( (rawcode==68) && (!(STRING->Flags & TRST_NORETURNBROADCAST)) )
  179.       || (rawcode==76)
  180.       || (rawcode==77)
  181.       || (rawcode==95) )
  182.     {
  183.       sgw->Actions &= ~(SGA_USE|SGA_BEEP|SGA_REDISPLAY);
  184.       sgw->IEvent->ie_Qualifier &= ~IEQUALIFIER_RCOMMAND;
  185.       if (!(qual & IEQUALIFIER_REPEAT))
  186.         {
  187.           sgw->Actions |= SGA_REUSE|SGA_END;
  188.           sgw->Code = KEYB_SHORTCUT;
  189.         }
  190.     }
  191.  
  192. //    if (userdata = (struct StrGadUserData *)sgw->Gadget->UserData)
  193. //    {
  194. //      if (userdata->flags & USERFLAG_POPUP)
  195. //      {
  196. //        if( (sgw->IEvent->ie_Qualifier & IEQUALIFIER_SHIFT) &&
  197. //            rawcode == RAWKEY_DOWN )
  198. //        {
  199. //          sgw->Actions &= ~(SGA_USE|SGA_BEEP|SGA_REDISPLAY);
  200. //          sgw->Actions |= SGA_END;
  201. //          sgw->Code = KEYB_POPUP;
  202. //          return (TRUE);
  203. //        }
  204. //      }
  205. //      if (userdata->flags & USERFLAG_UP_DOWN_ARROW)
  206. //      {
  207. //        uparrow = (rawcode == RAWKEY_UP);
  208. //        if (uparrow || (rawcode == RAWKEY_DOWN))
  209. //        {
  210. //          sgw->Actions &= ~(SGA_USE|SGA_BEEP|SGA_REDISPLAY);
  211. //          sgw->Actions |= SGA_REUSE|SGA_END;
  212. //          sgw->Code = KEYB_SHORTCUT;
  213. //        }
  214. //      }
  215. //    }
  216.       return (TRUE);
  217.     }
  218.   return (FALSE);
  219. }
  220.  
  221. struct Hook TR_StrEditHook = { { NULL }, TR_StrEditHookEntry, NULL, NULL };
  222.  
  223.  
  224. /////////////////////////////////////////////////////////////////////////////////////////////////////////////
  225. ////////////////////////////////////////////////////////////////////////////////////////////////// Methods //
  226. /////////////////////////////////////////////////////////////////////////////////////////////////////////////
  227.  
  228. TR_METHOD(String,NEW,NewData)
  229. {
  230.   if(!TRDP_DisplayObject_NEW(object,messageid,data,metaclass->trc_SuperClass)) return NULL;
  231.   data->project->trp_IDCMPFlags|=STRINGIDCMP;
  232.  
  233.   if(STRING->MaxChars==0) STRING->MaxChars=64;
  234.   if(!(STRING->WorkBuffer=
  235.        (STRPTR)TR_AllocPooled(data->project->trp_MemPool,STRING->MaxChars+2))) return NULL;
  236.  
  237.   DISPLAYOBJECT->MinHeight=(data->project->trp_PropFont->tf_YSize)+6;
  238.   DISPLAYOBJECT->MinWidth=DISPLAYOBJECT->MinHeight;
  239.   DISPLAYOBJECT->XResize=TRUE;
  240.   DISPLAYOBJECT->Flags|=TROB_DISPLAYOBJECT_TABOK;
  241.  
  242.   return (ULONG)object;
  243. }
  244.  
  245.  
  246. TR_METHOD(String,INSTALL,InstallData)
  247. {
  248.   struct TR_Project *project;
  249.  
  250.   TRDP_DisplayObject_INSTALL(object,messageid,data,metaclass->trc_SuperClass);
  251.   project=OBJECT->Project;
  252.   TR_InternalAreaFill(project,NULL,DISPLAYOBJECT->Left+4,DISPLAYOBJECT->Top+2,
  253.               DISPLAYOBJECT->Left+DISPLAYOBJECT->Width-5,
  254.               DISPLAYOBJECT->Top+DISPLAYOBJECT->Height-3,TRBF_NONE);
  255.   if(!((STRING->StrExt)=(struct StringExtend *)
  256.        TR_AllocPooled(project->trp_MemPool,sizeof(struct StringExtend)))) return NULL;
  257.   STRING->StrExt->Pens[1]=TR_GetPen(project,TRPT_TRITONPEN,TRTP_USSTRINGGADBACK);
  258.   STRING->StrExt->Pens[0]=TR_GetPen(project,TRPT_TRITONPEN,TRTP_USSTRINGGADFRONT);
  259.   STRING->StrExt->ActivePens[1]=TR_GetPen(project,TRPT_TRITONPEN,TRTP_SSTRINGGADBACK);
  260.   STRING->StrExt->ActivePens[0]=TR_GetPen(project,TRPT_TRITONPEN,TRTP_SSTRINGGADFRONT);
  261.   if(STRING->Flags&TRST_INVISIBLE)
  262.     {
  263.       STRING->StrExt->Pens[1]=TR_GetPen(project,TRPT_TRITONPEN,TRTP_USSTRINGGADFRONT);
  264.       STRING->StrExt->ActivePens[1]=TR_GetPen(project,TRPT_TRITONPEN,TRTP_SSTRINGGADFRONT);
  265.     }
  266.   STRING->StrExt->EditHook=&TR_StrEditHook;
  267.   STRING->StrExt->WorkBuffer=STRING->WorkBuffer;
  268.   if(DISPLAYOBJECT->PrivData=(ULONG)
  269.      TR_CreateGadgetTags(OBJECT->Project,
  270.              OBJECT,
  271.              STRING_KIND,
  272.              DISPLAYOBJECT->Left,
  273.              DISPLAYOBJECT->Top,
  274.              DISPLAYOBJECT->Width,
  275.              DISPLAYOBJECT->Height,
  276.              STRINGA_Justification, GACT_STRINGLEFT,
  277.              STRINGA_ReplaceMode,   FALSE,
  278.              STRINGA_ExitHelp,      FALSE,
  279.              GA_TabCycle,           TRUE,
  280.              GTST_String,           STRING->String,
  281.              GTST_MaxChars,         STRING->MaxChars,
  282.              GA_Disabled,           TR_DO_DISABLED,
  283.              TAG_END))
  284.     {
  285.       ((struct StringInfo*)(((struct Gadget *)(DISPLAYOBJECT->PrivData))->SpecialInfo))->Extension=
  286.     (STRING->StrExt);
  287.       return 1L;
  288.     }
  289.  
  290.   return NULL;
  291. }
  292.  
  293.  
  294. TR_SIMPLEMETHOD(String,PREGTREMOVE)
  295. {
  296.   ULONG textlength;
  297.  
  298.   FreeVec((APTR)(STRING->String));
  299.   textlength=TR_FirstOccurance(0,(STRPTR)
  300.                    (((struct StringInfo *)
  301.                  (((struct Gadget *)DISPLAYOBJECT->PrivData)->SpecialInfo))->Buffer))+1;
  302.   if(!(STRING->String=AllocVec(textlength, MEMF_ANY))) return NULL;
  303.   CopyMem((APTR)
  304.       (((struct StringInfo *)(((struct Gadget *)DISPLAYOBJECT->PrivData)->SpecialInfo))->Buffer),
  305.       (APTR)(STRING->String),textlength);
  306.   return 1L;
  307. }
  308.  
  309.  
  310. TR_SIMPLEMETHOD(String,REMOVE)
  311. {
  312.   if(STRING->StrExt)
  313.     TR_FreePooled(OBJECT->Project->trp_MemPool,(APTR)(STRING->StrExt),sizeof(struct StringExtend));
  314.   return 1L;
  315. }
  316.  
  317.  
  318. TR_METHOD(String,SETATTRIBUTE,SetAttributeData)
  319. {
  320.   ULONG textlength;
  321.  
  322.   switch(data->attribute)
  323.     {
  324.     case TRAT_Value:
  325.       STRING->MaxChars=(UWORD)(data->value);
  326.       return 1;
  327.  
  328.     case TRAT_Flags:
  329.       STRING->Flags=data->value;
  330.       return 1;
  331.  
  332.     case TRST_Filter:
  333.       textlength=TR_FirstOccurance(0,(STRPTR)(data->value))+1;
  334.       if(!(STRING->Filter=
  335.        (STRPTR)TR_AllocPooled(OBJECT->Project->trp_MemPool,textlength)))
  336.     return 0;
  337.       CopyMem((APTR)(data->value),(APTR)(STRING->Filter),textlength);
  338.       return 1;
  339.  
  340.     case 0:
  341.       if(!(data->value)) data->value=(ULONG)nullstr;
  342.       if(STRING->String) FreeVec((APTR)(STRING->String));
  343.       textlength=TR_FirstOccurance(0,(STRPTR)(data->value))+1;
  344.       if(!(STRING->String=AllocVec(textlength, MEMF_ANY))) return 0;
  345.       CopyMem((APTR)(data->value),(APTR)(STRING->String),textlength);
  346.       if(DISPLAYOBJECT->Installed)
  347.     GT_SetGadgetAttrs((struct Gadget *)DISPLAYOBJECT->PrivData,OBJECT->Project->trp_Window,NULL,
  348.               GTST_String,STRING->String,GA_Disabled,TR_DO_DISABLED,
  349.               TAG_END);
  350.       return 1;
  351.  
  352.     default:
  353.       return TRDP_DisplayObject_SETATTRIBUTE(object,messageid,data,metaclass->trc_SuperClass);
  354.     }
  355. }
  356.  
  357.  
  358. TR_SIMPLEMETHOD(String,GETATTRIBUTE)
  359. {
  360.   switch((ULONG)data)
  361.     {
  362.     case 0:
  363.       return (ULONG)
  364.     (((struct StringInfo *)(((struct Gadget *)DISPLAYOBJECT->PrivData)->SpecialInfo))->Buffer);
  365.     default:
  366.       return TRDP_DisplayObject_GETATTRIBUTE(object,messageid,data,metaclass->trc_SuperClass);
  367.     }
  368. }
  369.  
  370.  
  371. TR_SIMPLEMETHOD(String,KEYDOWN)
  372. {
  373.   ActivateGadget((struct Gadget *)DISPLAYOBJECT->PrivData,OBJECT->Project->trp_Window,NULL);
  374.   OBJECT->Project->trp_CurrentID=0;
  375.   OBJECT->Project->trp_IsShortcutDown=FALSE;
  376.   return 1;
  377. }
  378.  
  379.  
  380. TR_SIMPLEMETHOD(String,DISABLED_ENABLED)
  381. {
  382.   GT_SetGadgetAttrs((struct Gadget *)DISPLAYOBJECT->PrivData,OBJECT->Project->trp_Window,NULL,
  383.             GA_Disabled,TR_DO_DISABLED,TAG_END);
  384.   return 1;
  385. }
  386.  
  387.  
  388. TR_METHOD(String,EVENT,EventData)
  389. {
  390.   struct TR_Message *m;
  391.  
  392.   if((data->imsg->Class==IDCMP_GADGETUP)&&(data->imsg->IAddress==(APTR)(DISPLAYOBJECT->PrivData)))
  393.     if(m=TR_CreateMsg(Self.DO.O.Project->trp_App))
  394.       {
  395.     m->trm_ID=DISPLAYOBJECT->ID;
  396.     m->trm_Class=TRMS_NEWVALUE;
  397.     m->trm_Data=(ULONG)
  398.       (((struct StringInfo *)(((struct Gadget *)DISPLAYOBJECT->PrivData)->SpecialInfo))->Buffer);
  399.     return TROM_EVENT_SWALLOWED;
  400.       }
  401.   return TROM_EVENT_CONTINUE;
  402. }
  403.  
  404.  
  405. TR_SIMPLEMETHOD(String,DISPOSE)
  406. {
  407.   // if(STRING->WorkBuffer) TR_FreePooled((void *)(STRING->WorkBuffer),STRING->MaxChars);
  408.   // Not needed; the entire pool gets deleted
  409.   if(STRING->String) FreeVec((APTR)(STRING->String));
  410.   return 1;
  411. }
  412.  
  413.  
  414. TR_SIMPLEMETHOD(String,ACTIVATE)
  415. {
  416.   if((struct Gadget *)DISPLAYOBJECT->PrivData)
  417.     {
  418.       TR_DoMethodID(OBJECT->Project, OBJECT->Project->trp_CurrentID, TROM_KEYCANCELLED, NULL);
  419.       //TR_DoShortcut(OBJECT->Project, 0, TR_SHORTCUT_CANCELLED, NULL);
  420.       return ActivateGadget((struct Gadget *)DISPLAYOBJECT->PrivData,
  421.                 OBJECT->Project->trp_Window,NULL);
  422.     }
  423.   return 0;
  424. }
  425.