ifmapper 1.0.0 → 1.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (218) hide show
  1. data/HISTORY.txt +648 -627
  2. data/IFMapper.gemspec +29 -28
  3. data/IFMapper.rbw +31 -31
  4. data/TODO.txt +8 -7
  5. data/bin/IFMapper +31 -31
  6. data/docs/en/index.html +0 -0
  7. data/docs/en/start.html +3 -2
  8. data/docs/en/start.html~ +516 -0
  9. data/docs/es/index.html +0 -0
  10. data/docs/es/start.html +13 -14
  11. data/docs/es/start.html~ +1280 -0
  12. data/docs/images/IFMapper_main.gif +0 -0
  13. data/docs/images/automap.gif +0 -0
  14. data/docs/images/complex_connection.gif +0 -0
  15. data/docs/images/connection.gif +0 -0
  16. data/docs/images/connection_menu.gif +0 -0
  17. data/docs/images/room_description.gif +0 -0
  18. data/docs/images/room_small.gif +0 -0
  19. data/icons/copy.png +0 -0
  20. data/icons/cut.png +0 -0
  21. data/icons/filenew.png +0 -0
  22. data/icons/fileopen.png +0 -0
  23. data/icons/filesave.png +0 -0
  24. data/icons/filesaveas.png +0 -0
  25. data/icons/help.png +0 -0
  26. data/icons/kill.png +0 -0
  27. data/icons/nextpage.png +0 -0
  28. data/icons/paste.png +0 -0
  29. data/icons/prevpage.png +0 -0
  30. data/icons/printicon.png +0 -0
  31. data/icons/redo.png +0 -0
  32. data/icons/room_e.gif +0 -0
  33. data/icons/room_e.xpm +0 -0
  34. data/icons/room_n.gif +0 -0
  35. data/icons/room_n.xpm +0 -0
  36. data/icons/room_ne.gif +0 -0
  37. data/icons/room_ne.xpm +0 -0
  38. data/icons/room_nw.gif +0 -0
  39. data/icons/room_nw.xpm +0 -0
  40. data/icons/room_s.gif +0 -0
  41. data/icons/room_s.xpm +0 -0
  42. data/icons/room_se.gif +0 -0
  43. data/icons/room_se.xpm +0 -0
  44. data/icons/room_sw.gif +0 -0
  45. data/icons/room_sw.xpm +0 -0
  46. data/icons/room_w.gif +0 -0
  47. data/icons/room_w.xpm +0 -0
  48. data/icons/saveas.png +0 -0
  49. data/icons/undo.png +0 -0
  50. data/icons/winapp.png +0 -0
  51. data/icons/zoom.png +0 -0
  52. data/lib/IFMapper/AStar.rb +250 -250
  53. data/lib/IFMapper/Connection.rb +202 -202
  54. data/lib/IFMapper/FXAboutDialogBox.rb +32 -32
  55. data/lib/IFMapper/FXConnection.rb +364 -364
  56. data/lib/IFMapper/FXConnectionDialogBox.rb +124 -124
  57. data/lib/IFMapper/FXDCPostscript.rb +404 -404
  58. data/lib/IFMapper/FXDCPrint.rb +15 -15
  59. data/lib/IFMapper/FXItemList.rb +108 -0
  60. data/lib/IFMapper/FXMap.rb +2147 -2116
  61. data/lib/IFMapper/FXMapColorBox.rb +88 -88
  62. data/lib/IFMapper/FXMapDialogBox.rb +127 -127
  63. data/lib/IFMapper/FXMapFileDialog.rb +34 -34
  64. data/lib/IFMapper/FXMapperSettings.rb +206 -205
  65. data/lib/IFMapper/FXMapperWindow.rb +1592 -1571
  66. data/lib/IFMapper/FXPDFMapExporterOptionsDialogBox.rb +46 -0
  67. data/lib/IFMapper/FXRoom.rb +263 -263
  68. data/lib/IFMapper/FXRoomDialogBox.rb +159 -159
  69. data/lib/IFMapper/FXRoomList.rb +95 -95
  70. data/lib/IFMapper/FXSearchDialogBox.rb +51 -51
  71. data/lib/IFMapper/FXSection.rb +33 -33
  72. data/lib/IFMapper/FXSectionDialogBox.rb +38 -38
  73. data/lib/IFMapper/FXSpline.rb +52 -52
  74. data/lib/IFMapper/FXWarningBox.rb +51 -50
  75. data/lib/IFMapper/GUEReader.rb +445 -445
  76. data/lib/IFMapper/IFMReader.rb +584 -584
  77. data/lib/IFMapper/IFMWriter.rb +245 -227
  78. data/lib/IFMapper/Inform7Writer.rb +579 -573
  79. data/lib/IFMapper/InformReader.rb +478 -478
  80. data/lib/IFMapper/InformWriter.rb +364 -359
  81. data/lib/IFMapper/Map.rb +202 -200
  82. data/lib/IFMapper/MapPrinting.rb +162 -162
  83. data/lib/IFMapper/MapReader.rb +900 -900
  84. data/lib/IFMapper/PDFMapExporter.rb +526 -483
  85. data/lib/IFMapper/Room.rb +153 -151
  86. data/lib/IFMapper/Section.rb +234 -234
  87. data/lib/IFMapper/TADSReader.rb +474 -471
  88. data/lib/IFMapper/TADSWriter.rb +375 -370
  89. data/lib/IFMapper/TranscriptDialogBox.rb +0 -0
  90. data/lib/IFMapper/TranscriptReader.rb +1361 -1359
  91. data/lib/IFMapper/locales/en/Messages.rb +446 -435
  92. data/lib/IFMapper/locales/es/Messages.rb +451 -440
  93. data/lib/IFMapper/locales/es/Messages_iso-8859-1.rb +455 -440
  94. data/lib/IFMapper/locales/es/runme.sh +3 -3
  95. data/maps/A New Life.map b/data/maps/A New → Life.map +0 -0
  96. data/maps/AMFV.map +0 -0
  97. data/maps/AllRoads.map +0 -0
  98. data/maps/Aotearoa.map +0 -0
  99. data/maps/Bronze.map +0 -0
  100. data/maps/Bureaucracy.ifm +0 -0
  101. data/maps/Bureaucracy.map +0 -0
  102. data/maps/CityOfSecrets.map +0 -0
  103. data/maps/DDIV.map +0 -0
  104. data/maps/Following_A_Star.map +0 -0
  105. data/maps/Heated.map +0 -0
  106. data/maps/Heroine.map +0 -0
  107. data/maps/History Repeating.map b/data/maps/History → Repeating.map +0 -0
  108. data/maps/Hollywood_Hijinx.ifm +0 -0
  109. data/maps/Janitor.map +0 -0
  110. data/maps/Jigsaw.ifm +0 -0
  111. data/maps/Jigsaw.map +0 -0
  112. data/maps/LGOP.ifm +0 -0
  113. data/maps/Mercy.ifm +0 -0
  114. data/maps/Ninjas_Fate.map +0 -0
  115. data/maps/Pen_and_Paint.map +0 -0
  116. data/maps/Planetfall.ifm +0 -0
  117. data/maps/Planetfall.map +0 -0
  118. data/maps/Plundered_Hearts.ifm +0 -0
  119. data/maps/QuietEvening.map +0 -0
  120. data/maps/Ralph.ifm +0 -0
  121. data/maps/Reliques_of_Tolti_Alph.map +0 -0
  122. data/maps/Revolution.map +0 -0
  123. data/maps/Robots_of_Dawn.ifm +0 -0
  124. data/maps/SavoirFare.map +0 -0
  125. data/maps/Seastalker.ifm +0 -0
  126. data/maps/Seastalker.map +0 -0
  127. data/maps/Sherlock.ifm +0 -0
  128. data/maps/SoFar.ifm +0 -0
  129. data/maps/Starcross.ifm +0 -0
  130. data/maps/Suspended.ifm +0 -0
  131. data/maps/Tangle.map +0 -0
  132. data/maps/The_Lost_Sheep.map +0 -0
  133. data/maps/Unforgotten.map +0 -0
  134. data/maps/Warbler's Nest.map +0 -0
  135. data/maps/Warbler's_Nest.map +0 -0
  136. data/maps/Westminster_Abbey.map +0 -0
  137. data/maps/WinterWonderland.map +0 -0
  138. data/maps/Wishbringer.ifm +0 -0
  139. data/maps/Wishbringer2.ifm +0 -0
  140. data/maps/Zork1.ifm +0 -0
  141. data/maps/Zork2.ifm +0 -0
  142. data/maps/Zork3.ifm +0 -0
  143. data/maps/Zork_Zero.ifm +0 -0
  144. data/maps/anchor.ifm +0 -0
  145. data/maps/anchor.map +0 -0
  146. data/maps/atrox.ifm +0 -0
  147. data/maps/awaken.ifm +0 -0
  148. data/maps/babel.ifm +0 -0
  149. data/maps/balances.map +0 -0
  150. data/maps/ballerina.map +0 -0
  151. data/maps/bear.map +0 -0
  152. data/maps/bluechairs.map +0 -0
  153. data/maps/break_in.map +0 -0
  154. data/maps/bse.ifm +0 -0
  155. data/maps/building.map +0 -0
  156. data/maps/change.ifm +0 -0
  157. data/maps/christminster.map +0 -0
  158. data/maps/curses.ifm +0 -0
  159. data/maps/curves.ifm +0 -0
  160. data/maps/deadline.map +0 -0
  161. data/maps/delusions.map +0 -0
  162. data/maps/devours.map +0 -0
  163. data/maps/distress.map +0 -0
  164. data/maps/djinni.map +0 -0
  165. data/maps/dreamhold.map +0 -0
  166. data/maps/drift3.map +0 -0
  167. data/maps/eas.map +0 -0
  168. data/maps/eas2.map +0 -0
  169. data/maps/eas3.map +0 -0
  170. data/maps/edifice.ifm +0 -0
  171. data/maps/fallacy.map +0 -0
  172. data/maps/frozen.ifm +0 -0
  173. data/maps/gamlet.map +0 -0
  174. data/maps/glow.ifm +0 -0
  175. data/maps/guilty_bastards.map +0 -0
  176. data/maps/heist.map +0 -0
  177. data/maps/heroes.map +0 -0
  178. data/maps/inhumane.map +0 -0
  179. data/maps/kaged.map +0 -0
  180. data/maps/library.ifm +0 -0
  181. data/maps/lurkinghorror.map +0 -0
  182. data/maps/metamorphoses.map +0 -0
  183. data/maps/mindelec.ifm +0 -0
  184. data/maps/minster.ifm +0 -0
  185. data/maps/mite.map +0 -0
  186. data/maps/moonmist.map +0 -0
  187. data/maps/muldoon_legacy.map +0 -0
  188. data/maps/muse.ifm +0 -0
  189. data/maps/paperchase.ifm +0 -0
  190. data/maps/party.map +0 -0
  191. data/maps/pawn.map +0 -0
  192. data/maps/photograph.map +0 -0
  193. data/maps/pkgirl.map +0 -0
  194. data/maps/pytho.map +0 -0
  195. data/maps/risorgimento.map +0 -0
  196. data/maps/sherbet.map +0 -0
  197. data/maps/simple.map +0 -0
  198. data/maps/slouch.map +0 -0
  199. data/maps/space_st.ifm +0 -0
  200. data/maps/splashdown.map +0 -0
  201. data/maps/spring.map +0 -0
  202. data/maps/squarecircle.map +0 -0
  203. data/maps/stationfall.ifm +0 -0
  204. data/maps/theatre.ifm +0 -0
  205. data/maps/toonesia.ifm +0 -0
  206. data/maps/tortoise.ifm +0 -0
  207. data/maps/trinity.map +0 -0
  208. data/maps/vespers.map +0 -0
  209. data/maps/vgame.ifm +0 -0
  210. data/maps/wasp.map +0 -0
  211. data/maps/weather.ifm +0 -0
  212. data/maps/windhall.ifm +0 -0
  213. data/maps/worlds.map +0 -0
  214. data/maps/xtcontest.map +0 -0
  215. data/maps/zdungeon.map +0 -0
  216. data/maps/zebulon.ifm +0 -0
  217. data/maps/zerosum.map +0 -0
  218. metadata +226 -183
@@ -1,51 +1,51 @@
1
-
2
- #
3
- # Class used to display a connection dialog box
4
- #
5
- class FXSearchDialogBox < FXDialogBox
6
- attr_accessor :index
7
-
8
- def text=(x)
9
- @search.text = x
10
- @index = 0
11
- end
12
-
13
- def text
14
- return @search.text
15
- end
16
-
17
- def proc=(p)
18
- @search.connect(SEL_CHANGED, p)
19
- @proc = p
20
- end
21
-
22
- def initialize(parent)
23
- decor = DECOR_TITLE|DECOR_BORDER|DECOR_CLOSE
24
- super( parent, '', decor, 40, 200, 0, 0 )
25
- @index = 0
26
- mainFrame = FXVerticalFrame.new(self,
27
- FRAME_SUNKEN|FRAME_THICK|
28
- LAYOUT_FILL_X|LAYOUT_FILL_Y)
29
-
30
- frame = FXHorizontalFrame.new(mainFrame, LAYOUT_SIDE_TOP|LAYOUT_FILL_X)
31
-
32
- FXLabel.new(frame, "Search String: ", nil, 0, LAYOUT_FILL_X)
33
- @search = FXTextField.new(frame, 40, nil, 0, LAYOUT_FILL_ROW)
34
-
35
- frame = FXHorizontalFrame.new(mainFrame, LAYOUT_SIDE_BOTTOM|LAYOUT_FILL_X)
36
- @previous = FXButton.new(frame, "Previous Match")
37
- @previous.connect(SEL_COMMAND) { |sender, sel, e |
38
- @index -= 1 if @index > 0
39
- sender.handle(self, MKUINT(message, SEL_CHANGED), nil)
40
- @proc.call @search, nil, nil if @proc
41
- }
42
- @next = FXButton.new(frame, "Next Match")
43
- @next.connect(SEL_COMMAND) { |sender, sel, e |
44
- @index += 1
45
- @proc.call @search, nil, nil if @proc
46
- }
47
-
48
- # We need to create the dialog box first, so we can use select text.
49
- create
50
- end
51
- end
1
+
2
+ #
3
+ # Class used to display a connection dialog box
4
+ #
5
+ class FXSearchDialogBox < FXDialogBox
6
+ attr_accessor :index
7
+
8
+ def text=(x)
9
+ @search.text = x
10
+ @index = 0
11
+ end
12
+
13
+ def text
14
+ return @search.text
15
+ end
16
+
17
+ def proc=(p)
18
+ @search.connect(SEL_CHANGED, p)
19
+ @proc = p
20
+ end
21
+
22
+ def initialize(parent)
23
+ decor = DECOR_TITLE|DECOR_BORDER|DECOR_CLOSE
24
+ super( parent, '', decor, 40, 200, 0, 0 )
25
+ @index = 0
26
+ mainFrame = FXVerticalFrame.new(self,
27
+ FRAME_SUNKEN|FRAME_THICK|
28
+ LAYOUT_FILL_X|LAYOUT_FILL_Y)
29
+
30
+ frame = FXHorizontalFrame.new(mainFrame, LAYOUT_SIDE_TOP|LAYOUT_FILL_X)
31
+
32
+ FXLabel.new(frame, "Search String: ", nil, 0, LAYOUT_FILL_X)
33
+ @search = FXTextField.new(frame, 40, nil, 0, LAYOUT_FILL_ROW)
34
+
35
+ frame = FXHorizontalFrame.new(mainFrame, LAYOUT_SIDE_BOTTOM|LAYOUT_FILL_X)
36
+ @previous = FXButton.new(frame, "Previous Match")
37
+ @previous.connect(SEL_COMMAND) { |sender, sel, e |
38
+ @index -= 1 if @index > 0
39
+ sender.handle(self, MKUINT(message, SEL_CHANGED), nil)
40
+ @proc.call @search, nil, nil if @proc
41
+ }
42
+ @next = FXButton.new(frame, "Next Match")
43
+ @next.connect(SEL_COMMAND) { |sender, sel, e |
44
+ @index += 1
45
+ @proc.call @search, nil, nil if @proc
46
+ }
47
+
48
+ # We need to create the dialog box first, so we can use select text.
49
+ create
50
+ end
51
+ end
@@ -1,33 +1,33 @@
1
-
2
- require 'IFMapper/FXConnection'
3
- require 'IFMapper/FXRoom'
4
- require 'IFMapper/Section'
5
-
6
- class FXSection < Section
7
- def new_connection( roomA, exitA, roomB, exitB = nil )
8
- # Verify rooms exist in section (ie. don't allow links across
9
- # sections)
10
- if not @rooms.include?(roomA)
11
- raise ConnectionError, "Room #{roomA} not in section #{self}"
12
- end
13
- if roomB and not @rooms.include?(roomB)
14
- raise ConnectionError, "Room #{roomB} not in section #{self}"
15
- end
16
-
17
- c = FXConnection.new( roomA, roomB )
18
- return _new_connection(c, roomA, exitA, roomB, exitB)
19
- end
20
-
21
- def new_room(x, y)
22
- r = FXRoom.new( x, y, MSG_NEW_LOCATION )
23
- return _new_room(r, x, y)
24
- end
25
-
26
- def properties(map)
27
- if not @win
28
- @win = FXSectionDialogBox.new(map)
29
- end
30
- @win.copy_from(self)
31
- @win.show
32
- end
33
- end
1
+
2
+ require 'IFMapper/FXConnection'
3
+ require 'IFMapper/FXRoom'
4
+ require 'IFMapper/Section'
5
+
6
+ class FXSection < Section
7
+ def new_connection( roomA, exitA, roomB, exitB = nil )
8
+ # Verify rooms exist in section (ie. don't allow links across
9
+ # sections)
10
+ if not @rooms.include?(roomA)
11
+ raise ConnectionError, "Room #{roomA} not in section #{self}"
12
+ end
13
+ if roomB and not @rooms.include?(roomB)
14
+ raise ConnectionError, "Room #{roomB} not in section #{self}"
15
+ end
16
+
17
+ c = FXConnection.new( roomA, roomB )
18
+ return _new_connection(c, roomA, exitA, roomB, exitB)
19
+ end
20
+
21
+ def new_room(x, y)
22
+ r = FXRoom.new( x, y, MSG_NEW_LOCATION )
23
+ return _new_room(r, x, y)
24
+ end
25
+
26
+ def properties(map)
27
+ if not @win
28
+ @win = FXSectionDialogBox.new(map)
29
+ end
30
+ @win.copy_from(self)
31
+ @win.show
32
+ end
33
+ end
@@ -1,38 +1,38 @@
1
-
2
-
3
- class FXSectionDialogBox < FXDialogBox
4
-
5
- def copy_to()
6
- @section.name = @name.text
7
- @map.update_title
8
- end
9
-
10
- def copy_from(section)
11
- @name.text = section.name.to_s
12
- @section = section
13
- end
14
-
15
- def initialize(map)
16
- decor = DECOR_TITLE|DECOR_BORDER|DECOR_CLOSE
17
-
18
- super( map.window, "Section Information", decor, 40, 40, 0, 0 )
19
- mainFrame = FXVerticalFrame.new(self,
20
- FRAME_SUNKEN|FRAME_THICK|
21
- LAYOUT_FILL_X|LAYOUT_FILL_Y)
22
-
23
- frame = FXHorizontalFrame.new(mainFrame, LAYOUT_SIDE_TOP|LAYOUT_FILL_X)
24
-
25
- FXLabel.new(frame, "Name: ", nil, 0, LAYOUT_FILL_X)
26
- @name = FXTextField.new(frame, 40, nil, 0, LAYOUT_FILL_ROW)
27
-
28
- frame = FXVerticalFrame.new(mainFrame,
29
- LAYOUT_SIDE_TOP|LAYOUT_FILL_X|LAYOUT_FILL_Y)
30
-
31
-
32
- @name.connect(SEL_CHANGED) { copy_to() }
33
- @map = map
34
-
35
- # We need to create the dialog box first, so we can use select text.
36
- create
37
- end
38
- end
1
+
2
+
3
+ class FXSectionDialogBox < FXDialogBox
4
+
5
+ def copy_to()
6
+ @section.name = @name.text
7
+ @map.update_title
8
+ end
9
+
10
+ def copy_from(section)
11
+ @name.text = section.name.to_s
12
+ @section = section
13
+ end
14
+
15
+ def initialize(map)
16
+ decor = DECOR_TITLE|DECOR_BORDER|DECOR_CLOSE
17
+
18
+ super( map.window, "Section Information", decor, 40, 40, 0, 0 )
19
+ mainFrame = FXVerticalFrame.new(self,
20
+ FRAME_SUNKEN|FRAME_THICK|
21
+ LAYOUT_FILL_X|LAYOUT_FILL_Y)
22
+
23
+ frame = FXHorizontalFrame.new(mainFrame, LAYOUT_SIDE_TOP|LAYOUT_FILL_X)
24
+
25
+ FXLabel.new(frame, "Name: ", nil, 0, LAYOUT_FILL_X)
26
+ @name = FXTextField.new(frame, 40, nil, 0, LAYOUT_FILL_ROW)
27
+
28
+ frame = FXVerticalFrame.new(mainFrame,
29
+ LAYOUT_SIDE_TOP|LAYOUT_FILL_X|LAYOUT_FILL_Y)
30
+
31
+
32
+ @name.connect(SEL_CHANGED) { copy_to() }
33
+ @map = map
34
+
35
+ # We need to create the dialog box first, so we can use select text.
36
+ create
37
+ end
38
+ end
@@ -1,52 +1,52 @@
1
-
2
-
3
- #
4
- # Class used to evaluate a bspline.
5
- #
6
- class FXSpline
7
- OS = 1.0 / 6.0
8
- FS = 4.0 / 6.0
9
- def self.bspline_solve( r, p, num )
10
- ax = -OS * p[0][0] + 0.5 * p[1][0] - 0.5 * p[2][0] + OS * p[3][0]
11
- bx = 0.5 * p[0][0] - p[1][0] + 0.5 * p[2][0]
12
- cx = -0.5 * p[0][0] + 0.5 * p[2][0]
13
- dx = OS * p[0][0] + FS * p[1][0] + OS * p[2][0]
14
-
15
- ay = -OS * p[0][1] + 0.5 * p[1][1] - 0.5 * p[2][1] + OS * p[3][1]
16
- by = 0.5 * p[0][1] - p[1][1] + 0.5 * p[2][1]
17
- cy = -0.5 * p[0][1] + 0.5 * p[2][1]
18
- dy = OS * p[0][1] + FS * p[1][1] + OS * p[2][1]
19
-
20
- t = 0.0
21
- tinc = 1.0 / num
22
- 0.upto(num) {
23
- x = t * (t * (t * ax + bx) + cx) + dx
24
- y = t * (t * (t * ay + by) + cy) + dy
25
- r << [ x, y ]
26
- t += tinc
27
- }
28
- end
29
-
30
- def self.bspline(p)
31
- pts = []
32
- 0.upto(p.size-4) { |x|
33
- x2 = p[x+2][0] - p[x+1][0]
34
- x2 = x2 * x2
35
- y2 = p[x+2][1] - p[x+1][1]
36
- y2 = y2 * y2
37
- num = Math.sqrt( x2 + y2 ).to_i / 16
38
- bspline_solve(pts, p[x..x+3], num)
39
- }
40
- return pts
41
- end
42
- end
43
-
44
- class FXDC
45
- # Draw a bspline curve of any number of segments
46
- def drawBSpline(p)
47
- tmp = FXSpline::bspline(p)
48
- pts = tmp.collect { |x| FXPoint.new( x[0].to_i, x[1].to_i) }
49
- drawLines(pts)
50
- return pts
51
- end
52
- end
1
+
2
+
3
+ #
4
+ # Class used to evaluate a bspline.
5
+ #
6
+ class FXSpline
7
+ OS = 1.0 / 6.0
8
+ FS = 4.0 / 6.0
9
+ def self.bspline_solve( r, p, num )
10
+ ax = -OS * p[0][0] + 0.5 * p[1][0] - 0.5 * p[2][0] + OS * p[3][0]
11
+ bx = 0.5 * p[0][0] - p[1][0] + 0.5 * p[2][0]
12
+ cx = -0.5 * p[0][0] + 0.5 * p[2][0]
13
+ dx = OS * p[0][0] + FS * p[1][0] + OS * p[2][0]
14
+
15
+ ay = -OS * p[0][1] + 0.5 * p[1][1] - 0.5 * p[2][1] + OS * p[3][1]
16
+ by = 0.5 * p[0][1] - p[1][1] + 0.5 * p[2][1]
17
+ cy = -0.5 * p[0][1] + 0.5 * p[2][1]
18
+ dy = OS * p[0][1] + FS * p[1][1] + OS * p[2][1]
19
+
20
+ t = 0.0
21
+ tinc = 1.0 / num
22
+ 0.upto(num) {
23
+ x = t * (t * (t * ax + bx) + cx) + dx
24
+ y = t * (t * (t * ay + by) + cy) + dy
25
+ r << [ x, y ]
26
+ t += tinc
27
+ }
28
+ end
29
+
30
+ def self.bspline(p)
31
+ pts = []
32
+ 0.upto(p.size-4) { |x|
33
+ x2 = p[x+2][0] - p[x+1][0]
34
+ x2 = x2 * x2
35
+ y2 = p[x+2][1] - p[x+1][1]
36
+ y2 = y2 * y2
37
+ num = Math.sqrt( x2 + y2 ).to_i / 16
38
+ bspline_solve(pts, p[x..x+3], num)
39
+ }
40
+ return pts
41
+ end
42
+ end
43
+
44
+ class FXDC
45
+ # Draw a bspline curve of any number of segments
46
+ def drawBSpline(p)
47
+ tmp = FXSpline::bspline(p)
48
+ pts = tmp.collect { |x| FXPoint.new( x[0].to_i, x[1].to_i) }
49
+ drawLines(pts)
50
+ return pts
51
+ end
52
+ end
@@ -1,50 +1,51 @@
1
-
2
-
3
- class FXWarningBox < FXDialogBox
4
- def initialize(parent, text)
5
- super( parent, "Warning", DECOR_ALL, 0, 0, 400, 130)
6
- # Frame
7
- s = FXVerticalFrame.new(self,
8
- LAYOUT_SIDE_TOP|LAYOUT_FILL_X)
9
-
10
- f = FXHorizontalFrame.new(s, LAYOUT_SIDE_TOP|LAYOUT_FILL_X|LAYOUT_FILL_Y)
11
-
12
- font = FXFont.new(app, "Helvetica", 30)
13
- oops = FXLabel.new(f, "!", nil, 0, LAYOUT_SIDE_LEFT|LAYOUT_FILL_X|
14
- LAYOUT_CENTER_Y)
15
- oops.frameStyle = FRAME_RAISED|FRAME_THICK
16
- oops.baseColor = 'dark grey'
17
- oops.textColor = 'red'
18
- oops.padLeft = oops.padRight = 15
19
- oops.shadowColor = 'black'
20
- oops.borderColor = 'white'
21
- oops.font = font
22
-
23
- t = FXText.new(f)
24
- t.text = text
25
- t.visibleRows = 4
26
- t.visibleColumns = 80
27
- t.backColor = f.backColor
28
- t.disable
29
-
30
- # Separator
31
- FXHorizontalSeparator.new(s,
32
- LAYOUT_SIDE_TOP|LAYOUT_FILL_X|SEPARATOR_GROOVE)
33
-
34
- # Bottom buttons
35
- buttons = FXHorizontalFrame.new(s,
36
- LAYOUT_SIDE_BOTTOM|FRAME_NONE|
37
- LAYOUT_FILL_X|PACK_UNIFORM_WIDTH)
38
- # Accept
39
- yes = FXButton.new(buttons, "&Yes", nil, self, FXDialogBox::ID_ACCEPT,
40
- FRAME_RAISED|FRAME_THICK|LAYOUT_FILL_X|
41
- LAYOUT_RIGHT|LAYOUT_CENTER_Y)
42
-
43
- # Cancel
44
- no = FXButton.new(buttons, "&No", nil, self, FXDialogBox::ID_CANCEL,
45
- FRAME_RAISED|FRAME_THICK|LAYOUT_FILL_X|
46
- LAYOUT_RIGHT|LAYOUT_CENTER_Y)
47
- no.setDefault
48
- no.setFocus
49
- end
50
- end
1
+
2
+
3
+ class FXWarningBox < FXDialogBox
4
+ def initialize(parent, text)
5
+ super( parent, "Warning", DECOR_ALL, 0, 0, 400, 130)
6
+ # Frame
7
+ s = FXVerticalFrame.new(self,
8
+ LAYOUT_SIDE_TOP|LAYOUT_FILL_X)
9
+
10
+ f = FXHorizontalFrame.new(s, LAYOUT_SIDE_TOP|LAYOUT_FILL_X|LAYOUT_FILL_Y)
11
+
12
+ font = FXFont.new(app, "Helvetica", 30)
13
+ oops = FXLabel.new(f, "!", nil, 0, LAYOUT_SIDE_LEFT|LAYOUT_FILL_X|
14
+ LAYOUT_CENTER_Y)
15
+ oops.frameStyle = FRAME_RAISED|FRAME_THICK
16
+ oops.baseColor = 'dark grey'
17
+ oops.textColor = 'red'
18
+ oops.padLeft = oops.padRight = 15
19
+ oops.shadowColor = 'black'
20
+ oops.borderColor = 'white'
21
+ oops.font = font
22
+
23
+ t = FXText.new(f)
24
+ t.text = text
25
+ t.visibleRows = 4
26
+ t.visibleColumns = 80
27
+ t.backColor = f.backColor
28
+ t.disable
29
+
30
+ # Separator
31
+ FXHorizontalSeparator.new(s,
32
+ LAYOUT_SIDE_TOP|LAYOUT_FILL_X|SEPARATOR_GROOVE)
33
+
34
+ # Bottom buttons
35
+ buttons = FXHorizontalFrame.new(s,
36
+ LAYOUT_SIDE_BOTTOM|FRAME_NONE|
37
+ LAYOUT_FILL_X|PACK_UNIFORM_WIDTH)
38
+ # Accept
39
+ yes = FXButton.new(buttons, "&Yes", nil, self, FXDialogBox::ID_ACCEPT,
40
+ FRAME_RAISED|FRAME_THICK|LAYOUT_FILL_X|
41
+ LAYOUT_RIGHT|LAYOUT_CENTER_Y)
42
+
43
+ # Cancel
44
+ no = FXButton.new(buttons, "&No", nil, self, FXDialogBox::ID_CANCEL,
45
+ FRAME_RAISED|FRAME_THICK|LAYOUT_FILL_X|
46
+ LAYOUT_RIGHT|LAYOUT_CENTER_Y)
47
+ no.setDefault
48
+ no.setFocus
49
+ end
50
+ end
51
+