home *** CD-ROM | disk | FTP | other *** search
/ The CDPD Public Domain Collection for CDTV 4 / CDPD_IV.bin / fish / 911-930 / ff911 / gadlayout / gadlayout.man < prev    next >
Text File  |  1994-05-04  |  22KB  |  455 lines

  1.  
  2.                     GadLayout version 36.22 release 1.6
  3.                      The Dynamic Gadget Layout System
  4.  
  5.                          Copyright © 1992, 1993 by
  6.                              Timothy J. Aston
  7.                             All Rights Reserved
  8.  
  9.  
  10.  * IMPORTANT - Read This (PLEASE):
  11.  
  12. GadLayout is copyright, so you can't go ahead and just use it however you
  13. want, there are some restrictions.  GadLayout consists of the C source
  14. files, all header files, and all documentation included.  You may not
  15. modify GadLayout in any way.  GadLayout exists for you, the software
  16. developer, to use it; however, certain conditions must be complied with
  17. before you do:
  18.  
  19.  1. Your documentation must clearly state that it is making use of the
  20.     GadLayout dynamic gadget layout system by Timothy Aston.
  21.  2. You must provide me with, free of charge, a copy of the software you use
  22.     GadLayout in, and any subsequent updates to it that use GadLayout, also
  23.     free of charge.  This means that if the software you use it in is
  24.     shareware, I must be considered a full-registered user of the software.
  25.     Similarly for commercial software, you must provide me with a
  26.     complimentary copy.  And in all cases, as long as your software continues
  27.     to use GadLayout, you must provide with all publically released updates.
  28.     See the end of this document to find out how to get the stuff to me. 
  29.     I hope this isn't being too unreasonable, I basically just want to see
  30.     all the software that uses GadLayout.
  31.  3. If you modify the GadLayout source at all, you must send your
  32.     modifications to me.  You may not under any circumstances use the
  33.     GadLayout sources to create any kind of runtime-linking module, such
  34.     as a standard Amiga shared-library.
  35.  4. You may not distribute modified GadLayout source, or include GadLayout
  36.     source in a distribution without permission from the author.
  37.  5. Any modified versions of GadLayout will fall under this same licensing
  38.     agreement.
  39.  
  40.  
  41.  * Requirements:
  42.  
  43. GadLayout is designed for use by programmers developing software for Release 2
  44. and higher of the Amiga's operating system.  Though it can make use of
  45. locale.library, this is not required if you do not wish to make your gadgets
  46. locale-sensitive.  In fact, software using GadLayout only absolutely
  47. requires V36 of the OS to run (unless you make use of some of the locale
  48. features), however, it does REQUIRE V38 or greater of amiga.lib, because
  49. it needs the locale symbols to compile.
  50.  
  51.  
  52.  * Introduction:
  53.  
  54. Anyone that tried to design an attractive GUI in the days before Release 2
  55. has tremendous appreciation for the addition of gadtools.library.  Nice
  56. looking 3-D gadgets can be created and controlled with ease.  Though this
  57. was a major innovation, it is still lacking.  Another nice addition in
  58. Release 2 was much better support for user-definable fonts.  The problem
  59. is the GadTools does very little to help you adjust on the fly to different
  60. font sizes, you must do all the calculations yourself.  Anyone that has
  61. tried to do this realizes that this is quite a tedious task indeed.  What
  62. most people end up doing (including Commodore themselves :( ) is hard-code
  63. their programmes to use the Topaz 8 font.  As an added complication, with
  64. the advent of localization, programmes should now be able to adjust to adjust
  65. to different languages.
  66.  
  67. GadLayout is an attempt to take care of these problems.  It takes away the
  68. job of having to calculate gadget sizes and positions relative to font
  69. size and language being used.  Under GadTools, size and position have to
  70. be specified simply in absolute pixels.  GadLayout is partly a frontend to
  71. GadTools, allowing you to define size and height in much more complex ways
  72. (though you can still specify absolute pixels, this will still be easier
  73. than using straight GadTools, but it is not really taking advantage of the
  74. power GadLayout offers).  Gadgets can be automatically sized to fit text in
  75. any font (including proportional), and can be aligned with other gadgets.
  76. The actual technique is very simple, but gives you tremendous control over
  77. the placement of your gadgets.  GadLayout also expands on GadTools by
  78. offering you some new gadget kinds.
  79.  
  80. This document is meant to be a tutorial in C for using GadLayout in your
  81. programmes.  Not every detail of GadLayout will be given here, for a full
  82. reference, use the autodoc and includes file GadLayout.doc and gadlayout.h.
  83. In fact, to properly learn about programming with GadLayout, you should be
  84. consulting this document, the reference files and the examples concurrently.
  85.  
  86.  
  87.  * Before You Do Anything:
  88.  
  89. Though it maybe your software, you don't really have total freedom in the
  90. design of its user interface.  Commodore has a book called the User Interface
  91. Style Guide that defines some standards in how programmes should appear and
  92. opperate.  So before you decide how your programme will look, you study this
  93. book and make sure that it complies with the conventions Commodore has set
  94. out.
  95.  
  96.  
  97.  * The Basics:
  98.  
  99. GadLayout requires that LocaleBase be declared.  You do not need to open
  100. locale.library if you don't want to use make your gadgets locale-sensitive,
  101. but you will get a linker error if you don't declare it.  In C, you would
  102. use:
  103.  
  104.     struct Library *LocaleBase = NULL;
  105.  
  106. Next comes the definitions of your gadgets.  Each gadget you define as a
  107. tag list.  If you are not familiar with tag lists, please consult the
  108. Amiga ROM Kernal Reference Manual: Libraries, it explains how to use them.
  109. You should be able to get the jist from the examples as well.  As with
  110. any tag list, a GadLayout gadget tag list consists of a tag followed by
  111. some piece of information.  All the tags supported are defined in the C
  112. header file gadlayout.h (sorry, no header files for other languages, C is all
  113. I know).  The only required tag is GL_GadgetKind, though you will always want
  114. to use at least a few others.  You only have to include tags for data that
  115. has changed from the previous gadget, and tags can be given in any order
  116. (NOTE: there are cases where this is not necessarily the case, see later
  117. on).  A basic gadget could be defined as follows:
  118.  
  119.     struct TagItem mygad_layout_tags[] =
  120.     {
  121.         { GL_GadgetKind, BUTTON_KIND },
  122.         { GL_GadgetText, "Test Button" },
  123.         { GL_Top, 4 },
  124.         { GL_Left, 4 },
  125.         { GL_Width, 140 },
  126.         { GL_Height, 12 },
  127.         { GL_Flags, PLACETEXT_IN },
  128.         { TAG_DONE, NULL },
  129.     };
  130.  
  131. (The label before the comma is the tag, the expression to the left is that
  132. tag data, and the two together are called a tag item.  The examples given here
  133. will use a variety of the available tags, but for a full listing with
  134. explanations, you will need to consult the autodoc and header files.)
  135.  
  136. This example is very simple, and you really should not ever use something like
  137. this in real life.  The reason you shouldn't is because of the use of absolute
  138. co-ordinates, this is not much better than using straight GadTools.  If the
  139. font we were using here was something large, even like Times 13, the text
  140. would not fit in the gadget bounds and we'd get a mess.  The idea is that
  141. gadgets should adjust in size to different user fonts.  Here's how you'd
  142. really want to do it:
  143.  
  144.     struct TagItem mygad_layout_tags[] =
  145.     {
  146.         { GL_GadgetKind, BUTTON_KIND },
  147.         { GL_LocaleText, MSG_GAD_TESTBUTTON },
  148.         { GL_Top, 4 },
  149.         { GL_Left, 4 },
  150.         { GL_AutoWidth, 12 },
  151.         { GL_AutoHeight, 4 },
  152.         { GL_Flags, PLACETEXT_IN },
  153.         { TAG_DONE, NULL }
  154.     };
  155.  
  156. We've made only three changes here.  First of all, instead of hard-coding a
  157. string, we'll be getting a string from our locale language catalog (how to
  158. specify which catalog to use will be explained later on).  Next problem is
  159. fitting the text instead the gadget.  For this, we use the GL_AutoHeight and
  160. GL_AutoWidth tags.  GL_AutoHeight will make the gadget's height adjust
  161. automatically to whatever font the user is using (how to tell your gadgets
  162. which font to use will also be explained later on).  The data field in the
  163. tag list (4 in our example) is a constant that gets added to the height
  164. calculation, this is just so the text doesn't looked cramped inside the
  165. gadget's border.  GL_AutoWidth is similar, it looks at the gadget text and
  166. makes the gadget wide enough to fit that text with the current font, and
  167. also allows you to add a constant to that calculate to give a bit of a
  168. border.  Note that this is one of those cases where the order of the tags
  169. DOES matter: if you want to use GL_AutoWidth you MUST use either GL_GadgetText
  170. or GL_LocaleText beforehand; this is since GL_AutoWidth must know what the
  171. text is in order to calculate its width.
  172.  
  173. You make tag lists such as the one above for every gadget you want to include
  174. in your gadget list.  After these are all defined, you need to group them
  175. together in an array of LayoutGadget structures (see gadlayout.h).  Each
  176. element in the array is a gadget, it needs the gadget Intuition ID, and a
  177. pointer to its GadLayout tag list.  It also may need a pointer to its
  178. GadTools tag list.  GadTools tags are the tags that you would normally pass
  179. to the GadTools function CreateGadgetA() when creating a GadTools function.
  180. A very simple example might be:
  181.  
  182.     struct mygad_gadtools_tags[] =
  183.     {
  184.         { GT_Underscore, '_' },
  185.         { TAG_DONE, NULL }
  186.     }
  187.  
  188. Lastly, each element in the array needs a spot where it will store the Gadget
  189. structure pointer of the gadget once it gets created.  This should be
  190. initialized to NULL.  All these go in an array, eg:
  191.  
  192.     struct LayoutGadget mygadgets[] =
  193.     {
  194.         { GAD_MYGAD1, mygad1_layout_tags, mygad1_gadtools_tags, NULL },
  195.         { GAD_MYGAD2, mygad2_layout_tags, mygad2_gadtools_tags, NULL },
  196.         { -1, NULL, NULL, NULL }    /* Gadget ID of -1 marks the end */
  197.     }
  198.  
  199. All that's left is the actual creation and laying out of the gadgets.  This is
  200. done in one batch using a single call to the GadLayout function
  201. LayoutGadgetsA() (or its var args stub, LayoutGadgets()).  This routine takes
  202. a pointer to your initialized gadget list pointer, the screen the gadgets are
  203. going to made on, your LayoutGadget array, plus some tag lists for setting
  204. various options.  Here's how you might use it:
  205.  
  206.     struct Gadget *glist;
  207.     WORD right_extreme, lower_extreme;
  208. [...]
  209.     gi = LayoutGadgets(&glist, mygadgets, screen,
  210.         GL_RightExtreme, &right_extreme,
  211.         GL_LowerExtreme, &lower_extreme,
  212.         GL_DefTextAttr, screen->Font,
  213.         TAG_DONE);
  214.  
  215. The value returned is a pointer to a private structure.  You must keep this
  216. value in order to use the FreeLayoutGadgets() to properly free all resources.
  217. If the gadgets couldn't be laid out for some reason (eg. no memory), then
  218. the return value will be NULL.
  219.  
  220. This example makes use of some the tags that you can pass to LayoutGadgets().
  221. The first two tags are used in conjunction to find out how far right and how
  222. far down a window gadget imagery will be rendered.  You use these values when
  223. you open your window, so that you can have it sized to perfectly fit in all
  224. your gadgets.  The last tag, GL_DefTextAttr tells us which font to use for
  225. all the gadgets defined (not that it is possible to use different fonts for
  226. each gadget, but if they're all going to have the same font, this is a much
  227. easier way of specifying it).  Here we just grab the font that is being used
  228. by whatever screen we are to open on.  It is good practice to use the font
  229. that the user has selected as the Screen font in his/her Font preferences
  230. (you can get this by looking at wbscreen->Font) since you can very easily
  231. make your gadgets adjust to any font using GadLayout.
  232.  
  233. If the call was successful, glist will be an initialized gadget list, ready to
  234. be passed to OpenWindowTags(), AddGList(), etc.  This is a GadTools gadget
  235. list, so you must use gadtools.library functions such as GT_GetMsg() and
  236. GT_RefreshWindow() to handle the processing of these gadgets.
  237.  
  238. You finish off with a called FreeLayoutGadgets() in order to release the
  239. resources used by your gadgets.  NOTE: Do NOT use the GadTools function
  240. FreeGadgets() to free your gadgets, GadLayout uses some additional resources
  241. that this function will not free.
  242.  
  243.  
  244.  * Fancy Stuff:
  245.  
  246. GadLayout provides you with tremendous power and flexability in defining your
  247. gadgets.  So far we've only just touched in this with the automatic sizing.
  248. Another concept that GadLayout introduces is the idea of positioning and
  249. sizing gadgets relative to others.  Often times, you'll have gadgets generally
  250. laid out in columns of some sort.  Because gadget size will vary depending on
  251. font size, you'll specify a gadget's top edge relative to the bottom edge of
  252. the gadget immediately above it, using the GL_TopRel gadget.  Usually you
  253. will want all their widths to be the same, so you will use the GL_DupeWidth
  254. tag to make the width of a gadget the same as another (you should duplicate
  255. the width of the gadget with the longest string, so that others will be wide
  256. enough).  These are just a couple of examples, see the descriptions of the
  257. available tags to see the extensive list of options you have available to
  258. you in positioning gadgets.
  259.  
  260. You have to be a little careful when using tags like these that reference
  261. other gadgets.  It was stated before earlier that you need not specify tags
  262. for items that haven't changed from the previous gadget, and that the order
  263. of tags doesn't really matter.  But you'll see that you have to be a little
  264. more careful of this when using tags that reference other gadgets.  To see
  265. how, we'll have to look at how the gadgets are setup and laid-out by
  266. GadLayout:
  267.  
  268. Each gadget in the array is processed sequentially, and all the values
  269. calculated for it are preserved for the next gadget, so for a field that
  270. doesn't change (eg. say you're making a column of gadgets, the left edge won't
  271. change until you start a new column) you won't have to bother specifying it
  272. again and again.  But, once GadLayout hits a tag that refers to another
  273. gadget, it must stop the processing of that gadget and process the referenced
  274. gadget if it has not already been processed.  Where problems can arise is if
  275. this gadget attempts to reference back to the gadget that referenced it.  That
  276. gadget has only been partially processed, so not all fields in it will
  277. necessarily be defined.  And if the referencing tag needs to look at a field
  278. that has not yet been calculated, you'll get a wrong result.  Here's an
  279. example:
  280.  
  281.     struct TagItem button1_layout_tags[]
  282.     {
  283.         { GL_GadgetKind, BUTTON_KIND },
  284.         { GL_GadgetText, "A Button" },
  285.         { GL_DupeWidth, GAD_BUTTON2 },
  286.         { GL_AutoHeight, 4 },
  287.         { GL_Top, 4 },
  288.         { GL_Left, 4 },
  289.         { GL_Flags, PLACETEXT_IN },
  290.         { TAG_DONE, NULL }
  291.     };
  292.  
  293.     struct TagItem button2_layout_tags[]
  294.     {
  295.         { GL_GadgetKind, BUTTON_KIND },
  296.         { GL_GadgetText, "Another Button" },
  297.         { GL_AutoWidth, 12 },
  298.         { GL_TopRel, GAD_BUTTTON1 },
  299.         { GL_AddTop, 4 },
  300.         { GL_Left, 4 },
  301.         { GL_Flags, PLACETEXT_IN },
  302.         { TAG_DONE, NULL }
  303.     };
  304.  
  305. This will not yield the correct result at all.  When the GL_DupeWidth tag is
  306. hit, processing will jump to the second gadget.  Once it hits the GL_TopRel
  307. gadget, it will look back at the first gadget, and see that it is already
  308. being processed, so it won't try to process it now.  It grab its top edge
  309. and height fields to find its bottom edge so that the second gadget gets
  310. placed relative to that.  Problem is that the top edge and height for the
  311. first gadget have not been calculated, so the second gadget will not get the
  312. value you wanted for its top edge.  In order to get what we want, we just
  313. have to make sure that the top edge and height are already calculated before
  314. the second gadget will reference them:
  315.  
  316.     struct TagItem button1_layout_tags[]
  317.     {
  318.         { GL_GadgetKind, BUTTON_KIND },
  319.         { GL_GadgetText, "A Button" },
  320.         { GL_Top, 4 },
  321.         { GL_AutoHeight, 4 },
  322.         { GL_DupeWidth, GAD_BUTTON2 },
  323.         { GL_Left, 4 },
  324.         { GL_Flags, PLACETEXT_IN },
  325.         { TAG_DONE, NULL }
  326.     };
  327.  
  328.     struct TagItem button2_layout_tags[]
  329.     {
  330.         { GL_GadgetKind, BUTTON_KIND },
  331.         { GL_GadgetText, "Another Button" },
  332.         { GL_AutoWidth, 12 },
  333.         { GL_TopRel, GAD_BUTTTON1 },
  334.         { GL_AddTop, 4 },
  335.         { GL_Left, 4 },
  336.         { GL_Flags, PLACETEXT_IN },
  337.         { TAG_DONE, NULL }
  338.     };
  339.  
  340. Its a little confusing, you just have to follow the order in which gadgets
  341. will get processed, and you should be able to see why the first example is
  342. wrong.
  343.  
  344.  
  345.  * GadLayout Gadget Kinds:
  346.  
  347. As mentioned in the introduction, GadLayout expands upon the gadget kinds
  348. that GadTools supports.  Currently, GadLayout adds three kinds: IMAGE_KIND,
  349. DRAWER_KIND and FILE_KIND.  IMAGE_KIND is very similar to the GadTools
  350. BUTTON_KIND gadget, expect that instead of displaying text within, it will
  351. show an Intuition Image structure.  The DRAWER_KIND and FILE_KIND gadgets
  352. are both very similar, and are essentially just special kinds of IMAGE_KIND
  353. gadgets.  You use them to allow the user to select a path of filename
  354. respectively.  When the user clicks a DRAWER_KIND gadget, you should bring
  355. up an ASL file requester to allow the user to select a path (for example,
  356. the directory where downloads are placed by a terminal programme).  Likewise
  357. for a FILE_KIND gadget so that the user may choose a filename (for example,
  358. the name of a script to run).  As a matter of style, accompany the DRAWER_KIND
  359. and FILE_KIND gadgets with a string gadget to their immediate right so that
  360. the user may type his/her selection instead of having to go through the file
  361. requester.
  362.  
  363. These gadgets have tags specific to them, just like the GadTools gadgets do.
  364. But instead of putting them in a seperate tag list like you do with the tags
  365. for all GadTools gadget kinds, you include them with the GadLayout tags, eg:
  366.  
  367.     struct TagItem drawergad_layout_tags[] =
  368.     {
  369.         { GL_GadgetKind, IMAGE_KIND },
  370.         { GL_GadgetText, "My _Image" },
  371.         { GL_Top, 4 },
  372.         { GL_Left, 4 },
  373.         { GL_Width, 100 },
  374.         { GL_Height, 60 },
  375.         { GL_Flags, PLACETEXT_ABOVE },
  376.         { GLIM_Image, NULL },
  377.         { TAG_DONE, NULL }
  378.     };
  379. [...]
  380.     drawergad_layout_tags[6].ti_Data = image;
  381.  
  382. The GLIM_Image tag is a tag specific for IMAGE_KIND gadgets.  You use this to
  383. point to the Image structure that you want displayed within the gadget.  Note
  384. here how we actually set this AFTER the tag list has been defined.  This is
  385. something you will need to do sometimes with GadLayout, since all information
  386. is not necessarily known at initialization time (an excellent example of this
  387. will be with a LISTVIEW_KIND gadget and the GTLV_Labels task, you will have
  388. to first build the list, then you can set that pointer).
  389.  
  390. If you want to modify attributes of a GadLayout gadget kind, you must use the
  391. GadLayout function GL_SetGadgetAttrsA() (or the var args stub
  392. SetGadgetAttrs()) as opposed the the GadTools functions that you would use for
  393. modifying a GadTools gadget kind.
  394.  
  395.  
  396.  * Acknowledgements:
  397.  
  398. I'd like to thank the following people, all of them were a great help in
  399. getting GadLayout out the door:
  400.  
  401.  - Mark Rickan (general input and support)
  402.  - Ralph Schmidt (for answers to various gadget related questions)
  403.  - Olaf Barthel (used some of the code from his Term 2.4)
  404.  - Pasi Ilola, for porting the assembler headers, and some suggestions.
  405.  - Commodore (for writing the Style Guide)
  406.  - U2, for the music (which I listen to most of the time while developing :)
  407.  
  408.  
  409.  * About the Author:
  410.  
  411. I (Tim Aston) am a university student, taking specialized honours computing
  412. and information science at the University of Guelph.  My hobbies include
  413. computing, hockey (Montreal Canadiens all the way!), politics, etc.  My
  414. key interests in computing are personal computer application software and
  415. operating systems, in particular how they relate to user interface design.
  416.  
  417. Some of you may know me as the author of TransAmiga BBS, and I've also been
  418. around the FidoNet and IRC scene for a bit now, and may know me from there.
  419. My current project is a text editor, and it was while writing this that I
  420. realized how much a better system for laying out gadgets was needed.  From its
  421. initial conception to the first release, it has taken a little less than 2
  422. months to produce GadLayout.  I plan to continue to expand upon GadLayout
  423. (particularly with new gadget kinds) for as long as there is a need and
  424. sufficient demand.
  425.  
  426. If you're designing a programme with a GUI (whether it uses GadLayout or
  427. not), feel free to get in contact with me for some suggestions and ideas
  428. to improve upon it, I think I've got quite a knack for pointing out
  429. deficiences in a GUI.
  430.  
  431. If you wish to contact me, any of the following means are fine:
  432.  
  433.                 IRC: Timmer @ #amiga
  434.     InterNet E-Mail: cs1087@snowhite.cis.uoguelph.ca
  435.             FidoNet: Tim Aston @ 1:247/192
  436.                 FAX: (416)682-3501
  437.        Regular Mail: Tim Aston
  438.                      128 Riverview Blvd.
  439.                      St. Catharines, Ont.
  440.                      L2T 3M2
  441.                      Canada
  442.  
  443. Those are listed in the order in which I will generally be most swift in
  444. replying.  When you are releasing software that uses GadLayout, initially you
  445. must send it through the mail to my home address, however you can use my
  446. InterNet address to E-Mail me uuencoded updates.  I may be open to other
  447. means, just ask.
  448.  
  449. I thank you for you interest in GadLayout, and I'll be happy to listen to any
  450. questions of comments you might have.  I especially look forward to seeing
  451. your programmes' high quality GUIs using GadLayout!
  452.  
  453.  
  454. -Tim
  455. ¬