home *** CD-ROM | disk | FTP | other *** search
/ BCI NET / BCI NET Dec 94.iso / archives / telecomm / terms / term-4.1-source.lha / Extras / Source / gtlayout-Source.lha / gtlayout.c next >
Encoding:
C/C++ Source or Header  |  1994-09-07  |  249.2 KB  |  11,343 lines

  1. /*  GadTools layout toolkit
  2. **
  3. **  Copyright © 1993-1994 by Olaf `Olsen' Barthel
  4. **  Freely distributable.
  5. */
  6.  
  7. #include <exec/execbase.h>
  8. #include <exec/memory.h>
  9.  
  10. #include <graphics/videocontrol.h>
  11. #include <graphics/gfxmacros.h>
  12. #include <graphics/gfxbase.h>
  13.  
  14. #include <intuition/intuitionbase.h>
  15. #include <intuition/gadgetclass.h>
  16. #include <intuition/imageclass.h>
  17. #include <intuition/classusr.h>
  18. #include <intuition/icclass.h>
  19. #include <intuition/screens.h>
  20. #include <intuition/classes.h>
  21. #include <intuition/sghooks.h>
  22. #include <libraries/gadtools.h>
  23. #include <libraries/locale.h>
  24. #include <devices/timer.h>
  25.  
  26. #include <stdarg.h>
  27. #include <stdlib.h>
  28. #include <string.h>
  29. #include <stddef.h>
  30. #include <dos.h>
  31.  
  32. #include <clib/intuition_protos.h>
  33. #include <clib/graphics_protos.h>
  34. #include <clib/gadtools_protos.h>
  35. #include <clib/diskfont_protos.h>
  36. #include <clib/utility_protos.h>
  37. #include <clib/keymap_protos.h>
  38. #include <clib/locale_protos.h>
  39. #include <clib/exec_protos.h>
  40. #include <clib/macros.h>
  41.  
  42. #include <pragmas/intuition_pragmas.h>
  43. #include <pragmas/graphics_pragmas.h>
  44. #include <pragmas/gadtools_pragmas.h>
  45. #include <pragmas/diskfont_pragmas.h>
  46. #include <pragmas/utility_pragmas.h>
  47. #include <pragmas/keymap_pragmas.h>
  48. #include <pragmas/locale_pragmas.h>
  49. #include <pragmas/exec_pragmas.h>
  50.  
  51. #define _GTLAYOUT_C
  52. #include "gtlayout.h"
  53.  
  54.  
  55. /*****************************************************************************/
  56.  
  57.  
  58.     // Keyboard qualifiers
  59.  
  60. #define QUALIFIER_SHIFT        (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT)
  61. #define QUALIFIER_ALT        (IEQUALIFIER_LALT | IEQUALIFIER_RALT)
  62. #define QUALIFIER_CONTROL    (IEQUALIFIER_CONTROL)
  63.  
  64.  
  65. /*****************************************************************************/
  66.  
  67.  
  68.     // Undefine these to remove various chunks of support from this code
  69.  
  70. #ifdef LIB_CODE
  71. #define DO_PASSWORD_KIND
  72. #define DO_FRACTION_KIND
  73. #define DO_GAUGE_KIND
  74. #define DO_TAPEDECK_KIND
  75. #define DO_HEXHOOK
  76. #define DO_PICKSHORTCUTS
  77. #define DO_CLONING
  78. #else
  79. #define DO_PASSWORD_KIND
  80. //#define DO_FRACTION_KIND
  81. #define DO_GAUGE_KIND
  82. //#define DO_HEXHOOK
  83. #define DO_PICKSHORTCUTS
  84. #define DO_CLONING
  85. #define DO_TAPEDECK_KIND
  86. #endif    /* LIB_CODE */
  87.  
  88.  
  89. /*****************************************************************************/
  90.  
  91.  
  92.     // Stuff from amiga.lib that we want to declare stdargs/regargs
  93.  
  94. VOID __regargs    NewList(struct MinList *list);
  95. VOID __regargs    TimeDelay(LONG unit,ULONG secs,ULONG micros);
  96. ULONG __regargs    DoSuperMethodA(struct IClass *cl, Object *obj, Msg message);
  97. APTR __asm    AsmCreatePool(register __d0 ULONG MemFlags,register __d1 ULONG PuddleSize,register __d2 ULONG ThreshSize,register __a6 struct ExecBase *SysBase);
  98. VOID __asm    AsmDeletePool(register __a0 APTR PoolHeader,register __a6 struct ExecBase *SysBase);
  99. APTR __asm    AsmAllocPooled(register __a0 APTR PoolHeader, register __d0 ULONG Size,register __a6 struct ExecBase *SysBase);
  100. VOID __asm    AsmFreePooled(register __a0 APTR PoolHeader,register __a1 APTR Memory,register __d0 ULONG MemSize,register __a6 struct ExecBase *SysBase);
  101.  
  102. VOID __stdargs    kprintf(STRPTR,...);
  103.  
  104.  
  105. /*****************************************************************************/
  106.  
  107.  
  108.     // Scan an Exec list
  109.  
  110. #define SCANLIST(l,n)    for(n = (APTR)((struct MinList *)l) -> mlh_Head; \
  111.             ((struct MinNode *)n) -> mln_Succ; \
  112.             n = (APTR)((struct MinNode *)n) -> mln_Succ)
  113.  
  114.     // Scan the objects of a group
  115.  
  116. #define SCANGROUP(g,n)    for(n = (APTR)g -> Special . Group . ObjectList . mlh_Head; \
  117.             ((struct MinNode *)n) -> mln_Succ; \
  118.             n = (APTR)((struct MinNode *)n) -> mln_Succ)
  119.  
  120.     // Scan the objects of a group, only allowing active pages
  121.  
  122. #define SCANPAGE(g,n,p)    for(p = 0, n = (APTR)g -> Special . Group . ObjectList . mlh_Head; \
  123.             ((struct MinNode *)n) -> mln_Succ; \
  124.             n = (APTR)((struct MinNode *)n) -> mln_Succ) \
  125.             if ((p++ == g -> Special . Group . ActivePage) || !g -> Special . Group . Paging)
  126.  
  127.     // Get an object pointer from a gadget pointer
  128.  
  129. #define GETOBJECT(g,n)    ((n = (ObjectNode *)g -> UserData) && (n -> Host == g) && (n -> PointBack == n))
  130.  
  131.  
  132. /*****************************************************************************/
  133.  
  134.  
  135. #ifdef DO_PASSWORD_KIND
  136. #define TEST_PASSWORD_KIND(n) || (n -> Type == PASSWORD_KIND)
  137. #else
  138. #define TEST_PASSWORD_KIND(n) || (FALSE)
  139. #endif
  140.  
  141. #ifdef DO_FRACTION_KIND
  142. #define TEST_FRACTION_KIND(n) || (n -> Type == FRACTION_KIND)
  143. #else
  144. #define TEST_FRACTION_KIND(n) || (FALSE)
  145. #endif
  146.  
  147.     // Is an object derived from STRING_KIND?
  148.  
  149. #define LIKE_STRING_KIND(n)    ((n -> Type == STRING_KIND) TEST_PASSWORD_KIND(n) TEST_FRACTION_KIND(n))
  150.  
  151.  
  152. /*****************************************************************************/
  153.  
  154.  
  155. typedef UBYTE BOOLEAN;
  156.  
  157. #define INCREMENTER_KIND    42
  158. #define PICKER_KIND        43
  159. #define GROUP_KIND        44
  160.  
  161. typedef struct GaugeExtra
  162. {
  163.     LONG             InfoLength;
  164.     STRPTR             InfoText;
  165. } GaugeExtra;
  166.  
  167. typedef struct TapeDeckExtra
  168. {
  169.     struct Image        *ButtonImage;
  170.     LONG             ButtonWidth,
  171.                  ButtonHeight;
  172.     BOOLEAN             ButtonType,
  173.                  Toggle,
  174.                  Pressed,
  175.                  Smaller;
  176. } TapeDeckExtra;
  177.  
  178. typedef struct ButtonExtra
  179. {
  180.     BOOLEAN             ReturnKey;
  181.     BOOLEAN             EscKey;
  182.     BOOLEAN             ExtraFat;
  183. } ButtonExtra;
  184.  
  185. typedef struct BarExtra
  186. {
  187.     struct ObjectNode    *Parent;
  188.     BOOLEAN             FullSize;
  189. } BarExtra;
  190.  
  191. typedef struct BoxExtra
  192. {
  193.     STRPTR            *Labels;
  194.     STRPTR            *Lines;
  195.     AlignmentTypes         AlignText;
  196.     WORD             MaxSize;
  197.     BOOLEAN             DrawBox;
  198.     BOOLEAN             ReserveSpace;
  199. } BoxExtra;
  200.  
  201. typedef struct FrameExtra
  202. {
  203.     UWORD             InnerWidth;
  204.     UWORD             InnerHeight;
  205.     BOOLEAN             DrawBox;
  206. } FrameExtra;
  207.  
  208. typedef struct PickerExtra
  209. {
  210.     struct Gadget        *Parent;
  211.     struct Image        *Image;
  212. } PickerExtra;
  213.  
  214. typedef struct IncrementerExtra
  215. {
  216.     struct Gadget        *Parent;
  217.     struct Image        *Image;
  218.     LONG             Amount;
  219. } IncrementerExtra;
  220.  
  221. typedef struct GroupExtra
  222. {
  223.     struct MinList         ObjectList;
  224.     struct ObjectNode    *ParentGroup;
  225.     UWORD             ExtraLeft;
  226.     UWORD             ExtraTop;
  227.     LONG             MaxOffset;
  228.     LONG             MaxSize;
  229.     ULONG             ActivePage;
  230.     BOOLEAN             Horizontal;
  231.     BOOLEAN             Paging;
  232.     BOOLEAN             Spread;
  233.     BOOLEAN             SameSize;
  234.     BOOLEAN             LastAttributes;
  235. } GroupExtra;
  236.  
  237. typedef struct ListExtra
  238. {
  239.     struct List        *Labels;
  240.     struct Gadget        *Link;
  241.     LONG             LinkID;
  242.     struct Hook        *CallBack;
  243.     ULONG             ClickSeconds;
  244.     ULONG             ClickMicros;
  245.     STRPTR            *ExtraLabels;
  246.     UWORD             ExtraLabelWidth;
  247.     UWORD             MaxPen;
  248.     UWORD             MaxGrowX,MaxGrowY;
  249.     BOOLEAN             ReadOnly;
  250.     BOOLEAN             CursorKey;
  251.     BOOLEAN             AllocatedList;
  252. } ListExtra;
  253.  
  254. typedef struct RadioExtra
  255. {
  256.     STRPTR            *Choices;
  257.     UWORD             LabelWidth;
  258.     UBYTE             TitlePlace;
  259. } RadioExtra;
  260.  
  261. typedef struct TextExtra
  262. {
  263.     STRPTR             Text;
  264.     struct Gadget        *Picker;
  265.     UWORD             Len;
  266.     BOOLEAN             Border;
  267.     BOOLEAN             CopyText;
  268.     BOOLEAN             UsePicker;
  269.     UBYTE             Justification;
  270. } TextExtra;
  271.  
  272. typedef struct NumberExtra
  273. {
  274.     LONG             Number;
  275.     BOOLEAN             Border;
  276.     UBYTE             Justification;
  277. } NumberExtra;
  278.  
  279. typedef struct CycleExtra
  280. {
  281.     STRPTR            *Choices;
  282. } CycleExtra;
  283.  
  284. typedef struct PalExtra
  285. {
  286.     UBYTE            *ColourTable;
  287.     UWORD             Depth;
  288.     UWORD             NumColours;
  289.     BOOLEAN             SmallPalette;
  290. } PalExtra;
  291.  
  292. typedef struct SliderExtra
  293. {
  294.     STRPTR             LevelFormat;
  295.     DISPFUNC         DispFunc;
  296.     LONG             MaxLevelLen;
  297.     LONG             LevelWidth;
  298.     STRPTR             OriginalLabel;
  299.     UBYTE             LevelPlace;
  300.     BOOLEAN             FullLevelCheck;
  301. } SliderExtra;
  302.  
  303. typedef struct StringExtra
  304. {
  305.     struct LayoutHandle    *LayoutHandle;
  306.     struct Hook        *HistoryHook;
  307.     ULONG             MaxHistoryLines;
  308.     ULONG             NumHistoryLines;
  309.     struct Node        *CurrentNode;
  310.  
  311.     STRPTR             String;
  312.     LONG             MaxChars;
  313.     struct Hook        *EditHook;
  314.     struct Gadget        *Picker;
  315.     STRPTR             RealString;
  316.     STRPTR             Original;
  317.     LONG             LinkID;
  318.     LONG             Min;
  319.     LONG             Max;
  320.     UBYTE             Justification;
  321.     BOOLEAN             LastGadget;
  322.     BOOLEAN             UsePicker;
  323. } StringExtra;
  324.  
  325. typedef struct IntegerExtra
  326. {
  327.     struct LayoutHandle    *LayoutHandle;
  328.     struct Hook        *HistoryHook;
  329.     ULONG             MaxHistoryLines;
  330.     ULONG             NumHistoryLines;
  331.     struct Node        *CurrentNode;
  332.  
  333.     LONG             Number;
  334.     LONG             MaxChars;
  335.     struct Hook        *EditHook;
  336.     LONG             Min;
  337.     LONG             Max;
  338.     UBYTE             Justification;
  339.     BOOLEAN             LastGadget;
  340.     BOOLEAN             UseIncrementers;
  341.  
  342.     struct Gadget        *LeftIncrementer;
  343.     struct Gadget        *RightIncrementer;
  344.  
  345.     struct Hook        *IncrementerHook;
  346. } IntegerExtra;
  347.  
  348. typedef struct ScrollerExtra
  349. {
  350.     WORD             Visible,
  351.                  ArrowSize;
  352.     BOOLEAN             RelVerify,
  353.                  Immediate,
  354.                  Arrows,
  355.                  Vertical,
  356.                  Thin;
  357. } ScrollerExtra;
  358.  
  359. typedef struct ObjectNode
  360. {
  361.     struct MinNode         Node;
  362.     struct Gadget        *Host;
  363.     struct ObjectNode    *PointBack;
  364.     STRPTR             Label;
  365.     LONG             ID;
  366.     UBYTE             Type;
  367.     PlacementTypes         LabelPlace;
  368.     BOOLEAN             Disabled;
  369.     PlacementTypes         ObjectPlace;
  370.     LONG             Min;
  371.     LONG             Max;
  372.     LONG             Current;
  373.     UWORD             Left;
  374.     UWORD             Top;
  375.     UWORD             Width;
  376.     UWORD             Height;
  377.     UWORD             LabelWidth;
  378.     UWORD             Lines;
  379.     UWORD             Chars;
  380.     WORD             ExtraSpace;
  381.     BOOLEAN             NoKey;
  382.     BOOLEAN             HighLabel;
  383.     BOOLEAN             GroupIndent;
  384.     BOOLEAN             Centered;
  385.     BOOLEAN             PageSelector;
  386.     UBYTE             Key;
  387.     APTR             Storage;
  388.     UBYTE             StorageType;
  389.     UBYTE             Pad;
  390.  
  391.     union
  392.     {
  393.         GaugeExtra        Gauge;
  394.         TapeDeckExtra        TapeDeck;
  395.         ButtonExtra        Button;
  396.         BarExtra        Bar;
  397.         BoxExtra        Box;
  398.         FrameExtra        Frame;
  399.         PickerExtra        Picker;
  400.         IncrementerExtra    Incrementer;
  401.         GroupExtra        Group;
  402.         ListExtra        List;
  403.         RadioExtra        Radio;
  404.         TextExtra        Text;
  405.         NumberExtra        Number;
  406.         CycleExtra        Cycle;
  407.         PalExtra        Palette;
  408.         SliderExtra        Slider;
  409.         StringExtra        String;
  410.         IntegerExtra        Integer;
  411.         ScrollerExtra        Scroller;
  412.     } Special;
  413. } ObjectNode;
  414.  
  415. typedef struct LayoutHandle
  416. {
  417.         // WARNING: Beginning of this structure must match the definition in gui.h!
  418.  
  419.     struct Screen        *Screen;
  420.     struct DrawInfo        *DrawInfo;
  421.     struct Window        *Window;
  422.     APTR             VisualInfo;
  423.     struct Image        *AmigaGlyph,
  424.                 *CheckGlyph;
  425.  
  426.     struct Screen        *PubScreen;
  427.     struct MsgPort        *MsgPort;
  428.     struct Gadget        **GadgetArray;
  429.     struct Gadget        *Previous;
  430.     struct Gadget        *List;
  431.     ULONG             IDCMP;
  432.  
  433.     ObjectNode        *ActiveIncrementer;
  434.     LONG             IncrementerCountdown;
  435.  
  436.         // Cached from DrawInfo structure
  437.  
  438.     UWORD             TextPen;
  439.     UWORD             BackgroundPen;
  440.     UWORD             ShadowPen;
  441.     UWORD             ShinePen;
  442.     UWORD             AspectX;
  443.     UWORD             AspectY;
  444.  
  445.     struct Hook        *LocaleHook;
  446.     struct TextAttr        *TextAttr;
  447.     struct TextAttr        *InitialTextAttr;
  448.     struct TTextAttr     CopyTextAttr;
  449.     struct RastPort         RPort;
  450.     APTR             Pool;
  451.     UWORD             GlyphWidth;
  452.     UWORD             InterWidth;
  453.     UWORD             InterHeight;
  454.     LONG             Count;
  455.     LONG             Index;
  456.     LONG             MaxID;
  457.     ObjectNode        *TopGroup;
  458.     ObjectNode        *CurrentGroup;
  459.     ObjectNode        *EscKey;
  460.     ObjectNode        *ReturnKey;
  461.     ObjectNode        *CursorKey;
  462.     ObjectNode        *GrowView;
  463. #ifdef DO_FRACTION_KIND
  464.     struct Hook         FracEditHook;
  465. #endif
  466. #ifdef DO_PASSWORD_KIND
  467.     struct Hook         PasswordEditHook;
  468. #endif
  469. #ifdef DO_HEXHOOK
  470.     struct Hook         HexEditHook;
  471. #endif
  472.     struct Hook         DefaultEditHook;
  473.     struct Hook        *StandardEditHook;
  474.     struct Hook         BackfillHook;
  475.  
  476. #ifdef DO_PICKSHORTCUTS
  477.     UBYTE             Keys[256];
  478. #endif
  479.  
  480.     struct Hook        *HelpHook;        // Hook to call when help key is pressed
  481.     LONG             MaxPen;
  482.  
  483.     BOOLEAN             AutoRefresh;
  484.     BOOLEAN             CloseFont;
  485.     BOOLEAN             Failed;
  486.     BOOLEAN             Rescaled;
  487.     BOOLEAN             AutoActivate;
  488.     BOOLEAN             MoveToWindow;
  489.  
  490. #ifdef DO_CLONING
  491.     BOOLEAN             CloningPermitted;    // Genetic engineering?
  492.     BOOLEAN             ExactClone;        // Make an exact copy, i.e. preserve all colours
  493.     struct CloneExtra    *CloneExtra;        // Screen cloning information
  494. #endif
  495.  
  496.     struct timerequest     TimeRequest;
  497.     struct MsgPort         TimePort;
  498.  
  499.     struct Window        *Parent;        // Parent of this window
  500.     BOOL             BlockParent;
  501.  
  502. } LayoutHandle;
  503.  
  504. typedef struct LockNode
  505. {
  506.     struct MinNode         MinNode;
  507.     struct Window        *Window;
  508.     LONG             Count;
  509.     ULONG             OldIDCMPFlags;
  510.     struct Requester     Requester;
  511.     LONG             MinWidth;
  512.     LONG             MinHeight;
  513.     LONG             MaxWidth;
  514.     LONG             MaxHeight;
  515. } LockNode;
  516.  
  517. typedef struct ImageInfo
  518. {
  519.     ULONG             ImageType,
  520.                  GlyphWidth,
  521.                  GlyphHeight;
  522. } ImageInfo;
  523.  
  524. #define IIA_ImageType    (TAG_USER+739)
  525. #define IIA_GlyphWidth    (TAG_USER+740)
  526. #define IIA_GlyphHeight    (TAG_USER+741)
  527.  
  528. typedef enum ImageTypes
  529. {
  530.     IMAGECLASS_PICKER,
  531.     IMAGECLASS_LEFTINCREMENTER,
  532.     IMAGECLASS_RIGHTINCREMENTER,
  533.     IMAGECLASS_BACKWARD,
  534.     IMAGECLASS_FORWARD,
  535.     IMAGECLASS_PREVIOUS,
  536.     IMAGECLASS_NEXT,
  537.     IMAGECLASS_RECORD,
  538.     IMAGECLASS_PLAY,
  539.     IMAGECLASS_STOP,
  540.     IMAGECLASS_PAUSE,
  541.     IMAGECLASS_REWIND,
  542.     IMAGECLASS_EJECT
  543. } ImageTypes;
  544.  
  545. typedef enum StorageTypes
  546. {
  547.     STORAGE_BYTE,STORAGE_UBYTE,
  548.     STORAGE_WORD,STORAGE_UWORD,
  549.     STORAGE_LONG,STORAGE_ULONG,
  550.     STORAGE_STRPTR
  551. } StorageTypes;
  552.  
  553.  
  554. /*****************************************************************************/
  555.  
  556.  
  557.     // A single colour in 96 bit precision
  558.  
  559. struct ColourTriplet
  560. {
  561.     ULONG            Red,        // 32 bits each
  562.                 Green,
  563.                 Blue;
  564. };
  565.  
  566.     // A colour table ready to submit to LoadRGB32
  567.  
  568. struct ColourRecord
  569. {
  570.     UWORD            NumColours,    // Number of colours in this chunk
  571.                 FirstColour;    // First colour entry to set
  572.  
  573.     struct ColourTriplet    Triplets[0];    // Table entries
  574.  
  575.     WORD            Arnold;        // Array terminator, needs to be set to zero
  576. };
  577.  
  578.     // Screen reproduction
  579.  
  580. struct CloneExtra
  581. {
  582.     struct Screen        *Screen;
  583.     LONG            *Pens;
  584.     UWORD            *ScreenPens;
  585.     UWORD             MinWidth,
  586.                  MinHeight,
  587.                  MaxWidth,
  588.                  MaxHeight,
  589.                  TotalPens;
  590.     UBYTE             Depth;
  591.     struct IBox         Bounds;
  592. };
  593.  
  594.  
  595. /*****************************************************************************/
  596.  
  597.  
  598. STATIC VOID __regargs LTK_LayoutGroup(LayoutHandle *Handle, ObjectNode *Group);
  599.  
  600.  
  601. /*****************************************************************************/
  602.  
  603.  
  604. STATIC ULONG ghostingPat = 0x44441111;
  605.  
  606. STATIC struct ExecBase        *SysBase;
  607. STATIC struct Library        *IntuitionBase;
  608. STATIC struct GfxBase        *GfxBase;
  609. STATIC struct Library        *UtilityBase;
  610. STATIC struct Library        *GadToolsBase;
  611. STATIC struct Library        *KeymapBase;
  612. STATIC struct Library        *LocaleBase;
  613. STATIC struct Locale        *LTK_Locale;
  614. STATIC struct SignalSemaphore     LTK_LockSemaphore;
  615. STATIC struct MinList         LTK_LockList;
  616. STATIC struct IClass        *LTK_ImageClass;
  617.  
  618. STATIC BOOLEAN             V39,
  619.                  V40;
  620.  
  621. #ifdef DO_PICKSHORTCUTS
  622. STATIC UBYTE             LTK_Keys[2][256];
  623. STATIC struct SignalSemaphore     LTK_KeySemaphore;
  624. STATIC BOOLEAN             LTK_KeysInitialized;
  625. #endif
  626.  
  627.  
  628. /*****************************************************************************/
  629.  
  630.  
  631. STATIC ULONG __regargs
  632. Atol(STRPTR String)
  633. {
  634.     ULONG Value = 0;
  635.  
  636.     while(*String == ' ' || *String == '\t')
  637.         String++;
  638.  
  639.     while(*String)
  640.     {
  641.         if(*String >= '0' && *String <= '9')
  642.             Value = (Value * 10) + (*String++) - '0';
  643.         else
  644.             break;
  645.     }
  646.  
  647.     return(Value);
  648. }
  649.  
  650.  
  651. /*****************************************************************************/
  652.  
  653.  
  654. STATIC ULONG __asm __saveds
  655. LTK_BackfillRoutine(register __a0 struct Hook *Hook,register __a1 struct {ULONG Layer; struct Rectangle Bounds;} *Bounds,register __a2 struct RastPort *RPort)
  656. {
  657.     struct LayoutHandle    *Handle = (struct LayoutHandle *)Hook -> h_Data;
  658.     struct RastPort         RastPort = *RPort;
  659.  
  660.     RPort = &RastPort;
  661.  
  662.     RPort -> Layer = NULL;
  663.  
  664.     SetAPen(RPort,Handle -> BackgroundPen);
  665.     SetDrMd(RPort,JAM1);
  666.  
  667.     RectFill(RPort,Bounds -> Bounds . MinX,Bounds -> Bounds . MinY,Bounds -> Bounds . MaxX,Bounds -> Bounds . MaxY);
  668.  
  669.     return(TRUE);
  670. }
  671.  
  672.  
  673. /*****************************************************************************/
  674.  
  675.  
  676. #ifdef DO_HEXHOOK
  677.  
  678.     // Check whether the buffer only contains a valid hex/binary/octal number...
  679.  
  680. STATIC BOOLEAN __regargs
  681. LTK_ConvertNum(BOOLEAN negAllowed,STRPTR buffer,LONG *value)
  682. {
  683.     UBYTE    ch;
  684.     ULONG    num;
  685.     UWORD    i;
  686.     LONG    neg;
  687.  
  688.     num = 0;
  689.  
  690.     if((buffer[0] == '-') && negAllowed)
  691.     {
  692.         neg = -1;
  693.  
  694.         buffer++;
  695.     }
  696.     else
  697.         neg = 1;
  698.  
  699.     if(((buffer[0] == '0') && (buffer[1] == 'x')) || (buffer[0] == '$'))
  700.     {
  701.         if (buffer[0] == '$')
  702.             i = 1;
  703.         else
  704.             i = 2;
  705.  
  706.         while(buffer[i])
  707.         {
  708.             ch    = ToUpper(buffer[i]);
  709.             num    = num * 16;
  710.  
  711.             if((ch >= 'A') && (ch <= 'F'))
  712.                 num += ch - 'A' + 10;
  713.             else
  714.             {
  715.                 if ((ch >= '0') && (ch <= '9'))
  716.                     num += ch - '0';
  717.                 else
  718.                     return(FALSE);
  719.             }
  720.  
  721.             i++;
  722.         }
  723.  
  724.         *value = num * neg;
  725.  
  726.         return(TRUE);
  727.     }
  728.     else
  729.     {
  730.         if(buffer[0] == '%')
  731.         {
  732.             i = 1;
  733.  
  734.             while(buffer[i])
  735.             {
  736.                 ch = buffer[i];
  737.  
  738.                 if((ch < '0') || (ch > '1'))
  739.                     return(FALSE);
  740.  
  741.                 num = (num * 2) + ch - '0';
  742.  
  743.                 i++;
  744.             }
  745.         }
  746.         else
  747.         {
  748.             if(buffer[0] == '&')
  749.             {
  750.                 i = 1;
  751.  
  752.                 while(buffer[i])
  753.                 {
  754.                     ch = buffer[i];
  755.  
  756.                     if((ch < '0') || (ch > '7'))
  757.                         return(FALSE);
  758.  
  759.                     num = (num * 8) + ch - '0';
  760.  
  761.                     i++;
  762.                 }
  763.             }
  764.             else
  765.             {
  766.                 i = 0;
  767.  
  768.                 while(buffer[i])
  769.                 {
  770.                     ch = buffer[i];
  771.  
  772.                     if((ch < '0') || (ch > '9'))
  773.                         return(FALSE);
  774.  
  775.                     num = (num * 10) + ch - '0';
  776.  
  777.                     i++;
  778.                 }
  779.             }
  780.         }
  781.  
  782.         *value = num * neg;
  783.  
  784.         return(TRUE);
  785.     }
  786.  
  787.     return(FALSE);
  788. }
  789. #endif
  790.  
  791.  
  792. /*****************************************************************************/
  793.  
  794.  
  795. STATIC VOID __regargs
  796. LTK_AddHistory(struct SGWork *Work)
  797. {
  798.     ObjectNode *Node;
  799.  
  800.     if(GETOBJECT(Work -> Gadget,Node))
  801.     {
  802.         if(Node -> Special . String . HistoryHook)
  803.         {
  804.             struct MinList *List = Node -> Special . String . HistoryHook -> h_Data;
  805.  
  806.             while(Node -> Special . String . NumHistoryLines >= Node -> Special . String . MaxHistoryLines)
  807.             {
  808.                 CallHookPkt(Node -> Special . String . HistoryHook,Work -> Gadget,NULL);
  809.  
  810.                 Node -> Special . String . NumHistoryLines--;
  811.             }
  812.  
  813.             Work -> WorkBuffer[Work -> NumChars] = 0;
  814.  
  815.             if(CallHookPkt(Node -> Special . String . HistoryHook,Work -> Gadget,Work -> WorkBuffer))
  816.                 Node -> Special . String . NumHistoryLines++;
  817.  
  818.             if(List -> mlh_Head -> mln_Succ)
  819.                 Node -> Special . String . CurrentNode = (struct Node *)List -> mlh_TailPred;
  820.             else
  821.                 Node -> Special . String . CurrentNode = NULL;
  822.         }
  823.     }
  824. }
  825.  
  826. STATIC VOID __regargs
  827. LTK_HandleHistory(struct SGWork *Work)
  828. {
  829.     ObjectNode *Node;
  830.  
  831.     if(GETOBJECT(Work -> Gadget,Node))
  832.     {
  833.         if(Node -> Special . String . HistoryHook)
  834.         {
  835.             struct Node    *Choice    = NULL;
  836.             struct MinList    *List    = Node -> Special . String . HistoryHook -> h_Data;
  837.  
  838.             if(Work -> IEvent -> ie_Qualifier & QUALIFIER_SHIFT)
  839.             {
  840.                 if(Work -> IEvent -> ie_Code == CURSORUP)
  841.                 {
  842.                     if(List -> mlh_Head -> mln_Succ)
  843.                         Choice = (struct Node *)List -> mlh_Head;
  844.                 }
  845.                 else
  846.                 {
  847.                     if(List -> mlh_Head -> mln_Succ)
  848.                         Choice = (struct Node *)List -> mlh_TailPred;
  849.                 }
  850.             }
  851.             else
  852.             {
  853.                 struct Node *Current = Node -> Special . String . CurrentNode;
  854.  
  855.                 if(Work -> IEvent -> ie_Code == CURSORUP)
  856.                 {
  857.                     if(Current)
  858.                     {
  859.                         if(Current -> ln_Pred -> ln_Pred)
  860.                             Choice = Current -> ln_Pred;
  861.                         else
  862.                             Choice = Current;
  863.                     }
  864.                     else
  865.                     {
  866.                         if(List -> mlh_Head -> mln_Succ)
  867.                             Choice = (struct Node *)List -> mlh_TailPred;
  868.                     }
  869.                 }
  870.                 else
  871.                 {
  872.                     if(Current)
  873.                     {
  874.                         if(Current -> ln_Succ -> ln_Succ)
  875.                             Choice = Current -> ln_Succ;
  876.                     }
  877.                 }
  878.             }
  879.  
  880.             if(Choice != Node -> Special . String . CurrentNode)
  881.             {
  882.                 if(Choice)
  883.                 {
  884.                     strcpy(Work -> WorkBuffer,Choice -> ln_Name);
  885.  
  886.                     Work -> NumChars = Work -> BufferPos = strlen(Work -> WorkBuffer);
  887.                 }
  888.                 else
  889.                 {
  890.                     Work -> WorkBuffer[0]    = 0;
  891.                     Work -> NumChars    = 0;
  892.                     Work -> BufferPos    = 0;
  893.                 }
  894.  
  895.                 if(Node -> Type == INTEGER_KIND)
  896.                 {
  897. #ifdef DO_HEXHOOK
  898.                     LTK_ConvertNum((Node -> Special . Integer . Min < 0),Work -> WorkBuffer,&Work -> LongInt);
  899. #else
  900.                     Work -> LongInt = Atol(Work -> WorkBuffer);
  901. #endif
  902.                 }
  903.  
  904.                 Node -> Special . String . CurrentNode = Choice;
  905.  
  906.                 Work -> Actions = (Work -> Actions & ~SGA_BEEP) | SGA_USE | SGA_REDISPLAY;
  907.             }
  908.         }
  909.     }
  910. }
  911.  
  912.  
  913. /*****************************************************************************/
  914.  
  915.  
  916. #ifdef DO_FRACTION_KIND
  917. STATIC ULONG __asm __saveds
  918. LTK_FracEditRoutine(register __a0 struct Hook *Hook,register __a2 struct SGWork *Work,register __a1 ULONG *Msg)
  919. {
  920.     if(*Msg == SGH_KEY)
  921.     {
  922.         if(Work -> IEvent -> ie_Code == CURSORUP || Work -> IEvent -> ie_Code == CURSORDOWN)
  923.             LTK_HandleHistory(Work);
  924.  
  925.         if(Work -> EditOp == EO_ENTER)
  926.         {
  927.             LayoutHandle    *Handle = Hook -> h_Data;
  928.             ObjectNode    *Node;
  929.             BOOLEAN         Activate = TRUE;
  930.  
  931.             if(GETOBJECT(Work -> Gadget,Node))
  932.             {
  933.                 if(Node -> Type == FRACTION_KIND && Node -> Special . String . LastGadget)
  934.                     Activate = FALSE;
  935.             }
  936.  
  937.             if(!(Work -> IEvent -> ie_Qualifier & QUALIFIER_SHIFT))
  938.             {
  939.                 if(Activate && Handle -> AutoActivate)
  940.                     Work -> Actions |= SGA_NEXTACTIVE;
  941.  
  942.                 if(!(Work -> Actions & SGA_NEXTACTIVE))
  943.                     Work -> Code = '\r';
  944.             }
  945.         }
  946.  
  947.         if(Work -> EditOp == EO_INSERTCHAR || Work -> EditOp == EO_REPLACECHAR)
  948.         {
  949.             UBYTE DecimalPoint = (LTK_Locale ? LTK_Locale -> loc_DecimalPoint[0] : '.');
  950.  
  951.             if(Work -> Code == DecimalPoint || (Work -> Code >= '0' && Work -> Code <= '9'))
  952.             {
  953.                 if(Work -> Code == DecimalPoint)
  954.                 {
  955.                     BOOLEAN    UseIt = TRUE;
  956.                     LONG    i;
  957.  
  958.                     for (i = 0 ; UseIt && i < Work -> NumChars ; i++)
  959.                     {
  960.                         if(Work -> PrevBuffer[i] == DecimalPoint)
  961.                             UseIt = FALSE;
  962.                     }
  963.  
  964.                     if(!UseIt)
  965.                     {
  966.                         Work -> Actions &= ~SGA_USE;
  967.                         Work -> Actions |=  SGA_BEEP;
  968.                     }
  969.                 }
  970.             }
  971.             else
  972.             {
  973.                 Work -> Actions &= ~SGA_USE;
  974.                 Work -> Actions |=  SGA_BEEP;
  975.             }
  976.         }
  977.  
  978.         if(Work -> Actions & SGA_END)
  979.             LTK_AddHistory(Work);
  980.     }
  981.     else
  982.     {
  983.         if(*Msg != SGH_CLICK)
  984.             return(FALSE);
  985.     }
  986.  
  987.     return(TRUE);
  988. }
  989. #endif
  990.  
  991.  
  992. /*****************************************************************************/
  993.  
  994.  
  995. STATIC ULONG __asm __saveds
  996. LTK_DefaultEditRoutine(register __a0 struct Hook *Hook,register __a2 struct SGWork *Work,register __a1 ULONG *Msg)
  997. {
  998.     if(*Msg == SGH_KEY)
  999.     {
  1000.         if(Work -> IEvent -> ie_Code == CURSORUP || Work -> IEvent -> ie_Code == CURSORDOWN)
  1001.             LTK_HandleHistory(Work);
  1002.  
  1003.         if(Work -> EditOp == EO_ENTER)
  1004.         {
  1005.             LayoutHandle    *Handle = Hook -> h_Data;
  1006.             ObjectNode    *Node;
  1007.             BOOLEAN         Activate = TRUE;
  1008.  
  1009.             if(GETOBJECT(Work -> Gadget,Node))
  1010.             {
  1011.                 if(Node -> Type == STRING_KIND)
  1012.                 {
  1013.                     if(Node -> Special . String . LastGadget)
  1014.                         Activate = FALSE;
  1015.                 }
  1016. #ifndef DO_HEXHOOK
  1017.                 else
  1018.                 {
  1019.                     if(Node -> Type == INTEGER_KIND)
  1020.                     {
  1021.                         if(Node -> Special . Integer . LastGadget)
  1022.                             Activate = FALSE;
  1023.                     }
  1024.                 }
  1025. #endif
  1026.             }
  1027.  
  1028.             if(!(Work -> IEvent -> ie_Qualifier & QUALIFIER_SHIFT))
  1029.             {
  1030.                 if(Activate && Handle -> AutoActivate)
  1031.                     Work -> Actions |= SGA_NEXTACTIVE;
  1032.  
  1033.                 if(!(Work -> Actions & SGA_NEXTACTIVE))
  1034.                     Work -> Code = '\r';
  1035.             }
  1036.         }
  1037.  
  1038.         if(Work -> IEvent -> ie_Code == CURSORRIGHT && (Work -> IEvent -> ie_Qualifier & QUALIFIER_CONTROL))
  1039.         {
  1040.             if(Work -> BufferPos != Work -> NumChars)
  1041.             {
  1042.                 WORD i,Position = -1;
  1043.  
  1044.                 for(i = Work -> BufferPos ; i < Work -> NumChars ; i++)
  1045.                 {
  1046.                     if(Work -> WorkBuffer[i] == ' ')
  1047.                     {
  1048.                         for( ; i < Work -> NumChars ; i++)
  1049.                         {
  1050.                             if(Work -> WorkBuffer[i] != ' ')
  1051.                             {
  1052.                                 Position = i;
  1053.  
  1054.                                 break;
  1055.                             }
  1056.                         }
  1057.  
  1058.                         break;
  1059.                     }
  1060.                 }
  1061.  
  1062.                 if(Position != -1)
  1063.                     Work -> BufferPos = Position;
  1064.                 else
  1065.                     Work -> BufferPos = Work -> NumChars;
  1066.  
  1067.                 Work -> EditOp = EO_MOVECURSOR;
  1068.             }
  1069.         }
  1070.  
  1071.         if(Work -> IEvent -> ie_Code == CURSORLEFT && (Work -> IEvent -> ie_Qualifier & QUALIFIER_CONTROL))
  1072.         {
  1073.             if(Work -> BufferPos)
  1074.             {
  1075.                 WORD i,Position = -1;
  1076.  
  1077.                 for(i = Work -> BufferPos ; i >= 0 ; i--)
  1078.                 {
  1079.                     if(Work -> WorkBuffer[i] != ' ')
  1080.                     {
  1081.                         Position = i;
  1082.  
  1083.                         break;
  1084.                     }
  1085.                 }
  1086.  
  1087.                 if(Position == -1)
  1088.                     Position = 0;
  1089.  
  1090.                 if(Position)
  1091.                 {
  1092.                     i = Position;
  1093.  
  1094.                     Position = -1;
  1095.  
  1096.                     for( ; i >= 0 ; i--)
  1097.                     {
  1098.                         if(Work -> WorkBuffer[i] == ' ')
  1099.                         {
  1100.                             Position = i + 1;
  1101.  
  1102.                             break;
  1103.                         }
  1104.                     }
  1105.                 }
  1106.  
  1107.                 if(Position != -1)
  1108.                     Work -> BufferPos = Position;
  1109.                 else
  1110.                     Work -> BufferPos = 0;
  1111.  
  1112.                 Work -> EditOp = EO_MOVECURSOR;
  1113.             }
  1114.         }
  1115.  
  1116.         if(Work -> Actions & SGA_END)
  1117.             LTK_AddHistory(Work);
  1118.     }
  1119.     else
  1120.     {
  1121.         if(*Msg != SGH_CLICK)
  1122.             return(FALSE);
  1123.     }
  1124.  
  1125.     return(TRUE);
  1126. }
  1127.  
  1128.  
  1129. /*****************************************************************************/
  1130.  
  1131.  
  1132. #ifdef DO_HEXHOOK
  1133. STATIC ULONG __asm __saveds
  1134. LTK_HexEditRoutine(register __a0 struct Hook *hook,register __a2 struct SGWork *sgw,register __a1 ULONG *msg)
  1135. {
  1136.     ULONG result = FALSE;
  1137.  
  1138.     if(*msg == SGH_KEY)
  1139.     {
  1140.         BOOLEAN         activate    = TRUE;
  1141.         LayoutHandle    *handle        = hook -> h_Data;
  1142.         ObjectNode    *node;
  1143.  
  1144.         if(sgw -> IEvent -> ie_Code == CURSORUP || sgw -> IEvent -> ie_Code == CURSORDOWN)
  1145.             LTK_HandleHistory(sgw);
  1146.  
  1147.         if(GETOBJECT(sgw -> Gadget,node))
  1148.         {
  1149.             if(node -> Type == INTEGER_KIND)
  1150.             {
  1151.                 if(node -> Special . Integer . LastGadget)
  1152.                     activate = FALSE;
  1153.  
  1154.                 result = TRUE;
  1155.  
  1156.                 if(!LTK_ConvertNum((node -> Special . Integer . Min < 0),sgw -> WorkBuffer,(LONG *)&sgw -> StringInfo -> LongInt))
  1157.                 {
  1158.                     sgw -> EditOp    = EO_BADFORMAT;
  1159.                     sgw -> Actions    = SGA_BEEP;
  1160.                 }
  1161.             }
  1162.         }
  1163.  
  1164.         if(sgw -> EditOp == EO_ENTER && !(sgw -> IEvent -> ie_Qualifier & QUALIFIER_SHIFT))
  1165.         {
  1166.             if(activate && handle -> AutoActivate)
  1167.                 sgw -> Actions |= SGA_NEXTACTIVE;
  1168.  
  1169.             if(!(sgw -> Actions & SGA_NEXTACTIVE))
  1170.                 sgw -> Code = '\r';
  1171.         }
  1172.  
  1173.         if(sgw -> Actions & SGA_END)
  1174.             LTK_AddHistory(sgw);
  1175.     }
  1176.  
  1177.     return(result);
  1178. }
  1179. #endif
  1180.  
  1181.  
  1182. /*****************************************************************************/
  1183.  
  1184.  
  1185. #ifdef DO_PASSWORD_KIND
  1186. STATIC ULONG __asm __saveds
  1187. LTK_PasswordEditRoutine(register __a0 struct Hook *Hook,register __a2 struct SGWork *Work,register __a1 ULONG *Msg)
  1188. {
  1189.     ObjectNode *Node;
  1190.  
  1191.     if(GETOBJECT(Work -> Gadget,Node))
  1192.     {
  1193.         STRPTR    Buffer        = Node -> Special . String . RealString;
  1194.         STRPTR    Original    = Node -> Special . String . Original;
  1195.         WORD    Len;
  1196.  
  1197. /*        if(Work -> IEvent -> ie_Code == CURSORUP || Work -> IEvent -> ie_Code == CURSORDOWN)*/
  1198. /*            LTK_HandleHistory(Work);*/
  1199.  
  1200.         switch(*Msg)
  1201.         {
  1202.             case SGH_KEY:
  1203.  
  1204.                 switch(Work -> EditOp)
  1205.                 {
  1206.                     case EO_INSERTCHAR:
  1207.  
  1208.                         Buffer[Work -> BufferPos - 1]    = Work -> Code;
  1209.                         Buffer[Work -> NumChars]    = 0;
  1210.  
  1211.                         Work -> Code = (WORD)'·';
  1212.  
  1213.                         Work -> WorkBuffer[Work -> BufferPos - 1] = (UBYTE)'·';
  1214.  
  1215.                         break;
  1216.  
  1217.                     case EO_RESET:
  1218.  
  1219.                         Len = strlen(Original);
  1220.  
  1221.                         strcpy(Buffer,Original);
  1222.  
  1223.                         memset(Work -> WorkBuffer,'·',Len);
  1224.  
  1225.                         Work -> WorkBuffer[Len] = 0;
  1226.  
  1227.                         Work -> NumChars    = Len;
  1228.                         Work -> BufferPos    = Len;
  1229.                         Work -> EditOp        = EO_BIGCHANGE;
  1230.  
  1231.                         break;
  1232.  
  1233.                     case EO_CLEAR:
  1234.  
  1235.                         Work -> WorkBuffer[0]    = 0;
  1236.                         Work -> NumChars    = 0;
  1237.                         Work -> BufferPos    = 0;
  1238.                         Work -> EditOp        = EO_BIGCHANGE;
  1239.  
  1240.                         Buffer[0] = 0;
  1241.  
  1242.                         break;
  1243.  
  1244.                     case EO_DELBACKWARD:
  1245.  
  1246.                         Buffer[Work -> NumChars] = 0;
  1247.                         break;
  1248.  
  1249.                     case EO_NOOP:
  1250.  
  1251.                         break;
  1252.  
  1253.                     case EO_ENTER:
  1254.  
  1255.                         strcpy(Original,Buffer);
  1256.  
  1257.                         if(!(Work -> IEvent -> ie_Qualifier & QUALIFIER_SHIFT))
  1258.                         {
  1259.                             if(!Node -> Special . String . LastGadget && Node -> Special . String . LayoutHandle -> AutoActivate)
  1260.                                 Work -> Actions |= SGA_NEXTACTIVE;
  1261.  
  1262.                             if(!(Work -> Actions & SGA_NEXTACTIVE))
  1263.                                 Work -> Code = '\r';
  1264.                         }
  1265.  
  1266.                         break;
  1267.  
  1268.                     case EO_MOVECURSOR:
  1269.                     case EO_DELFORWARD:
  1270.  
  1271.                         Work -> Actions &= ~SGA_USE;
  1272.                         break;
  1273.  
  1274.                     default:
  1275.  
  1276.                         Work -> Actions &= ~SGA_USE;
  1277.                         Work -> Actions |=  SGA_BEEP;
  1278.                         break;
  1279.                 }
  1280.  
  1281.                 break;
  1282.  
  1283.             case SGH_CLICK:
  1284.  
  1285.                 Work -> BufferPos    = Work -> NumChars;
  1286.                 Work -> EditOp        = EO_BIGCHANGE;
  1287.  
  1288.                 break;
  1289.         }
  1290.  
  1291. /*        if(Work -> Actions & SGA_END)*/
  1292. /*            LTK_AddHistory(Work);*/
  1293.  
  1294.         return(TRUE);
  1295.     }
  1296.     else
  1297.         return(FALSE);
  1298. }
  1299. #endif
  1300.  
  1301.  
  1302. /*****************************************************************************/
  1303.  
  1304.  
  1305. STATIC VOID __regargs
  1306. LTK_SetPens(struct RastPort *rp, UWORD apen, UWORD bpen,UBYTE mode)
  1307. {
  1308.     if(V39)
  1309.         SetABPenDrMd(rp,apen,bpen,mode);
  1310.     else
  1311.     {
  1312.         if(apen != rp -> FgPen)
  1313.             SetAPen(rp,apen);
  1314.  
  1315.         if(bpen != rp -> BgPen)
  1316.             SetBPen(rp,bpen);
  1317.  
  1318.         if(mode != rp -> DrawMode)
  1319.             SetDrMd(rp,mode);
  1320.     }
  1321. }
  1322.  
  1323.  
  1324. /*****************************************************************************/
  1325.  
  1326.  
  1327. STATIC VOID __regargs
  1328. LTK_SetAPen(struct RastPort *rp,UWORD apen)
  1329. {
  1330.     if(V39)
  1331.     {
  1332.         if(GetAPen(rp) != apen)
  1333.             SetAPen(rp,apen);
  1334.     }
  1335.     else
  1336.     {
  1337.         if(apen != rp -> FgPen)
  1338.             SetAPen(rp,apen);
  1339.     }
  1340. }
  1341.  
  1342.  
  1343. /*****************************************************************************/
  1344.  
  1345.  
  1346. STATIC VOID __regargs
  1347. LTK_SetFont(LayoutHandle *handle,struct TextFont *font)
  1348. {
  1349.     SetFont(&handle -> RPort,font);
  1350.  
  1351.     if(handle -> Window)
  1352.         SetFont(handle -> Window -> RPort,font);
  1353. }
  1354.  
  1355.  
  1356. /*****************************************************************************/
  1357.  
  1358.  
  1359. STATIC VOID __regargs
  1360. LTK_DrawBevelBox(LayoutHandle *handle,ObjectNode *node)
  1361. {
  1362.     DrawBevelBox(&handle -> RPort,node -> Left,node -> Top,node -> Width,node -> Height,
  1363.         GT_VisualInfo,    handle -> VisualInfo,
  1364.         GTBB_Recessed,    TRUE,
  1365.     TAG_DONE);
  1366. }
  1367.  
  1368.  
  1369. /*****************************************************************************/
  1370.  
  1371.  
  1372. STATIC VOID __regargs
  1373. LTK_PlaceText(LayoutHandle *handle,STRPTR text,ULONG textLen,LONG x,LONG y)
  1374. {
  1375.     Move(&handle -> RPort,x,y);
  1376.     Text(&handle -> RPort,text,textLen);
  1377. }
  1378.  
  1379.  
  1380. /*****************************************************************************/
  1381.  
  1382.  
  1383. STATIC VOID __regargs
  1384. LTK_GetDisplayClip(struct Screen *screen,WORD *left,WORD *top,WORD *width,WORD *height)
  1385. {
  1386.     struct TagItem tags[2] = { VTAG_VIEWPORTEXTRA_GET, NULL, TAG_DONE };
  1387.  
  1388.     if(!VideoControl(screen -> ViewPort . ColorMap,tags))
  1389.     {
  1390.         struct ViewPortExtra    *vpe = (struct ViewPortExtra *)tags[0] . ti_Data;
  1391.         struct Rectangle     clip;
  1392.  
  1393.         QueryOverscan(GetVPModeID(&screen -> ViewPort),&clip,OSCAN_TEXT);
  1394.  
  1395.         *width    = vpe -> DisplayClip . MaxX - vpe -> DisplayClip . MinX + 1;
  1396.         *height    = vpe -> DisplayClip . MaxY - vpe -> DisplayClip . MinY + 1;
  1397.  
  1398.         if(*width < clip . MaxX - clip . MinX + 1)
  1399.             *width = clip . MaxX - clip . MinX + 1;
  1400.  
  1401.         if(*height < clip . MaxY - clip . MinY + 1)
  1402.             *height = clip . MaxY - clip . MinY + 1;
  1403.  
  1404.         if(*width > screen -> Width)
  1405.             *width = screen -> Width;
  1406.  
  1407.         if(*height > screen -> Height)
  1408.             *height = screen -> Height;
  1409.     }
  1410.     else
  1411.     {
  1412.         *width    = screen -> Width;
  1413.         *height = screen -> Height;
  1414.     }
  1415.  
  1416.     *left = screen -> LeftEdge;
  1417.     *top  = screen -> TopEdge;
  1418.  
  1419.     if(*left > 0)
  1420.         *left = 0;
  1421.     else
  1422.         *left = -(*left);
  1423.  
  1424.     if(*top > 0)
  1425.         *top = 0;
  1426.     else
  1427.         *top = -(*top);
  1428.  
  1429.     if((*left > screen -> Width) || (*left < 0))
  1430.         *left = 0;
  1431.  
  1432.     if ((*top > screen -> Height) || (*top < 0))
  1433.         *top = 0;
  1434. }
  1435.  
  1436.  
  1437. /*****************************************************************************/
  1438.  
  1439.  
  1440. STATIC VOID __regargs
  1441. LTK_MoveToWindow(LayoutHandle *handle)
  1442. {
  1443.     if(V39 && handle -> MoveToWindow)
  1444.     {
  1445.         WORD left,top,width,height;
  1446.  
  1447.         LTK_GetDisplayClip(handle->Screen,&left,&top,&width,&height);
  1448.  
  1449.         if(handle -> Window -> Width < width)
  1450.             left = (width - handle -> Window -> Width) / 2;
  1451.         else
  1452.             left = 0;
  1453.  
  1454.         if(handle -> Window -> Height < height)
  1455.             top = (height - handle -> Window -> Height) / 2;
  1456.         else
  1457.             top = 0;
  1458.  
  1459.         if((left = handle -> Window -> LeftEdge - left) < 0)
  1460.             left = 0;
  1461.  
  1462.         if((top = handle -> Window -> TopEdge - top) < 0)
  1463.             top = 0;
  1464.  
  1465.         ScreenPosition(handle -> Screen,SPOS_MAKEVISIBLE,left,top,left + width - 1,top + height - 1);
  1466.     }
  1467. }
  1468.  
  1469.  
  1470. /*****************************************************************************/
  1471.  
  1472.  
  1473. STATIC VOID __regargs
  1474. LTK_GetStorage(ObjectNode *Node)
  1475. {
  1476.     if(Node -> Storage)
  1477.     {
  1478.         LONG    Number = 0;
  1479.         STRPTR    String = NULL;
  1480.  
  1481.         switch(Node -> StorageType)
  1482.         {
  1483.             case STORAGE_BYTE:
  1484.  
  1485.                 Number = *(BYTE *)Node -> Storage;
  1486.                 break;
  1487.  
  1488.             case STORAGE_UBYTE:
  1489.  
  1490.                 Number = *(UBYTE *)Node -> Storage;
  1491.                 break;
  1492.  
  1493.             case STORAGE_WORD:
  1494.  
  1495.                 Number = *(WORD *)Node -> Storage;
  1496.                 break;
  1497.  
  1498.             case STORAGE_UWORD:
  1499.  
  1500.                 Number = *(UWORD *)Node -> Storage;
  1501.                 break;
  1502.  
  1503.             case STORAGE_LONG:
  1504.  
  1505.                 Number = *(LONG *)Node -> Storage;
  1506.                 break;
  1507.  
  1508.             case STORAGE_ULONG:
  1509.  
  1510.                 Number = *(ULONG *)Node -> Storage;
  1511.                 break;
  1512.  
  1513.             case STORAGE_STRPTR:
  1514.  
  1515.                 String = Node -> Storage;
  1516.                 break;
  1517.         }
  1518.  
  1519.         switch(Node -> Type)
  1520.         {
  1521.             case CHECKBOX_KIND:
  1522.             case LISTVIEW_KIND:
  1523.             case MX_KIND:
  1524.             case CYCLE_KIND:
  1525.             case PALETTE_KIND:
  1526.             case SLIDER_KIND:
  1527.             case SCROLLER_KIND:
  1528. #ifdef DO_GAUGE_KIND
  1529.             case GAUGE_KIND:
  1530. #endif
  1531.  
  1532. #ifdef DO_TAPEDECK_KIND
  1533.             case TAPEDECK_KIND:
  1534. #endif    /* DO_TAPEDECK_KIND */
  1535.  
  1536. #ifdef DO_FRACTION_KIND
  1537.             case FRACTION_KIND:
  1538. #endif
  1539.                 Node -> Current = Number;
  1540.                 break;
  1541.  
  1542.             case STRING_KIND:
  1543. #ifdef DO_PASSWORD_KIND
  1544.             case PASSWORD_KIND:
  1545. #endif
  1546.                 Node -> Special . String . String = String;
  1547.                 break;
  1548.  
  1549.             case INTEGER_KIND:
  1550.  
  1551.                 Node -> Special . Integer . Number = Number;
  1552.                 break;
  1553.         }
  1554.     }
  1555. }
  1556.  
  1557. STATIC VOID __regargs
  1558. LTK_PutStorage(ObjectNode *Node)
  1559. {
  1560.     if(Node -> Storage)
  1561.     {
  1562.         LONG    Number = 0;
  1563.         STRPTR    String = NULL;
  1564.  
  1565.         switch(Node -> Type)
  1566.         {
  1567.             case CHECKBOX_KIND:
  1568.             case LISTVIEW_KIND:
  1569.             case MX_KIND:
  1570.             case CYCLE_KIND:
  1571.             case PALETTE_KIND:
  1572.             case SLIDER_KIND:
  1573.             case SCROLLER_KIND:
  1574. #ifdef DO_GAUGE_KIND
  1575.             case GAUGE_KIND:
  1576. #endif
  1577.  
  1578. #ifdef DO_TAPEDECK_KIND
  1579.             case TAPEDECK_KIND:
  1580. #endif    /* DO_TAPEDECK_KIND */
  1581.                 Number = Node -> Current;
  1582.                 break;
  1583.  
  1584. #ifdef DO_FRACTION_KIND
  1585.             case FRACTION_KIND:
  1586.  
  1587.                 Number = (LONG)LT_String2Fixed(((struct StringInfo *)Node -> Host -> SpecialInfo) -> Buffer);
  1588.                 break;
  1589. #endif
  1590.  
  1591. #ifdef DO_PASSWORD_KIND
  1592.             case PASSWORD_KIND:
  1593.  
  1594.                 String = Node -> Special . String . Original;
  1595.                 break;
  1596. #endif
  1597.  
  1598.             case STRING_KIND:
  1599.  
  1600.                 String = ((struct StringInfo *)Node -> Host -> SpecialInfo) -> Buffer;
  1601.                 break;
  1602.  
  1603.             case INTEGER_KIND:
  1604.  
  1605.                 Number = ((struct StringInfo *)Node -> Host -> SpecialInfo) -> LongInt;
  1606.                 break;
  1607.         }
  1608.  
  1609.         switch(Node -> StorageType)
  1610.         {
  1611.             case STORAGE_BYTE:
  1612.  
  1613.                 if(!String)
  1614.                     *(BYTE *)Node -> Storage = (BYTE)Number;
  1615.  
  1616.                 break;
  1617.  
  1618.             case STORAGE_UBYTE:
  1619.  
  1620.                 if(!String)
  1621.                     *(UBYTE *)Node -> Storage = (UBYTE)Number;
  1622.  
  1623.                 break;
  1624.  
  1625.             case STORAGE_WORD:
  1626.  
  1627.                 if(!String)
  1628.                     *(WORD *)Node -> Storage = (WORD)Number;
  1629.  
  1630.                 break;
  1631.  
  1632.             case STORAGE_UWORD:
  1633.  
  1634.                 if(!String)
  1635.                     *(UWORD *)Node -> Storage = (UWORD)Number;
  1636.  
  1637.                 break;
  1638.  
  1639.             case STORAGE_LONG:
  1640.  
  1641.                 if(!String)
  1642.                     *(LONG *)Node -> Storage = (LONG)Number;
  1643.  
  1644.                 break;
  1645.  
  1646.             case STORAGE_ULONG:
  1647.  
  1648.                 if(!String)
  1649.                     *(ULONG *)Node -> Storage = (ULONG)Number;
  1650.  
  1651.                 break;
  1652.  
  1653.             case STORAGE_STRPTR:
  1654.  
  1655.                 if(String)
  1656.                     strcpy(Node -> Storage,String);
  1657.  
  1658.                 break;
  1659.         }
  1660.     }
  1661. }
  1662.  
  1663.  
  1664. /*****************************************************************************/
  1665.  
  1666.  
  1667. STATIC VOID __stdargs
  1668. sprintf(STRPTR buffer, STRPTR formatString,...)
  1669. {
  1670.     va_list varArgs;
  1671.  
  1672.     va_start(varArgs,formatString);
  1673.     RawDoFmt(formatString,varArgs,(VOID (*)())(VOID (*))"\x16\xC0\x4E\x75",buffer);
  1674.     va_end(varArgs);
  1675. }
  1676.  
  1677.  
  1678. /*****************************************************************************/
  1679.  
  1680.  
  1681. STATIC VOID __regargs
  1682. LTK_BlinkButton(LayoutHandle *handle,struct Gadget *gadget)
  1683. {
  1684.     if((gadget -> Flags & (GFLG_GADGIMAGE | GFLG_GADGHIMAGE)) && gadget -> SelectRender)
  1685.         DrawImageState(&handle -> RPort,gadget -> SelectRender,gadget -> LeftEdge,gadget -> TopEdge,IDS_SELECTED,handle -> DrawInfo);
  1686.  
  1687.     if(handle -> TimeRequest . tr_node . io_Device)
  1688.     {
  1689.         Forbid();
  1690.  
  1691.         handle -> TimePort . mp_SigTask = SysBase -> ThisTask;
  1692.  
  1693.         handle -> TimeRequest . tr_node . io_Command    = TR_ADDREQUEST;
  1694.         handle -> TimeRequest . tr_time . tv_secs    = 0;
  1695.         handle -> TimeRequest . tr_time . tv_micro    = 80000;
  1696.  
  1697.         SetSignal(0,SIGF_SINGLE);
  1698.         DoIO(&handle -> TimeRequest);
  1699.         Permit();
  1700.     }
  1701.     else
  1702.         TimeDelay(UNIT_VBLANK,0,80000);
  1703.  
  1704.     if ((gadget -> Flags & GFLG_GADGIMAGE) && gadget -> GadgetRender)
  1705.         DrawImageState(&handle -> RPort,gadget -> GadgetRender,gadget -> LeftEdge,gadget -> TopEdge,IDS_NORMAL,handle -> DrawInfo);
  1706. }
  1707.  
  1708.  
  1709. /*****************************************************************************/
  1710.  
  1711.  
  1712. #ifdef DO_GAUGE_KIND
  1713. STATIC VOID __regargs
  1714. LTK_DrawGauge(LayoutHandle *handle,ObjectNode *node,LONG percent,BOOLEAN fullRefresh)
  1715. {
  1716.     struct RastPort *rp = &handle -> RPort;
  1717.  
  1718.     if(fullRefresh)
  1719.     {
  1720.         LONG top = node -> Top + node -> Height - (handle -> RPort . TxHeight + 2);
  1721.  
  1722.         LTK_SetAPen(rp,handle -> BackgroundPen);
  1723.         RectFill(rp,node -> Left,node -> Top,node -> Left + node -> Width - 1,node -> Top + node -> Height - 1);
  1724.  
  1725.         DrawBevelBox(rp,node -> Left,node -> Top,node -> Width,node -> Height - (handle -> InterHeight + handle -> RPort . TxHeight + 2),
  1726.             GT_VisualInfo,    handle -> VisualInfo,
  1727.             GTBB_Recessed,    TRUE,
  1728.         TAG_DONE);
  1729.  
  1730.         LTK_SetPens(rp,handle -> TextPen,0,JAM1);
  1731.  
  1732.         LTK_PlaceText(handle,"0%",2,node -> Left,top + handle -> RPort . TxBaseline);
  1733.         LTK_PlaceText(handle,"100%",4,node -> Left + node -> Width - TextLength(rp,"100%",4),top + handle -> RPort . TxBaseline);
  1734.  
  1735.         if(node -> Width >= TextLength(rp,"0% 50% 100%",11))
  1736.         {
  1737.             LONG i,left,total = node -> Width - 2;
  1738.  
  1739.             LTK_PlaceText(handle,"50%",3,node -> Left + (node -> Width - TextLength(rp,"50%",3)) / 2,top + handle -> RPort . TxBaseline);
  1740.  
  1741.             top -= handle -> InterHeight;
  1742.  
  1743.             for (i = 0 ; i < 5 ; i++)
  1744.             {
  1745.                 left = (total * i) / 4;
  1746.  
  1747.                 RectFill(rp,node -> Left + left,top,node -> Left + left + 1,top + 1);
  1748.             }
  1749.         }
  1750.         else
  1751.         {
  1752.             LONG i,left,total = node -> Width - 2;
  1753.  
  1754.             top -= handle -> InterHeight;
  1755.  
  1756.             for (i = 0; i < 3; i++)
  1757.             {
  1758.                 left = (total * i) / 2;
  1759.  
  1760.                 RectFill(rp,node -> Left + left,top,node -> Left + left + 1,top + 1);
  1761.             }
  1762.         }
  1763.     }
  1764.  
  1765.     if(node -> Special . Gauge . InfoLength && node -> Special . Gauge . InfoText[0])
  1766.     {
  1767.         LONG            height    = node -> Height - (1 + handle -> InterHeight + handle -> RPort . TxHeight + 2 + 1);
  1768.         LONG            width    = node -> Width - (2 + 2);
  1769.         LONG            left    = 0;
  1770.         LONG            right    = (width * percent) / 100;
  1771.         struct TextExtent    Extent;
  1772.         LONG            len;
  1773.  
  1774.         if(right)
  1775.         {
  1776.             LTK_SetAPen(rp,handle -> DrawInfo -> dri_Pens[FILLPEN]);
  1777.  
  1778.             RectFill(rp,node -> Left + 2 + left,node -> Top + 1,node -> Left + 2 + right - 1,node -> Top + 1 + height - 1);
  1779.         }
  1780.  
  1781.         if(right < width)
  1782.         {
  1783.             left    = right;
  1784.             right    = width;
  1785.  
  1786.             LTK_SetAPen(rp,handle -> BackgroundPen);
  1787.             RectFill(rp,node -> Left + 2 + left,node -> Top + 1,node -> Left + 2 + right - 1,node -> Top + 1 + height - 1);
  1788.         }
  1789.  
  1790.         if(handle -> DrawInfo -> dri_Pens[FILLTEXTPEN] == handle -> DrawInfo -> dri_Pens[BACKGROUNDPEN])
  1791.         {
  1792.             if(handle -> DrawInfo -> dri_Pens[TEXTPEN] == handle -> DrawInfo -> dri_Pens[FILLPEN])
  1793.                 LTK_SetPens(rp,handle -> DrawInfo -> dri_Pens[TEXTPEN],handle -> BackgroundPen,JAM1 | COMPLEMENT);
  1794.             else
  1795.                 LTK_SetPens(rp,handle -> DrawInfo -> dri_Pens[TEXTPEN],handle -> BackgroundPen,JAM1);
  1796.         }
  1797.         else
  1798.         {
  1799.             if(handle -> DrawInfo -> dri_Pens[FILLTEXTPEN] == handle -> DrawInfo -> dri_Pens[FILLPEN])
  1800.                 LTK_SetPens(rp,handle -> DrawInfo -> dri_Pens[FILLTEXTPEN],handle -> BackgroundPen,JAM1 | COMPLEMENT);
  1801.             else
  1802.                 LTK_SetPens(rp,handle -> DrawInfo -> dri_Pens[FILLTEXTPEN],handle -> BackgroundPen,JAM1);
  1803.         }
  1804.  
  1805.         len = TextFit(rp,node -> Special . Gauge . InfoText,strlen(node -> Special . Gauge . InfoText),&Extent,NULL,1,width,32767);
  1806.  
  1807.         LTK_PlaceText(handle,node -> Special . Gauge . InfoText,len,node -> Left + 2 + (width - Extent . te_Width) / 2,node -> Top + 1 + (height - rp -> Font -> tf_YSize) / 2 + rp -> Font -> tf_Baseline);
  1808.  
  1809.         LTK_SetPens(rp,handle -> TextPen,handle->BackgroundPen,JAM1);
  1810.     }
  1811.     else
  1812.     {
  1813.         if(node -> Current < percent)
  1814.         {
  1815.             LONG height    = node -> Height - (1 + handle -> InterHeight + handle -> RPort . TxHeight + 2 + 1);
  1816.             LONG width    = node -> Width - (2 + 2);
  1817.             LONG left    = (width * node -> Current) / 100;
  1818.             LONG right    = (width * percent) / 100;
  1819.  
  1820.             if(right)
  1821.             {
  1822.                 LTK_SetAPen(rp,handle -> DrawInfo -> dri_Pens[FILLPEN]);
  1823.                 RectFill(rp,node -> Left + 2 + left,node -> Top + 1,node -> Left + 2 + right - 1,node -> Top + 1 + height - 1);
  1824.             }
  1825.         }
  1826.         else
  1827.         {
  1828.             if(node -> Current > percent)
  1829.             {
  1830.                 LONG height    = node -> Height - (1 + handle -> InterHeight + handle -> RPort . TxHeight + 2 + 1);
  1831.                 LONG width    = node -> Width - (2 + 2);
  1832.                 LONG left    = (width * percent) / 100;
  1833.                 LONG right    = (width * node -> Current) / 100;
  1834.  
  1835.                 if(right)
  1836.                 {
  1837.                     LTK_SetAPen(rp,handle -> BackgroundPen);
  1838.                     RectFill(rp,node -> Left + 2 + left,node -> Top + 1,node -> Left + 2 + right - 1,node -> Top + 1 + height - 1);
  1839.                 }
  1840.             }
  1841.         }
  1842.     }
  1843.  
  1844.     node -> Current = percent;
  1845.  
  1846.     LTK_PutStorage(node);
  1847. }
  1848. #endif
  1849.  
  1850.  
  1851. /*****************************************************************************/
  1852.  
  1853.  
  1854. STATIC VOID __regargs
  1855. LTK_PrintLine(LayoutHandle *handle,UBYTE alignType,LONG left,LONG top,LONG space,STRPTR line,LONG len)
  1856. {
  1857.     struct RastPort        *rp;
  1858.     LONG             width;
  1859.     struct TextExtent     extent;
  1860.  
  1861.     rp    = &handle -> RPort;
  1862.     len    = TextFit(rp,line,len,&extent,NULL,1,space,32767);
  1863.     width    = extent . te_Width;
  1864.  
  1865.     if(len)
  1866.     {
  1867.         LTK_SetPens(rp,handle -> TextPen,handle -> BackgroundPen,JAM2);
  1868.  
  1869.         if(alignType == ALIGNTEXT_CENTERED)
  1870.         {
  1871.             LTK_PlaceText(handle,line,len,left + (space - width) / 2,top + handle -> RPort . TxBaseline);
  1872.  
  1873.             if(width < space)
  1874.             {
  1875.                 LONG fill;
  1876.  
  1877.                 LTK_SetAPen(rp,handle -> BackgroundPen);
  1878.  
  1879.                 if((fill = (space - width) / 2) > 0)
  1880.                     RectFill(rp,left,top,left + fill - 1,top + handle -> RPort . TxHeight - 1);
  1881.  
  1882.                 if((fill = space - ((space - width) / 2)) > 0)
  1883.                     RectFill(rp,left + fill,top,left + space - 1,top + handle -> RPort . TxHeight - 1);
  1884.             }
  1885.         }
  1886.         else
  1887.         {
  1888.             if(alignType == ALIGNTEXT_LEFT)
  1889.             {
  1890.                 LTK_PlaceText(handle,line,len,left,top + handle -> RPort.TxBaseline);
  1891.  
  1892.                 if(left + width <= left + space - 1)
  1893.                 {
  1894.                     LTK_SetAPen(rp,handle -> BackgroundPen);
  1895.  
  1896.                     RectFill(rp,left + width,top,left + space - 1,top + handle -> RPort . TxHeight - 1);
  1897.                 }
  1898.             }
  1899.             else
  1900.             {
  1901.                 LTK_PlaceText(handle,line,len,left + space - width,top + handle -> RPort . TxBaseline);
  1902.  
  1903.                 if(width < space)
  1904.                 {
  1905.                     LTK_SetAPen(rp,handle -> BackgroundPen);
  1906.                     RectFill(rp,left,top,left + space - width - 1,top + handle -> RPort . TxHeight - 1);
  1907.                 }
  1908.             }
  1909.         }
  1910.     }
  1911.     else
  1912.     {
  1913.         LTK_SetAPen(rp,handle -> BackgroundPen);
  1914.         RectFill(rp,left,top,left + space - 1,top + handle -> RPort . TxHeight - 1);
  1915.     }
  1916. }
  1917.  
  1918.  
  1919. /*****************************************************************************/
  1920.  
  1921.  
  1922. STATIC VOID __regargs
  1923. LTK_PrintLinePadded(LayoutHandle *Handle,LONG Left,LONG Top,LONG Space,STRPTR Line,LONG Len)
  1924. {
  1925.     struct RastPort    *RPort    = &Handle -> RPort;
  1926.     LONG         Size    = 0;
  1927.     LONG         Start    = 0;
  1928.     LONG         Count    = 0;
  1929.     LONG         i    = 0;
  1930.     LONG         Width    = 0;
  1931.  
  1932.     while(i < Len && Line[i] == ' ')
  1933.     {
  1934.         Size++;
  1935.         i++;
  1936.     }
  1937.  
  1938.     while(i < Len)
  1939.     {
  1940.         while(i < Len && Line[i] != ' ')
  1941.         {
  1942.             Size++;
  1943.             i++;
  1944.         }
  1945.  
  1946.         Width += TextLength(RPort,&Line[Start],Size);
  1947.  
  1948.         Count++;
  1949.  
  1950.         while(i < Len && Line[i] == ' ')
  1951.             i++;
  1952.  
  1953.         Start    = i;
  1954.         Size    = 0;
  1955.     }
  1956.  
  1957.     if(Width)
  1958.     {
  1959.         LONG j;
  1960.  
  1961.         Space -= Width;
  1962.  
  1963.         j = Start = Size = 0;
  1964.  
  1965.         while(j < Len && Line[j] == ' ')
  1966.         {
  1967.             Size++;
  1968.             j++;
  1969.         }
  1970.  
  1971.         LTK_SetPens(RPort,Handle -> TextPen,Handle -> BackgroundPen,JAM2);
  1972.         Move(RPort,Left,Top + RPort -> TxBaseline);
  1973.  
  1974.         Count--;
  1975.  
  1976.         for(i = 0 ; i <= Count ; i++)
  1977.         {
  1978.             if(i)
  1979.             {
  1980.                 LONG Delta;
  1981.  
  1982.                 if(Delta = (Space * i) / Count - (Space * (i - 1)) / Count)
  1983.                 {
  1984.                     LTK_SetAPen(RPort,Handle -> BackgroundPen);
  1985.                     RectFill(RPort,RPort -> cp_x,Top,RPort -> cp_x + Delta - 1,Top + RPort -> TxHeight - 1);
  1986.  
  1987.                     LTK_SetAPen(RPort,Handle -> TextPen);
  1988.                     Move(RPort,RPort -> cp_x + Delta,RPort -> cp_y);
  1989.                 }
  1990.             }
  1991.  
  1992.             while(j < Len && Line[j] != ' ')
  1993.             {
  1994.                 Size++;
  1995.                 j++;
  1996.             }
  1997.  
  1998.             Text(RPort,&Line[Start],Size);
  1999.  
  2000.             while(j < Len && Line[j] == ' ')
  2001.                 j++;
  2002.  
  2003.             Start = j;
  2004.             Size = 0;
  2005.         }
  2006.     }
  2007.     else
  2008.     {
  2009.         LTK_SetAPen(RPort,Handle -> BackgroundPen);
  2010.         RectFill(RPort,Left,Top,Left + Space - 1,Top + RPort -> TxHeight - 1);
  2011.     }
  2012. }
  2013.  
  2014.  
  2015. /*****************************************************************************/
  2016.  
  2017.  
  2018. STATIC VOID __regargs
  2019. LTK_PrintBoxLine(LayoutHandle *handle,ObjectNode *node,LONG index)
  2020. {
  2021.     if(node -> Special . Box . Lines && node -> Special . Box . Lines[index])
  2022.     {
  2023.         LONG len = strlen(node -> Special . Box . Lines[index]);
  2024.  
  2025.         if(node -> Special . Box . AlignText == ALIGNTEXT_PAD)
  2026.             LTK_PrintLinePadded(handle,node -> Left + 4,node -> Top + 2 + index * handle -> RPort . TxHeight,node -> Width - 8,node -> Special . Box . Lines[index],len);
  2027.         else
  2028.             LTK_PrintLine(handle,node -> Special . Box . AlignText,node -> Left + 4,node -> Top + 2 + index * handle -> RPort . TxHeight,node -> Width - 8,node -> Special . Box . Lines[index],len);
  2029.     }
  2030. }
  2031.  
  2032.  
  2033. /*****************************************************************************/
  2034.  
  2035.  
  2036. STATIC VOID __regargs
  2037. LTK_ResetGroups(ObjectNode *group)
  2038. {
  2039.     ObjectNode *node;
  2040.  
  2041.     group -> Special . Group . ExtraLeft    = 0;
  2042.     group -> Special . Group . ExtraTop    = 0;
  2043.     group -> Special . Group . MaxOffset    = 0;
  2044.     group -> Special . Group . MaxSize    = 0;
  2045.     group -> GroupIndent            = FALSE;
  2046.     group -> Left                = 0;
  2047.     group -> Top                = 0;
  2048.     group -> Width                = 0;
  2049.     group -> Height                = 0;
  2050.  
  2051.     SCANGROUP(group,node)
  2052.     {
  2053.         if(node -> Type == GROUP_KIND)
  2054.             LTK_ResetGroups(node);
  2055.     }
  2056. }
  2057.  
  2058.  
  2059. /*****************************************************************************/
  2060.  
  2061.  
  2062. STATIC BOOLEAN __regargs
  2063. LTK_Rescale(LayoutHandle *handle,BOOLEAN trimWidth,BOOLEAN trimHeight)
  2064. {
  2065.     STATIC struct TextAttr topazAttr =
  2066.     {
  2067.         "topaz.font",
  2068.         8,
  2069.         FS_NORMAL,
  2070.         FPF_ROMFONT | FPF_DESIGNED
  2071.     };
  2072.  
  2073.     LONG    oldWidth;
  2074.     LONG    oldHeight;
  2075.     UBYTE    glyph;
  2076.     LONG    glyphWidth;
  2077.     LONG    count;
  2078.     LONG    i;
  2079.     LONG    total;
  2080.     BOOLEAN    found;
  2081.  
  2082.     oldWidth    = handle -> GlyphWidth;
  2083.     oldHeight    = handle -> RPort . TxHeight;
  2084.  
  2085.     if(handle -> CloseFont)
  2086.     {
  2087.         CloseFont(handle -> RPort . Font);
  2088.  
  2089.         handle -> CloseFont = FALSE;
  2090.     }
  2091.  
  2092.     /* GfxBase -> DefaultFont is guaranteed not to ever be removed from
  2093.      * memory,so we use that fact...
  2094.      */
  2095.  
  2096.     LTK_SetFont(handle,GfxBase -> DefaultFont);
  2097.  
  2098.     handle -> TextAttr            = &handle -> CopyTextAttr;
  2099.     handle -> CopyTextAttr . tta_Name    = handle -> RPort . Font -> tf_Message . mn_Node . ln_Name;
  2100.     handle -> CopyTextAttr . tta_YSize    = handle -> RPort . TxHeight;
  2101.     handle -> CopyTextAttr . tta_Style    = handle -> RPort . Font -> tf_Style;
  2102.     handle -> CopyTextAttr . tta_Flags    = handle -> RPort . TxFlags;
  2103.  
  2104.     if(handle -> RPort . Font -> tf_Style & FSF_TAGGED)
  2105.         handle -> CopyTextAttr . tta_Tags = ((struct TextFontExtension *)handle -> RPort . Font -> tf_Extension) -> tfe_Tags;
  2106.  
  2107.     FOREVER
  2108.     {
  2109.         count = 0;
  2110.         total = 0;
  2111.  
  2112.         for(i = 32 ; i < 127 ; i++)
  2113.         {
  2114.             glyph = i;
  2115.             total += TextLength(&handle -> RPort,&glyph,1);
  2116.             count++;
  2117.         }
  2118.  
  2119.         for(i = 160 ; i < 256 ; i++)
  2120.         {
  2121.             glyph = i;
  2122.             total += TextLength(&handle -> RPort,&glyph,1);
  2123.             count++;
  2124.         }
  2125.  
  2126.         glyphWidth = total / count;
  2127.  
  2128.         found = TRUE;
  2129.  
  2130.         if(trimWidth && (glyphWidth >= oldWidth))
  2131.             found = FALSE;
  2132.  
  2133.         if(trimHeight && (oldHeight >= handle -> RPort . TxHeight))
  2134.             found = FALSE;
  2135.  
  2136.         if(found)
  2137.         {
  2138.             handle -> GlyphWidth    = glyphWidth;
  2139.             handle -> Rescaled    = TRUE;
  2140.  
  2141.             if(glyphWidth <= 8)
  2142.                 handle -> InterWidth = 4;
  2143.             else
  2144.                 handle -> InterWidth = glyphWidth / 2;
  2145.  
  2146.             if(handle -> RPort . TxHeight <= 8)
  2147.                 handle -> InterHeight = 2;
  2148.             else
  2149.                 handle -> InterHeight = handle -> RPort . TxHeight / 4;
  2150.  
  2151.             LTK_ResetGroups(handle -> TopGroup);
  2152.  
  2153.             return(TRUE);
  2154.         }
  2155.  
  2156.         if(handle -> TextAttr == &topazAttr)
  2157.             return(FALSE);
  2158.  
  2159.         LTK_SetFont(handle,OpenFont(&topazAttr));
  2160.  
  2161.         handle -> TextAttr    = &topazAttr;
  2162.         handle -> CloseFont    = TRUE;
  2163.     }
  2164. }
  2165.  
  2166.  
  2167. /*****************************************************************************/
  2168.  
  2169.  
  2170. STATIC VOID __regargs
  2171. LTK_DrawIncrementer(struct RastPort *rp,BOOLEAN leftDirection,LONG left,LONG top,LONG width,LONG height)
  2172. {
  2173.     LONG middle;
  2174.     LONG x0,x1;
  2175.     LONG stop;
  2176.  
  2177.     middle = height / 2;
  2178.  
  2179.     if(leftDirection)
  2180.     {
  2181.         x0 = left + 2;
  2182.         x1 = left + width - 3;
  2183.     }
  2184.     else
  2185.     {
  2186.         x0 = left + width - 3;
  2187.         x1 = left + 2;
  2188.     }
  2189.  
  2190.     if(height > width)
  2191.         stop = (width - 4) / 2;
  2192.     else
  2193.         stop = (height - 4) / 2;
  2194.  
  2195.     Move(rp,x0,top + middle);
  2196.     Draw(rp,x1,top + middle - stop);
  2197.     Move(rp,x0,top + middle);
  2198.     Draw(rp,x1,top + middle + stop);
  2199. }
  2200.  
  2201.  
  2202. /*****************************************************************************/
  2203.  
  2204.  
  2205. #ifdef DO_TAPEDECK_KIND
  2206. STATIC VOID __regargs
  2207. LTK_DrawBackFore(struct RastPort *RPort,BOOLEAN Back,LONG Left,LONG Top,LONG Width,LONG Height)
  2208. {
  2209.     LONG i,Len,Start,ArrowWidth,ArrowHeight,Shift;
  2210.  
  2211.     ArrowWidth    = Width / 2;
  2212.     ArrowHeight    = Height;
  2213.     Left        = Left + (Width - ArrowWidth) / 2;
  2214.     Shift        = ArrowWidth / 2;
  2215.  
  2216.     if(Back)
  2217.     {
  2218.         for(i = 0 ; i < ArrowWidth ; i++)
  2219.         {
  2220.             Len    = (ArrowHeight * (i + 1)) / ArrowWidth;
  2221.             Start    = Top + (ArrowHeight - Len) / 2;
  2222.  
  2223.             Move(RPort,Left + i - Shift,Start);
  2224.             Draw(RPort,Left + i - Shift,Start + Len - 1);
  2225.  
  2226.             Move(RPort,Left + i + Shift,Start);
  2227.             Draw(RPort,Left + i + Shift,Start + Len - 1);
  2228.         }
  2229.     }
  2230.     else
  2231.     {
  2232.         for(i = 0 ; i < ArrowWidth ; i++)
  2233.         {
  2234.             Len    = (ArrowHeight * (i + 1)) / ArrowWidth;
  2235.             Start    = Top + (ArrowHeight - Len) / 2;
  2236.  
  2237.             Move(RPort,Left + ArrowWidth - 1 - i - Shift,Start);
  2238.             Draw(RPort,Left + ArrowWidth - 1 - i - Shift,Start + Len - 1);
  2239.  
  2240.             Move(RPort,Left + ArrowWidth - 1 - i + Shift,Start);
  2241.             Draw(RPort,Left + ArrowWidth - 1 - i + Shift,Start + Len - 1);
  2242.         }
  2243.     }
  2244. }
  2245. #endif    /* DO_TAPEDECK_KIND */
  2246.  
  2247.  
  2248. /*****************************************************************************/
  2249.  
  2250.  
  2251. #ifdef DO_TAPEDECK_KIND
  2252. STATIC VOID __regargs
  2253. LTK_DrawPrevNext(struct RastPort *RPort,BOOLEAN Prev,LONG Left,LONG Top,LONG Width,LONG Height)
  2254. {
  2255.     LONG i,Len,Start,ArrowWidth,ArrowHeight,LineWidth;
  2256.  
  2257.     LineWidth    = (Width + 15) / 16;
  2258.     ArrowWidth    = Width;
  2259.     ArrowHeight    = Height;
  2260.     Left        = Left - (LineWidth / 2);
  2261.  
  2262.     if(Prev)
  2263.     {
  2264.         for(i = 0 ; i < ArrowWidth ; i++)
  2265.         {
  2266.             Len    = (ArrowHeight * (i + 1) + ArrowWidth - 1) / ArrowWidth;
  2267.             Start    = Top + (ArrowHeight - Len) / 2;
  2268.  
  2269.             Move(RPort,Left + i,Start);
  2270.             Draw(RPort,Left + i,Start + Len - 1);
  2271.         }
  2272.  
  2273.         for(i = 0 ; i < LineWidth ; i++)
  2274.         {
  2275.             Move(RPort,Left + i,Top);
  2276.             Draw(RPort,Left + i,Top + Height - 1);
  2277.         }
  2278.     }
  2279.     else
  2280.     {
  2281.         for(i = 0 ; i < ArrowWidth ; i++)
  2282.         {
  2283.             Len    = (ArrowHeight * (i + 1) + ArrowWidth - 1) / ArrowWidth;
  2284.             Start    = Top + (ArrowHeight - Len) / 2;
  2285.  
  2286.             Move(RPort,Left + ArrowWidth - 1 - i,Start);
  2287.             Draw(RPort,Left + ArrowWidth - 1 - i,Start + Len - 1);
  2288.         }
  2289.  
  2290.         for(i = 0 ; i < LineWidth ; i++)
  2291.         {
  2292.             Move(RPort,Left + ArrowWidth - 1 - i,Top);
  2293.             Draw(RPort,Left + ArrowWidth - 1 - i,Top + Height - 1);
  2294.         }
  2295.     }
  2296. }
  2297. #endif    /* DO_TAPEDECK_KIND */
  2298.  
  2299.  
  2300. /*****************************************************************************/
  2301.  
  2302.  
  2303. STATIC VOID __regargs
  2304. LTK_DrawPicker(struct RastPort *RPort,BOOLEAN UpDirection,LONG Left,LONG Top,LONG Width,LONG Height)
  2305. {
  2306.     LONG i,Len,ArrowHeight,ArrowWidth,LineHeight,Start;
  2307.  
  2308.     LineHeight    = (Height + 15) / 16;
  2309.     ArrowHeight    = Height - (Height + 7) / 8;
  2310.     ArrowWidth    = Width;
  2311.  
  2312.     if(UpDirection)
  2313.     {
  2314.         for(i = 0 ; i < ArrowHeight ; i++)
  2315.         {
  2316.             Len    = (ArrowWidth * (i + 1) + ArrowHeight - 1) / ArrowHeight;
  2317.             Start    = Left + (ArrowWidth - Len) / 2;
  2318.  
  2319.             Move(RPort,Start,Top + i);
  2320.             Draw(RPort,Start + Len - 1,Top + i);
  2321.         }
  2322.     }
  2323.     else
  2324.     {
  2325.         for(i = 0 ; i < ArrowHeight ; i++)
  2326.         {
  2327.             Len    = (ArrowWidth * (i + 1) + ArrowHeight - 1) / ArrowHeight;
  2328.             Start    = Left + (ArrowWidth - Len) / 2;
  2329.  
  2330.             Move(RPort,Start,Top + ArrowHeight - 1 - i);
  2331.             Draw(RPort,Start + Len - 1,Top + ArrowHeight - 1 - i);
  2332.         }
  2333.     }
  2334.  
  2335.     for(i = 0 ; i < LineHeight ; i++)
  2336.     {
  2337.         Move(RPort,Left,Top + Height - 1 - i);
  2338.         Draw(RPort,Left + Width - 1,Top + Height - 1 - i);
  2339.     }
  2340. }
  2341.  
  2342.  
  2343. /*****************************************************************************/
  2344.  
  2345.  
  2346. #ifdef DO_TAPEDECK_KIND
  2347. STATIC VOID __regargs
  2348. LTK_RenderCircle(struct RastPort *RPort,LONG Left,LONG Top,LONG Radius,LONG AspectX,LONG AspectY)
  2349. {
  2350.     LONG x = 0,y = Radius,Delta = 2 * (1 - Radius),delta,Limit = 0,Length;
  2351.  
  2352.     while(y >= Limit)
  2353.     {
  2354.         if(Delta < 0)
  2355.         {
  2356.             delta = 2 * Delta + 2 * y - 1;
  2357.  
  2358.             if(delta > 0)
  2359.             {
  2360.                 x = x + 1;
  2361.                 y = y - 1;
  2362.                 Delta = Delta + 2 * x - 2 * y + 2;
  2363.             }
  2364.             else
  2365.             {
  2366.                 x = x + 1;
  2367.                 Delta = Delta + 2 * x + 1;
  2368.             }
  2369.         }
  2370.         else
  2371.         {
  2372.             if(Delta > 0)
  2373.             {
  2374.                 delta = 2 * Delta - 2 * x - 1;
  2375.  
  2376.                 if(delta > 0)
  2377.                 {
  2378.                     y = y - 1;
  2379.                     Delta = Delta - 2 * y + 1;
  2380.                 }
  2381.                 else
  2382.                 {
  2383.                     x = x + 1;
  2384.                     y = y - 1;
  2385.                     Delta = Delta + 2 * x - 2 * y + 2;
  2386.                 }
  2387.             }
  2388.             else
  2389.             {
  2390.                 x = x + 1;
  2391.                 y = y - 1;
  2392.                 Delta = Delta + 2 * x - 2 * y + 2;
  2393.             }
  2394.         }
  2395.  
  2396.         Length = (x * AspectY) / AspectX;
  2397.  
  2398.         Move(RPort,Left - Length,Top + y - 1);
  2399.         Draw(RPort,Left + Length - 1,Top + y - 1);
  2400.         Move(RPort,Left - Length,Top - y);
  2401.         Draw(RPort,Left + Length - 1,Top - y);
  2402.     }
  2403. }
  2404. #endif    /* DO_TAPEDECK_KIND */
  2405.  
  2406.  
  2407. /*****************************************************************************/
  2408.  
  2409.  
  2410. #ifdef DO_TAPEDECK_KIND
  2411. STATIC VOID __regargs
  2412. LTK_RenderArrow(struct RastPort *RPort,BOOLEAN LeftDirection,LONG Left,LONG Top,LONG Width,LONG Height)
  2413. {
  2414.     LONG i,Len,Start;
  2415.  
  2416.     if(LeftDirection)
  2417.     {
  2418.         for(i = 0 ; i < Width ; i++)
  2419.         {
  2420.             Len    = (Height * (i + 1) + Width - 1) / Width;
  2421.             Start    = Top + (Height - Len) / 2;
  2422.  
  2423.             Move(RPort,Left + i,Start);
  2424.             Draw(RPort,Left + i,Start + Len - 1);
  2425.         }
  2426.     }
  2427.     else
  2428.     {
  2429.         for(i = 0 ; i < Width ; i++)
  2430.         {
  2431.             Len    = (Height * (i + 1) + Width - 1) / Width;
  2432.             Start    = Top + (Height - Len) / 2;
  2433.  
  2434.             Move(RPort,Left + Width - 1 - i,Start);
  2435.             Draw(RPort,Left + Width - 1 - i,Start + Len - 1);
  2436.         }
  2437.     }
  2438. }
  2439. #endif    /* DO_TAPEDECK_KIND */
  2440.  
  2441.  
  2442. /*****************************************************************************/
  2443.  
  2444.  
  2445. #ifdef DO_TAPEDECK_KIND
  2446. STATIC VOID __regargs
  2447. LTK_DrawTapeButton(struct RastPort *RPort,ImageInfo *imageInfo,LONG Left,LONG Top,LONG Width,LONG Height,LONG AspectX,LONG AspectY,LONG Background)
  2448. {
  2449.     LONG        SizeX,SizeY,Mid,Size;
  2450.     ImageTypes    ImageType;
  2451.  
  2452.     ImageType    = imageInfo -> ImageType;
  2453.     SizeX        = imageInfo -> GlyphWidth;
  2454.     SizeY        = imageInfo -> GlyphHeight;
  2455.  
  2456.     Left    += 6;
  2457.     Top    += 3;
  2458.  
  2459.     Width    -= 2 * 6;
  2460.     Height    -= 2 * 3;
  2461.  
  2462.     if(!SizeY)
  2463.         SizeY = Height;
  2464.  
  2465.     if(!SizeX)
  2466.     {
  2467.         SizeX = (SizeY * AspectY) / AspectX;
  2468.  
  2469.         if(ImageType == IMAGECLASS_BACKWARD || ImageType == IMAGECLASS_FORWARD)
  2470.             SizeX *= 2;
  2471.     }
  2472.  
  2473.     if(SizeX > 0 && SizeY > 0)
  2474.     {
  2475.         switch(ImageType)
  2476.         {
  2477.             case IMAGECLASS_BACKWARD:
  2478.             case IMAGECLASS_FORWARD:
  2479.  
  2480.                 Left    = Left + (Width - SizeX) / 2;
  2481.                 Top    = Top + (Height - SizeY) / 2;
  2482.  
  2483.                 LTK_DrawBackFore(RPort,ImageType == IMAGECLASS_BACKWARD,Left,Top,SizeX,SizeY);
  2484.                 break;
  2485.  
  2486.             case IMAGECLASS_PREVIOUS:
  2487.             case IMAGECLASS_NEXT:
  2488.  
  2489.                 Left    = Left + (Width - SizeX) / 2;
  2490.                 Top    = Top + (Height - SizeY) / 2;
  2491.  
  2492.                 LTK_DrawPrevNext(RPort,ImageType == IMAGECLASS_PREVIOUS,Left,Top,SizeX,SizeY);
  2493.                 break;
  2494.  
  2495.             case IMAGECLASS_EJECT:
  2496.  
  2497.                 Left    = Left + (Width - SizeX) / 2;
  2498.                 Top    = Top + (Height - SizeY) / 2;
  2499.  
  2500.                 LTK_DrawPicker(RPort,TRUE,Left,Top,SizeX,SizeY);
  2501.                 break;
  2502.  
  2503.             case IMAGECLASS_RECORD:
  2504.  
  2505.                 LTK_RenderCircle(RPort,Left + Width / 2,Top + Height / 2,SizeY / 2,AspectX,AspectY);
  2506.                 break;
  2507.  
  2508.             case IMAGECLASS_PLAY:
  2509.             case IMAGECLASS_REWIND:
  2510.  
  2511.                 Left    = Left + (Width - SizeX) / 2;
  2512.                 Top    = Top + (Height - SizeY) / 2;
  2513.  
  2514.                 LTK_RenderArrow(RPort,ImageType == IMAGECLASS_REWIND,Left,Top,SizeX,SizeY);
  2515.                 break;
  2516.  
  2517.             case IMAGECLASS_STOP:
  2518.  
  2519.                 Left    = Left + (Width - SizeX) / 2;
  2520.                 Top    = Top + (Height - SizeY) / 2;
  2521.  
  2522.                 RectFill(RPort,Left,Top,Left + SizeX - 1,Top + SizeY - 1);
  2523.                 break;
  2524.  
  2525.             case IMAGECLASS_PAUSE:
  2526.  
  2527.                 Left    = Left + (Width - SizeX) / 2;
  2528.                 Top    = Top + (Height - SizeY) / 2;
  2529.  
  2530.                 RectFill(RPort,Left,Top,Left + SizeX - 1,Top + SizeY - 1);
  2531.  
  2532.                 Size    = SizeX - (2 * SizeX) / 3;
  2533.                 Mid    = SizeX / 3;
  2534.  
  2535.                 LTK_SetAPen(RPort,Background);
  2536.                 RectFill(RPort,Left + Mid,Top,Left + Mid + Size - 1,Top + SizeY - 1);
  2537.  
  2538.                 break;
  2539.         }
  2540.     }
  2541. }
  2542. #endif    /* DO_TAPEDECK_KIND */
  2543.  
  2544. /*****************************************************************************/
  2545.  
  2546.  
  2547. STATIC VOID __regargs
  2548. LTK_DrawBox(struct RastPort *rp,struct DrawInfo *drawInfo,LONG left,LONG top,LONG width,LONG height,BOOLEAN selected,BOOLEAN ghosted,ImageInfo *imageInfo)
  2549. {
  2550.     UWORD        *pens = drawInfo -> dri_Pens;
  2551.     UWORD         pen1,pen2,pen3,pen4;
  2552.     ImageTypes     imageType = imageInfo -> ImageType;
  2553.  
  2554.     if(selected)
  2555.     {
  2556.         pen1 = SHADOWPEN;
  2557.         pen2 = SHINEPEN;
  2558.         pen3 = FILLPEN;
  2559.         pen4 = FILLTEXTPEN;
  2560.     }
  2561.     else
  2562.     {
  2563.         pen1 = SHINEPEN;
  2564.         pen2 = SHADOWPEN;
  2565.         pen3 = BACKGROUNDPEN;
  2566.         pen4 = TEXTPEN;
  2567.     }
  2568.  
  2569.     LTK_SetPens(rp,pens[pen1],0,JAM1);
  2570.     Move(rp,left + 1,top + 1);
  2571.     Draw(rp,left + 1,top + height - 2);
  2572.     Draw(rp,left,top + height - 1);
  2573.     Draw(rp,left,top);
  2574.     Draw(rp,left + width - 2,top);
  2575.  
  2576.     LTK_SetAPen(rp,pens[pen2]);
  2577.     Move(rp,left + width - 2,top + height - 2);
  2578.     Draw(rp,left + width - 2,top + 1);
  2579.     Draw(rp,left + width - 1,top);
  2580.     Draw(rp,left + width - 1,top + height - 1);
  2581.     Draw(rp,left + 1,top + height - 1);
  2582.  
  2583.     LTK_SetAPen(rp,pens[pen3]);
  2584.     RectFill(rp,left + 2,top + 1,left + 2 + width - 5,top + 1 + height - 3);
  2585.  
  2586.     LTK_SetAPen(rp,pens[pen4]);
  2587.  
  2588.     switch(imageType)
  2589.     {
  2590.         case IMAGECLASS_PICKER:
  2591.         {
  2592.             LONG    Left    = left + 4,
  2593.                 Top    = top + 2,
  2594.                 Width    = width - 8,
  2595.                 Height    = height - 4;
  2596.  
  2597.             LTK_DrawPicker(rp,FALSE,Left,Top,Width,Height);
  2598.             break;
  2599.         }
  2600.  
  2601.         case IMAGECLASS_LEFTINCREMENTER:
  2602.         case IMAGECLASS_RIGHTINCREMENTER:
  2603.  
  2604.             LTK_DrawIncrementer(rp,imageType == IMAGECLASS_LEFTINCREMENTER,left + 2,top + 1,width - 4,height - 2);
  2605.             break;
  2606. #ifdef DO_TAPEDECK_KIND
  2607.         case IMAGECLASS_BACKWARD:
  2608.         case IMAGECLASS_FORWARD:
  2609.         case IMAGECLASS_PREVIOUS:
  2610.         case IMAGECLASS_NEXT:
  2611.         case IMAGECLASS_RECORD:
  2612.         case IMAGECLASS_PLAY:
  2613.         case IMAGECLASS_STOP:
  2614.         case IMAGECLASS_PAUSE:
  2615.         case IMAGECLASS_EJECT:
  2616.         case IMAGECLASS_REWIND:
  2617.  
  2618.             LTK_DrawTapeButton(rp,imageInfo,left,top,width,height,drawInfo -> dri_Resolution . X,drawInfo -> dri_Resolution . Y,pens[pen3]);
  2619.             break;
  2620. #endif    /* DO_TAPEDECK_KIND */
  2621.     }
  2622.  
  2623.     if(ghosted)
  2624.     {
  2625.         if(width > 4 || height > 2)
  2626.         {
  2627.             LTK_SetAPen(rp,pens[BLOCKPEN]);
  2628.  
  2629.             SetAfPt(rp,(UWORD *)&ghostingPat,1);
  2630.             RectFill(rp,left + 2,top + 1,left + width - 1 - 2,top + height - 1 - 1);
  2631.             SetAfPt(rp,NULL,0);
  2632.         }
  2633.     }
  2634. }
  2635.  
  2636.  
  2637. /*****************************************************************************/
  2638.  
  2639.  
  2640. STATIC ULONG __regargs
  2641. LTK_ImageClassDraw(struct Image *image,struct impDraw *drawMsg,ImageInfo *imageInfo)
  2642. {
  2643.     LTK_DrawBox(drawMsg -> imp_RPort,drawMsg -> imp_DrInfo,image -> LeftEdge + drawMsg -> imp_Offset . X,image -> TopEdge + drawMsg -> imp_Offset . Y,image -> Width,image -> Height,drawMsg -> imp_State == IDS_SELECTED,drawMsg -> imp_State == IDS_DISABLED,imageInfo);
  2644.  
  2645.     return(TRUE);
  2646. }
  2647.  
  2648.  
  2649. /*****************************************************************************/
  2650.  
  2651.  
  2652. STATIC ULONG __regargs
  2653. LTK_ImageClassErase(struct Image *image,struct impErase *eraseMsg)
  2654. {
  2655.     LONG left;
  2656.     LONG top;
  2657.  
  2658.     left    = eraseMsg -> imp_Offset . X + image -> LeftEdge;
  2659.     top    = eraseMsg -> imp_Offset . Y + image -> TopEdge;
  2660.  
  2661.     LTK_SetAPen(eraseMsg -> imp_RPort,0);
  2662.     RectFill(eraseMsg -> imp_RPort,left,top,left + image -> Width - 1,top + image -> Height - 1);
  2663.  
  2664.     return(TRUE);
  2665. }
  2666.  
  2667.  
  2668. /*****************************************************************************/
  2669.  
  2670. STATIC ULONG __regargs
  2671. LTK_ImageClassNew(struct IClass *class,Object *object,struct opSet *SetMethod)
  2672. {
  2673.     struct TagItem *Tag;
  2674.  
  2675.     if(Tag = FindTagItem(IIA_ImageType,SetMethod -> ops_AttrList))
  2676.     {
  2677.         struct Image *NewImage;
  2678.  
  2679.         if(NewImage = (struct Image *)DoSuperMethodA(class,object,(Msg)SetMethod))
  2680.         {
  2681.             struct ImageInfo *MoreInfo = INST_DATA(class,NewImage);
  2682.  
  2683.             MoreInfo -> ImageType    = Tag -> ti_Data;
  2684.             MoreInfo -> GlyphWidth    = GetTagData(IIA_GlyphWidth,0,SetMethod -> ops_AttrList);
  2685.             MoreInfo -> GlyphHeight    = GetTagData(IIA_GlyphHeight,0,SetMethod -> ops_AttrList);
  2686.  
  2687.             return((ULONG)NewImage);
  2688.         }
  2689.     }
  2690.  
  2691.     return(NULL);
  2692. }
  2693.  
  2694.  
  2695. /*****************************************************************************/
  2696.  
  2697.  
  2698. STATIC ULONG __saveds __asm
  2699. LTK_ImageDispatch(register __a0 struct IClass *class,register __a2 Object *object,register __a1 Msg msg)
  2700. {
  2701.     switch(msg -> MethodID)
  2702.     {
  2703.         case IM_ERASE:
  2704.  
  2705.             return(LTK_ImageClassErase((struct Image *)object,(struct impErase *)msg));
  2706.  
  2707.         case IM_DRAW:
  2708.  
  2709.             return(LTK_ImageClassDraw((struct Image *)object,(struct impDraw *)msg,(ImageInfo *)INST_DATA(class,object)));
  2710.  
  2711.         case OM_NEW:
  2712.  
  2713.             return(LTK_ImageClassNew(class,object,(struct opSet *)msg));
  2714.  
  2715.         default:
  2716.  
  2717.             return(DoSuperMethodA(class,object,msg));
  2718.     }
  2719. }
  2720.  
  2721.  
  2722. /*****************************************************************************/
  2723.  
  2724.  
  2725. STATIC VOID __regargs
  2726. LTK_TunnelDraw(struct RastPort *rp,LONG from,LONG to,LONG y,LONG left,LONG right)
  2727. {
  2728.     Draw(rp,from,y);
  2729.     Draw(rp,left - 1,y);
  2730.     Move(rp,right + 1,y);
  2731.     Draw(rp,to,y);
  2732. }
  2733.  
  2734.  
  2735. /*****************************************************************************/
  2736.  
  2737.  
  2738. STATIC VOID __regargs
  2739. LTK_DrawGroove(LayoutHandle *handle,LONG left,LONG top,LONG width,LONG height,LONG from,LONG to)
  2740. {
  2741.     struct RastPort *rp = &handle -> RPort;
  2742.  
  2743.     LTK_SetAPen(rp,handle -> ShadowPen);
  2744.  
  2745.     Move(rp,left + 1,top + 1);
  2746.     Draw(rp,left + 1,top + height - 2);
  2747.     Draw(rp,left,top + height - 1);
  2748.     LTK_TunnelDraw(rp,left,left + width - 2,top,from,to);
  2749.     Draw(rp,left + width - 4,top + 2);
  2750.     Draw(rp,left + width - 4,top + height - 3);
  2751.     Move(rp,left + width - 3,top + 2);
  2752.     Draw(rp,left + width - 3,top + height - 2);
  2753.     Draw(rp,left + 3,top + height - 2);
  2754.  
  2755.     LTK_SetAPen(rp,handle -> ShinePen);
  2756.     Move(rp,left + width - 2,top + height - 2);
  2757.     Draw(rp,left + width - 2,top + 1);
  2758.     Draw(rp,left + width - 1,top);
  2759.     Draw(rp,left + width - 1,top + height - 1);
  2760.     Draw(rp,left + 1,top + height - 1);
  2761.     Draw(rp,left + 3,top + height - 3);
  2762.     Draw(rp,left + 3,top + 2);
  2763.     Move(rp,left + 2,top + height - 3);
  2764.     LTK_TunnelDraw(rp,left + 2,left + width - 4,top + 1,from,to);
  2765. }
  2766.  
  2767.  
  2768. /*****************************************************************************/
  2769.  
  2770.  
  2771. STATIC VOID __regargs
  2772. LTK_DrawLabel(LayoutHandle *handle,ObjectNode *label)
  2773. {
  2774.     struct RastPort    *rp;
  2775.     LONG         left;
  2776.  
  2777.     left    = label -> Left + (label -> Width - label -> LabelWidth) / 2;
  2778.     rp    = &handle -> RPort;
  2779.  
  2780.     LockLayerRom(rp -> Layer);
  2781.  
  2782.     LTK_DrawGroove(handle,label -> Left + handle -> GlyphWidth / 2,label -> Top + handle -> RPort . TxHeight / 2,label -> Width - handle -> GlyphWidth,label -> Height - (handle -> RPort . TxHeight + handle -> InterHeight) / 2,left,left + label -> LabelWidth - 1);
  2783.  
  2784.     LTK_SetPens(rp,handle -> DrawInfo -> dri_Pens[HIGHLIGHTTEXTPEN],0,JAM1);
  2785.     LTK_PlaceText(handle,label -> Label,strlen(label -> Label),left + handle -> GlyphWidth,label -> Top + handle -> RPort . TxBaseline);
  2786.  
  2787.     UnlockLayerRom(rp -> Layer);
  2788. }
  2789.  
  2790.  
  2791. /*****************************************************************************/
  2792.  
  2793.  
  2794. STATIC APTR __regargs
  2795. LTK_Alloc(LayoutHandle *handle,ULONG amount)
  2796. {
  2797.     APTR result = NULL;
  2798.  
  2799.     if(!handle -> Failed)
  2800.     {
  2801.         result = AsmAllocPooled(handle -> Pool,amount,SysBase);
  2802.  
  2803.         if(!result)
  2804.             handle -> Failed = TRUE;
  2805.     }
  2806.  
  2807.     return(result);
  2808. }
  2809.  
  2810.  
  2811. /*****************************************************************************/
  2812.  
  2813.  
  2814. STATIC VOID __regargs
  2815. LTK_Free(LayoutHandle *handle,APTR mem,ULONG memsize)
  2816. {
  2817.     if(mem)
  2818.         AsmFreePooled(handle -> Pool,mem,memsize,SysBase);
  2819. }
  2820.  
  2821.  
  2822. /*****************************************************************************/
  2823.  
  2824.  
  2825. STATIC VOID __regargs
  2826. LTK_DetermineSize(LayoutHandle *Handle,ObjectNode *Node)
  2827. {
  2828.     if(!Handle -> Failed)
  2829.     {
  2830.         LONG i,Len,Width,Max;
  2831.  
  2832.         if(Node -> Label)
  2833.             Node -> LabelWidth = LT_LabelWidth(Handle,Node -> Label);
  2834.         else
  2835.             Node -> LabelWidth = 0;
  2836.  
  2837.         switch(Node -> Type)
  2838.         {
  2839.             case GROUP_KIND:
  2840.  
  2841.                 LTK_LayoutGroup(Handle,Node);
  2842.  
  2843.                 break;
  2844.  
  2845.             case XBAR_KIND:
  2846.  
  2847.                 Node -> Width    = Handle -> GlyphWidth;
  2848.                 Node -> Height    = 6;
  2849.  
  2850.                 break;
  2851.  
  2852.             case YBAR_KIND:
  2853.  
  2854.                 Node -> Width    = 6;
  2855.                 Node -> Height    = Handle -> RPort . TxHeight;
  2856.  
  2857.                 break;
  2858.  
  2859.             case FRAME_KIND:
  2860.  
  2861.                 if(Node -> Special . Frame . DrawBox)
  2862.                 {
  2863.                     Node -> Width    = 4 + Node -> Special . Frame . InnerWidth + 4;
  2864.                     Node -> Height    = 2 + Node -> Special . Frame . InnerHeight + 2;
  2865.                 }
  2866.                 else
  2867.                 {
  2868.                     Node -> Width    = Node -> Special . Frame . InnerWidth;
  2869.                     Node -> Height    = Node -> Special . Frame . InnerHeight;
  2870.                 }
  2871.  
  2872.                 break;
  2873.  
  2874.             case BOX_KIND:
  2875.  
  2876.                 Node -> LabelWidth = 0;
  2877.  
  2878.                 if(Node -> Special . Box . Labels)
  2879.                 {
  2880.                     for(i = 0 ; i < Node -> Lines ; i++)
  2881.                     {
  2882.                         if((Width = TextLength(&Handle -> RPort,Node -> Special . Box . Labels[i],strlen(Node -> Special . Box . Labels[i]))) > Node -> LabelWidth)
  2883.                             Node -> LabelWidth = Width;
  2884.                     }
  2885.                 }
  2886.  
  2887.                 Max = Node -> Chars;
  2888.  
  2889.                 if(Node -> Special . Box . Lines)
  2890.                 {
  2891.                     LONG MaxWidth = 0;
  2892.  
  2893.                     for(i = 0 ; i < Node -> Lines ; i++)
  2894.                     {
  2895.                         if(Node -> Special . Box . Lines[i])
  2896.                         {
  2897.                             if(Len = strlen(Node -> Special . Box . Lines[i]))
  2898.                             {
  2899.                                 if((Width = TextLength(&Handle -> RPort,Node -> Special . Box . Lines[i],Len)) > MaxWidth)
  2900.                                     MaxWidth = Width;
  2901.                             }
  2902.                         }
  2903.                     }
  2904.  
  2905.                     if(Max < (MaxWidth + Handle -> GlyphWidth - 1) / Handle -> GlyphWidth)
  2906.                         Max = (MaxWidth + Handle -> GlyphWidth - 1) / Handle -> GlyphWidth;
  2907.                 }
  2908.  
  2909.                 Node -> Height    = 2 + Node -> Lines * Handle -> RPort . TxHeight + 2;
  2910.                 Node -> Width    = 4 + Max * Handle -> GlyphWidth + 4;
  2911.  
  2912.                 break;
  2913.  
  2914.             case BUTTON_KIND:
  2915.  
  2916.                 if(Node -> Chars * Handle -> GlyphWidth > Node -> LabelWidth)
  2917.                     Node -> Width = Node -> Chars * Handle -> GlyphWidth;
  2918.                 else
  2919.                     Node -> Width = Node -> LabelWidth;
  2920.  
  2921.                 Node -> LabelWidth = 0;
  2922.                 Node -> LabelPlace = PLACE_IN;
  2923.  
  2924.                 if(Node -> Special . Button . ExtraFat)
  2925.                 {
  2926.                     Node -> Width    = 6 + Handle -> GlyphWidth + Node -> Width + Handle -> GlyphWidth + 6;
  2927.                     Node -> Height    = 2 + (3 * Handle -> RPort . TxHeight) / 2 + 2;
  2928.                 }
  2929.                 else
  2930.                 {
  2931.                     Node -> Width    = 6 + Node -> Width + 6;
  2932.                     Node -> Height    = 3 + Handle -> RPort . TxHeight + 3;
  2933.                 }
  2934.  
  2935.                 break;
  2936.  
  2937.             case CHECKBOX_KIND:
  2938.  
  2939.                 Node -> Width = Node -> Height = (3 * Handle -> RPort . TxHeight) / 2;
  2940.  
  2941.                 if(!V39)
  2942.                 {
  2943.                     if(Node -> Width < CHECKBOX_WIDTH)
  2944.                         Node -> Width = CHECKBOX_WIDTH;
  2945.  
  2946.                     if(Node -> Height < CHECKBOX_HEIGHT)
  2947.                         Node -> Height = CHECKBOX_HEIGHT;
  2948.                 }
  2949.                 else
  2950.                 {
  2951.                     Node -> Width = (Node -> Width * Handle -> AspectY) / Handle -> AspectX;
  2952.  
  2953.                     if(Node -> Height < CHECKBOX_HEIGHT)
  2954.                     {
  2955.                         Node -> Height    = CHECKBOX_HEIGHT;
  2956.                         Node -> Width    = (Node -> Height * Handle -> AspectY) / Handle -> AspectX;
  2957.                     }
  2958.                 }
  2959.  
  2960.                 break;
  2961.  
  2962.             case LISTVIEW_KIND:
  2963.  
  2964.                 i    = 0;
  2965.                 Max    = 0;
  2966.                 Width    = Node -> Chars * Handle -> GlyphWidth;
  2967.  
  2968.                 if(Node -> Special . List . Labels)
  2969.                 {
  2970.                     struct Node *Item;
  2971.  
  2972.                     SCANLIST(Node -> Special . List . Labels,Item)
  2973.                     {
  2974.                         i++;
  2975.  
  2976.                         if((Len = TextLength(&Handle -> RPort,Item -> ln_Name,strlen(Item -> ln_Name))) > Max)
  2977.                             Max = Len;
  2978.                     }
  2979.                 }
  2980.  
  2981.                 Node -> Max = i - 1;
  2982.  
  2983.                 if(Max > Width)
  2984.                 {
  2985.                     Width = Max;
  2986.  
  2987.                     Node -> Chars = Width / Handle -> GlyphWidth;
  2988.                 }
  2989.  
  2990.                 if(!V39)
  2991.                     Node -> Width = (4 + Width + 4) + (2 + 2 * Handle -> GlyphWidth + 2) + 8;
  2992.                 else
  2993.                     Node -> Width = (4 + Width + 4) + (2 + 2 * Handle -> GlyphWidth + 2);
  2994.  
  2995.                 Node -> Height = 2 + Node -> Lines * Handle -> RPort . TxHeight + 2;
  2996.  
  2997.                 if(Node -> Special . List . ReadOnly)
  2998.                 {
  2999.                     if(Node -> Special . List . LinkID != -1)
  3000.                     {
  3001.                         if(!V39)
  3002.                             Node -> Height += 2 + Handle -> RPort . TxHeight + 2;
  3003.                     }
  3004.                 }
  3005.                 else
  3006.                 {
  3007.                     if(Node -> Special . List . LinkID != -1 && Node -> Special . List . LinkID != NIL_LINK)
  3008.                         Node -> Height += 3 + Handle -> RPort . TxHeight + 3;
  3009.                 }
  3010.  
  3011.                 if(Node -> Special . List . ExtraLabels)
  3012.                 {
  3013.                     for(i = Max = 0 ; Node -> Special . List . ExtraLabels[i] ; i++)
  3014.                     {
  3015.                         if((Len = TextLength(&Handle -> RPort,Node -> Special . List . ExtraLabels[i],strlen(Node -> Special . List . ExtraLabels[i]))) > Max)
  3016.                             Max = Len;
  3017.                     }
  3018.  
  3019.                     Node -> Special . List . ExtraLabelWidth = Max;
  3020.                 }
  3021.  
  3022.                 if(Node -> LabelWidth > Node -> Width && (Node -> LabelPlace == PLACE_ABOVE || Node -> LabelPlace == PLACE_BELOW))
  3023.                     Node -> Width = Node -> LabelWidth;
  3024.  
  3025.                 break;
  3026.  
  3027.             case MX_KIND:
  3028.  
  3029.                 i    = 0;
  3030.                 Max    = 0;
  3031.  
  3032.                 while(Node -> Special . Radio . Choices[i])
  3033.                 {
  3034.                     if((Width = TextLength(&Handle -> RPort,Node -> Special . Radio . Choices[i],strlen(Node -> Special . Radio . Choices[i]))) > Max)
  3035.                         Max = Width;
  3036.  
  3037.                     i++;
  3038.                 }
  3039.  
  3040.                 Node -> Max = i - 1;
  3041.  
  3042.                 Node -> Special . Radio . LabelWidth = Max;
  3043.  
  3044.                 Node -> Height = MAX(MX_HEIGHT,Handle -> RPort . TxHeight);
  3045.  
  3046.                 if(!V39)
  3047.                     Node -> Width = MX_WIDTH;
  3048.                 else
  3049.                 {
  3050.                     Node -> Width = (Node -> Height * Handle -> AspectY) / Handle -> AspectX;
  3051.  
  3052.                     if(Node -> Height < MX_HEIGHT)
  3053.                     {
  3054.                         Node -> Height = MX_HEIGHT;
  3055.                         Node -> Width  = (Node -> Height * Handle -> AspectX) / Handle -> AspectY;
  3056.                     }
  3057.                 }
  3058.  
  3059.                 Node -> Lines  = i;
  3060.                 Node -> Height = Node -> Lines * (Node -> Height + Handle -> InterHeight) - Handle -> InterHeight;
  3061.  
  3062.                 break;
  3063.  
  3064.             case TEXT_KIND:
  3065.  
  3066.                 if(Node -> Special . Text . Text)
  3067.                     Max = TextLength(&Handle -> RPort,Node -> Special . Text . Text,strlen(Node -> Special . Text . Text));
  3068.                 else
  3069.                     Max = 0;
  3070.  
  3071.                 Width = Node -> Chars * Handle -> GlyphWidth;
  3072.  
  3073.                 if(Max > Width)
  3074.                     Width = Max;
  3075.  
  3076.                 Node -> Width    = 6 + Width + 6;
  3077.                 Node -> Height    = 3 + Handle -> RPort . TxHeight + 3;
  3078.  
  3079.                 if(Node -> Special . Text . UsePicker)
  3080.                     Node -> Width += (Node -> Height * Handle -> AspectY) / Handle -> AspectX;
  3081.  
  3082.                 if(Node -> LabelWidth > Node -> Width && (Node -> LabelPlace == PLACE_ABOVE || Node -> LabelPlace == PLACE_BELOW))
  3083.                     Node -> Width = Node -> LabelWidth;
  3084.  
  3085.                 break;
  3086.  
  3087. #ifdef DO_GAUGE_KIND
  3088.             case GAUGE_KIND:
  3089.  
  3090.                 Width = TextLength(&Handle -> RPort,"0% 100%",7);
  3091.  
  3092.                 if(Handle -> GlyphWidth * Node -> Chars > Width)
  3093.                     Width = Handle -> GlyphWidth * Node -> Chars;
  3094.  
  3095.                 Node -> Width    = 6 + Width + 6;
  3096.                 Node -> Height    = 3 + Handle -> RPort . TxHeight + 2 + Handle -> InterHeight + Handle -> RPort . TxHeight + 3;
  3097.  
  3098.                 if(Node -> Label)
  3099.                     Node -> LabelWidth = LT_LabelWidth(Handle,Node -> Label);
  3100.                 else
  3101.                     Node -> LabelWidth = 0;
  3102.  
  3103.                 if(Node -> LabelWidth > Node -> Width && (Node -> LabelPlace == PLACE_ABOVE || Node -> LabelPlace == PLACE_BELOW))
  3104.                     Node -> Width = Node -> LabelWidth;
  3105.  
  3106.                 break;
  3107. #endif
  3108.  
  3109. #ifdef DO_TAPEDECK_KIND
  3110.             case TAPEDECK_KIND:
  3111.             {
  3112.                 LONG Width,Height;
  3113.  
  3114.                 Width = TextLength(&Handle -> RPort,"AA",2);
  3115.  
  3116.                 if(Width < 2 * Handle -> GlyphWidth);
  3117.                     Width = 2 * Handle -> GlyphWidth;
  3118.  
  3119.                 if(Width < 2 * Handle -> RPort . TxHeight)
  3120.                     Width = 2 * Handle -> RPort . TxHeight;
  3121.  
  3122.                 if(Node -> Special . TapeDeck . Smaller)
  3123.                     Width = (3 * Width) / 4;
  3124.  
  3125.                 if(Width & 1)
  3126.                     Width++;
  3127.  
  3128.                 Width    = 1 + ((Width + 5) / 6) * 6;
  3129.                 Height    = (Handle -> AspectX * Width) / (Handle -> AspectY * 2);
  3130.  
  3131.                 if(!(Height & 1))
  3132.                     Height++;
  3133.  
  3134.                 if(Node -> Special . TapeDeck . ButtonType == TDBT_BACKWARD || Node -> Special . TapeDeck . ButtonType == TDBT_FORWARD)
  3135.                     Node -> Special . TapeDeck . ButtonWidth = Width;
  3136.                 else
  3137.                     Node -> Special . TapeDeck . ButtonWidth = Width / 2;
  3138.  
  3139.                 Node -> Special . TapeDeck . ButtonHeight = Height;
  3140.  
  3141.                 if(Handle -> GlyphWidth * Node -> Chars > Width)
  3142.                     Width = Handle -> GlyphWidth * Node -> Chars;
  3143.  
  3144.                 Node -> Width    = 6 + Width + 6;
  3145.                 Node -> Height    = 3 + Height + 3;
  3146.  
  3147.                 if(Node -> LabelWidth > Node -> Width && (Node -> LabelPlace == PLACE_ABOVE || Node -> LabelPlace == PLACE_BELOW))
  3148.                     Node -> Width = Node -> LabelWidth;
  3149.  
  3150.                 break;
  3151.             }
  3152. #endif    /* DO_TAPEDECK_KIND */
  3153.  
  3154.             case NUMBER_KIND:
  3155.  
  3156.                 Node -> Width    = 6 + Node -> Chars * Handle -> GlyphWidth + 6;
  3157.                 Node -> Height    = 2 + Handle -> RPort . TxHeight + 2;
  3158.  
  3159.                 break;
  3160.  
  3161.             case CYCLE_KIND:
  3162.  
  3163.                 Width = Node -> Chars * Handle -> GlyphWidth;
  3164.  
  3165.                 if(Node -> Special . Cycle . Choices)
  3166.                 {
  3167.                     for(i = 0 ; Node -> Special . Cycle . Choices[i] ; i++)
  3168.                     {
  3169.                         if((Len = TextLength(&Handle -> RPort,Node -> Special . Cycle . Choices[i],strlen(Node -> Special . Cycle . Choices[i]))) > Width)
  3170.                             Width = Len;
  3171.                     }
  3172.  
  3173.                     Node -> Max = i - 1;
  3174.                 }
  3175.  
  3176.                 Node -> Width    = 26 + Width + 6;
  3177.                 Node -> Height    = 3 + Handle -> RPort . TxHeight + 3;
  3178.  
  3179.                 if(Node -> LabelWidth > Node -> Width && (Node -> LabelPlace == PLACE_ABOVE || Node -> LabelPlace == PLACE_BELOW))
  3180.                     Node -> Width = Node -> LabelWidth;
  3181.  
  3182.                 break;
  3183.  
  3184.             case PALETTE_KIND:
  3185.  
  3186.                 if(Node -> Special . Palette . NumColours)
  3187.                     Node -> Max = Node -> Min + Node -> Special . Palette . NumColours - 1;
  3188.                 else
  3189.                 {
  3190.                     if(!Node -> Special . Palette . Depth)
  3191.                         Node -> Special . Palette . Depth = 1;
  3192.  
  3193.                     Node -> Special . Palette . NumColours = 1L << Node -> Special . Palette . Depth;
  3194.  
  3195.                     Node -> Max = Node -> Min + Node -> Special . Palette . NumColours - 1;
  3196.                 }
  3197.  
  3198.                 if(Node -> Special . Palette . SmallPalette)
  3199.                 {
  3200.                     Node -> Width   = Handle -> GlyphWidth * (Node -> Max - Node -> Min + 1);
  3201.                     Node -> Height  = 1 + Handle -> RPort . TxHeight + 1;
  3202.                 }
  3203.                 else
  3204.                 {
  3205.                     Node -> Width   = 2 * Handle -> GlyphWidth * (Node -> Max - Node -> Min + 1);
  3206.                     Node -> Height  = 2 * Handle -> RPort . TxHeight;
  3207.                 }
  3208.  
  3209.                 if(Node -> Chars * Handle -> GlyphWidth > Node -> Width)
  3210.                     Node -> Width = Node -> Chars * Handle -> GlyphWidth;
  3211.  
  3212.                 if(Node -> Special . Palette . NumColours > 16)
  3213.                 {
  3214.                     Node -> Height *= 2;
  3215.                     Node -> Width    /= 2;
  3216.                 }
  3217.  
  3218.                 if(Node -> Lines)
  3219.                 {
  3220.                     if(!Node -> Chars)
  3221.                         Node -> Width = Handle -> GlyphWidth;
  3222.                     else
  3223.                         Node -> Width = Node -> Chars * Handle -> GlyphWidth;
  3224.  
  3225.                     Node -> Height    = Node -> Lines * Handle -> RPort . TxHeight;
  3226.                 }
  3227.  
  3228.                 break;
  3229.  
  3230.             case SCROLLER_KIND:
  3231.  
  3232.                 if(Node -> Special . Scroller . Vertical)
  3233.                 {
  3234.                     if(Node -> Special . Scroller . Thin)
  3235.                         Node -> Width = 6 + Handle -> GlyphWidth + 6;
  3236.                     else
  3237.                         Node -> Width = 6 + (3 * Handle -> GlyphWidth) / 2 + 6;
  3238.  
  3239.                     Node -> Height = 2 + Node -> Lines * Handle -> RPort . TxHeight;
  3240.  
  3241.                     if(Node -> Special . Scroller . Arrows)
  3242.                     {
  3243.                         WORD ScrollerHeight = (Handle -> AspectX * Node -> Width) / Handle -> AspectY;
  3244.  
  3245.                         if(Node -> Height < 2 + Node -> Lines * Handle -> RPort . TxHeight + 2 * ScrollerHeight)
  3246.                             Node -> Height = 2 + Node -> Lines * Handle -> RPort . TxHeight + 2 * ScrollerHeight;
  3247.  
  3248.                         Node -> Special . Scroller . ArrowSize = ScrollerHeight;
  3249.                     }
  3250.                 }
  3251.                 else
  3252.                 {
  3253.                     Node -> Width  = 6 + Node -> Chars * Handle -> GlyphWidth + 6;
  3254.                     Node -> Height = 2 + Handle -> RPort . TxHeight;
  3255.  
  3256.                     if(Node -> Special . Scroller . Arrows)
  3257.                     {
  3258.                         WORD ScrollerWidth = (Handle -> AspectY * Node -> Height) / Handle -> AspectX;
  3259.  
  3260.                         if(Node -> Width < 6 + Handle -> GlyphWidth + 2 * ScrollerWidth + 6)
  3261.                             Node -> Width = 6 + Handle -> GlyphWidth + 2 * ScrollerWidth + 6;
  3262.  
  3263.                         Node -> Special . Scroller . ArrowSize = ScrollerWidth;
  3264.                     }
  3265.                 }
  3266.  
  3267.                 if(Node -> LabelWidth > Node -> Width && (Node -> LabelPlace == PLACE_ABOVE || Node -> LabelPlace == PLACE_BELOW))
  3268.                     Node -> Width = Node -> LabelWidth;
  3269.  
  3270.                 break;
  3271.  
  3272.             case SLIDER_KIND:
  3273.  
  3274.                 Node -> Width    = 6 + Node -> Chars * Handle -> GlyphWidth + 6;
  3275.                 Node -> Height    = 2 + Handle -> RPort . TxHeight + 1;
  3276.  
  3277.                 LT_LevelWidth(Handle,Node -> Special . Slider . LevelFormat,Node -> Special . Slider . DispFunc,Node -> Min,Node -> Max,&Node -> Special . Slider . LevelWidth,&Node -> Special . Slider . MaxLevelLen,Node -> Special . Slider . FullLevelCheck);
  3278.  
  3279.                 if(!V40)
  3280.                 {
  3281.                     if(Node -> Special . Slider . MaxLevelLen * Handle -> RPort . TxWidth < Node -> Special . Slider . LevelWidth)
  3282.                         Node -> Special . Slider . MaxLevelLen = (Node -> Special . Slider . LevelWidth + Handle -> RPort . TxWidth - 1) / Handle -> RPort . TxWidth;
  3283.                 }
  3284.  
  3285.                 if(Node -> Special . Slider . LevelPlace == PLACETEXT_LEFT && Node -> Label)
  3286.                 {
  3287.                     LONG    space,len;
  3288.                     STRPTR    Buffer;
  3289.  
  3290.                     space = TextLength(&Handle -> RPort," ",1);
  3291.                     space = (Node -> Special . Slider . LevelWidth + space - 1) / space;
  3292.  
  3293.                     if(!V40 && (Handle -> RPort . TxFlags & FPF_PROPORTIONAL))
  3294.                     {
  3295.                         Node -> Special . Slider . MaxLevelLen++;
  3296.  
  3297.                         space++;
  3298.                     }
  3299.  
  3300.                     if(Node -> Special . Slider . OriginalLabel)
  3301.                         LTK_Free(Handle,Node -> Label,strlen(Node -> Label) + 1);
  3302.                     else
  3303.                         Node -> Special . Slider . OriginalLabel = Node -> Label;
  3304.  
  3305.                     len = strlen(Node -> Special . Slider . OriginalLabel);
  3306.  
  3307.                     if(Buffer = LTK_Alloc(Handle,len + space + 1))
  3308.                     {
  3309.                         strcpy(Buffer,Node -> Special . Slider . OriginalLabel);
  3310.  
  3311.                         while(space > 0)
  3312.                         {
  3313.                             Buffer[len] = ' ';
  3314.                             len++;
  3315.                             space--;
  3316.                         }
  3317.  
  3318.                         Buffer[len] = 0;
  3319.  
  3320.                         Node -> Label        = Buffer;
  3321.                         Node -> LabelWidth    = LT_LabelWidth(Handle,Node -> Label);
  3322.                     }
  3323.                     else
  3324.                         break;
  3325.                 }
  3326.  
  3327.                 if(Node -> LabelWidth > Node -> Width && (Node -> LabelPlace == PLACE_ABOVE || Node -> LabelPlace == PLACE_BELOW))
  3328.                     Node -> Width = Node -> LabelWidth;
  3329.  
  3330.                 break;
  3331.  
  3332.             case STRING_KIND:
  3333.  
  3334.                 Node -> Width    = 6 + Node -> Chars * Handle -> GlyphWidth + 6;
  3335.                 Node -> Height    = 3 + Handle -> RPort . TxHeight + 3;
  3336.  
  3337.                 if(Node -> Special . String . UsePicker)
  3338.                     Node -> Width += (Node -> Height * Handle -> AspectY) / Handle -> AspectX;
  3339.  
  3340.                 if(Node -> LabelWidth > Node -> Width && (Node -> LabelPlace == PLACE_ABOVE || Node -> LabelPlace == PLACE_BELOW))
  3341.                     Node -> Width = Node -> LabelWidth;
  3342.  
  3343.                 break;
  3344.  
  3345.             case INTEGER_KIND:
  3346.  
  3347.                 Node -> Width    = 6 + Node -> Chars * Handle -> GlyphWidth + 6;
  3348.                 Node -> Height    = 3 + Handle -> RPort . TxHeight + 3;
  3349.  
  3350.                 if(Node -> Special . Integer . UseIncrementers)
  3351.                 {
  3352.                     Node -> Width += (Node -> Height * 4) / 5;
  3353.                     Node -> Width += (Node -> Height * 4) / 5;
  3354.                 }
  3355.  
  3356.                 if(Node -> LabelWidth > Node -> Width && (Node -> LabelPlace == PLACE_ABOVE || Node -> LabelPlace == PLACE_BELOW))
  3357.                     Node -> Width = Node -> LabelWidth;
  3358.  
  3359.                 break;
  3360.  
  3361.             case PASSWORD_KIND:
  3362.             case FRACTION_KIND:
  3363.  
  3364.                 Node -> Width    = 6 + Node -> Chars * Handle -> GlyphWidth + 6;
  3365.                 Node -> Height    = 3 + Handle -> RPort . TxHeight + 3;
  3366.  
  3367.                 if(Node -> LabelWidth > Node -> Width && (Node -> LabelPlace == PLACE_ABOVE || Node -> LabelPlace == PLACE_BELOW))
  3368.                     Node -> Width = Node -> LabelWidth;
  3369.  
  3370.                 break;
  3371.         }
  3372.     }
  3373. }
  3374.  
  3375.  
  3376. /*****************************************************************************/
  3377.  
  3378.  
  3379. STATIC ULONG __asm __saveds
  3380. LTK_DefaultHistoryHook(register __a0 struct Hook *Hook,register __a1 STRPTR NewString,register __a2 struct Gadget *Gadget)
  3381. {
  3382.     ObjectNode        *Node    = (ObjectNode *)Gadget -> UserData;
  3383.     struct LayoutHandle    *Handle    = Node -> Special . String . LayoutHandle;
  3384.     struct MinList        *List    = (struct MinList *)Hook -> h_Data;
  3385.  
  3386.     if(NewString)
  3387.     {
  3388.         ULONG *Data;
  3389.  
  3390.         if(Data = (ULONG *)LTK_Alloc(Handle,sizeof(ULONG) + sizeof(struct Node) + strlen(NewString) + 1))
  3391.         {
  3392.             struct Node *NewNode;
  3393.  
  3394.             *Data++ = sizeof(ULONG) + sizeof(struct Node) + strlen(NewString) + 1;
  3395.  
  3396.             NewNode = (struct Node *)Data;
  3397.  
  3398.             NewNode -> ln_Name = (STRPTR)(NewNode + 1);
  3399.  
  3400.             strcpy(NewNode -> ln_Name,NewString);
  3401.  
  3402.             AddTail((struct List *)List,NewNode);
  3403.         }
  3404.         else
  3405.             return(FALSE);
  3406.     }
  3407.     else
  3408.     {
  3409.         if(List -> mlh_Head -> mln_Succ)
  3410.         {
  3411.             ULONG *Data = (ULONG *)RemHead((struct List *)List);
  3412.  
  3413.             LTK_Free(Handle,&Data[-1],Data[-1]);
  3414.         }
  3415.     }
  3416.  
  3417.     return(TRUE);
  3418. }
  3419.  
  3420.  
  3421. /*****************************************************************************/
  3422.  
  3423.  
  3424. STATIC VOID __regargs
  3425. LTK_Spread(LayoutHandle *Handle,ObjectNode *Group,LONG Width,LONG Height)
  3426. {
  3427.     ObjectNode    *Node;
  3428.     LONG         Count;
  3429.  
  3430.     Count = 0;
  3431.  
  3432.     SCANGROUP(Group,Node)
  3433.     {
  3434.         Count++;
  3435.     }
  3436.  
  3437.     if(Group -> Special . Group . Horizontal)
  3438.     {
  3439.         LONG Room = Width - Group -> Width,Left,Width,i = 0;
  3440.  
  3441.         if(Count > 1)
  3442.         {
  3443.             Left = 0;
  3444.  
  3445.             Room += --Count * Handle -> InterWidth;
  3446.         }
  3447.         else
  3448.             Left = Room / 2;
  3449.  
  3450.         SCANGROUP(Group,Node)
  3451.         {
  3452.             if(!LIKE_STRING_KIND(Node) || Node -> Special . String . LinkID == -1)
  3453.             {
  3454.                 Width = Node -> Width;
  3455.  
  3456.                 switch(Node -> LabelPlace)
  3457.                 {
  3458.                     case PLACE_LEFT:
  3459.  
  3460.                         if(Node -> Type == MX_KIND)
  3461.                         {
  3462.                             Left += Node -> Special . Radio . LabelWidth + INTERWIDTH;
  3463.  
  3464.                             if(Node -> Label)
  3465.                             {
  3466.                                 if(Node -> Special . Radio . TitlePlace == PLACETEXT_LEFT)
  3467.                                     Left += Node -> LabelWidth + INTERWIDTH;
  3468.                                 else
  3469.                                     Width += INTERWIDTH + Node -> LabelWidth;
  3470.                             }
  3471.                         }
  3472.                         else
  3473.                             Left += Node -> LabelWidth + INTERWIDTH;
  3474.  
  3475.                         break;
  3476.  
  3477.                     case PLACE_RIGHT:
  3478.  
  3479.                         if(Node -> Type == MX_KIND)
  3480.                         {
  3481.                             Width += INTERWIDTH + Node -> Special . Radio . LabelWidth;
  3482.  
  3483.                             if(Node -> Label)
  3484.                             {
  3485.                                 if(Node -> Special . Radio . TitlePlace == PLACETEXT_LEFT)
  3486.                                     Left += Node -> LabelWidth + INTERWIDTH;
  3487.                                 else
  3488.                                     Width += INTERWIDTH + Node -> LabelWidth;
  3489.                             }
  3490.                         }
  3491.                         else
  3492.                             Width += INTERWIDTH + Node -> LabelWidth;
  3493.  
  3494.                         break;
  3495.                 }
  3496.  
  3497.                 if(Node -> Type == LISTVIEW_KIND && Node -> Special . List . ExtraLabelWidth)
  3498.                     Left += Node -> Special . List . ExtraLabelWidth + INTERWIDTH;
  3499.  
  3500.                 if(Node -> Type == SLIDER_KIND && Node -> Special . Slider . LevelPlace == PLACETEXT_RIGHT)
  3501.                     Width += INTERWIDTH + Node -> Special . Slider . LevelWidth;
  3502.  
  3503.                 Node -> Left = Left;
  3504.  
  3505.                 Left += Width + ((Room * (i + 1)) / Count - (Room * i) / Count);
  3506.  
  3507.                 i++;
  3508.             }
  3509.         }
  3510.     }
  3511.     else
  3512.     {
  3513.         LONG Room = Height - Group -> Height,Height,Top,y,i = 0;
  3514.  
  3515.         if(Count > 1)
  3516.         {
  3517.             Top = 0;
  3518.  
  3519.             Room += --Count * Handle -> InterHeight;
  3520.         }
  3521.         else
  3522.             Top = Room / 2;
  3523.  
  3524.         SCANGROUP(Group,Node)
  3525.         {
  3526.             if(!LIKE_STRING_KIND(Node) || Node -> Special . String . LinkID == -1)
  3527.             {
  3528.                 if(Count++)
  3529.                 {
  3530.                     if(Node -> ExtraSpace > 0)
  3531.                         y = Top + Node -> ExtraSpace * Handle -> InterHeight;
  3532.                     else
  3533.                     {
  3534.                         if(Node -> ExtraSpace < 0)
  3535.                             y = Top - Node -> ExtraSpace;
  3536.                         else
  3537.                             y = Top + Handle -> InterHeight;
  3538.                     }
  3539.                 }
  3540.                 else
  3541.                     y = Top;
  3542.  
  3543.                 if(Node -> LabelPlace == PLACE_ABOVE)
  3544.                     y += Handle -> RPort . TxHeight + INTERHEIGHT;
  3545.  
  3546.                 Node -> Top = y;
  3547.  
  3548.                 if(Node -> LabelPlace == PLACE_BELOW && Node -> Label)
  3549.                     Height = Node -> Height + INTERHEIGHT + Handle -> RPort . TxHeight;
  3550.                 else
  3551.                     Height = Node -> Height;
  3552.  
  3553.                 Top = y + Height + ((Room * (i + 1)) / Count - (Room * i) / Count);
  3554.  
  3555.                 i++;
  3556.             }
  3557.         }
  3558.     }
  3559. }
  3560.  
  3561.  
  3562. /*****************************************************************************/
  3563.  
  3564.  
  3565. STATIC VOID __regargs
  3566. LTK_LayoutGroup(LayoutHandle *Handle,ObjectNode *Group)
  3567. {
  3568.     if(!Handle -> Failed)
  3569.     {
  3570.         ObjectNode    *Node;
  3571.         ObjectNode    *ReturnKey;
  3572.         ObjectNode    *EscKey;
  3573.         ObjectNode    *CursorKey;
  3574.         LONG         Left;
  3575.         LONG         Top;
  3576.         LONG         Width;
  3577.         LONG         Height;
  3578.  
  3579.         Left        = 0;
  3580.         Top        = 0;
  3581.         ReturnKey    = NULL;
  3582.         EscKey        = NULL;
  3583.         CursorKey    = NULL;
  3584.  
  3585.         if(Group -> Special . Group . SameSize)
  3586.         {
  3587.             LONG MaxWidth  = 0;
  3588.             LONG MaxHeight = 0;
  3589.  
  3590.             SCANGROUP(Group,Node)
  3591.             {
  3592.                 LTK_DetermineSize(Handle,Node);
  3593.  
  3594.                 if(Node -> Type == BUTTON_KIND)
  3595.                 {
  3596.                     if(Node -> Special . Button . ReturnKey)
  3597.                         ReturnKey = Node;
  3598.                     else
  3599.                     {
  3600.                         if(Node -> Special . Button . EscKey)
  3601.                             EscKey = Node;
  3602.                     }
  3603.                 }
  3604.  
  3605.                 if(Node -> Type == LISTVIEW_KIND && Node -> Special . List . CursorKey)
  3606.                     CursorKey = Node;
  3607.  
  3608.                 if(Node -> Width > MaxWidth)
  3609.                     MaxWidth = Node -> Width;
  3610.  
  3611.                 if(Node -> Height > MaxHeight)
  3612.                     MaxHeight = Node -> Height;
  3613.             }
  3614.  
  3615.             if(ReturnKey)
  3616.             {
  3617.                 SCANGROUP(Group,Node)
  3618.                 {
  3619.                     Node -> GroupIndent = TRUE;
  3620.  
  3621.                     Node -> Width    += 4 + 4;
  3622.                     Node -> Height    += 2 + 2;
  3623.  
  3624.                     if(Node -> Width > MaxWidth)
  3625.                         MaxWidth = Node -> Width;
  3626.  
  3627.                     if(Node -> Height > MaxHeight)
  3628.                         MaxHeight = Node -> Height;
  3629.                 }
  3630.             }
  3631.  
  3632.             SCANGROUP(Group,Node)
  3633.             {
  3634.                 if(Node -> Width < MaxWidth)
  3635.                 {
  3636.                     if(Node -> Type == GROUP_KIND)
  3637.                         Node -> Special . Group . ExtraLeft += (MaxWidth - Node -> Width) / 2;
  3638.  
  3639.                     Node -> Width = MaxWidth;
  3640.                 }
  3641.  
  3642.                 if(Node -> Height < MaxHeight)
  3643.                 {
  3644.                     if(Node -> Type == GROUP_KIND)
  3645.                         Node -> Special . Group . ExtraTop += (MaxHeight - Node -> Height) / 2;
  3646.  
  3647.                     Node -> Height = MaxHeight;
  3648.                 }
  3649.             }
  3650.         }
  3651.         else
  3652.         {
  3653.             SCANGROUP(Group,Node)
  3654.             {
  3655.                 LTK_DetermineSize(Handle,Node);
  3656.  
  3657.                 if(Node -> Type == BUTTON_KIND)
  3658.                 {
  3659.                     if(Node -> Special . Button . ReturnKey)
  3660.                         ReturnKey = Node;
  3661.                     else
  3662.                     {
  3663.                         if(Node -> Special . Button . EscKey)
  3664.                             EscKey = Node;
  3665.                     }
  3666.                 }
  3667.  
  3668.                 if(Node -> Type == LISTVIEW_KIND && Node -> Special . List . CursorKey)
  3669.                     CursorKey = Node;
  3670.             }
  3671.  
  3672.             if(ReturnKey)
  3673.             {
  3674.                 SCANGROUP(Group,Node)
  3675.                 {
  3676.                     Node -> GroupIndent = TRUE;
  3677.  
  3678.                     Node -> Width    += 4 + 4;
  3679.                     Node -> Height    += 2 + 2;
  3680.                 }
  3681.             }
  3682.         }
  3683.  
  3684.         if(Group -> Special . Group . Horizontal)
  3685.         {
  3686.             LONG x,y,w,MaxTop = 0,MaxWidth = 0,MaxHeight = 0,Count = 0;
  3687.  
  3688.             if(Group -> Node . mln_Pred -> mln_Pred && Group -> Special . Group . LastAttributes)
  3689.             {
  3690.                 ObjectNode *LastGroup = (ObjectNode *)Group -> Node . mln_Pred;
  3691.  
  3692.                 MaxTop        = LastGroup -> Special . Group . MaxOffset;
  3693.                 MaxHeight    = LastGroup -> Special . Group . MaxSize;
  3694.             }
  3695.  
  3696.             SCANGROUP(Group,Node)
  3697.             {
  3698.                 if(!LIKE_STRING_KIND(Node) || Node -> Special . String . LinkID == -1)
  3699.                 {
  3700.                     if(!Group -> Special . Group . Paging && Count++)
  3701.                     {
  3702.                         if(Node -> ExtraSpace > 0)
  3703.                             x = Left + Node -> ExtraSpace * Handle -> InterWidth;
  3704.                         else
  3705.                         {
  3706.                             if(Node -> ExtraSpace < 0)
  3707.                                 x = Left - Node -> ExtraSpace;
  3708.                             else
  3709.                                 x = Left + Handle -> InterWidth;
  3710.                         }
  3711.                     }
  3712.                     else
  3713.                         x = Left;
  3714.  
  3715.                     y = Top;
  3716.                     w = Node -> Width;
  3717.  
  3718.                     switch(Node -> LabelPlace)
  3719.                     {
  3720.                         case PLACE_LEFT:
  3721.  
  3722.                             if(Node -> Type == MX_KIND)
  3723.                             {
  3724.                                 x += Node -> Special . Radio . LabelWidth + INTERWIDTH;
  3725.  
  3726.                                 if(Node -> Label)
  3727.                                 {
  3728.                                     if(Node -> Special . Radio . TitlePlace == PLACETEXT_LEFT)
  3729.                                         x += Node -> LabelWidth + INTERWIDTH;
  3730.                                     else
  3731.                                         w += INTERWIDTH + Node -> LabelWidth;
  3732.                                 }
  3733.                             }
  3734.                             else
  3735.                             {
  3736.                                 if(Node -> Label || Node -> Type == BOX_KIND)
  3737.                                     x += Node -> LabelWidth + INTERWIDTH;
  3738.                             }
  3739.  
  3740.                             break;
  3741.  
  3742.                         case PLACE_RIGHT:
  3743.  
  3744.                             if(Node -> Type == MX_KIND)
  3745.                             {
  3746.                                 w += INTERWIDTH + Node -> Special . Radio . LabelWidth;
  3747.  
  3748.                                 if(Node -> Label)
  3749.                                 {
  3750.                                     if(Node -> Special . Radio . TitlePlace == PLACETEXT_LEFT)
  3751.                                         x += Node -> LabelWidth + INTERWIDTH;
  3752.                                     else
  3753.                                         w += INTERWIDTH + Node -> LabelWidth;
  3754.                                 }
  3755.                             }
  3756.                             else
  3757.                             {
  3758.                                 if(Node -> Label || Node -> Type == BOX_KIND)
  3759.                                     w += INTERWIDTH + Node -> LabelWidth;
  3760.                             }
  3761.  
  3762.                             break;
  3763.  
  3764.                         case PLACE_ABOVE:
  3765.  
  3766.                             if(Node -> Label || Node -> Type == BOX_KIND)
  3767.                                 y += Handle -> RPort . TxHeight + INTERHEIGHT;
  3768.  
  3769.                             break;
  3770.  
  3771.                         case PLACE_BELOW:
  3772.  
  3773.                             break;
  3774.  
  3775.                         case PLACE_IN:
  3776.  
  3777.                             break;
  3778.                     }
  3779.  
  3780.                     if(Node -> Type == SLIDER_KIND && Node -> Special . Slider . LevelPlace == PLACETEXT_RIGHT)
  3781.                         w += INTERWIDTH + Node -> Special . Slider . LevelWidth;
  3782.  
  3783.                     if(Node -> Type == LISTVIEW_KIND && Node -> Special . List . ExtraLabelWidth)
  3784.                         x += Node -> Special . List . ExtraLabelWidth + INTERWIDTH;
  3785.  
  3786.                     if(y > MaxTop)
  3787.                         MaxTop = y;
  3788.  
  3789.                     if(Node -> Height > MaxHeight)
  3790.                         MaxHeight = Node -> Height;
  3791.  
  3792.                     if(Node -> LabelPlace == PLACE_BELOW && Node -> Label)
  3793.                     {
  3794.                         LONG Height = Node -> Height + INTERHEIGHT + Handle -> RPort . TxHeight;
  3795.  
  3796.                         if(Height > MaxHeight)
  3797.                             MaxHeight = Height;
  3798.                     }
  3799.                     else
  3800.                     {
  3801.                         if(Node -> Height > MaxHeight)
  3802.                             MaxHeight = Node -> Height;
  3803.                     }
  3804.  
  3805.                     if(x + w > MaxWidth)
  3806.                         MaxWidth = x+w;
  3807.  
  3808.                     Node -> Left = x;
  3809.  
  3810.                     if(!Group -> Special . Group . Paging)
  3811.                         Left = x + w;
  3812.                 }
  3813.             }
  3814.  
  3815.             SCANGROUP(Group,Node)
  3816.             {
  3817.                 if(!LIKE_STRING_KIND(Node) || Node -> Special . String . LinkID == -1)
  3818.                 {
  3819.                     Node -> Top = MaxTop;
  3820.  
  3821.                     if(Node -> Height < MaxHeight)
  3822.                     {
  3823.                         if(Node -> Type == LISTVIEW_KIND || Node -> Type == PALETTE_KIND)
  3824.                             Node -> Height = MaxHeight;
  3825.                         else
  3826.                         {
  3827.                             if(Node -> Type == GROUP_KIND)
  3828.                             {
  3829.                                 if(Node -> Special . Group . Spread)
  3830.                                     LTK_Spread(Handle,Node,Node -> Width,MaxHeight);
  3831.                                 else
  3832.                                     Node -> Special . Group . ExtraTop += (MaxHeight - Node -> Height) / 2; /* !FIX! */
  3833.  
  3834.                                 Node -> Height = MaxHeight;
  3835.                             }
  3836.                         }
  3837.                     }
  3838.                 }
  3839.             }
  3840.  
  3841.             Group -> Special . Group . MaxOffset = MaxTop;
  3842.             Group -> Special . Group . MaxSize   = MaxHeight;
  3843.  
  3844.             if(Group -> Special . Group . Paging)
  3845.                 Width = MaxWidth;
  3846.             else
  3847.                 Width = Left;
  3848.  
  3849.             Height  = MaxTop + MaxHeight;
  3850.         }
  3851.         else
  3852.         {
  3853.             LONG x,y,w,MaxLeft = 0,MaxWidth = 0,MaxHeight = 0,Count = 0;
  3854.  
  3855.             if(Group -> Node . mln_Pred -> mln_Pred && Group -> Special . Group . LastAttributes)
  3856.             {
  3857.                 ObjectNode *LastGroup = (ObjectNode *)Group -> Node . mln_Pred;
  3858.  
  3859.                 MaxLeft        = LastGroup -> Special . Group . MaxOffset;
  3860.                 MaxWidth    = LastGroup -> Special . Group . MaxSize;
  3861.             }
  3862.  
  3863.             SCANGROUP(Group,Node)
  3864.             {
  3865.                 if(!LIKE_STRING_KIND(Node) || Node -> Special . String . LinkID == -1)
  3866.                 {
  3867.                     if(!Group -> Special . Group . Paging && Count++)
  3868.                     {
  3869.                         if(Node -> ExtraSpace > 0)
  3870.                             y = Top + Node -> ExtraSpace * Handle -> InterHeight;
  3871.                         else
  3872.                         {
  3873.                             if(Node -> ExtraSpace < 0)
  3874.                                 y = Top - Node -> ExtraSpace;
  3875.                             else
  3876.                                 y = Top + Handle -> InterHeight;
  3877.                         }
  3878.                     }
  3879.                     else
  3880.                         y = Top;
  3881.  
  3882.                     w = Node -> Width;
  3883.                     x = Left;
  3884.  
  3885.                     switch(Node -> LabelPlace)
  3886.                     {
  3887.                         case PLACE_LEFT:
  3888.  
  3889.                             if(Node -> Type == MX_KIND)
  3890.                             {
  3891.                                 x += Node -> Special . Radio . LabelWidth + INTERWIDTH;
  3892.  
  3893.                                 if(Node -> Label)
  3894.                                 {
  3895.                                     if(Node -> Special . Radio . TitlePlace == PLACETEXT_LEFT)
  3896.                                         x += Node -> LabelWidth + INTERWIDTH;
  3897.                                 }
  3898.                             }
  3899.                             else
  3900.                             {
  3901.                                 if(Node -> Label || Node -> Type == BOX_KIND)
  3902.                                     x += Node -> LabelWidth + INTERWIDTH;
  3903.                             }
  3904.  
  3905.                             break;
  3906.  
  3907.                         case PLACE_RIGHT:
  3908.  
  3909.                             if(Node -> Type == MX_KIND)
  3910.                             {
  3911.                                 w += INTERWIDTH + Node -> Special . Radio . LabelWidth;
  3912.  
  3913.                                 if(Node -> Label)
  3914.                                 {
  3915.                                     if(Node -> Special . Radio . TitlePlace == PLACETEXT_LEFT)
  3916.                                         x += Node -> LabelWidth + INTERWIDTH;
  3917.                                     else
  3918.                                         w += INTERWIDTH + Node -> LabelWidth;
  3919.                                 }
  3920.                             }
  3921.                             else
  3922.                             {
  3923.                                 if(Node -> Label || Node -> Type == BOX_KIND)
  3924.                                     w += INTERWIDTH + Node -> LabelWidth;
  3925.                             }
  3926.  
  3927.                             break;
  3928.  
  3929.                         case PLACE_ABOVE:
  3930.  
  3931.                             if(Node -> Label || Node -> Type == BOX_KIND)
  3932.                                 y += Handle -> RPort . TxHeight + INTERHEIGHT;
  3933.  
  3934.                             break;
  3935.  
  3936.                         case PLACE_BELOW:
  3937.  
  3938.                             break;
  3939.  
  3940.                         case PLACE_IN:
  3941.  
  3942.                             break;
  3943.                     }
  3944.  
  3945.                     if(Node -> Type == SLIDER_KIND && Node -> Special . Slider . LevelPlace == PLACETEXT_RIGHT)
  3946.                         w += INTERWIDTH + Node -> Special . Slider . LevelWidth;
  3947.  
  3948.                     if(Node -> Type == LISTVIEW_KIND && Node -> Special . List . ExtraLabelWidth)
  3949.                         x += Node -> Special . List . ExtraLabelWidth + INTERWIDTH;
  3950.  
  3951.                     if(x > MaxLeft)
  3952.                         MaxLeft = x;
  3953.  
  3954.                     if(w > MaxWidth)
  3955.                         MaxWidth = w;
  3956.  
  3957.                     if(y + Node -> Height > MaxHeight)
  3958.                         MaxHeight = y + Node -> Height;
  3959.  
  3960.                     Node -> Top = y;
  3961.  
  3962.                     if(!Group -> Special . Group . Paging)
  3963.                         Top = y + Node -> Height;
  3964.  
  3965.                     if(Node -> LabelPlace == PLACE_BELOW && Node -> Label)
  3966.                         Top += INTERHEIGHT + Handle -> RPort . TxHeight;
  3967.                 }
  3968.             }
  3969.  
  3970.             SCANGROUP(Group,Node)
  3971.             {
  3972.                 if(!LIKE_STRING_KIND(Node) || Node -> Special . String . LinkID == -1)
  3973.                 {
  3974.                     Node -> Left = MaxLeft;
  3975.  
  3976.                     if(Node -> Type == GROUP_KIND && Group -> Special . Group . Paging)
  3977.                         Node -> Special . Group . ExtraTop += (MaxHeight - Node -> Height) / 2;
  3978.  
  3979.                     if(Node -> Width < MaxWidth)
  3980.                     {
  3981.                         if(Node -> Type == GROUP_KIND)
  3982.                         {
  3983.                             if(Node -> Special . Group . Spread)
  3984.                                 LTK_Spread(Handle,Node,MaxWidth,Node -> Height);
  3985.                             else
  3986.                                 Node -> Special . Group . ExtraLeft += (MaxWidth - Node -> Width) / 2;
  3987.  
  3988.                             Node -> Width = MaxWidth;
  3989.                         }
  3990.                         else
  3991.                         {
  3992.                             if(Node -> Type == LISTVIEW_KIND || Node -> Type == TEXT_KIND || Node -> Type == GAUGE_KIND || Node -> Type == NUMBER_KIND || Node -> Type == CYCLE_KIND || Node -> Type == PALETTE_KIND || LIKE_STRING_KIND(Node) || Node -> Type == INTEGER_KIND || Node -> Type == BUTTON_KIND || Node -> Type == SLIDER_KIND || Node -> Type == BOX_KIND || Node -> Type == SCROLLER_KIND)
  3993.                             {
  3994.                                 if(Node -> Label && Node -> LabelPlace == PLACE_RIGHT)
  3995.                                     Node -> Width = MaxWidth - (INTERWIDTH + Node -> LabelWidth);
  3996.                                 else
  3997.                                     Node -> Width = MaxWidth;
  3998.                             }
  3999.                             else
  4000.                             {
  4001.                                 if(Node -> Type == SLIDER_KIND)
  4002.                                 {
  4003.                                     if(Node -> Special . Slider . LevelPlace == PLACE_RIGHT)
  4004.                                     {
  4005.                                         if(Node -> Width + Node -> Special . Slider . LevelWidth + INTERWIDTH < MaxWidth)
  4006.                                             Node -> Width = MaxWidth - (Node -> Special . Slider . LevelWidth + INTERWIDTH);
  4007.                                     }
  4008.                                     else
  4009.                                         Node -> Width = MaxWidth;
  4010.                                 }
  4011.                             }
  4012.                         }
  4013.                     }
  4014.                 }
  4015.             }
  4016.  
  4017.             Group -> Special . Group . MaxOffset  = MaxLeft;
  4018.             Group -> Special . Group . MaxSize    = MaxWidth;
  4019.  
  4020.             if(Group -> Special . Group . Paging)
  4021.                 Height = MaxHeight;
  4022.             else
  4023.                 Height = Top;
  4024.  
  4025.             Width = MaxLeft + MaxWidth;
  4026.         }
  4027.  
  4028.         Group -> Left    = 0;
  4029.         Group -> Top    = 0;
  4030.         Group -> Width    = Width;
  4031.         Group -> Height    = Height;
  4032.  
  4033.         if(Group -> Label)
  4034.         {
  4035.             Group -> LabelWidth = LT_LabelWidth(Handle,Group -> Label) + 2 * Handle -> GlyphWidth;
  4036.  
  4037.             if(Group -> LabelWidth > Group -> Width)
  4038.             {
  4039.                 Group -> Special . Group . ExtraLeft += (Group -> LabelWidth - Group -> Width) / 2;
  4040.  
  4041.                 Group -> Width = Group -> LabelWidth;
  4042.             }
  4043.  
  4044.             Group -> Width    += 2 * (Handle -> GlyphWidth + Handle -> InterWidth) + 8;
  4045.             Group -> Height    += Handle -> RPort . TxHeight + 2 * Handle -> InterHeight + 3;
  4046.         }
  4047.  
  4048.         if(ReturnKey)
  4049.             Handle -> ReturnKey = ReturnKey;
  4050.  
  4051.         if(EscKey)
  4052.             Handle -> EscKey = EscKey;
  4053.  
  4054.         if(CursorKey)
  4055.             Handle -> CursorKey = CursorKey;
  4056.     }
  4057. }
  4058.  
  4059.  
  4060. /*****************************************************************************/
  4061.  
  4062.  
  4063. STATIC VOID __regargs
  4064. LTK_PlaceGroups(LayoutHandle *handle,ObjectNode *group,LONG left,LONG top)
  4065. {
  4066.     if(!handle -> Failed)
  4067.     {
  4068.         ObjectNode    *node;
  4069.         LONG         plusLeft,
  4070.                  plusTop,
  4071.                  lastSpace;
  4072.  
  4073.         if(group -> Label)
  4074.         {
  4075.             plusLeft    = 4 + handle -> GlyphWidth + handle -> InterWidth + group -> Special . Group . ExtraLeft;
  4076.             plusTop        = handle -> RPort . TxHeight + handle -> InterHeight + group -> Special . Group . ExtraTop;
  4077.         }
  4078.         else
  4079.         {
  4080.             plusLeft    = group -> Special . Group . ExtraLeft;
  4081.             plusTop        = group -> Special . Group . ExtraTop;
  4082.         }
  4083.  
  4084.         if(group -> ExtraSpace)
  4085.         {
  4086.             if(group -> Special . Group . ParentGroup -> Special . Group . Horizontal)
  4087.                 left += handle -> InterWidth;
  4088.             else
  4089.                 top += handle -> InterHeight;
  4090.         }
  4091.  
  4092.         group -> Left    = left;
  4093.         group -> Top    = top;
  4094.  
  4095.         left    += plusLeft;
  4096.         top    += plusTop;
  4097.  
  4098.         if(group -> Special . Group . Horizontal)
  4099.         {
  4100.             lastSpace = left;
  4101.  
  4102.             SCANGROUP(group,node)
  4103.             {
  4104.                 if(node -> Type == GROUP_KIND)
  4105.                     LTK_PlaceGroups(handle,node,lastSpace,top);
  4106.                 else
  4107.                 {
  4108.                     node -> Left    += left;
  4109.                     node -> Top    += top;
  4110.  
  4111.                     handle -> Count++;
  4112.                 }
  4113.  
  4114.                 if(!group -> Special . Group . Paging)
  4115.                 {
  4116.                     lastSpace = node -> Left + node -> Width + handle -> InterWidth;
  4117.  
  4118.                     if(node -> Type == MX_KIND)
  4119.                     {
  4120.                         if((node -> LabelPlace == PLACETEXT_RIGHT) || (node -> LabelPlace == PLACETEXT_LEFT))
  4121.                             lastSpace += INTERWIDTH + node -> Special . Radio . LabelWidth;
  4122.                     }
  4123.                 }
  4124.  
  4125.                 if(node -> Centered)
  4126.                 {
  4127.                     // !!! needs to be smarter about object height,dealing with labels,and the like
  4128.  
  4129.                     node -> Top = group -> Top + ((group -> Height - node -> Height) / 2);
  4130.                 }
  4131.             }
  4132.         }
  4133.         else
  4134.         {
  4135.             lastSpace = top;
  4136.  
  4137.             SCANGROUP(group,node)
  4138.             {
  4139.                 if(node -> Type == GROUP_KIND)
  4140.                     LTK_PlaceGroups(handle,node,left,lastSpace);
  4141.                 else
  4142.                 {
  4143.                     node -> Left    += left;
  4144.                     node -> Top    += top;
  4145.  
  4146.                     handle -> Count++;
  4147.                 }
  4148.  
  4149.                 if(!group -> Special . Group . Paging)
  4150.                     lastSpace = node -> Top + node -> Height + handle -> InterHeight;
  4151.  
  4152.                 if(node -> Centered)
  4153.                 {
  4154.                     // !!! needs to be smarter about object widths,like for MX_KIND
  4155.                     node -> Left = group -> Left + ((group -> Width - node -> Width) / 2);
  4156.                 }
  4157.             }
  4158.         }
  4159.     }
  4160. }
  4161.  
  4162.  
  4163. /*****************************************************************************/
  4164.  
  4165.  
  4166. STATIC ObjectNode * __regargs
  4167. LTK_FindNode_Position(ObjectNode *group,LONG x,LONG y)
  4168. {
  4169.     ObjectNode *node;
  4170.  
  4171.     SCANGROUP(group,node)
  4172.     {
  4173.         if(node -> Type == GROUP_KIND)
  4174.         {
  4175.             ObjectNode *result;
  4176.  
  4177.             if(result = LTK_FindNode_Position(node,x,y))
  4178.                 return(result);
  4179.         }
  4180.         else
  4181.         {
  4182.             if(node -> Left <= x && node -> Left + node -> Width > x && node -> Top <= y && node -> Top + node -> Height > y)
  4183.             {
  4184.                 if(node -> Type == PICKER_KIND)
  4185.                     return(node -> Special . Picker . Parent -> UserData);
  4186.  
  4187.                 if(node -> Type == INCREMENTER_KIND)
  4188.                     return(node -> Special . Incrementer . Parent -> UserData);
  4189.  
  4190.                 return(node);
  4191.             }
  4192.         }
  4193.     }
  4194.  
  4195.     return(NULL);
  4196. }
  4197.  
  4198.  
  4199. /*****************************************************************************/
  4200.  
  4201.  
  4202. STATIC ObjectNode * __regargs
  4203. LTK_FindNode(ObjectNode *group,LONG id)
  4204. {
  4205.     ObjectNode *node;
  4206.     ObjectNode *result;
  4207.  
  4208.     SCANGROUP(group,node)
  4209.     {
  4210.         if(node -> Type == GROUP_KIND)
  4211.         {
  4212.             if(node -> ID == id)
  4213.                 return(node);
  4214.  
  4215.             if(result = LTK_FindNode(node,id))
  4216.                 return(result);
  4217.         }
  4218.         else
  4219.         {
  4220.             if((node -> ID == id) && (node -> Type != PICKER_KIND) && (node -> Type != INCREMENTER_KIND))
  4221.                 return(node);
  4222.         }
  4223.     }
  4224.  
  4225.     return(NULL);
  4226. }
  4227.  
  4228.  
  4229. /*****************************************************************************/
  4230.  
  4231.  
  4232. STATIC struct Gadget * __regargs
  4233. LTK_FindGadget(LayoutHandle *handle,LONG id)
  4234. {
  4235.     if(handle && handle -> GadgetArray)
  4236.     {
  4237.         LONG i = handle -> Count;
  4238.  
  4239.         while(i--)
  4240.         {
  4241.             if(handle -> GadgetArray[i])
  4242.             {
  4243.                 if(handle -> GadgetArray[i] -> GadgetID == id && handle -> GadgetArray[i] -> UserData)
  4244.                 {
  4245.                     register struct ObjectNode *Node = (struct ObjectNode *)handle -> GadgetArray[i] -> UserData;
  4246.  
  4247.                     if(Node -> PointBack == Node && Node -> Host == handle -> GadgetArray[i])
  4248.                         return(handle -> GadgetArray[i]);
  4249.                 }
  4250.             }
  4251.         }
  4252.     }
  4253.  
  4254.     return(NULL);
  4255. }
  4256.  
  4257.  
  4258. /*****************************************************************************/
  4259.  
  4260.  
  4261. #ifdef DO_PICKSHORTCUTS
  4262. STATIC VOID __regargs
  4263. LTK_SearchKeys(LayoutHandle *handle,ObjectNode *group)
  4264. {
  4265.     ObjectNode    *node;
  4266.     ULONG         page;
  4267.  
  4268.     SCANPAGE(group,node,page)
  4269.     {
  4270.         if(node -> Type == GROUP_KIND)
  4271.             LTK_SearchKeys(handle,node);
  4272.         else
  4273.         {
  4274.             if(node -> Key)
  4275.             {
  4276.                 WORD i;
  4277.  
  4278.                 for(i = 0 ; i < 256 ; i++)
  4279.                 {
  4280.                     if(LTK_Keys[0][i] == node -> Key || LTK_Keys[1][i] == node -> Key)
  4281.                     {
  4282.                         handle -> Keys[LTK_Keys[0][i]] = TRUE;
  4283.                         handle -> Keys[LTK_Keys[1][i]] = TRUE;
  4284.  
  4285.                         break;
  4286.                     }
  4287.                 }
  4288.  
  4289.                 if(LTK_Keys[1][node -> Key])
  4290.                     node -> Key = LTK_Keys[0][node -> Key];
  4291.             }
  4292.             else
  4293.             {
  4294.                 if((handle -> CursorKey == node) || (handle -> ReturnKey == node) || (handle -> EscKey == node))
  4295.                     node -> NoKey = TRUE;
  4296.             }
  4297.         }
  4298.     }
  4299. }
  4300. #endif
  4301.  
  4302.  
  4303. /*****************************************************************************/
  4304.  
  4305.  
  4306. #ifdef DO_PICKSHORTCUTS
  4307. STATIC VOID __regargs
  4308. LTK_SelectKeys(LayoutHandle *handle,ObjectNode *group)
  4309. {
  4310.     UBYTE         bunch;
  4311.     ObjectNode    *node;
  4312.     ULONG         page;
  4313.  
  4314.     SCANPAGE(group,node,page)
  4315.     {
  4316.         bunch = 0;
  4317.  
  4318.         switch(node -> Type)
  4319.         {
  4320.             case GROUP_KIND:
  4321.  
  4322.                 LTK_SelectKeys(handle,node);
  4323.                 break;
  4324.  
  4325.             case TEXT_KIND:
  4326.  
  4327.                 if(!node -> Special . Text . UsePicker)
  4328.                     break;
  4329.  
  4330.             case FRACTION_KIND:
  4331.             case PASSWORD_KIND:
  4332.             case STRING_KIND:
  4333.  
  4334.                 if(node -> Special . String . UsePicker)
  4335.                     bunch = 255;
  4336.  
  4337.             case BUTTON_KIND:
  4338.             case CHECKBOX_KIND:
  4339.             case INTEGER_KIND:
  4340.  
  4341.                 bunch++;
  4342.  
  4343.             case LISTVIEW_KIND:
  4344.             case MX_KIND:
  4345.             case CYCLE_KIND:
  4346.             case PALETTE_KIND:
  4347.             case SCROLLER_KIND:
  4348.             case SLIDER_KIND:
  4349.  
  4350.                 bunch++;
  4351.  
  4352.                 if(node -> Label && !node -> Key && !node -> NoKey)
  4353.                 {
  4354.                     WORD    i,len,code,glyph;
  4355.                     STRPTR    label;
  4356.  
  4357.                     label    = node -> Label;
  4358.                     len    = strlen(label);
  4359.  
  4360.                     for(i = 0 ; i < len ; i++)
  4361.                     {
  4362.                         glyph    = ToLower(label[i]);
  4363.                         code    = -1;
  4364.  
  4365.                         if(bunch == 1)    // Support increment & decrement
  4366.                         {
  4367.                             if(LTK_Keys[0][glyph] && LTK_Keys[1][glyph])
  4368.                                 code = LTK_Keys[0][glyph];
  4369.                         }
  4370.                         else
  4371.                         {
  4372.                             if(bunch == 2)
  4373.                             {
  4374.                                 if(LTK_Keys[0][glyph])
  4375.                                     code = LTK_Keys[0][glyph];
  4376.                                 else
  4377.                                 {
  4378.                                     if(LTK_Keys[1][glyph] && LTK_Keys[0][glyph])
  4379.                                     {
  4380.                                         if(ToLower(LTK_Keys[1][glyph]) == glyph)
  4381.                                             code = LTK_Keys[0][glyph];
  4382.                                     }
  4383.                                 }
  4384.                             }
  4385.                         }
  4386.  
  4387.                         if(code != -1 && !handle -> Keys[code])
  4388.                         {
  4389.                             STRPTR newLabel;
  4390.  
  4391.                             if(newLabel = LTK_Alloc(handle,len + 2))
  4392.                             {
  4393.                                 node -> Label    = newLabel;
  4394.                                 node -> Key    = code;
  4395.  
  4396.                                 if(i)
  4397.                                     CopyMem(label,newLabel,i);
  4398.  
  4399.                                 newLabel[i] = '_';
  4400.  
  4401.                                 CopyMem(label + i,&newLabel[i + 1],len - i);
  4402.  
  4403.                                 handle -> Keys[code] = handle -> Keys[LTK_Keys[1][code]] = TRUE;
  4404.  
  4405.                                 break;
  4406.                             }
  4407.                         }
  4408.                     }
  4409.                 }
  4410.  
  4411.                 break;
  4412.         }
  4413.     }
  4414. }
  4415. #endif
  4416.  
  4417.  
  4418. /*****************************************************************************/
  4419.  
  4420.  
  4421. STATIC ObjectNode * __regargs
  4422. LTK_CreateObjectNode(LayoutHandle *handle,UBYTE type,ULONG id,STRPTR label)
  4423. {
  4424.     ObjectNode    *node;
  4425.     ULONG         size,extra;
  4426.  
  4427.     switch(type)
  4428.     {
  4429. #ifdef DO_GAUGE_KIND
  4430.  
  4431.         case GAUGE_KIND:
  4432.  
  4433.             extra = sizeof(GaugeExtra);
  4434.             break;
  4435. #endif
  4436.  
  4437. #ifdef DO_TAPEDECK_KIND
  4438.         case TAPEDECK_KIND:
  4439.  
  4440.             extra = sizeof(TapeDeckExtra);
  4441.             break;
  4442. #endif    /* DO_TAPEDECK_KIND */
  4443.  
  4444.         case BUTTON_KIND:
  4445.  
  4446.             extra = sizeof(ButtonExtra);
  4447.             break;
  4448.  
  4449.         case XBAR_KIND:
  4450.         case YBAR_KIND:
  4451.  
  4452.             extra = sizeof(BarExtra);
  4453.             break;
  4454.  
  4455.         case BOX_KIND:
  4456.  
  4457.             extra = sizeof(BoxExtra);
  4458.             break;
  4459.  
  4460.         case FRAME_KIND:
  4461.  
  4462.             extra = sizeof(FrameExtra);
  4463.             break;
  4464.  
  4465.         case PICKER_KIND:
  4466.  
  4467.             extra = sizeof(PickerExtra);
  4468.             break;
  4469.  
  4470.         case INCREMENTER_KIND:
  4471.  
  4472.             extra = sizeof(IncrementerExtra);
  4473.             break;
  4474.  
  4475.         case LISTVIEW_KIND:
  4476.  
  4477.             extra = sizeof(ListExtra);
  4478.             break;
  4479.  
  4480.         case MX_KIND:
  4481.  
  4482.             extra = sizeof(RadioExtra);
  4483.             break;
  4484.  
  4485.         case TEXT_KIND:
  4486.  
  4487.             extra = sizeof(TextExtra);
  4488.             break;
  4489.  
  4490.         case NUMBER_KIND:
  4491.  
  4492.             extra = sizeof(NumberExtra);
  4493.             break;
  4494.  
  4495.         case CYCLE_KIND:
  4496.  
  4497.             extra = sizeof(CycleExtra);
  4498.             break;
  4499.  
  4500.         case PALETTE_KIND:
  4501.  
  4502.             extra = sizeof(PalExtra);
  4503.             break;
  4504.  
  4505.         case SLIDER_KIND:
  4506.  
  4507.             extra = sizeof(SliderExtra);
  4508.             break;
  4509.  
  4510.         case SCROLLER_KIND:
  4511.  
  4512.             extra = sizeof(ScrollerExtra);
  4513.             break;
  4514.  
  4515.         case INTEGER_KIND:
  4516.  
  4517.             extra = sizeof(IntegerExtra);
  4518.             break;
  4519.  
  4520.         case FRACTION_KIND:
  4521.         case PASSWORD_KIND:
  4522.         case STRING_KIND:
  4523.  
  4524.             extra = sizeof(StringExtra);
  4525.             break;
  4526.  
  4527.         case HORIZONTAL_KIND:
  4528.         case VERTICAL_KIND:
  4529.  
  4530.             extra = sizeof(GroupExtra);
  4531.             break;
  4532.  
  4533.         default:
  4534.  
  4535.             extra = 0;
  4536.             break;
  4537.     }
  4538.  
  4539.     size = offsetof(ObjectNode,Special) + extra;
  4540.  
  4541.     if(node = LTK_Alloc(handle,size))
  4542.     {
  4543.         node -> Type        = type;
  4544.         node -> Label        = label;
  4545.         node -> ID        = id;
  4546.         node -> PointBack    = node;
  4547.  
  4548.         switch(type)
  4549.         {
  4550.             case LISTVIEW_KIND:
  4551.  
  4552.                 node -> LabelPlace        = PLACE_ABOVE;
  4553.                 node -> Lines            = 1;
  4554.                 node -> Current            = ~0;
  4555.                 node -> Special . List . LinkID    = -1;
  4556.  
  4557.                 break;
  4558.  
  4559.             case PASSWORD_KIND:
  4560.             case STRING_KIND:
  4561.  
  4562.                 node -> Special . String . LayoutHandle        = handle;
  4563.                 node -> Special . String . LinkID        = -1;
  4564.                 node -> Special . String . MaxChars        = 256;
  4565.                 node -> Special . String . MaxHistoryLines    = 0;
  4566.  
  4567.                 break;
  4568.  
  4569.             case INTEGER_KIND:
  4570.  
  4571.                 node -> Special . Integer . LayoutHandle    = handle;
  4572.                 node -> Special . Integer . Min            = -2147483647;
  4573.                 node -> Special . Integer . Max            = 2147483647;
  4574.                 node -> Special . Integer . MaxChars        = 11;
  4575.                 node -> Special . Integer . MaxHistoryLines    = 0;
  4576.  
  4577.                 break;
  4578.  
  4579. #ifdef DO_FRACTION_KIND
  4580.             case FRACTION_KIND:
  4581.  
  4582.                 node -> Special . String . LayoutHandle        = handle;
  4583.                 node -> Special . String . LinkID        = -1;
  4584.                 node -> Special . String . Min            = 0;
  4585.                 node -> Special . String . Max            = 2147483647;
  4586.                 node -> Special . String . MaxChars        = 12;
  4587.                 node -> Special . String . MaxHistoryLines    = 0;
  4588.  
  4589.                 break;
  4590. #endif
  4591.  
  4592. #ifdef DO_TAPEDECK_KIND
  4593.             case TAPEDECK_KIND:
  4594.  
  4595.                 node -> LabelPlace = PLACE_BELOW;
  4596.                 break;
  4597. #endif    /* DO_TAPEDECK_KIND */
  4598.  
  4599.             case MX_KIND:
  4600.  
  4601.                 node -> LabelPlace                = PLACE_RIGHT;
  4602.                 node -> Special . Radio . TitlePlace        = PLACETEXT_LEFT;
  4603.  
  4604.                 break;
  4605.  
  4606.             case SCROLLER_KIND:
  4607.  
  4608.                 node -> Special . Scroller . Visible = 2;
  4609.                 break;
  4610.  
  4611.             case SLIDER_KIND:
  4612.  
  4613.                 node -> Special . Slider . LevelPlace = PLACETEXT_LEFT;
  4614.                 break;
  4615.  
  4616.             case FRAME_KIND:
  4617.  
  4618.                 node -> Special . Frame . DrawBox = TRUE;
  4619.                 break;
  4620.  
  4621.             case BOX_KIND:
  4622.  
  4623.                 node -> Special . Box . DrawBox = TRUE;
  4624.                 break;
  4625.  
  4626.             case HORIZONTAL_KIND:
  4627.  
  4628.                 node -> Type = GROUP_KIND;
  4629.                 node -> Special . Group . Horizontal = TRUE;
  4630.                 break;
  4631.  
  4632.             case VERTICAL_KIND:
  4633.  
  4634.                 node -> Type = GROUP_KIND;
  4635.                 node -> Special . Group . Horizontal = FALSE;
  4636.                 break;
  4637.         }
  4638.     }
  4639.  
  4640.     return(node);
  4641. }
  4642.  
  4643.  
  4644. /*****************************************************************************/
  4645.  
  4646.  
  4647. STATIC VOID __regargs
  4648. LTK_DeleteObjectNode(LayoutHandle *handle,ObjectNode *node)
  4649. {
  4650.     struct Image **ImagePtr = NULL;
  4651.  
  4652.     if(node -> Type == PICKER_KIND)
  4653.     {
  4654.         if(node -> Special . Picker . Image)
  4655.             ImagePtr = &node -> Special . Picker . Image;
  4656.     }
  4657.     else
  4658.     {
  4659.         if(node -> Type == INCREMENTER_KIND)
  4660.             ImagePtr = &node -> Special . Incrementer . Image;
  4661.         else
  4662.         {
  4663.             if(node -> Type == TAPEDECK_KIND)
  4664.                 ImagePtr = &node -> Special . TapeDeck . ButtonImage;
  4665.         }
  4666.     }
  4667.  
  4668.     if(ImagePtr)
  4669.     {
  4670.         if(*ImagePtr)
  4671.         {
  4672.             DisposeObject(*ImagePtr);
  4673.  
  4674.             *ImagePtr = NULL;
  4675.         }
  4676.     }
  4677. }
  4678.  
  4679.  
  4680. /*****************************************************************************/
  4681.  
  4682.  
  4683. STATIC struct Gadget * __regargs
  4684. LTK_CreatePicker(LayoutHandle *handle,ObjectNode *parentNode,struct Gadget *parentGadget,struct NewGadget *ng)
  4685. {
  4686.     ObjectNode    *node;
  4687.     struct Gadget    *picker;
  4688.  
  4689.     if(node = LTK_CreateObjectNode(handle,PICKER_KIND,parentGadget -> GadgetID,NULL))
  4690.     {
  4691.         ng -> ng_LeftEdge    = ng -> ng_LeftEdge + ng -> ng_Width;
  4692.         ng -> ng_Width        = (ng -> ng_Height * handle -> AspectY) / handle -> AspectX;
  4693.         ng -> ng_GadgetText    = "";
  4694.         ng -> ng_UserData    = node;
  4695.         ng -> ng_Flags        = NULL;
  4696.  
  4697.         node -> Special . Picker . Image = NewObject(LTK_ImageClass,NULL,
  4698.             IIA_ImageType,    IMAGECLASS_PICKER,
  4699.             IA_Width,    ng -> ng_Width,
  4700.             IA_Height,    ng -> ng_Height,
  4701.         TAG_DONE);
  4702.  
  4703.         if(node -> Special . Picker . Image)
  4704.         {
  4705.             if(picker = CreateGadgetA(GENERIC_KIND,parentGadget,ng,NULL))
  4706.             {
  4707.                 picker -> GadgetType    |= GTYP_BOOLGADGET;
  4708.                 picker -> Flags        |= GFLG_GADGIMAGE | GFLG_GADGHIMAGE;
  4709.                 picker -> Activation    |= GACT_RELVERIFY;
  4710.                 picker -> GadgetRender     = node -> Special . Picker . Image;
  4711.                 picker -> SelectRender     = node -> Special . Picker . Image;
  4712.  
  4713.                 if(parentNode -> Disabled)
  4714.                     picker -> Flags |= GFLG_DISABLED;
  4715.  
  4716.                 node -> Host = picker;
  4717.  
  4718.                 node -> Special . Picker . Parent = parentGadget;
  4719.  
  4720.                 return(picker);
  4721.             }
  4722.             else
  4723.                         LTK_DeleteObjectNode(handle,node);
  4724.         }
  4725.     }
  4726.  
  4727.     return(NULL);
  4728. }
  4729.  
  4730.  
  4731. /*****************************************************************************/
  4732.  
  4733.  
  4734. STATIC struct Gadget * __regargs
  4735. LTK_CreateIncrementer(LayoutHandle *handle,ObjectNode *parentNode,struct Gadget *parentGadget,struct NewGadget *ng,BOOLEAN leftDirection,LONG incAmount)
  4736. {
  4737.     ObjectNode    *node;
  4738.     struct Gadget    *incer;
  4739.  
  4740.     if(node = LTK_CreateObjectNode(handle,INCREMENTER_KIND,parentGadget -> GadgetID,NULL))
  4741.     {
  4742.         ng -> ng_LeftEdge    = ng -> ng_LeftEdge + ng -> ng_Width;
  4743.         ng -> ng_Width        = (((ng -> ng_Height * handle -> AspectY) / handle -> AspectX) * 4) / 5,
  4744.         ng -> ng_GadgetText    = "";
  4745.         ng -> ng_UserData    = node;
  4746.         ng -> ng_Flags        = NULL;
  4747.  
  4748.         node -> Special . Incrementer . Amount = incAmount;
  4749.  
  4750.         if(leftDirection)
  4751.         {
  4752.             node -> Special . Incrementer . Image = NewObject(LTK_ImageClass,NULL,
  4753.                 IIA_ImageType,    IMAGECLASS_LEFTINCREMENTER,
  4754.                 IA_Width,    ng -> ng_Width,
  4755.                 IA_Height,    ng -> ng_Height,
  4756.             TAG_DONE);
  4757.         }
  4758.         else
  4759.         {
  4760.             node -> Special . Incrementer . Image = NewObject(LTK_ImageClass,NULL,
  4761.                 IIA_ImageType,    IMAGECLASS_RIGHTINCREMENTER,
  4762.                 IA_Width,    ng -> ng_Width,
  4763.                 IA_Height,    ng -> ng_Height,
  4764.             TAG_DONE);
  4765.         }
  4766.  
  4767.         if(node -> Special . Incrementer . Image)
  4768.         {
  4769.             if(incer = CreateGadgetA(GENERIC_KIND,handle -> Previous,ng,NULL))
  4770.             {
  4771.                 incer -> GadgetType    |= GTYP_BOOLGADGET;
  4772.                 incer -> Flags        |= GFLG_GADGIMAGE | GFLG_GADGHIMAGE;
  4773.                 incer -> Activation    |= GACT_IMMEDIATE | GACT_RELVERIFY;
  4774.                 incer -> GadgetRender     = node -> Special . Incrementer . Image;
  4775.                 incer -> SelectRender     = node -> Special . Incrementer . Image;
  4776.  
  4777.                 if(parentNode -> Disabled)
  4778.                     incer -> Flags |= GFLG_DISABLED;
  4779.  
  4780.                 node -> Host = incer;
  4781.  
  4782.                 node -> Special . Incrementer . Parent = parentGadget;
  4783.  
  4784.                 return(incer);
  4785.             }
  4786.             else
  4787.                 LTK_DeleteObjectNode(handle,node);
  4788.         }
  4789.     }
  4790.  
  4791.     return(NULL);
  4792. }
  4793.  
  4794.  
  4795. /*****************************************************************************/
  4796.  
  4797.  
  4798. STATIC VOID __regargs
  4799. LTK_LayoutGadgets(LayoutHandle *Handle,ObjectNode *Group)
  4800. {
  4801.     if(!Handle -> Failed)
  4802.     {
  4803.         STATIC struct TagItem NoUnderscoreVanillaTags[] =
  4804.         {
  4805.             {TAG_DONE}
  4806.         };
  4807.  
  4808.         STATIC struct TagItem VanillaTags[] =
  4809.         {
  4810.             {GT_Underscore,    '_'},
  4811.             {TAG_DONE}
  4812.         };
  4813.  
  4814.         STATIC struct TagItem DisabledTags[] =
  4815.         {
  4816.             {GT_Underscore,    '_' },
  4817.             {GA_Disabled,    TRUE},
  4818.             {TAG_DONE}
  4819.         };
  4820.  
  4821.         STATIC struct TagItem NoUnderscoreDisabledTags[] =
  4822.         {
  4823.             {GA_Disabled,    TRUE},
  4824.             {TAG_DONE}
  4825.         };
  4826.  
  4827.         struct NewGadget     NewGadget;
  4828.  
  4829.         struct Gadget        *Gadget,
  4830.                     *Extra;
  4831.         struct TagItem        *Tags;
  4832.         ULONG             page;
  4833.         ObjectNode        *Node;
  4834.  
  4835.         if(!Handle -> List)
  4836.         {
  4837.             if(!(Handle -> Previous = CreateContext(&Handle -> List)))
  4838.             {
  4839.                 Handle -> Failed = TRUE;
  4840.  
  4841.                 return;
  4842.             }
  4843.         }
  4844.  
  4845.         NewGadget . ng_TextAttr   = Handle -> TextAttr;
  4846.         NewGadget . ng_VisualInfo = Handle -> VisualInfo;
  4847.  
  4848.         SCANPAGE(Group,Node,page)
  4849.         {
  4850.             if(Node -> Type != FRAME_KIND && Node -> Type != BOX_KIND && Node -> Type != XBAR_KIND && Node -> Type != YBAR_KIND)
  4851.             {
  4852.                 Extra = NULL;
  4853.  
  4854.                 if(Node -> GroupIndent)
  4855.                 {
  4856.                     NewGadget . ng_LeftEdge    = Node -> Left + 4;
  4857.                     NewGadget . ng_TopEdge    = Node -> Top + 2;
  4858.                     NewGadget . ng_Width    = Node -> Width - (4 + 4);
  4859.                     NewGadget . ng_Height    = Node -> Height - (2 + 2);
  4860.                 }
  4861.                 else
  4862.                 {
  4863.                     NewGadget . ng_LeftEdge    = Node -> Left;
  4864.                     NewGadget . ng_TopEdge    = Node -> Top;
  4865.                     NewGadget . ng_Width    = Node -> Width;
  4866.                     NewGadget . ng_Height    = Node -> Height;
  4867.                 }
  4868.  
  4869.                 NewGadget . ng_GadgetText    = Node -> Label ? Node -> Label : (STRPTR)"";
  4870.                 NewGadget . ng_GadgetID        = Node -> ID;
  4871.                 NewGadget . ng_UserData        = Node;
  4872.  
  4873.                 if(Node -> NoKey)
  4874.                 {
  4875.                     if(Node -> Disabled)
  4876.                     {
  4877.                         if(!V39 && (Node -> Type == MX_KIND || Node -> Type == LISTVIEW_KIND))
  4878.                             Tags = NoUnderscoreVanillaTags;
  4879.                         else
  4880.                             Tags = NoUnderscoreDisabledTags;
  4881.                     }
  4882.                     else
  4883.                         Tags = NoUnderscoreVanillaTags;
  4884.                 }
  4885.                 else
  4886.                 {
  4887.                     if(Node -> Disabled)
  4888.                     {
  4889.                         if(!V39 && (Node -> Type == MX_KIND || Node -> Type == LISTVIEW_KIND))
  4890.                             Tags = VanillaTags;
  4891.                         else
  4892.                             Tags = DisabledTags;
  4893.                     }
  4894.                     else
  4895.                         Tags = VanillaTags;
  4896.                 }
  4897.  
  4898.                 switch(Node -> LabelPlace)
  4899.                 {
  4900.                     case PLACE_LEFT:
  4901.  
  4902.                         NewGadget . ng_Flags = PLACETEXT_LEFT;
  4903.                         break;
  4904.  
  4905.                     case PLACE_RIGHT:
  4906.  
  4907.                         NewGadget . ng_Flags = PLACETEXT_RIGHT;
  4908.                         break;
  4909.  
  4910.                     case PLACE_ABOVE:
  4911.  
  4912.                         NewGadget . ng_Flags = PLACETEXT_ABOVE;
  4913.                         break;
  4914.  
  4915.                     case PLACE_BELOW:
  4916.  
  4917.                         NewGadget . ng_Flags = PLACETEXT_BELOW;
  4918.                         break;
  4919.  
  4920.                     case PLACE_IN:
  4921.  
  4922.                         NewGadget . ng_Flags = PLACETEXT_IN;
  4923.                         break;
  4924.  
  4925.                     default:
  4926.  
  4927.                         NewGadget . ng_Flags = NULL;
  4928.                         break;
  4929.                 }
  4930.  
  4931.                 if(Node -> HighLabel)
  4932.                     NewGadget . ng_Flags |= NG_HIGHLABEL;
  4933.  
  4934.                 switch(Node -> Type)
  4935.                 {
  4936.                     case BUTTON_KIND:
  4937.  
  4938.                         Gadget = CreateGadgetA(BUTTON_KIND,Handle -> Previous,&NewGadget,Tags);
  4939.  
  4940.                         break;
  4941.  
  4942.                     case GROUP_KIND:
  4943.  
  4944.                         LTK_LayoutGadgets(Handle,Node);
  4945.  
  4946.                         continue;
  4947.  
  4948.                     case CHECKBOX_KIND:
  4949.  
  4950.                         Gadget = CreateGadget(CHECKBOX_KIND,Handle -> Previous,&NewGadget,
  4951.                             GTCB_Checked,    Node -> Current,
  4952.                             GTCB_Scaled,    TRUE,
  4953.                         TAG_MORE,Tags);
  4954.  
  4955.                         break;
  4956.  
  4957.                     case LISTVIEW_KIND:
  4958.  
  4959.                         if(!Node -> Special . List . ReadOnly && Node -> Special . List . LinkID != -1 && Node -> Special . List . LinkID != NIL_LINK)
  4960.                             Gadget = Node -> Special . List . Link = LTK_FindGadget(Handle,Node -> Special . List . LinkID);
  4961.                         else
  4962.                             Gadget = NULL;
  4963.  
  4964.                         Gadget = CreateGadget(LISTVIEW_KIND,Handle -> Previous,&NewGadget,
  4965.                             GTLV_Selected,        Node -> Current,
  4966.                             GTLV_ReadOnly,        Node -> Special . List . ReadOnly,
  4967.                             GTLV_ScrollWidth,    2 + 2 * Handle -> GlyphWidth + 2,
  4968.  
  4969.                             Node -> Current >= 0 ?            GTLV_Top:        TAG_IGNORE,Node -> Current,
  4970.                             Node -> Current >= 0 ?            GTLV_MakeVisible:    TAG_IGNORE,Node -> Current,
  4971.                             Node -> Special . List . Labels    ?    GTLV_Labels:        TAG_IGNORE,Node -> Special . List . Labels,
  4972.                             Node -> Special . List . LinkID != -1 ?    GTLV_ShowSelected:    TAG_IGNORE,Gadget,
  4973.                             Node -> Special . List . CallBack ?    GTLV_CallBack:        TAG_IGNORE,Node -> Special . List . CallBack,
  4974.                             Node -> Special . List . MaxPen ?    GTLV_MaxPen:        TAG_IGNORE,Node -> Special . List . MaxPen,
  4975.                         TAG_MORE,Tags);
  4976.  
  4977.                         break;
  4978.  
  4979.                     case MX_KIND:
  4980.  
  4981.                         NewGadget . ng_Height = Handle -> RPort . TxHeight;
  4982.  
  4983.                         Gadget = CreateGadget(MX_KIND,Handle -> Previous,&NewGadget,
  4984.                             GTMX_Labels,    Node -> Special . Radio . Choices,
  4985.                             GTMX_Active,    Node -> Current,
  4986.                             GTMX_Spacing,    Handle -> InterHeight,
  4987.                             GTMX_Scaled,    TRUE,
  4988.  
  4989.                             Node -> Label ? GTMX_TitlePlace : TAG_IGNORE,  Node -> Special . Radio . TitlePlace,
  4990.                         TAG_MORE,Tags);
  4991.  
  4992.                         break;
  4993.  
  4994.                     case TEXT_KIND:
  4995.  
  4996.                         if(Node -> Special . Text . UsePicker)
  4997.                             NewGadget . ng_Width -= (NewGadget . ng_Height * Handle -> AspectY) / Handle -> AspectX;
  4998.  
  4999.                         if(Gadget = CreateGadget(TEXT_KIND,Handle -> Previous,&NewGadget,
  5000.                             GTTX_Border,        Node -> Special . Text . Border,
  5001.                             GTTX_Justification,    Node -> Special . Text . Justification,
  5002.  
  5003.                             Node -> Special . Text . Text ? GTTX_Text : TAG_IGNORE,Node -> Special . Text . Text,
  5004.                         TAG_MORE,Tags))
  5005.                         {
  5006.                             if(Node -> Special . Text . UsePicker)
  5007.                             {
  5008.                                 Extra = LTK_CreatePicker(Handle,Node,Gadget,&NewGadget);
  5009.  
  5010.                                 if(!Extra)
  5011.                                     Gadget = NULL;
  5012.  
  5013.                                 Node -> Special . Text . Picker = Extra;
  5014.                             }
  5015.                         }
  5016.  
  5017.                         break;
  5018. #ifdef DO_GAUGE_KIND
  5019.                     case GAUGE_KIND:
  5020.  
  5021.                         NewGadget . ng_Height -= Handle -> InterHeight + Handle -> RPort . TxHeight + 2;
  5022.  
  5023.                         Gadget = CreateGadgetA(TEXT_KIND,Handle -> Previous,&NewGadget,NULL);
  5024.  
  5025.                         break;
  5026. #endif
  5027.  
  5028. #ifdef DO_TAPEDECK_KIND
  5029.                     case TAPEDECK_KIND:
  5030.  
  5031.                         if(Node -> Special . TapeDeck . ButtonType >= TDBT_BACKWARD && Node -> Special . TapeDeck . ButtonType < TDBTLAST)
  5032.                         {
  5033.                             LONG    ImageType;
  5034.                             UWORD    Activation,
  5035.                                 Flags;
  5036.  
  5037.                             if(Node -> Special . TapeDeck . Toggle)
  5038.                                 Activation = GACT_TOGGLESELECT | GACT_IMMEDIATE;
  5039.                             else
  5040.                                 Activation = GACT_RELVERIFY;
  5041.  
  5042.                             if(Node -> Current)
  5043.                                 Flags = GFLG_GADGIMAGE | GFLG_GADGHIMAGE | GFLG_SELECTED;
  5044.                             else
  5045.                                 Flags = GFLG_GADGIMAGE | GFLG_GADGHIMAGE;
  5046.  
  5047.                             switch(Node -> Special . TapeDeck . ButtonType)
  5048.                             {
  5049.                                 case TDBT_BACKWARD:
  5050.  
  5051.                                     ImageType = IMAGECLASS_BACKWARD;
  5052.                                     break;
  5053.  
  5054.                                 case TDBT_FORWARD:
  5055.  
  5056.                                     ImageType = IMAGECLASS_FORWARD;
  5057.                                     break;
  5058.  
  5059.                                 case TDBT_PREVIOUS:
  5060.  
  5061.                                     ImageType = IMAGECLASS_PREVIOUS;
  5062.                                     break;
  5063.  
  5064.                                 case TDBT_NEXT:
  5065.  
  5066.                                     ImageType = IMAGECLASS_NEXT;
  5067.                                     break;
  5068.  
  5069.                                 case TDBT_RECORD:
  5070.  
  5071.                                     ImageType = IMAGECLASS_RECORD;
  5072.                                     break;
  5073.  
  5074.                                 case TDBT_PLAY:
  5075.  
  5076.                                     ImageType = IMAGECLASS_PLAY;
  5077.                                     break;
  5078.  
  5079.                                 case TDBT_STOP:
  5080.  
  5081.                                     ImageType = IMAGECLASS_STOP;
  5082.                                     break;
  5083.  
  5084.                                 case TDBT_PAUSE:
  5085.  
  5086.                                     ImageType = IMAGECLASS_PAUSE;
  5087.                                     break;
  5088.  
  5089.                                 case TDBT_REWIND:
  5090.  
  5091.                                     ImageType = IMAGECLASS_REWIND;
  5092.                                     break;
  5093.  
  5094.                                 case TDBT_EJECT:
  5095.  
  5096.                                     ImageType = IMAGECLASS_EJECT;
  5097.                                     break;
  5098.                             }
  5099.  
  5100.                             if(Node -> Special . TapeDeck . ButtonImage = NewObject(LTK_ImageClass,NULL,
  5101.                                 IIA_ImageType,    ImageType,
  5102.                                 IIA_GlyphWidth,    Node -> Special . TapeDeck . ButtonWidth,
  5103.                                 IIA_GlyphHeight,Node -> Special . TapeDeck . ButtonHeight,
  5104.                                 IA_Width,    NewGadget . ng_Width,
  5105.                                 IA_Height,    NewGadget . ng_Height,
  5106.                             TAG_DONE))
  5107.                             {
  5108.                                 NewGadget . ng_GadgetText    = "";
  5109.                                 NewGadget . ng_Flags        = NULL;
  5110.  
  5111.                                 if(Gadget = CreateGadgetA(GENERIC_KIND,Handle -> Previous,&NewGadget,NULL))
  5112.                                 {
  5113.                                     Gadget -> GadgetType    |= GTYP_BOOLGADGET;
  5114.                                     Gadget -> Flags        |= Flags;
  5115.                                     Gadget -> Activation    |= Activation;
  5116.  
  5117.                                     Gadget -> GadgetRender     = Node -> Special . TapeDeck . ButtonImage;
  5118.                                     Gadget -> SelectRender     = Node -> Special . TapeDeck . ButtonImage;
  5119.  
  5120.                                     if(Node -> Disabled)
  5121.                                         Gadget -> Flags |= GFLG_DISABLED;
  5122.                                 }
  5123.                             }
  5124.                         }
  5125.  
  5126.                         break;
  5127. #endif    /* DO_TAPEDECK_KIND */
  5128.                     case NUMBER_KIND:
  5129.  
  5130.                         Gadget = CreateGadget(NUMBER_KIND,Handle -> Previous,&NewGadget,
  5131.                             GTNM_Number,        Node -> Special . Number . Number,
  5132.                             GTNM_Border,        Node -> Special . Number . Border,
  5133.                             GTNM_Justification,    Node -> Special . Number . Justification,
  5134.                             GTNM_Border,        Node -> Special . Number . Border,
  5135.                             GTNM_Justification,    Node -> Special . Number . Justification,
  5136.                         TAG_MORE,Tags);
  5137.  
  5138.                         break;
  5139.  
  5140.                     case CYCLE_KIND:
  5141.  
  5142.                         Gadget = CreateGadget(CYCLE_KIND,Handle -> Previous,&NewGadget,
  5143.                             GTCY_Labels,        Node -> Special . Cycle . Choices,
  5144.                             GTCY_Active,        Node -> Current,
  5145.                         TAG_MORE,Tags);
  5146.  
  5147.                         break;
  5148.  
  5149.                     case PALETTE_KIND:
  5150.  
  5151.                         Gadget = CreateGadget(PALETTE_KIND,Handle -> Previous,&NewGadget,
  5152.                             GTPA_Depth,        Node -> Special . Palette . Depth,
  5153.                             GTPA_Color,        Node -> Current,
  5154.                             GTPA_ColorOffset,    Node -> Min,
  5155.                             GTPA_IndicatorWidth,    MAX(10,Node -> Width / (Node -> Max - Node -> Min + 1)),
  5156.                             GTPA_IndicatorHeight,    Node -> Height,
  5157.  
  5158.                             Node -> Special . Palette . ColourTable ? GTPA_ColorTable : TAG_IGNORE,Node -> Special . Palette . ColourTable,
  5159.                         TAG_MORE,Tags);
  5160.  
  5161.                         break;
  5162.  
  5163.                     case SLIDER_KIND:
  5164.  
  5165.                         Gadget = CreateGadget(SLIDER_KIND,Handle -> Previous,&NewGadget,
  5166.                             GTSL_Min,        Node -> Min,
  5167.                             GTSL_Max,        Node -> Max,
  5168.                             GTSL_Level,        Node -> Current,
  5169.                             GTSL_MaxLevelLen,    Node -> Special . Slider . MaxLevelLen,
  5170.                             GTSL_LevelPlace,    Node -> Special . Slider . LevelPlace,
  5171.                             GTSL_LevelFormat,    Node -> Special . Slider . LevelFormat ? Node -> Special . Slider . LevelFormat : (STRPTR)"%ld",
  5172.                             GA_RelVerify,        TRUE,
  5173.  
  5174.                             V40 ? GTSL_MaxPixelLen : TAG_IGNORE,    Node -> Special . Slider . LevelWidth,
  5175.                             V40 ? GTSL_Justification : TAG_IGNORE,    GTJ_RIGHT,
  5176.                             Node -> Special . Slider . DispFunc ? GTSL_DispFunc : TAG_IGNORE,Node -> Special . Slider . DispFunc,
  5177.                         TAG_MORE,Tags);
  5178.  
  5179.                         break;
  5180.  
  5181.                     case SCROLLER_KIND:
  5182.  
  5183.                         Gadget = CreateGadget(SCROLLER_KIND,Handle -> Previous,&NewGadget,
  5184.                             GA_RelVerify,    Node -> Special . Scroller . RelVerify,
  5185.                             GA_Immediate,    Node -> Special . Scroller . Immediate,
  5186.                             GTSC_Top,    Node -> Current,
  5187.                             GTSC_Total,    Node -> Max,
  5188.                             GTSC_Visible,    Node -> Special . Scroller . Visible,
  5189.                             PGA_Freedom,    Node -> Special . Scroller . Vertical ? LORIENT_VERT : LORIENT_HORIZ,
  5190.  
  5191.                             Node -> Special . Scroller . Arrows ? GTSC_Arrows : TAG_IGNORE,Node -> Special . Scroller . ArrowSize,
  5192.                         TAG_MORE,Tags);
  5193.  
  5194.                         break;
  5195.  
  5196.                     case STRING_KIND:
  5197.  
  5198.                         if(Node -> Special . String . LinkID != -1)
  5199.                         {
  5200.                             ObjectNode *ListView = LTK_FindNode(Handle -> TopGroup,Node -> Special . String . LinkID);
  5201.  
  5202.                             if(ListView)
  5203.                             {
  5204.                                 NewGadget . ng_LeftEdge = ListView -> Left;
  5205.                                 NewGadget . ng_TopEdge  = ListView -> Top + ListView -> Height;
  5206.                                 NewGadget . ng_Width    = ListView -> Width;
  5207.                             }
  5208.                         }
  5209.  
  5210.                         if(Node -> Special . String . UsePicker)
  5211.                             NewGadget . ng_Width -= (NewGadget . ng_Height * Handle -> AspectY) / Handle -> AspectX;
  5212.  
  5213.                         if(Gadget = CreateGadget(STRING_KIND,Handle -> Previous,&NewGadget,
  5214.                             GTST_String,        Node -> Special . String . String,
  5215.                             GTST_MaxChars,        Node -> Special . String . MaxChars,
  5216.                             GTST_EditHook,        Node -> Special . String . EditHook ? Node -> Special . String . EditHook : Handle -> StandardEditHook,
  5217.                             GA_Immediate,        TRUE,
  5218.                             STRINGA_Justification,    Node -> Special . String . Justification,
  5219.                         TAG_MORE,Tags))
  5220.                         {
  5221.                             if(!V39)
  5222.                                 Gadget -> Activation |= GACT_IMMEDIATE;
  5223.  
  5224.                             if(Node -> Special . String . UsePicker)
  5225.                             {
  5226.                                 Extra = LTK_CreatePicker(Handle,Node,Gadget,&NewGadget);
  5227.  
  5228.                                 if(!Extra)
  5229.                                     Gadget = NULL;
  5230.  
  5231.                                 Node -> Special . String . Picker = Extra;
  5232.                             }
  5233.                         }
  5234.  
  5235.                         break;
  5236. #ifdef DO_FRACTION_KIND
  5237.                     case FRACTION_KIND:
  5238.  
  5239.                         if(Node -> Special . String . LinkID != -1)
  5240.                         {
  5241.                             ObjectNode *ListView = LTK_FindNode(Handle -> TopGroup,Node -> Special . String . LinkID);
  5242.  
  5243.                             if(ListView)
  5244.                             {
  5245.                                 NewGadget . ng_LeftEdge = ListView -> Left;
  5246.                                 NewGadget . ng_TopEdge    = ListView -> Top + ListView -> Height;
  5247.                                 NewGadget . ng_Width      = ListView -> Width;
  5248.                             }
  5249.                         }
  5250.  
  5251.                         /* ALWAYS */
  5252.                         {
  5253.                             UBYTE LocalBuffer[20];
  5254.  
  5255.                             sprintf(LocalBuffer,"%ld%lc%ld",Node -> Current / FIXED_UNITY,LTK_Locale ? LTK_Locale -> loc_DecimalPoint[0] : ' . ',Node -> Current % FIXED_UNITY);
  5256.  
  5257.                             if(Gadget = CreateGadget(STRING_KIND,Handle -> Previous,&NewGadget,
  5258.                                 GTST_String,        LocalBuffer,
  5259.                                 GTST_MaxChars,        Node -> Special . String . MaxChars > 12 ? 12 : Node -> Special . String . MaxChars,
  5260.                                 GTST_EditHook,        &Handle -> FracEditHook,
  5261.                                 GA_Immediate,        TRUE,
  5262.                                 STRINGA_Justification,    Node -> Special . String . Justification,
  5263.                             TAG_MORE,Tags))
  5264.                             {
  5265.                                 if(!V39)
  5266.                                     Gadget -> Activation |= GACT_IMMEDIATE;
  5267.                             }
  5268.                         }
  5269.  
  5270.                         break;
  5271. #endif
  5272.  
  5273. #ifdef DO_PASSWORD_KIND
  5274.                     case PASSWORD_KIND:
  5275.                     {
  5276.                         WORD Len;
  5277.  
  5278.                         if(Len = strlen(Node -> Special . String . Original))
  5279.                             memset(Node -> Special . String . Original,'·',Len);
  5280.  
  5281.                         if(Gadget = CreateGadget(STRING_KIND,Handle -> Previous,&NewGadget,
  5282.                             GTST_String,        Node -> Special . String . Original,
  5283.                             GTST_MaxChars,        Node -> Special . String . MaxChars,
  5284.                             GTST_EditHook,        &Handle -> PasswordEditHook,
  5285.                             GA_Immediate,        TRUE,
  5286.                             STRINGA_Justification,    Node -> Special . String . Justification,
  5287.                         TAG_MORE,Tags))
  5288.                         {
  5289.                             if(!V39)
  5290.                                 Gadget -> Activation |= GACT_IMMEDIATE;
  5291.                         }
  5292.  
  5293.                         if(Len)
  5294.                             strcpy(Node -> Special . String . Original,Node -> Special . String . RealString);
  5295.  
  5296.                         break;
  5297.                     }
  5298. #endif
  5299.  
  5300.                     case INTEGER_KIND:
  5301.  
  5302.                         if(Node -> Special . Integer . UseIncrementers)
  5303.                         {
  5304.                             NewGadget . ng_Width -= (((NewGadget . ng_Height * Handle -> AspectY) / Handle -> AspectX) * 4) / 5;
  5305.                             NewGadget . ng_Width -= (((NewGadget . ng_Height * Handle -> AspectY) / Handle -> AspectX) * 4) / 5;
  5306.  
  5307.                             if(Node -> Special . Integer . IncrementerHook)
  5308.                             {
  5309.                                 LONG Value;
  5310.  
  5311.                                 Value = (LONG)CallHookPkt(Node -> Special . Integer . IncrementerHook,(APTR)Node -> Special . Integer . Number,(APTR)INCREMENTERMSG_INITIAL);
  5312.  
  5313.                                 if(Value < Node -> Special . Integer . Min)
  5314.                                     Value = Node -> Special . Integer . Min;
  5315.                                 else
  5316.                                 {
  5317.                                     if(Value > Node -> Special . Integer . Max)
  5318.                                         Value = Node -> Special . Integer . Max;
  5319.                                 }
  5320.  
  5321.                                 Node -> Special . Integer . Number = Value;
  5322.                             }
  5323.                         }
  5324.  
  5325. #ifndef DO_HEXHOOK
  5326.                         Gadget = CreateGadget(INTEGER_KIND,Handle -> Previous,&NewGadget,
  5327.                             GTIN_Number,        Node -> Special . Integer . Number,
  5328.                             GTIN_MaxChars,        Node -> Special . Integer . MaxChars,
  5329.                             GTIN_EditHook,        Node -> Special . Integer . EditHook ? Node -> Special . Integer . EditHook : Handle -> StandardEditHook,
  5330.                             GA_Immediate,        TRUE,
  5331.                             STRINGA_Justification,    Node -> Special . Integer . Justification,
  5332.                         TAG_MORE,Tags);
  5333. #else
  5334.                         if(Node -> Special . Integer . EditHook)
  5335.                         {
  5336.                             Gadget = CreateGadget(INTEGER_KIND,Handle -> Previous,&NewGadget,
  5337.                                 GTIN_Number,        Node -> Special . Integer . Number,
  5338.                                 GTIN_MaxChars,        Node -> Special . Integer . MaxChars,
  5339.                                 GTIN_EditHook,        Node -> Special . Integer . EditHook,
  5340.                                 GA_Immediate,        TRUE,
  5341.                                 STRINGA_Justification,    Node -> Special . Integer . Justification,
  5342.                             TAG_MORE,Tags);
  5343.                         }
  5344.                         else
  5345.                         {
  5346.                             UBYTE LocalBuffer[20];
  5347.  
  5348.                             sprintf(LocalBuffer,"%ld",Node -> Special . Integer . Number);
  5349.  
  5350.                             Gadget = CreateGadget(STRING_KIND,Handle -> Previous,&NewGadget,
  5351.                                 GTST_String,        LocalBuffer,
  5352.                                 GTST_MaxChars,        Node -> Special . Integer . MaxChars,
  5353.                                 GTST_EditHook,        &Handle -> HexEditHook,
  5354.                                 GA_Immediate,        TRUE,
  5355.                                 STRINGA_Justification,    Node -> Special . Integer . Justification,
  5356.                             TAG_MORE,Tags);
  5357.                         }
  5358.  
  5359.                         if(Gadget)
  5360.                         {
  5361.                             struct StringInfo *StringInfo = (struct StringInfo *)Gadget -> SpecialInfo;
  5362.  
  5363.                             StringInfo -> LongInt = Node -> Special . Integer . Number;
  5364.                         }
  5365. #endif
  5366.  
  5367.                         if(Gadget)
  5368.                         {
  5369.                             if(!V39)
  5370.                                 Gadget -> Activation |= GACT_IMMEDIATE;
  5371.  
  5372.                             if(Node -> Special . Integer . UseIncrementers)
  5373.                             {
  5374.                                 Handle -> Previous = Gadget;
  5375.  
  5376.                                 if(Node -> Special . Integer . LeftIncrementer = LTK_CreateIncrementer(Handle,Node,Gadget,&NewGadget,TRUE,-1))
  5377.                                 {
  5378.                                     Handle -> Previous = Node -> Special . Integer . LeftIncrementer;
  5379.  
  5380.                                     if(Node -> Special . Integer . RightIncrementer = LTK_CreateIncrementer(Handle,Node,Gadget,&NewGadget,FALSE,1))
  5381.                                         Extra = Node -> Special . Integer . RightIncrementer;
  5382.                                     else
  5383.                                         Gadget = NULL;
  5384.                                 }
  5385.                                 else
  5386.                                     Gadget = NULL;
  5387.                             }
  5388.                         }
  5389.  
  5390.                         break;
  5391.                 }
  5392.  
  5393.                 if(Gadget)
  5394.                 {
  5395.                     Handle -> GadgetArray[Handle -> Index++] = Gadget;
  5396.  
  5397.                     if(Extra)
  5398.                         Handle -> Previous = Extra;
  5399.                     else
  5400.                         Handle -> Previous = Gadget;
  5401.  
  5402.                     Node -> Host = Gadget;
  5403.                 }
  5404.                 else
  5405.                 {
  5406.                     Handle -> Failed = TRUE;
  5407.  
  5408.                     return;
  5409.                 }
  5410.             }
  5411.         }
  5412.     }
  5413. }
  5414.  
  5415.  
  5416. /*****************************************************************************/
  5417.  
  5418.  
  5419. STATIC BOOLEAN __regargs
  5420. LTK_GlyphSetup(struct LayoutHandle *Handle,struct TextAttr *TextAttr)
  5421. {
  5422.     struct TextFont *Font;
  5423.  
  5424.     if(TextAttr)
  5425.     {
  5426.         Handle -> TextAttr = TextAttr;
  5427.  
  5428.         if(!(Font = OpenFont(Handle -> TextAttr)))
  5429.         {
  5430.             struct Library *DiskfontBase;
  5431.  
  5432.             if(DiskfontBase = OpenLibrary("diskfont.library",0))
  5433.             {
  5434.                 Font = OpenDiskFont(Handle -> TextAttr);
  5435.  
  5436.                 CloseLibrary(DiskfontBase);
  5437.             }
  5438.         }
  5439.  
  5440.         if(Font)
  5441.         {
  5442.             if(Handle -> CloseFont)
  5443.                 CloseFont(Handle -> RPort . Font);
  5444.             else
  5445.                 Handle -> CloseFont = TRUE;
  5446.         }
  5447.     }
  5448.     else
  5449.     {
  5450.         Handle -> TextAttr = Handle -> Screen -> Font;
  5451.  
  5452.         Font = Handle -> DrawInfo -> dri_Font;
  5453.  
  5454.         if(Handle -> CloseFont)
  5455.         {
  5456.             CloseFont(Handle -> RPort . Font);
  5457.  
  5458.             Handle -> CloseFont = FALSE;
  5459.         }
  5460.     }
  5461.  
  5462.     if(Font)
  5463.     {
  5464.         LONG    Count = 0;
  5465.         LONG    Total = 0;
  5466.         UBYTE    Glyph;
  5467.         UWORD    i;
  5468.  
  5469.         LTK_SetFont(Handle,Font);
  5470.  
  5471.         for(i = 32 ; i < 127 ; i++,Count++)
  5472.         {
  5473.             Glyph = i;
  5474.  
  5475.             Total += TextLength(&Handle -> RPort,&Glyph,1);
  5476.         }
  5477.  
  5478.         for(i = 160 ; i < 256 ; i++,Count++)
  5479.         {
  5480.             Glyph = i;
  5481.  
  5482.             Total += TextLength(&Handle -> RPort,&Glyph,1);
  5483.         }
  5484.  
  5485.         Handle -> GlyphWidth = Total / Count;
  5486.  
  5487.         if(Handle -> GlyphWidth <= 8)
  5488.             Handle -> InterWidth = 4;
  5489.         else
  5490.             Handle -> InterWidth = Handle -> GlyphWidth / 2;
  5491.  
  5492.         if(Handle -> RPort . TxHeight <= 8)
  5493.             Handle -> InterHeight = 2;
  5494.         else
  5495.             Handle -> InterHeight = Handle -> RPort . TxHeight / 4;
  5496.  
  5497.         return(TRUE);
  5498.     }
  5499.     else
  5500.         return(FALSE);
  5501. }
  5502.  
  5503.  
  5504. /*****************************************************************************/
  5505.  
  5506. #ifdef DO_CLONING
  5507. STATIC VOID __regargs
  5508. LTK_CloneScreen(struct LayoutHandle *Handle,LONG Width,LONG Height)
  5509. {
  5510.     struct ColorSpec    *ColourSpec;
  5511.     struct ColourRecord    *ColourRecord;
  5512.     struct CloneExtra    *Extra = Handle -> CloneExtra;
  5513.     LONG             AllocationSize;
  5514.     UWORD             i,j,*Pens = Handle -> CloneExtra -> ScreenPens;
  5515.     struct Screen        *Screen;
  5516.  
  5517.     Height += Handle -> Screen -> BarHeight + 1;
  5518.  
  5519.     if(Width < Extra -> MinWidth)
  5520.         Width = Extra -> MinWidth;
  5521.  
  5522.     if(Height < Extra -> MinHeight)
  5523.         Height = Extra -> MinHeight;
  5524.  
  5525.     if(V39)
  5526.     {
  5527.         if(!(ColourRecord = (struct ColourRecord *)AsmAllocPooled(Handle -> Pool,AllocationSize = sizeof(struct ColourRecord) + sizeof(struct ColourTriplet) * Extra -> TotalPens,SysBase)))
  5528.         {
  5529.             Handle -> Failed = TRUE;
  5530.  
  5531.             return;
  5532.         }
  5533.         else
  5534.         {
  5535.             memset(ColourRecord,0,AllocationSize);
  5536.  
  5537.             ColourRecord -> NumColours = Extra -> TotalPens;
  5538.  
  5539.             ColourSpec = NULL;
  5540.  
  5541.             for(i = 0 ; i < Extra -> TotalPens ; i++)
  5542.                 GetRGB32(Handle -> Screen -> ViewPort . ColorMap,Extra -> Pens[i],1,(ULONG *)&ColourRecord -> Triplets[i]);
  5543.         }
  5544.     }
  5545.     else
  5546.     {
  5547.         if(!(ColourSpec = (struct ColorSpec *)AsmAllocPooled(Handle -> Pool,AllocationSize = sizeof(struct ColorSpec) * (Extra -> TotalPens + 1),SysBase)))
  5548.         {
  5549.             Handle -> Failed = TRUE;
  5550.  
  5551.             return;
  5552.         }
  5553.         else
  5554.         {
  5555.             UWORD RGB;
  5556.  
  5557.             ColourRecord = NULL;
  5558.  
  5559.             for(i = 0 ; i < Extra -> TotalPens ; i++)
  5560.             {
  5561.                 RGB = GetRGB4(Handle -> Screen -> ViewPort . ColorMap,Extra -> Pens[i]);
  5562.  
  5563.                 ColourSpec[i] . ColorIndex    = i;
  5564.                 ColourSpec[i] . Red        = (RGB >> 8) & 0xF;
  5565.                 ColourSpec[i] . Green        = (RGB >> 4) & 0xF;
  5566.                 ColourSpec[i] . Blue        = (RGB     ) & 0xF;
  5567.             }
  5568.  
  5569.             ColourSpec[i] . ColorIndex = -1;
  5570.         }
  5571.     }
  5572.  
  5573.     if(Handle -> ExactClone)
  5574.     {
  5575.         for(i = 0 ; i < Handle -> DrawInfo -> dri_NumPens ; i++)
  5576.             Pens[i] = Extra -> Pens[i];
  5577.     }
  5578.     else
  5579.     {
  5580.         for(i = 0 ; i < Handle -> DrawInfo -> dri_NumPens ; i++)
  5581.         {
  5582.             for(j = 0 ; j < Extra -> TotalPens ; j++)
  5583.             {
  5584.                 if(Extra -> Pens[j] == Handle -> DrawInfo -> dri_Pens[i])
  5585.                 {
  5586.                     Pens[i] = j;
  5587.  
  5588.                     break;
  5589.                 }
  5590.             }
  5591.         }
  5592.     }
  5593.  
  5594.     Pens[i] = (UWORD)~0;
  5595.  
  5596.     if(Screen = OpenScreenTags(NULL,
  5597.         SA_Width,    Width,
  5598.         SA_Height,    Height,
  5599.         SA_Overscan,    OSCAN_TEXT,
  5600.         SA_BlockPen,    Pens[SHADOWPEN],
  5601.         SA_DetailPen,    Pens[BACKGROUNDPEN],
  5602.         SA_AutoScroll,    TRUE,
  5603.         SA_DisplayID,    GetVPModeID(&Handle -> Screen -> ViewPort),
  5604.         SA_Behind,    TRUE,
  5605.         SA_BackFill,    &Handle -> BackfillHook,
  5606.         SA_Depth,    Extra -> Depth,
  5607.         SA_Colors,    ColourSpec,
  5608.         SA_Colors32,    ColourRecord,
  5609.         SA_Pens,    Pens,
  5610.         SA_Font,    Handle -> TextAttr,
  5611.         SA_Title,    Handle -> Screen -> DefaultTitle,
  5612.     TAG_DONE))
  5613.     {
  5614.         struct DrawInfo *DrawInfo;
  5615.  
  5616.         if(DrawInfo = GetScreenDrawInfo(Screen))
  5617.         {
  5618.             APTR VisualInfo;
  5619.  
  5620.             if(VisualInfo = GetVisualInfoA(Screen,NULL))
  5621.             {
  5622.                 UnlockPubScreen(NULL,Handle -> PubScreen);
  5623.  
  5624.                 FreeScreenDrawInfo(Handle -> Screen,Handle -> DrawInfo);
  5625.  
  5626.                 FreeVisualInfo(Handle -> VisualInfo);
  5627.  
  5628.                 Handle -> PubScreen    = NULL;
  5629.                 Handle -> Screen    = Screen;
  5630.                 Handle -> DrawInfo    = DrawInfo;
  5631.                 Handle -> VisualInfo    = VisualInfo;
  5632.                 Handle -> TextPen    = Handle -> DrawInfo -> dri_Pens[TEXTPEN];
  5633.                 Handle -> BackgroundPen    = Handle -> DrawInfo -> dri_Pens[BACKGROUNDPEN];
  5634.                 Handle -> ShinePen    = Handle -> DrawInfo -> dri_Pens[SHINEPEN];
  5635.                 Handle -> ShadowPen    = Handle -> DrawInfo -> dri_Pens[SHADOWPEN];
  5636.                 Handle -> AspectX    = Handle -> DrawInfo -> dri_Resolution . X;
  5637.                 Handle -> AspectY    = Handle -> DrawInfo -> dri_Resolution . Y;
  5638.                 Handle -> MaxPen    = Extra -> TotalPens - 1;
  5639.  
  5640.                 Extra -> Screen = Screen;
  5641.  
  5642.                 if(ColourRecord)
  5643.                     AsmFreePooled(Handle -> Pool,ColourRecord,AllocationSize,SysBase);
  5644.  
  5645.                 if(ColourSpec)
  5646.                     AsmFreePooled(Handle -> Pool,ColourSpec,AllocationSize,SysBase);
  5647.  
  5648.                 return;
  5649.             }
  5650.  
  5651.             FreeScreenDrawInfo(Screen,DrawInfo);
  5652.         }
  5653.  
  5654.         CloseScreen(Screen);
  5655.     }
  5656.  
  5657.     if(ColourRecord)
  5658.         AsmFreePooled(Handle -> Pool,ColourRecord,AllocationSize,SysBase);
  5659.  
  5660.     if(ColourSpec)
  5661.         AsmFreePooled(Handle -> Pool,ColourSpec,AllocationSize,SysBase);
  5662.  
  5663.     Handle -> Failed = TRUE;
  5664. }
  5665.  
  5666. STATIC BOOLEAN __regargs
  5667. LTK_PrepareCloning(struct LayoutHandle *Handle)
  5668. {
  5669.     if(Handle -> CloneExtra)
  5670.         return(TRUE);
  5671.     else
  5672.     {
  5673.         struct DimensionInfo DimensionInfo;
  5674.  
  5675.         if(GetDisplayInfoData(NULL,(APTR)&DimensionInfo,sizeof(struct DimensionInfo),DTAG_DIMS,GetVPModeID(&Handle -> Screen -> ViewPort)))
  5676.         {
  5677.             if(Handle -> CloneExtra = (struct CloneExtra *)AsmAllocPooled(Handle -> Pool,sizeof(struct CloneExtra) + (sizeof(LONG) + sizeof(UWORD)) * Handle -> DrawInfo -> dri_NumPens + sizeof(UWORD),SysBase))
  5678.             {
  5679.                 UWORD     i,j,TotalPens = 0;
  5680.                 LONG    *Pens;
  5681.                 BOOLEAN     NotFound;
  5682.  
  5683.                 Handle -> CloneExtra -> Pens        = (LONG *)(Handle -> CloneExtra + 1);
  5684.                 Handle -> CloneExtra -> ScreenPens    = (UWORD *)(&Handle -> CloneExtra -> Pens[Handle -> DrawInfo -> dri_NumPens]);
  5685.                 Handle -> CloneExtra -> MinWidth    = DimensionInfo . MinRasterWidth;
  5686.                 Handle -> CloneExtra -> MinHeight    = DimensionInfo . MinRasterHeight;
  5687.                 Handle -> CloneExtra -> MaxWidth    = DimensionInfo . MaxRasterWidth;
  5688.                 Handle -> CloneExtra -> MaxHeight    = DimensionInfo . MaxRasterHeight;
  5689.  
  5690.                 Handle -> CloneExtra -> Bounds . Left    = 0;
  5691.                 Handle -> CloneExtra -> Bounds . Top    = 0;
  5692.                 Handle -> CloneExtra -> Bounds . Width    = DimensionInfo . MaxRasterWidth;
  5693.                 Handle -> CloneExtra -> Bounds . Height    = DimensionInfo . MaxRasterHeight;
  5694.  
  5695.                 Pens = Handle -> CloneExtra -> Pens;
  5696.  
  5697.                 if(Handle -> ExactClone)
  5698.                 {
  5699.                     for(i = 0 ; i < Handle -> DrawInfo -> dri_NumPens ; i++)
  5700.                         Pens[i] = Handle -> DrawInfo -> dri_Pens[i];
  5701.  
  5702.                     TotalPens = Handle -> DrawInfo -> dri_NumPens;
  5703.  
  5704.                     Handle -> CloneExtra -> Depth = Handle -> DrawInfo -> dri_Depth;
  5705.                 }
  5706.                 else
  5707.                 {
  5708.                     for(i = 0 ; i < Handle -> DrawInfo -> dri_NumPens ; i++)
  5709.                     {
  5710.                         for(j = 0,NotFound = TRUE ; NotFound && j < TotalPens ; j++)
  5711.                         {
  5712.                             if(Pens[j] == Handle -> DrawInfo -> dri_Pens[i])
  5713.                                 NotFound = FALSE;
  5714.                         }
  5715.  
  5716.                         if(NotFound)
  5717.                             Pens[TotalPens++] = Handle -> DrawInfo -> dri_Pens[i];
  5718.                     }
  5719.  
  5720.                     for(i = 0 ; i < DimensionInfo . MaxDepth ; i++)
  5721.                     {
  5722.                         if(TotalPens <= (1L << i))
  5723.                         {
  5724.                             Handle -> CloneExtra -> Depth = i;
  5725.  
  5726.                             break;
  5727.                         }
  5728.                     }
  5729.                 }
  5730.  
  5731.                 if((Handle -> CloneExtra -> TotalPens = TotalPens) && Handle -> CloneExtra -> Depth)
  5732.                 {
  5733.                     if(LTK_GlyphSetup(Handle,Handle -> InitialTextAttr))
  5734.                     {
  5735.                         Handle -> Failed = Handle -> Rescaled = FALSE;
  5736.  
  5737.                         LTK_ResetGroups(Handle -> TopGroup);
  5738.  
  5739.                         if(!V39 && (Handle -> RPort . TxFlags & FPF_PROPORTIONAL))
  5740.                         {
  5741.                             LTK_Rescale(Handle,FALSE,FALSE);
  5742.  
  5743.                             Handle -> Rescaled = FALSE;
  5744.                         }
  5745.  
  5746.                         return(TRUE);
  5747.                     }
  5748.                 }
  5749.                 else
  5750.                 {
  5751.                     AsmFreePooled(Handle -> Pool,Handle -> CloneExtra,sizeof(struct CloneExtra) + sizeof(LONG) * Handle -> DrawInfo -> dri_NumPens,SysBase);
  5752.  
  5753.                     Handle -> CloneExtra = NULL;
  5754.                 }
  5755.             }
  5756.         }
  5757.     }
  5758.  
  5759.     return(FALSE);
  5760. }
  5761. #endif
  5762.  
  5763. /*****************************************************************************/
  5764.  
  5765.  
  5766. STATIC VOID __regargs
  5767. LTK_CreateGadgets(LayoutHandle *Handle,struct IBox *Bounds,LONG Left,LONG Top,LONG PlusWidth,LONG PlusHeight)
  5768. {
  5769.     if(!Handle -> Failed)
  5770.     {
  5771.         BOOLEAN Fits;
  5772.         BOOLEAN Cloned = FALSE;
  5773.  
  5774.         if(!V39 && (Handle -> RPort . TxFlags & FPF_PROPORTIONAL))
  5775.         {
  5776.             LTK_Rescale(Handle,FALSE,FALSE);
  5777.  
  5778.             Handle -> Rescaled = FALSE;
  5779.         }
  5780.  
  5781.         do
  5782.         {
  5783.             LTK_LayoutGroup(Handle,Handle -> TopGroup);
  5784.             LTK_PlaceGroups(Handle,Handle -> TopGroup,Left,Top);
  5785.  
  5786.             Fits = TRUE;
  5787.  
  5788.             if(Handle -> TopGroup -> Width + PlusWidth > Bounds -> Width)
  5789.             {
  5790.                 if(Handle -> TopGroup -> Width + PlusWidth > Handle -> Screen -> Width)
  5791.                 {
  5792.                     Fits = FALSE;
  5793.  
  5794.                     if(Handle -> TopGroup -> Height + PlusHeight > Bounds -> Height)
  5795.                     {
  5796.                         if(!LTK_Rescale(Handle,TRUE,TRUE))
  5797.                             Handle -> Failed = TRUE;
  5798.                     }
  5799.                     else
  5800.                     {
  5801.                         if(!LTK_Rescale(Handle,TRUE,FALSE))
  5802.                             Handle -> Failed = TRUE;
  5803.                     }
  5804.                 }
  5805.             }
  5806.             else
  5807.             {
  5808.                 if(Handle -> TopGroup -> Height + PlusHeight > Bounds -> Height)
  5809.                 {
  5810.                     if(Handle -> TopGroup -> Height + PlusHeight > Handle -> Screen -> Height)
  5811.                     {
  5812.                         Fits = FALSE;
  5813.  
  5814.                         if(!LTK_Rescale(Handle,FALSE,TRUE))
  5815.                             Handle -> Failed = TRUE;
  5816.                     }
  5817.                 }
  5818.             }
  5819.  
  5820. #ifdef DO_CLONING
  5821.             if(Handle -> Failed && !Cloned && Handle -> CloningPermitted)
  5822.             {
  5823.                 if(LTK_PrepareCloning(Handle))
  5824.                     Bounds = &Handle -> CloneExtra -> Bounds;
  5825.  
  5826.                 Cloned = TRUE;
  5827.             }
  5828. #endif
  5829.  
  5830.             if(Fits && !Handle -> Rescaled && !Cloned && !Handle -> Failed && Handle -> GrowView)
  5831.             {
  5832.                 LONG    Width    = Handle -> TopGroup -> Width + PlusWidth,
  5833.                     Height    = Handle -> TopGroup -> Height + PlusHeight;
  5834.  
  5835.                 if(Bounds -> Width > Width || Bounds -> Height > Height)
  5836.                 {
  5837.                     ObjectNode    *View = Handle -> GrowView;
  5838.                     LONG         PlusChars,
  5839.                              PlusLines;
  5840.  
  5841.                     if(View -> Special . List . MaxGrowX)
  5842.                     {
  5843.                         PlusChars = (Bounds -> Width - Width) / Handle -> GlyphWidth;
  5844.  
  5845.                         if(PlusChars > 0 && View -> Chars + PlusChars > View -> Special . List . MaxGrowX)
  5846.                             PlusChars = View -> Special . List . MaxGrowX - View -> Chars;
  5847.  
  5848.                         if(PlusChars < 0)
  5849.                             PlusChars = 0;
  5850.                     }
  5851.                     else
  5852.                         PlusChars = 0;
  5853.  
  5854.                     if(View -> Special . List . MaxGrowY)
  5855.                     {
  5856.                         PlusLines = (Bounds -> Height - Height) / Handle -> RPort . TxHeight;
  5857.  
  5858.                         if(PlusLines > 0 && View -> Lines + PlusLines > View -> Special . List . MaxGrowY)
  5859.                             PlusLines = View -> Special . List . MaxGrowY - View -> Lines;
  5860.  
  5861.                         if(PlusLines < 0)
  5862.                             PlusLines = 0;
  5863.                     }
  5864.                     else
  5865.                         PlusLines = 0;
  5866.  
  5867.                     if(PlusChars || PlusLines)
  5868.                     {
  5869.                         View -> Chars += PlusChars;
  5870.                         View -> Lines += PlusLines;
  5871.  
  5872.                         LTK_ResetGroups(Handle -> TopGroup);
  5873.  
  5874.                         if(!V39 && (Handle -> RPort . TxFlags & FPF_PROPORTIONAL))
  5875.                         {
  5876.                             LTK_Rescale(Handle,FALSE,FALSE);
  5877.  
  5878.                             Handle -> Rescaled = FALSE;
  5879.                         }
  5880.  
  5881.                         Fits = FALSE;
  5882.                     }
  5883.                 }
  5884.  
  5885.                 Handle -> GrowView = NULL;
  5886.             }
  5887.         }
  5888.         while(!Fits && !Handle -> Failed);
  5889.  
  5890. #ifdef DO_CLONING
  5891.         if(!Handle -> Failed && Cloned)
  5892.             LTK_CloneScreen(Handle,Handle -> TopGroup -> Width + PlusWidth,Handle -> TopGroup -> Height + PlusHeight);
  5893. #endif
  5894.  
  5895.         if(!Handle -> Failed)
  5896.         {
  5897.             if(Handle -> GadgetArray = LTK_Alloc(Handle,sizeof(struct Gadget *) * Handle -> Count))
  5898.             {
  5899. #ifdef DO_PICKSHORTCUTS
  5900.                 LTK_SearchKeys(Handle,Handle -> TopGroup);
  5901.                 LTK_SelectKeys(Handle,Handle -> TopGroup);
  5902. #endif
  5903.                 LTK_LayoutGadgets(Handle,Handle -> TopGroup);
  5904.  
  5905.                 if(Handle -> Failed)
  5906.                 {
  5907.                     FreeGadgets(Handle -> List);
  5908.  
  5909.                     Handle -> List = NULL;
  5910.                 }
  5911.             }
  5912.         }
  5913.     }
  5914. }
  5915.  
  5916.  
  5917. /*****************************************************************************/
  5918.  
  5919.  
  5920. STATIC VOID __regargs
  5921. LTK_PrintLabel(LayoutHandle *handle,ObjectNode *node,UWORD left,UWORD top)
  5922. {
  5923.     STRPTR    label;
  5924.     LONG    len;
  5925.  
  5926.     LTK_SetAPen(&handle -> RPort,handle -> TextPen);
  5927.  
  5928.     Move(&handle -> RPort,left - (node -> LabelWidth + INTERWIDTH),top + handle -> RPort . TxBaseline + 1);
  5929.  
  5930.     label = node -> Label;
  5931.  
  5932.     len = 0;
  5933.  
  5934.     while(label[len] && (label[len] != '_'))
  5935.         len++;
  5936.  
  5937.     LockLayerRom(handle -> RPort . Layer);
  5938.  
  5939.     if(len)
  5940.         Text(&handle -> RPort,label,len);
  5941.  
  5942.     if(label[len] == '_' && label[len + 1])
  5943.     {
  5944.         SetSoftStyle(&handle -> RPort,FSF_UNDERLINED,AskSoftStyle(&handle -> RPort));
  5945.         Text(&handle -> RPort,label + len + 1,1);
  5946.         SetSoftStyle(&handle -> RPort,FS_NORMAL,AskSoftStyle(&handle -> RPort));
  5947.  
  5948.         label += len + 2;
  5949.  
  5950.         if(len = strlen(label))
  5951.             Text(&handle -> RPort,label,len);
  5952.     }
  5953.  
  5954.     UnlockLayerRom(handle -> RPort . Layer);
  5955. }
  5956.  
  5957.  
  5958. /*****************************************************************************/
  5959.  
  5960. STATIC VOID __regargs
  5961. LTK_DrawGroup(LayoutHandle *Handle,ObjectNode *Group)
  5962. {
  5963.     ObjectNode    *Node;
  5964.     LONG         i;
  5965.     ULONG         page;
  5966.  
  5967.     if(Group -> Label)
  5968.         LTK_DrawLabel(Handle,Group);
  5969.  
  5970.     SCANPAGE(Group,Node,page)
  5971.     {
  5972.         switch(Node -> Type)
  5973.         {
  5974.             case BUTTON_KIND:
  5975.  
  5976.                 if(Handle -> ReturnKey == Node)
  5977.                     LTK_DrawBevelBox(Handle,Node);
  5978.  
  5979.                 break;
  5980. #ifdef DO_GAUGE_KIND
  5981.             case GAUGE_KIND:
  5982.             {
  5983.                 LONG Percent = Node -> Current;
  5984.  
  5985.                 Node -> Current = 0;
  5986.  
  5987.                 LTK_DrawGauge(Handle,Node,Percent,TRUE);
  5988.  
  5989.                 break;
  5990.             }
  5991. #endif
  5992.             case GROUP_KIND:
  5993.  
  5994.                 if(Node -> Label)
  5995.                     LTK_DrawLabel(Handle,Node);
  5996.  
  5997.                 LTK_DrawGroup(Handle,Node);
  5998.  
  5999.                 break;
  6000.  
  6001.             case XBAR_KIND:
  6002.             {
  6003.                 WORD Top = Node -> Top + ((Node -> Height + 1) / 2) - 1;
  6004.  
  6005.                 LockLayerRom(Handle -> RPort . Layer);
  6006.  
  6007.                 if(Node -> Special . Bar . FullSize)
  6008.                 {
  6009.                     LTK_SetAPen(&Handle -> RPort,Handle -> ShadowPen);
  6010.                     Move(&Handle -> RPort,Handle -> Window -> BorderLeft,Top);
  6011.                     Draw(&Handle -> RPort,Handle -> Window -> Width - (Handle -> Window -> BorderRight + 1),Top);
  6012.  
  6013.                     LTK_SetAPen(&Handle -> RPort,Handle -> ShinePen);
  6014.                     Move(&Handle -> RPort,Handle -> Window -> BorderLeft,Top + 1);
  6015.                     Draw(&Handle -> RPort,Handle -> Window -> Width - (Handle -> Window -> BorderRight + 1),Top + 1);
  6016.                 }
  6017.                 else
  6018.                 {
  6019.                     if(Node -> Special . Bar . Parent -> Label)
  6020.                     {
  6021.                         LTK_SetAPen(&Handle -> RPort,Handle -> ShadowPen);
  6022.                         Move(&Handle -> RPort,Node -> Special . Bar . Parent -> Left + 2 * Handle -> GlyphWidth,Top + 1);
  6023.                         Draw(&Handle -> RPort,Node -> Special . Bar . Parent -> Left + 2 * Handle -> GlyphWidth,Top);
  6024.                         Draw(&Handle -> RPort,Node -> Special . Bar . Parent -> Left + Node -> Special . Bar . Parent -> Width - (2 * Handle -> GlyphWidth + 1) - 1,Top);
  6025.  
  6026.                         LTK_SetAPen(&Handle -> RPort,Handle -> ShinePen);
  6027.                         Move(&Handle -> RPort,Node -> Special . Bar . Parent -> Left + 2 * Handle -> GlyphWidth + 1,Top + 1);
  6028.                         Draw(&Handle -> RPort,Node -> Special . Bar . Parent -> Left + Node -> Special . Bar . Parent -> Width - (2 * Handle -> GlyphWidth + 1),Top + 1);
  6029.                         Draw(&Handle -> RPort,Node -> Special . Bar . Parent -> Left + Node -> Special . Bar . Parent -> Width - (2 * Handle -> GlyphWidth + 1),Top);
  6030.                     }
  6031.                     else
  6032.                     {
  6033.                         LTK_SetAPen(&Handle -> RPort,Handle -> ShadowPen);
  6034.                         Move(&Handle -> RPort,Node -> Special . Bar . Parent -> Left,Top + 1);
  6035.                         Draw(&Handle -> RPort,Node -> Special . Bar . Parent -> Left,Top);
  6036.                         Draw(&Handle -> RPort,Node -> Special . Bar . Parent -> Left + Node -> Special . Bar . Parent -> Width - 1,Top);
  6037.  
  6038.                         LTK_SetAPen(&Handle -> RPort,Handle -> ShinePen);
  6039.                         Move(&Handle -> RPort,Node -> Special . Bar . Parent -> Left + 1,Top + 1);
  6040.                         Draw(&Handle -> RPort,Node -> Special . Bar . Parent -> Left + Node -> Special . Bar . Parent -> Width - 1,Top + 1);
  6041.                         Draw(&Handle -> RPort,Node -> Special . Bar . Parent -> Left + Node -> Special . Bar . Parent -> Width - 1,Top);
  6042.                     }
  6043.                 }
  6044.  
  6045.                 UnlockLayerRom(Handle -> RPort . Layer);
  6046.  
  6047.                 break;
  6048.             }
  6049.  
  6050.             case YBAR_KIND:
  6051.             {
  6052.                 WORD Left = Node -> Left + ((Node -> Width + 1) / 2) - 1;
  6053.  
  6054.                 LockLayerRom(Handle -> RPort . Layer);
  6055.  
  6056.                 if(Node -> Special . Bar . Parent -> Label)
  6057.                 {
  6058.                     LTK_SetAPen(&Handle -> RPort,Handle -> ShadowPen);
  6059.                     Move(&Handle -> RPort,Left + 1,Node -> Special . Bar . Parent -> Top + Handle -> RPort . TxHeight + Handle -> InterHeight);
  6060.                     Draw(&Handle -> RPort,Left,Node -> Special . Bar . Parent -> Top + Handle -> RPort . TxHeight + Handle -> InterHeight);
  6061.                     Draw(&Handle -> RPort,Left,Node -> Special . Bar . Parent -> Top + Node -> Special . Bar . Parent -> Height - (Handle -> RPort . TxHeight + Handle -> InterHeight + 1) - 1);
  6062.  
  6063.                     LTK_SetAPen(&Handle -> RPort,Handle -> ShinePen);
  6064.                     Move(&Handle -> RPort,Left + 1,Node -> Special . Bar . Parent -> Top + Handle -> RPort . TxHeight + Handle -> InterHeight + 1);
  6065.                     Draw(&Handle -> RPort,Left + 1,Node -> Special . Bar . Parent -> Top + Node -> Special . Bar . Parent -> Height - (Handle -> RPort . TxHeight + Handle -> InterHeight + 1));
  6066.                     Draw(&Handle -> RPort,Left,Node -> Special . Bar . Parent -> Top + Node -> Special . Bar . Parent -> Height - (Handle -> RPort . TxHeight + Handle -> InterHeight + 1));
  6067.                 }
  6068.                 else
  6069.                 {
  6070.                     LTK_SetAPen(&Handle -> RPort,Handle -> ShadowPen);
  6071.                     Move(&Handle -> RPort,Left + 1,Node -> Special . Bar . Parent -> Top);
  6072.                     Draw(&Handle -> RPort,Left,Node -> Special . Bar . Parent -> Top);
  6073.                     Draw(&Handle -> RPort,Left,Node -> Special . Bar . Parent -> Top + Node -> Special . Bar . Parent -> Height - 1 - 1);
  6074.  
  6075.                     LTK_SetAPen(&Handle -> RPort,Handle -> ShinePen);
  6076.                     Move(&Handle -> RPort,Left + 1,Node -> Special . Bar . Parent -> Top + 1);
  6077.                     Draw(&Handle -> RPort,Left + 1,Node -> Special . Bar . Parent -> Top + Node -> Special . Bar . Parent -> Height - 1);
  6078.                     Draw(&Handle -> RPort,Left,Node -> Special . Bar . Parent -> Top + Node -> Special . Bar . Parent -> Height - 1);
  6079.                 }
  6080.  
  6081.                 UnlockLayerRom(Handle -> RPort . Layer);
  6082.  
  6083.                 break;
  6084.             }
  6085.  
  6086.             case FRAME_KIND:
  6087.  
  6088.                 if(Node -> Special . Frame . DrawBox)
  6089.                     LTK_DrawBevelBox(Handle,Node);
  6090.  
  6091.                 // FALL THROUGH TO...
  6092.  
  6093.             case TAPEDECK_KIND:
  6094.  
  6095.                 if(Node -> Label)
  6096.                 {
  6097.                     LTK_SetPens(&Handle -> RPort,Handle -> TextPen,Handle -> BackgroundPen,JAM2);
  6098.  
  6099.                     switch(Node -> LabelPlace)
  6100.                     {
  6101.                         case PLACE_LEFT:
  6102.  
  6103.                             LTK_PlaceText(Handle,Node -> Label,strlen(Node -> Label),Node -> Left - (Node -> LabelWidth + INTERWIDTH),Node -> Top + (Node -> Height - Handle -> RPort . TxHeight) / 2 + Handle -> RPort . TxBaseline);
  6104.                             break;
  6105.  
  6106.                         case PLACE_RIGHT:
  6107.  
  6108.                             LTK_PlaceText(Handle,Node -> Label,strlen(Node -> Label),Node -> Left + Node -> Width + INTERWIDTH,Node -> Top + (Node -> Height - Handle -> RPort . TxHeight) / 2 + Handle -> RPort . TxBaseline);
  6109.                             break;
  6110.  
  6111.                         case PLACE_ABOVE:
  6112.  
  6113.                             LTK_PlaceText(Handle,Node -> Label,strlen(Node -> Label),Node -> Left + (Node -> Width - Node -> LabelWidth) / 2,Node -> Top - (Handle -> RPort . TxHeight + INTERHEIGHT) + Handle -> RPort . TxBaseline);
  6114.                             break;
  6115.  
  6116.                         case PLACE_BELOW:
  6117.  
  6118.                             LTK_PlaceText(Handle,Node -> Label,strlen(Node -> Label),Node -> Left + (Node -> Width - Node -> LabelWidth) / 2,Node -> Top + Node -> Height + INTERHEIGHT + Handle -> RPort . TxBaseline);
  6119.                             break;
  6120.                     }
  6121.                 }
  6122.  
  6123.                 break;
  6124.  
  6125.             case MX_KIND:
  6126.  
  6127.                 if(Node -> Label && !V39)
  6128.                     LTK_PrintLabel(Handle,Node,Node -> Left,Node -> Top + (Node -> Height - Handle -> RPort . TxHeight) / 2);
  6129.  
  6130.                 break;
  6131.  
  6132.             case LISTVIEW_KIND:
  6133.  
  6134.                 if(Node -> Special . List . ExtraLabels)
  6135.                 {
  6136.                     LockLayerRom(Handle -> RPort . Layer);
  6137.  
  6138.                     LTK_SetPens(&Handle -> RPort,Handle -> TextPen,Handle -> BackgroundPen,JAM2);
  6139.  
  6140.                     for(i = 0 ; Node -> Special . List . ExtraLabels[i] ; i++)
  6141.                     {
  6142.                         LONG Len = strlen(Node -> Special . List . ExtraLabels[i]);
  6143.  
  6144.                         LTK_PlaceText(Handle,Node -> Special . List . ExtraLabels[i],Len,Node -> Left - (TextLength(&Handle -> RPort,Node -> Special . List . ExtraLabels[i],Len) + INTERWIDTH),Node -> Top + 2 + i * Handle -> RPort . TxHeight + Handle -> RPort . TxBaseline);
  6145.                     }
  6146.  
  6147.                     UnlockLayerRom(Handle -> RPort . Layer);
  6148.                 }
  6149.  
  6150.                 break;
  6151.  
  6152.             case BOX_KIND:
  6153.  
  6154.                 if(Node -> Special . Box . DrawBox)
  6155.                     LTK_DrawBevelBox(Handle,Node);
  6156.  
  6157.                 LockLayerRom(Handle -> RPort . Layer);
  6158.  
  6159.                 for(i = 0 ; i < Node -> Lines ; i++)
  6160.                 {
  6161.                     if(Node -> Special . Box . Labels && Node -> Special . Box . Labels[i])
  6162.                     {
  6163.                         LONG Len = strlen(Node -> Special . Box . Labels[i]);
  6164.  
  6165.                         LTK_SetPens(&Handle -> RPort,Handle -> TextPen,Handle -> BackgroundPen,JAM2);
  6166.                         LTK_PlaceText(Handle,Node -> Special . Box . Labels[i],Len,Node -> Left - (TextLength(&Handle -> RPort,Node -> Special . Box . Labels[i],Len) + INTERWIDTH),Node -> Top + 2 + i * Handle -> RPort . TxHeight + Handle -> RPort . TxBaseline);
  6167.                     }
  6168.  
  6169.                     LTK_PrintBoxLine(Handle,Node,i);
  6170.                 }
  6171.  
  6172.                 UnlockLayerRom(Handle -> RPort . Layer);
  6173.  
  6174.                 break;
  6175.         }
  6176.     }
  6177. }
  6178.  
  6179.  
  6180. /*****************************************************************************/
  6181.  
  6182.  
  6183. STATIC LONG __stdargs
  6184. DefaultDispFunc(struct Gadget *gad,WORD value)
  6185. {
  6186.     return(value);
  6187. }
  6188.  
  6189.  
  6190. VOID LIBENT
  6191. LT_LevelWidth(REG(a0) LayoutHandle *handle,REG(a1) STRPTR levelFormat,REG(a2) DISPFUNC dispFunc,REG(d0) LONG min,REG(d1) LONG max,REG(a3) LONG *maxWidth,REG(a5) LONG *maxLen,REG(d2) BOOL fullCheck)
  6192. {
  6193.     UBYTE    buffer[80];
  6194.     LONG    localMaxWidth;
  6195.     LONG    localMaxLen;
  6196.     LONG    len;
  6197.  
  6198.     localMaxWidth    = 0;
  6199.     localMaxLen    = 0;
  6200.  
  6201.     if(handle)
  6202.     {
  6203.         if(!dispFunc)
  6204.             dispFunc = DefaultDispFunc;
  6205.  
  6206.         if(!levelFormat)
  6207.             levelFormat = "%ld";
  6208.  
  6209.         if(fullCheck)
  6210.         {
  6211.             LONG i;
  6212.  
  6213.             for(i = min ; i <= max ; i++)
  6214.             {
  6215.                 sprintf(buffer,levelFormat,(*dispFunc)(NULL,i));
  6216.  
  6217.                 len = strlen(buffer);
  6218.  
  6219.                 if(len > localMaxLen)
  6220.                     localMaxLen = len;
  6221.  
  6222.                 len = TextLength(&handle -> RPort,buffer,len);
  6223.  
  6224.                 if(len > localMaxWidth)
  6225.                     localMaxWidth = len;
  6226.             }
  6227.         }
  6228.         else
  6229.         {
  6230.             sprintf(buffer,levelFormat,(*dispFunc)(NULL,min));
  6231.  
  6232.             len = strlen(buffer);
  6233.  
  6234.             if(len > localMaxLen)
  6235.                 localMaxLen = len;
  6236.  
  6237.             len = TextLength(&handle -> RPort,buffer,len);
  6238.  
  6239.             if(len > localMaxWidth)
  6240.                 localMaxWidth = len;
  6241.  
  6242.             sprintf(buffer,levelFormat,(*dispFunc)(NULL,max));
  6243.  
  6244.             len = strlen(buffer);
  6245.  
  6246.             if(len > localMaxLen)
  6247.                 localMaxLen = len;
  6248.  
  6249.             len = TextLength(&handle -> RPort,buffer,len);
  6250.  
  6251.             if(len > localMaxWidth)
  6252.                 localMaxWidth = len;
  6253.         }
  6254.     }
  6255.  
  6256.     if(maxLen)
  6257.         *maxLen = localMaxLen;
  6258.  
  6259.     if(maxWidth)
  6260.         *maxWidth = localMaxWidth + handle -> GlyphWidth;
  6261. }
  6262.  
  6263.  
  6264. /*****************************************************************************/
  6265.  
  6266.  
  6267. VOID LIBENT
  6268. LT_DeleteHandle(REG(a0) LayoutHandle *Handle)
  6269. {
  6270.     if(Handle)
  6271.     {
  6272.         UnlockPubScreen(NULL,Handle -> PubScreen);
  6273. #ifdef DO_CLONING
  6274.         if(Handle -> CloneExtra)
  6275.         {
  6276.             if(Handle -> CloneExtra -> Screen)
  6277.                 ScreenToBack(Handle -> CloneExtra -> Screen);
  6278.         }
  6279. #endif
  6280.         if(Handle -> List)
  6281.         {
  6282.             struct Gadget    *Gadget;
  6283.             ObjectNode    *Node;
  6284.  
  6285.             if(Handle -> Window)
  6286.                 RemoveGList(Handle -> Window,Handle -> List,(UWORD)-1);
  6287.  
  6288.             Gadget = Handle -> List;
  6289.  
  6290.             while(Gadget)
  6291.             {
  6292.                 if(GETOBJECT(Gadget,Node))
  6293.                     LTK_DeleteObjectNode(Handle,Node);
  6294.  
  6295.                 Gadget = Gadget -> NextGadget;
  6296.             }
  6297.  
  6298.             FreeGadgets(Handle -> List);
  6299.         }
  6300.  
  6301.         if(Handle -> Parent)
  6302.             LT_UnlockWindow(Handle -> Parent);
  6303.  
  6304.         if(Handle -> Window)
  6305.         {
  6306.             LT_DeleteWindowLock(Handle -> Window);
  6307.  
  6308.             if(Handle -> MsgPort && Handle -> Window -> UserPort)
  6309.             {
  6310.                 struct IntuiMessage    *intuiMsg;
  6311.                 struct Node        *next;
  6312.  
  6313.                 Forbid();
  6314.  
  6315.                 intuiMsg = (struct IntuiMessage *)Handle -> Window -> UserPort -> mp_MsgList . lh_Head;
  6316.  
  6317.                 while(next = intuiMsg -> ExecMessage . mn_Node . ln_Succ)
  6318.                 {
  6319.                     if(intuiMsg -> IDCMPWindow == Handle -> Window)
  6320.                     {
  6321.                         Remove(intuiMsg);
  6322.  
  6323.                         ReplyMsg(intuiMsg);
  6324.                     }
  6325.  
  6326.                     intuiMsg = (struct IntuiMessage *)next;
  6327.                 }
  6328.  
  6329.                 Handle -> Window -> UserPort = NULL;
  6330.  
  6331.                 ModifyIDCMP(Handle -> Window,NULL);
  6332.  
  6333.                 Permit();
  6334.             }
  6335.  
  6336.             ClearMenuStrip(Handle -> Window);
  6337.             CloseWindow(Handle -> Window);
  6338.         }
  6339.  
  6340.         DisposeObject(Handle -> AmigaGlyph);
  6341.         DisposeObject(Handle -> CheckGlyph);
  6342.  
  6343.         FreeScreenDrawInfo(Handle -> Screen,Handle -> DrawInfo);
  6344.  
  6345.         FreeVisualInfo(Handle -> VisualInfo);
  6346.  
  6347.         if(Handle -> RPort . Font && Handle -> CloseFont)
  6348.             CloseFont(Handle -> RPort . Font);
  6349. #ifdef DO_CLONING
  6350.         if(Handle -> CloneExtra)
  6351.         {
  6352.             if(Handle -> CloneExtra -> Screen)
  6353.                 CloseScreen(Handle -> CloneExtra -> Screen);
  6354.         }
  6355. #endif
  6356.         if(Handle -> Pool)
  6357.             AsmDeletePool(Handle -> Pool,SysBase);
  6358.  
  6359.         if(Handle -> TimeRequest . tr_node . io_Device)
  6360.             CloseDevice(&Handle -> TimeRequest);
  6361.  
  6362.         FreeMem(Handle,sizeof(LayoutHandle));
  6363.     }
  6364. }
  6365.  
  6366.  
  6367. /*****************************************************************************/
  6368.  
  6369. LayoutHandle * LIBENT
  6370. LT_CreateHandle(REG(a0) struct Screen *Screen,REG(a1) struct TextAttr *Font)
  6371. {
  6372.     return(LT_CreateHandleTags(Screen,
  6373.         LH_Font,    Font,
  6374.     TAG_DONE));
  6375. }
  6376.  
  6377. LayoutHandle * __stdargs
  6378. LT_CreateHandleTags(struct Screen *Screen,...)
  6379. {
  6380.     LayoutHandle    *Handle;
  6381.     va_list         VarArgs;
  6382.  
  6383.     va_start(VarArgs,Screen);
  6384.     Handle = LT_CreateHandleTagList(Screen,(struct TagItem *)VarArgs);
  6385.     va_end(VarArgs);
  6386.  
  6387.     return(Handle);
  6388. }
  6389.  
  6390. LayoutHandle * LIBENT
  6391. LT_CreateHandleTagList(REG(a0) struct Screen *Screen,REG(a1) struct TagItem *TagList)
  6392. {
  6393.     LayoutHandle    *Handle;
  6394.     struct Screen    *PubScreen;
  6395.     struct TextAttr    *textAttr;
  6396.  
  6397. #ifdef DO_PICKSHORTCUTS
  6398.     ObtainSemaphore(<K_KeySemaphore);
  6399.  
  6400.     if(!LTK_KeysInitialized)
  6401.     {
  6402.         UBYTE             mapBuffer[2 * 3];
  6403.         UBYTE             remapBuffer[10];
  6404.         LONG              i;
  6405.         struct InputEvent event;
  6406.  
  6407.         for(i = 0 ; i < 256; i++)
  6408.         {
  6409.             if((i > ' ' && i < 127) || i > 160)
  6410.             {
  6411.                 remapBuffer[0] = i;
  6412.                 remapBuffer[1] = 0;
  6413.  
  6414.                 if(MapANSI(remapBuffer,1,mapBuffer,3,NULL) == 1)
  6415.                 {
  6416.                     if(!(mapBuffer[1] & ~QUALIFIER_SHIFT))
  6417.                     {
  6418.                         event . ie_NextEvent        = NULL;
  6419.                         event . ie_Class        = IECLASS_RAWKEY;
  6420.                         event . ie_SubClass        = 0;
  6421.                         event . ie_Code            = mapBuffer[0];
  6422.                         event . ie_Qualifier        = mapBuffer[1] & ~QUALIFIER_SHIFT;
  6423.                         event . ie_position . ie_addr    = NULL;
  6424.  
  6425.                         if(MapRawKey(&event,remapBuffer,10,NULL) == 1)
  6426.                             LTK_Keys[0][i] = remapBuffer[0];
  6427.  
  6428.                         event . ie_NextEvent        = NULL;
  6429.                         event . ie_Class        = IECLASS_RAWKEY;
  6430.                         event . ie_SubClass        = 0;
  6431.                         event . ie_Code            = mapBuffer[0];
  6432.                         event . ie_Qualifier        = mapBuffer[1] | QUALIFIER_SHIFT;
  6433.                         event . ie_position . ie_addr    = NULL;
  6434.  
  6435.                         if(MapRawKey(&event,remapBuffer,10,NULL) == 1)
  6436.                             LTK_Keys[1][i] = remapBuffer[0];
  6437.                     }
  6438.                 }
  6439.             }
  6440.         }
  6441.  
  6442.         LTK_KeysInitialized = TRUE;
  6443.     }
  6444.  
  6445.     ReleaseSemaphore(<K_KeySemaphore);
  6446. #endif     /* DO_PICKSHORTCUTS */
  6447.  
  6448.     textAttr = (struct TextAttr *)GetTagData(LH_Font,NULL,TagList);
  6449.  
  6450.     if(!Screen)
  6451.     {
  6452.         if(!(PubScreen = LockPubScreen(NULL)))
  6453.             return(NULL);
  6454.         else
  6455.             Screen = PubScreen;
  6456.     }
  6457.     else
  6458.         PubScreen = NULL;
  6459.  
  6460.     if(Handle = AllocMem(sizeof(LayoutHandle),MEMF_ANY | MEMF_PUBLIC | MEMF_CLEAR))
  6461.     {
  6462.         Handle -> Screen    = Screen;
  6463.         Handle -> PubScreen    = PubScreen;
  6464.         Handle -> AutoActivate    = GetTagData(LH_AutoActivate,FALSE,TagList);
  6465.         Handle -> LocaleHook    = (struct Hook *)GetTagData(LH_LocaleHook,NULL,TagList);
  6466.  
  6467.         Handle -> Parent    = (struct Window *)GetTagData(LH_Parent,NULL,TagList);
  6468.         Handle -> BlockParent    = GetTagData(LH_BlockParent,FALSE,TagList);
  6469.  
  6470. #ifdef DO_CLONING
  6471.         Handle -> CloningPermitted    = GetTagData(LH_CloningPermitted,TRUE,TagList);
  6472.         Handle -> ExactClone        = GetTagData(LH_ExactClone,FALSE,TagList);
  6473. #endif
  6474.  
  6475. #ifdef DO_FRACTION_KIND
  6476.         Handle -> FracEditHook . h_Entry    = (HOOKFUNC)LTK_FracEditRoutine;
  6477.         Handle -> FracEditHook . h_Data        = Handle;
  6478. #endif
  6479.  
  6480. #ifdef DO_PASSWORD_KIND
  6481.         Handle -> PasswordEditHook . h_Entry    = (HOOKFUNC)LTK_PasswordEditRoutine;
  6482.         Handle -> PasswordEditHook . h_Data    = Handle;
  6483. #endif
  6484.  
  6485.         Handle -> DefaultEditHook . h_Entry    = (HOOKFUNC)LTK_DefaultEditRoutine;
  6486.         Handle -> DefaultEditHook . h_Data    = Handle;
  6487.  
  6488.         Handle -> BackfillHook . h_Entry    = (HOOKFUNC)LTK_BackfillRoutine;
  6489.         Handle -> BackfillHook . h_Data        = Handle;
  6490.  
  6491.         Handle -> StandardEditHook = (struct Hook *)GetTagData(LH_EditHook,(ULONG)&Handle -> DefaultEditHook,TagList);
  6492.  
  6493. #ifdef DO_HEXHOOK
  6494.         Handle -> HexEditHook . h_Entry        = (HOOKFUNC)LTK_HexEditRoutine;
  6495.         Handle -> HexEditHook . h_Data        = Handle;
  6496. #endif
  6497.         if(Handle -> Pool = AsmCreatePool(MEMF_PUBLIC | MEMF_ANY | MEMF_CLEAR,1024,1024,SysBase))
  6498.         {
  6499.             if(Handle -> DrawInfo = GetScreenDrawInfo(Screen))
  6500.             {
  6501.                 LONG i;
  6502.  
  6503.                 Handle -> TextPen    = Handle -> DrawInfo -> dri_Pens[TEXTPEN];
  6504.                 Handle -> BackgroundPen    = Handle -> DrawInfo -> dri_Pens[BACKGROUNDPEN];
  6505.                 Handle -> ShinePen    = Handle -> DrawInfo -> dri_Pens[SHINEPEN];
  6506.                 Handle -> ShadowPen    = Handle -> DrawInfo -> dri_Pens[SHADOWPEN];
  6507.                 Handle -> AspectX    = Handle -> DrawInfo -> dri_Resolution . X;
  6508.                 Handle -> AspectY    = Handle -> DrawInfo -> dri_Resolution . Y;
  6509.  
  6510.                 if(V39 && FindTagItem(LH_MenuGlyphs,TagList))
  6511.                 {
  6512.                     LONG Size,FontHeight = Handle -> DrawInfo -> dri_Font -> tf_Baseline + 2;
  6513.  
  6514.                     if(Screen -> Flags & SCREENHIRES)
  6515.                         Size = SYSISIZE_MEDRES;
  6516.                     else
  6517.                         Size = SYSISIZE_LOWRES;
  6518.  
  6519.                     if(Handle -> AmigaGlyph = NewObject(NULL,SYSICLASS,
  6520.                         SYSIA_DrawInfo,    Handle -> DrawInfo,
  6521.                         SYSIA_Size,    Size,
  6522.                         SYSIA_Which,    AMIGAKEY,
  6523.                         IA_Left,    0,
  6524.                         LA_Top,        0,
  6525.                         IA_Width,    (FontHeight * 3 * Handle -> AspectY) / (2 * Handle -> AspectX),
  6526.                         IA_Height,    FontHeight,
  6527.                     TAG_DONE))
  6528.                     {
  6529.                         if(!(Handle -> CheckGlyph = NewObject(NULL,SYSICLASS,
  6530.                             SYSIA_DrawInfo,    Handle -> DrawInfo,
  6531.                             SYSIA_Size,    Size,
  6532.                             SYSIA_Which,    MENUCHECK,
  6533.                             IA_Left,    0,
  6534.                             LA_Top,        0,
  6535.                             IA_Width,    (FontHeight * Handle -> AspectY) / Handle -> AspectX,
  6536.                             IA_Height,    FontHeight,
  6537.                         TAG_DONE)))
  6538.                         {
  6539.                             DisposeObject(Handle -> AmigaGlyph);
  6540.  
  6541.                             Handle -> AmigaGlyph = NULL;
  6542.                         }
  6543.                     }
  6544.                 }
  6545.  
  6546.                 for(i = 0 ; i < Handle -> DrawInfo -> dri_NumPens ; i++)
  6547.                 {
  6548.                     if(Handle -> DrawInfo -> dri_Pens[i] > Handle -> MaxPen)
  6549.                         Handle -> MaxPen = Handle -> DrawInfo -> dri_Pens[i];
  6550.                 }
  6551.  
  6552.                 if(Handle -> VisualInfo = GetVisualInfoA(Screen,NULL))
  6553.                 {
  6554.                     if(textAttr)
  6555.                         Handle -> InitialTextAttr = textAttr;
  6556.  
  6557.                     InitRastPort(&Handle -> RPort);
  6558.  
  6559.                     if(LTK_GlyphSetup(Handle,textAttr))
  6560.                     {
  6561. #ifdef DO_PICKSHORTCUTS
  6562.                         memset(Handle -> Keys,TRUE,256);
  6563.  
  6564.                         for(i = 0 ; i < 256 ; i++)
  6565.                         {
  6566.                             if(i != 32 && i != 160)
  6567.                             {
  6568.                                 if(LTK_Keys[0][i])
  6569.                                     Handle -> Keys[LTK_Keys[0][i]] = FALSE;
  6570.  
  6571.                                 if(LTK_Keys[1][i])
  6572.                                     Handle -> Keys[LTK_Keys[1][i]] = FALSE;
  6573.                             }
  6574.                         }
  6575. #endif
  6576.                         Handle -> TimePort . mp_Flags    = PA_SIGNAL;
  6577.                         Handle -> TimePort . mp_SigBit    = SIGB_SINGLE;
  6578.                         Handle -> TimePort . mp_SigTask    = SysBase -> ThisTask;
  6579.  
  6580.                         NewList((struct MinList *)&Handle -> TimePort . mp_MsgList);
  6581.  
  6582.                         Handle -> TimeRequest . tr_node . io_Message . mn_ReplyPort    = &Handle -> TimePort;
  6583.                         Handle -> TimeRequest . tr_node . io_Message . mn_Length    = sizeof(struct timerequest);
  6584.  
  6585.                         OpenDevice(TIMERNAME,UNIT_VBLANK,&Handle -> TimeRequest,NULL);
  6586.  
  6587.                         return(Handle);
  6588.                     }
  6589.                 }
  6590.             }
  6591.         }
  6592.  
  6593.         LT_DeleteHandle(Handle);
  6594.     }
  6595.     else
  6596.         UnlockPubScreen(NULL,PubScreen);
  6597.  
  6598.     return(NULL);
  6599. }
  6600.  
  6601.  
  6602. /*****************************************************************************/
  6603.  
  6604.  
  6605. STATIC VOID __regargs
  6606. LTK_AddGadgets(LayoutHandle *handle)
  6607. {
  6608.     if(handle)
  6609.     {
  6610.         AddGList(handle -> Window,handle -> List,(UWORD)-1,(UWORD)-1,NULL);
  6611.         RefreshGList(handle -> List,handle -> Window,NULL,(UWORD)-1);
  6612.  
  6613.         GT_RefreshWindow(handle -> Window,NULL);
  6614.  
  6615.         LTK_DrawGroup(handle,handle -> TopGroup);
  6616.     }
  6617. }
  6618.  
  6619.  
  6620. /*****************************************************************************/
  6621.  
  6622.  
  6623. BOOL LIBENT
  6624. LT_Rebuild(REG(a0) LayoutHandle *handle,REG(a1) struct IBox *bounds,REG(a2) LONG extraWidth,REG(d0) LONG extraHeight,REG(d1) BOOL clear)
  6625. {
  6626.     if(handle)
  6627.     {
  6628.         struct Gadget    *gadget;
  6629.         ObjectNode    *node;
  6630.         LONG         left,top;
  6631.         struct IBox     newBounds;
  6632.         LONG         i;
  6633.  
  6634.         RemoveGList(handle -> Window,handle -> List,(UWORD)-1);
  6635.  
  6636.         gadget = handle -> List;
  6637.  
  6638.         while(gadget)
  6639.         {
  6640.             if(GETOBJECT(gadget,node))
  6641.             {
  6642.                 node -> Host = NULL;
  6643.  
  6644.                 switch(node -> Type)
  6645.                 {
  6646.                     case PICKER_KIND:
  6647.  
  6648.                         if(node -> Special . Picker . Image)
  6649.                         {
  6650.                             DisposeObject(node -> Special . Picker . Image);
  6651.  
  6652.                             node -> Special . Picker . Image = NULL;
  6653.                         }
  6654.  
  6655.                         break;
  6656.  
  6657.                     case TAPEDECK_KIND:
  6658.  
  6659.                         if(node -> Special . TapeDeck . ButtonImage)
  6660.                         {
  6661.                             DisposeObject(node -> Special . TapeDeck . ButtonImage);
  6662.  
  6663.                             node -> Special . TapeDeck . ButtonImage = NULL;
  6664.                         }
  6665.  
  6666.                         break;
  6667.  
  6668.                     case INCREMENTER_KIND:
  6669.  
  6670.                         if(node -> Special . Incrementer . Image)
  6671.                         {
  6672.                             DisposeObject(node -> Special . Incrementer . Image);
  6673.  
  6674.                             node -> Special . Incrementer . Image = NULL;
  6675.                         }
  6676.  
  6677.                         break;
  6678.  
  6679.                     case STRING_KIND:
  6680.  
  6681.                         node -> Special . String . Picker = NULL;
  6682.  
  6683.                         break;
  6684.  
  6685.                     case TEXT_KIND:
  6686.  
  6687.                         node -> Special . Text . Picker = NULL;
  6688.  
  6689.                         break;
  6690.  
  6691.                     case INTEGER_KIND:
  6692.  
  6693.                         node -> Special . Integer . LeftIncrementer = NULL;
  6694.                         node -> Special . Integer . RightIncrementer = NULL;
  6695.  
  6696.                         break;
  6697.                 }
  6698.             }
  6699.  
  6700.             gadget = gadget -> NextGadget;
  6701.         }
  6702.  
  6703.         FreeGadgets(handle -> List);
  6704.  
  6705.         handle -> List = NULL;
  6706.  
  6707.         LTK_Free(handle,handle -> GadgetArray,sizeof(struct Gadget *) * handle -> Count);
  6708.  
  6709.         handle -> GadgetArray = NULL;
  6710.  
  6711.         handle -> Count = handle -> Index = 0;
  6712.  
  6713.         LTK_ResetGroups(handle -> TopGroup);
  6714.  
  6715.         if(!bounds)
  6716.         {
  6717.             LTK_GetDisplayClip(handle -> Screen,&newBounds . Left,&newBounds . Top,&newBounds . Width,&newBounds . Height);
  6718.  
  6719.             bounds = &newBounds;
  6720.         }
  6721.  
  6722.         left    = handle -> Window -> BorderLeft + handle -> InterWidth;
  6723.         top    = handle -> Window -> BorderTop + handle -> InterHeight;
  6724.  
  6725.         LTK_CreateGadgets(handle,bounds,left,top,left + handle -> InterWidth + handle -> Screen -> WBorRight,top + handle -> InterHeight + handle -> Screen -> WBorBottom);
  6726.  
  6727.         if(handle -> Failed)
  6728.             return(FALSE);
  6729.  
  6730.         if(clear)
  6731.         {
  6732.             LTK_SetPens(&handle -> RPort,handle -> BackgroundPen,0,JAM1);
  6733.  
  6734.             RectFill(&handle -> RPort,handle -> Window -> BorderLeft,handle -> Window -> BorderTop,handle -> Window -> Width - (handle -> Window -> BorderRight + 1),handle -> Window -> Height - (handle -> Window -> BorderBottom + 1));
  6735.         }
  6736.  
  6737.         LTK_AddGadgets(handle);
  6738.  
  6739.         handle -> Previous = NULL;
  6740.  
  6741.         for(i = 0 ; i < handle -> Count ; i++)
  6742.         {
  6743.             if(handle -> GadgetArray[i])
  6744.             {
  6745.                 if(GETOBJECT(handle -> GadgetArray[i],node))
  6746.                 {
  6747.                     if(LIKE_STRING_KIND(node) || (node -> Type == INTEGER_KIND))
  6748.                     {
  6749.                         if(!handle -> Previous)
  6750.                             handle -> Previous = handle -> GadgetArray[i];
  6751.                     }
  6752.                 }
  6753.             }
  6754.         }
  6755.  
  6756.         return(TRUE);
  6757.     }
  6758.     else
  6759.         return(FALSE);
  6760. }
  6761.  
  6762.  
  6763. /*****************************************************************************/
  6764.  
  6765.  
  6766. VOID LIBENT
  6767. LT_HandleInput(REG(a0) LayoutHandle *Handle,REG(d0) ULONG MsgQualifier,REG(a1) ULONG *MsgClass,REG(a2) UWORD *MsgCode,REG(a3) struct Gadget **MsgGadget)
  6768. {
  6769.     ObjectNode    *Node;
  6770.     BOOLEAN         Activate = FALSE;
  6771.  
  6772.     if(!Handle)
  6773.         return;
  6774.  
  6775.     switch(*MsgClass)
  6776.     {
  6777.         case IDCMP_REFRESHWINDOW:
  6778.  
  6779.             if(Handle -> AutoRefresh)
  6780.             {
  6781.                 LT_BeginRefresh(Handle);
  6782.  
  6783.                 LT_EndRefresh(Handle,TRUE);
  6784.  
  6785.                 *MsgClass = NULL;
  6786.             }
  6787.  
  6788.             break;
  6789.  
  6790.         case IDCMP_INTUITICKS:
  6791.  
  6792.             if(Handle -> ActiveIncrementer)
  6793.             {
  6794.                 Handle -> IncrementerCountdown--;
  6795.  
  6796.                 if(Handle -> IncrementerCountdown <= 0)
  6797.                 {
  6798.                     if(Handle -> ActiveIncrementer -> Host -> Flags & GFLG_SELECTED)
  6799.                     {
  6800.                         struct ObjectNode    *Parent;
  6801.                         LONG             Number;
  6802.  
  6803.                         *MsgClass    = IDCMP_GADGETUP;
  6804.                         *MsgCode    = 0;
  6805.                         *MsgGadget    = Handle -> ActiveIncrementer -> Special . Incrementer . Parent;
  6806.  
  6807.                         Parent = (*MsgGadget) -> UserData;
  6808.  
  6809.                         if(Parent -> Special . Integer . IncrementerHook)
  6810.                             Number = CallHookPkt(Parent -> Special . Integer . IncrementerHook,(APTR)LT_GetAttributes(Handle,Parent -> ID,TAG_DONE),Handle -> ActiveIncrementer -> Special . Incrementer . Amount < 0 ? (APTR)INCREMENTERMSG_DECREMENT : (APTR)INCREMENTERMSG_INCREMENT);
  6811.                         else
  6812.                             Number = ((LONG)LT_GetAttributes(Handle,Parent -> ID,TAG_DONE)) + Handle -> ActiveIncrementer -> Special . Incrementer . Amount;
  6813.  
  6814.                         if(Number >= Parent -> Special . Integer . Min && Number <= Parent -> Special . Integer . Max)
  6815.                             LT_SetAttributes(Handle,Parent -> ID,GTIN_Number,Number,TAG_DONE);
  6816.                     }
  6817.  
  6818.                     Handle -> IncrementerCountdown = 2;
  6819.                 }
  6820.             }
  6821.  
  6822.             break;
  6823.  
  6824.         case IDCMP_RAWKEY:
  6825.         {
  6826.             UBYTE            Buffer[10],Key;
  6827.             struct InputEvent    event;
  6828.             BOOLEAN            KeyUp;
  6829.  
  6830.             if(*MsgCode == 95 && Handle -> HelpHook)
  6831.             {
  6832.                 ObjectNode    *Item;
  6833.                 struct HelpMsg     Message;
  6834.                 struct IBox     Box;
  6835.  
  6836.                 if(Item = LTK_FindNode_Position(Handle -> TopGroup,Handle -> Window -> MouseX,Handle -> Window -> MouseY))
  6837.                 {
  6838.                     Message . ObjectID = Item -> ID;
  6839.  
  6840.                     Box . Left    = Item -> Left;
  6841.                     Box . Top    = Item -> Top;
  6842.                     Box . Width    = Item -> Width;
  6843.                     Box . Height    = Item -> Height;
  6844.                 }
  6845.                 else
  6846.                 {
  6847.                     Message . ObjectID = -1;
  6848.  
  6849.                     Box . Left    = 0;
  6850.                     Box . Top    = 0;
  6851.                     Box . Width    = Handle -> Window -> Width;
  6852.                     Box . Height    = Handle -> Window -> Height;
  6853.                 }
  6854.  
  6855.                 Message . Handle = Handle;
  6856.  
  6857.                 CallHookPkt(Handle -> HelpHook,&Message,&Box);
  6858.  
  6859.                 *MsgClass = NULL;
  6860.  
  6861.                 break;
  6862.             }
  6863.  
  6864.             if((*MsgCode >= 99 && *MsgCode <= 103) || *MsgCode == 96 || *MsgCode == 97)
  6865.             {
  6866.                 *MsgClass = NULL;
  6867.  
  6868.                 break;
  6869.             }
  6870.  
  6871.             event . ie_NextEvent        = NULL;
  6872.             event . ie_Code            = (*MsgCode) & ~IECODE_UP_PREFIX;
  6873.             event . ie_Qualifier        = MsgQualifier & ~QUALIFIER_SHIFT;
  6874.             event . ie_Class        = IECLASS_RAWKEY;
  6875.             event . ie_SubClass        = 0;
  6876.             event . ie_position . ie_addr    = (APTR)*MsgGadget;
  6877.  
  6878.             Buffer[0] = 0;
  6879.  
  6880.             if(MapRawKey(&event,Buffer,9,NULL) < 1)
  6881.             {
  6882.                 *MsgClass = NULL;
  6883.  
  6884.                 break;
  6885.             }
  6886.  
  6887.             if(!(Key = Buffer[0]))
  6888.             {
  6889.                 *MsgClass = NULL;
  6890.  
  6891.                 break;
  6892.             }
  6893.  
  6894.             if((*MsgCode) & IECODE_UP_PREFIX)
  6895.                 KeyUp = TRUE;
  6896.             else
  6897.                 KeyUp = FALSE;
  6898.  
  6899.             if(!KeyUp && Handle -> CursorKey && (*MsgCode == CURSORUP || *MsgCode == CURSORDOWN))
  6900.             {
  6901.                 ObjectNode    *Node;
  6902.                 struct Gadget    *Gadget;
  6903.                 LONG         NewState;
  6904.  
  6905.                 Node        = Handle -> CursorKey;
  6906.                 Gadget        = Node -> Host;
  6907.                 NewState    = Node -> Current;
  6908.  
  6909.                 if(*MsgCode == CURSORDOWN)
  6910.                 {
  6911.                     if(MsgQualifier & QUALIFIER_SHIFT)
  6912.                         NewState += Node -> Lines;
  6913.                     else
  6914.                     {
  6915.                         if(MsgQualifier & (QUALIFIER_ALT | QUALIFIER_CONTROL))
  6916.                             NewState = Node -> Max;
  6917.                         else
  6918.                             NewState++;
  6919.                     }
  6920.                 }
  6921.                 else
  6922.                     {
  6923.                     if(MsgQualifier & QUALIFIER_SHIFT)
  6924.                         NewState -= Node -> Lines;
  6925.                     else
  6926.                     {
  6927.                         if(MsgQualifier & (QUALIFIER_ALT | QUALIFIER_CONTROL))
  6928.                             NewState = Node -> Min;
  6929.                         else
  6930.                             NewState--;
  6931.                     }
  6932.                 }
  6933.  
  6934.                 if(NewState < Node -> Min)
  6935.                     NewState = Node -> Min;
  6936.                 else
  6937.                 {
  6938.                     if(NewState > Node -> Max)
  6939.                         NewState = Node -> Max;
  6940.                 }
  6941.  
  6942.                 if(NewState != Node -> Current && Node -> Max != Node -> Min)
  6943.                 {
  6944.                     Node -> Current = NewState;
  6945.  
  6946.                     GT_SetGadgetAttrs(Gadget,Handle -> Window,NULL,
  6947.                         GTLV_Top,        Node -> Current,
  6948.                         GTLV_MakeVisible,    Node -> Current,
  6949.  
  6950.                         Node -> Special . List . LinkID != -1 ? GTLV_Selected : TAG_IGNORE,Node -> Current,
  6951.                     TAG_DONE);
  6952.  
  6953.                     LTK_PutStorage(Node);
  6954.  
  6955.                     *MsgClass    = IDCMP_GADGETUP;
  6956.                     *MsgCode    = Node -> Current;
  6957.                     *MsgGadget    = Gadget;
  6958.                         }
  6959.                         else
  6960.                     *MsgClass = NULL;
  6961.  
  6962.                 return;
  6963.             }
  6964.  
  6965.             if(Key == '\33' && !KeyUp)
  6966.             {
  6967.                 ObjectNode *Node;
  6968.  
  6969.                 if(Node = Handle -> EscKey)
  6970.                 {
  6971.                     if(!Node -> Disabled)
  6972.                     {
  6973.                         LTK_BlinkButton(Handle,Node -> Host);
  6974.  
  6975.                         *MsgCode    = 0;
  6976.                         *MsgGadget    = Node -> Host;
  6977.                         *MsgClass    = IDCMP_GADGETUP;
  6978.                     }
  6979.                     else
  6980.                         *MsgClass = NULL;
  6981.  
  6982.                     return;
  6983.                 }
  6984.  
  6985.                 if(Handle -> Window -> Flags & WFLG_CLOSEGADGET)
  6986.                 {
  6987.                     *MsgCode    = 0;
  6988.                     *MsgGadget    = NULL;
  6989.                     *MsgClass    = IDCMP_CLOSEWINDOW;
  6990.                 }
  6991.                 else
  6992.                     *MsgClass = NULL;
  6993.  
  6994.                 return;
  6995.             }
  6996.             else
  6997.             {
  6998.                 struct Gadget    *Gadget;
  6999.                 ObjectNode    *Node;
  7000.                 LONG         i;
  7001.                 BOOLEAN         FoundIt = FALSE,
  7002.                          Forward;
  7003.  
  7004.                 if(MsgQualifier & QUALIFIER_SHIFT)
  7005.                     Forward = FALSE;
  7006.                 else
  7007.                     Forward = TRUE;
  7008.  
  7009.                 if(Handle -> ReturnKey && Key == '\r')
  7010.                 {
  7011.                     Node = Handle -> ReturnKey;
  7012.  
  7013.                     if(!KeyUp && !Node -> Disabled)
  7014.                     {
  7015.                         LTK_BlinkButton(Handle,Node -> Host);
  7016.  
  7017.                         *MsgClass    = IDCMP_GADGETUP;
  7018.                         *MsgCode    = 0;
  7019.                         *MsgGadget    = Node -> Host;
  7020.                     }
  7021.                     else
  7022.                         *MsgClass = NULL;
  7023.  
  7024.                     return;
  7025.                 }
  7026.  
  7027.                 for(i = 0 ; !FoundIt && i < Handle -> Count ; i++)
  7028.                 {
  7029.                     if(Gadget = Handle -> GadgetArray[i])
  7030.                     {
  7031.                         if(GETOBJECT(Gadget,Node))
  7032.                         {
  7033.                             if(Key == Node -> Key)
  7034.                             {
  7035.                                 if(Node -> Disabled)
  7036.                                     break;
  7037.                                 else
  7038.                                 {
  7039.                                     switch(Node -> Type)
  7040.                                     {
  7041. #ifdef DO_TAPEDECK_KIND
  7042.                                         case TAPEDECK_KIND:
  7043.  
  7044.                                             if(!(MsgQualifier & IEQUALIFIER_REPEAT))
  7045.                                             {
  7046.                                                 if(Node -> Special . TapeDeck . Toggle)
  7047.                                                 {
  7048.                                                     LT_SetAttributes(Handle,Node -> ID,
  7049.                                                         LATD_Pressed,!Node -> Current,
  7050.                                                     TAG_DONE);
  7051.  
  7052.                                                     LTK_PutStorage(Node);
  7053.                                                 }
  7054.  
  7055.                                                 if(Gadget -> Flags & GFLG_SELECTED)
  7056.                                                     *MsgCode = TRUE;
  7057.                                                 else
  7058.                                                     *MsgCode = FALSE;
  7059.  
  7060.                                                 *MsgClass    = IDCMP_GADGETUP;
  7061.                                                 *MsgGadget    = Gadget;
  7062.                                             }
  7063.                                             else
  7064.                                                 *MsgClass = NULL;
  7065.  
  7066.                                             break;
  7067. #endif    /* DO_TAPEDECK_KIND */
  7068.                                         case CHECKBOX_KIND:
  7069.  
  7070.                                             if(!KeyUp && !(MsgQualifier & IEQUALIFIER_REPEAT))
  7071.                                             {
  7072.                                                 Node -> Current = !Node -> Current;
  7073.  
  7074.                                                 LTK_PutStorage(Node);
  7075.  
  7076.                                                 GT_SetGadgetAttrs(Gadget,Handle -> Window,NULL,
  7077.                                                     GTCB_Checked,Node -> Current,
  7078.                                                 TAG_DONE);
  7079.  
  7080.                                                 *MsgClass    = IDCMP_GADGETUP;
  7081.                                                 *MsgCode    = Node -> Current;
  7082.                                                 *MsgGadget    = Gadget;
  7083.                                             }
  7084.                                             else
  7085.                                                 *MsgClass = NULL;
  7086.  
  7087.                                             FoundIt = TRUE;
  7088.  
  7089.                                             break;
  7090.  
  7091.                                         case LISTVIEW_KIND:
  7092.  
  7093.                                             if(!KeyUp)
  7094.                                             {
  7095.                                                 BOOLEAN setAttrs = FALSE;
  7096.  
  7097.                                                 if(Forward)
  7098.                                                 {
  7099.                                                     if(Node -> Current < Node -> Max)
  7100.                                                     {
  7101.                                                         Node -> Current++;
  7102.  
  7103.                                                         setAttrs = TRUE;
  7104.                                                     }
  7105.                                                 }
  7106.                                                 else
  7107.                                                 {
  7108.                                                     if(Node -> Current > Node -> Min)
  7109.                                                     {
  7110.                                                         Node -> Current--;
  7111.  
  7112.                                                         setAttrs = TRUE;
  7113.                                                     }
  7114.                                                 }
  7115.  
  7116.                                                 if(setAttrs)
  7117.                                                 {
  7118.                                                     if(Node -> Current < 0)
  7119.                                                     {
  7120.                                                         GT_SetGadgetAttrs(Gadget,Handle -> Window,NULL,
  7121.                                                             GTLV_Selected,Node -> Current,
  7122.                                                         TAG_DONE);
  7123.                                                     }
  7124.                                                     else
  7125.                                                     {
  7126.                                                                                     GT_SetGadgetAttrs(Gadget,Handle -> Window,NULL,
  7127.                                                             GTLV_Top,        Node -> Current,
  7128.                                                             GTLV_MakeVisible,    Node -> Current,
  7129.                                                             Node -> Special . List . LinkID != -1 ? GTLV_Selected : TAG_IGNORE,Node -> Current,
  7130.                                                         TAG_DONE);
  7131.                                                     }
  7132.  
  7133.                                                     LTK_PutStorage(Node);
  7134.  
  7135.                                                     *MsgClass    = IDCMP_GADGETUP;
  7136.                                                     *MsgCode    = Node -> Current;
  7137.                                                     *MsgGadget    = Gadget;
  7138.                                                 }
  7139.                                                 else
  7140.                                                     *MsgClass = NULL;
  7141.                                             }
  7142.                                             else
  7143.                                                 *MsgClass = NULL;
  7144.  
  7145.                                             FoundIt = TRUE;
  7146.  
  7147.                                             break;
  7148.  
  7149.                                         case MX_KIND:
  7150.  
  7151.                                             if(!KeyUp)
  7152.                                             {
  7153.                                                 if(Forward)
  7154.                                                 {
  7155.                                                     if(Node -> Current < Node -> Max)
  7156.                                                     {
  7157.                                                         Node -> Current++;
  7158.  
  7159.                                                         GT_SetGadgetAttrs(Gadget,Handle -> Window,NULL,
  7160.                                                             GTMX_Active,Node -> Current,
  7161.                                                         TAG_DONE);
  7162.  
  7163.                                                         LTK_PutStorage(Node);
  7164.  
  7165.                                                         *MsgClass    = IDCMP_GADGETDOWN;
  7166.                                                         *MsgCode    = Node -> Current;
  7167.                                                         *MsgGadget    = Gadget;
  7168.                                                     }
  7169.                                                     else
  7170.                                                         *MsgClass = NULL;
  7171.                                                 }
  7172.                                                 else
  7173.                                                 {
  7174.                                                     if(Node -> Current > Node -> Min)
  7175.                                                     {
  7176.                                                         Node -> Current--;
  7177.  
  7178.                                                         GT_SetGadgetAttrs(Gadget,Handle -> Window,NULL,
  7179.                                                             GTMX_Active,Node -> Current,
  7180.                                                         TAG_DONE);
  7181.  
  7182.                                                         LTK_PutStorage(Node);
  7183.  
  7184.                                                         *MsgClass    = IDCMP_GADGETDOWN;
  7185.                                                         *MsgCode    = Node -> Current;
  7186.                                                         *MsgGadget    = Gadget;
  7187.                                                     }
  7188.                                                     else
  7189.                                                         *MsgClass = NULL;
  7190.                                                 }
  7191.                                             }
  7192.                                             else
  7193.                                                 *MsgClass = NULL;
  7194.  
  7195.                                             FoundIt = TRUE;
  7196.  
  7197.                                             break;
  7198.  
  7199.                                         case TEXT_KIND:
  7200.  
  7201.                                             if(!KeyUp && !(MsgQualifier & IEQUALIFIER_REPEAT))
  7202.                                             {
  7203.                                                 if(Node -> Special . Text . Picker)
  7204.                                                 {
  7205.                                                     LTK_BlinkButton(Handle,Node -> Special . Text . Picker);
  7206.  
  7207.                                                     *MsgClass    = IDCMP_IDCMPUPDATE;
  7208.                                                     *MsgCode    = 0;
  7209.                                                     *MsgGadget    = Gadget;
  7210.                                                 }
  7211.                                                 else
  7212.                                                     *MsgClass = NULL;
  7213.                                             }
  7214.                                             else
  7215.                                                 *MsgClass = NULL;
  7216.  
  7217.                                             FoundIt = TRUE;
  7218.  
  7219.                                             break;
  7220.  
  7221.                                         case NUMBER_KIND:
  7222.  
  7223.                                             *MsgClass = NULL;
  7224.  
  7225.                                             FoundIt = TRUE;
  7226.  
  7227.                                             break;
  7228.  
  7229.                                         case CYCLE_KIND:
  7230.  
  7231.                                             if(!KeyUp && !(MsgQualifier & IEQUALIFIER_REPEAT))
  7232.                                             {
  7233.                                                 LTK_BlinkButton(Handle,Gadget);
  7234.  
  7235.                                                 if(Forward)
  7236.                                                 {
  7237.                                                     if(Node -> Current < Node -> Max)
  7238.                                                         Node -> Current++;
  7239.                                                     else
  7240.                                                         Node -> Current = Node -> Min;
  7241.                                                 }
  7242.                                                 else
  7243.                                                 {
  7244.                                                     if(Node -> Current > Node -> Min)
  7245.                                                         Node -> Current--;
  7246.                                                     else
  7247.                                                         Node -> Current = Node -> Max;
  7248.                                                 }
  7249.  
  7250.                                                 LTK_PutStorage(Node);
  7251.  
  7252.                                                 GT_SetGadgetAttrs(Gadget,Handle -> Window,NULL,
  7253.                                                     GTCY_Active,Node -> Current,
  7254.                                                 TAG_DONE);
  7255.  
  7256.                                                 *MsgClass    = IDCMP_GADGETUP;
  7257.                                                 *MsgCode    = Node -> Current;
  7258.                                                 *MsgGadget    = Gadget;
  7259.                                             }
  7260.                                             else
  7261.                                                 *MsgClass = NULL;
  7262.  
  7263.                                             FoundIt = TRUE;
  7264.  
  7265.                                             break;
  7266.  
  7267.                                         case PALETTE_KIND:
  7268.  
  7269.                                             if(!KeyUp)
  7270.                                             {
  7271.                                                 if(Forward)
  7272.                                                 {
  7273.                                                     if(Node -> Current < Node -> Max)
  7274.                                                         Node -> Current++;
  7275.                                                     else
  7276.                                                         Node -> Current = Node -> Min;
  7277.                                                 }
  7278.                                                 else
  7279.                                                 {
  7280.                                                     if(Node -> Current > Node -> Min)
  7281.                                                         Node -> Current--;
  7282.                                                     else
  7283.                                                         Node -> Current = Node -> Max;
  7284.                                                 }
  7285.  
  7286.                                                 LTK_PutStorage(Node);
  7287.  
  7288.                                                 GT_SetGadgetAttrs(Gadget,Handle -> Window,NULL,
  7289.                                                     GTPA_Color,Node -> Current,
  7290.                                                 TAG_DONE);
  7291.  
  7292.                                                 *MsgClass    = IDCMP_GADGETUP;
  7293.                                                 *MsgCode    = Node -> Current;
  7294.                                                 *MsgGadget    = Gadget;
  7295.                                             }
  7296.                                             else
  7297.                                                 *MsgClass = NULL;
  7298.  
  7299.                                             FoundIt = TRUE;
  7300.  
  7301.                                             break;
  7302.  
  7303.                                         case SLIDER_KIND:
  7304.  
  7305.                                             if(KeyUp)
  7306.                                             {
  7307.                                                 *MsgClass    = IDCMP_GADGETUP;
  7308.                                                 *MsgCode    = Node -> Current;
  7309.                                                 *MsgGadget    = Gadget;
  7310.                                             }
  7311.                                             else
  7312.                                             {
  7313.                                                 if(Forward)
  7314.                                                 {
  7315.                                                     if(Node -> Current < Node -> Max)
  7316.                                                     {
  7317.                                                         Node -> Current++;
  7318.  
  7319.                                                         GT_SetGadgetAttrs(Gadget,Handle -> Window,NULL,
  7320.                                                             GTSL_Level,Node -> Current,
  7321.                                                         TAG_DONE);
  7322.  
  7323.                                                         LTK_PutStorage(Node);
  7324.  
  7325.                                                         *MsgClass    = IDCMP_MOUSEMOVE;
  7326.                                                         *MsgCode    = Node -> Current;
  7327.                                                         *MsgGadget    = Gadget;
  7328.                                                     }
  7329.                                                     else
  7330.                                                         *MsgClass = NULL;
  7331.                                                 }
  7332.                                                 else
  7333.                                                 {
  7334.                                                     if(Node -> Current > Node -> Min)
  7335.                                                     {
  7336.                                                         Node -> Current--;
  7337.  
  7338.                                                         GT_SetGadgetAttrs(Gadget,Handle -> Window,NULL,
  7339.                                                             GTSL_Level,Node -> Current,
  7340.                                                         TAG_DONE);
  7341.  
  7342.                                                         LTK_PutStorage(Node);
  7343.  
  7344.                                                         *MsgClass    = IDCMP_MOUSEMOVE;
  7345.                                                         *MsgCode    = Node -> Current;
  7346.                                                         *MsgGadget    = Gadget;
  7347.                                                     }
  7348.                                                     else
  7349.                                                         *MsgClass = NULL;
  7350.                                                 }
  7351.                                             }
  7352.  
  7353.                                             FoundIt = TRUE;
  7354.  
  7355.                                             break;
  7356.  
  7357.                                         case SCROLLER_KIND:
  7358.  
  7359.                                             if(KeyUp)
  7360.                                             {
  7361.                                                 *MsgClass    = IDCMP_GADGETUP;
  7362.                                                 *MsgCode    = Node -> Current;
  7363.                                                 *MsgGadget    = Gadget;
  7364.                                             }
  7365.                                             else
  7366.                                             {
  7367.                                                 if(Forward)
  7368.                                                 {
  7369.                                                     if(Node -> Current < Node -> Max)
  7370.                                                     {
  7371.                                                         Node -> Current++;
  7372.  
  7373.                                                         GT_SetGadgetAttrs(Gadget,Handle -> Window,NULL,
  7374.                                                             GTSC_Top,Node -> Current,
  7375.                                                         TAG_DONE);
  7376.  
  7377.                                                         LTK_PutStorage(Node);
  7378.  
  7379.                                                         *MsgClass    = IDCMP_MOUSEMOVE;
  7380.                                                         *MsgCode    = Node -> Current;
  7381.                                                         *MsgGadget    = Gadget;
  7382.                                                     }
  7383.                                                     else
  7384.                                                         *MsgClass = NULL;
  7385.                                                 }
  7386.                                                 else
  7387.                                                 {
  7388.                                                     if(Node -> Current > Node -> Min)
  7389.                                                     {
  7390.                                                         Node -> Current--;
  7391.  
  7392.                                                         GT_SetGadgetAttrs(Gadget,Handle -> Window,NULL,
  7393.                                                             GTSC_Top,Node -> Current,
  7394.                                                         TAG_DONE);
  7395.  
  7396.                                                         LTK_PutStorage(Node);
  7397.  
  7398.                                                         *MsgClass    = IDCMP_MOUSEMOVE;
  7399.                                                         *MsgCode    = Node -> Current;
  7400.                                                         *MsgGadget    = Gadget;
  7401.                                                     }
  7402.                                                     else
  7403.                                                         *MsgClass = NULL;
  7404.                                                 }
  7405.                                             }
  7406.  
  7407.                                             FoundIt = TRUE;
  7408.  
  7409.                                             break;
  7410.  
  7411.                                         case STRING_KIND:
  7412.                                         case FRACTION_KIND:
  7413.                                         case PASSWORD_KIND:
  7414.  
  7415.                                             if(!KeyUp)
  7416.                                             {
  7417.                                                 if(Node -> Special . String . Picker && !Forward)
  7418.                                                 {
  7419.                                                     LTK_BlinkButton(Handle,Node -> Special . String . Picker);
  7420.  
  7421.                                                     *MsgClass    = IDCMP_IDCMPUPDATE;
  7422.                                                     *MsgCode    = 0;
  7423.                                                     *MsgGadget    = Gadget;
  7424.                                                 }
  7425.                                                 else
  7426.                                                 {
  7427.                                                     ActivateGadget(Gadget,Handle -> Window,NULL);
  7428.  
  7429.                                                     *MsgClass    = IDCMP_GADGETDOWN;
  7430.                                                     *MsgCode    = 0;
  7431.                                                     *MsgGadget    = Gadget;
  7432.  
  7433.                                                     Handle -> Previous = Gadget;
  7434.                                                 }
  7435.                                             }
  7436.                                             else
  7437.                                                 *MsgClass = NULL;
  7438.  
  7439.                                             FoundIt = TRUE;
  7440.  
  7441.                                             break;
  7442.  
  7443.                                         case INTEGER_KIND :
  7444.  
  7445.                                             if(!KeyUp)
  7446.                                             {
  7447.                                                 if(Node -> Special . Integer . UseIncrementers)
  7448.                                                 {
  7449.                                                     ObjectNode    *incNode,*Parent = (ObjectNode *)Gadget -> UserData;
  7450.                                                     LONG         Number;
  7451.                                                     struct Gadget    *Incrementer;
  7452.  
  7453.                                                     if(Forward)
  7454.                                                     {
  7455.                                                         incNode = Node -> Special . Integer . RightIncrementer -> UserData;
  7456.  
  7457.                                                         Incrementer = Node -> Special . Integer . RightIncrementer;
  7458.                                                     }
  7459.                                                     else
  7460.                                                     {
  7461.                                                         incNode = Node -> Special . Integer . LeftIncrementer -> UserData;
  7462.  
  7463.                                                         Incrementer = Node -> Special . Integer . LeftIncrementer;
  7464.                                                     }
  7465.  
  7466.                                                     if(Parent -> Special . Integer . IncrementerHook)
  7467.                                                         Number = CallHookPkt(Parent -> Special . Integer . IncrementerHook,(APTR)LT_GetAttributes(Handle,Parent -> ID,TAG_DONE),incNode -> Special . Incrementer . Amount < 0 ? (APTR)INCREMENTERMSG_DECREMENT : (APTR)INCREMENTERMSG_INCREMENT);
  7468.                                                     else
  7469.                                                         Number = LT_GetAttributes(Handle,Parent -> ID,TAG_DONE) + incNode -> Special . Incrementer . Amount;
  7470.  
  7471.                                                     if(Number >= Parent -> Special . Integer . Min && Number <= Parent -> Special . Integer . Max)
  7472.                                                     {
  7473.                                                         LTK_BlinkButton(Handle,Incrementer);
  7474.  
  7475.                                                         LT_SetAttributes(Handle,Parent -> ID,GTIN_Number,Number,TAG_DONE);
  7476.  
  7477.                                                         *MsgClass = IDCMP_GADGETUP;
  7478.  
  7479.                                                         LTK_PutStorage(Node);
  7480.                                                     }
  7481.                                                 }
  7482.                                                 else
  7483.                                                 {
  7484.                                                     ActivateGadget(Gadget,Handle -> Window,NULL);
  7485.  
  7486.                                                     *MsgClass = IDCMP_GADGETDOWN;
  7487.                                                 }
  7488.  
  7489.                                                 *MsgCode    = 0;
  7490.                                                 *MsgGadget    = Gadget;
  7491.  
  7492.                                                 Handle -> Previous = Gadget;
  7493.                                             }
  7494.                                             else
  7495.                                                 *MsgClass = NULL;
  7496.  
  7497.                                             FoundIt = TRUE;
  7498.  
  7499.                                             break;
  7500.  
  7501.                                         case BUTTON_KIND:
  7502.  
  7503.                                             if(!KeyUp && !(MsgQualifier & IEQUALIFIER_REPEAT))
  7504.                                             {
  7505.                                                 LTK_BlinkButton(Handle,Gadget);
  7506.  
  7507.                                                 *MsgClass    = IDCMP_GADGETUP;
  7508.                                                 *MsgCode    = 0;
  7509.                                                 *MsgGadget    = Gadget;
  7510.                                             }
  7511.                                             else
  7512.                                                 *MsgClass = NULL;
  7513.  
  7514.                                             FoundIt = TRUE;
  7515.  
  7516.                                             break;
  7517.                                     }
  7518.                                 }
  7519.                             }
  7520.                         }
  7521.                     }
  7522.                 }
  7523.             }
  7524.  
  7525.             break;
  7526.         }
  7527.  
  7528.         case IDCMP_GADGETDOWN:
  7529.  
  7530.             if(GETOBJECT((*MsgGadget),Node))
  7531.             {
  7532.                 switch(Node -> Type)
  7533.                 {
  7534.                     case STRING_KIND:
  7535.                     case INTEGER_KIND:
  7536.                     case FRACTION_KIND:
  7537.                     case PASSWORD_KIND:
  7538.  
  7539.                         Handle -> Previous = *MsgGadget;
  7540.                         break;
  7541. #ifdef DO_TAPEDECK_KIND
  7542.                     case TAPEDECK_KIND:
  7543.  
  7544.                         if(Node -> Special . TapeDeck . Toggle)
  7545.                         {
  7546.                             if((*MsgGadget) -> Flags & GFLG_SELECTED)
  7547.                                 *MsgCode = TRUE;
  7548.                             else
  7549.                                 *MsgCode = FALSE;
  7550.  
  7551.                             Node -> Current = *MsgCode;
  7552.  
  7553.                             LTK_PutStorage(Node);
  7554.  
  7555.                             if(Handle -> Previous && !Node -> PageSelector)
  7556.                                 Activate = TRUE;
  7557.  
  7558.                             *MsgClass = IDCMP_GADGETUP;
  7559.                         }
  7560.                         else
  7561.                             *MsgClass = NULL;
  7562.  
  7563.                         break;
  7564. #endif    /* DO_TAPEDECK_KIND */
  7565.                     case MX_KIND:
  7566.  
  7567.                         if(!V39 && Node -> Disabled)
  7568.                         {
  7569.                             GT_SetGadgetAttrs(*MsgGadget,Handle -> Window,NULL,
  7570.                                 GTMX_Active,Node -> Current,
  7571.                             TAG_DONE);
  7572.  
  7573.                             *MsgClass = NULL;
  7574.                         }
  7575.                         else
  7576.                         {
  7577.                             Node -> Current = *MsgCode;
  7578.  
  7579.                             LTK_PutStorage(Node);
  7580.  
  7581.                             if(Handle -> Previous && !Node -> PageSelector)
  7582.                                 Activate = TRUE;
  7583.                         }
  7584.  
  7585.                         break;
  7586.  
  7587.                     case SLIDER_KIND:
  7588.  
  7589.                         if(Node -> Min < 0)
  7590.                             Node -> Current = (WORD)*MsgCode;
  7591.                         else
  7592.                             Node -> Current = *MsgCode;
  7593.  
  7594.                         LTK_PutStorage(Node);
  7595.  
  7596.                         if(Handle -> Previous && !Node -> PageSelector)
  7597.                             Activate = TRUE;
  7598.  
  7599.                         break;
  7600.  
  7601.                     case SCROLLER_KIND:
  7602.  
  7603.                         Node -> Current = *MsgCode;
  7604.  
  7605.                         LTK_PutStorage(Node);
  7606.  
  7607.                         if(Handle -> Previous && !Node -> PageSelector)
  7608.                             Activate = TRUE;
  7609.  
  7610.                         break;
  7611.  
  7612.                     case INCREMENTER_KIND:
  7613.  
  7614.                         Handle -> ActiveIncrementer    = Node;
  7615.                         Handle -> IncrementerCountdown    = 6;
  7616.  
  7617.                         *MsgClass    = IDCMP_GADGETUP;
  7618.                         *MsgCode    = 0;
  7619.                         *MsgGadget    = Node -> Special . Incrementer . Parent;
  7620.  
  7621.                         /* ALWAYS */
  7622.                         {
  7623.                             struct ObjectNode    *Parent = (ObjectNode *)(*MsgGadget) -> UserData;
  7624.                             LONG             Number;
  7625.  
  7626.                             if(Parent -> Special . Integer . IncrementerHook)
  7627.                                 Number = CallHookPkt(Parent -> Special . Integer . IncrementerHook,(APTR)LT_GetAttributes(Handle,Parent -> ID,TAG_DONE),Node -> Special . Incrementer . Amount < 0 ? (APTR)INCREMENTERMSG_DECREMENT : (APTR)INCREMENTERMSG_INCREMENT);
  7628.                             else
  7629.                                 Number = LT_GetAttributes(Handle,Parent -> ID,TAG_DONE) + Node -> Special . Incrementer . Amount;
  7630.  
  7631.                             if(Number >= Parent -> Special . Integer . Min && Number <= Parent -> Special . Integer . Max)
  7632.                                 LT_SetAttributes(Handle,Parent -> ID,GTIN_Number,Number,TAG_DONE);
  7633.                             else
  7634.                                 *MsgClass = NULL;
  7635.                         }
  7636.  
  7637.                         break;
  7638.                 }
  7639.             }
  7640.  
  7641.             break;
  7642.  
  7643.         case IDCMP_MOUSEBUTTONS:
  7644.  
  7645.             if(((*MsgCode) & IECODE_UP_PREFIX) && Handle -> Previous)
  7646.                 Activate = TRUE;
  7647.  
  7648.             if((*MsgCode == SELECTUP) && (Handle -> ActiveIncrementer))
  7649.                 Handle -> ActiveIncrementer = NULL;
  7650.  
  7651.             break;
  7652.  
  7653.         case IDCMP_GADGETUP:
  7654.  
  7655.             if(GETOBJECT((*MsgGadget),Node))
  7656.             {
  7657.                 switch(Node -> Type)
  7658.                 {
  7659.                     case FRACTION_KIND:
  7660.  
  7661.                         LT_SetAttributes(Handle,(*MsgGadget) -> GadgetID,LAFC_Number,LT_GetAttributes(Handle,(*MsgGadget) -> GadgetID,TAG_DONE),TAG_DONE);
  7662.  
  7663.                     /* FALLS THROUGH */
  7664.  
  7665.                     case PASSWORD_KIND:
  7666.                     case STRING_KIND:
  7667.  
  7668.                         Handle -> Previous = NULL;
  7669.  
  7670.                         LTK_PutStorage(Node);
  7671.  
  7672.                         break;
  7673.  
  7674.                     case INTEGER_KIND:
  7675.                     {
  7676.                         struct StringInfo *StringInfo = (struct StringInfo *)(*MsgGadget) -> SpecialInfo;
  7677.                         LONG Contents = StringInfo -> LongInt;
  7678.  
  7679.                         if(Contents < Node -> Special . Integer . Min)
  7680.                             Contents = Node -> Special . Integer . Min;
  7681.                         else
  7682.                         {
  7683.                             if(Contents > Node -> Special . Integer . Max)
  7684.                                 Contents = Node -> Special . Integer . Max;
  7685.                         }
  7686.  
  7687.                         LT_SetAttributes(Handle,(*MsgGadget) -> GadgetID,GTIN_Number,Contents,TAG_DONE);
  7688.  
  7689.                         Handle -> Previous = NULL;
  7690.  
  7691.                         LTK_PutStorage(Node);
  7692.  
  7693.                         break;
  7694.                     }
  7695.  
  7696.                     case CHECKBOX_KIND:
  7697.  
  7698.                         if(!V39)
  7699.                         {
  7700.                             if((*MsgGadget) -> Flags & GFLG_SELECTED)
  7701.                                 *MsgCode = TRUE;
  7702.                             else
  7703.                                 *MsgCode = FALSE;
  7704.                         }
  7705.  
  7706.                         Node -> Current = *MsgCode;
  7707.  
  7708.                         LTK_PutStorage(Node);
  7709.  
  7710.                         if(Handle -> Previous && !Node -> PageSelector)
  7711.                             Activate = TRUE;
  7712.  
  7713.                         break;
  7714. #ifdef DO_TAPEDECK_KIND
  7715.                     case TAPEDECK_KIND:
  7716.  
  7717.                         if(Node -> Special . TapeDeck . Toggle)
  7718.                         {
  7719.                             if((*MsgGadget) -> Flags & GFLG_SELECTED)
  7720.                                 *MsgCode = TRUE;
  7721.                             else
  7722.                                 *MsgCode = FALSE;
  7723.  
  7724.                             Node -> Current = *MsgCode;
  7725.  
  7726.                             LTK_PutStorage(Node);
  7727.                         }
  7728.  
  7729.                         if(Handle -> Previous && !Node -> PageSelector)
  7730.                             Activate = TRUE;
  7731.  
  7732.                         break;
  7733. #endif    /* DO_TAPEDECK_KIND */
  7734.                     case CYCLE_KIND:
  7735.                     case PALETTE_KIND:
  7736.  
  7737.                         Node -> Current = *MsgCode;
  7738.  
  7739.                         LTK_PutStorage(Node);
  7740.  
  7741.                         if(Handle -> Previous && !Node -> PageSelector)
  7742.                             Activate = TRUE;
  7743.  
  7744.                         break;
  7745.  
  7746.                     case MX_KIND:
  7747.  
  7748.                         if(!V39 && Node -> Disabled)
  7749.                         {
  7750.                             GT_SetGadgetAttrs(*MsgGadget,Handle -> Window,NULL,
  7751.                                 GTMX_Active,Node -> Current,
  7752.                             TAG_DONE);
  7753.  
  7754.                             *MsgClass = NULL;
  7755.                         }
  7756.                         else
  7757.                         {
  7758.                             Node -> Current = *MsgCode;
  7759.  
  7760.                             LTK_PutStorage(Node);
  7761.  
  7762.                             if(Handle -> Previous && !Node -> PageSelector)
  7763.                                 Activate = TRUE;
  7764.                         }
  7765.  
  7766.                         break;
  7767.  
  7768.                     case SLIDER_KIND:
  7769.  
  7770.                         if(Node -> Min < 0)
  7771.                             Node -> Current = (WORD)*MsgCode;
  7772.                         else
  7773.                             Node -> Current = *MsgCode;
  7774.  
  7775.                         LTK_PutStorage(Node);
  7776.  
  7777.                         if(Handle -> Previous && !Node -> PageSelector)
  7778.                             Activate = TRUE;
  7779.  
  7780.                         break;
  7781.  
  7782.                     case SCROLLER_KIND:
  7783.  
  7784.                         Node -> Current = *MsgCode;
  7785.  
  7786.                         LTK_PutStorage(Node);
  7787.  
  7788.                         if(Handle -> Previous && !Node -> PageSelector)
  7789.                             Activate = TRUE;
  7790.  
  7791.                         break;
  7792.  
  7793.                     case PICKER_KIND:
  7794.  
  7795.                         *MsgClass    = IDCMP_IDCMPUPDATE;
  7796.                         *MsgCode    = 0;
  7797.                         *MsgGadget    = Node -> Special . Picker . Parent;
  7798.  
  7799.                         if(Handle -> Previous && !Node -> PageSelector)
  7800.                             Activate = TRUE;
  7801.  
  7802.                         break;
  7803.  
  7804.                     case INCREMENTER_KIND:
  7805.  
  7806.                         Handle -> ActiveIncrementer = NULL;
  7807.                         break;
  7808.  
  7809.                     case LISTVIEW_KIND:
  7810.  
  7811.                         if(Node -> Current != *MsgCode)
  7812.                             CurrentTime(&Node -> Special . List . ClickSeconds,&Node -> Special . List . ClickMicros);
  7813.                         else
  7814.                         {
  7815.                             ULONG Seconds,Micros;
  7816.  
  7817.                             CurrentTime(&Seconds,&Micros);
  7818.  
  7819.                             if(DoubleClick(Node -> Special . List . ClickSeconds,Node -> Special . List . ClickMicros,Seconds,Micros))
  7820.                                 *MsgClass = IDCMP_IDCMPUPDATE;
  7821.  
  7822.                             Node -> Special . List . ClickSeconds    = Seconds;
  7823.                             Node -> Special . List . ClickMicros    = Micros;
  7824.                         }
  7825.  
  7826.                         Node -> Current = *MsgCode;
  7827.  
  7828.                         LTK_PutStorage(Node);
  7829.  
  7830.                         if(Node -> Special . List . Link)
  7831.                         {
  7832.                             Handle -> Previous = Node -> Special . List . Link;
  7833.  
  7834.                             if(!Node -> PageSelector)
  7835.                                 Activate = TRUE;
  7836.                         }
  7837.                         else
  7838.                         {
  7839.                             if(Handle -> Previous && !Node -> PageSelector)
  7840.                                 Activate = TRUE;
  7841.                         }
  7842.  
  7843.                         break;
  7844.  
  7845.                     default:
  7846.  
  7847.                         if(Handle -> Previous && !Node -> PageSelector)
  7848.                             Activate = TRUE;
  7849.  
  7850.                         break;
  7851.                 }
  7852.             }
  7853.  
  7854.             break;
  7855.  
  7856.         case IDCMP_MOUSEMOVE:
  7857.  
  7858.             if(GETOBJECT((*MsgGadget),Node))
  7859.             {
  7860.                 if(Node -> Type == SLIDER_KIND)
  7861.                 {
  7862.                     if(Node -> Min < 0)
  7863.                         Node -> Current = (WORD)*MsgCode;
  7864.                     else
  7865.                         Node -> Current = *MsgCode;
  7866.  
  7867.                     LTK_PutStorage(Node);
  7868.                 }
  7869.                 else
  7870.                 {
  7871.                     if(Node -> Type == SCROLLER_KIND)
  7872.                     {
  7873.                         Node -> Current = *MsgCode;
  7874.  
  7875.                         LTK_PutStorage(Node);
  7876.                     }
  7877.                 }
  7878.             }
  7879.  
  7880.             break;
  7881.  
  7882.         case IDCMP_ACTIVEWINDOW:
  7883.  
  7884.             if(Handle -> Previous)
  7885.             {
  7886.                 Activate = TRUE;
  7887.  
  7888.                 *MsgClass    = IDCMP_GADGETDOWN;
  7889.                 *MsgCode    = 0;
  7890.                 *MsgGadget    = Handle -> Previous;
  7891.             }
  7892.  
  7893.             break;
  7894.  
  7895.         case IDCMP_INACTIVEWINDOW:
  7896.  
  7897.             Handle -> ActiveIncrementer = NULL;
  7898.             break;
  7899.     }
  7900.  
  7901.     if(Handle -> AutoActivate && Activate && Handle -> Previous)
  7902.     {
  7903.         if(GETOBJECT(Handle -> Previous,Node))
  7904.         {
  7905.             if(!Node -> Disabled)
  7906.                 ActivateGadget(Handle -> Previous,Handle -> Window,NULL);
  7907.         }
  7908.     }
  7909. }
  7910.  
  7911.  
  7912. /*****************************************************************************/
  7913.  
  7914.  
  7915. VOID LIBENT
  7916. LT_BeginRefresh(REG(a0) LayoutHandle *handle)
  7917. {
  7918.     if(handle)
  7919.     {
  7920.         GT_BeginRefresh(handle -> Window);
  7921.  
  7922.         LTK_DrawGroup(handle,handle -> TopGroup);
  7923.     }
  7924. }
  7925.  
  7926.  
  7927. /*****************************************************************************/
  7928.  
  7929.  
  7930. VOID LIBENT
  7931. LT_EndRefresh(REG(a0) LayoutHandle *handle,REG(d0) BOOL complete)
  7932. {
  7933.     if(handle)
  7934.         GT_EndRefresh(handle -> Window,complete);
  7935. }
  7936.  
  7937.  
  7938. /*****************************************************************************/
  7939.  
  7940.  
  7941. LONG __stdargs
  7942. LT_GetAttributes(LayoutHandle *Handle,LONG ID,...)
  7943. {
  7944.     va_list    VarArgs;
  7945.     LONG    Result;
  7946.  
  7947.     va_start(VarArgs,ID);
  7948.     Result = LT_GetAttributesA(Handle,ID,(struct TagItem *)VarArgs);
  7949.     va_end(VarArgs);
  7950.  
  7951.     return(Result);
  7952. }
  7953.  
  7954. LONG LIBENT
  7955. LT_GetAttributesA(REG(a0) LayoutHandle *Handle,REG(d0) LONG ID,REG(a1) struct TagItem *TagList)
  7956. {
  7957.     if(Handle)
  7958.     {
  7959.         ObjectNode *Node;
  7960.  
  7961.         if(Node = LTK_FindNode(Handle -> TopGroup,ID))
  7962.         {
  7963.             struct StringInfo *StringInfo;
  7964.  
  7965.             if(TagList)
  7966.             {
  7967.                 struct TagItem    *TagItem,
  7968.                         *TempPtr = TagList;
  7969.                 LONG        *Value;
  7970.  
  7971.                 while(TagItem = NextTagItem(&TempPtr))
  7972.                 {
  7973.                     Value = (LONG *)TagItem -> ti_Data;
  7974.  
  7975.                     switch(TagItem -> ti_Tag)
  7976.                     {
  7977.                         case LA_Left:
  7978.  
  7979.                             if(Node -> Type == FRAME_KIND && Node -> Special . Frame . DrawBox)
  7980.                                 *Value = Node -> Left + 4;
  7981.                             else
  7982.                                 *Value = Node -> Left;
  7983.  
  7984.                             break;
  7985.  
  7986.                         case LA_Top:
  7987.  
  7988.                             if(Node -> Type == FRAME_KIND && Node -> Special . Frame . DrawBox)
  7989.                                 *Value = Node -> Top + 2;
  7990.                             else
  7991.                                 *Value = Node -> Top;
  7992.  
  7993.                             break;
  7994.  
  7995.                         case LA_Width:
  7996.  
  7997.                             if(Node -> Type == FRAME_KIND && Node -> Special . Frame . DrawBox)
  7998.                                 *Value = Node -> Width - 8;
  7999.                             else
  8000.                                 *Value = Node -> Width;
  8001.  
  8002.                             break;
  8003.  
  8004.                         case LA_Height:
  8005.  
  8006.                             if(Node -> Type == FRAME_KIND && Node -> Special . Frame . DrawBox)
  8007.                                 *Value = Node -> Height - 4;
  8008.                             else
  8009.                                 *Value = Node -> Height;
  8010.  
  8011.                             break;
  8012.                     }
  8013.                 }
  8014.             }
  8015.  
  8016.             if(Node -> Host)
  8017.             {
  8018.                 struct Gadget *Gadget = Node -> Host;
  8019.  
  8020.                 switch(Node -> Type)
  8021.                 {
  8022.                     case CHECKBOX_KIND:
  8023.                     case LISTVIEW_KIND:
  8024.                     case MX_KIND:
  8025.                     case CYCLE_KIND:
  8026.                     case PALETTE_KIND:
  8027.                     case SLIDER_KIND:
  8028.                     case SCROLLER_KIND:
  8029. #ifdef DO_GAUGE_KIND
  8030.                     case GAUGE_KIND:
  8031. #endif
  8032. #ifdef DO_TAPEDECK_KIND
  8033.                     case TAPEDECK_KIND:
  8034. #endif    /* DO_TAPEDECK_KIND */
  8035.                         return(Node -> Current);
  8036.  
  8037. #ifdef DO_FRACTION_KIND
  8038.                     case FRACTION_KIND:
  8039.                     {
  8040.                         FIXED Contents;
  8041.  
  8042.                         StringInfo = (struct StringInfo *)Gadget -> SpecialInfo;
  8043.  
  8044.                         Contents = LT_String2Fixed(StringInfo -> Buffer);
  8045.  
  8046.                         if(Contents < Node -> Special . String . Min)
  8047.                             Contents = Node -> Special . String . Min;
  8048.                         else
  8049.                         {
  8050.                             if(Contents > Node -> Special . String . Max)
  8051.                                 Contents = Node -> Special . String . Max;
  8052.                         }
  8053.  
  8054.                         LT_SetAttributes(Handle,Gadget -> GadgetID,LAFC_Number,Contents,TAG_DONE);
  8055.  
  8056.                         return((LONG)Contents);
  8057.                     }
  8058. #endif
  8059.                     case STRING_KIND:
  8060.  
  8061.                         StringInfo = (struct StringInfo *)Gadget -> SpecialInfo;
  8062.  
  8063.                         return((LONG)StringInfo -> Buffer);
  8064. #ifdef DO_PASSWORD_KIND
  8065.                     case PASSWORD_KIND:
  8066.  
  8067.                         return((LONG)Node -> Special . String . Original);
  8068. #endif
  8069.                     case INTEGER_KIND:
  8070.                     {
  8071.                         LONG Contents;
  8072.  
  8073.                         StringInfo = (struct StringInfo *)Gadget -> SpecialInfo;
  8074.  
  8075.                         Contents = StringInfo -> LongInt;
  8076.  
  8077.                         if(Contents < Node -> Special . Integer . Min)
  8078.                             LT_SetAttributes(Handle,Gadget -> GadgetID,GTIN_Number,Contents = Node -> Special . Integer . Min,TAG_DONE);
  8079.                         else
  8080.                         {
  8081.                             if(Contents > Node -> Special . Integer . Max)
  8082.                                 LT_SetAttributes(Handle,Gadget -> GadgetID,GTIN_Number,Contents = Node -> Special . Integer . Max,TAG_DONE);
  8083.                             else
  8084.                                 Node -> Special . Integer . Number = Contents;
  8085.                         }
  8086.  
  8087.                         return(Contents);
  8088.                     }
  8089.  
  8090.                     case GROUP_KIND:
  8091.  
  8092.                         return((LONG)Node -> Special . Group . ActivePage);
  8093.                 }
  8094.             }
  8095.         }
  8096.     }
  8097.  
  8098.     return(NULL);
  8099. }
  8100.  
  8101.  
  8102. /*****************************************************************************/
  8103.  
  8104.  
  8105. VOID __stdargs
  8106. LT_SetAttributes(LayoutHandle *handle,LONG id,...)
  8107. {
  8108.     va_list VarArgs;
  8109.  
  8110.     va_start(VarArgs,id);
  8111.     LT_SetAttributesA(handle,id,(struct TagItem *)VarArgs);
  8112.     va_end(VarArgs);
  8113. }
  8114.  
  8115. VOID LIBENT
  8116. LT_SetAttributesA(REG(a0) LayoutHandle *handle,REG(d0) LONG id,REG(a1) struct TagItem *TagList)
  8117. {
  8118.     if(handle && TagList)
  8119.     {
  8120.         struct Gadget    *Gadget;
  8121.         struct TagItem    *ThisTag;
  8122.         ObjectNode    *Node;
  8123.  
  8124.         if(ThisTag = FindTagItem(LH_AutoActivate,TagList))
  8125.             handle -> AutoActivate = ThisTag -> ti_Data;
  8126.  
  8127.         if(ThisTag = FindTagItem(LH_LocaleHook,TagList))
  8128.             handle -> LocaleHook = (struct Hook *)ThisTag -> ti_Data;
  8129.  
  8130.         if(Gadget = LTK_FindGadget(handle,id))
  8131.         {
  8132.             if(Node = (ObjectNode *)Gadget -> UserData)
  8133.             {
  8134.                 if(Node -> Host != Gadget || Node -> PointBack != Node)
  8135.                     Node = NULL;
  8136.             }
  8137.         }
  8138.         else
  8139.             Node = LTK_FindNode(handle -> TopGroup,id);
  8140.  
  8141.         if(Node)
  8142.         {
  8143.             STATIC Tag Filter[] = { GA_Disabled,TAG_DONE };
  8144.  
  8145.             struct TagItem    *NewTags = NULL;
  8146.             ULONG         Exclude = NULL;
  8147.  
  8148.             switch(Node -> Type)
  8149.             {
  8150.                 case CHECKBOX_KIND:
  8151.  
  8152.                     if(!Gadget)
  8153.                         return;
  8154.  
  8155.                     if(ThisTag = FindTagItem(GTCB_Checked,TagList))
  8156.                     {
  8157.                         if((Node -> Current && ThisTag -> ti_Data) || (!Node -> Current && !ThisTag -> ti_Data))
  8158.                             Exclude = GTCB_Checked;
  8159.                         else
  8160.                         {
  8161.                             Node -> Current = ThisTag -> ti_Data;
  8162.  
  8163.                             LTK_PutStorage(Node);
  8164.                         }
  8165.                     }
  8166.  
  8167.                     break;
  8168.  
  8169. #ifdef DO_TAPEDECK_KIND
  8170.                 case TAPEDECK_KIND:
  8171.  
  8172.                     if(Gadget)
  8173.                     {
  8174.                         if(ThisTag = FindTagItem(LATD_Pressed,TagList))
  8175.                         {
  8176.                             if(Node -> Current != ThisTag -> ti_Data && Node -> Special . TapeDeck . Toggle)
  8177.                             {
  8178.                                 RemoveGList(handle -> Window,handle -> List,(UWORD)-1);
  8179.  
  8180.                                 if(Node -> Current = ThisTag -> ti_Data)
  8181.                                     Gadget -> Flags |= GFLG_SELECTED;
  8182.                                 else
  8183.                                     Gadget -> Flags &= ~GFLG_SELECTED;
  8184.  
  8185.                                 AddGList(handle -> Window,handle -> List,(UWORD)-1,(UWORD)-1,NULL);
  8186.                                 RefreshGList(Gadget,handle -> Window,NULL,1);
  8187.                             }
  8188.                         }
  8189.                     }
  8190.  
  8191.                     break;
  8192. #endif    /* DO_TAPEDECK_KIND */
  8193.  
  8194. #ifdef DO_GAUGE_KIND
  8195.                 case GAUGE_KIND:
  8196.  
  8197.                     if(Gadget)
  8198.                     {
  8199.                         LONG    Percent        = (LONG)Node -> Current;
  8200.                         BOOLEAN    NeedRefresh    = FALSE;
  8201.  
  8202.                         if(ThisTag = FindTagItem(LAGA_Percent,TagList))
  8203.                         {
  8204.                             Percent = (LONG)ThisTag -> ti_Data;
  8205.  
  8206.                             if(Percent < 0)
  8207.                                 Percent = 0;
  8208.                             else
  8209.                             {
  8210.                                 if(Percent > 100)
  8211.                                     Percent = 100;
  8212.                             }
  8213.  
  8214.                             if(Percent != (LONG)Node -> Current)
  8215.                                 NeedRefresh = TRUE;
  8216.                         }
  8217.  
  8218.                         if(ThisTag = FindTagItem(LAGA_InfoText,TagList))
  8219.                         {
  8220.                             STRPTR SomeText = (STRPTR)ThisTag -> ti_Data;
  8221.  
  8222.                             if(Node -> Special . Gauge . InfoLength)
  8223.                             {
  8224.                                 LONG Len = strlen(SomeText);
  8225.  
  8226.                                 if(Len > Node -> Special . Gauge . InfoLength)
  8227.                                     Len = Node -> Special . Gauge . InfoLength;
  8228.  
  8229.                                 CopyMem(SomeText,Node -> Special . Gauge . InfoText,Len);
  8230.  
  8231.                                 Node -> Special . Gauge . InfoText[Len] = 0;
  8232.  
  8233.                                 NeedRefresh = TRUE;
  8234.                             }
  8235.                         }
  8236.  
  8237.                         if(NeedRefresh)
  8238.                             LTK_DrawGauge(handle,Node,Percent,FALSE);
  8239.                     }
  8240.  
  8241.                     return;
  8242. #endif
  8243.                 case LISTVIEW_KIND:
  8244.  
  8245.                     if(!Gadget)
  8246.                         return;
  8247.  
  8248.                     if(ThisTag = FindTagItem(GTLV_Labels,TagList))
  8249.                     {
  8250.                         if(ThisTag -> ti_Data == (ULONG)~0)
  8251.                             Node -> Min = Node -> Max = -1;
  8252.                         else
  8253.                         {
  8254.                             struct List    *List;
  8255.                             LONG         Count = 0;
  8256.  
  8257.                             if(List = (struct List *)ThisTag -> ti_Data)
  8258.                             {
  8259.                                 struct Node *Item;
  8260.  
  8261.                                 SCANLIST(List,Item)
  8262.                                 {
  8263.                                     Count++;
  8264.                                 }
  8265.                             }
  8266.  
  8267.                             Node -> Min = 0;
  8268.  
  8269.                             if(Count)
  8270.                                 Node -> Max = Count - 1;
  8271.                             else
  8272.                                 Node -> Max = 0;
  8273.                         }
  8274.                     }
  8275.  
  8276.                     if(ThisTag = FindTagItem(GA_Disabled,TagList))
  8277.                     {
  8278.                         if(!V39)
  8279.                         {
  8280.                             if(!(NewTags = CloneTagItems(TagList)))
  8281.                                 return;
  8282.                             else
  8283.                                 FilterTagItems(NewTags,Filter,TAGFILTER_NOT);
  8284.                         }
  8285.                     }
  8286.  
  8287.                     if(ThisTag = FindTagItem(GTLV_Selected,TagList))
  8288.                     {
  8289.                         struct List *List;
  8290.  
  8291.                         Node -> Current = (LONG)ThisTag -> ti_Data;
  8292.  
  8293.                         if(ThisTag = FindTagItem(GTLV_Labels,TagList))
  8294.                             List = (struct List *)ThisTag -> ti_Data;
  8295.                         else
  8296.                             List = NULL;
  8297.  
  8298.                         if(Node -> Current < 0)
  8299.                         {
  8300.                             GT_SetGadgetAttrs(Gadget,handle -> Window,NULL,
  8301.                                 GTLV_Selected,            Node -> Current,
  8302.                                 List ? GTLV_Labels : TAG_IGNORE,List,
  8303.                             TAG_DONE);
  8304.                         }
  8305.                         else
  8306.                         {
  8307.                             GT_SetGadgetAttrs(Gadget,handle -> Window,NULL,
  8308.                                 GTLV_Selected,            Node -> Current,
  8309.                                 GTLV_Top,            Node -> Current,
  8310.                                 GTLV_MakeVisible,        Node -> Current,
  8311.  
  8312.                                 List ? GTLV_Labels : TAG_IGNORE,List,
  8313.                             TAG_DONE);
  8314.                         }
  8315.  
  8316.                         LTK_PutStorage(Node);
  8317.                     }
  8318.  
  8319.                     break;
  8320.  
  8321.                 case MX_KIND:
  8322.  
  8323.                     if(!Gadget)
  8324.                         return;
  8325.  
  8326.                     if(!V39)
  8327.                     {
  8328.                         if(FindTagItem(GA_Disabled,TagList))
  8329.                         {
  8330.                             if(!(NewTags = CloneTagItems(TagList)))
  8331.                                 return;
  8332.                             else
  8333.                                 FilterTagItems(NewTags,Filter,TAGFILTER_NOT);
  8334.                         }
  8335.                     }
  8336.  
  8337.                     if(ThisTag = FindTagItem(GTMX_Active,TagList))
  8338.                     {
  8339.                         if(Node -> Current == ThisTag -> ti_Data)
  8340.                             Exclude = GTMX_Active;
  8341.                         else
  8342.                         {
  8343.                             Node -> Current = ThisTag -> ti_Data;
  8344.  
  8345.                             LTK_PutStorage(Node);
  8346.                         }
  8347.                     }
  8348.  
  8349.                     break;
  8350.  
  8351.                 case CYCLE_KIND:
  8352.  
  8353.                     if(!Gadget)
  8354.                         return;
  8355.  
  8356.                     if(ThisTag = FindTagItem(GTCY_Active,TagList))
  8357.                     {
  8358.                         if(Node -> Current == ThisTag -> ti_Data)
  8359.                             Exclude = GTCY_Active;
  8360.                         else
  8361.                         {
  8362.                             Node -> Current = ThisTag -> ti_Data;
  8363.  
  8364.                             LTK_PutStorage(Node);
  8365.                         }
  8366.                     }
  8367.  
  8368.                     if(ThisTag = FindTagItem(GTCY_Labels,TagList))
  8369.                     {
  8370.                         STRPTR    *Strings;
  8371.                         LONG     Count = 0;
  8372.  
  8373.                         if(Strings = (STRPTR *)ThisTag -> ti_Data)
  8374.                         {
  8375.                             while(Strings[Count])
  8376.                                 Count++;
  8377.                         }
  8378.  
  8379.                         if(Count)
  8380.                             Node -> Max = Count - 1;
  8381.                         else
  8382.                             Node -> Max = 0;
  8383.                     }
  8384.  
  8385.                     break;
  8386.  
  8387.                 case PALETTE_KIND:
  8388.  
  8389.                     if(!Gadget)
  8390.                         return;
  8391.  
  8392.                     if(ThisTag = FindTagItem(GTPA_Color,TagList))
  8393.                     {
  8394.                         if(Node -> Current == ThisTag -> ti_Data)
  8395.                             Exclude = GTPA_Color;
  8396.                         else
  8397.                         {
  8398.                             Node -> Current = ThisTag -> ti_Data;
  8399.  
  8400.                             LTK_PutStorage(Node);
  8401.                         }
  8402.                     }
  8403.  
  8404.                     break;
  8405.  
  8406.                 case INTEGER_KIND:
  8407.  
  8408.                     if(!Gadget)
  8409.                         return;
  8410.  
  8411.                     if(ThisTag = FindTagItem(GTIN_Number,TagList))
  8412.                     {
  8413.                         LONG num;
  8414.  
  8415.                         num = ThisTag -> ti_Data;
  8416.  
  8417.                         if(num < Node -> Special . Integer . Min)
  8418.                             num = Node -> Special . Integer . Min;
  8419.                         else
  8420.                         {
  8421.                             if(num > Node -> Special . Integer . Max)
  8422.                                 num = Node -> Special . Integer . Max;
  8423.                         }
  8424. #ifdef DO_HEXHOOK
  8425.                         if(!Node -> Special . Integer . EditHook)
  8426.                         {
  8427.                             UBYTE             buffer[20];
  8428.                             struct StringInfo    *stringInfo;
  8429.  
  8430.                             sprintf(buffer,"%ld",num);
  8431.  
  8432.                             Exclude = GTIN_Number;
  8433.  
  8434.                             GT_SetGadgetAttrs(Gadget,handle -> Window,NULL,
  8435.                                 GTST_String,buffer,
  8436.                             TAG_DONE);
  8437.  
  8438.                             stringInfo = (struct StringInfo *)Gadget -> SpecialInfo;
  8439.  
  8440.                             stringInfo -> LongInt = num;
  8441.                         }
  8442.                         else
  8443.                         {
  8444.                             UBYTE             buffer[40];
  8445.                             struct StringInfo    *stringInfo;
  8446.                             STRPTR             Index;
  8447.                             LONG             Value,Number = num,
  8448.                                          Scale,Sign;
  8449.  
  8450.                             stringInfo = (struct StringInfo *)Gadget -> SpecialInfo;
  8451.  
  8452.                             Index = stringInfo -> Buffer;
  8453.  
  8454.                             while(*Index && *Index == ' ')
  8455.                                 Index++;
  8456.  
  8457.                             switch(Index[0])
  8458.                             {
  8459.                                 case '$':
  8460.  
  8461.                                     sprintf(buffer,"$%lx",num);
  8462.                                     break;
  8463.  
  8464.                                 case '&':
  8465.  
  8466.                                     if(Number < 0)
  8467.                                     {
  8468.                                         Sign = -1;
  8469.                                         Number = -Number;
  8470.                                     }
  8471.                                     else
  8472.                                         Sign = 1;
  8473.  
  8474.                                     for(Value = 0, Scale = 1 ; Number ; Number /= 8, Scale *= 10)
  8475.                                         Value += (Number & 7) * Scale;
  8476.  
  8477.                                     sprintf(buffer,"&%ld",Sign * Value);
  8478.                                     break;
  8479.  
  8480.                                 case '%':
  8481.  
  8482.                                     if(Number < 0)
  8483.                                     {
  8484.                                         Sign = -1;
  8485.                                         Number = -Number;
  8486.                                     }
  8487.                                     else
  8488.                                         Sign = 1;
  8489.  
  8490.                                     for(Value = 0, Scale = 1 ; Number ; Number /= 2, Scale *= 10)
  8491.                                         Value += (Number & 1) * Scale;
  8492.  
  8493.                                     sprintf(buffer,"%%%ld",Sign * Value);
  8494.                                     break;
  8495.  
  8496.                                 case '0':
  8497.  
  8498.                                     if(Index[1] == 'x')
  8499.                                     {
  8500.                                         sprintf(buffer,"0x%lx",num);
  8501.                                         break;
  8502.                                     }
  8503.  
  8504.                                     // Fall through to...
  8505.  
  8506.                                 default:
  8507.  
  8508.                                     sprintf(buffer,"%ld",num);
  8509.                                     break;
  8510.                             }
  8511.  
  8512.                             Exclude = GTIN_Number;
  8513.  
  8514.                             GT_SetGadgetAttrs(Gadget,handle -> Window,NULL,
  8515.                                 GTST_String,buffer,
  8516.                             TAG_DONE);
  8517.  
  8518.                             stringInfo -> LongInt = num;
  8519.                         }
  8520. #else
  8521.                         GT_SetGadgetAttrs(Gadget,handle -> Window,NULL,
  8522.                             GTIN_Number,num,
  8523.                         TAG_DONE);
  8524. #endif
  8525.                         Node -> Special . Integer . Number = num;
  8526.  
  8527.                         LTK_PutStorage(Node);
  8528.                     }
  8529.  
  8530.                     break;
  8531.  
  8532.                 case SLIDER_KIND:
  8533.  
  8534.                     if(!Gadget)
  8535.                         return;
  8536.  
  8537.                     if(ThisTag = FindTagItem(GTSL_Level,TagList))
  8538.                     {
  8539.                         if(Node -> Current == ThisTag -> ti_Data)
  8540.                             Exclude = GTSL_Level;
  8541.                         else
  8542.                         {
  8543.                             Node -> Current = ThisTag -> ti_Data;
  8544.  
  8545.                             LTK_PutStorage(Node);
  8546.                         }
  8547.                     }
  8548.  
  8549.                     if(ThisTag = FindTagItem(GTSL_Min,TagList))
  8550.                     {
  8551.                         Node -> Min = ThisTag -> ti_Data;
  8552.  
  8553.                         if(Node -> Current < Node -> Min)
  8554.                         {
  8555.                             Node -> Current = Node -> Min;
  8556.  
  8557.                             LTK_PutStorage(Node);
  8558.                         }
  8559.                     }
  8560.  
  8561.                     if(ThisTag = FindTagItem(GTSL_Max,TagList))
  8562.                     {
  8563.                         Node -> Max = ThisTag -> ti_Data;
  8564.  
  8565.                         if(Node -> Current > Node -> Max)
  8566.                         {
  8567.                             Node -> Current = Node -> Max;
  8568.  
  8569.                             LTK_PutStorage(Node);
  8570.                         }
  8571.                     }
  8572.  
  8573.                     break;
  8574.  
  8575.                 case SCROLLER_KIND:
  8576.  
  8577.                     if(!Gadget)
  8578.                         return;
  8579.  
  8580.                     if(ThisTag = FindTagItem(GTSC_Top,TagList))
  8581.                     {
  8582.                         if(Node -> Current == ThisTag -> ti_Data)
  8583.                             Exclude = GTSC_Top;
  8584.                         else
  8585.                         {
  8586.                             Node -> Current = ThisTag -> ti_Data;
  8587.  
  8588.                             LTK_PutStorage(Node);
  8589.                         }
  8590.                     }
  8591.  
  8592.                     if(ThisTag = FindTagItem(GTSC_Total,TagList))
  8593.                     {
  8594.                         Node -> Max = ThisTag -> ti_Data;
  8595.  
  8596.                         if(Node -> Current > Node -> Max)
  8597.                         {
  8598.                             Node -> Current = Node -> Max;
  8599.  
  8600.                             LTK_PutStorage(Node);
  8601.                         }
  8602.                     }
  8603.  
  8604.                     if(ThisTag = FindTagItem(GTSC_Visible,TagList))
  8605.                         Node -> Special . Scroller . Visible = ThisTag -> ti_Data;
  8606.  
  8607.                     break;
  8608.  
  8609.                 case BOX_KIND:
  8610.  
  8611.                     if(ThisTag = FindTagItem(LABX_Index,TagList))
  8612.                     {
  8613.                         LONG Index = ThisTag -> ti_Data;
  8614.  
  8615.                         if(Index >= 0 && Index < Node -> Lines)
  8616.                         {
  8617.                             if(ThisTag = FindTagItem(LABX_Text,TagList))
  8618.                             {
  8619.                                 if(Node -> Special . Box . ReserveSpace)
  8620.                                 {
  8621.                                     STRPTR    Text = (STRPTR)ThisTag -> ti_Data;
  8622.                                     WORD    Len = strlen(Text);
  8623.  
  8624.                                     if(Len > Node -> Special . Box . MaxSize)
  8625.                                         Len = Node -> Special . Box . MaxSize;
  8626.  
  8627.                                     CopyMem(Text,Node -> Special . Box . Lines[Index],Len);
  8628.  
  8629.                                     Node -> Special . Box . Lines[Index][Len] = 0;
  8630.                                 }
  8631.                                 else
  8632.                                     Node -> Special . Box . Lines[Index] = (STRPTR)ThisTag -> ti_Data;
  8633.  
  8634.                                 LTK_PrintBoxLine(handle,Node,Index);
  8635.                             }
  8636.                         }
  8637.                     }
  8638.  
  8639.                     if(ThisTag = FindTagItem(LABX_Lines,TagList))
  8640.                     {
  8641.                         STRPTR    *Lines = (STRPTR *)ThisTag -> ti_Data;
  8642.                         LONG     i;
  8643.  
  8644.                         if(Node -> Special . Box . ReserveSpace)
  8645.                         {
  8646.                             WORD Len;
  8647.  
  8648.                             for(i = 0 ; i < Node -> Lines ; i++)
  8649.                             {
  8650.                                 if(Lines[i])
  8651.                                 {
  8652.                                     Len = strlen(Lines[i]);
  8653.  
  8654.                                     if(Len > Node -> Special . Box . MaxSize)
  8655.                                         Len = Node -> Special . Box . MaxSize;
  8656.  
  8657.                                     CopyMem(Lines[i],Node -> Special . Box . Lines[i],Len);
  8658.  
  8659.                                     Node -> Special . Box . Lines[i][Len] = 0;
  8660.  
  8661.                                     LTK_PrintBoxLine(handle,Node,i);
  8662.                                 }
  8663.                                 else
  8664.                                     break;
  8665.                             }
  8666.                         }
  8667.                         else
  8668.                         {
  8669.                             for(i = 0 ; i < Node -> Lines ; i++)
  8670.                             {
  8671.                                 if(Lines[i])
  8672.                                 {
  8673.                                     Node -> Special . Box . Lines[i] = Lines[i];
  8674.  
  8675.                                     LTK_PrintBoxLine(handle,Node,i);
  8676.                                 }
  8677.                                 else
  8678.                                     break;
  8679.                             }
  8680.                         }
  8681.                     }
  8682.  
  8683.                     break;
  8684.  
  8685.                 case GROUP_KIND:
  8686.  
  8687.                     if(Node -> Special . Group . Paging)
  8688.                     {
  8689.                         if(ThisTag = FindTagItem(LAGR_ActivePage,TagList))
  8690.                         {
  8691.                             ObjectNode *node;
  8692.  
  8693.                             if(node = LTK_FindNode(handle -> TopGroup,id))
  8694.                             {
  8695.                                 if(node -> Type == GROUP_KIND)
  8696.                                 {
  8697.                                     if(node -> Special . Group . ActivePage != ThisTag -> ti_Data)
  8698.                                     {
  8699.                                         node -> Special . Group . ActivePage = ThisTag -> ti_Data;
  8700.  
  8701.                                         LTK_SetPens(&handle -> RPort,handle -> BackgroundPen,0,JAM1);
  8702.                                         RectFill(&handle -> RPort,node -> Left,node -> Top,node -> Left+node -> Width - 1,node -> Top + node -> Height - 1);
  8703.  
  8704.                                         LT_Rebuild(handle,NULL,0,0,FALSE);
  8705.                                     }
  8706.                                 }
  8707.                             }
  8708.                         }
  8709.                     }
  8710.  
  8711.                     break;
  8712.             }
  8713.  
  8714.             if(ThisTag = FindTagItem(LA_LabelText,TagList))
  8715.                 Node -> Label = (STRPTR)ThisTag -> ti_Data;
  8716.  
  8717.             if(ThisTag = FindTagItem(LA_LabelID,TagList))
  8718.             {
  8719.                 if(handle -> LocaleHook)
  8720.                     Node -> Label = (STRPTR)CallHookPkt(handle -> LocaleHook,handle,(APTR)ThisTag -> ti_Data);
  8721.             }
  8722.  
  8723.             if(ThisTag = FindTagItem(GA_Disabled,TagList))
  8724.             {
  8725.                 if((Node -> Disabled && ThisTag -> ti_Data) || (!Node -> Disabled && !ThisTag -> ti_Data))
  8726.                 {
  8727.                     if(NewTags = CloneTagItems(TagList))
  8728.                         FilterTagItems(NewTags,Filter,TAGFILTER_NOT);
  8729.                 }
  8730.                 else
  8731.                 {
  8732.                     struct Gadget *gad;
  8733.  
  8734.                     Node -> Disabled = ThisTag -> ti_Data;
  8735.  
  8736.                     switch(Node -> Type)
  8737.                     {
  8738.                         case TEXT_KIND:
  8739.  
  8740.                             gad = Node -> Special . Text . Picker;
  8741.                             break;
  8742.  
  8743.                         case STRING_KIND:
  8744.  
  8745.                             gad = Node -> Special . String . Picker;
  8746.                             break;
  8747.  
  8748.                         case INTEGER_KIND:
  8749.  
  8750.                             if(gad = Node -> Special . Integer . LeftIncrementer)
  8751.                             {
  8752.                                 RemoveGList(handle -> Window,handle -> List,(UWORD)-1);
  8753.  
  8754.                                 if(Node -> Disabled)
  8755.                                     gad -> Flags |= GFLG_DISABLED;
  8756.                                 else
  8757.                                     gad -> Flags &= ~GFLG_DISABLED;
  8758.  
  8759.                                 AddGList(handle -> Window,handle -> List,(UWORD)-1,(UWORD)-1,NULL);
  8760.                                 RefreshGList(gad,handle -> Window,NULL,1);
  8761.                             }
  8762.  
  8763.                             gad = Node -> Special . Integer . RightIncrementer;
  8764.                             break;
  8765.  
  8766.                         case TAPEDECK_KIND:
  8767.  
  8768.                             gad = Node -> Host;
  8769.  
  8770.                             Gadget = NULL;
  8771.  
  8772.                             break;
  8773.  
  8774.                         default:
  8775.  
  8776.                             gad = NULL;
  8777.                             break;
  8778.                     }
  8779.  
  8780.                     if(gad)
  8781.                     {
  8782.                         RemoveGList(handle -> Window,handle -> List,(UWORD)-1);
  8783.  
  8784.                         if(Node -> Disabled)
  8785.                             gad -> Flags |= GFLG_DISABLED;
  8786.                         else
  8787.                             gad -> Flags &= ~GFLG_DISABLED;
  8788.  
  8789.                         AddGList(handle -> Window,handle -> List,(UWORD)-1,(UWORD)-1,NULL);
  8790.                         RefreshGList(gad,handle -> Window,NULL,1);
  8791.                     }
  8792.                 }
  8793.             }
  8794.  
  8795.             if(Exclude)
  8796.             {
  8797.                 ULONG Filter[2];
  8798.  
  8799.                 Filter[0] = Exclude;
  8800.                 Filter[1] = TAG_DONE;
  8801.  
  8802.                 if(!NewTags)
  8803.                     NewTags = CloneTagItems(TagList);
  8804.  
  8805.                 if(NewTags)
  8806.                     FilterTagItems(NewTags,Filter,TAGFILTER_NOT);
  8807.             }
  8808.  
  8809.             if(Gadget)
  8810.             {
  8811.                 struct TagItem *tags = TagList;
  8812.  
  8813.                 if(NewTags)
  8814.                     tags = NewTags;
  8815.  
  8816.                 if(!V39 && Node -> Disabled && Node -> Type == SLIDER_KIND)
  8817.                 {
  8818.                     GT_SetGadgetAttrs(Gadget,handle -> Window,NULL,
  8819.                         GA_Disabled,    FALSE,
  8820.                     TAG_MORE,tags);
  8821.  
  8822.                     GT_SetGadgetAttrs(Gadget,handle -> Window,NULL,
  8823.                         GA_Disabled,    TRUE,
  8824.                     TAG_DONE);
  8825.                 }
  8826.                 else
  8827.                     GT_SetGadgetAttrsA(Gadget,handle -> Window,NULL,tags);
  8828.  
  8829.                 if(Node -> Type == STRING_KIND || Node -> Type == FRACTION_KIND || Node -> Type == PASSWORD_KIND)
  8830.                     LTK_PutStorage(Node);
  8831.             }
  8832.  
  8833.             FreeTagItems(NewTags);
  8834.         }
  8835.     }
  8836. }
  8837.  
  8838.  
  8839. /*****************************************************************************/
  8840.  
  8841. VOID __stdargs
  8842. LT_Add(LayoutHandle *Handle,UBYTE Type,STRPTR Label,LONG ID,...)
  8843. {
  8844.     va_list VarArgs;
  8845.  
  8846.     va_start(VarArgs,ID);
  8847.     LT_AddA(Handle,Type,Label,ID,(struct TagItem *)VarArgs);
  8848.     va_end(VarArgs);
  8849. }
  8850.  
  8851. VOID LIBENT
  8852. LT_AddA(REG(a0) LayoutHandle *Handle,REG(d0) UBYTE Type,REG(d1) STRPTR Label,REG(d2) LONG ID,REG(a1) struct TagItem *TagList)
  8853. {
  8854.     struct TagItem *TagItem;
  8855.  
  8856.     if(!Handle || Handle -> Failed)
  8857.         return;
  8858.  
  8859. /*    if(ID > Handle -> MaxID)*/
  8860. /*        Handle -> MaxID = ID + 1;*/
  8861.  
  8862.     if(Type == VERTICAL_KIND || Type == HORIZONTAL_KIND || Handle -> TopGroup)
  8863.     {
  8864.         ObjectNode *Node;
  8865.  
  8866.         switch(Type)
  8867.         {
  8868.             case BUTTON_KIND:
  8869.  
  8870.                 Handle -> IDCMP |= BUTTONIDCMP;
  8871.                 break;
  8872.  
  8873.             case CHECKBOX_KIND:
  8874.  
  8875.                 Handle -> IDCMP |= CHECKBOXIDCMP;
  8876.                 break;
  8877.  
  8878.             case LISTVIEW_KIND:
  8879.  
  8880.                 Handle -> IDCMP |= LISTVIEWIDCMP;
  8881.                 break;
  8882.  
  8883.             case MX_KIND:
  8884.  
  8885.                 Handle -> IDCMP |= MXIDCMP;
  8886.                 break;
  8887.  
  8888.             case CYCLE_KIND:
  8889.  
  8890.                 Handle -> IDCMP |= CYCLEIDCMP;
  8891.                 break;
  8892.  
  8893.             case PALETTE_KIND:
  8894.  
  8895.                 Handle -> IDCMP |= PALETTEIDCMP;
  8896.                 break;
  8897.  
  8898.             case SLIDER_KIND:
  8899.  
  8900.                 Handle -> IDCMP |= SLIDERIDCMP;
  8901.                 break;
  8902.  
  8903.             case SCROLLER_KIND:
  8904.  
  8905.                 Handle -> IDCMP |= SCROLLERIDCMP | ARROWIDCMP;
  8906.                 break;
  8907.  
  8908.             case INTEGER_KIND:
  8909.  
  8910.                 Handle -> IDCMP |= STRINGIDCMP | IDCMP_GADGETDOWN | IDCMP_INTUITICKS;
  8911.                 break;
  8912.  
  8913.             case STRING_KIND:
  8914.             case FRACTION_KIND:
  8915.             case PASSWORD_KIND:
  8916.  
  8917.                 Handle -> IDCMP |= STRINGIDCMP | IDCMP_GADGETDOWN;
  8918.                 break;
  8919.  
  8920.             case END_KIND:
  8921.  
  8922.                 Handle -> CurrentGroup = Handle -> CurrentGroup -> Special . Group . ParentGroup;
  8923.                 return;
  8924.         }
  8925.  
  8926.         if(Node = LTK_CreateObjectNode(Handle,Type,ID,Label))
  8927.         {
  8928.             struct MinList    *ParentList;
  8929.             LONG         FirstLabel    = -1;
  8930.             LONG         LastLabel    = -1;
  8931.  
  8932.             Type = Node -> Type;
  8933.  
  8934.             if(Type == GROUP_KIND)
  8935.             {
  8936.                 Node -> LabelPlace            = PLACE_IN;
  8937.                 Node -> Special . Group . ParentGroup    = Handle -> CurrentGroup;
  8938.  
  8939.                 if(!Handle -> TopGroup)
  8940.                 {
  8941.                     Handle -> TopGroup = Node;
  8942.  
  8943.                     ParentList = NULL;
  8944.                 }
  8945.                 else
  8946.                     ParentList = &Handle -> CurrentGroup -> Special . Group . ObjectList;
  8947.  
  8948.                 Handle -> CurrentGroup = Node;
  8949.  
  8950.                 NewList(&Node -> Special . Group . ObjectList);
  8951.             }
  8952.             else
  8953.                 ParentList = &Handle -> CurrentGroup -> Special . Group . ObjectList;
  8954.  
  8955.             if(Label && !Node -> NoKey)
  8956.             {
  8957.                 ULONG Len;
  8958.  
  8959.                 Len = 0;
  8960.  
  8961.                 while(Label[Len])
  8962.                 {
  8963.                     if(Label[Len] == '_')
  8964.                     {
  8965.                         Node -> Key = ToLower(Label[Len + 1]);
  8966.  
  8967.                         break;
  8968.                     }
  8969.  
  8970.                     Len++;
  8971.                 }
  8972.             }
  8973.  
  8974.             if(TagList)
  8975.             {
  8976.                 struct TagItem *TempList = TagList;
  8977.  
  8978.                 while(!Handle -> Failed && (TagItem = NextTagItem(&TempList)))
  8979.                 {
  8980.                     switch(TagItem -> ti_Tag)
  8981.                     {
  8982.                         case LA_BYTE:
  8983.  
  8984.                             Node -> Storage        = (APTR)TagItem -> ti_Data;
  8985.                             Node -> StorageType    = STORAGE_BYTE;
  8986.  
  8987.                             LTK_GetStorage(Node);
  8988.  
  8989.                             break;
  8990.  
  8991.                         case LA_UBYTE:
  8992.  
  8993.                             Node -> Storage        = (APTR)TagItem -> ti_Data;
  8994.                             Node -> StorageType    = STORAGE_UBYTE;
  8995.  
  8996.                             LTK_GetStorage(Node);
  8997.  
  8998.                             break;
  8999.  
  9000.                         case LA_WORD:
  9001.  
  9002.                             Node -> Storage        = (APTR)TagItem -> ti_Data;
  9003.                             Node -> StorageType    = STORAGE_WORD;
  9004.  
  9005.                             LTK_GetStorage(Node);
  9006.  
  9007.                             break;
  9008.  
  9009.                         case LA_UWORD:
  9010.  
  9011.                             Node -> Storage        = (APTR)TagItem -> ti_Data;
  9012.                             Node -> StorageType    = STORAGE_UWORD;
  9013.  
  9014.                             LTK_GetStorage(Node);
  9015.  
  9016.                             break;
  9017.  
  9018.                         case LA_LONG:
  9019.  
  9020.                             Node -> Storage        = (APTR)TagItem -> ti_Data;
  9021.                             Node -> StorageType    = STORAGE_LONG;
  9022.  
  9023.                             LTK_GetStorage(Node);
  9024.  
  9025.                             break;
  9026.  
  9027.                         case LA_ULONG:
  9028.  
  9029.                             Node -> Storage        = (APTR)TagItem -> ti_Data;
  9030.                             Node -> StorageType    = STORAGE_ULONG;
  9031.  
  9032.                             LTK_GetStorage(Node);
  9033.  
  9034.                             break;
  9035.  
  9036.                         case LA_STRPTR:
  9037.  
  9038.                             Node -> Storage        = (APTR)TagItem -> ti_Data;
  9039.                             Node -> StorageType    = STORAGE_STRPTR;
  9040.  
  9041.                             LTK_GetStorage(Node);
  9042.  
  9043.                             break;
  9044.  
  9045.                         case LAXB_FullSize:
  9046.  
  9047.                             if(Type == XBAR_KIND || Type == YBAR_KIND)
  9048.                                 Node -> Special . Bar . FullSize = TagItem -> ti_Data;
  9049.  
  9050.                             break;
  9051.  
  9052.                         case LA_FirstLabel:
  9053.  
  9054.                             FirstLabel = TagItem -> ti_Data;
  9055.                             break;
  9056.  
  9057.                         case LA_LastLabel:
  9058.  
  9059.                             LastLabel = TagItem -> ti_Data;
  9060.                             break;
  9061.  
  9062.                         case LA_LastGadget:
  9063.  
  9064.                             if(Type == INTEGER_KIND)
  9065.                                 Node -> Special . Integer . LastGadget = TagItem -> ti_Data;
  9066.                             else
  9067.                             {
  9068.                                 if(Type == FRACTION_KIND || Type == STRING_KIND || Type == PASSWORD_KIND)
  9069.                                     Node -> Special . String . LastGadget = TagItem -> ti_Data;
  9070.                             }
  9071.  
  9072.                             break;
  9073.  
  9074.                         case LA_HistoryLines:
  9075.  
  9076.                             if(Type == INTEGER_KIND)
  9077.                                 Node -> Special . Integer . MaxHistoryLines = TagItem -> ti_Data;
  9078.                             else
  9079.                             {
  9080.                                 if(Type == FRACTION_KIND || Type == STRING_KIND || Type == PASSWORD_KIND)
  9081.                                     Node -> Special . String . MaxHistoryLines = TagItem -> ti_Data;
  9082.                             }
  9083.  
  9084.                             break;
  9085.  
  9086.                         case LA_HistoryHook:
  9087.  
  9088.                             if(Type == INTEGER_KIND)
  9089.                                 Node -> Special . Integer . HistoryHook = (struct Hook *)TagItem -> ti_Data;
  9090.                             else
  9091.                             {
  9092.                                 if(Type == FRACTION_KIND || Type == STRING_KIND)
  9093.                                     Node -> Special . String . HistoryHook = (struct Hook *)TagItem -> ti_Data;
  9094.                             }
  9095.  
  9096.                             break;
  9097.  
  9098.                         case LAIN_IncrementerHook:
  9099.  
  9100.                             if(Type == INTEGER_KIND)
  9101.                                 Node -> Special . Integer . IncrementerHook = (struct Hook *)TagItem -> ti_Data;
  9102.  
  9103.                             break;
  9104.  
  9105.                         case LA_Min:
  9106.  
  9107.                             if(Type == INTEGER_KIND)
  9108.                                 Node -> Special . Integer . Min = TagItem -> ti_Data;
  9109. #ifdef DO_FRACTION_KIND
  9110.                             else
  9111.                             {
  9112.                                 if(Type == FRACTION_KIND)
  9113.                                     Node -> Special . String . Min = TagItem -> ti_Data;
  9114.                             }
  9115. #endif
  9116.                             break;
  9117.  
  9118.                         case LA_Max:
  9119.  
  9120.                             if(Type == INTEGER_KIND)
  9121.                                 Node -> Special . Integer . Max = TagItem -> ti_Data;
  9122. #ifdef DO_FRACTION_KIND
  9123.                             else
  9124.                             {
  9125.                                 if(Type == FRACTION_KIND)
  9126.                                     Node -> Special . String . Max = TagItem -> ti_Data;
  9127.                             }
  9128. #endif
  9129.                             break;
  9130.  
  9131.                         case LABX_ReserveSpace:
  9132.  
  9133.                             if(Type == BOX_KIND)
  9134.                                 Node -> Special . Box . ReserveSpace = TagItem -> ti_Data;
  9135.  
  9136.                             break;
  9137.  
  9138.                         case LA_Chars:
  9139.  
  9140.                             Node -> Chars = TagItem -> ti_Data;
  9141.  
  9142.                             break;
  9143.  
  9144.                         case LA_LabelPlace:
  9145.  
  9146.                             Node -> LabelPlace = TagItem -> ti_Data;
  9147.  
  9148.                             if(Type == MX_KIND)
  9149.                             {
  9150.                                 if(TagItem -> ti_Data == PLACE_RIGHT)
  9151.                                     Node -> LabelPlace = PLACE_RIGHT;
  9152.                                 else
  9153.                                     Node -> LabelPlace = PLACE_LEFT;
  9154.                             }
  9155.  
  9156.                             break;
  9157.  
  9158.                         case LA_ExtraSpace:
  9159.  
  9160.                             Node -> ExtraSpace = (WORD)TagItem -> ti_Data;
  9161.  
  9162.                             if(Node -> ExtraSpace == 1)
  9163.                                 Node -> ExtraSpace = 3;
  9164.  
  9165.                             break;
  9166.  
  9167.                         case LA_Center:
  9168.  
  9169.                             Node -> Centered = TagItem -> ti_Data;
  9170.                             break;
  9171.  
  9172.                         case LA_PageSelector:
  9173.  
  9174.                             Node -> PageSelector = TagItem -> ti_Data;
  9175.                             break;
  9176.  
  9177.                         case LABT_ExtraFat:
  9178.  
  9179.                             if(Node -> Type == BUTTON_KIND)
  9180.                                 Node -> Special . Button . ExtraFat = TagItem -> ti_Data;
  9181.  
  9182.                             break;
  9183. #ifdef DO_PICKSHORTCUTS
  9184.                         case LA_NoKey:
  9185.  
  9186.                             Node -> NoKey = TagItem -> ti_Data;
  9187.                             break;
  9188. #endif
  9189.                         case LA_HighLabel:
  9190.  
  9191.                             Node -> HighLabel = TagItem -> ti_Data;
  9192.                             break;
  9193.  
  9194.                         case LAPA_SmallPalette:
  9195.  
  9196.                             if(Type == PALETTE_KIND)
  9197.                                 Node -> Special . Palette . SmallPalette = TagItem -> ti_Data;
  9198.  
  9199.                             break;
  9200.  
  9201.                         case LA_Lines:
  9202.  
  9203.                             if(Type == BOX_KIND)
  9204.                             {
  9205.                                 LONG Count = TagItem -> ti_Data;
  9206.  
  9207.                                 if(Node -> Lines != Count)
  9208.                                 {
  9209.                                     if(Node -> Special . Box . Lines)
  9210.                                     {
  9211.                                         LTK_Free(Handle,Node -> Special . Box . Lines,sizeof(STRPTR) * Node -> Lines);
  9212.  
  9213.                                         Node -> Special . Box . Lines = NULL;
  9214.                                     }
  9215.                                 }
  9216.  
  9217.                                 if(!Node -> Special . Box . Lines)
  9218.                                 {
  9219.                                     if(Node -> Special . Box . Lines = (STRPTR *)LTK_Alloc(Handle,sizeof(STRPTR) * Count))
  9220.                                     {
  9221.                                         LONG i;
  9222.  
  9223.                                         for(i = 0 ; i < Count ; i++)
  9224.                                             Node -> Special . Box . Lines[i] = "";
  9225.                                     }
  9226.                                     else
  9227.                                         Handle -> Failed = TRUE;
  9228.                                 }
  9229.                             }
  9230.  
  9231.                             Node -> Lines = TagItem -> ti_Data;
  9232.  
  9233.                             break;
  9234.  
  9235.                         case LA_Picker:
  9236.  
  9237.                             if(Type == TEXT_KIND)
  9238.                                 Node -> Special . Text . UsePicker = TagItem -> ti_Data;
  9239.  
  9240.                             if(Type == STRING_KIND)
  9241.                                 Node -> Special . String . UsePicker = TagItem -> ti_Data;
  9242.  
  9243.                             break;
  9244.  
  9245.                         case LAGR_Spread:
  9246.  
  9247.                             if(Type == GROUP_KIND)
  9248.                                 Node -> Special . Group . Spread = TagItem -> ti_Data;
  9249.  
  9250.                             break;
  9251.  
  9252.                         case LAGR_SameSize:
  9253.  
  9254.                             if(Type == GROUP_KIND)
  9255.                                 Node -> Special . Group . SameSize = TagItem -> ti_Data;
  9256.  
  9257.                             break;
  9258.  
  9259.                         case LAGR_LastAttributes:
  9260.  
  9261.                             if(Type == GROUP_KIND)
  9262.                                 Node -> Special . Group . LastAttributes = TagItem -> ti_Data;
  9263.  
  9264.                             break;
  9265.  
  9266.                         case LAGR_ActivePage:
  9267.  
  9268.                             if(Type == GROUP_KIND)
  9269.                             {
  9270.                                 Node -> Special . Group . ActivePage    = TagItem -> ti_Data;
  9271.                                 Node -> Special . Group . Paging    = TRUE;
  9272.                             }
  9273.  
  9274.                             break;
  9275.  
  9276.                         case LABT_ReturnKey:
  9277.  
  9278.                             if(Type == BUTTON_KIND)
  9279.                                 Node -> Special . Button . ReturnKey = TagItem -> ti_Data;
  9280.  
  9281.                             break;
  9282.  
  9283.                         case LABT_EscKey:
  9284.  
  9285.                             if(Type == BUTTON_KIND)
  9286.                                 Node -> Special . Button . EscKey = TagItem -> ti_Data;
  9287.  
  9288.                             break;
  9289.  
  9290.                         case LALV_CursorKey:
  9291.  
  9292.                             if(Type == LISTVIEW_KIND)
  9293.                                 Node -> Special . List . CursorKey = TagItem -> ti_Data;
  9294.  
  9295.                             break;
  9296.  
  9297.                         case LALV_MaxGrowX:
  9298.  
  9299.                             if(Type == LISTVIEW_KIND)
  9300.                             {
  9301.                                 Handle -> GrowView = Node;
  9302.  
  9303.                                 Node -> Special . List . MaxGrowX = TagItem -> ti_Data;
  9304.                             }
  9305.  
  9306.                             break;
  9307.  
  9308.                         case LALV_MaxGrowY:
  9309.  
  9310.                             if(Type == LISTVIEW_KIND)
  9311.                             {
  9312.                                 Handle -> GrowView = Node;
  9313.  
  9314.                                 Node -> Special . List . MaxGrowY = TagItem -> ti_Data;
  9315.                             }
  9316.  
  9317.                             break;
  9318.  
  9319.                         case LALV_Labels:
  9320.  
  9321.                             if(Type == LISTVIEW_KIND)
  9322.                             {
  9323.                                 STRPTR *Labels = (STRPTR *)TagItem -> ti_Data;
  9324.  
  9325.                                 if(*Labels)
  9326.                                 {
  9327.                                     struct List *SomeList;
  9328.  
  9329.                                     if(SomeList = LTK_Alloc(Handle,sizeof(struct List)))
  9330.                                     {
  9331.                                         struct Node *SomeNode;
  9332.  
  9333.                                         NewList(SomeList);
  9334.  
  9335.                                         Node -> Special . List . Labels = SomeList;
  9336.  
  9337.                                         while(*Labels)
  9338.                                         {
  9339.                                             if(SomeNode = LTK_Alloc(Handle,sizeof(struct Node) + strlen(*Labels) + 1))
  9340.                                             {
  9341.                                                 SomeNode -> ln_Name = (STRPTR)(SomeNode + 1);
  9342.  
  9343.                                                 strcpy(SomeNode -> ln_Name,*Labels++);
  9344.  
  9345.                                                 AddTail(SomeList,SomeNode);
  9346.                                             }
  9347.                                         }
  9348.                                     }
  9349.                                 }
  9350.                             }
  9351.  
  9352.                             break;
  9353.  
  9354.                         case LA_Link:
  9355.  
  9356.                             if(Type == LISTVIEW_KIND)
  9357.                                 Node -> Special . List . LinkID = TagItem -> ti_Data;
  9358.  
  9359.                             if(Type == STRING_KIND || Type == FRACTION_KIND)
  9360.                                 Node -> Special . String . LinkID = TagItem -> ti_Data;
  9361.  
  9362.                             break;
  9363.  
  9364. #ifdef DO_TAPEDECK_KIND
  9365.                         case LATD_ButtonType:
  9366.  
  9367.                             if(Type == TAPEDECK_KIND)
  9368.                                 Node -> Special . TapeDeck . ButtonType = TagItem -> ti_Data;
  9369.  
  9370.                             break;
  9371.  
  9372.                         case LATD_Toggle:
  9373.  
  9374.                             if(Type == TAPEDECK_KIND)
  9375.                                 Node -> Special . TapeDeck . Toggle = TagItem -> ti_Data;
  9376.  
  9377.                             break;
  9378.  
  9379.                         case LATD_Pressed:
  9380.  
  9381.                             if(Type == TAPEDECK_KIND)
  9382.                                 Node -> Current = TagItem -> ti_Data;
  9383.  
  9384.                             break;
  9385.  
  9386.                         case LATD_Smaller:
  9387.  
  9388.                             if(Type == TAPEDECK_KIND)
  9389.                                 Node -> Special . TapeDeck . Smaller = TagItem -> ti_Data;
  9390.  
  9391.                             break;
  9392. #endif    /* DO_TAPEDECK_KIND */
  9393.  
  9394. #ifdef DO_GAUGE_KIND
  9395.                         case LAGA_Percent:
  9396.  
  9397.                             if(Type == GAUGE_KIND)
  9398.                             {
  9399.                                 LONG Percent = (LONG)TagItem -> ti_Data;
  9400.  
  9401.                                 if(Percent <= 0)
  9402.                                     Node -> Current = 0;
  9403.                                 else
  9404.                                 {
  9405.                                     if(Percent > 100)
  9406.                                         Node -> Current = 100;
  9407.                                     else
  9408.                                         Node -> Current = Percent;
  9409.                                 }
  9410.                             }
  9411.  
  9412.                             break;
  9413.  
  9414.                         case LAGA_InfoLength:
  9415.  
  9416.                             if(Type == GAUGE_KIND)
  9417.                             {
  9418.                                 LONG Length = (LONG)TagItem -> ti_Data;
  9419.  
  9420.                                 if(Length > Node -> Special . Gauge . InfoLength)
  9421.                                 {
  9422.                                     STRPTR NewText;
  9423.  
  9424.                                     if(NewText = (STRPTR)AsmAllocPooled(Handle -> Pool,Length + 1,SysBase))
  9425.                                     {
  9426.                                         if(Node -> Special . Gauge . InfoText)
  9427.                                         {
  9428.                                             strcpy(NewText,Node -> Special . Gauge . InfoText);
  9429.  
  9430.                                             AsmFreePooled(Handle -> Pool,Node -> Special . Gauge . InfoText,Node -> Special . Gauge . InfoLength + 1,SysBase);
  9431.                                         }
  9432.  
  9433.                                         NewText[0] = 0;
  9434.  
  9435.                                         Node -> Special . Gauge . InfoText    = NewText;
  9436.                                         Node -> Special . Gauge . InfoLength    = Length;
  9437.                                     }
  9438.                                     else
  9439.                                         Handle -> Failed = TRUE;
  9440.                                 }
  9441.                             }
  9442.  
  9443.                             break;
  9444.  
  9445.                         case LAGA_InfoText:
  9446.  
  9447.                             if(Type == GAUGE_KIND)
  9448.                             {
  9449.                                 STRPTR    SomeText    = (STRPTR)TagItem -> ti_Data;
  9450.                                 LONG    Len        = strlen(SomeText);
  9451.  
  9452.                                 if(!Node -> Special . Gauge . InfoLength)
  9453.                                 {
  9454.                                     if(Node -> Special . Gauge . InfoText = (STRPTR)AsmAllocPooled(Handle -> Pool,Len + 1,SysBase))
  9455.                                         Node -> Special . Gauge . InfoLength = Len;
  9456.                                     else
  9457.                                         Handle -> Failed = TRUE;
  9458.                                 }
  9459.  
  9460.                                 if(Node -> Special . Gauge . InfoLength)
  9461.                                 {
  9462.                                     if(Len > Node -> Special . Gauge . InfoLength)
  9463.                                         Len = Node -> Special . Gauge . InfoLength;
  9464.  
  9465.                                     CopyMem(SomeText,Node -> Special . Gauge . InfoText,Len);
  9466.  
  9467.                                     Node -> Special . Gauge . InfoText[Len] = 0;
  9468.                                 }
  9469.                             }
  9470.  
  9471.                             break;
  9472. #endif
  9473.                         case LALV_ExtraLabels:
  9474.  
  9475.                             if(Type == LISTVIEW_KIND)
  9476.                                 Node -> Special . List . ExtraLabels = (STRPTR *)TagItem -> ti_Data;
  9477.  
  9478.                             break;
  9479.  
  9480.                         case LAFR_InnerWidth:
  9481.  
  9482.                             if(Type == FRAME_KIND)
  9483.                                 Node -> Special . Frame . InnerWidth = TagItem -> ti_Data;
  9484.  
  9485.                             break;
  9486.  
  9487.                         case LAFR_InnerHeight:
  9488.  
  9489.                             if(Type == FRAME_KIND)
  9490.                                 Node -> Special . Frame . InnerHeight = TagItem -> ti_Data;
  9491.  
  9492.                             break;
  9493.  
  9494.                         case LA_DrawBox:
  9495.  
  9496.                             if(Type == FRAME_KIND)
  9497.                                 Node -> Special . Frame . DrawBox = TagItem -> ti_Data;
  9498.  
  9499.                             if(Type == BOX_KIND)
  9500.                                 Node -> Special . Box . DrawBox = TagItem -> ti_Data;
  9501.  
  9502.                             break;
  9503.  
  9504.                         case LABX_AlignText:
  9505.  
  9506.                             if(Type == BOX_KIND)
  9507.                                 Node -> Special . Box . AlignText = TagItem -> ti_Data;
  9508.  
  9509.                             break;
  9510.  
  9511.                         case LABX_Labels:
  9512.  
  9513.                             if(Type == BOX_KIND)
  9514.                             {
  9515.                                 STRPTR    *Labels    = (STRPTR *)TagItem -> ti_Data;
  9516.                                 LONG     Count    = 0;
  9517.  
  9518.                                 while(Labels[Count])
  9519.                                     Count++;
  9520.  
  9521.                                 if(Node -> Lines != Count)
  9522.                                 {
  9523.                                     if(Node -> Special . Box . Lines)
  9524.                                     {
  9525.                                         LTK_Free(Handle,Node -> Special . Box . Lines,sizeof(STRPTR) * Node -> Lines);
  9526.  
  9527.                                         Node -> Special . Box . Lines = NULL;
  9528.                                     }
  9529.                                 }
  9530.  
  9531.                                 if(Count)
  9532.                                 {
  9533.                                     if(!Node -> Special . Box . Lines)
  9534.                                     {
  9535.                                         if(Node -> Special . Box . Lines = LTK_Alloc(Handle,sizeof(STRPTR) * Count))
  9536.                                         {
  9537.                                             LONG i;
  9538.  
  9539.                                             for(i = 0 ; i < Count ; i++)
  9540.                                                 Node -> Special . Box . Lines[i] = "";
  9541.                                         }
  9542.                                     }
  9543.                                 }
  9544.  
  9545.                                 Node -> Lines = Count;
  9546.  
  9547.                                 Node -> Special . Box . Labels = Labels;
  9548.                             }
  9549.  
  9550.                             break;
  9551.  
  9552.                         case LABX_Lines:
  9553.  
  9554.                             if(Type == BOX_KIND)
  9555.                             {
  9556.                                 STRPTR    *Lines = (STRPTR *)TagItem -> ti_Data;
  9557.                                 LONG     Count = 0;
  9558.  
  9559.                                 while(Lines[Count])
  9560.                                     Count++;
  9561.  
  9562.                                 if(Node -> Lines && Count > Node -> Lines)
  9563.                                     Count = Node -> Lines;
  9564.  
  9565.                                 if(Count)
  9566.                                 {
  9567.                                     if(!Node -> Special . Box . Lines)
  9568.                                         Node -> Special . Box . Lines = LTK_Alloc(Handle,sizeof(STRPTR) * Count);
  9569.  
  9570.                                     if(Node -> Special . Box . Lines)
  9571.                                     {
  9572.                                         LONG i;
  9573.  
  9574.                                         for(i = 0 ; i < Count ; i++)
  9575.                                             Node -> Special . Box . Lines[i] = Lines[i];
  9576.                                     }
  9577.                                 }
  9578.  
  9579.                                 Node -> Lines = Count;
  9580.                             }
  9581.  
  9582.                             break;
  9583.  
  9584.                         case GA_Disabled:
  9585.  
  9586.                             Node -> Disabled = TagItem -> ti_Data;
  9587.                             break;
  9588.  
  9589.                         case GTCB_Checked:
  9590.  
  9591.                             if(Type == CHECKBOX_KIND)
  9592.                                 Node -> Current = TagItem -> ti_Data;
  9593.  
  9594.                             break;
  9595.  
  9596.                         case GTLV_Labels:
  9597.  
  9598.                             if(Type == LISTVIEW_KIND)
  9599.                                 Node -> Special . List . Labels = (struct List *)TagItem -> ti_Data;
  9600.  
  9601.                             break;
  9602.  
  9603.                         case GTLV_ReadOnly:
  9604.  
  9605.                             if(Type == LISTVIEW_KIND)
  9606.                                 Node -> Special . List . ReadOnly = TagItem -> ti_Data;
  9607.  
  9608.                             break;
  9609.  
  9610.                         case GTLV_MakeVisible:
  9611.                         case GTLV_Selected:
  9612.  
  9613.                             if(Type == LISTVIEW_KIND)
  9614.                                 Node -> Current = (LONG)TagItem -> ti_Data;
  9615.  
  9616.                             break;
  9617.  
  9618.                         case GTLV_CallBack:
  9619.  
  9620.                             if(Type == LISTVIEW_KIND)
  9621.                                 Node -> Special . List . CallBack = (struct Hook *)TagItem -> ti_Data;
  9622.  
  9623.                             break;
  9624.  
  9625.                         case GTLV_MaxPen:
  9626.  
  9627.                             if(Type == LISTVIEW_KIND)
  9628.                                 Node -> Special . List . MaxPen = TagItem -> ti_Data;
  9629.  
  9630.                             break;
  9631.  
  9632.                         case GTMX_Labels:
  9633.  
  9634.                             if(Type == MX_KIND)
  9635.                                 Node -> Special . Radio . Choices = (STRPTR *)TagItem -> ti_Data;
  9636.  
  9637.                             break;
  9638.  
  9639.                         case GTMX_Active:
  9640.  
  9641.                             if(Type == MX_KIND)
  9642.                                 Node -> Current = TagItem -> ti_Data;
  9643.  
  9644.                             break;
  9645.  
  9646.                         case GTMX_TitlePlace:
  9647.  
  9648.                             if(Type == MX_KIND && Label)
  9649.                             {
  9650.                                 if(TagItem -> ti_Data == PLACE_RIGHT)
  9651.                                     Node -> Special . Radio . TitlePlace = PLACETEXT_RIGHT;
  9652.                                 else
  9653.                                     Node -> Special . Radio . TitlePlace = PLACETEXT_LEFT;
  9654.                             }
  9655.  
  9656.                             break;
  9657.  
  9658.                         case GTTX_Text:
  9659.  
  9660.                             if(Type == TEXT_KIND)
  9661.                                 Node -> Special . Text . Text = (STRPTR)TagItem -> ti_Data;
  9662.  
  9663.                             break;
  9664.  
  9665.                         case GTTX_CopyText:
  9666.  
  9667.                             if(Type == TEXT_KIND)
  9668.                                 Node -> Special . Text . CopyText = TagItem -> ti_Data;
  9669.  
  9670.                             break;
  9671.  
  9672.                         case GTTX_Border:
  9673.  
  9674.                             if(Type == TEXT_KIND)
  9675.                                 Node -> Special . Text . Border = TagItem -> ti_Data;
  9676.  
  9677.                             break;
  9678.  
  9679.                         case GTNM_Number:
  9680.  
  9681.                             if(Type == NUMBER_KIND)
  9682.                                 Node -> Special . Number . Number = TagItem -> ti_Data;
  9683.  
  9684.                             break;
  9685.  
  9686.                         case GTNM_Border:
  9687.  
  9688.                             if(Type == NUMBER_KIND)
  9689.                                 Node -> Special . Number . Border = TagItem -> ti_Data;
  9690.  
  9691.                             break;
  9692.  
  9693.                         case GTTX_Justification:
  9694.  
  9695.                             if(Type == NUMBER_KIND)
  9696.                                 Node -> Special . Number . Justification = TagItem -> ti_Data;
  9697.  
  9698.                             if(Type == TEXT_KIND)
  9699.                                 Node -> Special . Text . Justification = TagItem -> ti_Data;
  9700.  
  9701.                             break;
  9702.  
  9703.                         case GTCY_Labels:
  9704.  
  9705.                             if(Type == CYCLE_KIND)
  9706.                                 Node -> Special . Cycle . Choices = (STRPTR *)TagItem -> ti_Data;
  9707.  
  9708.                             break;
  9709.  
  9710.                         case GTCY_Active:
  9711.  
  9712.                             if(Type == CYCLE_KIND)
  9713.                                 Node -> Current = TagItem -> ti_Data;
  9714.  
  9715.                             break;
  9716.  
  9717.                         case GTPA_Depth:
  9718.  
  9719.                             if(Type == PALETTE_KIND)
  9720.                             {
  9721.                                 Node -> Special . Palette . Depth = TagItem -> ti_Data;
  9722.  
  9723.                                 if(Handle -> MaxPen < (1L << Node -> Special . Palette . Depth) - 1)
  9724.                                     Handle -> MaxPen = (1L << Node -> Special . Palette . Depth) - 1;
  9725.                             }
  9726.  
  9727.                             break;
  9728.  
  9729.                         case GTPA_Color:
  9730.  
  9731.                             if(Type == PALETTE_KIND)
  9732.                                 Node -> Current = TagItem -> ti_Data;
  9733.  
  9734.                             break;
  9735.  
  9736.                         case GTPA_ColorOffset:
  9737.  
  9738.                             if(Type == PALETTE_KIND)
  9739.                                 Node -> Min = TagItem -> ti_Data;
  9740.  
  9741.                             break;
  9742.  
  9743.                         case GTPA_NumColors:
  9744.  
  9745.                             if(Type == PALETTE_KIND)
  9746.                             {
  9747.                                 Node -> Special . Palette . NumColours = TagItem -> ti_Data;
  9748.  
  9749.                                 if(Node -> Special . Palette . ColourTable)
  9750.                                 {
  9751.                                     LONG i;
  9752.  
  9753.                                     for(i = 0 ; i < Node -> Special . Palette . NumColours ; i++)
  9754.                                     {
  9755.                                         if(Node -> Special . Palette . ColourTable[i] > Handle -> MaxPen)
  9756.                                             Handle -> MaxPen = Node -> Special . Palette . ColourTable[i];
  9757.                                     }
  9758.                                 }
  9759.                             }
  9760.  
  9761.                             break;
  9762.  
  9763.                         case GTPA_ColorTable:
  9764.  
  9765.                             if(Type == PALETTE_KIND)
  9766.                             {
  9767.                                 Node -> Special . Palette . ColourTable = (UBYTE *)TagItem -> ti_Data;
  9768.  
  9769.                                 if(Node -> Special . Palette . NumColours)
  9770.                                 {
  9771.                                     LONG i;
  9772.  
  9773.                                     for(i = 0 ; i < Node -> Special . Palette . NumColours ; i++)
  9774.                                     {
  9775.                                         if(Node -> Special . Palette . ColourTable[i] > Handle -> MaxPen)
  9776.                                             Handle -> MaxPen = Node -> Special . Palette . ColourTable[i];
  9777.                                     }
  9778.                                 }
  9779.                             }
  9780.  
  9781.                             break;
  9782.  
  9783.                         case GTSC_Top:
  9784.  
  9785.                             if(Type == SCROLLER_KIND)
  9786.                                 Node -> Current = TagItem -> ti_Data;
  9787.  
  9788.                             break;
  9789.  
  9790.                         case GTSC_Total:
  9791.  
  9792.                             if(Type == SCROLLER_KIND)
  9793.                                 Node -> Max = TagItem -> ti_Data;
  9794.  
  9795.                             break;
  9796.  
  9797.                         case GTSC_Visible:
  9798.  
  9799.                             if(Type == SCROLLER_KIND)
  9800.                                 Node -> Special . Scroller . Visible = TagItem -> ti_Data;
  9801.  
  9802.                             break;
  9803.  
  9804.                         case GTSC_Arrows:
  9805.  
  9806.                             if(Type == SCROLLER_KIND)
  9807.                                 Node -> Special . Scroller . Arrows = (TagItem -> ti_Data != 0);
  9808.  
  9809.                             break;
  9810.  
  9811.                         case LASC_Thin:
  9812.  
  9813.                             if(Type == SCROLLER_KIND)
  9814.                                 Node -> Special . Scroller . Thin = TagItem -> ti_Data;
  9815.  
  9816.                             break;
  9817.  
  9818.                         case PGA_Freedom:
  9819.  
  9820.                             if(Type == SCROLLER_KIND)
  9821.                                 Node -> Special . Scroller . Vertical = (TagItem -> ti_Data == LORIENT_VERT);
  9822.  
  9823.                             break;
  9824.  
  9825.                         case GTSL_Min:
  9826.  
  9827.                             if(Type == SLIDER_KIND)
  9828.                                 Node -> Min = TagItem -> ti_Data;
  9829.  
  9830.                             break;
  9831.  
  9832.                         case GTSL_Max:
  9833.  
  9834.                             if(Type == SLIDER_KIND)
  9835.                                 Node -> Max = TagItem -> ti_Data;
  9836.  
  9837.                             break;
  9838.  
  9839.                         case GTSL_Level:
  9840.  
  9841.                             if(Type == SLIDER_KIND)
  9842.                                 Node -> Current = TagItem -> ti_Data;
  9843.  
  9844.                             break;
  9845.  
  9846.                         case GTSL_LevelFormat:
  9847.  
  9848.                             if(Type == SLIDER_KIND)
  9849.                                 Node -> Special . Slider . LevelFormat = (STRPTR)TagItem -> ti_Data;
  9850.  
  9851.                             break;
  9852.  
  9853.                         case GTSL_LevelPlace:
  9854.  
  9855.                             if(Type == SLIDER_KIND)
  9856.                             {
  9857.                                 if(TagItem -> ti_Data == PLACE_RIGHT)
  9858.                                     Node -> Special . Slider . LevelPlace = PLACETEXT_RIGHT;
  9859.                                 else
  9860.                                     Node -> Special . Slider . LevelPlace = PLACETEXT_LEFT;
  9861.                             }
  9862.  
  9863.                             break;
  9864.  
  9865.                         case GTSL_DispFunc:
  9866.  
  9867.                             if(Type == SLIDER_KIND)
  9868.                             {
  9869.                                 APTR p = (APTR)TagItem -> ti_Data;
  9870.  
  9871.                                 Node -> Special . Slider . DispFunc = (DISPFUNC)p;
  9872.                             }
  9873.  
  9874.                             break;
  9875.  
  9876.                         case LASL_FullCheck:
  9877.  
  9878.                             if(Type == SLIDER_KIND)
  9879.                                 Node -> Special . Slider . FullLevelCheck = TagItem -> ti_Data;
  9880.  
  9881.                             break;
  9882.  
  9883.                         case GTST_String:
  9884.  
  9885.                             if(Type == STRING_KIND || Type == PASSWORD_KIND)
  9886.                                 Node -> Special . String . String = (STRPTR)TagItem -> ti_Data;
  9887.  
  9888.                             break;
  9889.  
  9890.                         case GTST_MaxChars:
  9891.  
  9892.                             if(Type == STRING_KIND || Type == PASSWORD_KIND)
  9893.                                 Node -> Special . String . MaxChars = TagItem -> ti_Data;
  9894.  
  9895.                             break;
  9896.  
  9897.                         case GTST_EditHook:
  9898.  
  9899.                             if(Type == STRING_KIND)
  9900.                                 Node -> Special . String . EditHook = (struct Hook *)TagItem -> ti_Data;
  9901.                             else
  9902.                             {
  9903.                                 if(Type == INTEGER_KIND)
  9904.                                     Node -> Special . Integer . EditHook = (struct Hook *)TagItem -> ti_Data;
  9905.                             }
  9906.  
  9907.                             break;
  9908.  
  9909.                         case STRINGA_Justification:
  9910.  
  9911.                             if(Type == STRING_KIND || Type == FRACTION_KIND || Type == PASSWORD_KIND)
  9912.                                 Node -> Special . String . Justification = TagItem -> ti_Data;
  9913.                             else
  9914.                             {
  9915.                                 if(Type == INTEGER_KIND)
  9916.                                     Node -> Special . Integer . Justification = TagItem -> ti_Data;
  9917.                             }
  9918.  
  9919.                             break;
  9920. #ifdef DO_FRACTION_KIND
  9921.                         case LAFC_MaxChars:
  9922.  
  9923.                             if(Type == FRACTION_KIND)
  9924.                                 Node -> Special . String . MaxChars = TagItem -> ti_Data;
  9925.  
  9926.                             break;
  9927.  
  9928.                         case LAFC_Number:
  9929.  
  9930.                             if(Type == FRACTION_KIND)
  9931.                                 Node -> Current = TagItem -> ti_Data;
  9932.  
  9933.                             break;
  9934. #endif
  9935.                         case LAIN_UseIncrementers:
  9936.  
  9937.                             if(Type == INTEGER_KIND)
  9938.                             {
  9939.                                 if(Node -> Special . Integer . UseIncrementers = TagItem -> ti_Data)
  9940.                                     Handle -> IDCMP |= IDCMP_INTUITICKS;
  9941.                             }
  9942.  
  9943.                             break;
  9944.  
  9945.                         case GTIN_Number:
  9946.  
  9947.                             if(Type == INTEGER_KIND)
  9948.                                 Node -> Special . Integer . Number = TagItem -> ti_Data;
  9949.  
  9950.                             break;
  9951.  
  9952.                         case GTIN_MaxChars:
  9953.  
  9954.                             if(Type == INTEGER_KIND)
  9955.                                 Node -> Special . Integer . MaxChars = TagItem -> ti_Data;
  9956.  
  9957.                             break;
  9958.                     }
  9959.                 }
  9960.             }
  9961.  
  9962.             if(Handle -> Failed)
  9963.                 return;
  9964.  
  9965.             if((Type == FRACTION_KIND || Type == STRING_KIND || Type == INTEGER_KIND) && Node -> Special . String . MaxHistoryLines)
  9966.             {
  9967.                 if(!Node -> Special . Integer . HistoryHook)
  9968.                 {
  9969.                     struct Hook *Hook;
  9970.  
  9971.                     if(Hook = (struct Hook *)LTK_Alloc(Handle,sizeof(struct Hook) + sizeof(struct MinList)))
  9972.                     {
  9973.                         struct MinList *List;
  9974.  
  9975.                         List = Hook -> h_Data = (APTR)(Hook + 1);
  9976.  
  9977.                         NewList((struct List *)List);
  9978.  
  9979.                         Hook -> h_Entry = (HOOKFUNC)LTK_DefaultHistoryHook;
  9980.  
  9981.                         Node -> Special . Integer . HistoryHook = Hook;
  9982.                     }
  9983.                 }
  9984.  
  9985.                 if(Node -> Special . Integer . HistoryHook)
  9986.                 {
  9987.                     struct Node    *TextNode;
  9988.                     struct MinList    *List = (struct List *)Node -> Special . Integer . HistoryHook -> h_Data;
  9989.  
  9990.                     Node -> Special . Integer . LayoutHandle    = Handle;
  9991.                     Node -> Special . Integer . NumHistoryLines    = 0;
  9992.  
  9993.                     TextNode = (struct Node *)List -> mlh_Head;
  9994.  
  9995.                     while(TextNode -> ln_Succ)
  9996.                     {
  9997.                         Node -> Special . Integer . NumHistoryLines++;
  9998.  
  9999.                         TextNode = TextNode -> ln_Succ;
  10000.                     }
  10001.                 }
  10002.             }
  10003.  
  10004.             if(Type == TEXT_KIND && Node -> Special . Text . CopyText && Node -> Special . Text . Text)
  10005.             {
  10006.                 LONG    len;
  10007.                 STRPTR    text;
  10008.  
  10009.                 len = strlen(Node -> Special . Text . Text);
  10010.  
  10011.                 if(text = LTK_Alloc(Handle,len + 1))
  10012.                 {
  10013.                     strcpy(text,Node -> Special . Text . Text);
  10014.  
  10015.                     Node -> Special . Text . Text = text;
  10016.                 }
  10017.             }
  10018.  
  10019.             if(FirstLabel != -1 && LastLabel != -1)
  10020.             {
  10021.                 if(Type == MX_KIND || Type == CYCLE_KIND || Type == LISTVIEW_KIND || Type == BOX_KIND)
  10022.                 {
  10023.                     if(!Handle -> LocaleHook)
  10024.                         Handle -> Failed = TRUE;
  10025.                     else
  10026.                     {
  10027.                         if(Type == LISTVIEW_KIND)
  10028.                         {
  10029.                             struct List *SomeList;
  10030.  
  10031.                             if(SomeList = (struct List *)LTK_Alloc(Handle,sizeof(struct List)))
  10032.                             {
  10033.                                 struct Node    *SomeNode;
  10034.                                 LONG         Count = (LastLabel - FirstLabel + 1),i;
  10035.  
  10036.                                 NewList(SomeList);
  10037.  
  10038.                                 Node -> Special . List . Labels = SomeList;
  10039.  
  10040.                                 for(i = 0 ; i < Count ; i++)
  10041.                                 {
  10042.                                     if(SomeNode = LTK_Alloc(Handle,sizeof(struct Node)))
  10043.                                     {
  10044.                                         SomeNode -> ln_Name = (STRPTR)CallHookPkt(Handle -> LocaleHook,Handle,(APTR)(FirstLabel + i));
  10045.  
  10046.                                         AddTail(SomeList,SomeNode);
  10047.                                     }
  10048.                                 }
  10049.                             }
  10050.                         }
  10051.                         else
  10052.                         {
  10053.                             STRPTR    *Labels;
  10054.                             LONG     Count = (LastLabel - FirstLabel + 1),i;
  10055.  
  10056.                             if(Labels = LTK_Alloc(Handle,sizeof(STRPTR) * (Count + 1)))
  10057.                             {
  10058.                                 for(i = 0 ; i < Count ; i++)
  10059.                                     Labels[i] = (STRPTR)CallHookPkt(Handle -> LocaleHook,Handle,(APTR)(FirstLabel + i));
  10060.  
  10061.                                 Labels[i] = NULL;
  10062.  
  10063.                                 if(Type == MX_KIND)
  10064.                                     Node -> Special . Radio . Choices = Labels;
  10065.                                 else
  10066.                                 {
  10067.                                     if(Type == CYCLE_KIND)
  10068.                                         Node -> Special . Cycle . Choices = Labels;
  10069.                                     else
  10070.                                     {
  10071.                                         if(Type == BOX_KIND)
  10072.                                         {
  10073.                                             if(!Node -> Special . Box . Lines)
  10074.                                             {
  10075.                                                 if(Node -> Special . Box . Lines = LTK_Alloc(Handle,sizeof(STRPTR) * Count))
  10076.                                                 {
  10077.                                                     LONG i;
  10078.  
  10079.                                                     for(i = 0 ; i < Count ; i++)
  10080.                                                         Node -> Special . Box . Lines[i] = "";
  10081.                                                 }
  10082.                                             }
  10083.  
  10084.                                             Node -> Lines = Count;
  10085.  
  10086.                                             Node -> Special . Box . Labels = Labels;
  10087.                                         }
  10088.                                     }
  10089.                                 }
  10090.                             }
  10091.                         }
  10092.                     }
  10093.                 }
  10094.             }
  10095.  
  10096.             if(Type == BOX_KIND && Node -> Special . Box . ReserveSpace)
  10097.             {
  10098.                 LONG    Size;
  10099.                 STRPTR    Buffer;
  10100.  
  10101.                 if(!Node -> Special . Box . Lines)
  10102.                 {
  10103.                     if(Node -> Special . Box . Lines = LTK_Alloc(Handle,sizeof(STRPTR) * Node -> Lines))
  10104.                     {
  10105.                         LONG i;
  10106.  
  10107.                         for(i = 0 ; i < Node -> Lines ; i++)
  10108.                             Node -> Special . Box . Lines[i] = "";
  10109.                     }
  10110.                 }
  10111.  
  10112.                 if(!Node -> Chars)
  10113.                     Size = 10;
  10114.                 else
  10115.                     Size = Node -> Chars;
  10116.  
  10117.                 Node -> Special . Box . MaxSize = Size;
  10118.  
  10119.                 if(Buffer = (STRPTR)LTK_Alloc(Handle,(Size + 1) * Node -> Lines))
  10120.                 {
  10121.                     LONG i,Len;
  10122.  
  10123.                     for(i = 0 ; i < Node -> Lines ; i++)
  10124.                     {
  10125.                         if(Node -> Special . Box . Lines[i])
  10126.                         {
  10127.                             Len = strlen(Node -> Special . Box . Lines[i]);
  10128.  
  10129.                             if(Len > Size)
  10130.                                 Len = Size;
  10131.  
  10132.                             CopyMem(Node -> Special . Box . Lines[i],Buffer,Len);
  10133.  
  10134.                             Buffer[Len] = 0;
  10135.                         }
  10136.                         else
  10137.                             Buffer[0] = 0;
  10138.  
  10139.                         Node -> Special . Box . Lines[i] = Buffer;
  10140.  
  10141.                         Buffer += Size + 1;
  10142.                     }
  10143.                 }
  10144.             }
  10145.  
  10146.             if(Handle -> Failed)
  10147.                 return;
  10148.  
  10149.             if(ParentList)
  10150.             {
  10151. #ifdef DO_PASSWORD_KIND
  10152.                 if(Type == PASSWORD_KIND)
  10153.                 {
  10154.                     STRPTR Buffer;
  10155.  
  10156.                     if(!(Buffer = LTK_Alloc(Handle,2 * (Node -> Special . String . MaxChars + 1))))
  10157.                         return;
  10158.  
  10159.                     Node -> Special . String . RealString    = Buffer;
  10160.                     Node -> Special . String . Original    = Buffer + Node -> Special . String . MaxChars + 1;
  10161.  
  10162.                     if(Node -> Special . String . String)
  10163.                     {
  10164.                         strcpy(Node -> Special . String . RealString,    Node -> Special . String . String);
  10165.                         strcpy(Node -> Special . String . Original,    Node -> Special . String . String);
  10166.                     }
  10167.                 }
  10168. #endif
  10169.                 AddTail((struct List *)ParentList,(struct Node *)Node);
  10170.  
  10171.                 if(Type == XBAR_KIND || Type == YBAR_KIND)
  10172.                     Node -> Special . Bar . Parent = Handle -> CurrentGroup;
  10173.             }
  10174.         }
  10175.     }
  10176. }
  10177.  
  10178.  
  10179. /*****************************************************************************/
  10180.  
  10181.  
  10182. VOID __stdargs
  10183. LT_AddL(LayoutHandle *handle,UBYTE type,ULONG labelID,LONG id,...)
  10184. {
  10185.     if(handle)
  10186.     {
  10187.         struct TagItem    *tagList;
  10188.         va_list         varArg;
  10189.  
  10190.         va_start(varArg,id);
  10191.  
  10192.         tagList = (struct TagItem *)varArg;
  10193.  
  10194.         if(handle -> LocaleHook)
  10195.         {
  10196.             STRPTR label;
  10197.  
  10198.             label = (STRPTR)CallHookPkt(handle -> LocaleHook,handle,(APTR)labelID);
  10199.  
  10200.             LT_AddA(handle,type,label,id,tagList);
  10201.         }
  10202.         else
  10203.             handle -> Failed = TRUE;
  10204.  
  10205.         va_end(varArgs);
  10206.     }
  10207. }
  10208.  
  10209.  
  10210. /*****************************************************************************/
  10211.  
  10212.  
  10213. VOID __stdargs
  10214. LT_New(LayoutHandle *handle,...)
  10215. {
  10216.     va_list VarArgs;
  10217.  
  10218.     va_start(VarArgs,handle);
  10219.     LT_NewA(handle,(struct TagItem *)VarArgs);
  10220.     va_end(VarArgs);
  10221. }
  10222.  
  10223. VOID LIBENT
  10224. LT_NewA(REG(a0) LayoutHandle *handle,REG(a1) struct TagItem *tagList)
  10225. {
  10226.     if(handle)
  10227.     {
  10228.         struct TagItem    *tag;
  10229.         UBYTE         type;
  10230.         STRPTR         label;
  10231.         ULONG         id;
  10232.  
  10233.         if(tag = FindTagItem(LA_Type,tagList))
  10234.         {
  10235.             type = tag -> ti_Data;
  10236.  
  10237.             if(type == END_KIND)
  10238.             {
  10239.                 handle -> CurrentGroup = handle -> CurrentGroup -> Special . Group . ParentGroup;
  10240.  
  10241.                 return;
  10242.             }
  10243.  
  10244.             if(tag = FindTagItem(LA_ID,tagList))
  10245.                 id = tag -> ti_Data;
  10246. /*            else*/
  10247. /*                id = handle -> MaxID;*/
  10248.  
  10249.             if(tag = FindTagItem(LA_LabelID,tagList))
  10250.             {
  10251.                 if(handle -> LocaleHook)
  10252.                     label = (STRPTR)CallHookPkt(handle -> LocaleHook,handle,(APTR)tag -> ti_Data);
  10253.                 else
  10254.                     handle -> Failed = TRUE;
  10255.             }
  10256.             else
  10257.                 label = (STRPTR)GetTagData(LA_LabelText,NULL,tagList);
  10258.  
  10259.             LT_AddA(handle,type,label,id,tagList);
  10260.         }
  10261.         else
  10262.             handle -> Failed = TRUE;
  10263.     }
  10264. }
  10265.  
  10266.  
  10267. /*****************************************************************************/
  10268.  
  10269.  
  10270. VOID LIBENT
  10271. LT_EndGroup(REG(a0) LayoutHandle *handle)
  10272. {
  10273.     LT_AddA(handle,END_KIND,NULL,0,NULL);
  10274. }
  10275.  
  10276.  
  10277. /*****************************************************************************/
  10278.  
  10279.  
  10280. struct Window * __stdargs
  10281. LT_Layout(LayoutHandle *handle, STRPTR title,struct IBox *bounds,LONG extraWidth, LONG extraHeight,ULONG IDCMP, UBYTE align, ...)
  10282. {
  10283.     struct Window    *Result;
  10284.     va_list         VarArgs;
  10285.  
  10286.     va_start(VarArgs,align);
  10287.     Result = LT_LayoutA(handle,title,bounds,extraWidth,extraHeight,IDCMP,align,(struct TagItem *)VarArgs);
  10288.     va_end(VarArgs);
  10289.  
  10290.     return(Result);
  10291. }
  10292.  
  10293. struct Window * LIBENT
  10294. LT_LayoutA(REG(a0) LayoutHandle *handle, REG(a1) STRPTR title,REG(a2) struct IBox *bounds,REG(d0) LONG extraWidth, REG(d1) LONG extraHeight,REG(d2) ULONG IDCMP, REG(d3) UBYTE align, REG(a3) struct TagItem *TagParams)
  10295. {
  10296.     LONG         left, top, width, height;
  10297.     struct IBox     newBounds;
  10298.     struct Menu    *menu;
  10299.     struct TagItem    *item;
  10300.     LONG         placeLeft;
  10301.     LONG         placeTop;
  10302.     struct IBox     zoomBox;
  10303.     struct IBox    *zoom;
  10304.     LONG         i;
  10305.     struct TextFont    *font;
  10306.     struct TagItem    *NewTags = NULL,*Tags;
  10307.     BOOLEAN         FillBack = FALSE,BlockParent = handle -> BlockParent;
  10308.     struct Window    *Parent = handle -> Parent;
  10309.  
  10310.     if(!handle)
  10311.         return(NULL);
  10312.  
  10313.     if(!bounds)
  10314.     {
  10315.         LTK_GetDisplayClip(handle -> Screen,&newBounds . Left,&newBounds . Top,&newBounds . Width,&newBounds . Height);
  10316.  
  10317.         bounds = &newBounds;
  10318.     }
  10319.  
  10320.     if(title)
  10321.         top = handle -> Screen -> WBorTop + handle -> Screen -> Font -> ta_YSize + 1 + handle -> InterHeight;
  10322.     else
  10323.         top = handle -> Screen -> WBorTop + handle -> InterHeight;
  10324.  
  10325.     left = handle -> Screen -> WBorLeft + handle -> InterWidth;
  10326.  
  10327.     LTK_CreateGadgets(handle,bounds,left,top,left + handle -> InterWidth + handle -> Screen -> WBorRight,top + handle -> InterHeight + handle -> Screen -> WBorBottom);
  10328.  
  10329.     if(handle -> Failed)
  10330.         return(NULL);
  10331.  
  10332.     width    = left + handle -> TopGroup -> Width + handle -> InterWidth + handle -> Screen -> WBorRight;
  10333.     height    = top + handle -> TopGroup -> Height + handle -> InterHeight + handle -> Screen -> WBorBottom;
  10334.  
  10335.     if(align & ALIGNF_LEFT)
  10336.         placeLeft = 0;
  10337.     else
  10338.     {
  10339.         if(align & ALIGNF_RIGHT)
  10340.             placeLeft = bounds -> Width - (width + extraWidth);
  10341.         else
  10342.             placeLeft = (bounds -> Width - (width + extraWidth)) / 2;
  10343.     }
  10344.  
  10345.     if(align & ALIGNF_TOP)
  10346.         placeTop = 0;
  10347.     else
  10348.     {
  10349.         if(align & ALIGNF_BOTTOM)
  10350.             placeTop = bounds -> Height - (height + extraHeight);
  10351.         else
  10352.             placeTop = (bounds -> Height - (height + extraHeight)) / 2;
  10353.     }
  10354.  
  10355.     if(align & ALIGNF_EXTRA_LEFT)
  10356.         placeLeft += extraWidth;
  10357.     else
  10358.     {
  10359.         if(!(align & ALIGNF_EXTRA_RIGHT))
  10360.             placeLeft += extraWidth / 2;
  10361.     }
  10362.  
  10363.     if(align & ALIGNF_EXTRA_TOP)
  10364.         placeTop += extraHeight;
  10365.     else
  10366.     {
  10367.         if(!(align & ALIGNF_EXTRA_BOTTOM))
  10368.             placeTop += extraHeight / 2;
  10369.     }
  10370.  
  10371.     placeLeft    += bounds -> Left;
  10372.     placeTop    += bounds -> Top;
  10373.  
  10374.     if(placeLeft < 0)
  10375.         placeLeft = 0;
  10376.  
  10377.     if(placeTop < 0)
  10378.         placeTop = 0;
  10379.  
  10380.     menu = NULL;
  10381.     zoom = NULL;
  10382.  
  10383.     handle -> AutoRefresh = TRUE;
  10384. #ifdef DO_CLONING
  10385.     if(handle -> CloneExtra)
  10386.     {
  10387.         placeLeft    = 0;
  10388.         placeTop    = handle -> CloneExtra -> Screen -> BarHeight + 1;
  10389.  
  10390.         zoomBox . Left    = placeLeft;
  10391.         zoomBox . Top    = placeTop;
  10392.     }
  10393. #endif    /* DO_CLONING */
  10394.  
  10395.     /* ALWAYS */
  10396.     {
  10397.         struct TagItem *TagList = (struct TagItem *)TagParams;
  10398.  
  10399.         while(item = NextTagItem(&TagList))
  10400.         {
  10401.             switch((ULONG)item -> ti_Tag)
  10402.             {
  10403.                 case LA_Menu:
  10404.  
  10405.                     handle -> IDCMP |= IDCMP_MENUPICK;
  10406.  
  10407.                     menu = (struct Menu *)item -> ti_Data;
  10408.  
  10409.                     break;
  10410.  
  10411.                 case LAWN_UserPort:
  10412.  
  10413.                     handle -> MsgPort = (struct MsgPort *)item -> ti_Data;
  10414.  
  10415.                     break;
  10416.  
  10417.                 case LAWN_HelpHook:
  10418.  
  10419.                     handle -> HelpHook = (struct Hook *)item -> ti_Data;
  10420.  
  10421.                     break;
  10422.  
  10423.                 case LAWN_Left:
  10424.  
  10425.                     placeLeft = item -> ti_Data;
  10426.  
  10427.                     break;
  10428.  
  10429.                 case LAWN_Top:
  10430.  
  10431.                     placeTop = item -> ti_Data;
  10432.  
  10433.                     break;
  10434.  
  10435.                 case LAWN_Parent:
  10436.  
  10437.                     Parent = (struct Window *)item -> ti_Data;
  10438.                     break;
  10439.  
  10440.                 case LAWN_BlockParent:
  10441.  
  10442.                     BlockParent = item -> ti_Data;
  10443.                     break;
  10444.  
  10445.                 case LAWN_BelowMouse:
  10446.  
  10447.                     if((placeLeft = handle -> Screen -> MouseX - (width / 2)) < 0)
  10448.                         placeLeft = 0;
  10449.  
  10450.                     if((placeTop = handle -> Screen -> MouseY - (height / 2)) < 0)
  10451.                         placeTop = 0;
  10452.  
  10453.                     break;
  10454.  
  10455.                 case LAWN_Zoom:
  10456.  
  10457.                     if(item -> ti_Data)
  10458.                     {
  10459.                         if(V39)
  10460.                         {
  10461.                             zoomBox . Left    = -1;
  10462.                             zoomBox . Top    = -1;
  10463.                         }
  10464.                         else
  10465.                         {
  10466.                             zoomBox . Left    = placeLeft;
  10467.                             zoomBox . Top    = placeTop;
  10468.                         }
  10469.  
  10470.                         zoomBox . Width        = width;
  10471.                         zoomBox . Height    = handle -> Screen -> WBorTop + handle -> Screen -> Font -> ta_YSize + 1;
  10472.  
  10473.                         zoom = &zoomBox;
  10474.                     }
  10475.  
  10476.                     break;
  10477.  
  10478.                 case LAWN_MaxPen:
  10479.  
  10480.                     handle -> MaxPen = (LONG)item -> ti_Data;
  10481.                     break;
  10482.  
  10483.                 case LAWN_MoveToWindow:
  10484.  
  10485.                     handle -> MoveToWindow = (LONG)item -> ti_Data;
  10486.                     break;
  10487.  
  10488.                 case LAWN_AutoRefresh:
  10489.  
  10490.                     handle -> AutoRefresh = (LONG)item -> ti_Data;
  10491.                     break;
  10492.             }
  10493.         }
  10494.     }
  10495.  
  10496.     Tags = (struct TagItem *)TagParams;
  10497.  
  10498.     if(handle -> BackgroundPen && !V39)
  10499.     {
  10500.         if(NewTags = CloneTagItems(Tags))
  10501.         {
  10502.             STATIC Tag Filter[] = { WA_SimpleRefresh,TAG_DONE };
  10503.  
  10504.             FilterTagItems(NewTags,Filter,TAGFILTER_NOT);
  10505.  
  10506.             Tags = NewTags;
  10507.  
  10508.             FillBack = TRUE;
  10509.         }
  10510.         else
  10511.             return(NULL);
  10512.     }
  10513.  
  10514.     if(Parent)
  10515.     {
  10516.         WORD    Left,Top,Width,Height,MoveLeft,MoveTop,
  10517.             WindowLeft,WindowTop,WindowWidth,WindowHeight;
  10518.  
  10519.         WindowLeft    = Parent -> LeftEdge + Parent -> BorderLeft;
  10520.         WindowTop    = Parent -> TopEdge + Parent -> BorderTop;
  10521.         WindowWidth    = Parent -> Width - (Parent -> BorderLeft + Parent -> BorderRight);
  10522.         WindowHeight    = Parent -> Height - (Parent ->BorderTop + Parent -> BorderBottom);
  10523.  
  10524.         LTK_GetDisplayClip(Parent -> WScreen,&Left,&Top,&Width,&Height);
  10525.  
  10526.         if((MoveLeft = WindowLeft + (WindowWidth - width) / 2) < 0)
  10527.             MoveLeft = 0;
  10528.  
  10529.         if((MoveTop = WindowTop + (WindowHeight - height) / 2) < 0)
  10530.             MoveTop = 0;
  10531.  
  10532.         if(MoveLeft < Left || MoveLeft + width > Left + Width)
  10533.             MoveLeft = -1;
  10534.  
  10535.         if(MoveTop < Top || MoveTop + height > Top + Height)
  10536.             MoveTop = -1;
  10537.  
  10538.         if(MoveTop != -1 && MoveLeft != -1)
  10539.         {
  10540.             placeLeft    = MoveLeft;
  10541.             placeTop    = MoveTop;
  10542.         }
  10543.     }
  10544.  
  10545.     if(BlockParent && Parent)
  10546.     {
  10547.         LT_LockWindow(Parent);
  10548.  
  10549.         handle -> Parent = Parent;
  10550.     }
  10551.  
  10552.     if(handle -> Window = OpenWindowTags(NULL,
  10553.         WA_Left,        placeLeft,
  10554.         WA_Top,            placeTop,
  10555.         WA_Width,        width,
  10556.         WA_Height,        height,
  10557.         WA_NewLookMenus,    TRUE,
  10558.         WA_CustomScreen,    handle -> Screen,
  10559.         WA_BackFill,        &handle -> BackfillHook,
  10560.  
  10561.         !FillBack    ? WA_Gadgets :        TAG_IGNORE,    handle -> List,
  10562.         zoom    ? WA_Zoom :            TAG_IGNORE,    zoom,
  10563.         !handle -> MsgPort ? WA_IDCMP :        TAG_IGNORE,    IDCMP_REFRESHWINDOW | IDCMP_RAWKEY | IDCMP_ACTIVEWINDOW | IDCMP_INACTIVEWINDOW | IDCMP_MOUSEBUTTONS | IDCMP | handle -> IDCMP,
  10564.         title    ? WA_Title :            TAG_IGNORE,    title,
  10565.         handle -> AmigaGlyph ? WA_AmigaKey :    TAG_IGNORE,    handle -> AmigaGlyph,
  10566.         handle -> CheckGlyph ? WA_Checkmark :    TAG_IGNORE,    handle -> CheckGlyph,
  10567.     TAG_MORE,Tags))
  10568.     {
  10569.         font = handle -> RPort . Font;
  10570.  
  10571.         handle -> RPort = *handle -> Window -> RPort;
  10572.  
  10573.         LTK_SetFont(handle,font);
  10574.  
  10575.         if(NewTags)
  10576.         {
  10577.             FreeTagItems(NewTags);
  10578.  
  10579.             NewTags = NULL;
  10580.         }
  10581.  
  10582.         if(V39)
  10583.         {
  10584.             if(handle -> MaxPen > 0)
  10585.             {
  10586.                 SetMaxPen(&handle -> RPort,handle -> MaxPen);
  10587.                 SetMaxPen(handle -> Window -> RPort,handle -> MaxPen);
  10588.             }
  10589.         }
  10590.  
  10591.         if(FillBack)
  10592.             {
  10593.             LTK_SetAPen(handle -> Window -> RPort,handle -> BackgroundPen);
  10594.             RectFill(handle -> Window -> RPort,handle -> Window -> BorderLeft,handle -> Window -> BorderTop,handle -> Window -> Width - (handle -> Window -> BorderRight + 1),handle -> Window -> Height - (handle -> Window -> BorderBottom + 1));
  10595.  
  10596.             AddGList(handle -> Window,handle -> List,(UWORD)-1,(UWORD)-1,NULL);
  10597.             RefreshGList(handle -> List,handle -> Window,NULL,(UWORD)-1);
  10598.         }
  10599.  
  10600.         GT_RefreshWindow(handle -> Window,NULL);
  10601.         LTK_DrawGroup(handle,handle -> TopGroup);
  10602.  
  10603.         LTK_MoveToWindow(handle);
  10604.  
  10605.         if(handle -> MsgPort)
  10606.         {
  10607.             handle -> Window -> UserPort = handle -> MsgPort;
  10608.  
  10609.             if(!ModifyIDCMP(handle -> Window,IDCMP_REFRESHWINDOW | IDCMP_RAWKEY | IDCMP_INACTIVEWINDOW | IDCMP_ACTIVEWINDOW | IDCMP_MOUSEBUTTONS | IDCMP | handle -> IDCMP))
  10610.             {
  10611.                 handle -> Window -> UserPort = NULL;
  10612.  
  10613.                 return (NULL);
  10614.             }
  10615.         }
  10616.  
  10617.         if(menu)
  10618.             SetMenuStrip(handle -> Window,menu);
  10619.  
  10620.         handle -> Previous = NULL;
  10621.  
  10622.         for(i = 0 ; i < handle -> Count ; i++)
  10623.         {
  10624.             if(handle -> GadgetArray[i])
  10625.             {
  10626.                 ObjectNode *node;
  10627.  
  10628.                 if(GETOBJECT(handle -> GadgetArray[i],node))
  10629.                 {
  10630.                     if(LIKE_STRING_KIND(node) || (node -> Type == INTEGER_KIND))
  10631.                     {
  10632.                         if(!handle -> Previous)
  10633.                             handle -> Previous = handle -> GadgetArray[i];
  10634.                     }
  10635.                 }
  10636.             }
  10637.         }
  10638. #ifdef DO_CLONING
  10639.         if(handle -> CloneExtra)
  10640.             ScreenToFront(handle -> Window -> WScreen);
  10641. #endif
  10642.     }
  10643.     else
  10644.     {
  10645.         if(handle -> Parent)
  10646.         {
  10647.             LT_UnlockWindow(handle -> Parent);
  10648.  
  10649.             handle -> Parent = NULL;
  10650.         }
  10651.     }
  10652.  
  10653.     FreeTagItems(NewTags);
  10654.  
  10655.     return(handle -> Window);
  10656. }
  10657.  
  10658.  
  10659. /*****************************************************************************/
  10660.  
  10661.  
  10662. struct Menu * __stdargs
  10663. LT_LayoutMenus(LayoutHandle *handle,struct NewMenu *menuTemplate,...)
  10664. {
  10665.     struct Menu    *Result;
  10666.     va_list         VarArgs;
  10667.  
  10668.     va_start(VarArgs,menuTemplate);
  10669.     Result = LT_LayoutMenusA(handle,menuTemplate,(struct TagItem *)VarArgs);
  10670.     va_end(VarArgs);
  10671.  
  10672.     return(Result);
  10673. }
  10674.  
  10675. struct Menu * LIBENT
  10676. LT_LayoutMenusA(REG(a0) LayoutHandle *handle,REG(a1) struct NewMenu *menuTemplate,REG(a2) struct TagItem *TagParams)
  10677. {
  10678.     struct Menu *menu;
  10679.  
  10680.     menu = NULL;
  10681.  
  10682.     if(handle)
  10683.     {
  10684.         struct TagItem    *tag;
  10685.         LONG         label;
  10686.         BOOLEAN         foundFirst;
  10687.         BOOLEAN         foundLast;
  10688.  
  10689.         foundFirst    = FALSE;
  10690.         foundLast    = FALSE;
  10691.  
  10692.         if(tag = FindTagItem(LA_FirstLabel,(struct TagItem *)TagParams))
  10693.         {
  10694.             foundFirst = TRUE;
  10695.  
  10696.             label = tag -> ti_Data;
  10697.         }
  10698.  
  10699.         if(tag = FindTagItem(LA_LastLabel,(struct TagItem *)TagParams))
  10700.             foundLast = TRUE;
  10701.  
  10702.         if(foundFirst == foundLast)
  10703.         {
  10704.             struct NewMenu *localTemplate;
  10705.  
  10706.             localTemplate = NULL;
  10707.  
  10708.             if(foundFirst)
  10709.             {
  10710.                 if(handle -> LocaleHook)
  10711.                 {
  10712.                     LONG count;
  10713.  
  10714.                     count = 0;
  10715.  
  10716.                     while(menuTemplate[count] . nm_Type != NM_END)
  10717.                         count++;
  10718.  
  10719.                     count++;
  10720.  
  10721.                     if(localTemplate = AllocVec(sizeof(struct NewMenu) * count,MEMF_ANY | MEMF_PUBLIC))
  10722.                     {
  10723.                         LONG i;
  10724.  
  10725.                         CopyMem(menuTemplate,localTemplate,sizeof(struct NewMenu) * count);
  10726.  
  10727.                         for(i = 0 ; i < count ; i++)
  10728.                         {
  10729.                             if(localTemplate[i] . nm_Label != NM_BARLABEL && (localTemplate[i] . nm_Type == NM_TITLE || localTemplate[i] . nm_Type == NM_ITEM || localTemplate[i] . nm_Type == NM_SUB))
  10730.                             {
  10731.                                 localTemplate[i] . nm_Label = (STRPTR)CallHookPkt(handle -> LocaleHook,handle,(APTR)label);
  10732.  
  10733.                                 label++;
  10734.                             }
  10735.                         }
  10736.                     }
  10737.                 }
  10738.  
  10739.                 menuTemplate = localTemplate;
  10740.             }
  10741.  
  10742.             if(menuTemplate)
  10743.             {
  10744.                 if(menu = CreateMenusA(menuTemplate,NULL))
  10745.                 {
  10746.                     if(!LayoutMenus(menu,handle -> VisualInfo,
  10747.                         GTMN_NewLookMenus,    TRUE,
  10748.  
  10749.                         handle -> AmigaGlyph ? GTMN_AmigaKey :    TAG_IGNORE,handle -> AmigaGlyph,
  10750.                         handle -> CheckGlyph ? GTMN_Checkmark :    TAG_IGNORE,handle -> CheckGlyph,
  10751.                     TAG_DONE))
  10752.                     {
  10753.                         FreeMenus(menu);
  10754.  
  10755.                         menu = NULL;
  10756.                     }
  10757.                 }
  10758.  
  10759.                 if(localTemplate)
  10760.                     FreeVec(localTemplate);
  10761.             }
  10762.         }
  10763.     }
  10764.  
  10765.     return(menu);
  10766. }
  10767.  
  10768.  
  10769. /*****************************************************************************/
  10770.  
  10771.  
  10772. #ifdef DO_FRACTION_KIND
  10773. VOID LIBENT
  10774. LT_Fixed2String(REG(d0) FIXED fixed,REG(d1) STRPTR buffer)
  10775. {
  10776.     sprintf(buffer,"%ld%lc%ld",fixed / FIXED_UNITY,LTK_Locale ? LTK_Locale -> loc_DecimalPoint[0] : ' . ',fixed % FIXED_UNITY);
  10777. }
  10778. #endif
  10779.  
  10780.  
  10781. /*****************************************************************************/
  10782.  
  10783.  
  10784. #ifdef DO_FRACTION_KIND
  10785.  
  10786. FIXED LIBENT
  10787. LT_String2Fixed(REG(a0) STRPTR buffer)
  10788. {
  10789.     UBYTE    localBuffer[20];
  10790.     UBYTE    decimalPoint;
  10791.     LONG    i,left,right;
  10792.  
  10793.     if(LTK_Locale)
  10794.         decimalPoint = LTK_Locale -> loc_DecimalPoint[0];
  10795.     else
  10796.         decimalPoint = '.';
  10797.  
  10798.     strcpy(localBuffer,buffer);
  10799.  
  10800.     i = 0;
  10801.  
  10802.     while(buffer[i])
  10803.     {
  10804.         if(localBuffer[i] == decimalPoint)
  10805.         {
  10806.             localBuffer[i] = 0;
  10807.  
  10808.             if(i)
  10809.                 left = Atol(localBuffer);
  10810.             else
  10811.                 left = 0;
  10812.  
  10813.             if(localBuffer[i + 1])
  10814.             {
  10815.                 UBYTE rest[4];
  10816.  
  10817.                 CopyMem(&localBuffer[i + 1],rest,3);
  10818.  
  10819.                 rest[3] = 0;
  10820.  
  10821.                 right = Atol(rest);
  10822.             }
  10823.             else
  10824.                 right = 0;
  10825.  
  10826.             return((FIXED)(left * FIXED_UNITY + right));
  10827.         }
  10828.  
  10829.         i++;
  10830.     }
  10831.  
  10832.     left = Atol(localBuffer);
  10833.  
  10834.     return((FIXED)(left * FIXED_UNITY));
  10835. }
  10836. #endif
  10837.  
  10838.  
  10839. /*****************************************************************************/
  10840.  
  10841.  
  10842. #ifdef DO_FRACTION_KIND
  10843. ULONG LIBENT
  10844. LT_FixedMult(REG(d0) FIXED fixed,REG(d1) ULONG factor)
  10845. {
  10846.     return((fixed * factor) / FIXED_UNITY);
  10847. }
  10848. #endif
  10849.  
  10850.  
  10851. /*****************************************************************************/
  10852.  
  10853.  
  10854. BOOL
  10855. LT_Init()
  10856. {
  10857.     if(SysBase)
  10858.         return(TRUE);
  10859.     else
  10860.     {
  10861.         SysBase = *(struct ExecBase **)4;
  10862.  
  10863.         if(SysBase -> LibNode . lib_Version < 37)
  10864.         {
  10865.             SysBase = NULL;
  10866.  
  10867.             return(FALSE);
  10868.         }
  10869.         else
  10870.         {
  10871.             V39 = (SysBase -> LibNode . lib_Version >= 39);
  10872.             V40 = (SysBase -> LibNode . lib_Version >= 40);
  10873.  
  10874.             IntuitionBase    = OpenLibrary("intuition.library",37);
  10875.             GfxBase        = (struct GfxBase *)OpenLibrary("graphics.library",37);
  10876.             UtilityBase    = OpenLibrary("utility.library",37);
  10877.             GadToolsBase    = OpenLibrary("gadtools.library",37);
  10878.             KeymapBase    = OpenLibrary("keymap.library",37);
  10879.  
  10880.             if(LocaleBase = OpenLibrary("locale.library",38))
  10881.                 LTK_Locale = OpenLocale(NULL);
  10882.  
  10883.             if(IntuitionBase && GfxBase && UtilityBase && GadToolsBase && KeymapBase)
  10884.             {
  10885.                 if(LTK_ImageClass = MakeClass(NULL,IMAGECLASS,NULL,sizeof(ImageInfo),0))
  10886.                 {
  10887. #ifdef DO_PICKSHORTCUTS
  10888.                     InitSemaphore(<K_KeySemaphore);
  10889. #endif    /* DO_PICKSHORTCUTS */
  10890.                     LTK_ImageClass -> cl_Dispatcher . h_Entry = (HOOKFUNC)LTK_ImageDispatch;
  10891.  
  10892.                     InitSemaphore(<K_LockSemaphore);
  10893.  
  10894.                     NewList(<K_LockList);
  10895.  
  10896.                     return(TRUE);
  10897.                 }
  10898.             }
  10899.  
  10900.             LT_Exit();
  10901.  
  10902.             return(FALSE);
  10903.         }
  10904.     }
  10905. }
  10906.  
  10907.  
  10908. /*****************************************************************************/
  10909.  
  10910.  
  10911. VOID
  10912. LT_Exit()
  10913. {
  10914.     if(SysBase)
  10915.     {
  10916.         if(LTK_ImageClass)
  10917.         {
  10918.             FreeClass(LTK_ImageClass);
  10919.  
  10920.             LTK_ImageClass = NULL;
  10921.         }
  10922.  
  10923.         if(LTK_Locale)
  10924.         {
  10925.             CloseLocale(LTK_Locale);
  10926.  
  10927.             LTK_Locale = NULL;
  10928.         }
  10929.  
  10930.         CloseLibrary(LocaleBase);
  10931.  
  10932.         LocaleBase = NULL;
  10933.  
  10934.         CloseLibrary(KeymapBase);
  10935.  
  10936.         KeymapBase = NULL;
  10937.  
  10938.         CloseLibrary(GadToolsBase);
  10939.  
  10940.         GadToolsBase = NULL;
  10941.  
  10942.         CloseLibrary(UtilityBase);
  10943.  
  10944.         UtilityBase = NULL;
  10945.  
  10946.         CloseLibrary(GfxBase);
  10947.  
  10948.         GfxBase = NULL;
  10949.  
  10950.         CloseLibrary(IntuitionBase);
  10951.  
  10952.         IntuitionBase = NULL;
  10953.  
  10954.         SysBase = NULL;
  10955.     }
  10956. }
  10957.  
  10958.  
  10959. /*****************************************************************************/
  10960.  
  10961.  
  10962. LONG LIBENT
  10963. LT_LabelWidth(REG(a0) LayoutHandle *handle,REG(a1) STRPTR label)
  10964. {
  10965.     if(handle)
  10966.     {
  10967.         LONG len;
  10968.         LONG cnt;
  10969.  
  10970.         cnt = 0;
  10971.         len = 0;
  10972.  
  10973.         while(label[len])
  10974.         {
  10975.             if(label[len] == '_')
  10976.                 cnt += TextLength(&handle -> RPort,"_",1);
  10977.  
  10978.             len++;
  10979.         }
  10980.  
  10981.         return(TextLength(&handle -> RPort,label,len) - cnt);
  10982.     }
  10983.     else
  10984.         return(0);
  10985. }
  10986.  
  10987.  
  10988. /*****************************************************************************/
  10989.  
  10990.  
  10991. LONG LIBENT
  10992. LT_LabelChars(REG(a0) LayoutHandle *handle,REG(a1) STRPTR label)
  10993. {
  10994.     if(handle)
  10995.         return((LT_LabelWidth(handle,label) + handle -> GlyphWidth - 1) / handle -> GlyphWidth);
  10996.     else
  10997.         return(0);
  10998. }
  10999.  
  11000.  
  11001. /****************************************************************************/
  11002.  
  11003.  
  11004. VOID LIBENT
  11005. LT_LockWindow(REG(a0) struct Window *window)
  11006. {
  11007.     if(window)
  11008.     {
  11009.         LockNode    *lockNode;
  11010.         BOOLEAN         found;
  11011.  
  11012.         found = FALSE;
  11013.  
  11014.         ObtainSemaphore(<K_LockSemaphore);
  11015.  
  11016.         SCANLIST(<K_LockList,lockNode)
  11017.         {
  11018.             if(lockNode -> Window == window)
  11019.             {
  11020.                 lockNode -> Count++;
  11021.  
  11022.                 found = TRUE;
  11023.  
  11024.                 break;
  11025.             }
  11026.         }
  11027.  
  11028.         if(!found)
  11029.         {
  11030.             if(lockNode = AllocMem(sizeof(LockNode),MEMF_PUBLIC | MEMF_ANY | MEMF_CLEAR))
  11031.             {
  11032.                 AddTail((struct List *)<K_LockList,(struct Node *)lockNode);
  11033.  
  11034.                 lockNode -> Window        = window;
  11035.                 lockNode -> OldIDCMPFlags    = window -> IDCMPFlags;
  11036.                 lockNode -> Count        = 1;
  11037.                 lockNode -> MinWidth        = window -> MinWidth;
  11038.                 lockNode -> MaxWidth        = window -> MaxWidth;
  11039.                 lockNode -> MinHeight        = window -> MinHeight;
  11040.                 lockNode -> MaxHeight        = window -> MaxHeight;
  11041.  
  11042.                 WindowLimits(window,window -> Width,window -> Height,window -> Width,window -> Height);
  11043.  
  11044.                 ModifyIDCMP(window,window -> IDCMPFlags | IDCMP_SIZEVERIFY);
  11045.  
  11046.                 if(V39)
  11047.                 {
  11048.                     SetWindowPointer(window,
  11049.                         WA_BusyPointer,        TRUE,
  11050.                         WA_PointerDelay,    TRUE,
  11051.                     TAG_DONE);
  11052.                 }
  11053.                 else
  11054.                 {
  11055.                     STATIC UWORD __chip Stopwatch[(2 + 16) * 2] =
  11056.                     {
  11057.                         0x0000,0x0000,
  11058.  
  11059.                         0x0400,0x07C0,
  11060.                         0x0000,0x07C0,
  11061.                         0x0100,0x0380,
  11062.                         0x0000,0x07E0,
  11063.                         0x07C0,0x1FF8,
  11064.                         0x1FF0,0x3FEC,
  11065.                         0x3FF8,0x7FDE,
  11066.                         0x3FF8,0x7FBE,
  11067.                         0x7FFC,0xFF7F,
  11068.                         0x7EFC,0xFFFF,
  11069.                         0x7FFC,0xFFFF,
  11070.                         0x3FF8,0x7FFE,
  11071.                         0x3FF8,0x7FFE,
  11072.                         0x1FF0,0x3FFC,
  11073.                         0x07C0,0x1FF8,
  11074.                         0x0000,0x07E0,
  11075.  
  11076.                         0x0000,0x0000
  11077.                     };
  11078.  
  11079.                     SetPointer(window,Stopwatch,16,16,-6,0);
  11080.                 }
  11081.  
  11082.                 Request(&lockNode -> Requester,window);
  11083.             }
  11084.         }
  11085.  
  11086.         ReleaseSemaphore(<K_LockSemaphore);
  11087.     }
  11088. }
  11089.  
  11090.  
  11091. /****************************************************************************/
  11092.  
  11093.  
  11094. VOID LIBENT
  11095. LT_UnlockWindow(REG(a0) struct Window *window)
  11096. {
  11097.     if(window)
  11098.     {
  11099.         LockNode *lockNode;
  11100.  
  11101.         ObtainSemaphore(<K_LockSemaphore);
  11102.  
  11103.         SCANLIST(<K_LockList,lockNode)
  11104.         {
  11105.             if(lockNode -> Window == window)
  11106.             {
  11107.                 if(--lockNode -> Count < 1)
  11108.                 {
  11109.                     Remove((struct Node *)lockNode);
  11110.  
  11111.                     WindowLimits(window,lockNode -> MinWidth,lockNode -> MinHeight,lockNode -> MaxWidth,lockNode -> MaxHeight);
  11112.  
  11113.                     EndRequest(&lockNode -> Requester,window);
  11114.  
  11115.                     if(V39)
  11116.                         SetWindowPointerA(window,NULL);
  11117.                     else
  11118.                         ClearPointer(window);
  11119.  
  11120.                     ModifyIDCMP(window,lockNode -> OldIDCMPFlags);
  11121.  
  11122.                     FreeMem(lockNode,sizeof(LockNode));
  11123.                 }
  11124.  
  11125.                 break;
  11126.             }
  11127.         }
  11128.  
  11129.         ReleaseSemaphore(<K_LockSemaphore);
  11130.     }
  11131. }
  11132.  
  11133.  
  11134. /*****************************************************************************/
  11135.  
  11136.  
  11137. VOID LIBENT
  11138. LT_DeleteWindowLock(REG(a0) struct Window *window)
  11139. {
  11140.     if(window)
  11141.     {
  11142.         LockNode *lockNode;
  11143.  
  11144.         ObtainSemaphore(<K_LockSemaphore);
  11145.  
  11146.         SCANLIST(<K_LockList,lockNode)
  11147.         {
  11148.             if(lockNode -> Window == window)
  11149.             {
  11150.                 Remove((struct Node *)lockNode);
  11151.  
  11152.                 EndRequest(&lockNode -> Requester,window);
  11153.  
  11154.                 if(V39)
  11155.                     SetWindowPointerA(window,NULL);
  11156.                 else
  11157.                     ClearPointer(window);
  11158.  
  11159.                 ModifyIDCMP(window,lockNode -> OldIDCMPFlags);
  11160.  
  11161.                 FreeMem(lockNode,sizeof(LockNode));
  11162.  
  11163.                 break;
  11164.             }
  11165.         }
  11166.  
  11167.         ReleaseSemaphore(<K_LockSemaphore);
  11168.     }
  11169. }
  11170.  
  11171.  
  11172. /****************************************************************************/
  11173.  
  11174.  
  11175. VOID LIBENT
  11176. LT_ShowWindow(REG(a0) LayoutHandle *handle,REG(a1) BOOL activate)
  11177. {
  11178.     if(handle)
  11179.     {
  11180.         struct Window *window;
  11181.  
  11182.         window = handle -> Window;
  11183.  
  11184.         WindowToFront(window);
  11185.  
  11186.         if(activate)
  11187.             ActivateWindow(window);
  11188.  
  11189.         ScreenToFront(window -> WScreen);
  11190.  
  11191.         if((handle -> Window -> Flags & (WFLG_HASZOOM | WFLG_ZOOMED)) == (WFLG_HASZOOM | WFLG_ZOOMED))
  11192.         {
  11193.             WORD i;
  11194.  
  11195.             ZipWindow(window);
  11196.  
  11197.                 // wait for the window to unzoom before calling LTK_MoveToWindow()
  11198.  
  11199.             for(i = 0 ; i < 300 ; i++)
  11200.             {
  11201.                 if(!handle -> Window -> Flags & WFLG_ZOOMED)
  11202.                     break;
  11203.  
  11204.                 WaitTOF();
  11205.             }
  11206.         }
  11207.  
  11208.         LTK_MoveToWindow(handle);
  11209.     }
  11210. }
  11211.  
  11212.  
  11213. /****************************************************************************/
  11214.  
  11215.  
  11216. VOID LIBENT
  11217. LT_Activate(REG(a0) LayoutHandle *handle,REG(d0) LONG id)
  11218. {
  11219.     struct Gadget *gadget;
  11220.  
  11221.     if(gadget = LTK_FindGadget(handle,id))
  11222.     {
  11223.         ObjectNode *node;
  11224.  
  11225.         if(GETOBJECT(gadget,node))
  11226.         {
  11227.             if(!node -> Disabled)
  11228.             {
  11229.                 if(LIKE_STRING_KIND(node) || (node -> Type == INTEGER_KIND))
  11230.                 {
  11231.                     handle -> Previous = gadget;
  11232.  
  11233.                     ActivateGadget(handle -> Previous,handle -> Window,NULL);
  11234.                 }
  11235.             }
  11236.         }
  11237.     }
  11238. }
  11239.  
  11240.  
  11241. /****************************************************************************/
  11242.  
  11243.  
  11244. VOID LIBENT
  11245. LT_PressButton(REG(a0) LayoutHandle *handle,REG(d0) LONG id)
  11246. {
  11247.     struct Gadget *gadget;
  11248.  
  11249.     if(gadget = LTK_FindGadget(handle,id))
  11250.     {
  11251.         ObjectNode *node;
  11252.  
  11253.         if(GETOBJECT(gadget,node))
  11254.         {
  11255.             if(!node -> Disabled)
  11256.                 LTK_BlinkButton(handle,gadget);
  11257.         }
  11258.     }
  11259. }
  11260.  
  11261.  
  11262. /****************************************************************************/
  11263.  
  11264.  
  11265. WORD LIBENT
  11266. LT_GetCode(REG(d0) ULONG MsgQualifier,REG(d1) ULONG MsgClass,REG(d2) UWORD MsgCode,REG(a0) struct Gadget *MsgGadget)
  11267. {
  11268.     if(MsgClass == IDCMP_RAWKEY && !(MsgCode & IECODE_UP_PREFIX) && KeymapBase)
  11269.     {
  11270.         UBYTE            Buffer[10];
  11271.         struct InputEvent    Event;
  11272.         LONG            Len;
  11273.  
  11274.         Event . ie_NextEvent        = NULL;
  11275.         Event . ie_Code            = MsgCode & ~IECODE_UP_PREFIX;
  11276.         Event . ie_Qualifier        = MsgQualifier;
  11277.         Event . ie_Class        = IECLASS_RAWKEY;
  11278.         Event . ie_SubClass        = 0;
  11279.         Event . ie_position . ie_addr    = (APTR)MsgGadget;
  11280.  
  11281.         Buffer[0] = 0;
  11282.  
  11283.         if((Len = MapRawKey(&Event,Buffer,9,NULL)) > 0)
  11284.         {
  11285.             if(Buffer[0] != 0x9B || Len == 1)
  11286.                 return((WORD)Buffer[0]);
  11287.         }
  11288.     }
  11289.  
  11290.     return(-1);
  11291. }
  11292.  
  11293.  
  11294. /****************************************************************************/
  11295.  
  11296. #define MESSAGE_COOKIE 0x47138AEB
  11297.  
  11298. struct IntuiMessage * LIBENT
  11299. LT_GetIMsg(REG(a0) struct LayoutHandle *Handle)
  11300. {
  11301.     if(Handle)
  11302.     {
  11303.         struct IntuiMessage *Msg = GT_GetIMsg(Handle -> Window -> UserPort);
  11304.  
  11305.         if(Msg)
  11306.         {
  11307.             struct IntuiMessage *Clone;
  11308.  
  11309.             if(Clone = (struct IntuiMessage *)AllocMem(sizeof(struct ExtIntuiMessage),MEMF_ANY))
  11310.             {
  11311.                 CopyMem(Msg,Clone,sizeof(struct ExtIntuiMessage));
  11312.  
  11313.                 Clone -> ExecMessage . mn_Node . ln_Name    = (char *)MESSAGE_COOKIE;
  11314.                 Clone -> ExecMessage . mn_Node . ln_Pri        = -114;
  11315.                 Clone -> ExecMessage . mn_ReplyPort        = (struct MsgPort *)Clone;
  11316.                 Clone -> SpecialLink                = (struct IntuiMessage *)Clone;
  11317.  
  11318.                 GT_ReplyIMsg(Msg);
  11319.  
  11320.                 LT_HandleInput(Handle,Clone -> Qualifier,&Clone -> Class,&Clone -> Code,(struct Gadget **)&Clone -> IAddress);
  11321.  
  11322.                 return(Clone);
  11323.             }
  11324.             else
  11325.                 GT_ReplyIMsg(Msg);
  11326.         }
  11327.     }
  11328.  
  11329.     return(NULL);
  11330. }
  11331.  
  11332. VOID LIBENT
  11333. LT_ReplyIMsg(REG(a0) struct IntuiMessage *Msg)
  11334. {
  11335.     if(Msg)
  11336.     {
  11337.         if(Msg -> SpecialLink == (struct IntuiMessage *)Msg && Msg -> ExecMessage . mn_Node . ln_Name == (char *)MESSAGE_COOKIE && Msg -> ExecMessage . mn_Node . ln_Pri == -114 && Msg -> ExecMessage . mn_ReplyPort == (struct MsgPort *)Msg)
  11338.             FreeMem(Msg,sizeof(struct ExtIntuiMessage));
  11339.         else
  11340.             GT_ReplyIMsg(Msg);
  11341.     }
  11342. }
  11343.