home *** CD-ROM | disk | FTP | other *** search
/ AMIGA PD 1 / AMIGA-PD-1.iso / Programme_zum_Heft / Programmieren / Kurztests / ACE / Prgs / ReqEd / Source / ReqEd.b < prev    next >
Text File  |  1995-02-20  |  50KB  |  1,889 lines

  1. {*
  2. ** A Requester Editor for ACE programs.
  3. **
  4. ** A requester (in this context, a window containing gadgets and text)
  5. ** can be designed on-screen. Code, in the form of an ACE subprogram, 
  6. ** is then generated to render it, await gadget activity and clean up.
  7. **
  8. ** The programmer can add code to act upon specific gadget activity 
  9. ** and possibly return information to the main program.
  10. **
  11. ** Author: David J Benn
  12. **   Date: 6th-8th,10th,15th-22nd,25th,26th January 1995,
  13. **       13th,14th,18th-20th February 1995
  14. *}
  15.  
  16. DEFLNG a-z
  17.  
  18. STRING version SIZE 30
  19. version = "$VER: ReqEd 1.11 (20.02.95)"
  20.  
  21. {*
  22. ** General constants.
  23. *}
  24. CONST true     = -1&
  25. CONST false     = 0&
  26. CONST null     = 0&
  27. CONST default     = -1&
  28.  
  29. {*
  30. ** ASCII codes for special keys.
  31. *}
  32. CONST DEL_key     = 127
  33. CONST BKSPC_key = 8
  34. CONST ENTER_key = 13
  35.  
  36. {*
  37. ** Border constants.
  38. *}
  39. CONST NO_EDGE        = 0 
  40. CONST LEFT_EDGE        = 1 
  41. CONST RIGHT_EDGE    = 2 
  42. CONST TOP_EDGE        = 3 
  43. CONST BOTTOM_EDGE    = 4
  44. CONST EDGE_THICKNESS    = 2
  45.  
  46. {*
  47. ** Menu constants.
  48. *}
  49. CONST sDisable        = 0
  50. CONST sEnable        = 1
  51. CONST sCheck        = 2
  52.  
  53. CONST mProject        = 1
  54. CONST iProject        = 0
  55. CONST iExit         = 1    '..for Preview mode Project menu.
  56. CONST iNew        = 1    '..for Layout mode Project menu.
  57. CONST iOpen        = 2
  58. CONST iSave        = 3
  59. CONST iSaveAs        = 4
  60. CONST iToolBar        = 5
  61. CONST iSep1.1        = 6
  62. CONST iAbout        = 7
  63. CONST iQuit        = 8
  64.  
  65. CONST mWindow        = 2
  66. CONST iWindow        = 0
  67. CONST iRedraw        = 1
  68. CONST iPreview        = 2
  69. CONST iSep2.1        = 3
  70. CONST iSetId        = 4
  71. CONST iSetTitle        = 5
  72. CONST iSep2.2        = 6
  73. CONST iSizeGadget    = 7
  74. CONST iMoveable        = 8
  75. CONST iDepthGadget    = 9
  76. CONST iCloseGadget    = 10
  77. CONST iSmartRefresh    = 11
  78. CONST iBorderless    = 12
  79.  
  80. {*
  81. ** Gadget constants.
  82. *}
  83. CONST gButton        = 1
  84. CONST gString        = 2
  85. CONST gLongInt        = 3
  86. CONST gPotX        = 4
  87. CONST gPotY        = 5
  88. CONST gText        = 6
  89. CONST gRaisedBox    = 7
  90. CONST gRecessedBox    = 8
  91.  
  92. {*
  93. ** GUI Object List node "kinds" (note: values agree with gadget constants above).
  94. *}
  95. CONST headOfList     = 0
  96. CONST buttonGadget     = 1
  97. CONST stringGadget     = 2
  98. CONST longintGadget     = 3
  99. CONST potXGadget     = 4
  100. CONST potYGadget     = 5
  101. CONST staticText     = 6
  102. CONST raisedBevelBox    = 7
  103. CONST recessedBevelBox    = 8
  104.  
  105. {*
  106. ** Box styles.
  107. *}
  108. CONST NORMAL         = 0
  109. CONST RAISED         = 1
  110. CONST RECESSED         = 2
  111. CONST STRGAD         = 3
  112.  
  113. {*
  114. ** Miscellaneous constants.
  115. *}
  116. CONST toolWdw = 1
  117. CONST maxToolBarButtons = 8
  118.  
  119. {* 
  120. ** Structure definitions.
  121. *}
  122. STRUCT WindowStruct
  123.    ADDRESS  NextWindow
  124.    SHORTINT LeftEdge
  125.    SHORTINT TopEdge
  126.    SHORTINT xWidth
  127.    SHORTINT Height
  128.    SHORTINT MouseY
  129.    SHORTINT MouseX
  130.    SHORTINT MinWidth
  131.    SHORTINT MinHeight
  132.    SHORTINT MaxWidth
  133.    SHORTINT MaxHeight
  134.    LONGINT  Flags
  135.    ADDRESS  MenuStrip
  136.    ADDRESS  Title
  137.    ADDRESS  FirstRequest
  138.    ADDRESS  DMRequest
  139.    SHORTINT ReqCount
  140.    ADDRESS  WScreen
  141.    ADDRESS  RPort
  142.    BYTE     BorderLeft
  143.    BYTE     BorderTop
  144.    BYTE     BorderRight
  145.    BYTE     BorderBottom
  146.    ADDRESS  BorderRPort
  147.    ADDRESS  FirstGadget
  148.    ADDRESS  Parent
  149.    ADDRESS  Descendant
  150.    ADDRESS  Pointer
  151.    BYTE     PtrHeight
  152.    BYTE     PtrWidth
  153.    BYTE     XOffset
  154.    BYTE     YOffset
  155.    LONGINT  IDCMPFlags
  156.    ADDRESS  UserPort
  157.    ADDRESS  WindowPort
  158.    ADDRESS  MessageKey
  159.    BYTE     DetailPen
  160.    BYTE     BlockPen
  161.    ADDRESS  CheckMark
  162.    ADDRESS  ScreenTitle
  163.    SHORTINT GZZMouseX
  164.    SHORTINT GZZMouseY
  165.    SHORTINT GZZWidth
  166.    SHORTINT GZZHeight
  167.    ADDRESS  ExtData
  168.    ADDRESS  UserData
  169.    ADDRESS  WLayer
  170.    ADDRESS  IFont
  171. END STRUCT
  172.  
  173. STRUCT GUIObjType
  174.   SHORTINT kind
  175.   SHORTINT x1
  176.   SHORTINT y1
  177.   SHORTINT x2
  178.   SHORTINT y2
  179.   ADDRESS  theText
  180.   ADDRESS  fontName
  181.   SHORTINT fontHeight
  182.   SHORTINT textStyle
  183.   SHORTINT frontColor
  184.   SHORTINT backColor
  185.   LONGINT  potVal
  186.   ADDRESS  nextNode
  187. END STRUCT
  188.  
  189. STRUCT CoordType
  190.   SHORTINT x1
  191.   SHORTINT y1
  192.   SHORTINT x2
  193.   SHORTINT y2
  194.   LONGINT  valid
  195. END STRUCT
  196.  
  197. STRUCT FontInfo
  198.   ADDRESS  fontName
  199.   SHORTINT fontHeight  
  200.   SHORTINT textStyle
  201.   SHORTINT frontColor
  202.   SHORTINT backColor
  203. END STRUCT
  204.  
  205. {*
  206. ** Globals.
  207. *}
  208. LONGINT finished
  209. LONGINT wdwFlags, wdwID, dirty, toolBarActive
  210. SHORTINT wdw_x1, wdw_y1, wdw_x2, wdw_y2
  211. SHORTINT old_wdw_x1, old_wdw_y1
  212. SHORTINT gadCount
  213. STRING wdwTitle SIZE 100
  214. STRING projectName SIZE 80
  215. STRING reqName SIZE 80
  216. DECLARE STRUCT GUIObjType *guiObjList
  217. ADDRESS spriteData
  218. DIM STRING buttonText(maxToolBarButtons) SIZE 15
  219.  
  220. {*
  221. ** Shared library function declarations.
  222. *}
  223. LIBRARY "graphics.library"
  224. DECLARE FUNCTION SetDrMd(ADDRESS RPort, SHORTINT mode) LIBRARY graphics
  225. DECLARE FUNCTION SHORTINT TextLength(ADDRESS RPort, STRING theText, ~
  226.                      SHORTINT count) LIBRARY graphics
  227.  
  228. LIBRARY "intuition.library"
  229. DECLARE FUNCTION SetPointer(ADDRESS wdw,ADDRESS spData,h%,w%,xOff%,yOff%) LIBRARY intuition
  230. DECLARE FUNCTION SetWindowTitles(ADDRESS wdw,wdw_title$,scr_title$) LIBRARY intuition
  231. CONST LEAVE = -1&
  232.  
  233. {*
  234. ** External SUB declarations.
  235. *}
  236. DECLARE SUB LONGINT FontInfoRequest(ADDRESS fontInfoStruct) EXTERNAL
  237.  
  238. '..See external references section in FontReq.b re: the following kludge!
  239. ASSEM 
  240.   xdef _EXIT_PROG
  241. END ASSEM
  242.  
  243. {*
  244. ** Forward SUB references.
  245. *}
  246. DECLARE SUB RedrawGUIObjects
  247. DECLARE SUB ADDRESS GUIObjVal(ADDRESS guiObjAddr, STRING prompt)
  248.  
  249. {*
  250. ** Subprogram definitions.
  251. *}
  252.  
  253. {* General SUBs *}
  254. SUB InitToolBarButtonText
  255. SHARED buttonText
  256. SHORTINT i
  257.   FOR i=1 TO maxToolBarButtons
  258.     READ buttonText(i)
  259.   NEXT
  260.   DATA "Button", "String", "LongInt", "PotX", "PotY", "Text"
  261.   DATA "Plateau", "Panel"
  262. END SUB
  263.  
  264. SUB InitCrossHairPointerData
  265. SHARED spriteData
  266. SHORTINT bytes, i, theWord
  267. CONST numberOfPairs = 17
  268.  
  269.   bytes = numberOfPairs*2*SIZEOF(SHORTINT)
  270.   spriteData = ALLOC(bytes,0)    '..allocate CHIP memory for sprite data.
  271.  
  272.   IF spriteData <> null THEN
  273.     FOR i=0 TO bytes-1 STEP 2
  274.       READ theWord
  275.       *%(spriteData+i) := theWord
  276.     NEXT
  277.  
  278.     DATA 0,0    '..position, control
  279.  
  280.     DATA &H0000, &H0000
  281.     DATA &H0000, &H0000
  282.  
  283.     DATA &H0100, &H0000
  284.     DATA &H0100, &H0000
  285.     DATA &H0100, &H0000
  286.     DATA &H0100, &H0000
  287.  
  288.     DATA &H0000, &H0000
  289.     DATA &HFD7E, &H0000
  290.     DATA &H0000, &H0000
  291.  
  292.     DATA &H0100, &H0000
  293.     DATA &H0100, &H0000
  294.     DATA &H0100, &H0000
  295.     DATA &H0100, &H0000
  296.  
  297.     DATA &H0000, &H0000    
  298.     DATA &H0000, &H0000    
  299.     
  300.     DATA 0,0    '..end
  301.   END IF
  302. END SUB
  303.  
  304. SUB LTRIM$(STRING x)
  305. SHORTINT i
  306.   FOR i=1 TO LEN(x)
  307.     IF MID$(x,i,1) <> " " THEN EXIT FOR 
  308.   NEXT
  309.   LTRIM$ = MID$(x,i)
  310. END SUB
  311.  
  312. SUB SetCurrWdw
  313. SHARED toolBarActive, wdwID
  314. SHORTINT currWdw
  315.   IF NOT toolBarActive THEN 
  316.     WINDOW OUTPUT wdwID
  317.   ELSE
  318.     currWdw = WINDOW(0)
  319.     IF currWdw = wdwID OR currWdw = toolWdw THEN WINDOW OUTPUT currWdw
  320.   END IF
  321. END SUB
  322.  
  323. SUB SetWdwRect
  324. SHARED wdwID, toolBarActive, dirty
  325. SHARED old_wdw_x1, old_wdw_y1
  326. SHARED wdw_x1, wdw_y1, wdw_x2, wdw_y2
  327. DECLARE STRUCT WindowStruct *wdw
  328.   WINDOW OUTPUT wdwID
  329.   wdw = WINDOW(7)
  330.   wdw_x1 = wdw->LeftEdge
  331.   wdw_y1 = wdw->TopEdge
  332.   wdw_x2 = wdw_x1 + WINDOW(2)
  333.   wdw_y2 = wdw_y1 + WINDOW(3)
  334.   IF toolBarActive THEN WINDOW OUTPUT toolWdw
  335.   IF wdw_x1 <> old_wdw_x1 OR wdw_y1 <> old_wdw_y1 THEN 
  336.     dirty = true
  337.     old_wdw_x1 = wdw_x1
  338.     old_wdw_y1 = wdw_y1
  339.   END IF
  340. END SUB
  341.  
  342. SUB STRING Rect(SHORTINT x1,SHORTINT y1,SHORTINT x2,SHORTINT y2)
  343.   Rect = "("+LTRIM$(STR$(x1))+","+LTRIM$(STR$(y1))+")-("+ ~
  344.      LTRIM$(STR$(x2))+","+LTRIM$(STR$(y2))+")"
  345. END SUB
  346.  
  347. SUB ShowMouseCoordinates(SHORTINT x1, SHORTINT y1, SHORTINT x2, SHORTINT y2)
  348. SHARED wdwID, wdwFlags, wdwTitle
  349.   WINDOW OUTPUT wdwID
  350.   IF (wdwFlags AND 2) OR (wdwFlags AND 4) OR (wdwFlags AND 8) OR (wdwTitle <> "") THEN 
  351.     SetWindowTitles(WINDOW(7),    "("+LTRIM$(STR$(x1))+","+ ~
  352.                 LTRIM$(STR$(y1))+")-("+ ~
  353.                 LTRIM$(STR$(x2))+","+ ~
  354.                 LTRIM$(STR$(y2))+")", ~
  355.             LEAVE)
  356.   END IF
  357. END SUB
  358.  
  359. SUB ResetReqWdwTitle
  360. SHARED wdwID, wdwFlags, wdwTitle
  361.   WINDOW OUTPUT wdwID
  362.   IF wdwTitle <> "" THEN
  363.     SetWindowTitles(WINDOW(7),wdwTitle,LEAVE)
  364.   ELSE
  365.     IF (wdwFlags AND 2) OR (wdwFlags AND 4) OR (wdwFlags AND 8) THEN
  366.       SetWindowTitles(WINDOW(7),"",LEAVE)
  367.     END IF
  368.   END IF
  369. END SUB
  370.  
  371. SUB CreateWindow
  372. SHARED wdwTitle, wdwFlags, wdwID
  373. SHARED wdw_x1, wdw_y1, wdw_x2, wdw_y2
  374. SHARED spriteData
  375.   IF wdwFlags AND 2 THEN
  376.     '..Moveable, so need a title bar.
  377.     WINDOW wdwID,wdwTitle,(wdw_x1,wdw_y1)-(wdw_x2,wdw_y2),wdwFlags
  378.   ELSE
  379.     IF wdwTitle <> "" THEN
  380.       '..A title has been specified.
  381.       WINDOW wdwID,wdwTitle,(wdw_x1,wdw_y1)-(wdw_x2,wdw_y2),wdwFlags
  382.     ELSE
  383.       '..No title specified.
  384.       WINDOW wdwID,,(wdw_x1,wdw_y1)-(wdw_x2,wdw_y2),wdwFlags
  385.     END IF
  386.   END IF
  387.  
  388.   '..Set the window's mouse pointer.
  389.   IF spriteData <> null THEN CALL SetPointer(WINDOW(7), spriteData, 15, 15, -8, -7)
  390.  
  391.   '..Redraw gadgets and text.
  392.   RedrawGUIObjects
  393. END SUB
  394.  
  395. SUB SetupMenus
  396. SHARED toolBarActive, wdwFlags
  397. SHORTINT i
  398.   MENU mProject,iProject,sEnable,    "Project"
  399.   MENU mProject,iNew,sEnable,        "  New",    "N"
  400.   MENU mProject,iOpen,sEnable,        "  Open...",    "O"
  401.   MENU mProject,iSave,sEnable,        "  Save...",    "S"
  402.   MENU mProject,iSaveAs,sEnable,    "  Save As..."
  403.   MENU mProject,iToolBar,sEnable,    "  Tool Bar",    "T"
  404.   MENU mProject,iSep1.1,sDisable,    "-----------------"
  405.   MENU mProject,iAbout,sEnable,        "  About..."
  406.   MENU mProject,iQuit,sEnable,        "  Quit",    "Q"
  407.  
  408.   MENU mWindow,iWindow,sEnable,        "Window"
  409.   MENU mWindow,iRedraw,sEnable,        "  Redraw",    "R"
  410.   MENU mWindow,iPreview,sEnable,    "  Preview",    "P"
  411.   MENU mWindow,iSep2.1,sDisable,    "----------------"
  412.   MENU mWindow,iSetId,sEnable,        "  Set Id..."
  413.   MENU mWindow,iSetTitle,sEnable,    "  Set Title..."
  414.   MENU mWindow,iSep2.2,sDisable,    "----------------"
  415.   MENU mWindow,iSizeGadget,sEnable,    "  Size Gadget"
  416.   MENU mWindow,iMoveable,sEnable,    "  Moveable"
  417.   MENU mWindow,iDepthGadget,sEnable,    "  Depth Gadget"
  418.   MENU mWindow,iCloseGadget,sEnable,    "  Close Gadget"
  419.   MENU mWindow,iSmartRefresh,sEnable,    "  Smart Refresh"
  420.   MENU mWindow,iBorderless,sEnable,    "  Borderless"
  421.  
  422.   '..Is the Tool Bar window active?
  423.   IF toolBarActive THEN MENU mProject,iToolBar,sCheck
  424.  
  425.   '..Set window menu checkmarks.
  426.   FOR i=0 TO 5
  427.     IF wdwFlags AND CINT(2^i) THEN MENU mWindow,iSizeGadget+i,sCheck
  428.   NEXT 
  429. END SUB
  430.  
  431. SUB DrawTextLayoutGuide(SHORTINT x1, SHORTINT y1, SHORTINT x2, SHORTINT y2)
  432.   '..Left edge of layout guide 
  433.   '..(possibly adjust, since it may have grown in 
  434.   '..height due to large font being specified while 
  435.   '..near top of window).
  436.   IF y1 < 0 THEN y1 = 0
  437.   LINE (x1,y1)-(x1,y2),2
  438.  
  439.   '..Text length indicator.
  440.   LINE (x1,y2)-(x2,y2),2
  441. END SUB
  442.  
  443. {* GUI Object List related SUBs/FNs *}
  444.  
  445. DEF ADDRESS NewGUIObj = ALLOC(SIZEOF(GUIObjType))
  446.  
  447. SUB ADDRESS GUIObjListHead
  448. SHARED guiObjList
  449.   guiObjList = NewGUIObj
  450.  
  451.   IF guiObjList = null THEN 
  452.     MsgBox "Memory allocation error!","Continue"
  453.   END IF
  454.  
  455.   guiObjList->kind = headOfList
  456.  
  457.   GUIObjListHead = guiObjList
  458. END SUB
  459.  
  460. SUB LONGINT NodesOK(ADDRESS theNode)
  461. SHARED guiObjList
  462.   IF guiObjList = null THEN
  463.     MsgBox "GUI Object List is not initialised!","Continue"
  464.     NodesOK = false
  465.     EXIT SUB
  466.   END IF
  467.   
  468.   IF theNode = null THEN
  469.     MsgBox "GUI Object Node is null!","Continue"
  470.     NodesOK = false
  471.     EXIT SUB
  472.   END IF
  473.  
  474.   NodesOK = true
  475. END SUB
  476.  
  477. SUB LONGINT NodesMatch(ADDRESS a, ADDRESS b)
  478. DECLARE STRUCT GUIObjType *node1, *node2
  479.   node1 = a
  480.   node2 = b
  481.  
  482.   IF node1->kind = node2->kind AND ~
  483.      node1->x1 = node2->x1 AND node1->y1 = node2->y1 AND ~
  484.      node1->x2 = node2->x2 AND node1->y2 = node2->y2 THEN
  485.     '..They are equal.
  486.     NodesMatch = true
  487.   ELSE
  488.     '..They are different.
  489.     NodesMatch = false
  490.   END IF
  491. END SUB
  492.  
  493. SUB AddGUIObj(ADDRESS theNode)
  494. SHARED guiObjList, gadCount
  495. DECLARE STRUCT GUIObjType *curr
  496.   IF NodesOK(theNode) THEN
  497.     '..Seek end of the list.   
  498.     curr = guiObjList
  499.     WHILE curr->nextNode <> null
  500.       curr = curr->nextNode
  501.     WEND
  502.  
  503.     '..Add the new node.
  504.     IF GadCount <= 255 THEN
  505.       IF curr->kind >= buttonGadget AND curr->kind <= potYGadget THEN ++gadCount
  506.       curr->nextNode = theNode
  507.     END IF
  508.   END IF
  509. END SUB
  510.  
  511. SUB RemoveGUIObj(ADDRESS theNode)
  512. SHARED guiObjList, gadCount
  513. DECLARE STRUCT GUIObjType *prev, *curr
  514. LONGINT found
  515.   IF NodesOK(theNode) THEN
  516.     '..Find node.
  517.     prev = guiObjList
  518.     curr = guiObjList->nextNode
  519.     found = false
  520.     WHILE NOT found AND curr <> null
  521.       IF NodesMatch(theNode,curr) THEN 
  522.         found = true
  523.       ELSE
  524.         prev = curr
  525.         curr = curr->nextNode
  526.       END IF
  527.     WEND
  528.  
  529.     '..Remove node from list.
  530.     IF found THEN 
  531.       IF curr->kind >= buttonGadget AND curr->kind <= potYGadget THEN --gadCount
  532.       prev->nextNode = curr->nextNode
  533.     END IF
  534.   END IF
  535. END SUB
  536.  
  537. SUB RedrawGUIObjects
  538. SHARED guiObjList
  539. DECLARE STRUCT GUIObjType *curr
  540.   IF guiObjList = null THEN
  541.     MsgBox "GUI Object List is not initialised!","Continue"
  542.   ELSE
  543.     '..Traverse the list drawing objects in requester window.
  544.     curr = guiObjList->nextNode
  545.     WHILE curr <> null
  546.       objKind = curr->kind
  547.       IF objKind = staticText THEN
  548.     '..Text.
  549.     DrawTextLayoutGuide(curr->x1,curr->y1,curr->x2,curr->y2)
  550.       ELSE
  551.     '..Gadget or Bevel-Box.
  552.         CASE
  553.           objKind = buttonGadget     : boxStyle = RAISED
  554.           objKind = stringGadget     : boxStyle = STRGAD
  555.           objKind = longintGadget    : boxStyle = STRGAD
  556.           objKind = potXGadget       : boxStyle = RAISED
  557.           objKind = potYGadget       : boxStyle = RAISED
  558.       objKind = raisedBevelBox   : boxStyle = RAISED
  559.       objKind = recessedBevelBox : boxStyle = RECESSED
  560.         END CASE
  561.  
  562.     BEVELBOX (curr->x1,curr->y1)-(curr->x2,curr->y2),boxStyle
  563.       END IF
  564.  
  565.       curr = curr->nextNode
  566.     WEND
  567.   END IF
  568. END SUB
  569.  
  570. SUB SaveGUIObjects(SHORTINT fileNum)
  571. SHARED guiObjList
  572. DECLARE STRUCT GUIObjType *curr
  573.   IF guiObjList = null THEN
  574.     MsgBox "GUI Object List is not initialised!","Continue"
  575.   ELSE
  576.     '..Traverse the list writing objects to a file.   
  577.     curr = guiObjList->nextNode
  578.     WHILE curr <> null
  579.       WRITE #fileNum,curr->kind
  580.       IF curr->kind = potXGadget OR curr->kind = potYGadget THEN
  581.     WRITE #fileNum,curr->potVal
  582.       ELSE
  583.     IF curr->kind <> raisedBevelBox AND curr->kind <> recessedBevelBox THEN
  584.       WRITE #fileNum,CSTR(curr->theText)
  585.     END IF
  586.       END IF
  587.       IF curr->kind = staticText THEN
  588.     WRITE #fileNum,CSTR(curr->fontName)
  589.     WRITE #fileNum,curr->fontHeight
  590.     WRITE #fileNum,curr->textStyle
  591.     WRITE #fileNum,curr->frontColor
  592.     WRITE #fileNum,curr->backColor
  593.       END IF
  594.       WRITE #fileNum,curr->x1,curr->y1,curr->x2,curr->y2
  595.       curr = curr->nextNode
  596.     WEND
  597.   END IF
  598. END SUB
  599.  
  600. SUB GetGUIObjects(SHORTINT fileNum)
  601. SHARED guiObjList, gadCount
  602. DECLARE STRUCT GUIObjType *curr
  603. SHORTINT x1,y1,x2,y2
  604.   IF guiObjList = null THEN
  605.     MsgBox "GUI Object List is not initialised!","Continue"
  606.   ELSE
  607.     '..Read objects from a file adding them to the list.
  608.     gadCount = 0
  609.     curr = guiObjList
  610.     WHILE NOT EOF(fileNum)
  611.       curr->nextNode = NewGUIObj
  612.       curr = curr->nextNode
  613.       IF curr = null THEN MsgBox "Memory allocation error!","Continue":EXIT SUB
  614.       INPUT #fileNum,theVal : curr->kind = theVal
  615.       IF curr->kind <> staticText AND curr->kind <> raisedBevelBox AND ~
  616.      curr->kind <> recessedBevelBox THEN ++gadCount
  617.       IF curr->kind = potXGadget OR curr->kind = potYGadget THEN
  618.     INPUT #fileNum,theVal : curr->potVal = theVal
  619.       ELSE
  620.     IF curr->kind <> raisedBevelBox AND curr->kind <> recessedBevelBox THEN
  621.       INPUT #fileNum,theVal$
  622.           curr->theText = ALLOC(LEN(theVal$)+1)
  623.           IF curr->theText = null THEN MsgBox "Memory allocation error!","Continue":EXIT SUB
  624.           STRING theText ADDRESS curr->theText
  625.           theText = theVal$
  626.     END IF
  627.       END IF
  628.       IF curr->kind = staticText THEN
  629.     INPUT #fileNum,theVal$
  630.         curr->fontName = ALLOC(LEN(theVal$)+1)
  631.         IF curr->fontName = null THEN MsgBox "Memory allocation error!","Continue":EXIT SUB
  632.         STRING fontName ADDRESS curr->fontName
  633.         fontName = theVal$
  634.     INPUT #fileNum,theVal : curr->fontHeight = theVal
  635.     INPUT #fileNum,theVal : curr->textStyle = theVal
  636.     INPUT #fileNum,theVal : curr->frontColor = theVal
  637.     INPUT #fileNum,theVal : curr->backColor = theVal
  638.       END IF 
  639.       INPUT #fileNum,x1,y1,x2,y2
  640.       curr->x1 = x1 : curr->y1 = y1 : curr->x2 = x2 : curr->y2 = y2
  641.     WEND
  642.   END IF
  643. END SUB
  644.  
  645. SUB SHORTINT RenderGUIObjects(SHORTINT fileNum)
  646. SHARED guiObjList
  647. DECLARE STRUCT GUIObjType *curr
  648. LONGINT theGadNum
  649. SHORTINT x1,y1, x2,y2
  650. SHORTINT bevelBoxMode
  651.   IF guiObjList = null THEN
  652.     MsgBox "GUI Object List is not initialised!","Continue"
  653.     '..No minimum gadget number.
  654.     RenderGUIObjects = 0
  655.   ELSE
  656.     '..Traverse the list generating code to render objects.
  657.     theGadNum = 256
  658.     curr = guiObjList->nextNode
  659.     WHILE curr <> null
  660.       IF curr->kind = staticText THEN
  661.     '..Text.
  662.     PRINT #fileNum,"  FONT ";CHR$(34);CSTR(curr->fontName);CHR$(34);","; ~
  663.                    LTRIM$(STR$(curr->fontHeight));" : ";
  664.     PRINT #fileNum,"STYLE";curr->textStyle;" : ";
  665.     PRINT #fileNum,"COLOR";STR$(curr->frontColor);","; ~
  666.             LTRIM$(STR$(curr->backColor));" : ";
  667.         PRINT #fileNum,"PENUP";" : ";
  668.     IF CSTR(curr->theText) <> "" THEN
  669.       PRINT #fileNum,"SETXY";STR$(curr->x1);",";LTRIM$(STR$(curr->y2))
  670.       PRINT #fileNum,"  PRINT ";CHR$(34);CSTR(curr->theText);CHR$(34);";"
  671.     END IF
  672.       ELSE
  673.     objKind = curr->kind
  674.        IF objKind = raisedBevelBox OR objKind = recessedBevelBox THEN
  675.       '..Bevel-Box.
  676.       PRINT #fileNum,"  BEVELBOX ";Rect(curr->x1,curr->y1,curr->x2,curr->y2);",";
  677.       IF objKind = raisedBevelBox THEN 
  678.         bevelBoxMode = RAISED 
  679.       ELSE
  680.         bevelBoxMode = RECESSED
  681.       END IF
  682.       PRINT #fileNum,LTRIM$(STR$(bevelBoxMode))
  683.     ELSE
  684.       '..Gadget.
  685.       x1 = curr->x1 : y1 = curr->y1
  686.       x2 = curr->x2 : y2 = curr->y2
  687.       
  688.           objKind = curr->kind
  689.         
  690.       '..Are offsets required for this gadget?
  691.       IF objKind = buttonGadget THEN
  692.         ++x2
  693.         ++y2
  694.       ELSE
  695.         IF objKind = stringGadget OR objKind = longintGadget THEN
  696.           x1 = x1+6 : y1 = y1+3
  697.           x2 = x2+6 : y2 = y2+3
  698.         END IF
  699.       END IF
  700.  
  701.           --theGadNum
  702.  
  703.        PRINT #fileNum,"  GADGET";STR$(theGadNum);",ON,";
  704.       IF curr->kind <> potXGadget AND curr->kind <> potYGadget THEN
  705.         PRINT #fileNum,CHR$(34);
  706.         IF CSTR(curr->theText) <> "" THEN PRINT #fileNum,CSTR(curr->theText);
  707.           PRINT #fileNum,CHR$(34);",";
  708.         ELSE
  709.           PRINT #fileNum,LTRIM$(STR$(curr->potVal));",";
  710.       END IF
  711.       PRINT #fileNum,Rect(x1,y1,x2,y2);",";
  712.           CASE
  713.             curr->kind = buttonGadget  : PRINT #fileNum,"BUTTON"
  714.             curr->kind = stringGadget  : PRINT #fileNum,"STRING"
  715.             curr->kind = longintGadget : PRINT #fileNum,"LONGINT"
  716.             curr->kind = potXGadget    : PRINT #fileNum,"POTX"
  717.             curr->kind = potYGadget    : PRINT #fileNum,"POTY"
  718.           END CASE
  719.     END IF
  720.       END IF
  721.       curr = curr->nextNode
  722.     WEND
  723.     '..Return minimum gadget number or zero if no gadgets.
  724.     IF theGadNum <> 256 THEN RenderGUIObjects = theGadNum ELSE RenderGUIObjects = 0
  725.   END IF
  726. END SUB
  727.  
  728. {* GUI object modification SUBs *}
  729.  
  730. SUB ADDRESS InsideGUIObj(SHORTINT x, SHORTINT y)
  731. SHARED guiObjList
  732. DECLARE STRUCT GUIObjType *curr
  733. LONGINT withinBounds
  734.   IF guiObjList = null THEN
  735.     MsgBox "GUI Object List is not initialised!","Continue"
  736.     InsideGUIObj = null
  737.   ELSE
  738.     '..Find node.
  739.     curr = guiObjList->nextNode
  740.     withinBounds = false
  741.     WHILE NOT withinBounds AND curr <> null
  742.       IF x > curr->x1+EDGE_THICKNESS AND x < curr->x2-EDGE_THICKNESS AND ~ 
  743.      y > curr->y1+EDGE_THICKNESS AND y < curr->y2-EDGE_THICKNESS THEN
  744.         withinBounds = true
  745.       ELSE
  746.         curr = curr->nextNode
  747.       END IF
  748.     WEND
  749.  
  750.     '..Return address of node (or null).
  751.     IF withinBounds THEN InsideGUIObj = curr ELSE InsideGUIObj = null
  752.   END IF
  753. END SUB
  754.  
  755. SUB SelectGUIObj(ADDRESS theObject)
  756. SHARED wdwID
  757. DECLARE STRUCT GUIObjType *guiObject
  758. SHORTINT left, right, top, bottom
  759.   guiObject = theObject
  760.   left = guiObject->x1 : top = guiObject->y1
  761.   right = guiObject->x2 : bottom = guiObject->y2
  762.   WINDOW OUTPUT wdwID
  763.   COLOR 3:PENUP:SETXY left,top:PENDOWN
  764.   SETXY right,top:SETXY right,bottom:SETXY left,bottom:SETXY left,top
  765. END SUB
  766.  
  767. SUB DeleteGUIObj(ADDRESS theObject)
  768. SHARED wdwID, dirty
  769. DECLARE STRUCT GUIObjType *guiObject
  770. STRING objName SIZE 20
  771.   guiObject = theObject
  772.   objKind = guiObject->kind
  773.   CASE
  774.     objKind = buttonGadget     : objName = "button"  
  775.     objKind = stringGadget     : objName = "string gadget"
  776.     objKind = longintGadget    : objName = "longint gadget"  
  777.     objKind = potXGadget       : objName = "horizontal slider"  
  778.     objKind = potYGadget       : objName = "vertical slider"  
  779.     objKind = staticText       : objName = "static text"
  780.     objKind = raisedBevelBox   : objName = "plateau"
  781.     objKind = recessedBevelBox : objName = "panel"
  782.   END CASE
  783.   IF MsgBox("Delete selected "+objName+"?","Yes","No") THEN 
  784.     RemoveGUIObj(theObject)
  785.     IF NOT dirty THEN dirty = true
  786.   END IF
  787.   '..Refresh display to get rid of selection box and
  788.   '..possibly to reflect absence of deleted object.
  789.   WINDOW OUTPUT wdwID
  790.   CLS : RedrawGUIObjects
  791. END SUB
  792.  
  793. SUB ModifyGUIObjVal(ADDRESS theObject)
  794. SHARED dirty, wdwID
  795. DECLARE STRUCT GUIObjType *guiObject, tmpObject
  796. STRING objName SIZE 20
  797. STRING prompt SIZE 30
  798.  
  799.   guiObject = theObject
  800.  
  801.   objKind = guiObject->kind
  802.  
  803.   '..Can't modify Bevel-Box since it holds no text value!
  804.   IF objKind = raisedBevelBox OR objKind = recessedBevelBox THEN 
  805.     MsgBox "No text to modify.","Continue"
  806.     '..Refresh display to get rid of selection box.
  807.     WINDOW OUTPUT wdwID
  808.     CLS : RedrawGUIObjects
  809.     EXIT SUB
  810.   END IF
  811.  
  812.   CASE
  813.    objKind = buttonGadget : objName="button" : prompt = "Enter Button Text"
  814.    objKind = stringGadget : objName="string gadget" : prompt = "Enter Default Text"
  815.    objKind = longintGadget : objName="longint gadget" : prompt = "Enter Default Value"  
  816.    objKind = potXGadget : objName="horizontal slider":prompt = "Enter Maximum Slider Value"
  817.    objKind = potYGadget : objName="vertical slider":prompt = "Enter Maximum Slider Value" 
  818.    objKind = staticText : objName="static text":prompt = "Enter Static Text"  
  819.   END CASE
  820.  
  821.   '..Store current values.
  822.   IF objKind <> potXGadget AND objKind <> potYGadget THEN 
  823.     tmpObject->theText = guiObject->theText
  824.   END IF
  825.  
  826.   IF objKind = staticText THEN
  827.     tmpObject->fontName = guiObject->fontName
  828.     tmpObject->fontHeight = guiObject->fontHeight
  829.     tmpObject->textStyle = guiObject->textStyle
  830.     tmpObject->frontColor = guiObject->frontColor
  831.     tmpObject->backColor = guiObject->backColor
  832.   END IF
  833.  
  834.   IF objKind = potXGadget OR objKind = potYGadget THEN
  835.     tmpObject->potVal = guiObject->potVal
  836.   END IF
  837.  
  838.   '..Change the GUI object?
  839.   IF MsgBox("Modify selected "+objName+"?","Yes","No") THEN 
  840.     IF GUIObjVal(theObject, prompt) <> null THEN 
  841.       '..Valid change made.     
  842.       IF NOT dirty THEN dirty = true
  843.     ELSE
  844.       '..Invalid value(s) entered, so restore old values.
  845.       IF objKind <> potXGadget AND objKind <> potYGadget THEN 
  846.          guiObject->theText = tmpObject->theText
  847.       END IF
  848.  
  849.       IF objKind = staticText THEN
  850.         guiObject->fontName = tmpObject->fontName
  851.         guiObject->fontHeight = tmpObject->fontHeight
  852.         guiObject->textStyle = tmpObject->textStyle
  853.         guiObject->frontColor = tmpObject->frontColor
  854.         guiObject->backColor = tmpObject->backColor
  855.       END IF
  856.  
  857.      IF objKind = potXGadget OR objKind = potYGadget THEN
  858.         guiObject->potVal = tmpObject->potVal
  859.      END IF
  860.     END IF
  861.   END IF
  862.   '..Refresh display to get rid of selection box.
  863.   WINDOW OUTPUT wdwID
  864.   CLS : RedrawGUIObjects
  865. END SUB
  866.  
  867. SUB MoveGUIObj(ADDRESS theObject)
  868. SHARED wdwID, dirty
  869. DECLARE STRUCT GUIObjType *guiObject
  870. ADDRESS RPort
  871. SHORTINT oldX1,oldY1, oldX2,oldY2
  872. SHORTINT x,y, lastX,lastY, xDiff,yDiff
  873. SHORTINT left, right, top, bottom
  874.  
  875.   guiObject = theObject
  876.  
  877.   '..Remove the object from the list.
  878.   RemoveGUIObj(guiObject)
  879.  
  880.   '..Refresh the display to show absence of the object.
  881.   WINDOW OUTPUT wdwID
  882.   CLS : RedrawGUIObjects
  883.   
  884.   '..Get initial position of object.
  885.   left = guiObject->x1 : top = guiObject->y1
  886.   right = guiObject->x2 : bottom = guiObject->y2
  887.  
  888.   oldX1 = left : oldY1 = top
  889.   oldX2 = right : oldY2 = bottom
  890.  
  891.   RPort = WINDOW(8)
  892.   SetDrMd(RPort,2)    '..XOR mode
  893.  
  894.   selected = true
  895.  
  896.   lastX = MOUSE(1) : lastY = MOUSE(2)
  897.   x = lastX : y = lastY
  898.  
  899.   '..Allow the object to be moved.
  900.   WHILE selected AND ~
  901.     lastX > left+EDGE_THICKNESS AND lastX < right-EDGE_THICKNESS AND ~
  902.     lastY > top+EDGE_THICKNESS AND lastY < bottom-EDGE_THICKNESS
  903.     IF MOUSE(0) THEN
  904.       '..Draw selection box.
  905.       COLOR 1:PENUP:SETXY left,top:PENDOWN
  906.       SETXY right,top:SETXY right,bottom:SETXY left,bottom:SETXY left,top
  907.  
  908.       ShowMouseCoordinates(left,top,right,bottom)
  909.  
  910.       '..Wait for mouse position to change or left button to be released.
  911.       WHILE selected AND x = lastX AND y = lastY
  912.         x = MOUSE(1) : y = MOUSE(2)
  913.         IF NOT MOUSE(0) THEN selected = false
  914.       WEND
  915.  
  916.       '..Erase selection box.
  917.       COLOR 0:PENUP:SETXY left,top:PENDOWN
  918.       SETXY right,top:SETXY right,bottom:SETXY left,bottom:SETXY left,top
  919.  
  920.       '..Adjust selection box? 
  921.       '..Treat horizontal and vertical motion independently.
  922.       xDiff = x-lastX : yDiff = y-lastY
  923.  
  924.       IF left+xDiff >= 0 THEN
  925.         left = left + xDiff : right = right + xDiff
  926.     lastX = x
  927.       ELSE
  928.     x = lastX
  929.       END IF
  930.  
  931.       IF top+yDiff >= 0 THEN
  932.         top = top + yDiff : bottom = bottom + yDiff 
  933.     lastY = y
  934.       ELSE
  935.     y = lastY
  936.       END IF
  937.     ELSE
  938.       '..Mouse button has been released.
  939.       selected = false
  940.     END IF 
  941.   WEND
  942.    
  943.   SetDrMd(RPort,1)    '..JAM2 mode
  944.   
  945.   '..Modify the object's position.
  946.   guiObject->x1 = left : guiObject->y1 = top
  947.   guiObject->x2 = right : guiObject->y2 = bottom
  948.  
  949.   '..Add the modified object to (the end of) the list.
  950.   guiObject->nextNode = null
  951.   AddGUIObj(guiObject)
  952.  
  953.   '..Refresh the display to show object's (new) position.
  954.   WINDOW OUTPUT wdwID
  955.   CLS : RedrawGUIObjects
  956.  
  957.   IF NOT dirty AND (left <> oldX1 OR right <> oldX2 OR ~
  958.           top <> oldY1 OR bottom <> oldY2) THEN dirty = true
  959.  
  960.   ResetReqWdwTitle
  961. END SUB
  962.  
  963. SUB SHORTINT ObjEdge(SHORTINT x, SHORTINT y, ADDRESS theObject)
  964. DECLARE STRUCT GUIObjType *guiObject
  965.   guiObject = theObject
  966.  
  967.   CASE
  968.     x >= guiObject->x1 AND x <= guiObject->x1+EDGE_THICKNESS AND ~
  969.     y >= guiObject->y1 AND y <= guiObject->y2 : ObjEdge = LEFT_EDGE
  970.  
  971.     x >= guiObject->x2-EDGE_THICKNESS AND x <= guiObject->x2 AND ~
  972.     y >= guiObject->y1 AND y <= guiObject->y2: ObjEdge = RIGHT_EDGE
  973.  
  974.     y >= guiObject->y1 AND y <= guiObject->y1+EDGE_THICKNESS AND ~
  975.     x >= guiObject->x1 AND x <= guiObject->x2 : ObjEdge = TOP_EDGE
  976.  
  977.     y >= guiObject->y2-EDGE_THICKNESS AND y <= guiObject->y2 AND ~
  978.     x >= guiObject->x1 AND x <= guiObject->x2: ObjEdge = BOTTOM_EDGE
  979.  
  980.     default : ObjEdge = NO_EDGE
  981.   END CASE
  982. END SUB
  983.  
  984. SUB ADDRESS OnGUIObjBorder(SHORTINT x, SHORTINT y, ADDRESS edge)
  985. SHARED guiObjList
  986. DECLARE STRUCT GUIObjType *curr
  987. LONGINT onBorder
  988.   IF guiObjList = null THEN
  989.     MsgBox "GUI Object List is not initialised!","Continue"
  990.     OnGUIObjBorder = null
  991.     *%edge := NO_EDGE
  992.   ELSE
  993.     '..Find node.
  994.     curr = guiObjList->nextNode
  995.     onBorder = false
  996.     WHILE NOT onBorder AND curr <> null
  997.       *%edge := ObjEdge(x,y,curr)
  998.       IF *%edge <> NO_EDGE THEN
  999.     onBorder = true
  1000.       ELSE
  1001.         curr = curr->nextNode
  1002.       END IF
  1003.     WEND
  1004.  
  1005.     '..Return address of node (or null).
  1006.     IF onBorder THEN 
  1007.       OnGUIObjBorder = curr
  1008.     ELSE 
  1009.       *%edge := NO_EDGE
  1010.       OnGUIObjBorder = null
  1011.     END IF
  1012.   END IF
  1013. END SUB
  1014.  
  1015. SUB ResizeGUIObj(ADDRESS theObject, SHORTINT edge)
  1016. SHARED wdwID, dirty
  1017. DECLARE STRUCT GUIObjType *guiObject
  1018. ADDRESS RPort
  1019. SHORTINT oldX1,oldY1, oldX2,oldY2
  1020. SHORTINT x,y, lastX,lastY
  1021. SHORTINT left, right, top, bottom
  1022.  
  1023.   guiObject = theObject
  1024.  
  1025.   IF guiObject->kind = staticText THEN EXIT SUB
  1026.  
  1027.   '..Remove the object from the list.
  1028.   RemoveGUIObj(guiObject)
  1029.  
  1030.   '..Refresh the display to show absence of the object.
  1031.   WINDOW OUTPUT wdwID
  1032.   CLS : RedrawGUIObjects
  1033.   
  1034.   '..Get initial position of object.
  1035.   left = guiObject->x1 : top = guiObject->y1
  1036.   right = guiObject->x2 : bottom = guiObject->y2
  1037.  
  1038.   oldX1 = left : oldY1 = top
  1039.   oldX2 = right : oldY2 = bottom
  1040.  
  1041.   RPort = WINDOW(8)
  1042.   SetDrMd(RPort,2)    '..XOR mode
  1043.  
  1044.   selected = true
  1045.  
  1046.   lastX = MOUSE(1) : lastY = MOUSE(2)
  1047.   x = lastX : y = lastY
  1048.  
  1049.   '..Allow the object to be resized.
  1050.   WHILE selected
  1051.     IF MOUSE(0) THEN
  1052.       '..Draw selection box.
  1053.       COLOR 1:PENUP:SETXY left,top:PENDOWN
  1054.       SETXY right,top:SETXY right,bottom:SETXY left,bottom:SETXY left,top
  1055.  
  1056.       ShowMouseCoordinates(left,top,right,bottom)
  1057.  
  1058.       '..Wait for mouse position to change or left button to be released.
  1059.       WHILE selected AND x = lastX AND y = lastY
  1060.         x = MOUSE(1) : y = MOUSE(2)
  1061.         IF NOT MOUSE(0) THEN selected = false
  1062.       WEND
  1063.  
  1064.       '..Erase selection box.
  1065.       COLOR 0:PENUP:SETXY left,top:PENDOWN
  1066.       SETXY right,top:SETXY right,bottom:SETXY left,bottom:SETXY left,top
  1067.  
  1068.       '..Adjust one edge of the selection box?
  1069.       IF x >= 0 AND y >= 0 THEN
  1070.     '..Yes.
  1071.         CASE
  1072.       edge = LEFT_EDGE   : IF x < right-EDGE_THICKNESS THEN left = x
  1073.       edge = RIGHT_EDGE  : IF x > left+EDGE_THICKNESS THEN right = x
  1074.       edge = TOP_EDGE    : IF y < bottom-EDGE_THICKNESS THEN top = y
  1075.       edge = BOTTOM_EDGE : IF y > top+EDGE_THICKNESS THEN bottom = y
  1076.         END CASE     
  1077.         lastX = x : lastY = y
  1078.       ELSE
  1079.     '..No. Retain previous edge position.
  1080.     x = lastX : y = lastY
  1081.       END IF
  1082.     ELSE
  1083.       '..Mouse button has been released.
  1084.       selected = false
  1085.     END IF 
  1086.   WEND
  1087.    
  1088.   SetDrMd(RPort,1)    '..JAM2 mode
  1089.   
  1090.   '..Modify the object's position.
  1091.   guiObject->x1 = left : guiObject->y1 = top
  1092.   guiObject->x2 = right : guiObject->y2 = bottom
  1093.  
  1094.   '..Add the modified object to (the end of) the list.
  1095.   guiObject->nextNode = null
  1096.   AddGUIObj(guiObject)
  1097.  
  1098.   '..Refresh the display to show object's (new) position.
  1099.   WINDOW OUTPUT wdwID
  1100.   CLS : RedrawGUIObjects
  1101.  
  1102.   IF NOT dirty AND (left <> oldX1 OR right <> oldX2 OR ~
  1103.           top <> oldY1 OR bottom <> oldY2) THEN dirty = true
  1104.  
  1105.   ResetReqWdwTitle
  1106. END SUB
  1107.  
  1108. {* Project menu SUBs *}
  1109.  
  1110. SUB ToggleToolBar
  1111. SHARED toolBarActive, wdwID, buttonText
  1112. SHORTINT fontWidth, fontHeight, n
  1113.  
  1114.   IF NOT toolBarActive THEN
  1115.     '..Activate Tool Bar.
  1116.     fontWidth = SCREEN(5)
  1117.     fontHeight = SCREEN(6)
  1118.     WINDOW toolWdw,,(10,10)-(10+11*fontWidth,10+19.5*fontHeight),10
  1119.     FOR n=gButton TO gRecessedBox
  1120.       '..Render tool bar buttons making each one as wide as necessary
  1121.       '..to accomodate the longest button text.
  1122.       GADGET n,ON,buttonText(n-gButton+1),(fontWidth,fontHeight+(n-1)*2*fontHeight)- ~
  1123.                 (fontWidth+8*fontWidth,fontHeight+n*2*fontHeight),BUTTON,1
  1124.     NEXT
  1125.  
  1126.     WINDOW OUTPUT wdwID
  1127.     MENU mProject,iToolBar,sCheck
  1128.     toolBarActive = true
  1129.   ELSE
  1130.     '..Deactivate Tool Bar.
  1131.     FOR n=gButton TO gRecessedBox
  1132.       GADGET CLOSE n
  1133.     NEXT
  1134.     WINDOW OUTPUT toolWdw    '..prevent main window menus from being cleared.
  1135.     WINDOW CLOSE toolWdw
  1136.     WINDOW OUTPUT wdwID
  1137.     MENU mProject,iToolBar,sEnable
  1138.     toolBarActive = false
  1139.   END IF
  1140. END SUB
  1141.  
  1142. SUB SetProjectName(STRING fileReqTitle)
  1143. SHARED projectName
  1144. STRING newProjectName SIZE 80
  1145.   newProjectName = FileBox$(fileReqTitle)
  1146.   IF newProjectName <> "" THEN projectName = newProjectName
  1147. END SUB
  1148.  
  1149. SUB StoreInfo
  1150. SHARED projectName, reqName
  1151. SHARED wdwID, wdwTitle, wdwFlags
  1152. SHARED wdw_x1, wdw_y1, wdw_x2, wdw_y2
  1153.   OPEN "O",#1,projectName+".req"
  1154.   IF HANDLE(1) = null THEN 
  1155.     MsgBox "Unable to open "+projectName+".req for writing.","Continue"
  1156.     EXIT SUB
  1157.   ELSE
  1158.     PRINT #1,"#REQED PROJECT#"
  1159.     PRINT #1,reqName
  1160.     WRITE #1,wdwID
  1161.     IF wdwTitle <> "" THEN PRINT #1,wdwTitle ELSE PRINT #1,"#NULL#"
  1162.     WRITE #1,wdwFlags
  1163.     WRITE #1,wdw_x1,wdw_y1,wdw_x2,wdw_y2
  1164.     SaveGUIObjects(1)
  1165.     CLOSE #1
  1166.   END IF
  1167. END SUB
  1168.  
  1169. SUB GenerateCode
  1170. SHARED projectName, reqName, wdwID, wdwTitle, wdwFlags
  1171. SHARED wdw_x1, wdw_y1, wdw_x2, wdw_y2
  1172. STRING theTitle SIZE 80
  1173. SHORTINT minGadget
  1174.   IF reqName = "" THEN
  1175.     reqName = InputBox$("Requester SUB name?","Set requester SUB name",reqName,170,10)
  1176.   END IF
  1177.  
  1178.   IF reqName = "" THEN
  1179.     MsgBox projectName+".b not created.","Continue"
  1180.     EXIT SUB
  1181.   END IF
  1182.   OPEN "O",#1,projectName+".b"  
  1183.   IF HANDLE(1) = null THEN 
  1184.     MsgBox "Unable to open "+projectName+".b for writing.","Continue"
  1185.     EXIT SUB
  1186.   ELSE
  1187.     PRINT #1,"SUB ";reqName  
  1188.     {* Variables *}
  1189.     PRINT #1,"SHORTINT theGadget, n"  
  1190.     {* Code for window *}
  1191.     PRINT #1,"  WINDOW";STR$(wdwID);",";
  1192.     IF wdwTitle <> "" THEN
  1193.       '..A title has been specified. 
  1194.       PRINT #1,CHR$(34);wdwTitle;CHR$(34);
  1195.     ELSE
  1196.       '..There's no title but the window is moveable
  1197.       '..(otherwise we want no title bar at all).
  1198.       IF wdwFlags AND 2 THEN PRINT #1,CHR$(34);CHR$(34);
  1199.     END IF
  1200.     PRINT #1,",";Rect(wdw_x1,wdw_y1,wdw_x2,wdw_y2);",";LTRIM$(STR$(wdwFlags))
  1201.     {* Render gadgets, bevel-boxes and text *}
  1202.     PRINT #1,"  ";CHR$(123);"* RENDER GADGETS, BEVEL-BOXES AND TEXT *";CHR$(125)
  1203.     minGadget = RenderGUIObjects(1)
  1204.     {* Await and handle gadget activity *}
  1205.     PRINT #1,"  ";CHR$(123);"* GADGET HANDLING CODE STARTS HERE *";CHR$(125)
  1206.     PRINT #1,"  GADGET WAIT 0"
  1207.     PRINT #1,"  theGadget = GADGET(1)"
  1208.     {* Cleanup code *}
  1209.     PRINT #1,"  ";CHR$(123);"* CLEAN UP *";CHR$(125)
  1210.     IF minGadget <> 0 THEN
  1211.       PRINT #1,"  FOR n=255 TO";minGadget;"STEP -1"
  1212.       PRINT #1,"    GADGET CLOSE n"
  1213.       PRINT #1,"  NEXT" 
  1214.     END IF
  1215.     PRINT #1,"  WINDOW CLOSE";wdwID
  1216.     PRINT #1,"END SUB"
  1217.   END IF
  1218.   CLOSE #1
  1219. END SUB
  1220.  
  1221. SUB SaveProject
  1222. SHARED dirty, projectName, reqName
  1223.   SetWdwRect
  1224.   IF dirty THEN
  1225.     IF projectName = "" THEN CALL SetProjectName("Save Project")
  1226.     IF projectName = "" THEN
  1227.       '..Abort.
  1228.       MsgBox "Project name not specified.","Continue"
  1229.     ELSE
  1230.       GenerateCode
  1231.       IF reqName <> "" THEN
  1232.     '..Abort.
  1233.         StoreInfo
  1234.         dirty = false
  1235.       END IF
  1236.     END IF
  1237.   END IF
  1238. END SUB
  1239.  
  1240. SUB SaveAs
  1241. SHARED projectName, reqName, dirty
  1242. STRING oldProjectName SIZE 80
  1243. STRING oldReqName SIZE 80
  1244.   oldProjectName = projectName
  1245.   projectName = ""
  1246.   SetProjectName("Save As...")
  1247.   IF projectName = "" THEN
  1248.     '..Abort.
  1249.     MsgBox "Name not specified.","Continue"
  1250.     projectName = oldProjectName
  1251.   ELSE
  1252.     SetWdwRect
  1253.     oldReqName = reqName
  1254.     reqName = ""
  1255.     GenerateCode
  1256.     IF reqName = "" THEN
  1257.       '..Abort.
  1258.       reqName = oldReqName
  1259.       projectName = oldProjectName
  1260.     ELSE
  1261.       StoreInfo
  1262.       IF dirty THEN dirty = false
  1263.     END IF
  1264.   END IF
  1265. END SUB
  1266.  
  1267. SUB CloseProject
  1268. SHARED wdwID
  1269.   MENU CLEAR
  1270.   WINDOW CLOSE wdwID
  1271. END SUB
  1272.  
  1273. SUB OpenProject
  1274. SHARED projectName, reqName, dirty
  1275. SHARED wdwID, wdwTitle, wdwFlags
  1276. SHARED wdw_x1, wdw_y1, wdw_x2, wdw_y2
  1277. SHARED old_wdw_x1, old_wdw_y1
  1278. STRING oldProjectName SIZE 80
  1279. STRING fileType SIZE 80
  1280. STRING theName SIZE 80
  1281.  
  1282.   IF dirty THEN
  1283.     IF projectName <> "" THEN theName = projectName ELSE theName = "project"
  1284.     IF MsgBox("Save "+theName+"?","Yes","No") THEN CALL SaveProject
  1285.   END IF
  1286.  
  1287.   oldProjectName = projectName
  1288.   SetProjectName("Open Project")
  1289.  
  1290.   IF projectName = "" THEN
  1291.     MsgBox "Project name not specified.","Continue"
  1292.     projectName = oldProjectName
  1293.     EXIT SUB
  1294.   END IF 
  1295.  
  1296.   IF INSTR(projectName,".req") = 0 THEN
  1297.     MsgBox projectName+" not of required type.","Continue"
  1298.     projectName = oldProjectName
  1299.     EXIT SUB
  1300.   END IF
  1301.  
  1302.   IF GUIObjListHead = null THEN
  1303.     projectName = oldProjectName
  1304.     EXIT SUB
  1305.   END IF
  1306.  
  1307.   OPEN "I",#1,projectName
  1308.   IF HANDLE(1) = null THEN
  1309.     MsgBox "Unable to open "+projectName+" for input.","Continue"
  1310.     projectName = oldProjectName
  1311.     EXIT SUB
  1312.   ELSE
  1313.     LINE INPUT #1,fileType
  1314.     IF fileType <> "#REQED PROJECT#" THEN
  1315.       MsgBox projectName+" not of required type.","Continue"
  1316.       projectName = oldProjectName
  1317.       CLOSE #1
  1318.       EXIT SUB
  1319.     END IF
  1320.     CloseProject
  1321.     LINE INPUT #1,reqName
  1322.     INPUT #1,wdwID
  1323.     LINE INPUT #1,wdwTitle : IF wdwTitle = "#NULL#" THEN wdwTitle = ""
  1324.     INPUT #1,wdwFlags
  1325.     INPUT #1,wdw_x1,wdw_y1,wdw_x2,wdw_y2
  1326.     old_wdw_x1 = wdw_x1 : old_wdw_y1 = wdw_y1
  1327.     GetGUIObjects(1)
  1328.     CLOSE #1
  1329.     projectName = LEFT$(projectName,INSTR(projectName,".req")-1)
  1330.   END IF
  1331.   CreateWindow
  1332.   SetupMenus  
  1333.   dirty = false
  1334. END SUB
  1335.  
  1336. SUB NewProject
  1337. SHARED dirty, wdwID, wdwTitle, gadCount
  1338. SHARED wdwFlags, projectName, reqName
  1339. SHARED wdw_x1, wdw_y1, wdw_x2, wdw_y2
  1340. SHARED old_wdw_x1, old_wdw_y1
  1341. STRING theName SIZE 80
  1342.   IF dirty THEN
  1343.     IF projectName <> "" THEN theName = projectName ELSE theName = "project"
  1344.     IF MsgBox("Save "+theName+"?","Yes","No") THEN CALL SaveProject
  1345.   END IF
  1346.   CloseProject
  1347.   IF GUIObjListHead = null THEN EXIT SUB
  1348.   wdwID = 9
  1349.   wdwFlags = 0
  1350.   wdwTitle = ""
  1351.   reqName = ""
  1352.   projectName = ""
  1353.   wdw_x1 = 170 : wdw_y1 = 50 : old_wdw_x1 = 0 : old_wdw_y1 = 0
  1354.   wdw_x2 = 470 : wdw_y2 = 175
  1355.   gadCount = 0
  1356.   CreateWindow
  1357.   SetUpMenus  
  1358.   dirty = false
  1359. END SUB
  1360.  
  1361. SUB QuitProgram
  1362. SHARED finished, dirty, projectName
  1363. STRING theName SIZE 80
  1364.   IF dirty THEN
  1365.     IF projectName <> "" THEN theName = projectName ELSE theName = "project"
  1366.     IF MsgBox("Save "+theName+"?","Yes","No") THEN CALL SaveProject
  1367.   END IF
  1368.   finished = true
  1369. END SUB
  1370.  
  1371. {* Window menu SUBs *}
  1372.  
  1373. SUB PreviewRequester
  1374. SHARED wdwID, wdwFlags, wdwTitle
  1375. SHARED wdw_x1, wdw_y1, wdw_x2, wdw_y2
  1376. SHARED guiObjList
  1377. DECLARE STRUCT GUIObjType *curr
  1378. SHORTINT x1,y1, x2,y2
  1379. SHORTINT ID
  1380. SHORTINT objKind
  1381. LONGINT theGadNum
  1382. SHORTINT bevelBoxMode
  1383.  
  1384.   '..Render the window.
  1385.   SetWdwRect
  1386.   ID = wdwID-1
  1387.   IF ID = toolWdw THEN ID = 9  '..wrap around?
  1388.   IF wdwFlags AND 2 THEN
  1389.     '..Moveable, so need a title bar.
  1390.     WINDOW ID,wdwTitle,(wdw_x1,wdw_y1)-(wdw_x2,wdw_y2),wdwFlags
  1391.   ELSE
  1392.     IF wdwTitle <> "" THEN
  1393.       '..A title has been specified.
  1394.       WINDOW ID,wdwTitle,(wdw_x1,wdw_y1)-(wdw_x2,wdw_y2),wdwFlags
  1395.     ELSE
  1396.       '..No title specified.
  1397.       WINDOW ID,,(wdw_x1,wdw_y1)-(wdw_x2,wdw_y2),wdwFlags
  1398.     END IF
  1399.   END IF
  1400.  
  1401.   '..Set up menu.
  1402.   MENU mProject,iProject,sEnable,    "Project"
  1403.   MENU mProject,iExit,sEnable,        "Exit", "E"
  1404.  
  1405.   '..Render gadgets and text.
  1406.   IF guiObjList = null THEN
  1407.     MsgBox "GUI Object List is not initialised!","Continue"
  1408.   ELSE
  1409.     '..Traverse the list rendering objects.
  1410.     theGadNum = 256
  1411.     curr = guiObjList->nextNode
  1412.     WHILE curr <> null
  1413.       IF curr->kind = staticText THEN
  1414.     '..Text.
  1415.     FONT CSTR(curr->fontName),curr->fontHeight
  1416.     STYLE curr->textStyle
  1417.     COLOR curr->frontColor,curr->backColor
  1418.         PENUP
  1419.     IF curr->theText <> null THEN
  1420.       SETXY curr->x1,curr->y2
  1421.       PRINT CSTR(curr->theText);
  1422.         END IF    
  1423.       ELSE
  1424.     objKind = curr->kind
  1425.     IF objKind = raisedBevelBox OR objKind = recessedBevelBox THEN
  1426.       '..Bevel-Box.
  1427.       IF objKind = raisedBevelBox THEN 
  1428.         bevelBoxMode = RAISED 
  1429.       ELSE
  1430.         bevelBoxMode = RECESSED
  1431.       END IF
  1432.       BEVELBOX (curr->x1,curr->y1)-(curr->x2,curr->y2),bevelBoxMode
  1433.     ELSE
  1434.       '..Gadget.
  1435.       x1 = curr->x1 : y1 = curr->y1
  1436.       x2 = curr->x2 : y2 = curr->y2
  1437.       
  1438.           objKind = curr->kind
  1439.         
  1440.       '..Are offsets required for this gadget?
  1441.       IF objKind = buttonGadget THEN
  1442.         ++x2
  1443.         ++y2
  1444.       ELSE
  1445.         IF objKind = stringGadget OR objKind = longintGadget THEN
  1446.           x1 = x1+6 : y1 = y1+3
  1447.           x2 = x2+6 : y2 = y2+3
  1448.         END IF
  1449.       END IF
  1450.  
  1451.           --theGadNum     
  1452.  
  1453.       IF curr->kind <> potXGadget AND curr->kind <> potYGadget THEN
  1454.          GADGET theGadNum,ON,CSTR(curr->theText),(x1,y1)-(x2,y2),objKind
  1455.       ELSE
  1456.          GADGET theGadNum,ON,curr->potVal,(x1,y1)-(x2,y2),objKind
  1457.       END IF
  1458.         END IF
  1459.       END IF
  1460.       curr = curr->nextNode
  1461.     WEND
  1462.     
  1463.     '..Await Exit item selection from Project menu or close-gadget click.
  1464.     REPEAT
  1465.       MENU WAIT
  1466.     UNTIL (MENU(0) = mProject AND MENU(1) = iExit) OR GADGET(1) = 256
  1467.  
  1468.     '..Clean up.    
  1469.     FOR n=255 TO theGadNum STEP -1
  1470.       GADGET CLOSE n
  1471.     NEXT
  1472.     WINDOW CLOSE ID
  1473.   END IF  
  1474. END SUB
  1475.  
  1476. SUB ToggleFlag(SHORTINT theItem)
  1477. SHARED wdwFlags
  1478. SHORTINT theFlag
  1479.   theFlag = CINT(2^(theItem-iSizeGadget))
  1480.   IF wdwFlags AND theFlag THEN 
  1481.     '..Set flag
  1482.     wdwFlags = wdwFlags - theFlag
  1483.   ELSE
  1484.     '..Reset flag
  1485.     wdwFlags = wdwFlags OR theFlag
  1486.   END IF
  1487. END SUB
  1488.  
  1489. SUB SetWdwID
  1490. SHARED wdwID, dirty
  1491. SHORTINT newID
  1492. STRING wdwIDStr SIZE 2
  1493.   wdwIDStr = STR$(wdwID)
  1494.   wdwIDStr = LTRIM$(wdwIDStr)
  1495.   newID = InputBox("New window ID (2..9)","Set window ID",wdwIDStr,170,10)
  1496.   IF newID <> wdwID AND newID >= 2 AND newID <= 9 THEN
  1497.     dirty = newID <> wdwID
  1498.     SetWdwRect
  1499.     CloseProject
  1500.     wdwID = newID
  1501.     CreateWindow
  1502.     SetUpMenus
  1503.   END IF
  1504. END SUB
  1505.  
  1506. SUB SetWdwTitle
  1507. SHARED wdwID, wdwTitle, dirty
  1508. STRING newTitle SIZE 100
  1509.   newTitle = InputBox$("New window Title?","Set window Title",wdwTitle,170,10)  
  1510.   IF newTitle <> wdwTitle THEN
  1511.     dirty = newTitle <> wdwTitle
  1512.     wdwTitle = newTitle
  1513.     SetWdwRect
  1514.     CloseProject
  1515.     CreateWindow
  1516.     SetUpMenus
  1517.   END IF
  1518. END SUB
  1519.  
  1520. SUB ModifyWindow(SHORTINT theItem)
  1521. SHARED dirty
  1522.   IF theItem >= iSizeGadget THEN 
  1523.     CALL ToggleFlag(theItem)
  1524.     IF NOT dirty THEN dirty = true
  1525.     SetWdwRect
  1526.     CloseProject
  1527.     CreateWindow
  1528.     SetUpMenus
  1529.   ELSE
  1530.     CASE 
  1531.       theItem = iSetID    : SetWdwID
  1532.       theItem = iSetTitle : SetWdwTitle
  1533.     END CASE
  1534.   END IF
  1535. END SUB
  1536.  
  1537. SUB DrawBox(SHORTINT objKind, ADDRESS theCoord)
  1538. SHARED wdwID
  1539. ADDRESS RPort
  1540. SHORTINT xDiff,yDiff, x,y, firstX,firstY
  1541. DECLARE STRUCT CoordType *coord
  1542.  
  1543.   coord = theCoord
  1544.  
  1545.   WINDOW OUTPUT wdwID
  1546.   RPort = WINDOW(8)
  1547.  
  1548.   '..Await a mouse click in the requester window.
  1549.   WHILE NOT MOUSE(0):SLEEP FOR .02:WEND
  1550.  
  1551.   '..Go no further if user didn't click in requester window.
  1552.   IF WINDOW(0) <> wdwID THEN
  1553.     coord->valid = false
  1554.     EXIT SUB 
  1555.   END IF
  1556.  
  1557.   firstX = MOUSE(1) : firstY = MOUSE(2)
  1558.  
  1559.   IF MOUSE(0) THEN
  1560.     SetDrMd(RPort,2)    '..XOR mode
  1561.  
  1562.     WHILE MOUSE(0)
  1563.       x = MOUSE(1) : y = MOUSE(2)
  1564.       xDiff = x-firstX : yDiff = y-firstY
  1565.       IF xDiff > 0 AND yDiff > 0 THEN 
  1566.      COLOR 1:PENUP:SETXY firstX,firstY:PENDOWN
  1567.     SETXY x,firstY:SETXY x,y:SETXY firstX,y:SETXY firstX,firstY
  1568.         ShowMouseCoordinates(firstX,firstY,x,y)
  1569.     COLOR 0:PENUP:SETXY firstX,firstY:PENDOWN
  1570.     SETXY x,firstY:SETXY x,y:SETXY firstX,y:SETXY firstX,firstY
  1571.       END IF
  1572.     WEND    
  1573.       
  1574.     SetDrMd(RPort,1)    '..JAM2 mode
  1575.  
  1576.     ResetReqWdwTitle
  1577.   
  1578.     IF xDiff > 0 AND yDiff > 0 THEN
  1579.       IF objKind = staticText THEN
  1580.     '..Text.
  1581.     DrawTextLayoutGuide(firstX,firstY,x,y)
  1582.     coord->valid = true   
  1583.       ELSE
  1584.     '..Gadget.
  1585.         CASE
  1586.           objKind = buttonGadget     : boxStyle = RAISED
  1587.           objKind = stringGadget     : boxStyle = STRGAD
  1588.           objKind = longintGadget    : boxStyle = STRGAD
  1589.           objKind = potXGadget       : boxStyle = RAISED
  1590.           objKind = potYGadget       : boxStyle = RAISED
  1591.       objKind = raisedBevelBox   : boxStyle = RAISED
  1592.       objKind = recessedBevelBox : boxStyle = RECESSED
  1593.         END CASE
  1594.  
  1595.      BEVELBOX (firstX,firstY)-(x,y),boxStyle
  1596.       coord->valid = true
  1597.       END IF
  1598.  
  1599.       '..Return coordinate info' for object.
  1600.       coord->x1 = firstX : coord->y1 = firstY
  1601.       coord->x2 = x : coord->y2 = y 
  1602.     ELSE
  1603.       coord->valid = false
  1604.     END IF
  1605.   ELSE
  1606.     coord->valid = false
  1607.   END IF
  1608. END SUB
  1609.  
  1610. SUB ADDRESS GUIObjVal(ADDRESS guiObjAddr, STRING prompt)
  1611. SHARED wdwID
  1612. DECLARE STRUCT GUIObjType *guiObj
  1613. DECLARE STRUCT FontInfo info
  1614. ADDRESS textAddress, RPort
  1615. SHORTINT objKind
  1616. STRING tmpString
  1617. STRING defaultString
  1618.  
  1619.   guiObj = guiObjAddr 
  1620.   objKind = guiObj->kind
  1621.  
  1622.   IF objKind <> potXGadget AND objKind <> potYGadget THEN
  1623.     IF guiObj->theText <> null THEN 
  1624.     defaultString = CSTR(guiObj->theText)
  1625.     ELSE
  1626.         defaultString = ""
  1627.     END IF
  1628.     IF objKind = longintGadget THEN
  1629.       '..Want to allow only entry of digits 0..9!
  1630.       textAddress = SADD(LTRIM$(STR$(InputBox(prompt,,defaultString,170,10))))
  1631.     ELSE
  1632.       textAddress = SADD(InputBox$(prompt,,defaultString,170,10))
  1633.     END IF
  1634.  
  1635.     guiObj->theText = ALLOC(LEN(CSTR(textAddress))+1)
  1636.     IF guiObj->theText = null THEN 
  1637.     MsgBox "Memory allocation error!","Continue"
  1638.     GUIObjVal = null
  1639.     ELSE
  1640.         STRING theText ADDRESS guiObj->theText
  1641.         theText = CSTR(textAddress)
  1642.         GUIObjVal = guiObj->theText
  1643.     END IF
  1644.  
  1645.     IF objKind = staticText THEN
  1646.       IF FontInfoRequest(info) THEN
  1647.     '..Okay -> use info' from requester.
  1648.     textAddress = info->fontName
  1649.     guiObj->fontHeight = info->fontHeight
  1650.     guiObj->textStyle = info->textStyle
  1651.     guiObj->frontColor = info->frontColor
  1652.     guiObj->backColor = info->backColor
  1653.       ELSE
  1654.     '..Use defaults.
  1655.         textAddress = SADD("topaz")
  1656.         guiObj->fontHeight = 8
  1657.         guiObj->textStyle = 0
  1658.         guiObj->frontColor = 1
  1659.         guiObj->backColor = 0
  1660.       END IF
  1661.  
  1662.       '..Copy the font name.
  1663.       guiObj->fontName = ALLOC(LEN(CSTR(textAddress))+1)
  1664.       IF guiObj->fontName = null THEN 
  1665.     MsgBox "Memory allocation error!","Continue"
  1666.     GUIObjVal = null
  1667.       ELSE
  1668.         STRING fontName ADDRESS guiObj->fontName
  1669.         fontName = CSTR(textAddress)
  1670.       END IF
  1671.  
  1672.       '..Adjust text selection box.
  1673.       guiObj->y1 = guiObj->y2 - guiObj->fontHeight
  1674.       WINDOW OUTPUT wdwID
  1675.       RPort = WINDOW(8)
  1676.       FONT CSTR(guiObj->fontName),guiObj->fontHeight
  1677.       IF CSTR(guiObj->theText) = "" THEN
  1678.     '..Make sure selection box is big enough to use!
  1679.     tmpString = "M"  '..use a wide character.
  1680.     length = 1
  1681.       ELSE
  1682.         tmpString = CSTR(guiObj->theText)
  1683.         length = LEN(tmpString)
  1684.       END IF
  1685.       guiObj->x2 = guiObj->x1 + TextLength(RPort,tmpString,length)
  1686.     END IF
  1687.   ELSE
  1688.     '..POTX or POTY.
  1689.     REPEAT
  1690.       IF guiObj->potVal > 0 THEN 
  1691.     defaultString = LTRIM$(STR$(guiObj->potVal))
  1692.       ELSE
  1693.     defaultString = ""
  1694.       END IF
  1695.       guiObj->potVal = InputBox(prompt,,defaultString,170,10)
  1696.     UNTIL guiObj->potVal > 0
  1697.     GUIObjVal = guiObj->potVal
  1698.   END IF
  1699. END SUB
  1700.  
  1701. SUB CreateGUIObj(SHORTINT objKind, SHORTINT boxStyle)
  1702. SHARED wdwID, dirty
  1703. DECLARE STRUCT CoordType coord
  1704. DECLARE STRUCT GUIObjType *guiObj
  1705. STRING prompt SIZE 30
  1706.  
  1707.   WINDOW OUTPUT toolWdw
  1708.   GADGET objKind,OFF
  1709.   WINDOW OUTPUT wdwID
  1710.    
  1711.   DrawBox(objKind, coord)
  1712.  
  1713.   IF coord->valid THEN
  1714.     guiObj = NewGUIObj
  1715.     guiObj->kind = objKind
  1716.     guiObj->x1 = coord->x1
  1717.     guiObj->y1 = coord->y1
  1718.     guiObj->x2 = coord->x2
  1719.     guiObj->y2 = coord->y2
  1720.  
  1721.     IF objKind = raisedBevelBox OR objKind = recessedBevelBox THEN
  1722.         '..Add bevel-box object to the list and set the "dirty" 
  1723.     '..flag since the layout has changed.
  1724.         AddGUIObj(guiObj)
  1725.         IF NOT dirty THEN dirty = true      
  1726.     ELSE
  1727.       CASE
  1728.         objKind = buttonGadget  : prompt = "Enter Button Text"
  1729.         objKind = stringGadget  : prompt = "Enter Default Text"
  1730.         objKind = longintGadget : prompt = "Enter Default Value" 
  1731.         objKind = potXGadget    : prompt = "Enter Maximum Slider Value (> 0)"
  1732.         objKind = potYGadget    : prompt = "Enter Maximum Slider Value (> 0)" 
  1733.         objKind = staticText    : prompt = "Enter Static Text"
  1734.       END CASE    
  1735.  
  1736.       IF GUIObjVal(guiObj, prompt) <> null THEN       
  1737.         '..The GUI object is valid so add it to the list
  1738.         '..and set the "dirty" flag since the layout has changed.
  1739.         AddGUIObj(guiObj)
  1740.         IF NOT dirty THEN dirty = true
  1741.  
  1742.         '..Redraw text layout guide now that we have font, style and color,
  1743.         '..having previously adjusted the selection box.
  1744.         IF objKind = staticText THEN
  1745.           WINDOW OUTPUT wdwID
  1746.           CLS : RedrawGUIObjects
  1747.         END IF
  1748.       END IF
  1749.     END IF
  1750.   END IF
  1751.   
  1752.   '..Restore gadget imagery in tool window.
  1753.   WINDOW OUTPUT toolWdw
  1754.   FOR n = gButton TO gRecessedBox : GADGET n,ON : NEXT
  1755.   WINDOW OUTPUT wdwID
  1756. END SUB
  1757.  
  1758. {*
  1759. ** Main.
  1760. *}
  1761. '..Initialise GUI object list.
  1762. IF GUIObjListHead = null THEN STOP
  1763.  
  1764. '..Initialise tool bar button text array.
  1765. InitToolBarButtonText
  1766.  
  1767. '..Initialise main window cross-hair mouse pointer.
  1768. InitCrossHairPointerData
  1769.  
  1770. '..Set up initial project.
  1771. wdwID = 9
  1772. wdw_x1 = 170 : wdw_y1 = 50 : old_wdw_x1 = wdw_x1 : old_wdw_y1 = wdw_y1
  1773. wdw_x2 = 470 : wdw_y2 = 175
  1774. gadCount = 0
  1775. toolBarActive = false : finished = false
  1776.  
  1777. CreateWindow
  1778. SetupMenus
  1779.  
  1780. '..Activate event trapping.
  1781. ON MENU GOSUB handle_menu : MENU ON
  1782. ON GADGET GOSUB handle_gadget : GADGET ON
  1783. ON WINDOW GOSUB handle_window : WINDOW ON
  1784. ON MOUSE GOSUB handle_mouse : MOUSE ON
  1785.  
  1786. '..Await events.
  1787. WHILE NOT finished
  1788.   SetCurrWdw
  1789.   SLEEP FOR .02
  1790. WEND
  1791.  
  1792. '..Deactivate event trapping.
  1793. MENU OFF : GADGET OFF : WINDOW OFF : MOUSE OFF
  1794.  
  1795. '..Clean up.
  1796. CloseProject
  1797. IF toolBarActive THEN CALL ToggleToolBar
  1798. CLEAR ALLOC
  1799. STOP
  1800.  
  1801. {*
  1802. ** Event handlers.
  1803. *}
  1804.  
  1805. {* Menu handler *}
  1806. handle_menu:
  1807.   theMenu = MENU(0)
  1808.   theItem = MENU(1)
  1809.  
  1810.   '..Project menu?
  1811.   IF theMenu = mProject THEN
  1812.     CASE
  1813.     theItem = iNew       : NewProject
  1814.     theItem = iOpen    : OpenProject
  1815.     theItem = iSave    : SaveProject
  1816.     theItem = iSaveAs  : SaveAs
  1817.     theItem = iToolBar : ToggleToolBar
  1818.     theItem = iAbout   : MsgBox "ReqEd v1.11, by David J Benn","Continue"
  1819.     theItem = iQuit       : QuitProgram
  1820.     END CASE
  1821.     RETURN
  1822.   END IF
  1823.  
  1824.   '..Window menu?
  1825.   IF theMenu = mWindow THEN
  1826.     CASE 
  1827.       theItem = iRedraw : WINDOW OUTPUT wdwID:CLS:RedrawGUIObjects
  1828.       theItem = iPreview : PreviewRequester    
  1829.       default : IF theItem <> 0 THEN CALL ModifyWindow(theItem)
  1830.     END CASE
  1831.     RETURN
  1832.   END IF  
  1833.  
  1834. '..No menu.
  1835. RETURN
  1836.  
  1837. {* Window (close-gadget) handler *}
  1838. handle_window:
  1839.   IF WINDOW(0) = toolWdw THEN CALL ToggleToolBar
  1840. RETURN
  1841.  
  1842. {* Gadget handler (for Tool Bar) *}
  1843. handle_gadget:
  1844.   theGadget = GADGET(1) 
  1845.  
  1846.   CASE
  1847.     theGadget = gButton      : boxStyle = RAISED
  1848.     theGadget = gString      : boxStyle = STRGAD
  1849.     theGadget = gLongInt     : boxStyle = STRGAD
  1850.     theGadget = gPotX           : boxStyle = RAISED
  1851.     theGadget = gPotY          : boxStyle = RAISED
  1852.     theGadget = gText          : boxStyle = NORMAL
  1853.     theGadget = gRaisedBox   : boxStyle = RAISED
  1854.     theGadget = gRecessedBox : boxStyle = RECESSED
  1855.   END CASE
  1856.  
  1857.   CreateGUIObj(theGadget, boxStyle)
  1858. RETURN
  1859.  
  1860. {* Mouse-handler (left mouse-button click) *}
  1861. handle_mouse:
  1862. ADDRESS theObject
  1863. SHORTINT edge
  1864.   IF WINDOW(0) = wdwID THEN
  1865.     '..Get current mouse coordinates.
  1866.     mouseX = MOUSE(1) : mouseY = MOUSE(2)
  1867.     '..On a GUI object's border? If so, resize object from specified edge.
  1868.     theObject = OnGUIObjBorder(mouseX, mouseY, @edge)
  1869.     IF theObject <> null THEN
  1870.     ResizeGUIObj(theObject, edge) 
  1871.     ELSE
  1872.         '..Within a GUI object's bounds?
  1873.         theObject = InsideGUIObj(mouseX, mouseY)
  1874.         IF theObject <> null THEN
  1875.             '..Show the object as being selected.
  1876.             SelectGUIObj(theObject)
  1877.           theKey$ = INKEY$
  1878.             CASE
  1879.         theKey$ = CHR$(DEL_key) OR theKey$ = CHR$(BKSPC_key) : DeleteGUIObj(theObject)
  1880.             theKey$ = CHR$(ENTER_key) : ModifyGUIObjVal(theObject)
  1881.             default : MoveGUIObj(theObject)
  1882.           END CASE    
  1883.         END IF
  1884.     END IF
  1885.   END IF
  1886. RETURN
  1887.  
  1888. END
  1889.