home *** CD-ROM | disk | FTP | other *** search
/ Enigma Amiga Life 106 / EnigmaAmiga106CD.iso / www / afc / afc-dir / mgui_all.lha / mgui_Source.lha / Source / mgui.e next >
Text File  |  1999-02-20  |  33KB  |  1,269 lines

  1. /*
  2.  
  3.     $VER: MGui V2.30 - (C)Amiga Foundation Classes
  4.  
  5.     Base: $000C0000
  6.  
  7.  
  8.     V1.00 - First Release
  9.  
  10.     V1.10 - EasyGUI 3.3a updated.
  11.  
  12.     V1.20 - Added:
  13.                     + MGUI_NAME a tag that allows user TO define a "name", (a LONG)
  14.                       TO identify various GUIs.
  15.  
  16.                     + action() method, you can DO a lot of things with it!
  17.  
  18.             Updated:  pos(): now can search FOR NAME, GUIHANDLES, AND MAIN.
  19.  
  20.             Now is part of the AFC
  21.  
  22.    V1.21  - MGUI_FREEGUI tag added.
  23.  
  24.    V1.30  - Now it is EasuGUI 3.3b compatible.
  25.  
  26.    V1.40  - Added addA() method
  27.  
  28.    V1.50  - NEW multi-gui handling routines (EasyGUI compatible)
  29.  
  30.    V2.00  - Completely rewritten.
  31.  
  32.    V2.10  - Added the hide/show method.
  33.  
  34.    V2.20  - Added MGUI_INFO field
  35.  
  36.    V2.30  - Removed the MGUI_MGUI tag.
  37. */
  38.  
  39. OPT OSVERSION = 37
  40. OPT PREPROCESS
  41. OPT LARGE
  42.  
  43. ->#define DO_MGUI_MODULE
  44.  
  45. ->#define TEST
  46. #define DO_FABIO_PLUGIN
  47.  
  48. #ifdef DO_MGUI_MODULE
  49. OPT MODULE
  50. OPT EXPORT
  51. #endif
  52.  
  53. MODULE 'tools/easygui',
  54.        'afc/nodemaster',
  55.        'exec/memory'
  56.  
  57. #ifndef DO_MGUI_MODULE
  58. MODULE 'tools/exceptions',
  59.        'intuition/intuition', 'exec/ports'
  60.  
  61.   #ifdef DO_FABIO_PLUGIN
  62.     MODULE '*DOOPSI:NewVersion/PlugIns/CenterTxt',
  63.            'fabio/appwin_oo'
  64.   #endif
  65. #endif
  66.  
  67. CONST MGUI_BASE = $000C0000
  68.  
  69. CONST MGUI_VERSION=2,
  70.       MGUI_REVISION=30
  71.  
  72. ENUM MGUI_MAIN=MGUI_BASE, MGUI_FREEPROC,
  73.      MGUI_ADDEXTERNAL, MGUI_REMEXTERNAL,
  74.      MGUI_LOCK, MGUI_LOCKALL,
  75.      MGUI_HIDE, MGUI_HIDEALL,
  76.      MGUI_NAME, MGUI_USER, MGUI_FREEGUI,
  77.      MGUI_SCREEN, MGUI_INFO
  78.  
  79. ENUM MGUI_SEARCH_NAME=1, MGUI_SEARCH_GUIHANDLE, MGUI_SEARCH_MAIN
  80.  
  81. SET MGUI_ACTION_TOFRONT, MGUI_ACTION_TOBACK, MGUI_ACTION_ACTIVATE,
  82.     MGUI_ACTION_ALL
  83.  
  84. -> /// Main Docs
  85. /*
  86. @node main "Amiga Foundation Classes: mgui/Main"
  87.  
  88.  
  89.                       ** Mgui- Original By Fabio Rotondo **
  90.  
  91.                          Part of Amiga Foundation Classes
  92.  
  93.                            --- NO LONGER SUPPORTED ---
  94.  
  95.  
  96.     @{"  Introduction  " LINK mgui_intro}       @{" Author(s) Info " LINK author}       @{" Amiga Foundation Classes " LINK "afc.guide/main"}
  97.  
  98.  
  99.     Requires: @{" NodeMaster " LINK "NodeMaster.guide/Main"}, EasyGUI
  100.  
  101.     Base: $000C
  102.  
  103.     COMMANDS                          BRIEF DESCRIPTION
  104.     -----------------------------------------------------------------------
  105.     @{" mgui()                         " LINK mgui_mgui} Init the object.
  106.     @{" addA(wtitle, gui, tags)        " LINK mgui_addA} Add a new GUI.
  107.     @{" clear()                        " LINK mgui_clear} Close all GUIs.
  108.     @{" del()                          " LINK mgui_del} Delete a GUI.
  109.     @{" empty()                        " LINK mgui_empty} Check if mgui has no GUIs.
  110.     @{" first()                        " LINK mgui_first} Pos on first GUI.
  111.     @{" freeguis()                     " LINK mgui_INTERNAL} * INTERNAL USE ONLY *
  112.     @{" gui()                          " LINK mgui_gui} Actual GUI pointer.
  113.     @{" lock(mode=TRUE)                " LINK mgui_lock} Lock/Unlock GUI.
  114.     @{" message()                      " LINK mgui_message} Parse a message.
  115.     @{" nm()                           " LINK mgui_nm} Returns related NodeMaster object.
  116.     @{" numgui()                       " LINK mgui_numgui} Number of avail GUIs.
  117.     @{" pop(pos=TRUE)                  " LINK mgui_pop} Pop a GUI from the stack.
  118.     @{" pos(v, m=NAME, here=FALSE)     " LINK mgui_pos} Search for a GUI.
  119.     @{" push()                         " LINK mgui_push} Push a GUI into the stack.
  120.     @{" setattrs(tags)                 " LINK mgui_setattrs} Set various attributes.
  121.     @{" succ()                         " LINK mgui_succ} Pos on next GUI.
  122.     @{" version()                      " LINK mgui_version} Returns object's version and revision.
  123.  
  124.     @{" ERROR TABLE " LINK Error_Table}
  125.  
  126. @endnode
  127.  
  128. @node author "Author(s) Info"
  129.  
  130.     Original By:  Fabio Rotondo  (fsoft@intercom.it)
  131.  
  132.     E Version By: Fabio Rotondo
  133.  
  134.  
  135.  
  136.     Address:
  137.  
  138.             Fabio Rotondo
  139.             C.so Vercelli 9
  140.             28100 Novara
  141.             ITALY
  142.  
  143.             e-mail: fsoft@intercom.it
  144.                     Fabio.Rotondo@deagostini.it
  145.  
  146.             Phone:  (ITA) - (0)321 -   459676  (home)
  147.                     (ITA) - (0)2   - 38086520  (office)
  148.                     (ITA) - (0)338 -  7336477  (GSM Phone)
  149.  
  150.             Fax:    (ITA) - (0)2   - 38086278
  151.  
  152.             Web:    http://www.intercom.it/~fsoft               (my home page)
  153.  
  154.                     http://www.intercom.it/~fsoft/ablast.html   (Amiga Blast Home Page)
  155. @endnode
  156.  
  157. @node mgui_intro "mgui / Introduction"
  158.  
  159.     MGUI
  160.  
  161.     Mgui is a class that helps Amiga E programmers to write multi-gui programs
  162.     very easily.
  163.  
  164.     It rely heavily on EasyGUI, so it is very hard that it will be ported to
  165.     any other language. Anyway, I decided to include it in AFC because it is
  166.     extremily useful.
  167.  
  168.     Note: you must to know how to use EasyGUI to use mgui.
  169.  
  170.     I have nothing more to add. Just try this class and enjoy yourself.
  171.  
  172.     Cheers,
  173.  
  174.         Fabio Rotondo
  175.  
  176. @endnode
  177.  
  178. @node Error_Table "mgui / Error Table"
  179.  
  180. At the moment, this class does not define any error.
  181.  
  182. @endnode
  183.  
  184. */
  185. -> ///
  186.  
  187. OBJECT gui_obj
  188.   PUBLIC
  189.   gh    :PTR TO guihandle   -> Puntatore ALL'HANDLE della GUI
  190.   main  :CHAR               -> Flag TRUE/FALSE per determinare se questa GUI è la principale
  191.   gui   :PTR TO LONG        -> Puntatore alla GUI allocata dinamicamente
  192.   user                      -> Qualcosa dell'utente...
  193.   info                      -> Qualcos'altro dell'utente...
  194.   mg    :PTR TO mgui        -> MGUI corrente.
  195.   PRIVATE
  196.   sig   :LONG
  197.   kill  :CHAR               -> Flag TRUE/FALSE per uccidere una gui
  198.   kind  :CHAR               -> 0=GUI, 1=EXTERNAL
  199.   name  :LONG               -> "nome" della GUI: max una LONG.
  200.   free  :CHAR               -> Flag TRUE/FALSE per fare il disposegui() della GUI
  201.   fromdel:CHAR
  202.   xinfo :PTR TO LONG        -> Puntatore agli oggetti da "Uccidere"
  203. ENDOBJECT
  204.  
  205.  
  206. OBJECT mgui
  207.   PRIVATE
  208.   nm     :PTR TO nodemaster
  209.   extsig :LONG                -> Messaggi "esterni" a MGUI
  210.   screen :PTR TO LONG
  211.   cgui   :PTR TO gui_obj      -> Puntatore alla GUI che ha generato il messaggio
  212.   multi  :PTR TO multihandle  -> Multi Handler
  213.   fromclear:CHAR
  214. ENDOBJECT
  215.  
  216. #ifndef DO_MGUI_MODULE
  217. #ifdef DO_FABIO_PLUGIN
  218. DEF times=0
  219. #endif
  220. #endif
  221.  
  222. -> /// PROC mgui() OF mgui
  223. /*
  224. @node mgui_mgui "mgui / mgui()"
  225.  
  226.           NAME: mgui()
  227.  
  228.    DESCRIPTION: mgui class constructor.
  229.  
  230.         INPUTS: NONE
  231.  
  232.        RESULTS: NONE
  233.  
  234.       SEE ALSO: @{" NodeMaster/nodemaster() " LINK "NodeMaster.guide/NodeMaster_nodemaster"}
  235.  
  236. @endnode
  237. */
  238. PROC mgui() OF mgui
  239.   self.nm:=NIL
  240.   NEW self.nm.nodemaster()
  241.   self.screen :=NIL
  242.   self.extsig :=NIL
  243.   self.multi  :=multiinit()
  244.   self.fromclear:=FALSE
  245. ENDPROC
  246. -> ///
  247.  
  248. -> /// end()
  249. PROC end() OF mgui
  250.   self.clear()
  251.   END self.nm
  252. ENDPROC
  253. -> ///
  254.  
  255. -> /// PROC first() OF mgui IS self.nm.first()
  256. /*
  257. @node mgui_first "mgui / first()"
  258.  
  259.           NAME: first()
  260.  
  261.    DESCRIPTION: Set position to the first GUI in the mgui object.
  262.  
  263.         INPUTS: NONE
  264.  
  265.        RESULTS: a PTR to GUI        - First() succeded.
  266.  
  267.                 NIL                 - First() failed.
  268.  
  269.       SEE ALSO: @{" NodeMaster/first() " LINK "NodeMaster.guide/NodeMaster_first"}
  270.  
  271. @endnode
  272. */
  273. PROC first() OF mgui IS self.nm.first()
  274. -> ///
  275.  
  276. -> /// PROC succ() OF mgui IS self.nm.succ()
  277. /*
  278. @node mgui_succ "mgui / succ()"
  279.  
  280.           NAME: succ()
  281.  
  282.    DESCRIPTION: Set position to the next GUI in the mgui object.
  283.  
  284.         INPUTS: NONE
  285.  
  286.        RESULTS: a PTR to GUI    -  succ() succeded.
  287.  
  288.                 NIL             -  succ() failed.
  289.  
  290.       SEE ALSO: @{" NodeMaster/succ() " LINK "NodeMaster.guide/NodeMaster_succ"}
  291.  
  292. @endnode
  293. */
  294. PROC succ() OF mgui IS self.nm.succ()
  295. -> ///
  296.  
  297. -> /// PROC empty() OF mgui IS self.nm.empty()
  298. /*
  299. @node mgui_empty "mgui / empty()"
  300.  
  301.           NAME: empty()
  302.  
  303.    DESCRIPTION: Checks if mgui object is empty or not.
  304.  
  305.         INPUTS: NONE
  306.  
  307.        RESULTS: TRUE        - mgui object is empty.
  308.  
  309.                 FALSE       - at least one GUI is present.
  310.  
  311.       SEE ALSO: @{" NodeMaster/empty() " LINK "NodeMaster.guide/NodeMaster_empty"}
  312.  
  313. @endnode
  314. */
  315. PROC empty() OF mgui IS self.nm.empty()
  316. -> ///
  317.  
  318. -> /// PROC gui() OF mgui IS self.nm.obj()
  319. /*
  320. @node mgui_gui "mgui / gui()"
  321.  
  322.           NAME: gui()
  323.  
  324.    DESCRIPTION: Get actual GUI pointer.
  325.  
  326.         INPUTS: NONE
  327.  
  328.        RESULTS: a PTR to a GUI      - gui() succeded.
  329.  
  330.                 NIL                 - gui() failed. (mgui is empty)
  331.  
  332.       SEE ALSO: @{" NodeMaster/obj() " LINK "NodeMaster.guide/NodeMaster_obj"}
  333.  
  334. @endnode
  335. */
  336. PROC gui() OF mgui IS self.nm.obj()
  337. -> ///
  338.  
  339. -> /// PROC numgui() OF mgui IS self.nm.numitems()
  340. /*
  341. @node mgui_numgui "mgui / numgui()"
  342.  
  343.           NAME: numgui()
  344.  
  345.    DESCRIPTION: Get the number of GUIs opened at the moment.
  346.  
  347.         INPUTS: NONE
  348.  
  349.        RESULTS: a LONG containing the number of GUIs opened.
  350.  
  351.       SEE ALSO: @{" NodeMaster/numitems() " LINK "NodeMaster.guide/NodeMaster_numitems"}
  352.  
  353. @endnode
  354. */
  355. PROC numgui() OF mgui IS self.nm.numitems()
  356. -> ///
  357.  
  358. -> /// PROC push() OF mgui IS self.nm.push()
  359. /*
  360. @node mgui_push "mgui / push()"
  361.  
  362.           NAME: push()
  363.  
  364.    DESCRIPTION: Push a GUI into the stack.
  365.  
  366.         INPUTS: NONE
  367.  
  368.        RESULTS: TRUE        - GUI pushed into the stack.
  369.  
  370.                 FALSE       - push() failed. (Stack is full)
  371.  
  372.       SEE ALSO: @{" NodeMaster/push() " LINK "NodeMaster.guide/NodeMaster_push"}
  373.  
  374. @endnode
  375. */
  376. PROC push() OF mgui IS self.nm.push()
  377. -> ///
  378.  
  379. -> /// PROC pop(pos=TRUE) OF mgui IS self.nm.pop(pos)
  380. /*
  381. @node mgui_pop "mgui / pop()"
  382.  
  383.           NAME: pop(pos=TRUE)
  384.  
  385.    DESCRIPTION: Pop a GUI from the stack.
  386.  
  387.         INPUTS: pos     - Should be TRUE or FALSE:
  388.  
  389.                           TRUE  - (default) a GUI is pop()ed from the stack
  390.                                   and the mgui object is positioned on it.
  391.  
  392.                           FALSE - a GUI is pop()ed from the stack, but mgui
  393.                                   IS NOT positioned on it (ie. just clear a
  394.                                   push()ed GUI)
  395.  
  396.        RESULTS: a PTR to GUI    - pop() succeded.
  397.  
  398.                 NIL             - pop() failed (stack is empty or pos=FALSE)
  399.  
  400.       SEE ALSO: @{" NodeMaster/pop() " LINK "NodeMaster.guide/NodeMaster_pop"}
  401.  
  402. @endnode
  403. */
  404. PROC pop(pos=TRUE) OF mgui IS self.nm.pop(pos)
  405. -> ///
  406.  
  407. -> /// PROC clear() OF mgui
  408. /*
  409. @node mgui_clear "mgui / clear()"
  410.  
  411.           NAME: clear()
  412.  
  413.    DESCRIPTION: Close all GUIs.
  414.  
  415.         INPUTS: NONE
  416.  
  417.        RESULTS: all GUIs are closed.
  418.  
  419.       SEE ALSO: @{" NodeMaster/clear() " LINK "NodeMaster.guide/NodeMaster_clear"}
  420.  
  421. @endnode
  422. */
  423. PROC clear() OF mgui
  424.   DEF gui:PTR TO gui_obj
  425.  
  426. #ifdef TEST
  427.   WriteF('Clearing ALL...\n')
  428. #endif
  429.   self.fromclear:=TRUE
  430.  
  431.   IF self.nm.empty()=FALSE
  432.     gui:=self.nm.first()
  433.     REPEAT
  434.       gui:=self.del(gui)
  435.     UNTIL gui=FALSE
  436.   ENDIF
  437.   self.nm.clear()
  438.  
  439.   cleanmulti(self.multi)
  440.  
  441.   self.fromclear:=FALSE
  442.  
  443. #ifdef TEST
  444. ->  WriteF('Multi Sig:\h\n', self.multi.sig)
  445. #endif
  446. ENDPROC
  447. -> ///
  448.  
  449. -> /// PROC clearguis() OF mgui IS Raise("cgui")
  450. /*
  451.    Private use only.
  452. */
  453. PROC clearguis() OF mgui IS Raise("cgui")
  454. -> ///
  455.  
  456. -> /// PROC addA(wtitle:PTR TO CHAR, gui, tags=NIL:PTR TO LONG) OF mgui HANDLE
  457. /*
  458. @node mgui_addA "mgui / addA()"
  459.  
  460.           NAME: addA(wtitle:PTR TO CHAR, gui, tags=NIL:PTR TO LONG)
  461.  
  462.    DESCRIPTION: Add a new GUI to mgui object using tag-list.
  463.  
  464.         INPUTS: wtitle          - Title of the GUI window.
  465.  
  466.                 gui             - GUI description (see EasyGUI)
  467.  
  468.                 tags            - Tag List. You can happily mix EasyGUI tags
  469.                                   with Mgui tags in the same list.
  470.  
  471.        RESULTS: a PTR to a gui_obj - The GUI has been added.
  472.  
  473.          NOTES: - This method may raise exceptions coming from NodeMaster() and
  474.                   EasyGUI.
  475.  
  476.                 - Starting from EasyGUI V3.3a, new tags have been added to
  477.                   allow better multiple GUIs handling.
  478.                   Please, note that:
  479.  
  480.                     -->> you MUST NOT use the EG_CLEAN tag <<--
  481.  
  482.                   Use the MGUI_FREEPROC method instead.
  483.  
  484.                 - Don't use EG_INFO. Use MGUI_INFO instead.
  485.  
  486.                 - This method actually returns TWO values:
  487.  
  488.                         gui - a pointer to a valid gui_obj
  489.                          gh - pointer to the gui handle
  490.  
  491.       SEE ALSO: @{" setattrs() " LINK Mgui_setattrs}
  492.  
  493.                 EasyGUI/easyguiA()
  494.  
  495.                 @{" NodeMaster/add() " LINK "NodeMaster.guide/NodeMaster_add"}
  496.  
  497.  
  498. @endnode
  499. */
  500. PROC addA(wtitle:PTR TO CHAR, gui, tags=NIL:PTR TO LONG) OF mgui HANDLE
  501.   DEF gh=NIL:PTR TO guihandle
  502.   DEF guio=NIL:PTR TO gui_obj
  503.   DEF taglist=NIL:PTR TO LONG
  504.   DEF count=0, t, pos, v
  505.  
  506.   NEW guio
  507.  
  508.   guio.main  := FALSE
  509.   guio.xinfo := NIL
  510.   guio.gui   := gui
  511.   guio.kill  := FALSE
  512.   guio.kind  := 0
  513.   guio.name  := NIL
  514.   guio.user  := NIL
  515.   guio.free  := TRUE
  516.   guio.mg    := NIL
  517.   guio.fromdel:=FALSE
  518.   guio.mg    := self
  519.  
  520.   t:=tags
  521.   WHILE (Long(tags++))
  522.     count++
  523.   ENDWHILE
  524.   tags:=t
  525.  
  526.   taglist:=List(count+8)
  527.  
  528.   IF count
  529.     ListCopy(taglist, tags, count)
  530.     ListAdd(taglist, [EG_INFO, guio, EG_CLEAN, {closeproc}, NIL, NIL], 6)
  531.   ELSE
  532.     ListCopy(taglist, [EG_INFO, guio, EG_CLEAN, {closeproc}, NIL, NIL], 6)
  533.   ENDIF
  534.   gh:=addmultiA(self.multi, wtitle, gui, taglist) ->[EG_INFO, guio, EG_CLOSE, {closeproc}, NIL, NIL]) ->taglist) ->s)
  535.  
  536.   guio.gh    := gh
  537.  
  538.   self.nm.add(guio)
  539.   self.setattrs(taglist)
  540.  
  541.   Dispose(taglist)
  542.  
  543.   RETURN guio, gh
  544.  
  545. EXCEPT
  546.   Dispose(taglist)
  547.   cleangui(gh)
  548.   END guio
  549.   ReThrow()
  550. ENDPROC
  551. -> ///
  552.  
  553. -> /// PROC message() OF mgui HANDLE
  554. /*
  555. @node mgui_message "mgui / message()"
  556.  
  557.           NAME: message()
  558.  
  559.    DESCRIPTION: Waits for a new message from the user.
  560.                 This is one of the coolest methods of the object:
  561.                 you just do not have to do anything: everything is
  562.                 handled by this method, which minds also for
  563.                 inputs coming from external signals.
  564.  
  565.         INPUTS: NONE
  566.  
  567.        RESULTS: This method returns THREE values at a time:
  568.  
  569.                 parsed          - TRUE if signal arrived has been
  570.                                        correctly parsed.
  571.  
  572.                 sig             - Signal arrived at Wait().
  573.  
  574.                 res             - result returned by guimessage().
  575.  
  576.       SEE ALSO: EasyGUI/guimessage()
  577.  
  578. @endnode
  579. */
  580. PROC message() OF mgui HANDLE
  581.   DEF res=NIL, sig=NIL, parsed=FALSE
  582.   DEF gh:PTR TO guihandle
  583.   DEF quitvar = FALSE
  584.   DEF gui:PTR TO gui_obj
  585.   DEF prg
  586.  
  587.   IF self.multi.sig OR self.extsig
  588.     sig:=Wait(self.multi.sig OR self.extsig)
  589.     IF sig AND self.multi.sig
  590.       parsed:=TRUE
  591.       sig   :=sig
  592.       res:=multimessage(self.multi)
  593.     ENDIF
  594.     IF sig AND self.extsig
  595.       IF self.first()
  596.         REPEAT
  597.           gui:=self.gui()
  598.           IF gui.kind=1
  599.             IF (gui.sig AND sig)
  600.               parsed:=TRUE
  601.               prg:=gui.xinfo
  602.               prg(gui.gui)
  603.             ENDIF
  604.           ENDIF
  605.         UNTIL (self.succ()=FALSE) OR (parsed=TRUE)
  606.       ENDIF
  607.     ENDIF
  608.   ENDIF
  609. EXCEPT
  610.   IF exception="cgui" THEN self.clear() ELSE ReThrow()
  611. ENDPROC parsed, sig, res
  612. -> ///
  613.  
  614. -> /// PROC setattrs(tags:PTR TO LONG) OF mgui
  615. /*
  616. @node mgui_setattrs "mgui / setattrs()"
  617.  
  618.           NAME: setattrs(tags)
  619.  
  620.    DESCRIPTION: This method is used to change some current GUI's attributes
  621.                 and also to change mgui object's attributes.
  622.                 This is the only way to modify mgui behaviours.
  623.  
  624.         INPUTS: There are two kind of tags, those working on the current GUI
  625.                 and the others working on mgui itself. We'll list them
  626.                 separately.
  627.  
  628.                 GUI Tags, these are the tags acting on the current GUI:
  629.  
  630.                 MGUI_MAIN - Tells mgui whether the current GUI is the main one
  631.                             or not. When the main GUI is closed, all the
  632.                             others GUI will be closed at the same time.
  633.                             Possible values, TRUE / FALSE.
  634.  
  635.                 MGUI_FREEPROC - Tells mgui what procedure(s) to call when
  636.                                 the current GUI'll be closed. This is very
  637.                                 useful, because you can create very complex
  638.                                 GUI with a lot of dinamycally allocated
  639.                                 objects and structures, that have to be freed
  640.                                 on GUI closing. This command needs a list
  641.                                 (or a structure) containing: PTR to proc and
  642.                                 arguments to pass to the procedure. Example:
  643.  
  644.                                 [MGUI_FREEPROC, [{freeobj}, obj,
  645.                                                  {freesig}, sig,
  646.                                                  NIL, NIL],
  647.                                  NIL, NIL]
  648.  
  649.                 MGUI_NAME   - This is not just a name, it is more like an
  650.                               "handle". Name value can be of 4 bytes (4 CHARS)
  651.                               just like the errors you usually Raise().
  652.                               Possible values, anything 4 bytes long.
  653.                               Example: "MAIN"
  654.  
  655.                 MGUI_USER   - This is a field you should fill with anything you
  656.                               want. It is just a PTR to something.
  657.                               Possible values, everything.
  658.                               Example: myobj.
  659.  
  660.                 MGUI_INFO   - This is the MGui replacement FOR EG_INFO.
  661.  
  662.                 MGUI_LOCK   - You can lock/unlock a GUI with this tag, so you
  663.                               can receive user's inputs or just ignore them.
  664.                               Possible values: TRUE (locks GUI), FALSE (unlock GUI)
  665.  
  666.                 MGUI_FREEGUI - You can tell to Mgui class whether to free a GUI
  667.                                or not. Usually, Mgui will mind GUI deallocation
  668.                                after closing the GUI, so you don't have to
  669.                                worry about it, but sometimes, it is better if
  670.                                YOU do it by yourself. For example, in a
  671.                                multi-gui list. This TAG will allow you to do
  672.                                whatever you want with your GUI definition.
  673.                                Possible values: TRUE (default) free the gui
  674.                                definition. FALSE do not free gui definition.
  675.                                NOTE: by default the gui definition WILL BE
  676.                                freed. And you have to set this tag to FALSE
  677.                                for every GUI you do not want to free.
  678.  
  679.                 MGUI Tags, these are tags action on the mgui object as a whole:
  680.  
  681.                 MGUI_ADDSIGMASK - With this tag you can add to mgui Wait()
  682.                                   signal some external signals you want mgui to
  683.                                   hear about. When the Wait() is trigged by
  684.                                   one of these sigs, the message isn't parsed
  685.                                   and the message() method will return it to
  686.                                   your control: you should be able to handle
  687.                                   this message correctly.
  688.  
  689.                 MGUI_REMSIGMASK - With this tag you can remove an external
  690.                                   signal previously added with MGUI_ADDSIGMASK.
  691.                                   From now on, Wait() will not wait for it
  692.                                   anymore.
  693.  
  694.                 MGUI_ADDEXTERNAL - This is a tag very similar to
  695.                                    MGUI_ADDSIGMASK, but this time, you have to
  696.                                    provide to mgui also a procedure to call
  697.                                    whenever the Wait() is trigged by the sig
  698.                                    you want. This is very useful, for example,
  699.                                    to wait for Commodity or ARexx events and
  700.                                    then to have mgui to handle all these stuff
  701.                                    for you.
  702.                                    The syntax is the following:
  703.                                    [MGUI_ADDEXTERNAL, [{procedure}, signal,
  704.                                                        proc_params],
  705.                                     NIL, NIL]
  706.  
  707.                                     procedure - proc to call when Wait() is
  708.                                                 trigged.
  709.  
  710.                                     signal    - External signal to check.
  711.  
  712.                                     proc_params - Paramteres to pass to the
  713.                                                   procedure. If you want to
  714.                                                   pass more than one single
  715.                                                   value, enclose them inside
  716.                                                   []. Example:
  717.                                                   [param1, param2, param3]
  718.  
  719.                 MGUI_REMEXTERNAL - This tag removes a signal set with
  720.                                    MGUI_ADDEXTERNAL. From now on, Wait() will
  721.                                    not wait for external exents anymore.
  722.                                    Possible values: signal to remove.
  723.                                    Example:
  724.                                    [MGUI_REMEXTERNAL, signal, NIL, NIL]
  725.  
  726.                 MGUI_LOCKALL    - This tag will enable you to lock/unlock
  727.                                   ALL GUIs in one single shot.
  728.                                   Possible values: TRUE (locks GUIs), FALSE
  729.                                   (unlock GUIs)
  730.  
  731.  
  732.          NOTES: - Don't use EG_INFO in your program. Use MGUI_INFO instead.
  733.  
  734.                 - Don't use EG_CLEAN in your program. Use MGUI_FREEPROC instead (it is
  735.                   also more comfy than EG_CLEAN)
  736.  
  737.        RESULTS: NONE
  738.  
  739.       SEE ALSO: @{" message() " LINK mgui_message}
  740.                 @{" action()  " LINK mgui_action}
  741.  
  742. @endnode
  743.  
  744. */
  745. PROC setattrs(tags:PTR TO LONG) OF mgui
  746.   DEF t, i, x:PTR TO LONG
  747.   DEF gui:PTR TO gui_obj
  748.   DEF k
  749.  
  750.   IF self.empty() THEN RETURN
  751.  
  752.   gui:=self.gui()
  753.  
  754.   WHILE (t:=Long(tags++))
  755.     i:=Long(tags++)
  756.     SELECT t
  757.       CASE MGUI_INFO
  758.         gui.info := i
  759.       CASE MGUI_MAIN
  760.         gui.main := i
  761.       CASE MGUI_NAME
  762.         gui.name := i
  763.       CASE MGUI_USER
  764.         gui.user := i
  765.       CASE MGUI_FREEGUI
  766.         gui.free := i
  767.       CASE MGUI_ADDEXTERNAL
  768.         gui:=NIL
  769.         x:=i
  770.         k:=self.extsig
  771.         k:=k OR x[1]
  772.         self.extsig:=k
  773.  
  774.         NEW gui
  775.         gui.gh    := NIL
  776.         gui.xinfo := x[0]  -> PROC
  777.         gui.sig   := x[1]  -> Signal
  778.         gui.gui   := x[2]  -> Info
  779.         gui.kill  := FALSE
  780.         gui.kind  := 1
  781.         gui.mg    := self
  782.  
  783.         self.nm.add(gui)
  784.  
  785.       CASE MGUI_REMEXTERNAL
  786.         self.nm.push()
  787.         IF gui:=self.first()
  788.           REPEAT
  789.             IF gui.kind=1 THEN IF gui.sig=i
  790.               gui.kill:=TRUE
  791.               k:=self.extsig
  792.               k:=k AND Not(i)
  793.               self.extsig:=k
  794.             ENDIF
  795.           UNTIL (gui:=self.succ())=FALSE
  796.         ENDIF
  797.         self.nm.pop()
  798.  
  799.       CASE MGUI_LOCK
  800.         self.lock(i)
  801.  
  802.       CASE MGUI_LOCKALL
  803.         self.nm.push()
  804.         IF self.first()
  805.           REPEAT
  806.             self.lock(i)
  807.           UNTIL self.succ() = NIL
  808.         ENDIF
  809.         self.nm.pop()
  810.       CASE MGUI_FREEPROC
  811.         gui.xinfo:=i
  812. #ifdef TEST
  813.   WriteF('Free PROC:\h\n', gui.xinfo[0])
  814. #endif
  815.       CASE MGUI_HIDE
  816.         self.hide(i)
  817.       CASE MGUI_HIDEALL
  818.         self.nm.push()
  819.         IF self.first()
  820.           REPEAT
  821.             self.hide(i)
  822.           UNTIL self.succ() = NIL
  823.         ENDIF
  824.         self.nm.pop()
  825.       CASE MGUI_SCREEN
  826.         self.screen:=i
  827.     ENDSELECT
  828.   ENDWHILE
  829. ENDPROC
  830. -> ///
  831.  
  832. -> /// PROC lock(mode=TRUE) OF mgui
  833. /*
  834. @node mgui_lock "mgui / lock()"
  835.  
  836.           NAME: lock(mode=TRUE)
  837.  
  838.    DESCRIPTION: This method locks or unlocks current GUI.
  839.  
  840.         INPUTS: mode        - TRUE locks the GUI (default),
  841.  
  842.                               FALSE unlocks the GUI.
  843.  
  844.        RESULTS: NONE
  845.  
  846.       SEE ALSO: @{" setattrs() " LINK mgui_setattrs}
  847.  
  848.                 EasyGUI/blockwin()
  849.                 EasyGUI/unblockwin()
  850. @endnode
  851. */
  852. PROC lock(mode=TRUE) OF mgui
  853.   DEF gui:PTR TO gui_obj
  854.  
  855.   gui:=self.gui()
  856.  
  857.   IF gui.kind<>0 THEN RETURN
  858.  
  859.   IF mode=TRUE
  860.     blockwin(gui.gh)
  861.   ELSE
  862.     unblockwin(gui.gh)
  863.   ENDIF
  864. ENDPROC
  865. ->///
  866.  
  867. -> /// hide
  868. PROC hide(mode=TRUE) OF mgui
  869.   DEF gui:PTR TO gui_obj
  870.  
  871.   gui:=self.gui()
  872.  
  873.   IF gui.kind<>0 THEN RETURN
  874.  
  875.   IF mode=TRUE
  876.     closewin(gui.gh)
  877.   ELSE
  878.     openwin(gui.gh)
  879.   ENDIF
  880.  
  881. ENDPROC
  882. -> ///
  883.  
  884. -> /// PROC del(gui=NIL:PTR TO gui_obj) OF mgui HANDLE
  885. /*
  886. @node mgui_del "mgui / del()"
  887.  
  888.           NAME: del()
  889.  
  890.    DESCRIPTION: This method close current GUI.
  891.                 The current GUI is closed and the proc set using
  892.                 MGUI_FREEPROC tag is called to free resources.
  893.  
  894.         INPUTS: NONE
  895.  
  896.        RESULTS: PTR to next avaible GUI or NIL if it was the last GUI.
  897.  
  898.  
  899.       SEE ALSO: @{" add() " LINK mgui_add}
  900.  
  901.                 @{" NodeMaster/del() " LINK "NodeMaster.guide/NodeMaster_del"}
  902.  
  903. @endnode
  904.  
  905. */
  906. PROC del(gui=NIL:PTR TO gui_obj) OF mgui HANDLE
  907.   DEF t:PTR TO LONG
  908.   DEF cproc, info
  909.  
  910.   IF self.nm.empty() THEN RETURN
  911.  
  912.   IF gui=NIL THEN gui:=self.nm.obj()
  913.  
  914.   IF self.fromclear THEN gui.main:=FALSE
  915.  
  916. #ifdef TEST
  917.   WriteF('Deleting GUI:\h - Kind:\d (\d)\n', gui.gh, gui.kind, gui.main)
  918.   WriteF('Free PROC:\h\n', gui.xinfo[0])
  919. #endif
  920. ->  gui:=self.nm.obj()
  921.  
  922.   IF gui.kind=0
  923.     IF gui.main = FALSE
  924.       gui.fromdel:=TRUE
  925.       IF gui.gh.wnd<>NIL THEN cleangui(gui.gh)
  926.  
  927.       IF (t:=gui.xinfo)
  928.         REPEAT
  929.           cproc:=Long(t++)
  930.           info :=Long(t++)
  931.  
  932.           IF (cproc<>NIL)  THEN cproc(info)
  933.         UNTIL (cproc=NIL)
  934.         disposegui(t)
  935.       ENDIF
  936.       disposegui(gui.gui)
  937.  
  938.       END gui
  939.       gui:=self.nm.del()
  940.     ELSE
  941.       gui.free:=FALSE
  942.       gui.main:=FALSE
  943.       Raise("cgui")
  944.     ENDIF
  945.   ELSE
  946. ->    self.setattrs([MGUI_REMEXTERNAL, gui.sig, NIL, NIL])
  947.     END gui
  948.     gui:=self.nm.del()
  949.  
  950.   ENDIF
  951.  
  952. EXCEPT
  953.   ReThrow()
  954. ENDPROC gui
  955. -> ///
  956.  
  957. -> /// PROC pos(v, mode=MGUI_SEARCH_NAME, fromhere=FALSE) OF mgui
  958. /*
  959. @node mgui_pos  "mgui / pos() "
  960.  
  961.           NAME: pos(value, mode=MGUI_SEARCH_NAME, fromhere=FALSE)
  962.  
  963.    DESCRIPTION: This method will scan all GUIs to find the one matching the
  964.                 value required. Value may vary and it is influenced by the
  965.                 mode value.
  966.  
  967.         INPUTS: value       - Value to search.
  968.  
  969.                 mode        - Search mode. Avaible modes are:
  970.  
  971.                               MGUI_SEARCH_NAME  - Compare value with GUI's name
  972.                                                   field.
  973.  
  974.                               MGUI_SEACH_GUIHANDLE - Compare value with GUI's
  975.                                                      guihandle.
  976.  
  977.                               MGUI_SEARCH_MAIN  - Will search for the first
  978.                                                   GUI with the main flag set.
  979.  
  980.                 fromhere    - Tells mgui whether to scan from the beginning
  981.                               of the list of GUIs or just from the current
  982.                               position. Default is FALSE: the list is scanned
  983.                               from the first position.
  984.  
  985.  
  986.        RESULTS: a PTR to GUI - pos() succeded.
  987.  
  988.                 NIL          - pos() failed.
  989.  
  990.           NOTE: When the pos() has mode set to MGUI_SEARCH_MAIN, value is
  991.                 ignored.
  992.  
  993.       SEE ALSO:
  994.  
  995. @endnode
  996. */
  997. PROC pos(v, mode=MGUI_SEARCH_NAME, fromhere=FALSE) OF mgui
  998.   DEF gui:PTR TO gui_obj
  999.   DEF ok=FALSE
  1000.  
  1001.   IF self.nm.empty() THEN RETURN FALSE
  1002.  
  1003.   self.nm.push()
  1004.   IF fromhere=FALSE
  1005.     gui:=self.nm.first()
  1006.   ELSE
  1007.     gui:=self.nm.obj()
  1008.   ENDIF
  1009.  
  1010.   IF gui
  1011.     REPEAT
  1012.       SELECT mode
  1013.         CASE MGUI_SEARCH_NAME
  1014.           IF gui.name=v THEN ok:=TRUE
  1015.         CASE MGUI_SEARCH_GUIHANDLE
  1016.           IF gui.gh = v THEN ok:=TRUE
  1017.         CASE MGUI_SEARCH_MAIN
  1018.           IF gui.main THEN ok:=TRUE
  1019.       ENDSELECT
  1020.       IF ok=FALSE THEN gui:=self.nm.succ()
  1021.     UNTIL ((gui=FALSE) OR (ok=TRUE))
  1022.   ENDIF
  1023.  
  1024.   IF ok
  1025.     self.nm.pop(FALSE)
  1026.     ok:=self.nm.obj()
  1027.   ELSE
  1028.     self.nm.pop()
  1029.   ENDIF
  1030. ENDPROC ok
  1031. -> ///
  1032.  
  1033. -> /// PROC nm() OF mgui IS self.nm
  1034. /*
  1035. @node mgui_nm  "mgui / nm() "
  1036.  
  1037.           NAME: nm()
  1038.  
  1039.    DESCRIPTION: This method returns the PTR to the embedded
  1040.                 NodeMaster object.
  1041.  
  1042.         INPUTS: NONE
  1043.  
  1044.        RESULTS: a PTR to NodeMaster object.
  1045.  
  1046.       SEE ALSO: @{" NodeMaster " LINK "NodeMaster.guide/main"}
  1047. @endnode
  1048.  
  1049. */
  1050. PROC nm() OF mgui IS self.nm
  1051. -> ///
  1052.  
  1053. -> /// PROC action(act)  OF mgui
  1054. /*
  1055. @node mgui_action  "mgui / action() "
  1056.  
  1057.           NAME: action(actions)
  1058.  
  1059.    DESCRIPTION: This method is used to trig some actions on current GUI.
  1060.  
  1061.         INPUTS: actions - Action to perform on current GUI.
  1062.                           Current defined actions are:
  1063.  
  1064.                           MGUI_ACTION_TOFRONT   - Brings GUI window to front.
  1065.  
  1066.                           MGUI_ACTION_TOBACK    - Brings GUI window to back.
  1067.  
  1068.                           MGUI_ACTION_ACTIVATE  - Activate GUI window.
  1069.  
  1070.                           These actions can be ORed together. Example:
  1071.  
  1072.                           action(MGUI_ACTION_TOFRONT OR MGUI_ACTION_ACTIVATE)
  1073.  
  1074.        RESULTS: TRUE    - Actions performed.
  1075.  
  1076.                 FALSE   - action() failed (maybe no GUI is avaible)
  1077.  
  1078.  
  1079.       SEE ALSO: @{" setattrs() " LINK mgui_setattrs}
  1080.  
  1081. @endnode
  1082.  
  1083. */
  1084. PROC action(act)  OF mgui
  1085.   DEF gui:PTR TO gui_obj
  1086.  
  1087.   IF (gui:=self.nm.obj())=NIL THEN RETURN FALSE
  1088.  
  1089.   IF act AND MGUI_ACTION_TOFRONT THEN WindowToFront(gui.gh.wnd)
  1090.   IF act AND MGUI_ACTION_TOBACK THEN WindowToBack(gui.gh.wnd)
  1091.   IF act AND MGUI_ACTION_ACTIVATE THEN ActivateWindow(gui.gh.wnd)
  1092. ENDPROC TRUE
  1093. -> ///
  1094.  
  1095. -> /// PROC version() OF mgui IS MGUI_VERSION, MGUI_REVISION
  1096. /*
  1097. @node mgui_version  "mgui / version() "
  1098.  
  1099.           NAME: version()
  1100.  
  1101.    DESCRIPTION: This method returns current version and revision of the
  1102.                 mgui class currently in use.
  1103.  
  1104.         INPUTS: NONE
  1105.  
  1106.        RESULTS: This method returns TWO values: version and revision.
  1107.  
  1108.       SEE ALSO:
  1109.  
  1110. @endnode
  1111. */
  1112. PROC version() OF mgui IS MGUI_VERSION, MGUI_REVISION
  1113. -> ///
  1114.  
  1115. PROC closeproc(mh:PTR TO multihandle, gui:PTR TO gui_obj)
  1116.   IF gui.free
  1117.     gui.free:=FALSE
  1118. #ifdef TEST
  1119.     WriteF('Closing gui:\h - (\h) Main:\d\n', gui.gh, gui, gui.main)
  1120.     WriteF('Free PROC:\h\n', gui.xinfo[0])
  1121. #endif
  1122.     IF gui.mg<>NIL
  1123. #ifdef TEST
  1124. ->      WriteF('From clear:\d\n', gui.mg.fromclear)
  1125. #endif
  1126.       IF (gui.mg.fromclear=FALSE) AND (gui.fromdel=FALSE)
  1127.         IF gui.mg.pos(gui.gh, MGUI_SEARCH_GUIHANDLE) THEN gui.mg.del(gui)
  1128.       ENDIF
  1129.     ENDIF
  1130.   ENDIF
  1131. ENDPROC
  1132.  
  1133.  
  1134. #ifndef DO_MGUI_MODULE
  1135.  
  1136. PROC main_end()
  1137.   Raise("end")
  1138. ENDPROC
  1139.  
  1140. PROC main() HANDLE
  1141.   DEF mg=NIL:PTR TO mgui
  1142.   DEF win=NIL:PTR TO window
  1143.   DEF sig
  1144.  
  1145.   NEW mg.mgui()
  1146.  
  1147.   mg.addA('MGUI Main', [ROWS, [SBUTTON, {kill_all}, 'Kill ALL'],
  1148.                        [SBUTTON, {newgui}, 'NEW!'],
  1149.                        [SBUTTON, {hideall}, 'Hide'],
  1150.                        [SBUTTON, {showall}, 'Show']
  1151.                        ],
  1152.                        [MGUI_MAIN, TRUE, NIL, NIL]
  1153.           )
  1154.  
  1155.   test(mg)
  1156.  
  1157.   test(mg)
  1158.  
  1159.   test(mg)
  1160.  
  1161. ->  mg.lock(TRUE)
  1162.  
  1163.   IF (win:=OpenWindowTagList(NIL, [WA_WIDTH, 200,
  1164.                                WA_HEIGHT, 100,
  1165.                                WA_TITLE, 'Click Inside!',
  1166.                                WA_IDCMP, IDCMP_MOUSEBUTTONS,
  1167.                                NIL, NIL]))=NIL THEN Raise("win")
  1168.  
  1169.   sig:=win.userport::mp.sigbit
  1170.   sig:=Shl(1, sig)
  1171.  
  1172.   mg.setattrs([MGUI_ADDEXTERNAL, [{click}, sig, [win, win.userport, mg, sig, {win}]],
  1173.              0,0])
  1174.  
  1175.   WHILE (mg.empty() = FALSE)
  1176.     mg.message()
  1177. ->    WriteF('Win:\d\n', win)
  1178.   ENDWHILE
  1179.  
  1180. EXCEPT DO
  1181.   IF win THEN CloseWindow(win)
  1182.   report_exception()
  1183.   WriteF('Exiting...\n')
  1184.   END mg
  1185.   CleanUp(0)
  1186. ENDPROC
  1187.  
  1188. #ifdef DO_FABIO_PLUGIN
  1189. PROC kill_pi(tx:PTR TO centertxt)
  1190.   WriteF('Killing Plug in:\h\n', tx)
  1191.   END tx
  1192. ENDPROC
  1193. #endif
  1194.  
  1195. PROC hideall(gui:PTR TO gui_obj)
  1196.   gui.mg.setattrs([MGUI_HIDEALL, TRUE, NIL, NIL])
  1197.   gui.mg.first()
  1198.   gui.mg.hide(FALSE)
  1199. ENDPROC
  1200.  
  1201. PROC showall(gui:PTR TO gui_obj) IS gui.mg.setattrs([MGUI_HIDEALL, FALSE, NIL, NIL])
  1202.  
  1203. PROC newgui(gui:PTR TO gui_obj) IS test(gui.mg)
  1204.  
  1205.  
  1206. PROC kill_all(gui:PTR TO gui_obj) IS gui.mg.clearguis()
  1207.  
  1208. PROC msg() IS WriteF('Message!\n')
  1209.  
  1210. #ifdef DO_FABIO_PLUGIN
  1211. PROC test(mg:PTR TO mgui)
  1212.   DEF txt=NIL:PTR TO centertxt
  1213.   DEF gui:PTR TO LONG
  1214.  
  1215.   gui:=NEW [ROWS,
  1216.        NEW   [PLUGIN, 0, NEW txt.centertxt('This is a PlugIN!', 2,1, TRUE,1)],
  1217.        NEW   [SBUTTON, {msg}, 'Msg'],
  1218.        NEW   [SBUTTON, 1, 'End']
  1219.            ]
  1220.  
  1221.   WriteF('PlugIn:\h\n', txt)
  1222.  
  1223.   mg.addA('Fabio PlugIn', gui, NEW [MGUI_FREEPROC, NEW [{kill_pi}, txt, NIL, NIL],
  1224.                                     NIL, NIL])
  1225. ENDPROC
  1226. #endif
  1227.  
  1228. PROC click(t:PTR TO LONG)
  1229.   DEF x:PTR TO LONG
  1230.  
  1231.   x:=GetMsg(t[1])
  1232.   ReplyMsg(x)
  1233.   WriteF('Win Clicked: \d Times!\n', times++)
  1234. ENDPROC
  1235.  
  1236. /*
  1237. PROC main() HANDLE
  1238.   DEF mg=NIL:PTR TO mgui
  1239.   DEF gui:PTR TO gui_obj
  1240.  
  1241.   NEW mg.mgui()
  1242.  
  1243.   gui:=mg.addA('Main', [BUTTON, {kill_son}, 'Kill'], [MGUI_MAIN, TRUE, NIL, NIL]) ->, [EG_INFO, mg, NIL, NIL])
  1244.  
  1245.   mg.addA('Son', [BUTTON, 1, 'Close Me!'], [MGUI_NAME, "son", NIL, NIL])
  1246.  
  1247.   WHILE mg.empty() = FALSE
  1248.     mg.message()
  1249.   ENDWHILE
  1250.  
  1251.   WriteF('No more GUIs\n')
  1252.  
  1253. EXCEPT DO
  1254.   END mg
  1255.   report_exception()
  1256. ENDPROC
  1257.  
  1258. PROC kill_son(gui:PTR TO gui_obj)
  1259.  
  1260.   IF gui.mg.pos("son") THEN gui.mg.del()
  1261.  
  1262. ENDPROC
  1263. */
  1264. #endif
  1265.  
  1266.  
  1267.  
  1268.  
  1269.