ifmapper 1.0.0 → 1.0.6

Sign up to get free protection for your applications and to get access to all the features.
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
@@ -0,0 +1,46 @@
1
+ class FXPDFMapExporterOptionsDialogBox < FXDialogBox
2
+
3
+ attr_accessor :pdfpapersize # Map options
4
+
5
+ def initialize(parent, title, map)
6
+
7
+ decor = DECOR_TITLE|DECOR_BORDER|DECOR_CLOSE
8
+
9
+ super( parent, title, decor, 40, 40, 0, 0 )
10
+ mainFrame = FXVerticalFrame.new(self,
11
+ FRAME_SUNKEN|FRAME_THICK|
12
+ LAYOUT_FILL_X|LAYOUT_FILL_Y)
13
+
14
+ frame = FXHorizontalFrame.new(mainFrame, LAYOUT_SIDE_TOP|LAYOUT_FILL_X)
15
+
16
+ FXLabel.new(frame, BOX_PDF_PAGE_SIZE, nil, 0, LAYOUT_FILL_X)
17
+ pane = FXPopup.new(self)
18
+ BOX_PDF_PAGE_SIZE_TEXT.each { |t|
19
+ FXOption.new(pane, t, nil, nil, 0, JUSTIFY_HZ_APART|ICON_AFTER_TEXT)
20
+ }
21
+ @pagesize = FXOptionMenu.new(frame, pane, FRAME_RAISED|FRAME_THICK|
22
+ JUSTIFY_HZ_APART|ICON_AFTER_TEXT|
23
+ LAYOUT_CENTER_X|LAYOUT_CENTER_Y)
24
+
25
+ @locationnos = FXCheckButton.new(mainFrame, BOX_PDF_LOCATIONNOS, nil, 0,
26
+ ICON_BEFORE_TEXT|LAYOUT_CENTER_X|LAYOUT_SIDE_TOP|
27
+ LAYOUT_SIDE_RIGHT)
28
+ @locationnos.setCheck(true)
29
+
30
+ buttons = FXHorizontalFrame.new(mainFrame,
31
+ LAYOUT_SIDE_BOTTOM|LAYOUT_FILL_X|
32
+ PACK_UNIFORM_WIDTH)
33
+
34
+ require 'IFMapper/PDFMapExporter'
35
+ @pagesize.connect(SEL_COMMAND) { map.pdfpapersize = @pagesize.currentNo }
36
+ @locationnos.connect(SEL_COMMAND) { map.pdflocationnos = @locationnos.checkState }
37
+
38
+ # Accept
39
+ FXButton.new(buttons, "&OK", nil, self, FXDialogBox::ID_ACCEPT,
40
+ FRAME_RAISED|LAYOUT_FILL_X|FRAME_THICK|LAYOUT_RIGHT|LAYOUT_CENTER_Y)
41
+
42
+
43
+ create
44
+
45
+ end
46
+ end
@@ -1,263 +1,263 @@
1
-
2
- require 'IFMapper/Room'
3
- require 'IFMapper/FXRoomDialogBox'
4
-
5
- #
6
- # Class used to reprent an IF room
7
- #
8
- class FXRoom < Room
9
- attr_accessor :xx, :yy
10
- attr_accessor :selected
11
-
12
- @@win = nil
13
-
14
- def self.no_maps
15
- @@win.hide if @@win
16
- end
17
-
18
- def marshal_dump
19
- super + [ @selected ]
20
- end
21
-
22
- def marshal_load(vars)
23
- super(vars)
24
- @selected = vars[-1]
25
- @xx = x * WW + WS_2
26
- @yy = y * HH + HS_2
27
- end
28
-
29
- def initialize(x, y, *opts)
30
- @xx = x * WW + WS_2
31
- @yy = y * HH + HS_2
32
- @selected = false
33
- super(x, y, *opts)
34
- end
35
-
36
- #
37
- # Set a new x position for the room. Value is in grid units.
38
- #
39
- def x=(v)
40
- @x = v
41
- @xx = v * WW + WS_2
42
- end
43
-
44
- #
45
- # Set a new y position for the room. Value is in grid units.
46
- #
47
- def y=(v)
48
- @y = v
49
- @yy = v * HH + HS_2
50
- end
51
-
52
- #
53
- # Set selection. If floating Room Properties window is open, copy
54
- # the room data over to it.
55
- #
56
- def selected=(value)
57
- if value and @@win and @@win.shown?
58
- @@win.copy_from(self)
59
- end
60
- @selected = value
61
- end
62
-
63
- #
64
- # Open a modal requester to change properties
65
- #
66
- def modal_properties(map)
67
- if @@win and @@win.shown?
68
- shown = @@win
69
- @@win.hide
70
- end
71
- win = FXRoomDialogBox.new(map, self, nil, true)
72
- win.setFocus
73
- win.show
74
- win.copy_from(self)
75
- if win.execute != 0
76
- win.copy_to()
77
- else
78
- return false
79
- end
80
- if shown
81
- @@win.show
82
- end
83
- return true
84
- end
85
-
86
- def update_properties(map)
87
- return if not @@win or not @@win.shown?
88
- @@win.map = map
89
- @@win.copy_from(self)
90
- end
91
-
92
- # Open a new requester to change room properties
93
- def properties( map, event = nil )
94
- if not @@win
95
- @@win = FXRoomDialogBox.new(map, self, event, false)
96
- end
97
- @@win.show
98
- update_properties(map)
99
- end
100
-
101
- #
102
- # Given a connection and/or an exit index, return the x and y offset
103
- # multipliers needed from the top corner of the box.
104
- #
105
- def _corner(c, idx)
106
- idx = @exits.index(c) unless idx
107
- raise "corner: #{c} not found in #{self}" unless idx
108
- x = y = 0
109
- case idx
110
- when 0
111
- x = 0.5
112
- when 1
113
- x = 1
114
- when 2
115
- x = 1
116
- y = 0.5
117
- when 3
118
- x = 1
119
- y = 1
120
- when 4
121
- x = 0.5
122
- y = 1
123
- when 5
124
- y = 1
125
- when 6
126
- y = 0.5
127
- when 7
128
- else
129
- raise "error wrong index #{idx}"
130
- end
131
- return [ x, y ]
132
- end
133
-
134
-
135
- # Given a connection belonging to a room, return draw coordinate
136
- # of that corner.
137
- def corner( c, zoom, idx = nil )
138
- x, y = _corner(c, idx)
139
- x = @xx + W * x
140
- y = @yy + H * y
141
- return [x * zoom, y * zoom]
142
- end
143
-
144
-
145
- #
146
- # Main draw function for room
147
- #
148
- def draw(dc, zoom, idx, opt, data)
149
- dc.font = data['objfont']
150
- draw_box(dc, zoom, idx, opt)
151
- return if zoom < 0.5
152
- dc.font = data['font']
153
- x, y = draw_name(dc, zoom)
154
- dc.font = data['objfont']
155
- draw_objects(dc, zoom, x, y)
156
- end
157
-
158
-
159
- protected
160
-
161
- #
162
- # Draw the room index number
163
- #
164
- def draw_index(dc, zoom, idx)
165
- x = (@xx + W - 20 ) * zoom
166
- y = (@yy + HH - HS - 5 ) * zoom
167
- dc.drawText(x, y, (idx + 1).to_s)
168
- end
169
-
170
- #
171
- # Draw the 'room' and 'index' boxes
172
- #
173
- def draw_box(dc, zoom, idx, opt)
174
- if @selected
175
- dc.foreground = 'yellow'
176
- else
177
- if @darkness
178
- dc.foreground = opt['Box Darkness Color']
179
- else
180
- dc.foreground = opt['Box BG Color']
181
- end
182
- end
183
-
184
- x = @xx * zoom
185
- y = @yy * zoom
186
- w = W * zoom
187
- h = H * zoom
188
- dc.fillRectangle(x, y, w, h)
189
-
190
-
191
- dc.foreground = opt['Box Border Color']
192
- dc.lineWidth = 2 * zoom
193
- dc.lineWidth = 2 if dc.lineWidth < 2
194
- dc.lineStyle = LINE_SOLID
195
- dc.drawRectangle(x, y, w, h)
196
-
197
- # Draw grey square for index
198
- if opt['Location Numbers'] and zoom >= 0.5
199
- dc.foreground = opt['Box Number Color']
200
- x += w # Index goes at bottom right of square
201
- y += h
202
- w = WIDX * zoom
203
- h = HIDX * zoom
204
- x -= w
205
- y -= h
206
- dc.fillRectangle(x, y, w, h)
207
-
208
- dc.foreground = opt['Box Border Color']
209
- dc.drawRectangle(x, y, w, h)
210
-
211
- draw_index(dc, zoom, idx)
212
- end
213
- end
214
-
215
- #
216
- # Draw text line wrapping after certain length (in chars)
217
- #
218
- def draw_text_wrap(dc, x, y, zoom, maxLen, text)
219
- return if y > (@yy + H) * zoom
220
- if text.size > maxLen
221
- str = text
222
- fh = dc.font.getFontHeight
223
- while str and str.size > maxLen
224
- idx = str.rindex(/[ -]/, maxLen)
225
- unless idx
226
- idx = str.index(/[ -]/, maxLen)
227
- idx = str.size unless idx
228
- end
229
- dc.drawText(x, y, str[0..idx])
230
- str = str[idx+1..-1]
231
- y += fh
232
- str = nil if y > (@yy + H) * zoom
233
- end
234
- dc.drawText(x, y, str) if str
235
- else
236
- dc.drawText(x, y, text)
237
- end
238
- return [x, y]
239
- end
240
-
241
- #
242
- # Draw name of room
243
- #
244
- def draw_name(dc, zoom)
245
- x = (@xx + 5) * zoom
246
- y = (@yy + 15) * zoom
247
- return draw_text_wrap( dc, x, y, zoom, 15, @name )
248
- end
249
-
250
-
251
- #
252
- # Draw the objects as a comma separated list
253
- #
254
- def draw_objects(dc, zoom, x, y)
255
- return if @objects == ''
256
- fh = dc.font.getFontHeight
257
- y += fh
258
- objs = @objects.split("\n")
259
- objs = objs.join(', ')
260
- return draw_text_wrap( dc, x, y, zoom, 23, objs )
261
- end
262
-
263
- end
1
+
2
+ require 'IFMapper/Room'
3
+ require 'IFMapper/FXRoomDialogBox'
4
+
5
+ #
6
+ # Class used to reprent an IF room
7
+ #
8
+ class FXRoom < Room
9
+ attr_accessor :xx, :yy
10
+ attr_reader :selected
11
+
12
+ @@win = nil
13
+
14
+ def self.no_maps
15
+ @@win.hide if @@win
16
+ end
17
+
18
+ def marshal_dump
19
+ super + [ @selected ]
20
+ end
21
+
22
+ def marshal_load(vars)
23
+ super(vars)
24
+ @selected = vars[-1]
25
+ @xx = x * WW + WS_2
26
+ @yy = y * HH + HS_2
27
+ end
28
+
29
+ def initialize(x, y, *opts)
30
+ @xx = x * WW + WS_2
31
+ @yy = y * HH + HS_2
32
+ @selected = false
33
+ super(x, y, *opts)
34
+ end
35
+
36
+ #
37
+ # Set a new x position for the room. Value is in grid units.
38
+ #
39
+ def x=(v)
40
+ @x = v
41
+ @xx = v * WW + WS_2
42
+ end
43
+
44
+ #
45
+ # Set a new y position for the room. Value is in grid units.
46
+ #
47
+ def y=(v)
48
+ @y = v
49
+ @yy = v * HH + HS_2
50
+ end
51
+
52
+ #
53
+ # Set selection. If floating Room Properties window is open, copy
54
+ # the room data over to it.
55
+ #
56
+ def selected=(value)
57
+ if value and @@win and @@win.shown?
58
+ @@win.copy_from(self)
59
+ end
60
+ @selected = value
61
+ end
62
+
63
+ #
64
+ # Open a modal requester to change properties
65
+ #
66
+ def modal_properties(map)
67
+ if @@win and @@win.shown?
68
+ shown = @@win
69
+ @@win.hide
70
+ end
71
+ win = FXRoomDialogBox.new(map, self, nil, true)
72
+ win.setFocus
73
+ win.show
74
+ win.copy_from(self)
75
+ if win.execute != 0
76
+ win.copy_to()
77
+ else
78
+ return false
79
+ end
80
+ if shown
81
+ @@win.show
82
+ end
83
+ return true
84
+ end
85
+
86
+ def update_properties(map)
87
+ return if not @@win or not @@win.shown?
88
+ @@win.map = map
89
+ @@win.copy_from(self)
90
+ end
91
+
92
+ # Open a new requester to change room properties
93
+ def properties( map, event = nil )
94
+ if not @@win
95
+ @@win = FXRoomDialogBox.new(map, self, event, false)
96
+ end
97
+ @@win.show
98
+ update_properties(map)
99
+ end
100
+
101
+ #
102
+ # Given a connection and/or an exit index, return the x and y offset
103
+ # multipliers needed from the top corner of the box.
104
+ #
105
+ def _corner(c, idx)
106
+ idx = @exits.index(c) unless idx
107
+ raise "corner: #{c} not found in #{self}" unless idx
108
+ x = y = 0
109
+ case idx
110
+ when 0
111
+ x = 0.5
112
+ when 1
113
+ x = 1
114
+ when 2
115
+ x = 1
116
+ y = 0.5
117
+ when 3
118
+ x = 1
119
+ y = 1
120
+ when 4
121
+ x = 0.5
122
+ y = 1
123
+ when 5
124
+ y = 1
125
+ when 6
126
+ y = 0.5
127
+ when 7
128
+ else
129
+ raise "error wrong index #{idx}"
130
+ end
131
+ return [ x, y ]
132
+ end
133
+
134
+
135
+ # Given a connection belonging to a room, return draw coordinate
136
+ # of that corner.
137
+ def corner( c, zoom, idx = nil )
138
+ x, y = _corner(c, idx)
139
+ x = @xx + W * x
140
+ y = @yy + H * y
141
+ return [x * zoom, y * zoom]
142
+ end
143
+
144
+
145
+ #
146
+ # Main draw function for room
147
+ #
148
+ def draw(dc, zoom, idx, opt, data)
149
+ dc.font = data['objfont']
150
+ draw_box(dc, zoom, idx, opt)
151
+ return if zoom < 0.5
152
+ dc.font = data['font']
153
+ x, y = draw_name(dc, zoom)
154
+ dc.font = data['objfont']
155
+ draw_objects(dc, zoom, x, y)
156
+ end
157
+
158
+
159
+ protected
160
+
161
+ #
162
+ # Draw the room index number
163
+ #
164
+ def draw_index(dc, zoom, idx)
165
+ x = (@xx + W - 20 ) * zoom
166
+ y = (@yy + HH - HS - 5 ) * zoom
167
+ dc.drawText(x, y, (idx + 1).to_s)
168
+ end
169
+
170
+ #
171
+ # Draw the 'room' and 'index' boxes
172
+ #
173
+ def draw_box(dc, zoom, idx, opt)
174
+ if @selected
175
+ dc.foreground = 'yellow'
176
+ else
177
+ if @darkness
178
+ dc.foreground = opt['Box Darkness Color']
179
+ else
180
+ dc.foreground = opt['Box BG Color']
181
+ end
182
+ end
183
+
184
+ x = @xx * zoom
185
+ y = @yy * zoom
186
+ w = W * zoom
187
+ h = H * zoom
188
+ dc.fillRectangle(x, y, w, h)
189
+
190
+
191
+ dc.foreground = opt['Box Border Color']
192
+ dc.lineWidth = 2 * zoom
193
+ dc.lineWidth = 2 if dc.lineWidth < 2
194
+ dc.lineStyle = LINE_SOLID
195
+ dc.drawRectangle(x, y, w, h)
196
+
197
+ # Draw grey square for index
198
+ if opt['Location Numbers'] and zoom >= 0.5
199
+ dc.foreground = opt['Box Number Color']
200
+ x += w # Index goes at bottom right of square
201
+ y += h
202
+ w = WIDX * zoom
203
+ h = HIDX * zoom
204
+ x -= w
205
+ y -= h
206
+ dc.fillRectangle(x, y, w, h)
207
+
208
+ dc.foreground = opt['Box Border Color']
209
+ dc.drawRectangle(x, y, w, h)
210
+
211
+ draw_index(dc, zoom, idx)
212
+ end
213
+ end
214
+
215
+ #
216
+ # Draw text line wrapping after certain length (in chars)
217
+ #
218
+ def draw_text_wrap(dc, x, y, zoom, maxLen, text)
219
+ return if y > (@yy + H) * zoom
220
+ if text.size > maxLen
221
+ str = text
222
+ fh = dc.font.getFontHeight
223
+ while str and str.size > maxLen
224
+ idx = str.rindex(/[ -]/, maxLen)
225
+ unless idx
226
+ idx = str.index(/[ -]/, maxLen)
227
+ idx = str.size unless idx
228
+ end
229
+ dc.drawText(x, y, str[0..idx])
230
+ str = str[idx+1..-1]
231
+ y += fh
232
+ str = nil if y > (@yy + H) * zoom
233
+ end
234
+ dc.drawText(x, y, str) if str
235
+ else
236
+ dc.drawText(x, y, text)
237
+ end
238
+ return [x, y]
239
+ end
240
+
241
+ #
242
+ # Draw name of room
243
+ #
244
+ def draw_name(dc, zoom)
245
+ x = (@xx + 5) * zoom
246
+ y = (@yy + 15) * zoom
247
+ return draw_text_wrap( dc, x, y, zoom, 15, @name )
248
+ end
249
+
250
+
251
+ #
252
+ # Draw the objects as a comma separated list
253
+ #
254
+ def draw_objects(dc, zoom, x, y)
255
+ return if @objects == ''
256
+ fh = dc.font.getFontHeight
257
+ y += fh
258
+ objs = @objects.split("\n")
259
+ objs = objs.join(', ')
260
+ return draw_text_wrap( dc, x, y, zoom, 23, objs )
261
+ end
262
+
263
+ end