home *** CD-ROM | disk | FTP | other *** search
/ Garbo / Garbo.cdr / mac / hypercrd / xcmd / prctclxf.sit / DemoStack / card_2288.txt < prev    next >
Text File  |  1990-08-28  |  19KB  |  690 lines

  1. -- card: 2288 from stack: in
  2. -- bmap block id: 8187
  3. -- flags: 0000
  4. -- background id: 2685
  5. -- name: Draw Tree
  6. ----- HyperTalk script -----
  7. on openCard
  8.   hide menuBar
  9.   get lockMenuBar(true)
  10.   setTreeDirty
  11.   pass openCard
  12. end openCard
  13.  
  14. on closeCard
  15.   get lockMenuBar(false)
  16.   pass closeCard
  17. end closeCard
  18.  
  19. ---------------------------------------------------------------------
  20. -- The "tree dirty" flags remember what aspects of the tree must
  21. -- be recalculated. Whenever the tree changes setTreeDirty should
  22. -- be called with no parameters
  23. ---------------------------------------------------------------------
  24.  
  25. function treeDirty what
  26. global gTreeDirtyWidths
  27. global gTreeDirtyCoordinates
  28. global gTreeDirtyDraw
  29. if (what = "widths") then return gTreeDirtyWidths
  30. if (what = "coordinates") then return gTreeDirtyCoordinates
  31. if (what = "draw") then return gTreeDirtyDraw
  32. return ((gTreeDirtyWidths) or (gTreeDirtyCoordinates) or (gTreeDirtyDraw))
  33. end treeDirty
  34.  
  35. on setTreeDirty what, dirty
  36.   global gTreeDirtyWidths
  37.   global gTreeDirtyCoordinates
  38.   global gTreeDirtyDraw
  39.   global gTreeDirtyWhat
  40.   if (what = "widths") then put dirty into gTreeDirtyWidths
  41.   else if (what = "coordinates") then put dirty into gTreeDirtyCoordinates
  42.   else if (what = "draw") then put dirty into gTreeDirtyDraw
  43.   else if (what Γëá empty) and (what Γëá gTreeDirtyWhat) then
  44.     put true into gTreeDirtyWidths
  45.     put true into gTreeDirtyCoordinates
  46.     put true into gTreeDirtyDraw
  47.     put what into gTreeDirtyWhat
  48.   else if (what = empty) then
  49.     put true into gTreeDirtyWidths
  50.     put true into gTreeDirtyCoordinates
  51.     put true into gTreeDirtyDraw
  52.   end if
  53. end setTreeDirty
  54.  
  55. ---------------------------------------------------------------------
  56. -- These functions return information about the nodes in the tree.
  57. -- If the tree is dirty (see below) then the data are recalculated.
  58. ---------------------------------------------------------------------
  59.  
  60. on treeErase
  61.   eraseRect the rect of cd fld "DrawingArea", 1
  62.   setTreeDirty draw, true
  63. end treeErase
  64.  
  65. on treeDraw what
  66.   answer "Draw what part of the tree?" with "Indexes" or "Data" or "Keys"
  67.   put it into what
  68.   if (what Γëá empty) then
  69.     setTreeDirty what, true
  70.     if (treeDirty(draw)) then
  71.       set cursor to watch
  72.       treeErase
  73.       treeSetupDraw
  74.       put treeCoordinates(what) into coordinates
  75.       put treeRoot(rect of cd fld "DrawingArea", what) into point
  76.       treeExecuteDraw treeName(), coordinates, point, what
  77.       treeRestoreDraw
  78.       setTreeDirty draw, false
  79.       put "Finished Drawing " & what & "." into cd fld "Progress"
  80.       choose browse tool
  81.     end if
  82.   end if
  83. end treeDraw
  84.  
  85. function treeWidth what
  86. global gTreeSavedWidth
  87. setTreeDirty what, true
  88. if (treeDirty(widths)) then
  89.   treeSetupDraw
  90.   put treeCalcWidth(treeName(), what) into gTreeSavedWidth
  91.   treeRestoreDraw
  92.   setTreeDirty widths, false
  93. end if
  94. return gTreeSavedWidth
  95. end treeWidth
  96.  
  97. function treeCoordinates what
  98. global gTreeSavedCoordinates
  99. setTreeDirty what, true
  100. if (treeDirty(coordinates)) then
  101.   treeSetupDraw
  102.   put treeCalcCoordinates(treeName(), treeWidth(what)) into gTreeSavedCoordinates
  103.   treeRestoreDraw
  104.   setTreeDirty coordinates, false
  105. end if
  106. return gTreeSavedCoordinates
  107. end treeCoordinates
  108.  
  109. function treeRoot drawrect, what
  110.  
  111. -- get width of left and right sides of tree
  112. put treeWidth(what) into widths
  113. put item 1 of line 1 of widths into lwidth
  114. put item 1 of line 2 of widths into rwidth
  115.  
  116. -- get width of draw rectangle
  117. put ((item 3 of drawrect) - (item 1 of drawrect)) into drawwidth
  118.  
  119. -- adjust center so maximum amount of tree will be visible
  120. if ((lwidth Γëñ drawwidth/2) and (rwidth Γëñ drawwidth/2)) then
  121.   put (item 1 of drawrect + drawwidth/2) into center
  122. else if (lwidth < rwidth) then
  123.   put (item 1 of drawrect + lwidth) into center
  124. else
  125.   put (item 3 of drawrect - rwidth) into center
  126. end if
  127.  
  128. put center into item 1 of point
  129. put item 2 of drawrect into item 2 of point
  130. return point
  131. end treeRoot
  132.  
  133. function treeRect
  134. end treeRect
  135.  
  136. function treeName
  137. return("demoTree")
  138. end treeName
  139.  
  140. function treeClear tree
  141. get btree(dispose, tree)
  142. get btree(new, tree, numeric)
  143. setTreeDirty empty
  144. return it
  145. end treeClear
  146.  
  147. ---------------------------------------------------------------------
  148. -- Functions for updating the tree and calculating things for the
  149. -- tree.
  150. ---------------------------------------------------------------------
  151.  
  152. -- Setup environment for drawing
  153. on treeSetupDraw
  154.   global gTreeSetupDraw
  155.   global gTreeDrawEnv
  156.   add 1 to gTreeSetupDraw
  157.   if (gTreeSetupDraw = 1) then
  158.     put tool() into line 1 of gTreeDrawEnv
  159.     put setTextStyle("Geneva, 9, 9, center") into line 2 of gTreeDrawEnv
  160.   end if
  161. end treeSetupDraw
  162.  
  163. -- Restore drawing environment
  164. on treeRestoreDraw
  165.   global gTreeSetupDraw
  166.   global gTreeDrawEnv
  167.   subtract 1 from gTreeSetupDraw
  168.   if (gTreeSetupDraw = 0) then
  169.     choose line 1 of gTreeDrawEnv
  170.     get setTextStyle(line 2 of gTreeDrawEnv)
  171.   end if
  172. end treeRestoreDraw
  173.  
  174. -- Draw the tree
  175. on treeExecuteDraw tree, coordinates, point, what
  176.   put "Drawing tree..." into cd fld "Progress"
  177.  
  178.   put btree(levelorder, tree, what) into nodes
  179.   put btree(levelorder, tree, indexes) into indexes
  180.   put line 1 of coordinates into coordinatesH
  181.   put line 2 of coordinates into coordinatesV
  182.  
  183.   add nodeVertical() to item 2 of point
  184.  
  185.   choose text tool
  186.   repeat with i=1 to number(items in nodes)
  187.  
  188.     put (item i of indexes) into index
  189.  
  190.     -- get coordinates of node
  191.     put (item index of coordinatesH + item 1 of point) into nodeH
  192.     put (item index of coordinatesV + item 2 of point) into nodeV
  193.  
  194.     -- if this node has a parent
  195.     if (i > 1) then
  196.       -- get parent's coordinates
  197.       put ((item (index div 2) of coordinatesH) + item 1 of point) into parentH
  198.       put ((item (index div 2) of coordinatesV) + item 2 of point) into parentV
  199.  
  200.       -- draw line from parent to node
  201.       choose line tool
  202.       drag from round(parentH),round(parentV) to round(nodeH),(round(nodeV)-nodeVertical())
  203.       choose text tool
  204.     end if
  205.     -- draw node
  206.     click at round(nodeH),round(nodeV)-nodeMargin()
  207.     type (item i of nodes)
  208.   end repeat
  209. end treeExecuteDraw
  210.  
  211. --
  212. -- Calculates the width of the left and right children of every
  213. -- node in the tree. The widths are returned in pixels, one item
  214. -- per node, and correspond to a level-order traversal of the tree.
  215. -- Parameters:
  216. --   tree  The tree to calculate for
  217. -- Returns:
  218. -- Line 1  Widths of left sides of nodes
  219. -- Line 2  Widths of right sides of nodes
  220. --
  221. function treeCalcWidth tree, what
  222. put "Calculating widths of nodes..." into cd fld "Progress"
  223.  
  224. -- get level order traversal of tree
  225. put btree(levelorder, tree, what) into nodes
  226. put btree(levelorder, tree, indexes) into indexes
  227.  
  228. -- these variables hold the lists of left and right widths
  229. put empty into lwidths
  230. put empty into rwidths
  231.  
  232. -- work up towards root from bottom of tree
  233. repeat with i=number(items in nodes) down to 1
  234.   set cursor to busy
  235.  
  236.   -- get index to node and to its children
  237.   put (item i of indexes) into index
  238.   put lindex(index) into left
  239.   put rindex(index) into right
  240.   put (left is in indexes) into hasleft
  241.   put (right is in indexes) into hasright
  242.  
  243.   -- calculate left and right widths
  244.   put number(chars in item i of nodes)*the textSize/2 into nodeWidth
  245.   if ((not hasleft) and (not hasright)) then
  246.     -- node is a leaf
  247.     put nodeWidth into lwidth
  248.     put nodeWidth into rwidth
  249.   else
  250.     -- node has children
  251.     if (hasleft) then
  252.       put (item left of lwidths + item left of rwidths) into lwidth
  253.     else put nodeWidth into lwidth
  254.     if (hasright) then
  255.       put (item right of lwidths + item right of rwidths) into rwidth
  256.     else put nodeWidth into rwidth
  257.   end if
  258.  
  259.   -- store widths
  260.   put lwidth into item index of lwidths
  261.   put rwidth into item index of rwidths
  262.  
  263. end repeat
  264.  
  265. -- make result
  266. put lwidths into line 1 of widths
  267. put rwidths into line 2 of widths
  268. return widths
  269. end treeCalcWidth
  270.  
  271. --
  272. -- Calculates the coordinates of the nodes in the tree. The root
  273. -- of the tree is at 0,0.
  274. -- Parameters:
  275. --   tree  The tree to calculate for
  276. -- Returns:
  277. --   Line 1  Horizontal coordinates in level-order
  278. --   Line 2  Vertical coordinates in level-order
  279. --
  280. function treeCalcCoordinates tree, widths
  281. put "Calculating coordinates of nodes..." into cd fld "Progress"
  282.  
  283. put btree(levelorder, tree, indexes) into indexes
  284. put line 1 of widths into lwidths
  285. put line 2 of widths into rwidths
  286.  
  287. -- these variables will hold the coordinates of each of the nodes
  288. put empty into coordinatesH
  289. put empty into coordinatesV
  290.  
  291. -- nodeH and nodeV hold the coordinates of the current node
  292. put 0 into nodeH
  293. put 0 into nodeV
  294.  
  295. repeat with i=1 to number(items in indexes)
  296.   set cursor to busy
  297.  
  298.   put (item i of indexes) into index
  299.  
  300.   -- if this node has a parent
  301.   if (i > 1) then
  302.     -- get parent's coordinates
  303.     put item (index div 2) of coordinatesH into parentH
  304.     put item (index div 2) of coordinatesV into parentV
  305.  
  306.     -- calculate vertical coordinate of node
  307.     put trunc(log2(index)) into height
  308.     put (height * (nodeVertical()+nodeTop())) into nodeV
  309.  
  310.     -- calculate horizontal coordinate of node
  311.     if ((index mod 2) = 0) then
  312.       -- node is a left child
  313.       put (parentH - (item index of rwidths)) into nodeH
  314.     else
  315.       -- node is a right child
  316.       put (parentH + (item index of lwidths)) into nodeH
  317.     end if
  318.   end if
  319.  
  320.   -- store coordinates of node
  321.   put nodeH into item index of coordinatesH
  322.   put nodeV into item index of coordinatesV
  323. end repeat
  324.  
  325. -- return the coordinates
  326. put coordinatesH into line 1 of coordinates
  327. put coordinatesV into line 2 of coordinates
  328. return coordinates
  329. end treeCalcCoordinates
  330.  
  331. -- return vertical space needed by text of node
  332. function nodeVertical
  333. return the textHeight + 2*nodeMargin()
  334. end nodeVertical
  335.  
  336. -- return vertical space needed for tree's edges
  337. function nodeTop
  338. return 4
  339. end nodeTop
  340.  
  341. -- return margin around text of node
  342. function nodeMargin
  343. return 2
  344. end nodeMargin
  345.  
  346. -- return index of left child
  347. function lindex i
  348. return 2*i
  349. end lindex
  350.  
  351. -- return index of right child
  352. function rindex i
  353. return 2*i+1
  354. end rindex
  355.  
  356. ---------------------------------------------------------------------
  357. -- report the error to the user
  358. ---------------------------------------------------------------------
  359.  
  360. on treeError error
  361.   answer "Error: " & errorstring(error)
  362. end treeError
  363.  
  364. ---------------------------------------------------------------------
  365. -- some simple drawing functions
  366. ---------------------------------------------------------------------
  367.  
  368. -- Erase the specified rectangle
  369. on eraseRect rct, pat
  370.   put the tool into saved_tool
  371.   put the pattern into saved_pat
  372.   put the filled into saved_filled
  373.   choose rect tool
  374.   set pattern to pat
  375.   set filled to true
  376.   drag from (item 1 to 2 of rct) to (item 3 to 4 of rct)
  377.   set pattern to saved_pat
  378.   set filled to saved_filled
  379.   choose saved_tool
  380. end eraseRect
  381.  
  382. --
  383. -- Set the style of text; returns the old style, so that when
  384. -- the caller is finished the text enviroment may be restored
  385. -- to its original values. For instance,
  386. --   on doStuff
  387. --     put setTextStyle(Courier, 12, 16, left) into saved_style
  388. --     ...do stuff...
  389. --     get setTextStyle(saved_style)
  390. --   end doStuff
  391. --
  392. function setTextStyle new_style
  393. put the textFont into item 1 of old_style
  394. put the textSize into item 2 of old_style
  395. put the textHeight into item 3 of old_style
  396. put the textAlign into item 4 of old_style
  397. set textFont to item 1 of new_style
  398. set textSize to item 2 of new_style
  399. set textHeight to item 3 of new_style
  400. set textAlign to item 4 of new_style
  401. return old_style
  402. end setTextStyle
  403.  
  404.  
  405.  
  406.  
  407.  
  408. -- part 1 (button)
  409. -- low flags: 00
  410. -- high flags: 8003
  411. -- rect: left=129 top=8 right=30 bottom=229
  412. -- title width / last selected line: 0
  413. -- icon id / first selected line: 0 / 0
  414. -- text alignment: 1
  415. -- font id: 0
  416. -- text size: 12
  417. -- style flags: 0
  418. -- line height: 16
  419. -- part name: Random Tree
  420. ----- HyperTalk script -----
  421. on mouseUp
  422.   -- get size of tree from user
  423.   put 0 into size
  424.   repeat until ((1 Γëñ size) and (size Γëñ 128))
  425.     ask "Enter size of tree (1-128): " with 16
  426.     put it into size
  427.     if (size = empty) then exit mouseUp
  428.   end repeat
  429.   -- fill tree with random data
  430.   set cursor to watch
  431.   get randomizeTree(treeName(), size, 1000)
  432.   if (it Γëá empty) then treeError(it)
  433.   treeDraw
  434. end mouseUp
  435.  
  436. function randomizeTree tree, size, max
  437. get treeClear(tree)
  438. if (it Γëá empty) then return it
  439. put empty into list
  440. repeat with i=1 to size
  441.   put random(max) & "," after list
  442. end repeat
  443. get btree(insert, tree, list, empty, ",")
  444. return empty
  445. end randomizeTree
  446.  
  447.  
  448.  
  449.  
  450. -- part 4 (button)
  451. -- low flags: 00
  452. -- high flags: 8003
  453. -- rect: left=245 top=8 right=30 bottom=345
  454. -- title width / last selected line: 0
  455. -- icon id / first selected line: 0 / 0
  456. -- text alignment: 1
  457. -- font id: 0
  458. -- text size: 12
  459. -- style flags: 0
  460. -- line height: 16
  461. -- part name: Complete Tree
  462. ----- HyperTalk script -----
  463. on mouseUp
  464.  
  465.   -- get height of tree from user
  466.   put -1 into height
  467.   repeat until ((0 Γëñ height) and (height Γëñ 7))
  468.     ask "Enter height of tree (0-7): " with 4
  469.     put it into height
  470.     if (height = empty) then exit mouseUp
  471.   end repeat
  472.  
  473.   -- build the tree
  474.   set cursor to watch
  475.   get buildCompleteTree(treeName(), height)
  476.   if (it Γëá empty) then treeError(it)
  477.  
  478.   treeDraw
  479. end mouseUp
  480.  
  481. function buildCompleteTree tree, height
  482. global completed_tree
  483.  
  484. -- create the tree
  485. get treeClear(tree)
  486. if (it Γëá empty) then return it
  487.  
  488. -- build a list of items to insert into tree
  489. put empty into completed_tree
  490. completeTree 2^height, 1, height
  491.  
  492. -- insert into tree
  493. get btree(insert, tree, completed_tree, empty, ",")
  494. return it
  495. end buildCompleteTree
  496.  
  497. ----------------------------------------------------------------------
  498. -- Recursively build a list of items so that when inserted into
  499. -- a tree it will be a complete tree.
  500. -- Parameters:
  501. --   node  Value to place at root node
  502. --   index Index to root node (should initially be 1)
  503. --   height Height of tree
  504. -- For instance, to build a tree with 15 items use:
  505. --  completeTree 8, 1, 4
  506. ----------------------------------------------------------------------
  507. on completeTree node, index, height
  508.   global completed_tree
  509.   put node into item index of completed_tree
  510.   if (height > 0) then
  511.     completeTree node-(2^(height-1)), 2*index, height-1
  512.     completeTree node+(2^(height-1)), 2*index+1, height-1
  513.   end if
  514. end completeTree
  515.  
  516.  
  517.  
  518. -- part 6 (button)
  519. -- low flags: 00
  520. -- high flags: 8003
  521. -- rect: left=13 top=7 right=29 bottom=113
  522. -- title width / last selected line: 0
  523. -- icon id / first selected line: 0 / 0
  524. -- text alignment: 1
  525. -- font id: 0
  526. -- text size: 12
  527. -- style flags: 0
  528. -- line height: 16
  529. -- part name: Draw Tree
  530. ----- HyperTalk script -----
  531. on mouseUp
  532.   treeDraw draw
  533. end mouseUp
  534.  
  535.  
  536.  
  537.  
  538.  
  539. -- part 8 (button)
  540. -- low flags: 00
  541. -- high flags: 8003
  542. -- rect: left=358 top=8 right=30 bottom=458
  543. -- title width / last selected line: 0
  544. -- icon id / first selected line: 0 / 0
  545. -- text alignment: 1
  546. -- font id: 0
  547. -- text size: 12
  548. -- style flags: 0
  549. -- line height: 16
  550. -- part name: Father William
  551. ----- HyperTalk script -----
  552. on mouseUp
  553.   -- build a tree containing text from the poem "Father William"
  554.   -- by Lewis Carroll
  555.   set cursor to watch
  556.   setTreeDirty
  557.   get btree(dispose, treeName())
  558.   get btree(new, treeName())
  559.   put "You are old Father William the young man said And your hair has become very white And yet you incessantly stand on your head Do you think at your age it is right" into keys
  560.   put "In my youth Father William replied to his son I feared it might injure the brain But now that I'm perfectly sure I have none Why I do it again and again" into data
  561.   get btree(insert, treeName(), keys, data, space)
  562.  
  563.   treeDraw
  564. end mouseUp
  565.  
  566.  
  567.  
  568. -- part 9 (field)
  569. -- low flags: 01
  570. -- high flags: 0000
  571. -- rect: left=1 top=35 right=202 bottom=510
  572. -- title width / last selected line: 0
  573. -- icon id / first selected line: 0 / 0
  574. -- text alignment: 0
  575. -- font id: 3
  576. -- text size: 12
  577. -- style flags: 0
  578. -- line height: 16
  579. -- part name: DrawingArea
  580.  
  581.  
  582. -- part 14 (field)
  583. -- low flags: 01
  584. -- high flags: 0004
  585. -- rect: left=88 top=294 right=314 bottom=484
  586. -- title width / last selected line: 0
  587. -- icon id / first selected line: 0 / 0
  588. -- text alignment: 0
  589. -- font id: 0
  590. -- text size: 12
  591. -- style flags: 0
  592. -- line height: 16
  593. -- part name: Progress
  594.  
  595.  
  596. -- part 18 (field)
  597. -- low flags: 01
  598. -- high flags: 0007
  599. -- rect: left=11 top=205 right=291 bottom=509
  600. -- title width / last selected line: 0
  601. -- icon id / first selected line: 0 / 0
  602. -- text alignment: 0
  603. -- font id: 3
  604. -- text size: 10
  605. -- style flags: 0
  606. -- line height: 13
  607. -- part name: Commands
  608. ----- HyperTalk script -----
  609. on enterInField
  610.   set cursor to watch
  611.   executeField
  612. end enterInField
  613.  
  614. on returnInField
  615.   if the commandKey is down then send enterInField
  616.   else pass returnInField
  617. end returnInField
  618.  
  619. -------------------------------------------------------------------
  620. -- Execute the selected lines in the field
  621. -------------------------------------------------------------------
  622. on executeField
  623.   put (word 2 of selectedLine())-1 into firstLine
  624.   put selectedChunk() into saveChunk
  625.   put selectedText() into commands
  626.   if (commands = empty) then put value(selectedLine()) into commands
  627.   repeat with i=1 to number(lines of commands)
  628.     select line i+firstLine of cd fld "Commands"
  629.     do line i of commands
  630.   end repeat
  631.   select saveChunk
  632. end executeField
  633.  
  634.  
  635.  
  636.  
  637. -- part 19 (field)
  638. -- low flags: 01
  639. -- high flags: 0000
  640. -- rect: left=36 top=294 right=312 bottom=135
  641. -- title width / last selected line: 0
  642. -- icon id / first selected line: 0 / 0
  643. -- text alignment: 0
  644. -- font id: 3
  645. -- text size: 12
  646. -- style flags: 0
  647. -- line height: 16
  648. -- part name: 
  649.  
  650.  
  651. -- part contents for background part 9
  652. ----- text -----
  653. DemoStack 0.9
  654.  
  655. -- part contents for background part 1
  656. ----- text -----
  657. Draw Tree
  658.  
  659. -- part contents for background part 12
  660. ----- text -----
  661. Card #10
  662.  
  663. -- part contents for background part 14
  664. ----- text -----
  665.  
  666.  
  667.  
  668.  
  669.  
  670.  
  671.  
  672.  
  673.  
  674.  
  675.  
  676. -- part contents for card part 14
  677. ----- text -----
  678. Finished Drawing Keys.
  679.  
  680. -- part contents for card part 18
  681. ----- text -----
  682. Instructions:
  683. "Draw Tree" draws the demo tree, which should first be configured using one of the other buttons. A dialog box asks what type of data to draw: the keys of the nodes, the data fields of the nodes, or the indexes of the nodes.
  684. "Random Tree" builds and draws a tree containing random integers.
  685. "Complete Tree" builds and draws a tree containing all of its nodes.
  686. "Father William" builds and draws a tree containing part of the poem "Father William" by Lewis Carroll.
  687.  
  688. -- part contents for card part 19
  689. ----- text -----
  690. Status: