#include #include #include #include #include #include #include #include #include #include #include #include #ifndef LINKLIB #include "proto/gadoutline.h" #else #include "libraries/gadoutline.h" #include "interface.h" #endif #include "support/debug.h" #define CATCOMP_BLOCK 1 #define CATCOMP_NUMBERS 1 #include "gadout_examples.h" #include "support/rkmmodel.h" #define NOISY 0 /********************************************* ** ** Main window outline support data ** *********************************************/ // This is a list of IDs to assign to each command (gadget) in the outline. // Because almost all references to the outline are made through IDs rather // than pointers, you will need to assign IDs to most commands, including // any command that has a hotkey attached. (Hotkeys are stored internally // as just the ID number of the command that a hotkey is attached to, so // if it doesn't have a number the library is unable to find the command // to send an CHM_HOTKEY message to it.) // These "standard" ID codes can range from 1 to 4095; the value of 0 means // "no ID code," and the upper 20 bits of the ID are used for storing // "group" ID codes. Every command which is given a non-zero standard ID // must be the only command in the outline with that ID; the library will // report an error if it finds more than one command with the same ID. enum { LISTVIEW_ID = 1, LVEDIT_ID, PALETTE_ID, CYCLE_ID, BUTTON_ID, SLIDER_ID, CHECKBOX_ID, BASICPROP_ID, BASICINT_ID, RIGHTIM_ID, LEFTIM_ID, INTFRAME_ID, RKMMODEL_ID, VAL2INT_ID, VAL2PROP_ID, PROP_ID, INTEGER_ID, LEFT_ID, RIGHT_ID, PROPKNOB_ID, DRAWPROP_ID, DRAWINT_ID, JUMPWIN_ID, REQFONT_ID, ICONIFY_ID, WINVALUES_ID, OUTVALUES_ID, KEYSHOW_ID }; // This tag list is located outside of the outline because // it is fairly long [and this makes a nice example :)]. However, // when the GadOutline structure is created, space is reserved // to track these tags just like the tags directly included // in the outline. struct TagItem slider_obj_tags[] = { { GA_RelVerify, TRUE }, { GA_Immediate, TRUE }, { PGA_FREEDOM, LORIENT_HORIZ }, { GTSL_Min, 0 }, { GTSL_Max, 15 }, { GTSL_Level, 0 }, { GTSL_LevelFormat, MSG_EX1_SLIDER_FMT }, { GTSL_LevelPlace, PLACETEXT_RIGHT }, { GTSL_MaxLevelLen, 2 }, { TAG_END, 0 } }; // Now, the drawing tags which all the icons start with: static ULONG IconInitDraw[] = { GODT_FillRect, GO_SCLPNT(BACKGROUNDPEN,0,0,63,63), GODT_DrawStdFrame, GO_SCLPNT(SHINEPEN,0,0,63,63), GODT_SetRightBound, GO_TSIZE(GOM_Add,-200,GOT_PercStdFrmW), GODT_SetBottomBound, GO_TSIZE(GOM_Add,-200,GOT_PercStdFrmH), GODT_SetLeftBound, GO_TSIZE(GOM_Add,200,GOT_PercStdFrmW), GODT_SetTopBound, GO_TSIZE(GOM_Add,200,GOT_PercStdFrmH), TAG_END }; // And one for BOOPSI-style thin icons: static ULONG ThinIconInitDraw[] = { GODT_MapHighPen, GO_MAPPEN(FILLPEN,FILLPEN), GODT_FillRect, GO_SCLPNT(FILLPEN,0,0,63,63), GODT_DrawLine, GO_SCLPNT(SHINEPEN,0,0,0,63), GODT_DrawLine, GO_SCLPNT(SHADOWPEN,0,63,63,63), GODT_DrawLine, GO_SCLPNT(SHADOWPEN,63,0,63,63), GODT_DrawLine, GO_SCLPNT(SHINEPEN,0,0,63,0), GODT_MapHighPen, GO_MAPPEN(FILLPEN,BACKGROUNDPEN), GODT_SetRightBound, GO_TSIZE(GOM_Add,-2,GOT_Pixels), GODT_SetBottomBound, GO_TSIZE(GOM_Add,-2,GOT_Pixels), GODT_SetLeftBound, GO_TSIZE(GOM_Add,2,GOT_Pixels), GODT_SetTopBound, GO_TSIZE(GOM_Add,2,GOT_Pixels), TAG_END }; // And these are the control tags to tell what size // an icon should be. static ULONG SmallIconControl[] = { GOCT_SizeBodyWidth, GO_TSIZE(GOM_StdSet,400,GOT_PercStdFrmW), GOCT_SizeBodyWidth, GO_TSIZE(GOM_StdAdd,200,GOT_PercChar0), GOCT_SizeBodyHeight, GO_TSIZE(GOM_StdSet,400,GOT_PercStdFrmH), GOCT_SizeBodyHeight, GO_TSIZE(GOM_StdAdd,100,GOT_PercCharH), TAG_END }; // Similarily, for the thin icon. static ULONG ThinIconControl[] = { GOCT_SizeBodyWidth, GO_TSIZE(GOM_StdAdd,200,GOT_PercChar0), GOCT_SizeBodyHeight, GO_TSIZE(GOM_StdAdd,125,GOT_PercCharH), GOCT_SizeBodyWidth, GO_TSIZE(GOM_StdMax,12,GOT_Pixels), GOCT_SizeBodyHeight, GO_TSIZE(GOM_StdMax,8,GOT_Pixels), TAG_END }; // These are the translation tables for a simple prop<=>int interconnection. struct TagItem prop2intmap[] = { {PGA_Top, STRINGA_LongVal}, {TAG_END,} }; struct TagItem int2propmap[] = { {STRINGA_LongVal, PGA_Top}, {TAG_END,} }; // These are various translation tables used to implement the // RKMModel demonstration, taken directly from userkmmodel.c. static struct TagItem go2rkmmodel[] = { {PGA_Top, RKMMOD_CurrVal}, {STRINGA_LongVal, RKMMOD_CurrVal}, {TAG_END,} }; static struct TagItem right2rkmmodel[] = { {GA_ID, RKMMOD_Up}, {TAG_END,} }; static struct TagItem left2rkmmodel[] = { {GA_ID, RKMMOD_Down}, {TAG_END,} }; static struct TagItem mapcurrval2prop[] = { {RKMMOD_CurrVal, PGA_Top}, {TAG_END,} }; static struct TagItem mapcurrval2int[] = { {RKMMOD_CurrVal, STRINGA_LongVal}, {TAG_END,} }; #define VISIBLE 10L #define TOTAL 100L #define INITIALVAL 25L #define STRING_LEN 100 /********************************************* ** ** Main window gadget outline ** *********************************************/ // This is the main outline structure. It is simply an array of ULONGs, // organized as a series of commands. Each command may have up to 8 // parameters and 3 tag lists, although currently the library only // does something with the first two tag lists. The first tag list // is always a list of outline commands (GOCT_*) used to control the // command - see the header file for information on these. The // interpretation of the second tag list depends on the command type -- // It may be a list of GadTools tags, Window tags, Screen tags, GOCT_ // tags to add to the command tag list of following commands, etc. // When the outline is created, all of the supplied parameters and tag // lists are copied and used to track the state of the gadgets. Because // only the state of tags directly supplied to the outline are tracked, // you will need to make sure you include GTST_String, GTCY_Active, // GTCY_Labels, etc., even if you do not set them until the gadgets have // been created. If these are not included, during a resize and other // times that the gadgets need to be rebuilt, they will revert to their // default values. // NOTE!!!!! _ALL_ tag lists in the outline MUST end with a TAG_END. // The library does not consider a TAG_MORE, or anything else, a list // terminator. So when you use TAG_MORE, it will look like this: // // ..., TAG_MORE, (ULONG)&more_tags, TAG_END, NEW_COMMAND(), ... static ULONG outline[] = { // Default GadOutline GOA_ type tags. These tags are immediately parsed // when this command is encountered just as if they were passed to // AllocGadOutline(). GO_OUTLINETAGS(0,0), TAG_END, // 1st tag list -- no command tags. GOA_FontMinSize, 2, // 2nd tag list -- new outline tags. GOA_WindowResize, TRUE, GOA_LocaleStrBlock, (ULONG)&CatCompBlock[0], GOA_CatalogName, (ULONG)&"gadout_examples.catalog", GOA_HighButtons, TRUE, TAG_END, // Default window tags. These are supplied as defaults when GO_OpenWindow() // is called; they will be overridden by any tags passed directly to the // function call. Only include this command once. GO_WINDOWTAGS(0,0), TAG_END, // 1st tag list -- no command tags. WA_Title, MSG_EX1_TITLE_TXT, WA_IDCMP, IDCMP_CLOSEWINDOW | IDCMP_REFRESHWINDOW | IDCMP_NEWSIZE | IDCMP_GADGETHELP, WA_Zoom, ~0, WA_NewLookMenus, TRUE, WA_Activate, TRUE, WA_CloseGadget, TRUE, WA_DepthGadget, TRUE, WA_DragBar, TRUE, WA_SizeGadget, TRUE, WA_SizeBBottom, TRUE, WA_ReportMouse, TRUE, WA_SimpleRefresh, TRUE, TAG_END, // Global command tags -- Added to the first tag list (command list) // of every command which follows this and matches the command's ID. // Since the command ID is 0, this will simply match every command. // Space will be allocated to track their state just as if they were // directly supplied to the command. GO_COMMANDTAGS(0,0), TAG_END, GOCT_SetHotKey, 0, // Automatically set hot key code GOCT_SetUserHook, 1, // Set user hook to translation 1 // (Computed in translation hook below.) TAG_END, // Global object tags -- Added to the second tag list (object list) // of every command which follows this and matches its ID. Since this // command's GroupID mask is GO_GRPID_L and code is 0, and its StdID is 0, // this will match every command with the GO_GRPID_L bit set. Space will be // allocated to track their state just as if they were directly supplied // to the command. // Note that the GOA_Underscore global attribute is a much better way to // automatically set the GT_Underscore tag in each object; this is just // a way to demonstrate the GO_OBJECTTAGS() command. :) #define UNDERSCORE_GRP GO_GRPID_L GO_OBJECTTAGS(UNDERSCORE_GRP,0), TAG_END, GT_Underscore, '_', // Add the GadTools underscore tag. TAG_END, // Start the layout. A layout is organized as a recursive collection // of "groups." A group can be either horizontal or vertical, and may // contain both actual boxes or other groups. // Initial group. It has no GrpID and no StdID because we will never // directly reference it. The last value, '1', is the "weight" of the // group. When multiple boxes and groups are together, their relative // weights are used to determine how to distribute the space among them. // In this case, a 1 gives this group all of the weight; since it is the // root group, this means it gets all the space in the window. GO_VERTGRP(0,0,1), // Command tags to set the space around the group. GOM_PadSet means // to directly set the amount of padding [padding is space that the // library is allowed to remove to make a layout fit within its bounds.] // GOT_PercCharH and GOT_PercCharW are the "type" units - in this case, // we are asking for 100 Percent of a character height and width. // These sizing commands are simply executing sequentially by the library, // allowing you to combine them with different functions [ie, GOM_PadSet // and then GOM_PadAdd] for more detailed control over the spacing. GOCT_SizeSpaceAbove, GO_TSIZE(GOM_PadSet,50,GOT_PercCharH), GOCT_SizeSpaceBelow, GO_TSIZE(GOM_PadSet,50,GOT_PercCharH), GOCT_SizeSpaceLeft, GO_TSIZE(GOM_PadSet,50,GOT_PercCharW), GOCT_SizeSpaceRight, GO_TSIZE(GOM_PadSet,50,GOT_PercCharW), TAG_END, /* ----------------------------------------------------------- */ // First we will draw a title at the top of the window. This involves // creating a "DRAWBOX," which is a box that contains GODT_* drawing // tags. GOSD_Normal means this is a standard drawing, rather than // a button. We give this box 0 weight, because we don't want it // to get any more spacing than it needs. GO_DRAWBOX(GOSD_Normal,0,0,0), // These two tags control how much vertical space the body will get. // We first set its "standard" space to 1 character height; this is // the bare minimum amount of height that this box can have. We // also give it half a character height of padding; this is space // which is really nice to have for it to look nice, but the library // can get rid of if it needs to try to make the layout fit. GOCT_SizeBodyHeight, GO_TSIZE(GOM_StdSet,100,GOT_PercCharH), GOCT_SizeBodyHeight, GO_TSIZE(GOM_PadSet,50,GOT_PercCharH), TAG_END, // Finally, we draw the text. This looks complicated, but it is // fairly straight-forward. Drawing tags are simply sequentially // executed commands use to render onto the window, and control // how the rendering should be performed. // First, we set the text mode. "FLGALL" is a special macro used // with tags which set flags; these tags can control which bits to // set or clear, using "FLGALL," "FLGON," and "FLGOFF." This tag // means to directly set all text mode flags, in this case making // it so that text is centered about the X axis, the cursor is left // on the right center of the text, and the Y cursor position is // relative to the center of the line of text GODT_SetTextMode, FLGALL(TXTMD_CENTER | TXTMD_ENDRIGHT | TXTMD_RELCENTER), // Next, turn on the BOLD text style. GODT_SetTextStyle, FLGON(TXTSTL_BOLD), // The "Origin" is a set of two X/Y coordinate pairs, which may be set // to a value, and later referenced as offsets. In this case, it is // very useful for drawing 3D text - we can set the origin to the // position we want to draw it at, and then draw the shadow one pixel // offset from the foreground. // GO_SCLPNT is a macro that creates the standard data format for // drawing commands. Its arguments are a standard pen [0 to 15] // and two pairs of coordinates, whose values each range from 0 to 63 // and are interpreted as 'x/63 of the current drawing boundaries.' // The default boundaries for a DRAWBOX are simply the box's body, // so the point (32,32) will give is the center of the box. // Since GODT_SetOrigin doesn't use the pen parameter and we aren't // going to use the second X/Y pair, we will set these to 0. GODT_SetOrigin, GO_SCLPNT(0,32,32,0,0), // We now move one pixel to the left and one pixel below the center // point we found above. GO_PIXPNT is another macro for creating // the drawing parameter. This one takes one of the coordinates // previously defined by GODT_SetOrigin and an offset to apply to // it; this offset may range from -16 to +15, and may be applied // to either the first or second coordinate previously defined // by GODT_SetOrigin. GODT_MoveTo, GO_PIXPNT(0,PX1(1),PY1(1),0,0), // This tag simply set the pen which following text will use. GODT_ChooseTextAPen, SHADOWPEN, // And then we draw the text. GODT_DrawText, MSG_EX1_HEAD_TXT, // Next, move back to the exact center point. GODT_MoveTo, GO_PIXPNT(0,PX1(0),PY1(0),0,0), // And draw the text again, this time using the standard text highlight // pen. GODT_DrawHighText, MSG_EX1_HEAD_TXT, TAG_END, /* ----------------------------------------------------------- */ // Make a divider bar. GO_DRAWBOX(GOSD_Normal,0,0,0), // The important thing here is the spacing -- we want to make sure // that the body has exactly the amount of space needed by a frame, // since our divider bar is simply a standard frame with its top // and bottom crunched together so they are touching. What we do // is set set the body width and height large enough to both sides // of the frame, and make sure the pad spacing is zero. The library // by default puts any extra space in a box into its body, so the // body's width will be stretched across to conform with the rest // of the vertical group the box is in. But since we set this box's // weight to 0, the body height will be untouched. GOCT_SizeBodyWidth, GO_TSIZE(GOM_StdSet,200,GOT_PercStdFrmW), GOCT_SizeBodyWidth, GO_TSIZE(GOM_PadSet,0,GOT_Pixels), GOCT_SizeBodyHeight, GO_TSIZE(GOM_StdSet,200,GOT_PercStdFrmH), GOCT_SizeBodyHeight, GO_TSIZE(GOM_PadSet,0,GOT_Pixels), // We then put some pad spacing in the space areas above and below // the box, so things look nice. GOCT_SizeSpaceAbove, GO_TSIZE(GOM_PadSet,50,GOT_PercCharH), GOCT_SizeSpaceBelow, GO_TSIZE(GOM_PadSet,50,GOT_PercCharH), TAG_END, // And draw the frame, using the entire body. The bottom-right side // of the frame is draw in the complement of the given pen, so to // draw a recessed frame you would just specify a pen of SHADOWPEN. GODT_DrawStdFrame, GO_SCLPNT(SHINEPEN,0,0,63,63), TAG_END, /* ----------------------------------------------------------- */ // We now make another drawbox, in which we will supply some // additional text. The main thing to note here is the use of // 'GOCT_FmtPtrTag' to determine how large the box should be; this // tag is used to get the text from one of the tags in the second // list, and use it to set some values which you can later refer // to with GO_TSIZE(). In this case, we grab the formatted text // which we draw in the body, and use it to determine the width and // height which it needs to be contained. #if 0 GO_DRAWBOX(GOSD_Normal,0,0,0), GOCT_FmtPtrTag, GODT_DrawStdText, GOCT_SizeBodyWidth, GO_TSIZE(GOM_StdMax,100,GOT_PercTextMaxW), GOCT_SizeBodyHeight, GO_TSIZE(GOM_StdMax,100,GOT_PercTextMaxH), TAG_END, GODT_SetTextMode, FLGALL(TXTMD_CENTER | TXTMD_ENDCENTER | TXTMD_RELTOP), GODT_MoveTo, GO_SCLPNT(0,32,0,0,0), GODT_DrawStdText, MSG_EX1_SUBHEAD_TXT, TAG_END, #endif /* ----------------------------------------------------------- */ // Start the main part of the window -- divide into horizontal slices. GO_HORIZGRP(0,0,1), TAG_END, // Left horizontal slice -- divide into vertical slices. GO_VERTGRP(0,0,1), TAG_END, /* ----------------------------------------------------------- */ // Draw the title text for this section. GO_DRAWBOX(GOSD_Normal,0,0,0), GOCT_FmtPtrTag, GODT_DrawStdText, GOCT_SizeBodyWidth, GO_TSIZE(GOM_StdMax,100,GOT_PercTextMaxW), GOCT_SizeBodyHeight, GO_TSIZE(GOM_StdMax,100,GOT_PercTextMaxH), TAG_END, GODT_SetTextMode, FLGALL(TXTMD_CENTER | TXTMD_ENDCENTER | TXTMD_RELTOP), GODT_MoveTo, GO_SCLPNT(0,32,0,0,0), GODT_DrawStdText, MSG_EX1_GADTOOLS_TXT, TAG_END, /* ----------------------------------------------------------- */ // Create a GadTools box. The parameters are, in order, // GadTools Kind, GrpID, StdID, Weight, Label, Flags. GO_GTBOX(LISTVIEW_KIND, UNDERSCORE_GRP, LISTVIEW_ID, 1, MSG_EX1_LISTVIEW_LAB, PLACETEXT_ABOVE|NG_HIGHLABEL), // Set the minimum size that the listview's body can be. // GOM_StdMax means to set the standard size [the bare // minimum size of the box] to the maximum of its current // value and the new value being supplied. GOCT_SizeBodyWidth, GO_TSIZE(GOM_StdMax,500,GOT_PercCharW), //GOCT_SizeBodyHeight, GO_TSIZE(GOM_StdMax,300,GOT_PercCharH), // Link this object to another. These tags tells the library // to point the GTLV_ShowSelected tag in this command's // second/object/GadTools taglist to the object created // by the INFOEDIT_ID command. This object's creation will // be deferred until the object it is linked to has been // created; if that object is never created, this one won't // be either. GOCT_LinkFromTag, GTLV_ShowSelected, GOCT_LinkToStdID, LVEDIT_ID, // Point hotkey events to the INFOEDIT_ID command. The // standard GadTools hook automatically sets the command's // hotkey by examining its label text; this allows us to // keep that automatic hotkey while making the hotkey // actually refer to a different command. GOCT_SetHotKeyCmd, LVEDIT_ID, TAG_END, // Start of the second - GadTools - taglist. These are the // tags which will be tracked by the library. GTLV_Selected, ~0, GTLV_Labels, NULL, GTLV_ShowSelected, NULL, GTLV_Top, NULL, TAG_END, /* ----------------------------------------------------------- */ // Create a string gadget. This is the gadget that the // previous ListView has a TagLink to. GO_GTBOX(STRING_KIND, UNDERSCORE_GRP, LVEDIT_ID, 0, NULL, 0), // Tell the library to ignore this box's dimensions // when computing both the minimum size of the layout // and the final position of all the boxes. We need to do // this because this gadget is attached to the listview, // so its dimensions are taken into account there. GOCT_IgnoreMinDimens, TRUE, GOCT_IgnoreFinDimens, TRUE, TAG_END, // Set GadTools tags. The standard hook looks for // GTST_MaxChars and allocates a buffer of that size to track // the string gadget's value. It currently does _NOT_ change // the size of this buffer to match a change in this tag, // so make sure you leave plenty of room here. GTST_MaxChars, STRING_LEN, GTST_String, MSG_EX1_EMPTY_STR, TAG_END, /* ----------------------------------------------------------- */ GO_GTBOX(PALETTE_KIND, UNDERSCORE_GRP, PALETTE_ID, 0, MSG_EX1_PALETTE_LAB, NG_HIGHLABEL|PLACETEXT_ABOVE), // Set up an initial value for the indicator. GOCT_CopyFromTSize, GO_TSIZE(GOM_Set,15,GOT_Pixels), GOCT_CopyTSizeToTag, GTPA_IndicatorHeight, // Adjust the body's width and height a bit GOCT_SizeBodyWidth, GO_TSIZE(GOM_StdMax,500,GOT_PercCharW), GOCT_SizeBodyHeight, GO_TSIZE(GOM_StdMax,200,GOT_PercCharH), // Compute a nice size for the palette's indicator. GOCT_SizeUser1, GO_TSIZE(GOM_VarSet,20,GOT_PercBodyH), GOCT_SizeUser1, GO_TSIZE(GOM_VarMin,250,GOT_PercCharH), GOCT_SizeUser1, GO_TSIZE(GOM_VarMax,6,GOT_Pixels), // Copy value in User1 to GTPA_IndicatorHeight tag. GOCT_CopyUser1ToTag, GTPA_IndicatorHeight, TAG_END, GTPA_IndicatorHeight, 15, GTPA_Color, 0, GTPA_Depth, 2, TAG_END, // Add another vertical group inside the current one. We are // going to do something a bit different with this one... GO_VERTGRP(0,0,0), // This tag tells the library to exactly align all of the box's // label areas, space areas and bodies. GOCT_FitToGroup, TRUE, TAG_END, /* ----------------------------------------------------------- */ GO_GTBOX(CYCLE_KIND, UNDERSCORE_GRP, CYCLE_ID, 0, MSG_EX1_CYCLE_LAB, PLACETEXT_LEFT|NG_HIGHLABEL), #if 0 // The CYCLE_KIND minimum dimension hook is now implemented. :) // But we will leave this here; these are the commands which // can be used to compute the size needed by a cycle gadget. // // Set up information about the array of strings supplied // in the tag "GTCY_Labels" in the second tag list. GOCT_TextArrayTag, GTCY_Labels, // Set user variable 1 to the maximum width of all of these // strings. GOCT_SizeUser1, GO_TSIZE(GOM_StdSet,100,GOT_PercTextMaxW), // Add 4 pixels to the value in User1. GOCT_SizeUser1, GO_TSIZE(GOM_StdAdd,4,GOT_Pixels), // Set the body width to the maximum of its current value // and the Std value in User1. GOCT_SizeBodyWidth, GO_TSIZE(GOM_StdMax,100,GOT_PercMdUser1), // Add 20 pixels for the cycle imagery. We have now supplied // all of the information needed to determine the minimum // size of this gadget. We had to go to all of this work // because the library's standard gadtools hook for cycle // gadget wasn't finished yet... But this makes a nice // example, anyway... ;) GOCT_SizeBodyWidth, GO_TSIZE(GOM_StdAdd,20,GOT_Pixels), #endif TAG_END, GTCY_Labels, MSG_EX1_CYCLE_GAD, GTCY_Active, 0, TAG_END, /* ----------------------------------------------------------- */ GO_GTBOX(BUTTON_KIND, UNDERSCORE_GRP, BUTTON_ID, 0, MSG_EX1_BUTTON_LAB, PLACETEXT_IN), TAG_END, // We need to track the gadget's disabled state. GA_Disabled, FALSE, TAG_END, /* ----------------------------------------------------------- */ GO_GTBOX(SLIDER_KIND, UNDERSCORE_GRP, SLIDER_ID, 1, MSG_EX1_SLIDER_LAB, NG_HIGHLABEL|PLACETEXT_LEFT), TAG_END, // Include all of the previously declared tags; these will // be tracked just as if they appeared right in the outline. TAG_MORE, (ULONG)&slider_obj_tags, TAG_END, /* ----------------------------------------------------------- */ GO_GTBOX(CHECKBOX_KIND, UNDERSCORE_GRP, CHECKBOX_ID, 0, MSG_EX1_CHECKBOX_LAB, NG_HIGHLABEL|PLACETEXT_LEFT), TAG_END, GTCB_Checked, TRUE, TAG_END, GO_ENDGRP(), GO_ENDGRP(), GO_DRAWBOX(GOSD_Normal,0,0,0), GOCT_SizeSpaceLeft, GO_TSIZE(GOM_PadSet,50,GOT_PercCharW), GOCT_SizeSpaceRight, GO_TSIZE(GOM_PadSet,50,GOT_PercCharW), GOCT_SizeBodyWidth, GO_TSIZE(GOM_StdSet,4,GOT_Pixels), GOCT_SizeBodyWidth, GO_TSIZE(GOM_PadSet,0,GOT_Pixels), GOCT_SizeBodyHeight, GO_TSIZE(GOM_StdSet,2,GOT_Pixels), GOCT_SizeBodyHeight, GO_TSIZE(GOM_PadSet,0,GOT_Pixels), TAG_END, GODT_DrawStdFrame, GO_SCLPNT(SHINEPEN,0,0,63,63), TAG_END, GO_VERTGRP(0,0,1), TAG_END, // Draw the title text for this section. GO_DRAWBOX(GOSD_Normal,0,0,0), GOCT_FmtPtrTag, GODT_DrawStdText, GOCT_SizeBodyWidth, GO_TSIZE(GOM_StdMax,100,GOT_PercTextMaxW), GOCT_SizeBodyHeight, GO_TSIZE(GOM_StdMax,100,GOT_PercTextMaxH), TAG_END, GODT_SetTextMode, FLGALL(TXTMD_CENTER | TXTMD_ENDCENTER | TXTMD_RELTOP), GODT_MoveTo, GO_SCLPNT(0,32,0,0,0), GODT_DrawStdText, MSG_EX1_BOOPSI_TXT, TAG_END, GO_EMPTYBOX(0,0,1), GOCT_SizeBodyHeight, GO_TSIZE(GOM_PadSet,5,GOT_PercCharH), TAG_END, /* ----------------------------------------------------------- */ /* Basic BOOPSI example. */ /* This example creates a prop gadget connected to an integer */ /* Gadget. To do this, we make two BOOPSI gadgets of the */ /* appropriate type and connect them to each other through */ /* ICA_MAP and ICA_TARGET. */ /* ----------------------------------------------------------- */ GO_HORIZGRP(0,0,0), TAG_END, // Here we create a BOOPSI gadget. The first argument is // the type of object - in this case, GOSB_AddGad says we // are creating a BOOPSI gadget which should be attached to // the window. Next come the standard GrID, StdID and weight. // The last two arguments are the class - the first is a class // name and the second a class address. These are sent // directly to NewObject(). GO_BOOPSIBOX(GOSB_AddGad,0,BASICPROP_ID,1,(ULONG)&"propgclass",NULL), GOCT_SizeBodyHeight, GO_TSIZE(GOM_StdSet,100,GOT_PercCharH), GOCT_SizeBodyWidth, GO_TSIZE(GOM_StdSet,400,GOT_PercCharW), GOCT_SizeBodyWidth, GO_TSIZE(GOM_StdMax,20,GOT_Pixels), GOCT_SizeSpaceRight, GO_TSIZE(GOM_AllSet,0,GOT_Pixels), // A "LateLink" is a connection formed between two objects // after they are created; it is done by sending low-level // messages after the gadget creation cycle is completely // finished. To form the ICA maps, we need to use LateLinks // since the objects point to each other -- there is not // an order the library can construct the objects in which // can be done at build-time. GOCT_LateFromTag, ICA_TARGET, GOCT_LateToStdID, BASICINT_ID, TAG_END, ICA_MAP, (ULONG)&prop2intmap[0], ICA_TARGET, NULL, PGA_Freedom, FREEHORIZ, PGA_Total, TOTAL, PGA_Top, INITIALVAL, PGA_Visible, VISIBLE, PGA_NewLook, TRUE, TAG_END, // This is one way to do an integer gadget with a frame -- // create a horizontal drawing group which draws the frame, // and put a borderless int gadget inside the group. GO_HDRAWGRP(0,0,0), GOCT_FitToGroup, TRUE, GOCT_SizeTextLeft, GO_TSIZE(GOM_StdSet,200,GOT_PercStdFrmW), GOCT_SizeTextAbove, GO_TSIZE(GOM_StdSet,200,GOT_PercStdFrmH), GOCT_SizeTextRight, GO_TSIZE(GOM_StdSet,200,GOT_PercStdFrmW), GOCT_SizeTextBelow, GO_TSIZE(GOM_StdSet,200,GOT_PercStdFrmH), TAG_END, GODT_ResetBounds, GO_FRMBOUNDS(2,2,2,2, 4,4,4,4), GODT_DrawStdFrame, GO_SCLPNT(SHINEPEN,0,0,63,63), TAG_END, GO_BOOPSIBOX(GOSB_AddGad,0,BASICINT_ID,0,(ULONG)&"strgclass",NULL), GOCT_SizeSpaceLeft, GO_TSIZE(GOM_AllSet,0,GOT_Pixels), GOCT_SizeBodyHeight, GO_TSIZE(GOM_StdSet,100,GOT_PercCharH), GOCT_SizeBodyWidth, GO_TSIZE(GOM_StdSet,300,GOT_PercChar0), //GOCT_LinkFromTag, GA_Image, //GOCT_LateToStdID, BASICPROP_ID, GOCT_LateFromTag, ICA_TARGET, GOCT_LateToStdID, BASICPROP_ID, GOCT_CopyTextAttr, STRINGA_Font, TAG_END, ICA_MAP, (ULONG)&int2propmap[0], ICA_TARGET, NULL, STRINGA_LongVal, INITIALVAL, STRINGA_MaxChars, 4, STRINGA_Font, NULL, TAG_END, GO_ENDGRP(), GO_ENDGRP(), GO_EMPTYBOX(0,0,1), GOCT_SizeBodyHeight, GO_TSIZE(GOM_PadSet,50,GOT_PercCharH), TAG_END, // Draw the title text for this section. GO_DRAWBOX(GOSD_Normal,0,0,0), GOCT_FmtPtrTag, GODT_DrawStdText, GOCT_SizeBodyWidth, GO_TSIZE(GOM_StdMax,100,GOT_PercTextMaxW), GOCT_SizeBodyHeight, GO_TSIZE(GOM_StdMax,100,GOT_PercTextMaxH), TAG_END, GODT_SetTextMode, FLGALL(TXTMD_CENTER | TXTMD_ENDCENTER | TXTMD_RELTOP), GODT_MoveTo, GO_SCLPNT(0,32,0,0,0), GODT_DrawStdText, MSG_EX1_CUSTOMOBJ_TXT, TAG_END, GO_EMPTYBOX(0,0,1), GOCT_SizeBodyHeight, GO_TSIZE(GOM_PadSet,5,GOT_PercCharH), TAG_END, /* ----------------------------------------------------------- */ /* Custom class BOOPSI example. */ /* This example creates a complex BOOPSI structure based on */ /* the RKMModel tutorial. It is comprised of the objects: */ /* */ /* RIGHTIM_ID, LEFTIM_ID - BOOPSI images for the arrow gads. */ /* */ /* RIGHT_ID, LEFT_ID - BOOPSI buttons making the arrow gads. */ /* */ /* INTEGER_ID, INTFRAME_ID - An integer gadget for the value, */ /* along with a frame which is attached to the gadget. */ /* */ /* PROP_ID - The actual prop gadget. */ /* */ /* VAL2PROG_ID, VAL2INT_ID - Interconnection objects which */ /* are added to our custom class so that it can send update */ /* messages back to the integer and prop gadgets. */ /* */ /* RKMMODEL_ID - Our custom gadget, which manages the */ /* interactions between all of the above gadgets. See the */ /* RKMModel tutorial for details on this class. */ /* ----------------------------------------------------------- */ GO_HORIZGRP(0,0,0), TAG_END, // For this example, we are going fudge things a bit and draw // our own arrow buttons, since the system ones don't scale. // But this is how we would have used a system image... #if 0 GO_BOOPSIIMAGE(GOSB_Image,0,RIGHTIM_ID,(ULONG)&"sysiclass",NULL), GOCT_SetBodyLeft, GO_TSIZE(GOM_Set,0,GOT_Pixels), GOCT_SetBodyTop, GO_TSIZE(GOM_Set,0,GOT_Pixels), GOCT_SetBodyWidth, GO_BSIZE(GOM_Set,RIGHT_ID,GOTB_BodyWidth), GOCT_SetBodyHeight, GO_BSIZE(GOM_Set,RIGHT_ID,GOTB_BodyHeight), TAG_END, SYSIA_Which, RIGHTIMAGE, TAG_END, #endif #if 0 GO_BOOPSIIMAGE(GOSB_Image,0,LEFTIM_ID,(ULONG)&"sysiclass",NULL), GOCT_SetBodyLeft, GO_TSIZE(GOM_Set,0,GOT_Pixels), GOCT_SetBodyTop, GO_TSIZE(GOM_Set,0,GOT_Pixels), GOCT_SetBodyWidth, GO_BSIZE(GOM_Set,LEFT_ID,GOTB_BodyWidth), GOCT_SetBodyHeight, GO_BSIZE(GOM_Set,LEFT_ID,GOTB_BodyHeight), TAG_END, SYSIA_Which, LEFTIMAGE, TAG_END, #endif // Create custom drawings for the up/down buttons. These // are then attached to the actual button gadgets. #define ARROW_RGT (53) #define ARROW_TOP (10) #define ARROW_BOT (55) #define ARROW_LFT (10) #define ARROW_LMID (26) #define ARROW_RMID (38) GO_DRAWIMAGE(GOSD_BoopsiIm,0,RIGHTIM_ID), GOCT_SetBodyLeft, GO_TSIZE(GOM_Set,0,GOT_Pixels), GOCT_SetBodyTop, GO_TSIZE(GOM_Set,0,GOT_Pixels), GOCT_SetBodyWidth, GO_BSIZE(GOM_Set,RIGHT_ID,GOTB_BodyWidth), GOCT_SetBodyHeight, GO_BSIZE(GOM_Set,RIGHT_ID,GOTB_BodyHeight), TAG_END, GODT_ExecDrawing, (ULONG)&ThinIconInitDraw[0], GODT_AreaStart, GO_SCLPNT(TEXTPEN,ARROW_RGT,32,0,0), GODT_AreaDrawTo2, GO_SCLPNT(TEXTPEN,ARROW_LFT,ARROW_TOP,ARROW_LMID,32), GODT_AreaDrawTo2, GO_SCLPNT(TEXTPEN,ARROW_LFT,ARROW_BOT,ARROW_RGT,32), GODT_AreaFill, GO_SCLPNT(TEXTPEN,0,0,0,0), TAG_END, GO_DRAWIMAGE(GOSD_BoopsiIm,0,LEFTIM_ID), GOCT_SetBodyLeft, GO_TSIZE(GOM_Set,0,GOT_Pixels), GOCT_SetBodyTop, GO_TSIZE(GOM_Set,0,GOT_Pixels), GOCT_SetBodyWidth, GO_BSIZE(GOM_Set,RIGHT_ID,GOTB_BodyWidth), GOCT_SetBodyHeight, GO_BSIZE(GOM_Set,RIGHT_ID,GOTB_BodyHeight), TAG_END, GODT_ExecDrawing, (ULONG)&ThinIconInitDraw[0], GODT_AreaStart, GO_SCLPNT(TEXTPEN,ARROW_LFT,32,0,0), GODT_AreaDrawTo2, GO_SCLPNT(TEXTPEN,ARROW_RGT,ARROW_TOP,ARROW_RMID,32), GODT_AreaDrawTo2, GO_SCLPNT(TEXTPEN,ARROW_RGT,ARROW_BOT,ARROW_LFT,32), GODT_AreaFill, GO_SCLPNT(TEXTPEN,0,0,0,0), TAG_END, // Create the RKMModel object. GOCT_AddMember is used by // the BOOPSI command to send OM_ADDMEMBER methods to its // object when building the layout. GO_BOOPSIOBJ(GOSB_Object,0,RKMMODEL_ID,NULL,1), GOCT_AddMember, VAL2PROP_ID, GOCT_AddMember, VAL2INT_ID, TAG_END, RKMMOD_CurrVal, INITIALVAL, RKMMOD_Limit, (TOTAL-VISIBLE), TAG_END, // Create the integer gadget. In this case, we are going // to give it a frame by attaching a custom drawing to // the gadget. Due to problems either in BOOPSI or my // understanding of it :), custom drawing attached to another // gadget cannot get their drawing size of the size requested // by the gadget; we thus have to go through a bit of effort // to extract that size on our own. GO_DRAWIMAGE(GOSD_BoopsiIm,0,INTFRAME_ID), // Put the top-left edge of the frame in the integer gadget's // text area. "Scale by -100 percent" essentially negates // a value. GOCT_SetBodyLeft, GO_BSIZE(GOM_Set,INTEGER_ID,GOTB_TextLeft), GOCT_SetBodyLeft, GO_TSIZE(GOM_Set,-100,GOT_PercScale), GOCT_SetBodyTop, GO_BSIZE(GOM_Set,INTEGER_ID,GOTB_TextAbove), GOCT_SetBodyTop, GO_TSIZE(GOM_Set,-100,GOT_PercScale), // Make the width and height the sum of the two text areas // and the body area. GOCT_SetBodyWidth, GO_BSIZE(GOM_Set,INTEGER_ID,GOTB_TextLeft), GOCT_SetBodyWidth, GO_BSIZE(GOM_Add,INTEGER_ID,GOTB_BodyWidth), GOCT_SetBodyWidth, GO_BSIZE(GOM_Add,INTEGER_ID,GOTB_TextRight), GOCT_SetBodyHeight, GO_BSIZE(GOM_Set,RIGHT_ID,GOTB_TextAbove), GOCT_SetBodyHeight, GO_BSIZE(GOM_Add,RIGHT_ID,GOTB_BodyHeight), GOCT_SetBodyHeight, GO_BSIZE(GOM_Add,RIGHT_ID,GOTB_TextBelow), TAG_END, GODT_DrawStdFrame, GO_SCLPNT(SHINEPEN,0,0,63,63), TAG_END, GO_BOOPSIBOX(GOSB_AddGad,0,INTEGER_ID,0,(ULONG)&"strgclass",NULL), GOCT_SizeBodyHeight, GO_TSIZE(GOM_StdSet,100,GOT_PercCharH), GOCT_SizeBodyWidth, GO_TSIZE(GOM_StdSet,300,GOT_PercChar0), GOCT_SizeTextLeft, GO_TSIZE(GOM_StdSet,200,GOT_PercStdFrmW), GOCT_SizeTextAbove, GO_TSIZE(GOM_StdSet,200,GOT_PercStdFrmH), GOCT_SizeTextRight, GO_TSIZE(GOM_StdSet,200,GOT_PercStdFrmW), GOCT_SizeTextBelow, GO_TSIZE(GOM_StdSet,200,GOT_PercStdFrmH), GOCT_SizeSpaceRight, GO_TSIZE(GOM_AllSet,0,GOT_Pixels), GOCT_LinkFromTag, GA_Image, GOCT_LinkToStdID, INTFRAME_ID, GOCT_LinkFromTag, ICA_TARGET, GOCT_LinkToStdID, RKMMODEL_ID, GOCT_CopyTextFont, STRINGA_Font, TAG_END, ICA_MAP, (ULONG)&go2rkmmodel[0], ICA_TARGET, NULL, STRINGA_LongVal, INITIALVAL, STRINGA_MaxChars, 4, STRINGA_Font, NULL, GA_Image, NULL, TAG_END, GO_BOOPSIBOX(GOSB_AddGad,0,PROP_ID,1,(ULONG)&"propgclass",NULL), GOCT_SizeBodyHeight, GO_TSIZE(GOM_StdSet,100,GOT_PercCharH), GOCT_SizeBodyWidth, GO_TSIZE(GOM_StdSet,400,GOT_PercCharW), GOCT_SizeBodyWidth, GO_TSIZE(GOM_StdMax,20,GOT_Pixels), GOCT_SizeSpaceLeft, GO_TSIZE(GOM_AllSet,0,GOT_Pixels), GOCT_SizeSpaceRight, GO_TSIZE(GOM_AllSet,0,GOT_Pixels), GOCT_LinkFromTag, ICA_TARGET, GOCT_LinkToStdID, RKMMODEL_ID, TAG_END, ICA_MAP, (ULONG)&go2rkmmodel[0], ICA_TARGET, NULL, PGA_Freedom, FREEHORIZ, PGA_Total, TOTAL, PGA_Top, INITIALVAL, PGA_Visible, VISIBLE, PGA_NewLook, TRUE, TAG_END, // Create the up/down buttons. We need to do these this way // [rather than just directly making a GO_DRAWBOX()] because // we need to get at the underlying BOOPSI button gadget to // connect it to the rest of our system. GO_BOOPSIBOX(GOSB_AddGad,0,LEFT_ID,0,(ULONG)&"buttongclass",NULL), GOCT_ExecSizeTags, (ULONG)&ThinIconControl[0], GOCT_SizeSpaceLeft, GO_TSIZE(GOM_AllSet,0,GOT_Pixels), GOCT_SizeSpaceRight, GO_TSIZE(GOM_AllSet,0,GOT_Pixels), GOCT_LinkFromTag, ICA_TARGET, GOCT_LinkToStdID, RKMMODEL_ID, GOCT_LinkFromTag, GA_Image, GOCT_LinkToStdID, LEFTIM_ID, TAG_END, ICA_MAP, (ULONG)&left2rkmmodel[0], ICA_TARGET, NULL, GA_Image, NULL, TAG_END, GO_BOOPSIBOX(GOSB_AddGad,0,RIGHT_ID,0,(ULONG)&"buttongclass",NULL), GOCT_ExecSizeTags, (ULONG)&ThinIconControl[0], GOCT_SizeSpaceLeft, GO_TSIZE(GOM_AllSet,0,GOT_Pixels), GOCT_LinkFromTag, ICA_TARGET, GOCT_LinkToStdID, RKMMODEL_ID, GOCT_LinkFromTag, GA_Image, GOCT_LinkToStdID, RIGHTIM_ID, TAG_END, ICA_MAP, (ULONG)&right2rkmmodel[0], ICA_TARGET, NULL, GA_Image, NULL, TAG_END, // Create the interconnection objects which RKMClasses uses // to send update messages out to the prop and integer. GO_BOOPSIOBJ(GOSB_Object,0,VAL2PROP_ID,(ULONG)&"icclass",NULL), GOCT_LinkFromTag, ICA_TARGET, GOCT_LinkToStdID, PROP_ID, TAG_END, ICA_MAP, (ULONG)&mapcurrval2prop[0], ICA_TARGET, NULL, TAG_END, GO_BOOPSIOBJ(GOSB_Object,0,VAL2INT_ID,(ULONG)&"icclass",NULL), GOCT_LinkFromTag, ICA_TARGET, GOCT_LinkToStdID, INTEGER_ID, TAG_END, ICA_MAP, (ULONG)&mapcurrval2int[0], ICA_TARGET, NULL, TAG_END, GO_ENDGRP(), GO_DRAWBOX(GOSD_Normal,0,0,0), GOCT_FmtPtrTag, GODT_DrawStdText, GOCT_SizeBodyWidth, GO_TSIZE(GOM_StdMax,100,GOT_PercTextMaxW), GOCT_SizeBodyHeight, GO_TSIZE(GOM_StdMax,100,GOT_PercTextMaxH), TAG_END, GODT_SetTextMode, FLGALL(TXTMD_CENTER | TXTMD_ENDCENTER | TXTMD_RELTOP), GODT_MoveTo, GO_SCLPNT(0,32,0,0,0), GODT_DrawStdText, MSG_EX1_RKMMODEL_LAB, TAG_END, GO_EMPTYBOX(0,0,1), GOCT_SizeBodyHeight, GO_TSIZE(GOM_PadSet,50,GOT_PercCharH), TAG_END, // Draw the title text for this section. GO_DRAWBOX(GOSD_Normal,0,0,0), GOCT_FmtPtrTag, GODT_DrawStdText, GOCT_SizeBodyWidth, GO_TSIZE(GOM_StdMax,100,GOT_PercTextMaxW), GOCT_SizeBodyHeight, GO_TSIZE(GOM_StdMax,100,GOT_PercTextMaxH), TAG_END, GODT_SetTextMode, FLGALL(TXTMD_CENTER | TXTMD_ENDCENTER | TXTMD_RELTOP), GODT_MoveTo, GO_SCLPNT(0,32,0,0,0), GODT_DrawStdText, MSG_EX1_CUSTOMIMG_TXT, TAG_END, GO_EMPTYBOX(0,0,1), GOCT_SizeBodyHeight, GO_TSIZE(GOM_PadSet,5,GOT_PercCharH), TAG_END, /* ----------------------------------------------------------- */ /* GO drawings with BOOPSI example. */ /* This example gives an idea of what is possible when */ /* integrating GadOutline's custom drawings with BOOPSI */ /* objects. It creates a prop/integer gadget just like the */ /* first example, and adds a custom drawing which the prop */ /* gadget uses as its knob. It is comprised of the objects: */ /* */ /* PROPKNOB_ID - The drawing used to make the knob. */ /* */ /* DRAWINT_ID - The integer gadget. */ /* */ /* DRAWPROP_ID - The actual prop gadget. */ /* ----------------------------------------------------------- */ GO_HORIZGRP(0,0,0), TAG_END, // This command defines our prop knob. Unfortunately, the // system's prop gadget can't make an auto-sizing knob with // a custom knob image, so we force the knob to be a constant // percentage of the prop's body. GO_DRAWIMAGE(GOSD_BoopsiIm,0,PROPKNOB_ID), // Top and left are relative to the knob position. GOCT_SetBodyLeft, GO_TSIZE(GOM_Set,0,GOT_Pixels), GOCT_SetBodyTop, GO_TSIZE(GOM_Set,0,GOT_Pixels), // Make the width 15% of the total prop container width. GOCT_SetBodyWidth, GO_BSIZE(GOM_Set,BASICPROP_ID,GOTB_BodyWidth), GOCT_SetBodyWidth, GO_TSIZE(GOM_Add,-2,GOT_Pixels), GOCT_SetBodyWidth, GO_TSIZE(GOM_Set,15,GOT_PercScale), // Make the height the container height, without the borders. GOCT_SetBodyHeight, GO_BSIZE(GOM_Set,BASICPROP_ID,GOTB_BodyHeight), GOCT_SetBodyHeight, GO_TSIZE(GOM_Add,-2,GOT_Pixels), TAG_END, GODT_DrawStdFrame, GO_SCLPNT(SHINEPEN,0,0,63,63), GODT_SetRightBound, GO_TSIZE(GOM_Add,-100,GOT_PercStdFrmW), GODT_SetBottomBound, GO_TSIZE(GOM_Add,-100,GOT_PercStdFrmH), GODT_SetLeftBound, GO_TSIZE(GOM_Add,100,GOT_PercStdFrmW), GODT_SetTopBound, GO_TSIZE(GOM_Add,100,GOT_PercStdFrmH), GODT_FillRect, GO_SCLPNT(BACKGROUNDPEN,0,0,63,63), GODT_SetDrawMode, FLGOFF(DRWMD_HIGHLIGHT), GODT_SetOrigin, GO_SCLPNT(0,16,16,16,48), GODT_DrawLine, GO_PIXPNT(SHADOWPEN,PX1(1),PY1(1),PX2(1),PY2(1)), GODT_DrawLine, GO_PIXPNT(SHINEPEN,PX1(0),PY1(0),PX2(0),PY2(0)), GODT_SetOrigin, GO_SCLPNT(0,32,16,32,48), GODT_DrawLine, GO_PIXPNT(SHADOWPEN,PX1(1),PY1(1),PX2(1),PY2(1)), GODT_DrawLine, GO_PIXPNT(SHINEPEN,PX1(0),PY1(0),PX2(0),PY2(0)), GODT_SetOrigin, GO_SCLPNT(0,48,16,48,48), GODT_DrawLine, GO_PIXPNT(SHADOWPEN,PX1(1),PY1(1),PX2(1),PY2(1)), GODT_DrawLine, GO_PIXPNT(SHINEPEN,PX1(0),PY1(0),PX2(0),PY2(0)), TAG_END, // Create the prop gadget, connecting its image and selected // image to our custom drawing. GO_BOOPSIBOX(GOSB_AddGad,0,DRAWPROP_ID,1,(ULONG)&"propgclass",NULL), GOCT_SizeBodyHeight, GO_TSIZE(GOM_StdSet,100,GOT_PercCharH), GOCT_SizeBodyWidth, GO_TSIZE(GOM_StdSet,400,GOT_PercCharW), GOCT_SizeBodyWidth, GO_TSIZE(GOM_StdMax,20,GOT_Pixels), GOCT_SizeSpaceRight, GO_TSIZE(GOM_AllSet,0,GOT_Pixels), GOCT_LateFromTag, ICA_TARGET, GOCT_LateToStdID, DRAWINT_ID, GOCT_LinkFromTag, GA_Image, GOCT_LinkToStdID, PROPKNOB_ID, GOCT_LinkFromTag, GA_SelectRender, GOCT_LinkToStdID, PROPKNOB_ID, TAG_END, ICA_MAP, (ULONG)&prop2intmap[0], ICA_TARGET, NULL, PGA_Freedom, FREEHORIZ, PGA_Total, TOTAL, PGA_Top, INITIALVAL, PGA_Visible, VISIBLE, PGA_NewLook, TRUE, GA_Image, NULL, GA_SelectRender, NULL, TAG_END, // Create the integer gadget with frame, just like the // first example. GO_HDRAWGRP(0,0,0), GOCT_FitToGroup, TRUE, GOCT_SizeTextLeft, GO_TSIZE(GOM_StdSet,200,GOT_PercStdFrmW), GOCT_SizeTextAbove, GO_TSIZE(GOM_StdSet,200,GOT_PercStdFrmH), GOCT_SizeTextRight, GO_TSIZE(GOM_StdSet,200,GOT_PercStdFrmW), GOCT_SizeTextBelow, GO_TSIZE(GOM_StdSet,200,GOT_PercStdFrmH), TAG_END, GODT_ResetBounds, GO_FRMBOUNDS(2,2,2,2, 4,4,4,4), GODT_DrawStdFrame, GO_SCLPNT(SHINEPEN,0,0,63,63), TAG_END, GO_BOOPSIBOX(GOSB_AddGad,0,DRAWINT_ID,0,(ULONG)&"strgclass",NULL), GOCT_SizeSpaceLeft, GO_TSIZE(GOM_AllSet,0,GOT_Pixels), GOCT_SizeBodyHeight, GO_TSIZE(GOM_StdSet,100,GOT_PercCharH), GOCT_SizeBodyWidth, GO_TSIZE(GOM_StdSet,300,GOT_PercChar0), GOCT_LateFromTag, ICA_TARGET, GOCT_LateToStdID, DRAWPROP_ID, GOCT_LinkFromTag, GA_Image, GOCT_LateToStdID, DRAWPROP_ID, GOCT_CopyTextFont, STRINGA_Font, TAG_END, ICA_MAP, (ULONG)&int2propmap[0], ICA_TARGET, NULL, STRINGA_LongVal, INITIALVAL, STRINGA_MaxChars, 4, STRINGA_Font, NULL, TAG_END, GO_ENDGRP(), GO_ENDGRP(), GO_ENDGRP(), GO_DRAWBOX(GOSD_Normal,0,0,0), GOCT_SizeSpaceLeft, GO_TSIZE(GOM_PadSet,50,GOT_PercCharW), GOCT_SizeSpaceRight, GO_TSIZE(GOM_PadSet,50,GOT_PercCharW), GOCT_SizeBodyWidth, GO_TSIZE(GOM_StdSet,4,GOT_Pixels), GOCT_SizeBodyWidth, GO_TSIZE(GOM_PadSet,0,GOT_Pixels), GOCT_SizeBodyHeight, GO_TSIZE(GOM_StdSet,2,GOT_Pixels), GOCT_SizeBodyHeight, GO_TSIZE(GOM_PadSet,0,GOT_Pixels), TAG_END, GODT_DrawStdFrame, GO_SCLPNT(SHINEPEN,0,0,63,63), TAG_END, GO_VERTGRP(0,0,0), TAG_END, // Draw the title text for this section. GO_DRAWBOX(GOSD_Normal,0,0,0), GOCT_FmtPtrTag, GODT_DrawStdText, GOCT_SizeBodyWidth, GO_TSIZE(GOM_StdMax,100,GOT_PercTextMaxW), GOCT_SizeBodyHeight, GO_TSIZE(GOM_StdMax,100,GOT_PercTextMaxH), TAG_END, GODT_SetTextMode, FLGALL(TXTMD_CENTER | TXTMD_ENDCENTER | TXTMD_RELTOP), GODT_MoveTo, GO_SCLPNT(0,32,0,0,0), GODT_DrawStdText, MSG_EX1_DYNAMIC_TXT, TAG_END, GO_EMPTYBOX(0,0,1), GOCT_SizeBodyHeight, GO_TSIZE(GOM_PadSet,25,GOT_PercCharH), TAG_END, GO_HORIZGRP(0,0,0), GOCT_FitToGroup, TRUE, TAG_END, // Draw a font request icon, with title text. GO_DRAWBOX(GOSD_BoopsiGad,UNDERSCORE_GRP,REQFONT_ID, GO_WEIGHT(GO_WDIST(1,0,0,0,1,0),GO_WDIST(1,0,0,0,1,0),1)), GOCT_SetHotKey, 'f', GOCT_FmtPtrTag, GODT_DrawStdText, GOCT_SizeTextLeft, GO_TSIZE(GOM_StdSet,100,GOT_PercTextMaxW), GOCT_FmtPtrTag, GODT_DrawText, GOCT_SizeBodyWidth, GO_TSIZE(GOM_StdSet,100,GOT_PercTextMaxW), GOCT_SizeBodyWidth, GO_TSIZE(GOM_StdAdd,400,GOT_PercStdFrmW), GOCT_SizeBodyWidth, GO_TSIZE(GOM_StdAdd,3,GOT_Pixels), GOCT_SizeBodyHeight, GO_TSIZE(GOM_StdSet,100,GOT_PercTextMaxH), GOCT_SizeBodyHeight, GO_TSIZE(GOM_StdAdd,400,GOT_PercStdFrmH), TAG_END, GODT_ExecDrawing, (ULONG)&IconInitDraw[0], GODT_SetDrawMode, FLGOFF(DRWMD_HIGHLIGHT), GODT_SetTextMode, FLGALL(TXTMD_LEFT | TXTMD_ENDLEFT | TXTMD_RELCENTER), GODT_SetOrigin, GO_SCLPNT(0,0,32,0,0), GODT_ChooseTextAPen, SHADOWPEN, GODT_MoveTo, GO_PIXPNT(0,PX1(3),PY1(0),0,0), GODT_DrawText, MSG_EX1_FONT_FMT, GODT_MoveTo, GO_PIXPNT(0,PX1(0),PY1(0),0,0), GODT_DrawText, MSG_EX1_FONT_FMT, GODT_MoveTo, GO_PIXPNT(0,PX1(2),PY1(0),0,0), GODT_ChooseTextAPen, FILLPEN, GODT_DrawText, MSG_EX1_FONT_FMT, GODT_MoveTo, GO_PIXPNT(0,PX1(1),PY1(0),0,0), GODT_DrawHighText, MSG_EX1_FONT_FMT, GODT_ResetBounds, GO_BOXBOUNDS(2,3,2,3), GODT_SetDrawMode, FLGOFF(DRWMD_HIGHLIGHT), GODT_SetTextMode, FLGALL(TXTMD_RIGHT | TXTMD_ENDRIGHT | TXTMD_RELCENTER), GODT_SetTextStyle, FLGALL(0), GODT_MoveTo, GO_SCLPNT(0,63,32,0,0), GODT_DrawStdText, MSG_EX1_FONT_LAB, TAG_END, GO_EMPTYBOX(0,0,1), GOCT_SizeBodyWidth, GO_TSIZE(GOM_PadSet,100,GOT_PercCharW), TAG_END, #define JUMP_2TOP (0) #define JUMP_2LEFT (25) #define JUMP_2RIGHT (63) #define JUMP_2MID (18) #define JUMP_2BOT (55) #define JUMP_1TOP (17) #define JUMP_1LEFT (0) #define JUMP_1RIGHT (42) #define JUMP_1MID (31) #define JUMP_1BOT (63) #if 0 #define JUMP_LINEX1 (10) #define JUMP_LINEY1 (55) #define JUMP_LINEX2 (55) #define JUMP_LINEY2 (47) #define JUMP_LINEX3 (40) #define JUMP_LINEY3 (42) #define JUMP_LINEX4 (57) #define JUMP_LINEY4 (60) #endif // Draw a "jump screens" icon, with title text. GO_DRAWBOX(GOSD_BoopsiGad,UNDERSCORE_GRP,JUMPWIN_ID, GO_WEIGHT(GO_WDIST(1,0,0,0,1,0),GO_WDIST(1,0,0,0,1,0),1)), GOCT_SetHotKey, 'j', GOCT_FmtPtrTag, GODT_DrawStdText, GOCT_SizeTextLeft, GO_TSIZE(GOM_StdSet,100,GOT_PercTextMaxW), GOCT_ExecSizeTags, (ULONG)&SmallIconControl[0], TAG_END, GODT_ExecDrawing, (ULONG)&IconInitDraw[0], GODT_SetDrawMode, FLGOFF(DRWMD_HIGHLIGHT), GODT_SetRastMode, FLGALL(JAM2), //GODT_SetStdFillPat, FLPAT_HASH2, GODT_SetDrI15Pen, 0, GODT_MapHighPen, GO_MAPPEN(15,15), GODT_ChooseBPen, BACKGROUNDPEN, GODT_FillRect, GO_SCLPNT(BARBLOCKPEN,JUMP_2LEFT,JUMP_2TOP,JUMP_2RIGHT,JUMP_2MID), GODT_FillRect, GO_SCLPNT(BACKGROUNDPEN,JUMP_2RIGHT-5,JUMP_2TOP,JUMP_2RIGHT,JUMP_2MID), GODT_DrawRect, GO_SCLPNT(TEXTPEN,JUMP_2LEFT,JUMP_2TOP,JUMP_2RIGHT,JUMP_2MID), GODT_FillRect, GO_SCLPNT(15,JUMP_2LEFT,JUMP_2MID,JUMP_2RIGHT,JUMP_2BOT), GODT_DrawRect, GO_SCLPNT(TEXTPEN,JUMP_2LEFT,JUMP_2MID,JUMP_2RIGHT,JUMP_2BOT), GODT_SetOrigin, GO_SCLPNT(0,JUMP_1LEFT,JUMP_1TOP,JUMP_1RIGHT,JUMP_1BOT), //GODT_FillRect, GO_PIXPNT(BACKGROUNDPEN,PX1(-1),PY1(-1),PX2(1),PY2(1)), GODT_FillRect, GO_SCLPNT(BARBLOCKPEN,JUMP_1LEFT,JUMP_1TOP,JUMP_1RIGHT,JUMP_1MID), GODT_FillRect, GO_SCLPNT(BACKGROUNDPEN,JUMP_1RIGHT-5,JUMP_1TOP,JUMP_1RIGHT,JUMP_1MID), GODT_DrawRect, GO_SCLPNT(TEXTPEN,JUMP_1LEFT,JUMP_1TOP,JUMP_1RIGHT,JUMP_1MID), GODT_FillRect, GO_SCLPNT(15,JUMP_1LEFT,JUMP_1MID,JUMP_1RIGHT,JUMP_1BOT), GODT_DrawRect, GO_SCLPNT(TEXTPEN,JUMP_1LEFT,JUMP_1MID,JUMP_1RIGHT,JUMP_1BOT), #if 0 GODT_SetOrigin, GO_SCLPNT(0,JUMP_LINEX1,JUMP_LINEY1,JUMP_LINEX2,JUMP_LINEY2), GODT_DrawLine, GO_PIXPNT(TEXTPEN,PX1(0),PY1(1),PX2(0),PY2(1)), GODT_SetOrigin, GO_SCLPNT(0,JUMP_LINEX2,JUMP_LINEY2,JUMP_LINEX3,JUMP_LINEY3), GODT_DrawLine, GO_PIXPNT(TEXTPEN,PX1(1),PY1(-1),PX2(1),PY2(-1)), GODT_SetOrigin, GO_SCLPNT(0,JUMP_LINEX2,JUMP_LINEY2,JUMP_LINEX4,JUMP_LINEY4), GODT_DrawLine, GO_PIXPNT(TEXTPEN,PX1(1),PY1(0),PX2(1),PY2(0)), GODT_SetOrigin, GO_SCLPNT(0,JUMP_LINEX1,JUMP_LINEY1,JUMP_LINEX2,JUMP_LINEY2), GODT_DrawLine, GO_PIXPNT(HIGHLIGHTTEXTPEN,PX1(0),PY1(0),PX2(0),PY2(0)), //GODT_DrawLine, GO_PIXPNT(HIGHLIGHTTEXTPEN,PX1(-1),PY1(0),PX2(-1),PY2(0)), GODT_SetOrigin, GO_SCLPNT(0,JUMP_LINEX2,JUMP_LINEY2,JUMP_LINEX3,JUMP_LINEY3), GODT_DrawLine, GO_PIXPNT(HIGHLIGHTTEXTPEN,PX1(0),PY1(0),PX2(0),PY2(0)), //GODT_DrawLine, GO_PIXPNT(HIGHLIGHTTEXTPEN,PX1(-1),PY1(0),PX2(-1),PY2(0)), GODT_SetOrigin, GO_SCLPNT(0,JUMP_LINEX2,JUMP_LINEY2,JUMP_LINEX4,JUMP_LINEY4), GODT_DrawLine, GO_PIXPNT(HIGHLIGHTTEXTPEN,PX1(0),PY1(0),PX2(0),PY2(0)), //GODT_DrawLine, GO_PIXPNT(HIGHLIGHTTEXTPEN,PX1(-1),PY1(0),PX2(-1),PY2(0)), #endif GODT_ResetBounds, GO_BOXBOUNDS(2,3,2,3), GODT_SetDrawMode, FLGOFF(DRWMD_HIGHLIGHT), GODT_SetTextMode, FLGALL(TXTMD_RIGHT | TXTMD_ENDRIGHT | TXTMD_RELCENTER), GODT_SetRastMode, FLGALL(JAM1), GODT_MoveTo, GO_SCLPNT(0,63,32,0,0), GODT_DrawStdText, MSG_EX1_JUMP_LAB, TAG_END, GO_ENDGRP(), GO_EMPTYBOX(0,0,1), GOCT_SizeBodyHeight, GO_TSIZE(GOM_PadSet,25,GOT_PercCharH), TAG_END, GO_VERTGRP(0,0,0), GOCT_FitToGroup, TRUE, TAG_END, // Draw a outline values request icon, with title text. GO_DRAWBOX(GOSD_BoopsiGad,UNDERSCORE_GRP,OUTVALUES_ID, GO_WEIGHT(GO_WDIST(1,0,0,0,1,0),GO_WDIST(1,0,0,0,1,0),1)), GOCT_SetHotKey, 'o', GOCT_FmtPtrTag, GODT_DrawStdText, GOCT_SizeTextLeft, GO_TSIZE(GOM_StdSet,100,GOT_PercTextMaxW), GOCT_FmtPtrTag, GODT_DrawText, GOCT_SizeBodyWidth, GO_TSIZE(GOM_StdSet,100,GOT_PercTextMaxW), GOCT_SizeBodyWidth, GO_TSIZE(GOM_StdAdd,400,GOT_PercStdFrmW), GOCT_SizeBodyWidth, GO_TSIZE(GOM_StdAdd,3,GOT_Pixels), GOCT_SizeBodyHeight, GO_TSIZE(GOM_StdSet,100,GOT_PercTextMaxH), GOCT_SizeBodyHeight, GO_TSIZE(GOM_StdAdd,400,GOT_PercStdFrmH), TAG_END, GODT_ExecDrawing, (ULONG)&IconInitDraw[0], GODT_SetDrawMode, FLGOFF(DRWMD_HIGHLIGHT), GODT_SetTextMode, FLGALL(TXTMD_LEFT | TXTMD_ENDLEFT | TXTMD_RELCENTER), GODT_SetOrigin, GO_SCLPNT(0,0,32,0,0), GODT_ChooseTextAPen, SHADOWPEN, GODT_MoveTo, GO_PIXPNT(0,PX1(3),PY1(0),0,0), GODT_DrawText, MSG_EX1_OUTVALUES_FMT, GODT_MoveTo, GO_PIXPNT(0,PX1(0),PY1(0),0,0), GODT_DrawText, MSG_EX1_OUTVALUES_FMT, GODT_MoveTo, GO_PIXPNT(0,PX1(2),PY1(0),0,0), GODT_ChooseTextAPen, FILLPEN, GODT_DrawText, MSG_EX1_OUTVALUES_FMT, GODT_MoveTo, GO_PIXPNT(0,PX1(1),PY1(0),0,0), GODT_DrawHighText, MSG_EX1_OUTVALUES_FMT, GODT_ResetBounds, GO_BOXBOUNDS(2,3,2,3), GODT_SetDrawMode, FLGOFF(DRWMD_HIGHLIGHT), GODT_SetTextMode, FLGALL(TXTMD_RIGHT | TXTMD_ENDRIGHT | TXTMD_RELCENTER), GODT_SetTextStyle, FLGALL(0), GODT_MoveTo, GO_SCLPNT(0,63,32,0,0), GODT_DrawStdText, MSG_EX1_OUTVALUES_LAB, TAG_END, // Draw a window values request icon, with title text. GO_DRAWBOX(GOSD_BoopsiGad,UNDERSCORE_GRP,WINVALUES_ID, GO_WEIGHT(GO_WDIST(1,0,0,0,1,0),GO_WDIST(1,0,0,0,1,0),1)), GOCT_SetHotKey, 'w', GOCT_FmtPtrTag, GODT_DrawStdText, GOCT_SizeTextLeft, GO_TSIZE(GOM_StdSet,100,GOT_PercTextMaxW), GOCT_FmtPtrTag, GODT_DrawText, GOCT_SizeBodyWidth, GO_TSIZE(GOM_StdSet,100,GOT_PercTextMaxW), GOCT_SizeBodyWidth, GO_TSIZE(GOM_StdAdd,400,GOT_PercStdFrmW), GOCT_SizeBodyWidth, GO_TSIZE(GOM_StdAdd,3,GOT_Pixels), GOCT_SizeBodyHeight, GO_TSIZE(GOM_StdSet,100,GOT_PercTextMaxH), GOCT_SizeBodyHeight, GO_TSIZE(GOM_StdAdd,400,GOT_PercStdFrmH), TAG_END, GODT_ExecDrawing, (ULONG)&IconInitDraw[0], GODT_SetDrawMode, FLGOFF(DRWMD_HIGHLIGHT), GODT_SetTextMode, FLGALL(TXTMD_LEFT | TXTMD_ENDLEFT | TXTMD_RELCENTER), GODT_SetOrigin, GO_SCLPNT(0,0,32,0,0), GODT_ChooseTextAPen, SHADOWPEN, GODT_MoveTo, GO_PIXPNT(0,PX1(3),PY1(0),0,0), GODT_DrawText, MSG_EX1_WINVALUES_FMT, GODT_MoveTo, GO_PIXPNT(0,PX1(0),PY1(0),0,0), GODT_DrawText, MSG_EX1_WINVALUES_FMT, GODT_MoveTo, GO_PIXPNT(0,PX1(2),PY1(0),0,0), GODT_ChooseTextAPen, FILLPEN, GODT_DrawText, MSG_EX1_WINVALUES_FMT, GODT_MoveTo, GO_PIXPNT(0,PX1(1),PY1(0),0,0), GODT_DrawHighText, MSG_EX1_WINVALUES_FMT, GODT_ResetBounds, GO_BOXBOUNDS(2,3,2,3), GODT_SetDrawMode, FLGOFF(DRWMD_HIGHLIGHT), GODT_SetTextMode, FLGALL(TXTMD_RIGHT | TXTMD_ENDRIGHT | TXTMD_RELCENTER), GODT_SetTextStyle, FLGALL(0), GODT_MoveTo, GO_SCLPNT(0,63,32,0,0), GODT_DrawStdText, MSG_EX1_WINVALUES_LAB, TAG_END, GO_ENDGRP(), GO_EMPTYBOX(0,0,1), GOCT_SizeBodyHeight, GO_TSIZE(GOM_PadSet,25,GOT_PercCharH), TAG_END, GO_DRAWBOX(GOSD_BoopsiGad,UNDERSCORE_GRP,ICONIFY_ID,0), GOCT_HotKeyFromTag, GODT_DrawStdText, GOCT_FmtPtrTag, GODT_DrawStdText, GOCT_SizeBodyWidth, GO_TSIZE(GOM_StdSet,100,GOT_PercTextMaxW), GOCT_SizeBodyWidth, GO_TSIZE(GOM_StdAdd,400,GOT_PercStdFrmW), GOCT_SizeBodyHeight, GO_TSIZE(GOM_StdSet,100,GOT_PercTextMaxH), GOCT_SizeBodyHeight, GO_TSIZE(GOM_StdAdd,400,GOT_PercStdFrmH), TAG_END, GA_Disabled, FALSE, GODT_ExecDrawing, (ULONG)&IconInitDraw[0], GODT_SetTextMode, FLGALL(TXTMD_CENTER | TXTMD_ENDLEFT | TXTMD_RELCENTER), GODT_MoveTo, GO_SCLPNT(0,32,32,0,0), GODT_DrawStdText, MSG_EX1_ICONIFY_LAB, TAG_END, #if 0 GO_GTBOX(BUTTON_KIND, UNDERSCORE_GRP, ICONIFY_ID, 0, MSG_EX1_ICONIFY_LAB, PLACETEXT_IN), TAG_END, GA_Disabled, FALSE, TAG_END, #endif GO_EMPTYBOX(0,0,1), GOCT_SizeBodyHeight, GO_TSIZE(GOM_PadSet,25,GOT_PercCharH), TAG_END, GO_DRAWBOX(GOSD_Normal,0,0,0), GOCT_SizeBodyWidth, GO_TSIZE(GOM_StdSet,2,GOT_Pixels), GOCT_SizeBodyWidth, GO_TSIZE(GOM_PadSet,0,GOT_Pixels), GOCT_SizeBodyHeight, GO_TSIZE(GOM_StdSet,2,GOT_Pixels), GOCT_SizeBodyHeight, GO_TSIZE(GOM_PadSet,0,GOT_Pixels), GOCT_SizeSpaceAbove, GO_TSIZE(GOM_PadSet,50,GOT_PercCharH), GOCT_SizeSpaceBelow, GO_TSIZE(GOM_PadSet,50,GOT_PercCharH), TAG_END, GODT_DrawLine, GO_SCLPNT(SHINEPEN,0,0,63,0), GODT_DrawLine, GO_SCLPNT(SHADOWPEN,0,63,63,63), TAG_END, GO_DRAWBOX(GOSD_Normal,0,KEYSHOW_ID,0), GOCT_FmtPtrTag, GODT_DrawStdText, GOCT_SizeBodyWidth, GO_TSIZE(GOM_StdMax,100,GOT_PercTextMaxW), GOCT_SizeBodyHeight, GO_TSIZE(GOM_StdMax,200,GOT_PercTextMaxH), TAG_END, GODT_BodyTextPtr, MSG_EX1_EMPTY_STR, GODT_LeftTextPtr, MSG_EX1_EMPTY_STR, GODT_SetTextMode, FLGALL(TXTMD_CENTER | TXTMD_ENDCENTER | TXTMD_RELTOP), GODT_EraseRect, GO_SCLPNT(0,0,0,63,63), GODT_MoveTo, GO_SCLPNT(0,32,0,0,0), GODT_DrawStdText, MSG_EX1_LASTKEY_LAB, GODT_ChooseTextAPen, TEXTPEN, GODT_ChooseTextBPen, HIGHLIGHTTEXTPEN, GODT_DrawTextTag, GODT_BodyTextPtr, TAG_END, GO_ENDGRP(), GO_ENDGRP(), GO_ENDGRP(), // Every outline must end with this command. GO_ENDOUTLINE() }; /********************************************* ** ** Example hooks used in outline ** *********************************************/ // This is an example command hook. It implements the code for finding // the minimum dimensions of a checkbox and the code for responding to hotkey // events. // Note that this hook is not directly referenced in the outline - instead, // a code is supplied for it in GOCT_SetUserHook and the translation hook // converts this code to the actual address. You don't normally need to // use this circulatory method, but we are doing it here to also demonstrate // how translation hooks work. // First, some functions we will use. static UWORD get_cb_width(struct GadOutline* go) { if(GadToolsBase->lib_Version >= 39) { return (UWORD)GO_InterpretTypedSize(go,2, GO_TSIZE(GOM_Add,300,GOT_PercChar0)); } else { return 26; } } static UWORD get_cb_height(struct GadOutline* go) { if(GadToolsBase->lib_Version >= 39) { return (UWORD)GO_InterpretTypedSize(go,3, GO_TSIZE(GOM_Add,100,GOT_PercCharH)); } else { return 11; } } ULONG __asm __saveds checkbox_code(register __a0 struct Hook *hook, register __a2 struct CmdInfo *ci, register __a1 struct CmdHookMsg *msg) { struct GadOutline *go; // Global outline information. struct BoxAttr *ba; // Box which called this hook. struct Gadget *gad; // Gadget of hook, if created. ULONG ret; // Return code. UWORD kind; // GadTools kind of this box. // --------------------------------------------------- // Find some Universally Interesting variables. // --------------------------------------------------- if(ci) { go = ci->ci_GadOutline; // Extract GadOutline kind = GETCMDSUBC(ci->ci_Command); // GadTools kind gad = ci->ci_Object; // Currently created gadget ba = ci->ci_BoxAttr; // And BoxAttr of caller. } else go = NULL; #if NOISY D(bug("ID# %08lx: Msg=%08lx; Cmd=%08lx\n", ci->ci_CmdID,msg->chm_Message,ci->ci_Command)); #endif // --------------------------------------------------- // Sanity checking... // --------------------------------------------------- if(!hook || !msg || !ci || !go) return 0; // --------------------------------------------------- // Check if this is correct type of command. // --------------------------------------------------- if( (ci->ci_Command&GO_OUTCMD(0,0,0xFFFF,0xFFFF,0)) != GO_OUTCMD(0,0,GOK_Box,GOKB_GadTools,0) ) { // Continue processing this message. Note that you must ALWAYS // pass along the return value from lower-level hooks if you are // not going to set it yourself. return GO_ContCmdHookA(ci,msg); } switch(msg->chm_Message) { case CHM_GETMINDIMENS: { struct GODimensInfo *gdi; WORD height,width; // The structure to fill in with our dimension information. gdi = msg->chm_MinDim; // Some example calls, just for the heck of it... :) // Note that when a hook is executed, the command is // automatically "in context." This means that TypedSize // commands will refer to the current command for such // things as finding what the underscore character is. height = GO_InterpretTypedSize(go,0, GO_TSIZE(GOM_Set,100,GOT_PercCharH)); width = GO_ParseTypedSizeList(go,0, GOCT_FmtPtr,ci->ci_BoxText, GOCT_SizeParse,GO_TSIZE(GOM_Set,100,GOT_PercTextMaxW), TAG_END); // If this is a checkbox... if(kind == CHECKBOX_KIND) { // Let default hook do what it can. The library currently // knows how to take care of GadTools labels, and we don't // really want to duplicate -everything- here. Note that // we save the return value, because we have nothing else // to say. ret = GO_ContCmdHookA(ci,msg); width = get_cb_width(go); height = get_cb_height(go); // Make sure the checkbox's body is big enough. if(gdi->gdi_StdBodyWidth < width) { gdi->gdi_StdBodyWidth = width; } if(gdi->gdi_StdBodyHeight < height) { gdi->gdi_StdBodyHeight = 11; } } else { // If not a checkbox, just let the system handle it. ret = GO_ContCmdHookA(ci,msg); } } break; case CHM_HOTKEY: { struct TagItem *tg; // Only respond to IDCMP_VANILLAKEY events and IDCMP_RAWKEY // down events. if( (msg->chm_KeyGOIMsg->StdIMsg.Class != IDCMP_VANILLAKEY && msg->chm_KeyGOIMsg->StdIMsg.Class != IDCMP_RAWKEY) || (msg->chm_KeyGOIMsg->StdIMsg.Class == IDCMP_RAWKEY && (msg->chm_KeyGOIMsg->StdIMsg.Code&0x80) != 0) ) { return GO_ContCmdHookA(ci,msg); } // If this is a checkbox and we are tracking its state... if( kind == CHECKBOX_KIND && (tg=FindTagItem(GTCB_Checked,ci->ci_GadToolsTags)) != NULL ) { struct TagItem update[] = { { 0, 0 }, { TAG_END, 0 } }; // A REALLY stupid way to do a checkbox hotkey, but it's // the basic code for most other types... // If shift is pressed, decrement. if( (msg->chm_KeyGOIMsg->StdIMsg.Qualifier &( IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT | IEQUALIFIER_CAPSLOCK ) ) != 0 ) { if(tg->ti_Data <= 0) tg->ti_Data = 1; else tg->ti_Data--; // Else, increment. } else { if(tg->ti_Data >= 1) tg->ti_Data = 0; else tg->ti_Data++; } // Send a message to command to update its state. update[0].ti_Tag = GTCB_Checked; update[0].ti_Data = tg->ti_Data; GO_CallCmdHook( ci, CHM_SETOBJATTR, 0, &update[0] ); // If an error occured, exit stage left. if(go->go_LastReqReturn) return 0; // If the gadget has been created, turn the GOIMsg // into the correct kind of event. Yes, we are allowed // to do this. :) if(gad) { msg->chm_KeyGOIMsg->StdIMsg.Class = IDCMP_GADGETUP; msg->chm_KeyGOIMsg->StdIMsg.Code = tg->ti_Data; msg->chm_KeyGOIMsg->StdIMsg.IAddress = (APTR)gad; } // We don't continue this message because we basically // just ate it. Chomp chomp... yummy... ret = 0; } } default: { ret = GO_ContCmdHookA(ci,msg); } break; } return ret; } struct Hook checkbox_hook = { { 0 }, (ULONG (*)())checkbox_code, NULL, NULL }; // This is an example translation hook. This hook is global to the outline // and allows you to not only localize the outline array, but theoretically // make it completely independant of any direct references to absolute // program addresses. // When first initializing a GadOutline, the library internally only sends // the CHM_TRANSCMDHOOK message to translate any user command hooks supplied // in the outline; all other translation messages are sent when the library // sends CHM_INITCMDATTR and CHM_INITOBJATTR to the command's hook, and thus // can be modified using a user hook. // The standard hook asks for translation of GadTools text pointers and the // standard GadTools tags which supply strings or arrays of strings. Class *rkmmodcl = NULL; ULONG __asm __saveds translation_code(register __a0 struct Hook *hook, register __a2 struct GadOutline *go, register __a1 struct CmdHookMsg *msg) { ULONG ret; // Return code. // --------------------------------------------------- // Sanity checking... // --------------------------------------------------- if(!hook || !msg || !go) return 0; switch(msg->chm_Message) { case CHM_TRANSTEXTPTR: case CHM_TRANSTEXTFMT: case CHM_TRANSNEWTEXTPTR: { // Version 3 of the library now contains routines to // use locale.library for localization. Let's see how // it does... D(bug("Given text code: %ld\n",msg->chm_TransCode)); ret = GO_ContTransHookA(go,msg); D(bug(" Got string: %ls\n",ret)); return ret; } break; /*** *** A custom translation code for arrays - looks up the given *** string ID, and parses it as a series of \0 terminated *** strings. An empty string (consisting of only \0) ends *** the array. ***/ case CHM_TRANSTEXTARRAY: { UBYTE** array; UBYTE* str; UBYTE* pos; int size; array = NULL; if( (str=GO_GetString(go,msg->chm_TransCode)) ) { size = 1; pos = str; while(*pos) { size++; while(*pos) pos++; pos++; } size *= sizeof(UBYTE *); if( (array = GO_AllocMem(go,GOTYPE_WARN,size,MEMF_PUBLIC)) ) { size = 0; pos = str; while(*pos) { array[size] = pos; size++; while(*pos) pos++; pos++; } array[size] = NULL; } } return (ULONG)array; } break; case CHM_TRANSCMDHOOK: { if(msg->chm_TransCode == 1) return (ULONG)&checkbox_hook; else return msg->chm_TransCode; } break; case CHM_TRANSPRIVCLASS: { D(bug("Trans priv: code=%lx; value=%lx;\n ID=%ld; obj=%ls\n", msg->chm_TransCode,msg->chm_TransCmd->ci_BoxValue, msg->chm_TransCmd->ci_CmdID,msg->chm_TransCmd->ci_BoxText)); if(msg->chm_TransCode == 1) return (ULONG)rkmmodcl; else return msg->chm_TransCode; } break; default: { } break; } return GO_ContTransHookA(go,msg); } struct Hook translation_hook = { { 0 }, (ULONG (*)())translation_code, NULL, NULL }; /********************************************* ** ** Program environment ** *********************************************/ static struct Process *me = NULL; static struct Window *oldwin = NULL; // what me->pr_WindowPtr previously was /********************************************* ** ** Current program state ** *********************************************/ static struct GadOutline *gad_outline = NULL; static struct FontRequester *fr = NULL; static UBYTE *go_error; // Where error results are returned static struct List info_list; /********************************************* ** ** All library bases ** *********************************************/ #define MIN_VERSION 37L // minimum version number for our libs long __oslibversion = MIN_VERSION; #ifndef LINKLIB struct Library *GadOutlineBase = NULL; #endif static void quit(UBYTE *err); static void closedown(void); static void opendisplay(struct GadOutline *go); static void handledisplay(struct GadOutline *go); static void free_list(struct List *list); /********************************************* ** ** Routines for a clean exit, with optional error display ** *********************************************/ static struct EasyStruct error_es = { sizeof(struct EasyStruct), 0, "GadOutline Example1 Requester", "Problem during startup:\n%ls", "Quit" }; static void quit(UBYTE *err) { closedown(); if(err == NULL) err = go_error; if(err != NULL) (void)EasyRequest(NULL,&error_es, NULL, err); _exit(0); } static void closedown(void) { if(gad_outline) FreeGadOutline(gad_outline); free_list(&info_list); if(fr) FreeAslRequest(fr); if(rkmmodcl) freeRKMModClass(rkmmodcl); if(me) me->pr_WindowPtr = (APTR)oldwin; #ifndef LINKLIB if(GadOutlineBase) CloseLibrary(GadOutlineBase); #endif } /********************************************* ** ** Routines for opening the screen, window and gadgets ** *********************************************/ static void create_node(struct List *list,UBYTE *name) { struct Node *nd; if( nd=AllocVec(sizeof(struct Node)+strlen(name)+5,MEMF_CLEAR) ) { nd->ln_Name = (char *)(nd+1); strcpy((UBYTE *)(nd+1),name); AddTail(list,nd); } } static void free_list(struct List *list) { struct Node *nd; while( nd=RemTail(list) ) { FreeVec(nd); } } static void opendisplay(struct GadOutline *go) { // First, set what the ListView will display. create_node(&info_list,"When creating ListView"); create_node(&info_list,"gadgets, you may attach"); create_node(&info_list,"them to strings using a"); create_node(&info_list,"'TagLink.' TagLinks are"); create_node(&info_list,"also used to make"); create_node(&info_list,"connections between"); create_node(&info_list,"BOOPSI objects and in"); create_node(&info_list,"any other places where"); create_node(&info_list,"you need the tag of one"); create_node(&info_list,"command to point to the"); create_node(&info_list,"object created by"); create_node(&info_list,"another command."); create_node(&info_list,""); create_node(&info_list,"The library will"); create_node(&info_list,"automatically determine"); create_node(&info_list,"what order it needs to"); create_node(&info_list,"create the objects in"); create_node(&info_list,"and set the correct tag"); create_node(&info_list,"values when they are"); create_node(&info_list,"created."); create_node(&info_list,""); create_node(&info_list,"A new feature of V3,"); create_node(&info_list,"LateLinks, allow you"); create_node(&info_list,"to create links between"); create_node(&info_list,"two commands, which is"); create_node(&info_list,"be applied after both"); create_node(&info_list,"objects are created."); create_node(&info_list,"This is needed for"); create_node(&info_list,"more complicated"); create_node(&info_list,"BOOPSI designs in which"); create_node(&info_list,"the links between"); create_node(&info_list,"objects form a cycle,"); create_node(&info_list,"in that there is no"); create_node(&info_list,"order which the objects"); create_node(&info_list,"can be created that"); create_node(&info_list,"will automatically"); create_node(&info_list,"resolve all the links."); GO_SetObjAttrs(go,LISTVIEW_ID,0,GTLV_Labels,&info_list,TAG_END); GO_OpenWindow(go, TAG_END); if(go->go_LastReqReturn || !go->go_Window) return; me->pr_WindowPtr = (APTR)go->go_Window; } static void get_keys(UBYTE* buffer,UBYTE* label,UBYTE *keys) { UBYTE *pos; pos = &buffer[0]; strcpy(pos,"\2337m"); pos += strlen(pos); strcpy(pos,label); pos += strlen(pos); strcpy(pos,"\2330m\2331m "); pos += strlen(pos); while( *keys && (pos < &buffer[95]) ) { if( (*keys >= ' ' && *keys <= 126) || *keys >= 160 ) { *pos = *keys; pos++; keys++; } else if(*keys == '$') { *pos = '$'; pos++; *pos = *keys; pos++; keys++; } else { *pos = '$'; pos++; *pos = ( ((*keys)/16) >= 10 ) ? ((*keys)/16)+'A'-10 : ((*keys)/16)+'0'; pos++; *pos = ( ((*keys)&15) >= 10 ) ? ((*keys)&15)+'A'-10 : ((*keys)&15)+'0'; pos++; #if 0 *pos = 'x'; pos++; #endif keys++; } } *pos = 0; } static UBYTE keybuffer[100]; ULONG ticks = 0; static void handledisplay(struct GadOutline *go) { struct GOIMsg *msg; struct Gadget *gadget; ULONG class; UWORD code; UWORD qual; if(go == NULL || go->go_Window == NULL) return; while (1) { Wait( (1L<go_Window->UserPort->mp_SigBit) ); while (msg = GO_GetGOIMsg(go)) { struct GOIMsg *dupmsg; class = msg->StdIMsg.Class; code = msg->StdIMsg.Code; qual = msg->StdIMsg.Qualifier; gadget=msg->StdIMsg.IAddress; gadget = (struct Gadget *)msg->StdIMsg.IAddress; dupmsg = GO_DupGOIMsg(go,msg); GO_ReplyGOIMsg(msg); switch (class) { case IDCMP_CLOSEWINDOW: return; case IDCMP_NEWSIZE: D(bug("IDCMP NewSize.\n")); break; case IDCMP_CHANGEWINDOW: D(bug("IDCMP Change Window.\n")); break; case IDCMP_INTUITICKS: #if 0 if(ticks++ > 20) { ticks = 0; GO_SetWindowAttrs(go,0, GOA_Iconify,FALSE,TAG_END); } #endif break; case IDCMP_REFRESHWINDOW: D(bug("IDCMP Refresh Window.\n")); GO_BeginRefresh(go); GO_EndRefresh(go, TRUE); break; case IDCMP_GADGETHELP: D(bug("IDCMP Gadget Help.\n")); break; case IDCMP_VANILLAKEY: { get_keys(&keybuffer[0],"(VAN)",&dupmsg->KeyPress[0]); GO_SetObjAttrs(go,KEYSHOW_ID,0, GODT_LeftTextPtr, "(VAN)", GODT_BodyTextPtr, &keybuffer[0], TAG_END); D(bug("Van key (Code %lx) (Len %ld): '%ls'\n", code,strlen(&dupmsg->KeyPress[0]),&keybuffer[0])); } break; case IDCMP_RAWKEY: { get_keys(&keybuffer[0],"(RAW)",&dupmsg->KeyPress[0]); GO_SetObjAttrs(go,KEYSHOW_ID,0, GODT_LeftTextPtr, "(RAW)", GODT_BodyTextPtr, &keybuffer[0], TAG_END); D(bug("Raw key (Code %lx) (Len %ld): '%ls'\n", code,strlen(&dupmsg->KeyPress[0]),&keybuffer[0])); } break; case IDCMP_GADGETUP: { D(bug("A gadget up type: %ld\n",gadget->GadgetID)); switch(gadget->GadgetID) { case ICONIFY_ID: { GO_SetWindowAttrs(go,0, GOA_Iconify,1,TAG_END); } break; case JUMPWIN_ID: { UBYTE nextname[MAXPUBSCREENNAME+1]; if(NextPubScreen(go->go_Screen,&nextname[0])) { GO_OpenWindow(go,WA_PubScreenName,&nextname[0],TAG_END); } } break; case REQFONT_ID: { // Pop up the font requester if (AslRequestTags(fr, // Supply initial values for requester ASLFO_InitialName, (ULONG)go->go_TextAttr.tta_Name, ASLFO_InitialSize, go->go_TextAttr.tta_YSize, ASLFO_MinHeight, 2, //ASL_FontStyles, go->go_TextAttr.tta_Style, //ASL_FuncFlags, FONF_STYLES, ASLFO_Window, go->go_Window, ASLFO_SleepWindow, TRUE, TAG_END)) { DimenGadOutline(go, GOA_TextAttr,&fr->fo_Attr, TAG_END); } } break; case OUTVALUES_ID: { ULONG scrn,win,maxw,maxh,minw,minh; UBYTE* fontname; ULONG fontsize,fontstyle; ULONG replev,faillev; ULONG ileft, itop, iwidth, iconify; ULONG winpos; GetGadOutlineAttrs(go, 0, GOA_ScreenAddr, &scrn, GOA_WindowAddr, &win, GOA_MaxWidth, &maxw, GOA_MaxHeight, &maxh, GOA_MinWidth, &minw, GOA_MinHeight, &minh, GOA_FontName, &fontname, GOA_FontSize, &fontsize, GOA_FontStyle, &fontstyle, GOA_ErrorReportLevel, &replev, GOA_ErrorFailLevel, &faillev, GOA_IconLeft, &ileft, GOA_IconTop, &itop, GOA_IconWidth, &iwidth, GOA_WindowPos, &winpos, GOA_Iconify, &iconify, TAG_END); GO_ShowError(go,GO_MAKEERR(GOTYPE_FINE,0),NULL, "Current outline values:\n\n" "Screen = %08lx Window = %08lx\n" "MaxWid = %08lx MaxHgt = %08lx\n" "MinWid = %08lx MinHgt = %08lx\n" "RepLev = %08lx FailLv = %08lx\n" "ILeft = %08lx ITop = %08lx\n" "IWidth = %08lx Iconify= %08lx\n" "WinPos = %08lx\n" "FSize = %08lx FStyle = %08lx\n" "FName = %ls\n", scrn, win, maxw, maxh, minw, minh, replev, faillev, ileft, itop, iwidth, iconify, winpos, fontsize, fontstyle, fontname); } break; case WINVALUES_ID: { UBYTE* title; ULONG left,top,width,height; ULONG* zoom; GO_GetWindowAttrs(go, 0, WA_Title, &title, WA_Left, &left, WA_Top, &top, WA_Width, &width, WA_Height, &height, WA_Zoom, &zoom, TAG_END); GO_ShowError(go,GO_MAKEERR(GOTYPE_FINE,0),NULL, "Current window values:\n\n" "Title = %ls\n" "CurLeft = %08lx CurTop = %08lx\n" "CurWdth = %08lx CurHgt = %08lx\n" "ZipLeft = %08lx ZipTop = %08lx\n" "ZipWdth = %08lx ZipHgt = %08lx\n", title, left, top, width, height, zoom[0], zoom[1], zoom[2], zoom[3]); } break; #if 0 case PUBSCREEN_ID: { UBYTE *name; name = (UBYTE *)GO_GetObjAttr(go,PUBSCREEN_ID,0, GTST_String,NULL); if(name) { strncpy(pub_screen,name,99); } else { pub_screen[0] = 0; } // This routine automagically closes the previous // window and opens a new window with the gadgets // in the same state. GO_OpenWindow(go, WA_PubScreenName, pub_screen, TAG_END ); if(!go->go_Window || go->go_LastReqReturn) quit("Couldn't open window."); update_fontinfo(go); } break; case SETFONT_ID: { // Pop up the font requester if (AslRequestTags(fr, // Supply initial values for requester ASL_FontName, (ULONG)go->go_TargetTA.tta_Name, ASL_FontHeight, go->go_TargetTA.tta_YSize, ASL_FontStyles, go->go_TargetTA.tta_Style, ASL_FuncFlags, FONF_STYLES, ASL_Window, go->go_Window, TAG_END)) { DimenGadOutline(go, GOA_TextAttr,&fr->fo_Attr, TAG_END); } } break; #endif } } break; } if(dupmsg) GO_UndupGOIMsg(dupmsg); } } } /********************************************* ** ** Program's main entry point ** *********************************************/ void __regargs main(int argc,char **argv) { NewList(&info_list); if( !(me = (struct Process *)FindTask(NULL)) ) quit("Can't find myself!"); oldwin = (struct Window *)me->pr_WindowPtr; if( (rkmmodcl=initRKMModClass()) == NULL ) { quit("Can't create RKMModel class!"); } if( (fr = (struct FontRequester *) AllocAslRequestTags(ASL_FontRequest,TAG_END)) == NULL) { quit("Can't allocate font requester!"); } #ifndef LINKLIB GadOutlineBase = OpenLibrary("gadoutline.library", 0); if (!GadOutlineBase) quit("Can't open gadoutline.library."); D(bug("Opened the library. Creating outline...\n",NULL)); #endif gad_outline = AllocGadOutline(outline, GOA_ErrorText, &go_error, GOA_ScreenName, NULL, GOA_OutlineSize, sizeof(outline), GOA_SetTransHook, &translation_hook, TAG_END); if(gad_outline == NULL) { quit(go_error); } opendisplay(gad_outline); handledisplay(gad_outline); quit(NULL); }