ifmapper 0.6 → 0.7
Sign up to get free protection for your applications and to get access to all the features.
- data/HISTORY.txt +68 -1
- data/IFMapper.gemspec +2 -2
- data/IFMapper.rb +5 -1
- data/lib/IFMapper/AStar.rb +7 -7
- data/lib/IFMapper/Connection.rb +2 -2
- data/lib/IFMapper/FXConnection.rb +7 -4
- data/lib/IFMapper/FXDCPostscript.rb +404 -0
- data/lib/IFMapper/FXDCPrint.rb +15 -0
- data/lib/IFMapper/FXMap.rb +271 -60
- data/lib/IFMapper/FXMapperSettings.rb +26 -7
- data/lib/IFMapper/FXMapperWindow.rb +209 -68
- data/lib/IFMapper/FXRoom.rb +8 -5
- data/lib/IFMapper/IFMReader.rb +4 -3
- data/lib/IFMapper/IFMWriter.rb +219 -0
- data/lib/IFMapper/Map.rb +23 -5
- data/lib/IFMapper/MapPrinting.rb +1 -0
- data/lib/IFMapper/PDFMapExporter.rb +11 -9
- data/lib/IFMapper/Room.rb +13 -9
- data/lib/IFMapper/Section.rb +2 -1
- metadata +17 -14
data/lib/IFMapper/FXMap.rb
CHANGED
@@ -41,13 +41,16 @@ class FXMap < Map
|
|
41
41
|
@@cursor_w = nil
|
42
42
|
@@cursor_nw = nil
|
43
43
|
|
44
|
-
|
44
|
+
|
45
45
|
def _changed
|
46
46
|
create_pathmap
|
47
47
|
update_title
|
48
48
|
draw
|
49
49
|
end
|
50
50
|
|
51
|
+
#
|
52
|
+
# Jump to a certain section #
|
53
|
+
#
|
51
54
|
def section=(x)
|
52
55
|
super
|
53
56
|
@complexConnection = false
|
@@ -57,28 +60,43 @@ class FXMap < Map
|
|
57
60
|
end
|
58
61
|
end
|
59
62
|
|
60
|
-
|
63
|
+
#
|
64
|
+
# Go to previous section (if any)
|
65
|
+
#
|
61
66
|
def previous_section
|
62
67
|
self.section = @section - 1
|
63
68
|
_changed
|
64
69
|
end
|
65
70
|
|
71
|
+
#
|
72
|
+
# Go to next section (if any)
|
73
|
+
#
|
66
74
|
def next_section
|
67
75
|
self.section = @section + 1
|
68
76
|
_changed
|
69
77
|
end
|
70
78
|
|
79
|
+
#
|
80
|
+
# Map has been modified. Update also pathmap.
|
81
|
+
#
|
71
82
|
def modified=(x)
|
72
83
|
@modified = true
|
73
84
|
_changed
|
74
85
|
end
|
75
86
|
|
87
|
+
#
|
88
|
+
# Popup the section properties to allow renaming it
|
89
|
+
#
|
76
90
|
def rename_section
|
77
91
|
@sections[@section].properties(self)
|
78
92
|
modified = true
|
79
93
|
end
|
80
94
|
|
95
|
+
#
|
96
|
+
# Delete current section from map
|
97
|
+
#
|
81
98
|
def delete_section
|
99
|
+
return navigation_warning if @navigation
|
82
100
|
w = FXWarningBox.new(@window, "Are you sure you want to delete this section?")
|
83
101
|
return if w.execute == 0
|
84
102
|
|
@@ -86,7 +104,11 @@ class FXMap < Map
|
|
86
104
|
modified = true
|
87
105
|
end
|
88
106
|
|
89
|
-
|
107
|
+
#
|
108
|
+
# Add a new section to map and make it current
|
109
|
+
#
|
110
|
+
def new_section
|
111
|
+
return navigation_warning if @navigation
|
90
112
|
@sections.push( FXSection.new )
|
91
113
|
@section = @sections.size - 1
|
92
114
|
end
|
@@ -113,6 +135,48 @@ class FXMap < Map
|
|
113
135
|
puts m
|
114
136
|
end
|
115
137
|
|
138
|
+
#
|
139
|
+
# Determine whether a pathmap area from x,y to x+w,y+h is free
|
140
|
+
# of rooms
|
141
|
+
#
|
142
|
+
def _free_area?(x, y, w, h)
|
143
|
+
x.upto(x+w) { |xx|
|
144
|
+
y.upto(x+h) { |yy|
|
145
|
+
return false if @pmap[xx][yy].kind_of?(Room)
|
146
|
+
}
|
147
|
+
}
|
148
|
+
return true
|
149
|
+
end
|
150
|
+
|
151
|
+
#
|
152
|
+
# Given a list of rooms, find an area in the map where we could
|
153
|
+
# place them. If found, return x/y offset so rooms can be moved
|
154
|
+
# there. This is used for pasting rooms.
|
155
|
+
#
|
156
|
+
def find_empty_area(rooms)
|
157
|
+
return nil if rooms.empty?
|
158
|
+
minx = maxx = rooms[0].x
|
159
|
+
miny = maxy = rooms[0].y
|
160
|
+
rooms.each { |r|
|
161
|
+
minx = r.x if r.x < minx
|
162
|
+
maxx = r.x if r.x > maxx
|
163
|
+
miny = r.y if r.y < miny
|
164
|
+
maxy = r.y if r.y > maxy
|
165
|
+
}
|
166
|
+
w = maxx - minx
|
167
|
+
h = maxy - miny
|
168
|
+
|
169
|
+
# Find an area in pathmap that has w x h empty rooms
|
170
|
+
0.upto(@width-1-w) { |x|
|
171
|
+
0.upto(@height-1-h) { |y|
|
172
|
+
if _free_area?(x, y, w, h)
|
173
|
+
return [x - minx, y - miny]
|
174
|
+
end
|
175
|
+
}
|
176
|
+
}
|
177
|
+
return nil
|
178
|
+
end
|
179
|
+
|
116
180
|
#
|
117
181
|
# Reinitialize the pathmap to an empty matrix
|
118
182
|
#
|
@@ -166,8 +230,6 @@ class FXMap < Map
|
|
166
230
|
a = c.roomA
|
167
231
|
b = c.roomB
|
168
232
|
|
169
|
-
# First, check the neighboring starting/ending nodes in grid
|
170
|
-
# are empty. If not, we need to abort and remove path from list.
|
171
233
|
dirA = a.exits.index(c)
|
172
234
|
raise "connection not found #{c} at #{a}" unless dirA
|
173
235
|
|
@@ -231,7 +293,7 @@ class FXMap < Map
|
|
231
293
|
# We succeeded. Get the path
|
232
294
|
c.failed = false
|
233
295
|
c.gpts = aStar.path
|
234
|
-
# Put path in pathmap so subsequent paths will avoid crossing it.
|
296
|
+
# Put path in pathmap so subsequent paths will try to avoid crossing it.
|
235
297
|
c.gpts.each { |p| @pmap[p[0]][p[1]] = c }
|
236
298
|
|
237
299
|
# Okay, we have a valid path.
|
@@ -289,20 +351,14 @@ class FXMap < Map
|
|
289
351
|
end
|
290
352
|
|
291
353
|
#
|
292
|
-
#
|
293
|
-
# in canvas.
|
354
|
+
# Create a new room for the current section
|
294
355
|
#
|
295
|
-
def
|
356
|
+
def new_room(x, y)
|
296
357
|
@modified = true
|
297
|
-
x = x / WW
|
298
|
-
y = y / HH
|
299
358
|
r = @sections[@section].new_room(x, y)
|
300
359
|
@pmap[x][y] = r
|
301
360
|
|
302
|
-
buf = FXMapperWindow::copy_buffer()
|
303
|
-
r.copy(buf) if buf
|
304
361
|
r.selected = true
|
305
|
-
|
306
362
|
|
307
363
|
if @options['Edit on Creation']
|
308
364
|
if not r.modal_properties(self)
|
@@ -311,10 +367,19 @@ class FXMap < Map
|
|
311
367
|
return nil
|
312
368
|
end
|
313
369
|
end
|
314
|
-
|
315
370
|
return r
|
316
371
|
end
|
317
372
|
|
373
|
+
#
|
374
|
+
# Function used to add a new room. x and y are absolute pixel positions
|
375
|
+
# in canvas.
|
376
|
+
#
|
377
|
+
def new_xy_room(x, y)
|
378
|
+
x = x / WW
|
379
|
+
y = y / HH
|
380
|
+
return new_room(x, y)
|
381
|
+
end
|
382
|
+
|
318
383
|
|
319
384
|
# Given a canvas (mouse) x/y position, return:
|
320
385
|
#
|
@@ -360,14 +425,19 @@ class FXMap < Map
|
|
360
425
|
next if not b # Complex connection in progress
|
361
426
|
|
362
427
|
if c.gpts.size > 0
|
363
|
-
|
428
|
+
2.times { |t|
|
429
|
+
if t == 0
|
430
|
+
r = a
|
431
|
+
dir = r.exits.index(c)
|
432
|
+
else
|
433
|
+
r = b
|
434
|
+
dir = r.exits.rindex(c)
|
435
|
+
end
|
364
436
|
next if not r
|
365
|
-
dir = r.exits.index(c)
|
366
437
|
x1, y1 = r.corner(c, 1, dir)
|
367
438
|
v = FXRoom::DIR_TO_VECTOR[dir]
|
368
439
|
x2 = x1 + v[0] * WS
|
369
440
|
y2 = y1 + v[1] * HS
|
370
|
-
|
371
441
|
if x1 == x2
|
372
442
|
x1 -= W / 2
|
373
443
|
x2 += W / 2
|
@@ -376,6 +446,9 @@ class FXMap < Map
|
|
376
446
|
y1 -= H / 2
|
377
447
|
y2 += H / 2
|
378
448
|
end
|
449
|
+
x1, x2 = x2, x1 if x2 < x1
|
450
|
+
y1, y2 = y2, y1 if y2 < y1
|
451
|
+
|
379
452
|
if x >= x1 and x <= x2 and
|
380
453
|
y >= y1 and y < y2
|
381
454
|
return c
|
@@ -401,11 +474,7 @@ class FXMap < Map
|
|
401
474
|
end
|
402
475
|
}
|
403
476
|
|
404
|
-
|
405
|
-
# a complex connection instead.
|
406
|
-
roomA, roomB, a, b = quadrant_to_rooms( exitA, x, y )
|
407
|
-
return roomA if roomA.kind_of?(Connection)
|
408
|
-
return roomB if roomB.kind_of?(Connection)
|
477
|
+
return nil
|
409
478
|
end
|
410
479
|
|
411
480
|
return nil
|
@@ -547,7 +616,8 @@ class FXMap < Map
|
|
547
616
|
roomB = to_room(x2, y2)
|
548
617
|
# Oops, user tried to create rooms where we already
|
549
618
|
# have a complex connection. Don't create anything, then.
|
550
|
-
if roomA.kind_of?(Connection) or
|
619
|
+
if roomA.kind_of?(Connection) or
|
620
|
+
(roomB.kind_of?(Connection) and not @complexConnection)
|
551
621
|
return [roomA, roomB, nil, nil]
|
552
622
|
end
|
553
623
|
|
@@ -563,8 +633,13 @@ class FXMap < Map
|
|
563
633
|
raise "not a connection"
|
564
634
|
end
|
565
635
|
roomA, roomB, a, b = quadrant_to_rooms( exitA, x, y )
|
566
|
-
|
567
|
-
|
636
|
+
unless a and roomA and roomA[exitA] == nil
|
637
|
+
return
|
638
|
+
end
|
639
|
+
_new_complex_connection(roomA, exitA)
|
640
|
+
end
|
641
|
+
|
642
|
+
def _new_complex_connection(roomA, exitA)
|
568
643
|
if @complexConnection.kind_of?(TrueClass)
|
569
644
|
@complexConnection = [roomA, exitA]
|
570
645
|
c = new_connection( roomA, exitA, nil )
|
@@ -662,6 +737,9 @@ class FXMap < Map
|
|
662
737
|
s.normalText = s.text = msg
|
663
738
|
end
|
664
739
|
|
740
|
+
#
|
741
|
+
# Based on x,y coordinate, switch mouse icon shape
|
742
|
+
#
|
665
743
|
def cursor_switch(x, y)
|
666
744
|
if not @options['Use Room Cursor']
|
667
745
|
@canvas.defaultCursor = @@cursor_arrow
|
@@ -726,42 +804,18 @@ class FXMap < Map
|
|
726
804
|
# to cursor position
|
727
805
|
#
|
728
806
|
def mousewheel_cb(sender, sel, event)
|
729
|
-
|
730
|
-
|
731
|
-
x = (event.last_x / @zoom).to_i
|
732
|
-
y = (event.last_y / @zoom).to_i
|
807
|
+
# x = event.last_x / @zoom
|
808
|
+
# y = event.last_y / @zoom
|
733
809
|
case event.code
|
734
810
|
when -120
|
735
811
|
zoom_out
|
736
|
-
# pos[0] -= x / 2
|
737
|
-
# pos[1] -= y / 2
|
738
|
-
pos = [ pos[0] * @zoom, pos[1] * @zoom ]
|
739
|
-
@scrollwindow.setPosition(pos[0], pos[1])
|
740
812
|
when 120
|
741
813
|
zoom_in
|
742
|
-
|
743
|
-
#pos[0] = -x # * @zoom * 2
|
744
|
-
#pos[1] = -y # * @zoom * 2
|
745
|
-
|
746
|
-
# pos = [ pos[0], pos[1] ]
|
747
|
-
# pos = [ pos[0] * @zoom, pos[1] * @zoom ]
|
748
|
-
@scrollwindow.setPosition(pos[0], pos[1])
|
749
814
|
end
|
750
|
-
# x
|
751
|
-
# y
|
752
|
-
#
|
753
|
-
#
|
754
|
-
# end
|
755
|
-
# if y > @canvas.height
|
756
|
-
# y = @canvas.height
|
757
|
-
# end
|
758
|
-
|
759
|
-
# pos = [ pos[0] - x, pos[1] - y ]
|
760
|
-
# p "SET: #{pos.join(',')}"
|
761
|
-
|
762
|
-
# # @scrollwindow.setPosition(pos[0], pos[1])
|
763
|
-
# p @scrollwindow.position
|
764
|
-
draw
|
815
|
+
# x *= @zoom
|
816
|
+
# y *= @zoom
|
817
|
+
# center_view_on_xy(x.to_i, y.to_i)
|
818
|
+
# draw
|
765
819
|
end
|
766
820
|
|
767
821
|
#
|
@@ -795,10 +849,28 @@ class FXMap < Map
|
|
795
849
|
if r.x >= x1 and r.x <= x2 and
|
796
850
|
r.y >= y1 and r.y <= y2
|
797
851
|
r.selected = true
|
852
|
+
r.update_properties(self)
|
798
853
|
else
|
799
854
|
r.selected = false
|
800
855
|
end
|
801
856
|
}
|
857
|
+
|
858
|
+
@sections[@section].connections.each { |c|
|
859
|
+
next if not c.roomB
|
860
|
+
a = c.roomA
|
861
|
+
b = c.roomB
|
862
|
+
|
863
|
+
if (a.x >= x1 and a.x <= x2 and
|
864
|
+
a.y >= y1 and a.y <= y2) or
|
865
|
+
(b.x >= x1 and b.x <= x2 and
|
866
|
+
b.y >= y1 and b.y <= y2)
|
867
|
+
c.selected = true
|
868
|
+
c.update_properties(self)
|
869
|
+
else
|
870
|
+
c.selected = false
|
871
|
+
end
|
872
|
+
}
|
873
|
+
|
802
874
|
draw
|
803
875
|
dc = FXDCWindow.new(@canvas)
|
804
876
|
dc.drawRectangle(x, y, w * @zoom, h * @zoom)
|
@@ -842,6 +914,52 @@ class FXMap < Map
|
|
842
914
|
end
|
843
915
|
end
|
844
916
|
|
917
|
+
#
|
918
|
+
# Given a room, center scrollwindow so room is visible
|
919
|
+
#
|
920
|
+
def center_view_on_room(r)
|
921
|
+
xx = (r.xx + W / 2) * @zoom
|
922
|
+
yy = (r.yy + H / 2) * @zoom
|
923
|
+
center_view_on_xy(xx, yy)
|
924
|
+
end
|
925
|
+
|
926
|
+
#
|
927
|
+
# Given an x and y coordinate for the canvas, center on it
|
928
|
+
#
|
929
|
+
def center_view_on_xy(xx, yy)
|
930
|
+
cw = @scrollwindow.getContentWidth
|
931
|
+
ch = @scrollwindow.getContentHeight
|
932
|
+
w = @scrollwindow.getViewportWidth
|
933
|
+
h = @scrollwindow.getViewportHeight
|
934
|
+
|
935
|
+
xx -= w / 2
|
936
|
+
yy -= h / 2
|
937
|
+
maxx = cw - w / 2
|
938
|
+
maxy = ch - h / 2
|
939
|
+
if xx > maxx
|
940
|
+
xx = maxx
|
941
|
+
elsif xx < 0
|
942
|
+
xx = 0
|
943
|
+
end
|
944
|
+
if yy > maxy
|
945
|
+
yy = maxy
|
946
|
+
elsif yy < 0
|
947
|
+
yy = 0
|
948
|
+
end
|
949
|
+
|
950
|
+
@scrollwindow.setPosition( -xx, -yy )
|
951
|
+
end
|
952
|
+
|
953
|
+
#
|
954
|
+
# Return current selection as an array of rooms and an array of
|
955
|
+
# connections
|
956
|
+
#
|
957
|
+
def get_selection
|
958
|
+
rooms = @sections[@section].rooms.find_all { |r| r.selected }
|
959
|
+
conns = @sections[@section].connections.find_all { |r| r.selected }
|
960
|
+
return rooms, conns
|
961
|
+
end
|
962
|
+
|
845
963
|
#
|
846
964
|
# Clear rooms/connections selected
|
847
965
|
#
|
@@ -850,6 +968,66 @@ class FXMap < Map
|
|
850
968
|
@sections[@section].connections.each { |r| r.selected = false }
|
851
969
|
end
|
852
970
|
|
971
|
+
#
|
972
|
+
# Add a proper link submenu option for an exit
|
973
|
+
#
|
974
|
+
def rmb_link_menu(submenu, c, room, idx, old_idx)
|
975
|
+
return if room[idx] == c
|
976
|
+
dir = Room::DIRECTIONS[idx]
|
977
|
+
dir = dir.upcase
|
978
|
+
if room[idx]
|
979
|
+
cmd = FXMenuCommand.new(submenu, "Switch with link in #{dir} Exit")
|
980
|
+
cmd.connect(SEL_COMMAND) {
|
981
|
+
c2 = room[idx]
|
982
|
+
room[old_idx] = c2
|
983
|
+
room[idx] = c
|
984
|
+
create_pathmap
|
985
|
+
draw
|
986
|
+
}
|
987
|
+
else
|
988
|
+
cmd = FXMenuCommand.new(submenu, "Move link to #{dir} Exit")
|
989
|
+
cmd.connect(SEL_COMMAND) {
|
990
|
+
room[old_idx] = nil
|
991
|
+
room[idx] = c
|
992
|
+
create_pathmap
|
993
|
+
draw
|
994
|
+
}
|
995
|
+
end
|
996
|
+
end
|
997
|
+
|
998
|
+
#
|
999
|
+
# Handle right mouse button click
|
1000
|
+
#
|
1001
|
+
def rmb_click_cb(sender, sel, event)
|
1002
|
+
rooms, links = get_selection
|
1003
|
+
|
1004
|
+
menu = nil
|
1005
|
+
if not links.empty? and links.size == 1
|
1006
|
+
c = links[0]
|
1007
|
+
a = c.roomA
|
1008
|
+
b = c.roomB
|
1009
|
+
menu = FXMenuPane.new(@window)
|
1010
|
+
submenu = FXMenuPane.new(@window)
|
1011
|
+
old_idx = a.exits.index(c)
|
1012
|
+
0.upto(7) { |idx|
|
1013
|
+
rmb_link_menu( submenu, c, a, idx, old_idx )
|
1014
|
+
}
|
1015
|
+
FXMenuCascade.new(menu, a.name, nil, submenu)
|
1016
|
+
submenu = FXMenuPane.new(@window)
|
1017
|
+
old_idx = b.exits.rindex(c)
|
1018
|
+
0.upto(7) { |idx|
|
1019
|
+
rmb_link_menu( submenu, c, b, idx, old_idx )
|
1020
|
+
}
|
1021
|
+
FXMenuCascade.new(menu, b.name, nil, submenu)
|
1022
|
+
end
|
1023
|
+
if menu
|
1024
|
+
menu.create
|
1025
|
+
menu.popup(nil, event.root_x, event.root_y)
|
1026
|
+
@window.getApp.runModalWhileShown(menu)
|
1027
|
+
end
|
1028
|
+
end
|
1029
|
+
|
1030
|
+
|
853
1031
|
#
|
854
1032
|
# Handle left mouse button click
|
855
1033
|
#
|
@@ -911,9 +1089,11 @@ class FXMap < Map
|
|
911
1089
|
if not roomA
|
912
1090
|
new_xy_connection( x, y )
|
913
1091
|
else
|
914
|
-
|
915
|
-
|
916
|
-
|
1092
|
+
if a and roomA
|
1093
|
+
@complexConnection = [roomA, exitA]
|
1094
|
+
new_connection( roomA, exitA, nil )
|
1095
|
+
_new_complex_connection( roomA, exitA )
|
1096
|
+
end
|
917
1097
|
end
|
918
1098
|
else
|
919
1099
|
new_xy_connection( x, y )
|
@@ -932,6 +1112,7 @@ class FXMap < Map
|
|
932
1112
|
clear_selection
|
933
1113
|
end
|
934
1114
|
# Select the stuff
|
1115
|
+
selection.update_properties(self)
|
935
1116
|
selection.selected = true
|
936
1117
|
end
|
937
1118
|
end
|
@@ -1057,6 +1238,7 @@ class FXMap < Map
|
|
1057
1238
|
@canvas.connect(SEL_MOTION, method(:motion_cb))
|
1058
1239
|
@canvas.connect(SEL_MIDDLEBUTTONPRESS, method(:mmb_click_cb))
|
1059
1240
|
@canvas.connect(SEL_MIDDLEBUTTONRELEASE, method(:mmb_release_cb))
|
1241
|
+
@canvas.connect(SEL_RIGHTBUTTONPRESS, method(:rmb_click_cb))
|
1060
1242
|
@canvas.connect(SEL_KEYPRESS, method(:keypress_cb))
|
1061
1243
|
end
|
1062
1244
|
|
@@ -1167,6 +1349,9 @@ class FXMap < Map
|
|
1167
1349
|
@modified = true
|
1168
1350
|
end
|
1169
1351
|
|
1352
|
+
#
|
1353
|
+
# Give user some warning if he tries to modify a read-only mode.
|
1354
|
+
#
|
1170
1355
|
def navigation_warning
|
1171
1356
|
w = FXWarningBox.new(@window, "Map is in Read Only Mode. Go to Map Information to change this.")
|
1172
1357
|
w.execute
|
@@ -1446,6 +1631,32 @@ class FXMap < Map
|
|
1446
1631
|
# Print map
|
1447
1632
|
#
|
1448
1633
|
def print(printer)
|
1634
|
+
# dc = FXDCPrint.new(@window.getApp)
|
1635
|
+
require 'IFMapper/FXDCPostscript'
|
1636
|
+
oldzoom = @zoom
|
1637
|
+
oldsection = @section
|
1638
|
+
begin
|
1639
|
+
dc = FXDCPostscript.new(@window.getApp)
|
1640
|
+
xmax = @width * WW
|
1641
|
+
ymax = @height * HH
|
1642
|
+
@zoom = 1.0
|
1643
|
+
dc.setContentRange(0, 0, xmax, ymax)
|
1644
|
+
dc.beginPrint(printer) {
|
1645
|
+
0.upto(@sections.size-1) { |p|
|
1646
|
+
self.section = p
|
1647
|
+
clear_selection
|
1648
|
+
dc.beginPage(p+1) {
|
1649
|
+
dc.lineCap = CAP_ROUND
|
1650
|
+
draw_connections(dc)
|
1651
|
+
draw_rooms(dc)
|
1652
|
+
}
|
1653
|
+
}
|
1654
|
+
}
|
1655
|
+
rescue => e
|
1656
|
+
status "#{e}"
|
1657
|
+
end
|
1658
|
+
self.section = oldsection
|
1659
|
+
@zoom = oldzoom
|
1449
1660
|
end
|
1450
1661
|
|
1451
1662
|
#
|
@@ -1459,7 +1670,7 @@ class FXMap < Map
|
|
1459
1670
|
dc = FXDCWindow.new(@image)
|
1460
1671
|
dc.setClipRectangle( -pos[0]-5, -pos[1]-5, w, h)
|
1461
1672
|
dc.font = @font
|
1462
|
-
#
|
1673
|
+
#dc.lineCap = CAP_ROUND
|
1463
1674
|
draw_background(dc, event)
|
1464
1675
|
draw_grid(dc, event) if @options['Grid Boxes']
|
1465
1676
|
if @options['Grid Straight Connections']
|