fxruby 1.6.22 → 1.6.23

Sign up to get free protection for your applications and to get access to all the features.
Files changed (201) hide show
  1. data/.gitignore +14 -0
  2. data/.yardopts +8 -0
  3. data/History.txt +6 -0
  4. data/Manifest.txt +317 -24
  5. data/README.git +3 -0
  6. data/README.rdoc +537 -0
  7. data/Rakefile +62 -46
  8. data/Rakefile.cross +397 -0
  9. data/doap.rdf +3 -3
  10. data/doap.rdf.erb +87 -0
  11. data/examples/WhatAQuietStiff.rb +356 -0
  12. data/examples/canvasdemo.rb +88 -0
  13. data/examples/gdchart.rb +76 -0
  14. data/examples/gembrowser.rb +289 -0
  15. data/examples/rmagick.rb +44 -0
  16. data/lib/fox16/canvas.rb +606 -0
  17. data/lib/fox16/irb.rb +1 -0
  18. data/lib/fox16/splashscreen.rb +1 -0
  19. data/lib/fox16/tkcompat.rb +56 -0
  20. data/lib/fox16/version.rb +1 -1
  21. data/rdoc-sources/FX4Splitter.rb +44 -44
  22. data/rdoc-sources/FX7Segment.rb +3 -3
  23. data/rdoc-sources/FXAccelTable.rb +1 -1
  24. data/rdoc-sources/FXApp.rb +51 -51
  25. data/rdoc-sources/FXArrowButton.rb +6 -6
  26. data/rdoc-sources/FXBMPIcon.rb +12 -12
  27. data/rdoc-sources/FXBMPImage.rb +6 -6
  28. data/rdoc-sources/FXBitmap.rb +9 -9
  29. data/rdoc-sources/FXBitmapFrame.rb +3 -3
  30. data/rdoc-sources/FXBitmapView.rb +12 -12
  31. data/rdoc-sources/FXButton.rb +5 -5
  32. data/rdoc-sources/FXCanvas.rb +4 -4
  33. data/rdoc-sources/FXCheckButton.rb +7 -7
  34. data/rdoc-sources/FXChoiceBox.rb +16 -16
  35. data/rdoc-sources/FXColorBar.rb +9 -9
  36. data/rdoc-sources/FXColorDialog.rb +4 -4
  37. data/rdoc-sources/FXColorList.rb +1 -1
  38. data/rdoc-sources/FXColorRing.rb +4 -4
  39. data/rdoc-sources/FXColorSelector.rb +38 -38
  40. data/rdoc-sources/FXColorWell.rb +15 -15
  41. data/rdoc-sources/FXColorWheel.rb +8 -8
  42. data/rdoc-sources/FXComboBox.rb +24 -24
  43. data/rdoc-sources/FXCursor.rb +12 -12
  44. data/rdoc-sources/FXDC.rb +176 -176
  45. data/rdoc-sources/FXDCPrint.rb +20 -20
  46. data/rdoc-sources/FXDCWindow.rb +2 -2
  47. data/rdoc-sources/FXDataTarget.rb +1 -1
  48. data/rdoc-sources/FXDebugTarget.rb +1 -1
  49. data/rdoc-sources/FXDelegator.rb +2 -2
  50. data/rdoc-sources/FXDial.rb +9 -9
  51. data/rdoc-sources/FXDialogBox.rb +3 -3
  52. data/rdoc-sources/FXDict.rb +2 -3
  53. data/rdoc-sources/FXDirBox.rb +2 -2
  54. data/rdoc-sources/FXDirList.rb +14 -14
  55. data/rdoc-sources/FXDirSelector.rb +14 -14
  56. data/rdoc-sources/FXDockBar.rb +35 -35
  57. data/rdoc-sources/FXDockHandler.rb +2 -2
  58. data/rdoc-sources/FXDockSite.rb +11 -11
  59. data/rdoc-sources/FXDockTitle.rb +2 -2
  60. data/rdoc-sources/FXDocument.rb +2 -2
  61. data/rdoc-sources/FXDragCorner.rb +2 -2
  62. data/rdoc-sources/FXDrawable.rb +5 -5
  63. data/rdoc-sources/FXDriveBox.rb +3 -3
  64. data/rdoc-sources/FXFileDialog.rb +24 -24
  65. data/rdoc-sources/FXFileDict.rb +11 -11
  66. data/rdoc-sources/FXFileList.rb +25 -25
  67. data/rdoc-sources/FXFileSelector.rb +31 -31
  68. data/rdoc-sources/FXFileStream.rb +3 -3
  69. data/rdoc-sources/FXFoldingList.rb +76 -76
  70. data/rdoc-sources/FXFont.rb +133 -133
  71. data/rdoc-sources/FXFontDialog.rb +1 -1
  72. data/rdoc-sources/FXFontSelector.rb +14 -14
  73. data/rdoc-sources/FXFrame.rb +5 -5
  74. data/rdoc-sources/FXGIFCursor.rb +6 -6
  75. data/rdoc-sources/FXGIFIcon.rb +6 -6
  76. data/rdoc-sources/FXGIFImage.rb +5 -5
  77. data/rdoc-sources/FXGLContext.rb +1 -1
  78. data/rdoc-sources/FXGLObject.rb +8 -8
  79. data/rdoc-sources/FXGLShape.rb +23 -23
  80. data/rdoc-sources/FXGLViewer.rb +51 -51
  81. data/rdoc-sources/FXGLVisual.rb +1 -0
  82. data/rdoc-sources/FXGradientBar.rb +31 -31
  83. data/rdoc-sources/FXGroupBox.rb +6 -6
  84. data/rdoc-sources/FXHeader.rb +30 -33
  85. data/rdoc-sources/FXHorizontalFrame.rb +12 -12
  86. data/rdoc-sources/FXICOIcon.rb +14 -14
  87. data/rdoc-sources/FXICOImage.rb +5 -5
  88. data/rdoc-sources/FXIcon.rb +7 -7
  89. data/rdoc-sources/FXIconDict.rb +1 -0
  90. data/rdoc-sources/FXIconList.rb +60 -60
  91. data/rdoc-sources/FXId.rb +1 -1
  92. data/rdoc-sources/FXImage.rb +49 -49
  93. data/rdoc-sources/FXImageFrame.rb +12 -12
  94. data/rdoc-sources/FXImageView.rb +10 -10
  95. data/rdoc-sources/FXInputDialog.rb +4 -4
  96. data/rdoc-sources/FXJPGIcon.rb +13 -13
  97. data/rdoc-sources/FXJPGImage.rb +5 -5
  98. data/rdoc-sources/FXKnob.rb +12 -12
  99. data/rdoc-sources/FXLabel.rb +3 -3
  100. data/rdoc-sources/FXList.rb +31 -31
  101. data/rdoc-sources/FXListBox.rb +7 -7
  102. data/rdoc-sources/FXMDIChild.rb +24 -24
  103. data/rdoc-sources/FXMDIClient.rb +1 -1
  104. data/rdoc-sources/FXMatrix.rb +2 -2
  105. data/rdoc-sources/FXMemoryBuffer.rb +1 -1
  106. data/rdoc-sources/FXMemoryStream.rb +1 -1
  107. data/rdoc-sources/FXMenuButton.rb +20 -19
  108. data/rdoc-sources/FXMenuCaption.rb +9 -9
  109. data/rdoc-sources/FXMenuCascade.rb +1 -1
  110. data/rdoc-sources/FXMenuCheck.rb +2 -2
  111. data/rdoc-sources/FXMenuCommand.rb +1 -1
  112. data/rdoc-sources/FXMenuRadio.rb +2 -2
  113. data/rdoc-sources/FXMenuSeparator.rb +2 -2
  114. data/rdoc-sources/FXMenuTitle.rb +5 -5
  115. data/rdoc-sources/FXMessageBox.rb +16 -16
  116. data/rdoc-sources/FXOptionMenu.rb +14 -14
  117. data/rdoc-sources/FXPCXIcon.rb +12 -12
  118. data/rdoc-sources/FXPCXImage.rb +5 -5
  119. data/rdoc-sources/FXPNGIcon.rb +12 -12
  120. data/rdoc-sources/FXPNGImage.rb +5 -5
  121. data/rdoc-sources/FXPPMIcon.rb +6 -6
  122. data/rdoc-sources/FXPPMImage.rb +5 -5
  123. data/rdoc-sources/FXPacker.rb +4 -4
  124. data/rdoc-sources/FXPopup.rb +5 -5
  125. data/rdoc-sources/FXPrintDialog.rb +21 -21
  126. data/rdoc-sources/FXProgressBar.rb +10 -10
  127. data/rdoc-sources/FXProgressDialog.rb +3 -3
  128. data/rdoc-sources/FXQuatd.rb +19 -19
  129. data/rdoc-sources/FXQuatf.rb +23 -23
  130. data/rdoc-sources/FXRGBIcon.rb +13 -13
  131. data/rdoc-sources/FXRGBImage.rb +5 -5
  132. data/rdoc-sources/FXRadioButton.rb +10 -10
  133. data/rdoc-sources/FXRanged.rb +2 -2
  134. data/rdoc-sources/FXRangef.rb +2 -2
  135. data/rdoc-sources/FXRealSlider.rb +33 -33
  136. data/rdoc-sources/FXRealSpinner.rb +31 -31
  137. data/rdoc-sources/FXRecentFiles.rb +14 -14
  138. data/rdoc-sources/FXRectangle.rb +22 -22
  139. data/rdoc-sources/FXRegistry.rb +3 -3
  140. data/rdoc-sources/FXReplaceDialog.rb +20 -20
  141. data/rdoc-sources/FXRootWindow.rb +2 -2
  142. data/rdoc-sources/FXRuler.rb +28 -28
  143. data/rdoc-sources/FXRulerView.rb +5 -5
  144. data/rdoc-sources/FXScrollArea.rb +27 -27
  145. data/rdoc-sources/FXScrollBar.rb +26 -26
  146. data/rdoc-sources/FXScrollPane.rb +3 -3
  147. data/rdoc-sources/FXScrollWindow.rb +6 -6
  148. data/rdoc-sources/FXSearchDialog.rb +8 -8
  149. data/rdoc-sources/FXSeparator.rb +24 -24
  150. data/rdoc-sources/FXSettings.rb +44 -44
  151. data/rdoc-sources/FXShutter.rb +35 -35
  152. data/rdoc-sources/FXSize.rb +14 -14
  153. data/rdoc-sources/FXSlider.rb +33 -33
  154. data/rdoc-sources/FXSphered.rb +2 -2
  155. data/rdoc-sources/FXSpheref.rb +2 -2
  156. data/rdoc-sources/FXSpinner.rb +30 -30
  157. data/rdoc-sources/FXSplashWindow.rb +5 -5
  158. data/rdoc-sources/FXSplitter.rb +18 -18
  159. data/rdoc-sources/FXSpring.rb +15 -15
  160. data/rdoc-sources/FXStatusBar.rb +14 -14
  161. data/rdoc-sources/FXStatusLine.rb +7 -7
  162. data/rdoc-sources/FXStream.rb +20 -20
  163. data/rdoc-sources/FXSwitcher.rb +23 -23
  164. data/rdoc-sources/FXTGAIcon.rb +12 -12
  165. data/rdoc-sources/FXTGAImage.rb +5 -5
  166. data/rdoc-sources/FXTIFIcon.rb +13 -13
  167. data/rdoc-sources/FXTIFImage.rb +5 -5
  168. data/rdoc-sources/FXTabBar.rb +31 -31
  169. data/rdoc-sources/FXTabBook.rb +13 -13
  170. data/rdoc-sources/FXTabItem.rb +22 -22
  171. data/rdoc-sources/FXTable.rb +148 -148
  172. data/rdoc-sources/FXText.rb +91 -91
  173. data/rdoc-sources/FXTextField.rb +39 -39
  174. data/rdoc-sources/FXToggleButton.rb +32 -32
  175. data/rdoc-sources/FXToolBar.rb +25 -25
  176. data/rdoc-sources/FXToolBarGrip.rb +12 -12
  177. data/rdoc-sources/FXToolBarShell.rb +13 -13
  178. data/rdoc-sources/FXToolBarTab.rb +16 -16
  179. data/rdoc-sources/FXTopWindow.rb +18 -18
  180. data/rdoc-sources/FXTranslator.rb +1 -1
  181. data/rdoc-sources/FXTreeList.rb +66 -66
  182. data/rdoc-sources/FXTreeListBox.rb +20 -20
  183. data/rdoc-sources/FXTriStateButton.rb +23 -23
  184. data/rdoc-sources/FXVec2d.rb +1 -1
  185. data/rdoc-sources/FXVec2f.rb +1 -1
  186. data/rdoc-sources/FXVec3d.rb +1 -1
  187. data/rdoc-sources/FXVec3f.rb +1 -1
  188. data/rdoc-sources/FXVec4d.rb +1 -1
  189. data/rdoc-sources/FXVec4f.rb +1 -1
  190. data/rdoc-sources/FXVerticalFrame.rb +12 -12
  191. data/rdoc-sources/FXVisual.rb +19 -19
  192. data/rdoc-sources/FXWindow.rb +96 -96
  193. data/rdoc-sources/FXWizard.rb +9 -9
  194. data/rdoc-sources/FXXBMIcon.rb +7 -7
  195. data/rdoc-sources/FXXBMImage.rb +6 -6
  196. data/rdoc-sources/FXXPMIcon.rb +13 -13
  197. data/rdoc-sources/FXXPMImage.rb +5 -5
  198. data/rdoc-sources/Makefile +3 -3
  199. metadata +44 -31
  200. data/README +0 -39
  201. data/README.txt +0 -483
@@ -0,0 +1,44 @@
1
+ require 'fox16'
2
+ require 'RMagick'
3
+
4
+ include Fox
5
+
6
+ class RMagickExample < FXMainWindow
7
+
8
+ def initialize(app)
9
+ super(app, "RMagick Example", :width => 800, :height => 600)
10
+
11
+ # Construct an ImageList
12
+ dippy = Magick::ImageList.new(File.join("icons", "dippy.png"))
13
+
14
+ # Manipulate the image
15
+ text = Magick::Draw.new
16
+ text.annotate(dippy, 0, 0, 0, 60, "Dippy Duck") do
17
+ self.gravity = Magick::SouthGravity
18
+ self.pointsize = 24
19
+ self.stroke = 'transparent'
20
+ self.fill = '#0000A9'
21
+ self.font_weight = Magick::BoldWeight
22
+ end
23
+
24
+ # Extract image data and use it to construct FXPNGImage
25
+ dippy_image = FXPNGImage.new(app, dippy.to_blob)
26
+
27
+ # Display it inside an FXImageFrame
28
+ FXImageFrame.new(self, dippy_image, :opts => LAYOUT_FILL)
29
+ end
30
+
31
+ def create
32
+ super
33
+ show(PLACEMENT_SCREEN)
34
+ end
35
+
36
+ end
37
+
38
+ if __FILE__ == $0
39
+ FXApp.new("RMagick Example", "FXRuby") do |app|
40
+ RMagickExample.new(app)
41
+ app.create
42
+ app.run
43
+ end
44
+ end
@@ -0,0 +1,606 @@
1
+ module Fox
2
+ #
3
+ # The Canvas module defines a framework similar to that provided by Tk's Canvas
4
+ # widget (and subsequent improvements, such as GNOME's Canvas and wxWindows'
5
+ # Object Graphics Library).
6
+ #
7
+ # Links
8
+ # =====
9
+ #
10
+ # Tk's Canvas Widget
11
+ # http://starship.python.net/crew/fredrik/tkmanual/canvas.html
12
+ # http://www.dci.clrc.ac.uk/Publications/Cookbook/chap4.html
13
+ #
14
+ # GNOME's Canvas Widget
15
+ # http://developer.gnome.org/doc/whitepapers/canvas/canvas.html
16
+ #
17
+ module Canvas
18
+
19
+ class CanvasError < Exception
20
+ end
21
+
22
+ class Shape
23
+
24
+ attr_accessor :x, :y, :foreground, :target, :selector
25
+
26
+ def initialize(x, y)
27
+ @enabled = true
28
+ @visible = true
29
+ @selected = false
30
+ @draggable = false
31
+ @x = x
32
+ @y = y
33
+ @foreground = FXRGB(0, 0, 0)
34
+ @target = nil
35
+ @selector = 0
36
+ end
37
+
38
+ # Return the bounding box for this shape
39
+ def bounds
40
+ FXRectangle.new(x, y, width, height)
41
+ end
42
+
43
+ # Hit test
44
+ def hit?(xpos, ypos)
45
+ (xpos >= x) && (xpos < x+width) && (ypos >= y) && (ypos < y+height)
46
+ end
47
+
48
+ # Move shape to specified position
49
+ def move(x, y)
50
+ @x, @y = x, y
51
+ end
52
+
53
+ # Resize shape to specified width and height
54
+ def resize(w, h)
55
+ end
56
+
57
+ # Move and resize the shape
58
+ def position(x, y, w, h)
59
+ move(x, y)
60
+ resize(w, h)
61
+ end
62
+
63
+ # Enable this shape
64
+ def enable
65
+ @enabled = true
66
+ end
67
+
68
+ # Disable this shape
69
+ def disable
70
+ @enabled = false
71
+ end
72
+
73
+ # Is this shape enabled?
74
+ def enabled?
75
+ @enabled
76
+ end
77
+
78
+ # Show this shape
79
+ def show
80
+ @visible = true
81
+ end
82
+
83
+ # Hide this shape
84
+ def hide
85
+ @visible = false
86
+ end
87
+
88
+ # Is this shape visible?
89
+ def visible?
90
+ @visible
91
+ end
92
+
93
+ # Select this shape
94
+ def select
95
+ @selected = true
96
+ end
97
+
98
+ # Deselect this shape
99
+ def deselect
100
+ @selected = false
101
+ end
102
+
103
+ # Is this shape selected?
104
+ def selected?
105
+ @selected
106
+ end
107
+
108
+ # Set this shape's draggability
109
+ def draggable=(d)
110
+ @draggable = d
111
+ end
112
+
113
+ # Is this shape draggable?
114
+ def draggable?
115
+ @draggable
116
+ end
117
+
118
+ # Draw this shape into the specificed device context
119
+ def draw(dc)
120
+ end
121
+
122
+ # Draws outline
123
+ def drawOutline(dc, x, y, w, h)
124
+ points = []
125
+ points << FXPoint.new(x - 0.5*w, y - 0.5*h)
126
+ points << FXPoint.new(x + 0.5*w, y)
127
+ points << FXPoint.new(x + 0.5*w, y + 0.5*h)
128
+ points << FXPoint.new(x - 0.5*w, y + 0.5*h)
129
+ points << points[0]
130
+ dc.drawLines(points)
131
+ end
132
+
133
+ # Default: make 6 control points
134
+ def makeControlPoints
135
+ end
136
+ end
137
+
138
+ class ShapeGroup
139
+
140
+ include Enumerable
141
+
142
+ # Initialize this shape group
143
+ def initialize
144
+ @shapes = []
145
+ end
146
+
147
+ # Does the group contain this shape?
148
+ def include?(shape)
149
+ @shapes.include?(shape)
150
+ end
151
+
152
+ # Add a shape to this group
153
+ def addShape(shape)
154
+ @shapes << shape
155
+ end
156
+
157
+ # Remove a shape from this group
158
+ def removeShape(shape)
159
+ @shapes.remove(shape)
160
+ end
161
+
162
+ def each
163
+ @shapes.each { |shape| yield shape }
164
+ end
165
+
166
+ def reverse_each
167
+ @shapes.reverse_each { |shape| yield shape }
168
+ end
169
+ end
170
+
171
+ class LineShape < Shape
172
+
173
+ attr_accessor :lineWidth, :lineCap, :lineJoin, :lineStyle
174
+ attr_accessor :x1, :y1, :x2, :y2
175
+
176
+ def initialize(x1, y1, x2, y2)
177
+ super(x1, y1)
178
+ @x1, @y1, @x2, @y2 = x1, y1, x2, y2
179
+ @lineWidth = 1
180
+ @lineCap = CAP_NOT_LAST
181
+ @lineJoin = JOIN_MITER
182
+ @lineStyle = LINE_SOLID
183
+ end
184
+
185
+ def width
186
+ 0
187
+ end
188
+
189
+ def height
190
+ 0
191
+ end
192
+
193
+ def draw(dc)
194
+ # Save old values
195
+ oldForeground = dc.foreground
196
+ oldLineWidth = dc.lineWidth
197
+ oldLineCap = dc.lineCap
198
+ oldLineJoin = dc.lineJoin
199
+ oldLineStyle = dc.lineStyle
200
+
201
+ # Set properties for this line
202
+ dc.foreground = foreground
203
+ dc.lineWidth = lineWidth
204
+ dc.lineCap = lineCap
205
+ dc.lineJoin = lineJoin
206
+ dc.lineStyle = lineStyle
207
+
208
+ # Draw the line
209
+ dc.drawLine(x1, y1, x2, y2)
210
+
211
+ # Restore old properties
212
+ dc.lineWidth = oldLineWidth
213
+ dc.lineCap = oldLineCap
214
+ dc.lineJoin = oldLineJoin
215
+ dc.lineStyle = oldLineStyle
216
+ dc.foreground = oldForeground
217
+ end
218
+ end
219
+
220
+ class RectangleShape < Shape
221
+
222
+ attr_accessor :width, :height
223
+
224
+ def initialize(x, y, w, h)
225
+ super(x, y)
226
+ @width = w
227
+ @height = h
228
+ end
229
+
230
+ def draw(dc)
231
+ oldForeground = dc.foreground
232
+ dc.foreground = foreground
233
+ dc.drawRectangle(x, y, width, height)
234
+ dc.foreground = oldForeground
235
+ end
236
+ end
237
+
238
+ class TextShape < RectangleShape
239
+
240
+ attr_reader :font, :text
241
+
242
+ def initialize(x, y, w, h, text=nil)
243
+ super(x, y, w, h)
244
+ @text = text
245
+ @font = FXApp.instance.normalFont
246
+ end
247
+
248
+ def draw(dc)
249
+ super(dc)
250
+ oldForeground = dc.foreground
251
+ oldTextFont = dc.font
252
+ dc.font = @font
253
+ dc.drawImageText(x, y, text)
254
+ dc.font = oldTextFont if oldTextFont
255
+ dc.foreground = oldForeground
256
+ end
257
+ end
258
+
259
+ class CircleShape < Shape
260
+
261
+ attr_accessor :radius
262
+
263
+ def initialize(x, y, radius)
264
+ super(x, y)
265
+ @radius = radius
266
+ end
267
+
268
+ def width
269
+ 2*radius
270
+ end
271
+
272
+ def height
273
+ 2*radius
274
+ end
275
+
276
+ def draw(dc)
277
+ oldForeground = dc.foreground
278
+ oldLineWidth = dc.lineWidth
279
+ dc.foreground = foreground
280
+ dc.lineWidth = 5 if selected?
281
+ dc.drawArc(x, y, width, height, 0, 64*180)
282
+ dc.drawArc(x, y, width, height, 64*180, 64*360)
283
+ dc.foreground = oldForeground
284
+ dc.lineWidth = oldLineWidth
285
+ end
286
+ end
287
+
288
+ class PolygonShape < Shape
289
+ end
290
+
291
+ class ImageShape < Shape
292
+
293
+ attr_accessor :image
294
+
295
+ def initialize(x, y, image)
296
+ @image = image
297
+ end
298
+
299
+ def draw(dc)
300
+ dc.drawImage(image)
301
+ end
302
+ end
303
+
304
+ # Base class for canvas selection policies
305
+ class SelectionPolicy
306
+ def initialize(canvas)
307
+ @canvas = canvas
308
+ end
309
+
310
+ def selectShape(shape, notify)
311
+ unless shape.selected?
312
+ shape.select
313
+ @canvas.updateShape(shape)
314
+ if notify && (@canvas.target != nil)
315
+ @canvas.target.handle(@canvas, MKUINT(@canvas.message, SEL_SELECTED), shape)
316
+ end
317
+ end
318
+ end
319
+
320
+ def deselectShape(shape, notify)
321
+ if shape.selected?
322
+ shape.deselect
323
+ @canvas.updateShape(shape)
324
+ if notify && (@canvas.target != nil)
325
+ @canvas.target.handle(@canvas, MKUINT(@canvas.message, SEL_DESELECTED), shape)
326
+ end
327
+ end
328
+ end
329
+ end
330
+
331
+ # Single shape selected at one time
332
+ class SingleSelectionPolicy < SelectionPolicy
333
+ def initialize(canvas)
334
+ super
335
+ end
336
+
337
+ def selectShape(shape, notify)
338
+ unless shape.selected?
339
+ @canvas.killSelection(notify)
340
+ end
341
+ super
342
+ end
343
+ end
344
+
345
+ class ShapeCanvas < FXCanvas
346
+
347
+ # Window state flags
348
+ FLAG_SHOWN = 0x00000001 # Is shown
349
+ FLAG_ENABLED = 0x00000002 # Able to receive input
350
+ FLAG_UPDATE = 0x00000004 # Is subject to GUI update
351
+ FLAG_DROPTARGET = 0x00000008 # Drop target
352
+ FLAG_FOCUSED = 0x00000010 # Has focus
353
+ FLAG_DIRTY = 0x00000020 # Needs layout
354
+ FLAG_RECALC = 0x00000040 # Needs recalculation
355
+ FLAG_TIP = 0x00000080 # Show tip
356
+ FLAG_HELP = 0x00000100 # Show help
357
+ FLAG_DEFAULT = 0x00000200 # Default widget
358
+ FLAG_INITIAL = 0x00000400 # Initial widget
359
+ FLAG_SHELL = 0x00000800 # Shell window
360
+ FLAG_ACTIVE = 0x00001000 # Window is active
361
+ FLAG_PRESSED = 0x00002000 # Button has been pressed
362
+ FLAG_KEY = 0x00004000 # Keyboard key pressed
363
+ FLAG_CARET = 0x00008000 # Caret is on
364
+ FLAG_CHANGED = 0x00010000 # Window data changed
365
+ FLAG_LASSO = 0x00020000 # Lasso mode
366
+ FLAG_TRYDRAG = 0x00040000 # Tentative drag mode
367
+ FLAG_DODRAG = 0x00080000 # Doing drag mode
368
+ FLAG_SCROLLINSIDE = 0x00100000 # Scroll only when inside
369
+ FLAG_SCROLLING = 0x00200000 # Right mouse scrolling
370
+
371
+ include Responder
372
+
373
+ attr_accessor :scene
374
+
375
+ def initialize(p, tgt=nil, sel=0, opts=FRAME_NORMAL, x=0, y=0, w=0, h=0)
376
+ # Initialize base class
377
+ super(p, tgt, sel, opts, x, y, w, h)
378
+
379
+ # Start with an empty group
380
+ @scene = ShapeGroup.new
381
+
382
+ # Selection policy
383
+ @selectionPolicy = SingleSelectionPolicy.new(self)
384
+
385
+ @flags = 0
386
+
387
+ # Map
388
+ FXMAPFUNC(SEL_PAINT, 0, "onPaint")
389
+ FXMAPFUNC(SEL_MOTION, 0, "onMotion")
390
+ FXMAPFUNC(SEL_LEFTBUTTONPRESS, 0, "onLeftBtnPress")
391
+ FXMAPFUNC(SEL_LEFTBUTTONRELEASE, 0, "onLeftBtnRelease")
392
+ FXMAPFUNC(SEL_CLICKED,0,"onClicked")
393
+ FXMAPFUNC(SEL_DOUBLECLICKED,0,"onDoubleClicked")
394
+ FXMAPFUNC(SEL_TRIPLECLICKED,0,"onTripleClicked")
395
+ FXMAPFUNC(SEL_COMMAND,0,"onCommand")
396
+ end
397
+
398
+ # Find the shape of the least depth containing this point
399
+ def findShape(x, y)
400
+ @scene.reverse_each do |shape|
401
+ return shape if shape.hit?(x, y)
402
+ end
403
+ nil
404
+ end
405
+
406
+ # Repaint
407
+ def updateShape(shape)
408
+ if @scene.include?(shape)
409
+ update
410
+ else
411
+ raise CanvasError
412
+ end
413
+ end
414
+
415
+ # Enable one shape
416
+ def enableShape(shape)
417
+ if @scene.include?(shape)
418
+ unless shape.enabled?
419
+ shape.enable
420
+ updateShape(shape)
421
+ end
422
+ else
423
+ raise CanvasError
424
+ end
425
+ end
426
+
427
+ # Disable one shape
428
+ def disableShape(shape)
429
+ if @scene.include?(shape)
430
+ if shape.enabled?
431
+ shape.disable
432
+ updateShape(shape)
433
+ end
434
+ else
435
+ raise CanvasError
436
+ end
437
+ end
438
+
439
+ # Select one shape
440
+ def selectShape(shape, notify=false)
441
+ if @scene.include?(shape)
442
+ @selectionPolicy.selectShape(shape, notify)
443
+ else
444
+ raise CanvasError
445
+ end
446
+ end
447
+
448
+ # Deselect one shape
449
+ def deselectShape(shape, notify=false)
450
+ if @scene.include?(shape)
451
+ @selectionPolicy.deselectShape(shape, notify)
452
+ else
453
+ raise CanvasError
454
+ end
455
+ end
456
+
457
+ # Kill selection
458
+ def killSelection(notify)
459
+ changes = false
460
+ @scene.each do |shape|
461
+ if shape.selected?
462
+ shape.deselect
463
+ updateShape(shape)
464
+ changes = true
465
+ if notify && (target != nil)
466
+ target.handle(self, MKUINT(message, SEL_DESELECTED), shape)
467
+ end
468
+ end
469
+ end
470
+ changes
471
+ end
472
+
473
+ # Paint
474
+ def onPaint(sender, sel, evt)
475
+ dc = FXDCWindow.new(self, evt)
476
+ dc.foreground = backColor
477
+ dc.fillRectangle(evt.rect.x, evt.rect.y, evt.rect.w, evt.rect.h)
478
+ @scene.each do |shape|
479
+ shape.draw(dc)
480
+ end
481
+ dc.end
482
+ return 1
483
+ end
484
+
485
+ # Motion
486
+ def onMotion(sender, sel, evt)
487
+ # Drag and drop mode
488
+ if (@flags & FLAG_DODRAG) != 0
489
+ handle(self, MKUINT(0, SEL_DRAGGED), evt)
490
+ return 1
491
+ end
492
+
493
+ # Tentative drag and drop
494
+ if (@flags & FLAG_TRYDRAG) != 0
495
+ if evt.moved?
496
+ @flags &= ~FLAG_TRYDRAG
497
+ if handle(this, MKUINT(0, SEL_BEGINDRAG), evt) != 0
498
+ @flags |= FLAG_DODRAG
499
+ end
500
+ end
501
+ return 1
502
+ end
503
+ end
504
+
505
+ # Left button press
506
+ def onLeftBtnPress(sender, sel, evt)
507
+ handle(self, MKUINT(0, SEL_FOCUS_SELF), evt)
508
+ if enabled?
509
+ grab
510
+ flags &= ~FLAG_UPDATE
511
+
512
+ # Give target the first chance at handling this
513
+ return 1 if target && (target.handle(self, MKUINT(message, SEL_LEFTBUTTONPRESS), evt) != 0)
514
+
515
+ # Locate shape
516
+ shape = findShape(evt.win_x, evt.win_y)
517
+
518
+ # No shape here
519
+ if shape.nil?
520
+ return 1
521
+ end
522
+
523
+ # Change current shape
524
+ @currentShape = shape
525
+
526
+ # Change item selection
527
+ if shape.enabled? && !shape.selected?
528
+ selectShape(shape, true)
529
+ end
530
+
531
+ # Are we dragging?
532
+ if shape.selected? && shape.draggable?
533
+ flags |= FLAG_TRYDRAG
534
+ end
535
+
536
+ flags |= FLAG_PRESSED
537
+ return 1
538
+ end
539
+ return 0
540
+ end
541
+
542
+ # Left button release
543
+ def onLeftBtnRelease(sender, sel, evt)
544
+ flg = @flags
545
+ if enabled?
546
+ ungrab
547
+ @flags |= FLAG_UPDATE
548
+ @flags &= ~(FLAG_PRESSED|FLAG_TRYDRAG|FLAG_LASSO|FLAG_DODRAG)
549
+
550
+ # First chance callback
551
+ return 1 if target && target.handle(self, MKUINT(message, SEL_LEFTBUTTONRELEASE), evt) != 0
552
+
553
+ # Was dragging
554
+ if (flg & FLAG_DODRAG) != 0
555
+ handle(self, MKUINT(0, SEL_ENDDRAG), evt)
556
+ return 1
557
+ end
558
+
559
+ # Must have pressed
560
+ if (flg & FLAG_PRESSED) != 0
561
+ # Change selection
562
+ if @currentShape && @currentShape.enabled?
563
+ deselectShape(@currentShape, true)
564
+ end
565
+
566
+ # Generate clicked callbacks
567
+ if evt.click_count == 1
568
+ handle(self, MKUINT(0, SEL_CLICKED), @currentShape)
569
+ elsif evt.click_count == 2
570
+ handle(self, MKUINT(0, SEL_DOUBLECLICKED), @currentShape)
571
+ elseif evt.click_count == 3
572
+ handle(self, MKUINT(0, SEL_TRIPLECLICKED), @currentShape)
573
+ end
574
+
575
+ # Generate command callback only when clicked on item
576
+ if @currentShape && @currentShape.enabled?
577
+ handle(self, MKUINT(0, SEL_COMMAND), @currentShape)
578
+ end
579
+ return 1
580
+ end
581
+ return 0
582
+ end
583
+ end
584
+
585
+ # Command message
586
+ def onCommand(sender, sel, ptr)
587
+ return target && target.handle(self, MKUINT(message, SEL_COMMAND), ptr)
588
+ end
589
+
590
+ # Clicked on canvas
591
+ def onClicked(sender, sel, ptr)
592
+ return target && target.handle(self, MKUINT(message, SEL_CLICKED), ptr)
593
+ end
594
+
595
+ # Double-clicked on canvas
596
+ def onDoubleClicked(sender, sel, ptr)
597
+ return target && target.handle(self, MKUINT(message, SEL_DOUBLECLICKED), ptr)
598
+ end
599
+
600
+ # Triple-clicked on canvas
601
+ def onTripleClicked(sender, sel, ptr)
602
+ return target && target.handle(self, MKUINT(message, SEL_TRIPLECLICKED), ptr)
603
+ end
604
+ end
605
+ end
606
+ end