1 /***************************************************************************
3 BetterString.mcc - A better String gadget MUI Custom Class
4 Copyright (C) 1997-2000 Allan Odgaard
5 Copyright (C) 2005 by BetterString.mcc Open Source Team
7 This library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Lesser General Public
9 License as published by the Free Software Foundation; either
10 version 2.1 of the License, or (at your option) any later version.
12 This library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
17 BetterString class Support Site: http://www.sf.net/projects/bstring-mcc/
21 ***************************************************************************/
28 #include <clib/alib_protos.h>
29 #include <clib/macros.h>
30 #include <devices/clipboard.h>
31 #include <devices/inputevent.h>
32 #include <libraries/mui.h>
33 #include <proto/dos.h>
34 #include <proto/exec.h>
35 #include <proto/keymap.h>
36 #include <proto/intuition.h>
37 #include <proto/iffparse.h>
38 #include <proto/locale.h>
39 #include <proto/muimaster.h>
40 #include <proto/utility.h>
45 #include "SDI_stdarg.h"
49 #include <aros/macros.h>
50 #define LONG2BE(x) AROS_LONG2BE(x)
51 #define BE2LONG(x) AROS_BE2LONG(x)
57 static BOOL
BlockEnabled(struct InstData
*data
)
59 return((data
->Flags
& FLG_BlockEnabled
) && data
->BlockStart
!= data
->BlockStop
);
62 #if defined(__amigaos4__) || defined(__MORPHOS__)
63 static int VARARGS68K
MySPrintf(char *buf
, char *fmt
, ...)
68 RawDoFmt(fmt
, VA_ARG(args
, void *), NULL
, buf
);
73 #elif defined(__AROS__)
74 #define MySPrintf __sprintf /* from amiga lib */
76 static int STDARGS
MySPrintf(char *buf
, char *fmt
,...)
78 static const UWORD PutCharProc
[2] = {0x16C0,0x4E75};
79 /* dirty hack to avoid assembler part :-)
82 RawDoFmt(fmt
, (APTR
)(((ULONG
)&fmt
)+4), (APTR
)PutCharProc
, buf
);
88 VOID
AddToUndo (struct InstData
*data
)
91 MyFreePooled(data
->Pool
, data
->Undo
);
93 if((data
->Undo
= (STRPTR
)MyAllocPooled(data
->Pool
, strlen(data
->Contents
)+1)))
95 strcpy(data
->Undo
, data
->Contents
);
96 data
->UndoPos
= data
->BufferPos
;
97 data
->Flags
&= ~FLG_RedoAvailable
;
101 WORD
AlignOffset (Object
*obj
, struct InstData
*data
)
103 struct MUI_AreaData
*ad
= muiAreaData(obj
);
104 struct TextFont
*font
= data
->Font
? data
->Font
: ad
->mad_Font
;
105 WORD width
= ad
->mad_Box
.Width
- ad
->mad_subwidth
;
108 if(data
->Alignment
!= MUIV_String_Format_Left
)
110 STRPTR text
= data
->Contents
+data
->DisplayPos
;
111 UWORD StrLength
= strlen(text
);
112 UWORD length
, textlength
, crsr_width
;
114 length
= MyTextFit(font
, text
, StrLength
, width
, 1);
115 textlength
= MyTextLength(font
, text
, length
);
117 crsr_width
= (data
->Flags
& FLG_Active
) ? MyTextLength(font
, (*(data
->Contents
+data
->BufferPos
) == '\0') ? "n" : data
->Contents
+data
->BufferPos
, 1) : 0;
118 if(crsr_width
&& !BlockEnabled(data
) && data
->BufferPos
== data
->DisplayPos
+StrLength
)
120 textlength
+= crsr_width
;
123 switch(data
->Alignment
)
125 case MUIV_String_Format_Center
:
126 offset
= (width
- textlength
)/2;
128 case MUIV_String_Format_Right
:
129 offset
= (width
- textlength
);
136 BOOL
Reject (UBYTE code
, STRPTR reject
)
142 if(code
== *reject
++)
149 BOOL
Accept (UBYTE code
, STRPTR accept
)
151 return(accept
? !Reject(code
, accept
) : TRUE
);
154 UWORD
DecimalValue (UBYTE code
)
156 if(code
>= '0' && code
<= '9')
158 if(code
>= 'a' && code
<= 'f')
159 return(code
- 'a' + 10);
160 if(code
>= 'A' && code
<= 'F')
161 return(code
- 'A' + 10);
166 BOOL
IsHex (UBYTE code
)
169 (code
>= '0' && code
<= '9') ||
170 (code
>= 'a' && code
<= 'f') ||
171 (code
>= 'A' && code
<= 'F') ? TRUE
: FALSE
);
174 LONG
FindDigit (struct InstData
*data
)
176 WORD pos
= data
->BufferPos
;
178 if(IsDigit(data
->locale
, *(data
->Contents
+pos
)))
180 while(pos
> 0 && IsDigit(data
->locale
, *(data
->Contents
+pos
-1)))
185 while(*(data
->Contents
+pos
) != '\0' && !IsDigit(data
->locale
, *(data
->Contents
+pos
)))
189 if(*(data
->Contents
+pos
) == '\0')
191 pos
= data
->BufferPos
;
192 while(pos
&& !IsDigit(data
->locale
, *(data
->Contents
+pos
)))
195 while(pos
> 0 && IsDigit(data
->locale
, *(data
->Contents
+pos
-1)))
198 if(!pos
&& !IsDigit(data
->locale
, *data
->Contents
))
206 UWORD
NextWord (STRPTR text
, UWORD x
, struct Locale
*locale
)
208 while(IsAlNum(locale
, (UBYTE
)text
[x
]))
211 while(text
[x
] != '\0' && !IsAlNum(locale
, (UBYTE
)text
[x
]))
217 UWORD
PrevWord (STRPTR text
, UWORD x
, struct Locale
*locale
)
222 while(x
&& !IsAlNum(locale
, (UBYTE
)text
[x
]))
225 while(x
> 0 && IsAlNum(locale
, (UBYTE
)text
[x
-1]))
231 VOID
strcpyback (STRPTR dest
, STRPTR src
)
235 length
= strlen(src
)+1;
236 dest
= dest
+ length
;
246 VOID
DeleteBlock (struct InstData
*data
)
249 if(BlockEnabled(data
))
251 UWORD Blk_Start
, Blk_Width
;
252 Blk_Start
= (data
->BlockStart
< data
->BlockStop
) ? data
->BlockStart
: data
->BlockStop
;
253 Blk_Width
= abs(data
->BlockStop
-data
->BlockStart
);
254 strcpy(data
->Contents
+Blk_Start
, data
->Contents
+Blk_Start
+Blk_Width
);
255 data
->BufferPos
= Blk_Start
;
259 VOID
CopyBlock (struct InstData
*data
)
261 struct MsgPort
*port
;
262 struct IOClipReq
*iorequest
;
263 UWORD Blk_Start
, Blk_Width
;
265 if(data
->Flags
& FLG_Secret
)
268 if(BlockEnabled(data
))
270 Blk_Start
= (data
->BlockStart
< data
->BlockStop
) ? data
->BlockStart
: data
->BlockStop
;
271 Blk_Width
= abs(data
->BlockStop
-data
->BlockStart
);
276 Blk_Width
= strlen(data
->Contents
);
279 if((port
= CreateMsgPort()))
281 if((iorequest
= (struct IOClipReq
*)CreateIORequest(port
, sizeof(struct IOClipReq
))))
283 if(!OpenDevice("clipboard.device", 0, (struct IORequest
*)iorequest
, 0))
285 ULONG IFF_Head
[] = { LONG2BE(MAKE_ID('F','O','R','M')),
286 LONG2BE(12 + ((Blk_Width
+ 1) & ~1)),
287 LONG2BE(MAKE_ID('F','T','X','T')),
288 LONG2BE(MAKE_ID('C','H','R','S')),
292 iorequest
->io_ClipID
= 0;
293 iorequest
->io_Offset
= 0;
294 iorequest
->io_Data
= (STRPTR
)IFF_Head
;
295 iorequest
->io_Length
= sizeof(IFF_Head
);
296 iorequest
->io_Command
= CMD_WRITE
;
297 DoIO((struct IORequest
*)iorequest
);
299 iorequest
->io_Data
= data
->Contents
+Blk_Start
;
300 iorequest
->io_Length
= Blk_Width
;
301 DoIO((struct IORequest
*)iorequest
);
303 iorequest
->io_Command
= CMD_UPDATE
;
304 DoIO((struct IORequest
*)iorequest
);
306 CloseDevice((struct IORequest
*)iorequest
);
308 DeleteIORequest((struct IORequest
*)iorequest
);
314 VOID
Paste (struct InstData
*data
)
316 struct MsgPort
*port
;
317 struct IOClipReq
*iorequest
;
319 if((port
= CreateMsgPort()))
321 if((iorequest
= (struct IOClipReq
*)CreateIORequest(port
, sizeof(struct IOClipReq
))))
323 if(!OpenDevice("clipboard.device", 0, (struct IORequest
*)iorequest
, 0))
328 iorequest
->io_ClipID
= 0;
329 iorequest
->io_Offset
= 0;
330 iorequest
->io_Data
= (STRPTR
)IFF_Head
;
331 iorequest
->io_Length
= sizeof(IFF_Head
);
332 iorequest
->io_Command
= CMD_READ
;
333 DoIO((struct IORequest
*)iorequest
);
334 length
= IFF_Head
[1]-4;
336 if(iorequest
->io_Actual
== sizeof(IFF_Head
) &&
337 *IFF_Head
== BE2LONG(MAKE_ID('F','O','R','M')) &&
338 IFF_Head
[2] == BE2LONG(MAKE_ID('F','T','X','T')) && length
> 8)
340 iorequest
->io_Length
= 8;
341 DoIO((struct IORequest
*)iorequest
);
344 while(length
> 0 && *IFF_Head
!= BE2LONG(MAKE_ID('C','H','R','S')))
346 iorequest
->io_Offset
+= BE2LONG(IFF_Head
[1]);
347 length
-= BE2LONG(IFF_Head
[1])+8;
348 DoIO((struct IORequest
*)iorequest
);
351 if(*IFF_Head
== BE2LONG(MAKE_ID('C','H','R','S')))
353 ULONG pastelength
= BE2LONG(IFF_Head
[1]);
355 if(data
->MaxLength
&& strlen(data
->Contents
)+pastelength
> data
->MaxLength
-1)
358 pastelength
= (data
->MaxLength
-1)-strlen(data
->Contents
);
361 data
->Contents
= (STRPTR
)ExpandPool(data
->Pool
, data
->Contents
, pastelength
);
362 strcpyback(data
->Contents
+data
->BufferPos
+pastelength
, data
->Contents
+data
->BufferPos
);
363 iorequest
->io_Length
= pastelength
;
364 iorequest
->io_Data
= data
->Contents
+data
->BufferPos
;
365 DoIO((struct IORequest
*)iorequest
);
369 if(data
->Contents
[data
->BufferPos
] == '\0')
370 data
->Contents
[data
->BufferPos
] = '?';
384 iorequest
->io_Offset
= 0xfffffff;
385 iorequest
->io_Data
= NULL
;
386 DoIO((struct IORequest
*)iorequest
);
388 CloseDevice((struct IORequest
*)iorequest
);
390 DeleteIORequest((struct IORequest
*)iorequest
);
396 ULONG
ConvertKey (struct IntuiMessage
*imsg
)
398 struct InputEvent event
;
401 event
.ie_NextEvent
= NULL
;
402 event
.ie_Class
= IECLASS_RAWKEY
;
403 event
.ie_SubClass
= 0;
404 event
.ie_Code
= imsg
->Code
;
405 event
.ie_Qualifier
= imsg
->Qualifier
;
406 event
.ie_EventAddress
= (APTR
*) *((ULONG
*)imsg
->IAddress
);
408 MapRawKey(&event
, &code
, 1, NULL
);
412 ULONG
HandleInput(struct IClass
*cl
, Object
*obj
, struct MUIP_HandleEvent
*msg
)
414 struct InstData
*data
= (struct InstData
*)INST_DATA(cl
, obj
);
415 struct MUI_AreaData
*ad
= muiAreaData(obj
);
416 struct TextFont
*Font
= data
->Font
? data
->Font
: ad
->mad_Font
;
418 BOOL movement
= FALSE
;
419 BOOL deletion
= FALSE
;
423 Object
*focus
= NULL
;
424 if(msg
->muikey
== MUIKEY_UP
)
425 focus
= data
->KeyUpFocus
;
426 else if(msg
->muikey
== MUIKEY_DOWN
)
427 focus
= data
->KeyDownFocus
;
429 if(focus
&& _win(obj
))
431 set(_win(obj
), MUIA_Window_ActiveObject
, focus
);
432 result
= MUI_EventHandlerRC_Eat
;
436 WORD StringLength
= strlen(data
->Contents
);
438 if(msg
->imsg
->Class
== IDCMP_RAWKEY
&& msg
->imsg
->Code
>= IECODE_KEY_CODE_FIRST
&& msg
->imsg
->Code
<= IECODE_KEY_CODE_LAST
)
440 if(data
->Flags
& FLG_Active
)
442 if(!(data
->Flags
& FLG_BlockEnabled
))
443 data
->BlockStart
= data
->BufferPos
;
446 if(data
->Flags
& FLG_NoInput
)
448 switch(msg
->imsg
->Code
)
451 case 65: /* Backspace */
452 case 70: /* Delete */
458 if(input
) switch(msg
->imsg
->Code
)
461 if(!(msg
->imsg
->Qualifier
& IEQUALIFIER_RCOMMAND
))
464 if(!(edited
= FileNameComplete(obj
, (msg
->imsg
->Qualifier
& (IEQUALIFIER_RSHIFT
| IEQUALIFIER_LSHIFT
)) ? TRUE
: FALSE
, data
)))
470 if(data
->BufferPos
< StringLength
)
472 if(msg
->imsg
->Qualifier
& (IEQUALIFIER_LSHIFT
| IEQUALIFIER_RSHIFT
))
474 data
->BufferPos
= StringLength
;
478 if(msg
->imsg
->Qualifier
& (IEQUALIFIER_RALT
| IEQUALIFIER_LALT
))
480 data
->BufferPos
= NextWord(data
->Contents
, data
->BufferPos
, data
->locale
);
484 if(BlockEnabled(data
) && !(msg
->imsg
->Qualifier
& IEQUALIFIER_CONTROL
))
485 data
->BufferPos
= MAX(data
->BlockStart
, data
->BlockStop
);
497 if(msg
->imsg
->Qualifier
& (IEQUALIFIER_LSHIFT
| IEQUALIFIER_RSHIFT
))
503 if(msg
->imsg
->Qualifier
& (IEQUALIFIER_RALT
| IEQUALIFIER_LALT
))
505 data
->BufferPos
= PrevWord(data
->Contents
, data
->BufferPos
, data
->locale
);
509 if(BlockEnabled(data
) && !(msg
->imsg
->Qualifier
& IEQUALIFIER_CONTROL
))
510 data
->BufferPos
= MIN(data
->BlockStart
, data
->BlockStop
);
520 case 65: /* Backspace */
521 if(BlockEnabled(data
))
529 if(msg
->imsg
->Qualifier
& (IEQUALIFIER_CONTROL
| IEQUALIFIER_LSHIFT
| IEQUALIFIER_RSHIFT
))
532 strcpy(data
->Contents
, data
->Contents
+data
->BufferPos
);
537 if(msg
->imsg
->Qualifier
& (IEQUALIFIER_RALT
| IEQUALIFIER_LALT
))
539 UWORD NewPos
= PrevWord(data
->Contents
, data
->BufferPos
, data
->locale
);
542 strcpy(data
->Contents
+NewPos
, data
->Contents
+data
->BufferPos
);
543 data
->BufferPos
= NewPos
;
547 strcpy(data
->Contents
+data
->BufferPos
-1, data
->Contents
+data
->BufferPos
);
556 case 70: /* Delete */
557 if(BlockEnabled(data
))
563 if(data
->BufferPos
< StringLength
)
565 if(msg
->imsg
->Qualifier
& (IEQUALIFIER_CONTROL
| IEQUALIFIER_LSHIFT
| IEQUALIFIER_RSHIFT
))
568 *(data
->Contents
+data
->BufferPos
) = '\0';
572 if(msg
->imsg
->Qualifier
& (IEQUALIFIER_RALT
| IEQUALIFIER_LALT
))
575 strcpy(data
->Contents
+data
->BufferPos
, data
->Contents
+NextWord(data
->Contents
, data
->BufferPos
, data
->locale
));
579 strcpy(data
->Contents
+data
->BufferPos
, data
->Contents
+data
->BufferPos
+1);
589 if(data
->Popup
&& msg
->muikey
== MUIKEY_POPUP
)
591 DoMethod(data
->Popup
, MUIM_Popstring_Open
);
595 UBYTE code
= ConvertKey(msg
->imsg
);
596 if((((code
>= 32 && code
<= 126) || code
>= 160) && !(msg
->imsg
->Qualifier
& IEQUALIFIER_RCOMMAND
)) || (code
&& msg
->imsg
->Qualifier
& IEQUALIFIER_CONTROL
))
598 if(!(data
->Flags
& FLG_NoInput
))
601 if((data
->MaxLength
== 0 || data
->MaxLength
-1 > strlen(data
->Contents
)) && Accept(code
, data
->Accept
) && Reject(code
, data
->Reject
))
603 data
->Contents
= (STRPTR
)ExpandPool(data
->Pool
, data
->Contents
, 1);
604 strcpyback(data
->Contents
+data
->BufferPos
+1, data
->Contents
+data
->BufferPos
);
605 *(data
->Contents
+data
->BufferPos
) = code
;
617 if(data
->Flags
& FLG_NoInput
)
626 return(MUI_EventHandlerRC_Eat
);
634 if(!(data
->Flags
& FLG_StayActive
))
635 set(_win(obj
), MUIA_Window_ActiveObject
, (data
->Flags
& FLG_AdvanceOnCr
) ? (msg
->imsg
->Qualifier
& (IEQUALIFIER_RSHIFT
| IEQUALIFIER_LSHIFT
) ? MUIV_Window_ActiveObject_Prev
: MUIV_Window_ActiveObject_Next
) : MUIV_Window_ActiveObject_None
);
636 set(obj
, MUIA_String_Acknowledge
, data
->Contents
);
637 return(MUI_EventHandlerRC_Eat
);
638 /* Skip the "un-block" code */
642 UBYTE key
= *(data
->Contents
+data
->BufferPos
);
644 if(data
->BufferPos
< StringLength
)
646 *(data
->Contents
+data
->BufferPos
) = IsLower(data
->locale
, key
) ? ConvToUpper(data
->locale
, key
) : ConvToLower(data
->locale
, key
);
655 UWORD Stop
= NextWord(data
->Contents
, data
->BufferPos
, data
->locale
);
657 while(data
->BufferPos
< Stop
)
659 UBYTE key
= *(data
->Contents
+data
->BufferPos
);
661 *(data
->Contents
+data
->BufferPos
) = IsLower(data
->locale
, key
) ? ConvToUpper(data
->locale
, key
) : ConvToLower(data
->locale
, key
);
674 if(BlockEnabled(data
))
681 *data
->Contents
= '\0';
698 if((pos
= FindDigit(data
)) >= 0)
700 if((cut
= StrToLong(data
->Contents
+pos
, (LONG
*)&result
)))
702 UBYTE string
[12], format
[12];
705 MySPrintf(format
, "%%0%ldlu", cut
);
706 MySPrintf(string
, format
, result
);
707 Overwrite(string
, pos
, cut
, data
);
722 if((pos
= FindDigit(data
)) >= 0)
724 if((cut
= StrToLong(data
->Contents
+pos
, (LONG
*)&result
)))
726 if(result
|| code
== '$')
728 UBYTE string
[12], format2
[12];
729 STRPTR format
= "%lx";
734 MySPrintf(format
, "%%0%ldlu", cut
);
736 MySPrintf(string
, format
, result
);
737 Overwrite(string
, pos
, cut
, data
);
750 UWORD pos
= data
->BufferPos
;
753 while(pos
&& IsHex(*(data
->Contents
+pos
-1)))
756 while(IsHex(*(data
->Contents
+pos
+cut
)))
758 result
= (result
<< 4) + DecimalValue(*(data
->Contents
+pos
+cut
));
766 MySPrintf(string
, "%lu", result
);
767 Overwrite(string
, pos
, cut
, data
);
777 STRPTR oldcontents
= data
->Contents
;
778 data
->Contents
= data
->Original
;
779 data
->Original
= oldcontents
;
780 data
->Flags
|= FLG_Original
;
781 data
->Flags
&= ~FLG_BlockEnabled
;
782 data
->BufferPos
= strlen(data
->Contents
);
790 if(data
->Undo
&& (((code
== 'Z') && (data
->Flags
& FLG_RedoAvailable
)) || ((code
== 'z') && !(data
->Flags
& FLG_RedoAvailable
))))
792 STRPTR oldcontents
= data
->Contents
;
793 UWORD oldpos
= data
->BufferPos
;
795 data
->Contents
= data
->Undo
;
796 data
->Undo
= oldcontents
;
797 data
->Flags
^= FLG_RedoAvailable
;
798 data
->Flags
&= ~FLG_BlockEnabled
;
799 data
->BufferPos
= data
->UndoPos
;
800 data
->UndoPos
= oldpos
;
811 msg
->imsg
->Qualifier
&= ~IEQUALIFIER_RSHIFT
;
820 if(data
->FNCBuffer
&& !FNC
)
822 struct FNCData
*fncbuffer
= data
->FNCBuffer
, *fncframe
;
826 fncframe
= fncbuffer
;
827 fncbuffer
= fncbuffer
->next
;
828 MyFreePooled(data
->Pool
, fncframe
);
830 data
->FNCBuffer
= NULL
;
833 if(movement
&& msg
->imsg
->Qualifier
& IEQUALIFIER_CONTROL
)
834 data
->Flags
|= FLG_BlockEnabled
;
835 else data
->Flags
&= ~FLG_BlockEnabled
;
837 if(data
->Flags
& FLG_BlockEnabled
)
839 data
->BlockStop
= data
->BufferPos
;
842 if(deletion
|| edited
)
844 struct TagItem tags
[] =
846 { MUIA_String_Contents
, (ULONG
)data
->Contents
},
849 DoSuperMethod(cl
, obj
, OM_SET
, tags
, NULL
);
850 // set(obj, MUIA_String_Contents, data->Contents);
853 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
854 result
= MUI_EventHandlerRC_Eat
;
858 if(data
->CtrlChar
&& ConvertKey(msg
->imsg
) == data
->CtrlChar
)
860 set(_win(obj
), MUIA_Window_ActiveObject
, obj
);
861 result
= MUI_EventHandlerRC_Eat
;
867 if(msg
->imsg
->Class
== IDCMP_MOUSEBUTTONS
)
869 if(msg
->imsg
->Code
== (IECODE_LBUTTON
| IECODE_UP_PREFIX
))
871 if(data
->ehnode
.ehn_Events
& (IDCMP_MOUSEMOVE
| IDCMP_INTUITICKS
))
873 DoMethod(_win(obj
), MUIM_Window_RemEventHandler
, &data
->ehnode
);
874 data
->ehnode
.ehn_Events
&= ~(IDCMP_MOUSEMOVE
| IDCMP_INTUITICKS
);
875 DoMethod(_win(obj
), MUIM_Window_AddEventHandler
, &data
->ehnode
);
878 #ifdef ALLOW_OUTSIDE_MARKING
879 if((data
->Flags
& (FLG_Active
|FLG_DragOutside
)) == (FLG_Active
|FLG_DragOutside
))
882 get(_win(obj
), MUIA_Window_ActiveObject
, &active
);
884 kprintf("MUI error: %lx, %lx\n", active
, obj
);
886 WORD x
= ad
->mad_Box
.Left
+ ad
->mad_addleft
;
887 WORD y
= ad
->mad_Box
.Top
+ ad
->mad_addtop
;
888 WORD width
= ad
->mad_Box
.Width
- ad
->mad_subwidth
;
889 WORD height
= Font
->tf_YSize
;
891 if(!(msg
->imsg
->MouseX
>= x
&& msg
->imsg
->MouseX
< x
+width
&& msg
->imsg
->MouseY
>= y
&& msg
->imsg
->MouseY
< y
+height
))
893 kprintf("Detected LMB+up outside (drag: %ld)\n", data
->Flags
& FLG_DragOutside
? 1:0);
894 set(_win(obj
), MUIA_Window_ActiveObject
, MUIV_Window_ActiveObject_None
);
899 else if(msg
->imsg
->Code
== IECODE_LBUTTON
)
901 WORD x
= ad
->mad_Box
.Left
+ ad
->mad_addleft
;
902 WORD y
= ad
->mad_Box
.Top
+ ad
->mad_addtop
;
903 WORD width
= ad
->mad_Box
.Width
- ad
->mad_subwidth
;
904 WORD height
= Font
->tf_YSize
;
906 if(msg
->imsg
->MouseX
>= x
&& msg
->imsg
->MouseX
< x
+width
&& msg
->imsg
->MouseY
>= y
&& msg
->imsg
->MouseY
< y
+height
)
908 WORD offset
= msg
->imsg
->MouseX
- x
;
910 offset
-= AlignOffset(obj
, data
);
911 data
->BufferPos
= data
->DisplayPos
+ MyTextFit(Font
, data
->Contents
+data
->DisplayPos
, StringLength
-data
->DisplayPos
, offset
+1, 1);
913 if(DoubleClick(data
->StartSecs
, data
->StartMicros
, msg
->imsg
->Seconds
, msg
->imsg
->Micros
))
915 else data
->ClickCount
= 0;
916 data
->StartSecs
= msg
->imsg
->Seconds
;
917 data
->StartMicros
= msg
->imsg
->Micros
;
919 switch(data
->ClickCount
)
922 if(!(data
->Flags
& FLG_BlockEnabled
&& msg
->imsg
->Qualifier
& IEQUALIFIER_CONTROL
))
923 data
->BlockStart
= data
->BufferPos
;
927 if(*(data
->Contents
+data
->BufferPos
) != '\0')
929 UWORD start
= data
->BufferPos
,
930 stop
= data
->BufferPos
;
931 BOOL alpha
= IsAlNum(data
->locale
, (UBYTE
)*(data
->Contents
+data
->BufferPos
));
933 while(start
> 0 && alpha
== IsAlNum(data
->locale
, (UBYTE
)*(data
->Contents
+start
-1)))
936 while(alpha
== IsAlNum(data
->locale
, (UBYTE
)*(data
->Contents
+stop
)) && *(data
->Contents
+stop
) != '\0')
939 data
->BlockStart
= start
;
940 data
->BufferPos
= stop
;
945 data
->BlockStart
= 0;
946 data
->BufferPos
= strlen(data
->Contents
);
950 data
->BlockStart
= data
->BufferPos
;
951 data
->ClickCount
= 0;
954 data
->BlockStop
= data
->BufferPos
;
955 data
->Flags
|= FLG_BlockEnabled
;
957 DoMethod(_win(obj
), MUIM_Window_RemEventHandler
, &data
->ehnode
);
958 data
->ehnode
.ehn_Events
|= (IDCMP_MOUSEMOVE
| IDCMP_INTUITICKS
);
959 DoMethod(_win(obj
), MUIM_Window_AddEventHandler
, &data
->ehnode
);
961 if(data
->Flags
& FLG_Active
)
962 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
963 else set(_win(obj
), MUIA_Window_ActiveObject
, obj
);
964 result
= MUI_EventHandlerRC_Eat
;
968 data
->ClickCount
= 0;
969 if(data
->Flags
& FLG_Active
&& !(data
->Flags
& FLG_StayActive
))
971 #ifdef ALLOW_OUTSIDE_MARKING
972 kprintf("Clicked outside gadget\n");
973 data
->Flags
|= FLG_DragOutside
;
975 DoMethod(_win(obj
), MUIM_Window_RemEventHandler
, &data
->ehnode
);
976 data
->ehnode
.ehn_Events
|= IDCMP_MOUSEMOVE
;
977 DoMethod(_win(obj
), MUIM_Window_AddEventHandler
, &data
->ehnode
);
979 set(_win(obj
), MUIA_Window_ActiveObject
, MUIV_Window_ActiveObject_None
);
987 #ifdef ALLOW_OUTSIDE_MARKING
988 if(msg
->imsg
->Class
== IDCMP_MOUSEMOVE
)
990 data
->Flags
&= ~FLG_DragOutside
;
991 kprintf("Detected drag\n");
994 if((msg
->imsg
->Class
== IDCMP_MOUSEMOVE
|| msg
->imsg
->Class
== IDCMP_INTUITICKS
) && data
->Flags
& FLG_Active
)
996 WORD x
, width
, mousex
;
998 x
= ad
->mad_Box
.Left
+ ad
->mad_addleft
;
999 mousex
= msg
->imsg
->MouseX
- AlignOffset(obj
, data
);
1000 width
= ad
->mad_Box
.Width
- ad
->mad_subwidth
;
1002 switch(data
->ClickCount
)
1008 if(data
->DisplayPos
)
1010 data
->BufferPos
= data
->DisplayPos
;
1014 if(mousex
>= x
+width
)
1016 if(data
->DisplayPos
< StringLength
)
1019 data
->BufferPos
= data
->DisplayPos
+ MyTextFit(Font
, data
->Contents
+data
->DisplayPos
, StringLength
-data
->DisplayPos
, ad
->mad_Box
.Width
- ad
->mad_subwidth
, 1);
1023 data
->BufferPos
= StringLength
;
1028 WORD offset
= mousex
- x
;
1031 data->BufferPos = 0;
1033 */ data
->BufferPos
= data
->DisplayPos
+ MyTextFit(Font
, data
->Contents
+data
->DisplayPos
, StringLength
-data
->DisplayPos
, offset
+1, 1);
1036 data
->BlockStop
= data
->BufferPos
;
1037 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
1043 WORD offset
= mousex
- x
,
1046 if(mousex
< x
&& data
->DisplayPos
)
1049 newpos
= data
->DisplayPos
;
1053 // offset -= AlignOffset(obj, data);
1055 newpos
= data
->DisplayPos
+ MyTextFit(Font
, data
->Contents
+data
->DisplayPos
, StringLength
-data
->DisplayPos
, offset
+1, 1);
1058 if(newpos
>= data
->BlockStart
)
1060 while(IsAlNum(data
->locale
, (UBYTE
)*(data
->Contents
+newpos
)))
1065 while(newpos
> 0 && IsAlNum(data
->locale
, (UBYTE
)*(data
->Contents
+newpos
-1)))
1069 if(data
->BufferPos
!= newpos
)
1071 data
->BlockStop
= data
->BufferPos
= newpos
;
1072 MUI_Redraw(obj
, MADF_DRAWUPDATE
);