home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / amiga / gui / mui / mui14-dv.lha / MUI / Developer / Docs / MUIdev.doc < prev    next >
Encoding:
Text File  |  1993-10-28  |  31.8 KB  |  778 lines

  1.  
  2.  
  3.                        MUI - MagicUserInterface
  4.  
  5.        A system to create and maintain graphical user interfaces
  6.  
  7.                        Programmer Documentation
  8.  
  9.                   (c) Copyright 1993 by Stefan Stuntz
  10.  
  11. Getting Started
  12. ***************
  13.  
  14.    Note: This documentation does not cover all concepts of MUI
  15. programming in detail. It's important that you also read the
  16. accompanying per class autodocs and have a look at the supplied demo
  17. programs!
  18.  
  19. Object Oriented Programming
  20. ===========================
  21.  
  22.    The MUI system is based on BOOPSI, the Basic Object Oriented
  23. Programming System for Intuition. Understanding MUI and understanding
  24. this documentation requires at least a little knowledge about the
  25. concepts of object oriented programming, about classes, objects,
  26. methods and attributes. An absolutely sufficient introduction to these
  27. topics can be found in the "Libraries" part of the "ROM Kernel
  28. Reference Manuals" or in several Amiga mail articles.
  29.  
  30.    When talking about BOOPSI, most people automatically think of BOOPSI
  31. images and BOOPSI gadgets as part of the Amiga operating system.
  32. However, BOOPSI for itself is just a system for object oriented
  33. programming. One could e.g. have object oriented spread sheet software
  34. or object oriented file systems based on BOOPSI, intuition's builtin
  35. classes (gadgetclass, imageclass) are just two from thousands of
  36. possibilities.
  37.  
  38.    The MUI system also uses BOOPSI only as a base for object oriented
  39. programming. Thus, MUI classes are all subclasses of BOOPSI's rootclass
  40. and have nothing in common with the system supplied gadget or image
  41. classes. Unfortunately, Commodore missed some very important topics
  42. when designing these classes, disabling them for use in automatic
  43. layout systems such as MUI. Anyway, MUI features an interface to
  44. BOOPSI's gadgetclass and allows using already available gadgets (e.g.
  45. the Kick 3.x colorwheel) in MUI applications.
  46.  
  47. Available Classes
  48. =================
  49.  
  50.    The MUI system comes with several classes, each of them available as
  51. seperate shared system library. These classes are organized in a tree.
  52. As usual in the OO programming model, objects inherit all methods and
  53. attributes from their true class as well as from all their
  54. superclasses. Here is a quick summary with some short notes what the
  55. classes are used for. More detailed information can be found later in
  56. this document and in the per class autodocs files coming with the
  57. developer archive.
  58.  
  59.      rootclass               (BOOPSI's base class)
  60.      \--Notify               (implements notification mechanism)
  61.         +--Application       (main class for all applications)
  62.         +--Window            (handles intuition window related topics)
  63.         \--Area              (base class for all GUI elements)
  64.            +--Rectangle      (creates empty rectangles)
  65.            +--Image          (creates images)
  66.            +--Text           (creates some text)
  67.            +--String         (creates a string gadget)
  68.            +--Prop           (creates a proportional gadget)
  69.            +--Gauge          (creates a fule gauge)
  70.            +--Scale          (creates a percentage scale)
  71.            +--Boopsi         (interface to BOOPSI gadgets)
  72.            +--Colorfield     (creates a field with changeable color)
  73.            +--List           (creates a line-oriented list)
  74.            !  +--Floattext   (special list with floating text)
  75.            !  +--Volumelist  (special list with volumes)
  76.            !  +--Scrmodelist (special list with screen modes)
  77.            !  \--Dirlist     (special list with files)
  78.            \--Group          (groups other GUI elements - handles layout)
  79.               +--Virtgroup   (handles virtual groups)
  80.               +--Scrollgroup (handles virtual groups with scrollers)
  81.               +--Scrollbar   (creates a scrollbar)
  82.               +--Listview    (creates a listview)
  83.               +--Radio       (creates radio buttons)
  84.               +--Cycle       (creates cycle gadgets)
  85.               +--Slider      (creates slider gadgets)
  86.               +--Coloradjust (creates some RGB sliders)
  87.               \--Palette     (creates a complete palette gadget)
  88.  
  89. Application Theory
  90. ==================
  91.  
  92.    A MUI application consists of a (sometimes very) big object tree
  93. (don't mix up with the class tree explained above).  The root of this
  94. tree is always an instance of application class, called application
  95. object. This application object handles the various communication
  96. channels such as user input through windows, ARexx commands or
  97. commodities messages.
  98.  
  99.    An application object itself would be enough to create non-GUI
  100. programs with just ARexx and commodities capabilities. If you want to
  101. have windows with lots of nice gadgets and other user interface stuff,
  102. you will have to add window objects to your application. Since the
  103. application object is able to to handle any number of children, the
  104. number of windows is not limited.
  105.  
  106.    Window objects are instances of window class and handle all the
  107. actions related with opening, closing, moving, resizing and refreshing
  108. of intuition windows. However, a window for itself is not of much use
  109. without having any contents to display.  That's why window objects
  110. always need a so called root object.
  111.  
  112.    With this root object, we finally reach the gadget related classes
  113. of the MUI system. These gadget related classes are all subclasses of
  114. area class, they describe a rectangle region with some class dependant
  115. contents. Many different classes such as strings, buttons, checkmarks
  116. or listviews are available, but the most important subclass of area
  117. class is probably the group class. Instances of this class are able to
  118. handle any number of child objects and control the size and position of
  119. these children with various attributes. Of course these children can
  120. again be group objects with other sets of children.  Since you usually
  121. want your window to contain more than just one object, the root object
  122. of a window will be a group class object in almost all cases.
  123.  
  124.    Because these first paragraphs are very important to understand how
  125. MUI works, here's a brief summary:
  126.  
  127.    An application consists of exactly one application object. This
  128. application object may have any number of children, each of them being
  129. a window object. Every window object contains a root object, usually of
  130. type group class. This group object again handles any number of child
  131. objects, either other group objects or some user interface elements
  132. such as strings, sliders or buttons.
  133.  
  134.    A little diagram might make things more clear:
  135.  
  136.                                  +-------------+
  137.                                  ! Application !
  138.                                  +-------------+
  139.                                         !
  140.               ... ------+---------------+----------------+
  141.                         !               !                !
  142.                    +--------+       +--------+       +--------+
  143.                    ! Window !       ! Window !       ! Window !
  144.                    +--------+       +--------+       +--------+
  145.                         !               !                !
  146.                     +-------+
  147.                     ! Group !          ...              ...
  148.                     +-------+
  149.                         !
  150.          +------------+-+--------+-----------------+
  151.          !            !          !                 !
  152.      +--------+   +-------+   +------+         +-------+
  153.      ! String !   ! Group !   ! Text !         ! Group !
  154.      +--------+   +-------+   +------+         +-------+
  155.                       !                            !
  156.        ... -----+-----+-----+          +-----------+------- ...
  157.                 !           !          !           !
  158.              +------+   +-------+   +------+   +-------+
  159.              ! List !   ! Cycle !   ! List !   ! Group !
  160.              +------+   +-------+   +------+   +-------+
  161.                                                    !
  162.                                              +-----+-----+
  163.                                              !           !
  164.                                          +--------+  +--------+
  165.                                          ! Button !  ! Button !
  166.                                          +--------+  +--------+
  167.  
  168.    As shown in this tree, only three types of objects are allowed to
  169. have children:
  170.  
  171.      Application: zero or more children of window class.
  172.           Window: exactly one child of any subclass of area class.
  173.            Group: one or more children of any subclass of area class.
  174.  
  175. Object Handling
  176. ===============
  177.  
  178.    Since MUI uses BOOPSI as object oriented programming system, objects
  179. could simply be created using intuition.library/NewObject().  However,
  180. `muimaster.library' also features a generation function called
  181.  
  182.      Object * MUI_NewObjectA(STRPTR class, struct TagItem *taglist);
  183.  
  184. with the varargs stub
  185.      Object * MUI_NewObject(STRPTR class, Tag tag1, ..., TAG_DONE);
  186.  
  187.    That's the function you should use when creating objects of public
  188. MUI classes. The parameter `class' specifies the name of the object's
  189. class (e.g. `MUIC_Window', `MUIC_Slider', ...).  If the needed class
  190. isn't already in memory, it is automatically loaded from disk.
  191.  
  192.    With `taglist', you specify initial create time attributes for your
  193. object. Every attribute from the objects true class or from one of its
  194. super classes is valid here, as long as it's marked with the letter `I'
  195. in the accompanying autodocs documentation.
  196.  
  197.    To create a string object with a string-kind frame, a maximum length
  198. of 80 and the initial contents "foobar", you would have to use the
  199. following command:
  200.  
  201.      MyString = MUI_NewObject(MUIC_String,
  202.                     MUIA_Frame          , MUIV_Frame_String,
  203.                     MUIA_String_Contents, "foobar",
  204.                     MUIA_String_MaxLen  , 80,
  205.                     TAG_DONE);
  206.  
  207.    Once your object is ready, you can start talking to it by setting or
  208. getting one of its attributes or by sending it methods. The standard
  209. BOOPSI functions `SetAttrs()', `GetAttr()' and `DoMethod()' are used
  210. for these purposes:
  211.  
  212.         char *contents;
  213.         SetAttrs(MyString,MUIA_String_Contents,"look",TAG_DONE);
  214.         GetAttr(MUIA_String_Contents,MyString,&contents);
  215.         printf("Always %s on the bright side of life.",contents);
  216.      
  217.          DoMethod(mylist,MUIM_List_Remove,42); /* remove entry nr 42 */
  218.  
  219.    As already mentioned above, all attributes and methods are completely
  220. documented in the autodocs coming with this distribution. These
  221. autodocs follow the usual format, you can parse them with one of the
  222. various tools to create some hypertext online help for your favourite
  223. editor.
  224.  
  225.    When you're done with an object, you should delete it with a call to
  226.  
  227.      VOID MUI_DisposeObject(Object *obj);
  228.  
  229. from `muimaster.library'. After doing so, the object pointer is invalid
  230. and must no longer be used.
  231.  
  232.    When deleting objects, the parent-child connections mentioned above
  233. play an important role. If you dispose an object with children, not
  234. only the object itself but also all of its children (and their
  235. children, and the children of their children ...) get deleted. Since in
  236. a usual MUI application, the application object is the father of every
  237. window, the window is the father of it's contents and every group is
  238. the father of its sub objects, a single dispose of the application
  239. object will free the entire application.
  240.  
  241.    Note well: you may *not* delete objects that are currently children
  242. of other objects. Thus, if you have a complete application tree, the
  243. only thing you can delete is the application object itself as this one
  244. has no father. You can, however, add and remove children dynamically.
  245. More information on that topic follows later in this document.
  246.  
  247. Macros
  248. ======
  249.  
  250.    This chapter is only valid if you use C as your MUI programming
  251. language. Other language interfaces might feature other types of macros
  252. or support functions. Please have a look at the supplied interfaces to
  253. see how they work.
  254.  
  255.    The tree structure that builds up an application also appears in the
  256. source code of a MUI program. Since adding child objects is always
  257. possible with a special attribute of the parent object, it is common to
  258. create the whole tree with one big function call.
  259.  
  260.    To help making these calls more clear, the MUI header files contain
  261. several macros that simplify the task of object generation.
  262.  
  263.    Instead of
  264.  
  265.      MUI_NewObject(MUIC_Window, ..., TAG_DONE);
  266.      MUI_NewObject(MUIC_String, ..., TAG_DONE);
  267.      MUI_NewObject(MUIC_Slider, ..., TAG_DONE);
  268.  
  269. you can simply use
  270.  
  271.      WindowObject, ..., End;
  272.      StringObject, ..., End;
  273.      SliderObject, ..., End;
  274.  
  275.    Please note that the `xxxObject' macros contain an opening bracket
  276. and thus must always be terminated with an `End' macro that contains
  277. the matching closing bracket.
  278.  
  279.    Besides these "two way" macros, there are also some complete object
  280. definitions available which all create specific objects with certain
  281. types of attributes. The macro
  282.  
  283.      SimpleButton("Cancel")
  284.  
  285. would e.g. generate a complete button object with the correct frame,
  286. background and input capabilities. Though lots of these types of macros
  287. are available and can of course be used directly in your applications,
  288. they are mainly intended as some kind of example. Usually you will need
  289. some more sophisticated generation capabilities with a more specific
  290. set of macros.
  291.  
  292.    Note: If your application needs lots of objects from a specific type
  293. (e.g. 200 buttons), you can save some memory by turning macros into
  294. functions.
  295.  
  296. Layout Engine
  297. *************
  298.  
  299. Overview
  300. ========
  301.  
  302.    One of the most important and powerful features of MUI is its dynamic
  303. layout engine. As opposed to other available user interface tools, the
  304. programmer of a MUI application doesn't have to care about gadget sizes
  305. and positions. MUI handles all necessary calculations automatically,
  306. making every program completely screen, window size and font sensitive
  307. without the need for the slightest programmer interaction.
  308.  
  309.    From a programmers point of view, all you have to do is to define
  310. some rectangle areas that shall contain the objects you want to see in
  311. your window. Objects of group class are used for this purpose. These
  312. objects are not visible themselves, but instead tell their children
  313. whether they should appear horizontally or vertically (there are more
  314. sophisticated layout possibilities, more on this later).
  315.  
  316.    For automatic and dynamic layout, it's important that every single
  317. object knows about its minimum and maximum dimensions. Before opening a
  318. window, MUI asks all its gadgets about these values and uses them to
  319. calculate the windows extreme sizes.
  320.  
  321.    Once the window is opened, layout takes place. Starting with the
  322. current window size, the root object and all its children are placed
  323. depending on the type of their father's group and on some additional
  324. attributes.  The algorithm ensures that objects will never become
  325. smaller as their minimum or larger as their maximum size.
  326.  
  327.    The important thing with this mechanism is that object placement
  328. depends on window size. This allows very easy implementation of a
  329. sizing gadget: whenever the user resizes a window, MUI simply starts a
  330. new layout process and recalculates object positions and sizes
  331. automatically. No programmer interaction is needed.
  332.  
  333. Groups
  334. ======
  335.  
  336.    As mentioned above, a programmer specifies a windows outfit by
  337. grouping objects either horizontally or vertically. As a little
  338. example, lets have a look at a simple file requester window:
  339.  
  340.      +---------------------------------------+
  341.      !                                       !
  342.      !  +------------------------+ +------+  !
  343.      !  ! C                (dir) ! ! dh0: !  !
  344.      !  ! Classes          (dir) ! ! dh1: !  !
  345.      !  ! Devs             (dir) ! ! dh2: !  !
  346.      !  ! Expansion        (dir) ! ! df0: !  !
  347.      !  ! ...                    ! ! df1: !  !
  348.      !  ! Trashcan.info    1.172 ! ! df2: !  !
  349.      !  ! Utilities.info     632 ! ! ram: !  !
  350.      !  ! WBStartup.info     632 ! ! rad: !  !
  351.      !  +------------------------+ +------+  !
  352.      !                                       !
  353.      !  Path: _____________________________  !
  354.      !                                       !
  355.      !  File: _____________________________  !
  356.      !                                       !
  357.      !  +------+                 +--------+  !
  358.      !  ! Okay !                 ! Cancel !  !
  359.      !  +------+                 +--------+  !
  360.      !                                       !
  361.      +---------------------------------------+
  362.  
  363.    This window consists of two listview objects, two string gadgets and
  364. two buttons. To tell MUI how these objects shall be placed, you need to
  365. define groups around them. Here, the window consists of a vertical group
  366. that contains a horizontal group with both lists as first child, the
  367. path gadget as second child, the file gadget as third child and again a
  368. horizontal group with both buttons as fourth child.
  369.  
  370.    Using the previously defined macro language, the specification could
  371. look like this (in this example, `VGroup' creates a vertical group and
  372. `HGroup' creates a horizontal group):
  373.  
  374.      VGroup,
  375.         Child, HGroup,
  376.            Child, FileListview(),
  377.            Child, DeviceListview(),
  378.            End,
  379.         Child, PathGadget(),
  380.         Child, FileGadget(),
  381.         Child, HGroup,
  382.            Child, OkayButton(),
  383.            Child, CancelButton(),
  384.            End,
  385.         End;
  386.  
  387.    This tiny piece of source is completely enough to define the
  388. contents of a window, all necessary sizes and positions are
  389. automatically calculated by the MUI system.
  390.  
  391.    To understand how these calculations work, it's important to know
  392. that all basic objects (e.g. strings, buttons, lists) have a fixed
  393. minimum and a maximum size. Group objects calculate their minimum and
  394. maximum sizes from their children, depending whether they are
  395. horizontal or vertical:
  396.  
  397.    - Horizontal groups
  398.  
  399.      The minimum width of a horizontal group is the sum of all minimum
  400.      widths of its children.
  401.  
  402.      The maximum width of a horizontal group is the sum of all maximum
  403.      widths of its children.
  404.  
  405.      The minimum height of a horizontal group is the biggest minimum
  406.      height of its children.
  407.  
  408.      The maximum height of a horizontal group is the smallest maximum
  409.      height of its children.
  410.  
  411.    - Vertical groups
  412.  
  413.      The minimum height of a vertical group is the sum of all minimum
  414.      heights of its children.
  415.  
  416.      The maximum height of a vertical group is the sum of all maximum
  417.      heights of its children.
  418.  
  419.      The minimum width of a vertical group is the biggest minimum width
  420.      of its children.
  421.  
  422.      The maximum width of a vertical group is the smallest maximum
  423.      width of its children.
  424.  
  425.    Maybe this algorithm sounds a little complicated, but in fact it is
  426. really straight forward and ensures that objects will neither get
  427. smaller as their minimum nor bigger as their maximum size.
  428.  
  429.    Before a window is opened, it asks its root object (usually a group
  430. object) to calculate minimum and maximum sizes. These sizes are used as
  431. the windows bounding dimensions, the smallest possible window size will
  432. result in all objects being display in their minimum size.
  433.  
  434.    Once minimum and maximum sizes are calculated, layout process
  435. starts. The root object is told to place itself in the rectangle
  436. defined by the current window size. This window size is either
  437. specified by the programmer or results from a window resize operation
  438. by the user. When an object is told to layout itself, it simply sets
  439. its position and dimensions to the given rectangle.  In case of a group
  440. object, a more or less complicated algorithm distributes all available
  441. space between its children and tells them to layout too.
  442.  
  443.    This "more or less complicated algorithm" is responsible for the
  444. object arrangement. Depending on some attributes of the group object
  445. (horizontal or vertical, ...) and on some attributes of the children
  446. (minimum and maximum dimensions, ...), space is distributed and
  447. children are placed.
  448.  
  449.    A little example makes things more clear. Let's see what happens in
  450. a window that contains nothing but three horizontally grouped
  451. colorfield objects:
  452.  
  453.      +---------------------------------+
  454.      !                                 !
  455.      !  +-------+ +-------+ +-------+  !
  456.      !  !       ! !       ! !       !  !
  457.      !  ! field ! ! field ! ! field !  !
  458.      !  !   1   ! !   2   ! !   3   !  !
  459.      !  !       ! !       ! !       !  !
  460.      !  +-------+ +-------+ +-------+  !
  461.      !                                 !
  462.      +---------------------------------+
  463.  
  464.    Colorfield objects have a minimum width and height of one pixel and
  465. no (in fact a very big) maximum width and height. Since we have a
  466. horizontal group, the minmax calculation explained above yields to a
  467. minimum width of three pixels and a minimum height of one pixel for the
  468. windows root object (the horizontal group containing the colorfields).
  469. Maximum dimensions of the group are unlimited. Using these results, MUI
  470. is able to calculate the windows bounding dimensions by adding some
  471. spacing values and window border thicknesses.
  472.  
  473.    Once min and max dimensions are calculated, the window can be opened
  474. with a programmer or user specified size. This size is the starting
  475. point for the following layout calculations. For our little example,
  476. let's imagine that the current window size is 100 pixels wide and 50
  477. pixels high.
  478.  
  479.    MUI subtracts the window borders and some window inner spacing and
  480. tells the root object to layout itself into the rectangle left=5,
  481. top=20, width=90, height=74. Since our root object is a horizontal
  482. group in this case, it knows that each colorfield can get the full
  483. height of 74 pixels and that the available width of 90 pixels needs to
  484. be shared by all three fields.  Thus, the resulting fields will all get
  485. a width of 90/3=30 pixels.
  486.  
  487.    That's the basic way MUI's layout system works. There are a lot more
  488. possibilities to influence layout, you can e.g.  assign different
  489. weights to objects, define some inter object spacing or even make
  490. two-dimensional groups. These sophisticated layout issues are discussed
  491. in the autodocs of group class.
  492.  
  493. Building An Application
  494. ***********************
  495.  
  496. Creation
  497. ========
  498.  
  499.    Creating all the objects that make up an applications user interface
  500. is usually done with one big `MUI_NewObject()' call. This call returns
  501. a pointer to the application object as its result and contains lots of
  502. other object creation calls as parameter for its tag items. Using the
  503. previously defined macro language, a sample generation call could look
  504. like this:
  505.  
  506.      app = ApplicationObject,
  507.         MUIA_Application_Title      , "Settings",
  508.         MUIA_Application_Version    , "$VER: Settings 6.16 (20.10.93)",
  509.         MUIA_Application_Copyright  , "⌐1992/93, Stefan Stuntz",
  510.         MUIA_Application_Author     , "Stefan Stuntz",
  511.         MUIA_Application_Description, "Just a silly demo",
  512.         MUIA_Application_Base       , "SETTINGS",
  513.      
  514.         SubWindow, window1 = WindowObject,
  515.            MUIA_Window_Title, "Save/use me and start me again!",
  516.            MUIA_Window_ID   , MAKE_ID('S','E','T','T'),
  517.      
  518.            WindowContents, VGroup,
  519.      
  520.               Child, ColGroup(2), GroupFrameT("User Identification"),
  521.                  Child, Label2("Name:"  ), Child, str1 = String(0,40),
  522.                  Child, Label2("Street:"), Child, str2 = String(0,40),
  523.                  Child, Label2("City:"  ), Child, str3 = String(0,40),
  524.                  Child, Label1("Passwd:"), Child, str4 = String(0,40),
  525.                  Child, Label1("Sex:"   ), Child, str5 = String(0,40),
  526.                  Child, Label("Age:"),
  527.                  Child, sl  = SliderObject, End,
  528.                  End,
  529.      
  530.               Child, VSpace(2),
  531.      
  532.               Child, HGroup,
  533.                      MUIA_Group_SameSize, TRUE,
  534.                  Child, btsave   = KeyButton("Save"  ,'s'),
  535.                  Child, btuse    = KeyButton("Use"   ,'u'),
  536.                  Child, btcancel = KeyButton("Cancel",'>'),
  537.                  End,
  538.      
  539.               End,
  540.            End,
  541.      
  542.         SubWindow, window2 = WindowObject,
  543.            MUIA_Window_Title, "Window 2",
  544.              ...,
  545.              ...,
  546.              End,
  547.      
  548.         SubWindow,
  549.              ...
  550.              End,
  551.      
  552.         End;
  553.      
  554.      if (!app) fail(app,"Failed to create Application.");
  555.  
  556.    This big structure is indeed one single function call that builds a
  557. lot of other objects on the fly. Windows are created as children of the
  558. application object, a windows contents are created as child of the
  559. window and a groups contents are created as children of the group.
  560.  
  561.    Though many single objects are created, error handling is very easy.
  562. When a parent object encounters a NULL pointer supplied as one of its
  563. children, it will automatically dispose all other supplied children and
  564. fail too. Thus, even errors occuring in a very deep level will cause
  565. the complete application object to fail.  On the other hand, if you
  566. receive a non NULL application pointer, you can be sure that all other
  567. objects have successfully been created.
  568.  
  569.    Once you're done with your application, a single
  570.  
  571.      MUI_DisposeObject(app);
  572.  
  573. is enough to get rid of all previously created objects.
  574.  
  575. Notificiation
  576. =============
  577.  
  578.    The central element for controlling a MUI application is the
  579. notification mechanism. To understand how it works, its important to
  580. know that most objects feature lots of attributes that define their
  581. current state. Notification makes it possible to react on changes of
  582. these attributes.
  583.  
  584.    Attributes are changed either directly by the programmer (with a
  585. call to SetAttrs()) or by the user manipulation some gadgets.  If he
  586. e.g. drags around the knob of a proportional gadget, the
  587. MUIA_Prop_First attribute will continously be updated and reflect the
  588. current position.
  589.  
  590.    With notification, you could directly use this attribute change to
  591. set the MUIA_List_TopPixel attribute of a list object, building up a
  592. full featured listview:
  593.  
  594.      DoMethod(sbar, MUIM_Notify, MUIA_Prop_First, MUIV_EveryTime,
  595.               list, 3, MUIM_Set, MUIA_List_TopPixel, MUIV_TriggerValue);
  596.  
  597.    To make it clear: Every time, the scrollbar object changes its
  598. `MUIA_Prop_First' value, the list object shall change its
  599. `MUIA_List_TopPixel' attribute accordingly. The value 3 in the above
  600. function call identifies the number of the following parameters. Since
  601. you can call any method with any parameters here and MUI needs to save
  602. it somewhere, it's important to set it correctly.
  603.  
  604.    From now on the list and the scrollbar are connected to each other.
  605. As soon as the proportional gadget is moved, the position of the list
  606. changes accordingly; the programmer doesn't have to care about.
  607.  
  608.    Notification is mostly used with either the
  609. `MUIM_Application_ReturnID' or with the `MUIM_CallHook' method. If you
  610. e.g. have a specific hook that should be called whenever the user
  611. presses a button, you could use the following notify method:
  612.  
  613.      DoMethod(button, MUIM_Notify, MUIA_Button_Pressed, FALSE,
  614.               button, 2, MUIM_CallHook, &ButtonHook);
  615.      
  616.      /* Whenever the button's pressed attribute is set to FALSE
  617.         (i.e. the user has released the button), the button object
  618.         itself will call ButtonHook. */
  619.  
  620.    Futher information can be found in the autodocs of notify class.
  621.  
  622. Dynamic Object Linking
  623. **********************
  624.  
  625. Overview
  626. ========
  627.  
  628.    Usually, the complete user interface of an application is created
  629. with one single command. This makes error handling very easy and allows
  630. parallel usage of several windows. However, sometimes it makes sense to
  631. create certain windows only when they are actually needed: For example,
  632. if an application supplies many subwindows and would use too much
  633. memory, or if the number and contents of needed windows is not known at
  634. application startup time.
  635.  
  636.    Therefore MUI supports the option of "late binding".  Using this
  637. mechanism, children can be added and removed after their parent object
  638. already has been created. MUI uses the methods `OM_ADDMEMBER' and
  639. `OM_REMMEMBER' for this purpose:
  640.  
  641.      DoMethod(parent,OM_ADDMEMBER,child); /* add child object    */
  642.      DoMethod(parent,OM_REMMEMBER,child); /* remove child object */
  643.  
  644.    Both methods are only supported by MUI's application and group
  645. class; these are the only classes that can manage several children.
  646. Dynamic object linking for window and group class is explained in
  647. detail in the following chapters.
  648.  
  649.    Note: Objects that do not have parents, be it, because they are not
  650. yet connected using `OM_ADDMEMBER' or because they were disconnected
  651. using `OM_REMMEMBER', it's the programmer's task to delete them by
  652. calling `MUI_DisposeObject()'.  On the other side, objects that still
  653. are children of other objects must not be deleted!
  654.  
  655. Dynamic Windows
  656. ===============
  657.  
  658.    Let's say an application object is already set up and another (not
  659. yet existing) window has to be added. First, the window object needs to
  660. be created:
  661.  
  662.      win = WindowObject,
  663.         MUIA_Window_Title, "New Window",
  664.            WindowContents, VGroup,
  665.               Child, ...,
  666.               Child, ...,
  667.               Child, ...,
  668.               End,
  669.            End,
  670.         End;
  671.      
  672.      if (!win) fail(); /* failure check */
  673.  
  674. After the window object is created, it can be added to the application
  675. as one of its children:
  676.  
  677.      DoMethod(app,OM_ADDMEMBER,win);
  678.  
  679.    Now this window has become a part of the application, just as if it
  680. had been created as a subwindow together with the application object.
  681. It can be opened and closed by setting the according attributes and
  682. will be deleted automatically as soon as the application is ended.
  683.  
  684.    Usually, however, you'll want to delete this window directly after
  685. usage, because the late binding wouldn't make much sense otherwise.
  686.  
  687. After closing the window via
  688.  
  689.      set(win,MUIA_Window_Open,FALSE);
  690.  
  691. you can remove it by calling
  692.  
  693.      DoMethod(app,OM_REMMEMBER,win);
  694.  
  695.    After this you have to delete the window object "by hand", since the
  696. application no longer knows of it:
  697.  
  698.      MUI_DisposeObject(win);
  699.  
  700.    This method makes it possible to create subroutines that open their
  701. own window, wait for some imput events und return something.
  702.  
  703. To illustrate this, here is a short example:
  704.  
  705.      set(app,MUIA_Application_Sleep,TRUE);  // disable other windows
  706.      
  707.      win = WindowObject, ...., End;         // create new window
  708.      
  709.      if (win)                               // ok ?
  710.      {
  711.          DoMethod(app,OM_ADDMEMBER,win);    // add window...
  712.          set(win,MUIA_Window_Open,TRUE);    // and open it
  713.      
  714.          while (running)
  715.          {
  716.              switch (DoMethod(app,MUIM_Application_Input,&sigs))
  717.              {
  718.                  ... // Extra Input loop. For this window only.
  719.                  ... // Note: The special value
  720.                  ... // MUIV_Application_ReturnID_Quit should be recognized
  721.                  ... // as well
  722.              }
  723.          }
  724.      
  725.          set(win,MUIA_Window_Open,FALSE);   // Close window
  726.      
  727.          DoMethod(app,OM_REMMEMBER,win);    // remove
  728.      
  729.          MUI_DisposeObject(win);            // and kill it
  730.      }
  731.      
  732.      set(app,MUIA_Application_Sleep,FALSE); // wake up the application
  733.  
  734. Dynamic Groups
  735. --------------
  736.  
  737.    In the same way you can add windows to an application after its
  738. creation, you can add elements to already existing group objects. This
  739. may be useful if a group contains many similar children or if the
  740. number of children is not known in the beginning.
  741.  
  742.    You can add new elements to groups or delete them again, but the
  743. window that contains this group must not be open!
  744.  
  745. A small example:
  746.  
  747.          app = ApplicationObject,
  748.              ...,
  749.              SubWindow, win = WindowObject,
  750.                  WindowContents, VGroup,
  751.                      ...,
  752.                      grp = VGroup,
  753.                  End,
  754.                  ...,
  755.              End,
  756.          End,
  757.      End;
  758.      
  759.      /* The group 'grp' has been created without any children. */
  760.      /* The window must not be opened now!                     */
  761.      
  762.      for (i=0; i<NumPlayers; i++)
  763.      {
  764.         Object *name = StringObject, MUIA_String_MaxLen, 30, End;
  765.         if (name)
  766.            DoMethod(grp,OM_ADDMEMBER,name); // add gadget to group.
  767.         else
  768.            fail();
  769.      }
  770.      
  771.      /* After we have at least one element in the group 'grp', */
  772.      /* the window can be opened...                            */
  773.  
  774.    Of course you may (if the window is closed) remove elements from
  775. groups. Please note that window objects containing empty groups must
  776. not be opened.
  777.  
  778.