fxruby 1.6.22-x86-mingw32 → 1.6.23-x86-mingw32
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.
- data/.gitignore +14 -0
- data/.yardopts +8 -0
- data/History.txt +6 -0
- data/Manifest.txt +317 -24
- data/README.git +3 -0
- data/README.rdoc +537 -0
- data/Rakefile +62 -46
- data/Rakefile.cross +397 -0
- data/doap.rdf +3 -3
- data/doap.rdf.erb +87 -0
- data/examples/WhatAQuietStiff.rb +356 -0
- data/examples/canvasdemo.rb +88 -0
- data/examples/gdchart.rb +76 -0
- data/examples/gembrowser.rb +289 -0
- data/examples/rmagick.rb +44 -0
- data/lib/1.8/fox16.so +0 -0
- data/lib/1.9/fox16.so +0 -0
- data/lib/fox16/canvas.rb +606 -0
- data/lib/fox16/irb.rb +1 -0
- data/lib/fox16/splashscreen.rb +1 -0
- data/lib/fox16/tkcompat.rb +56 -0
- data/lib/fox16/version.rb +1 -1
- data/rdoc-sources/FX4Splitter.rb +44 -44
- data/rdoc-sources/FX7Segment.rb +3 -3
- data/rdoc-sources/FXAccelTable.rb +1 -1
- data/rdoc-sources/FXApp.rb +51 -51
- data/rdoc-sources/FXArrowButton.rb +6 -6
- data/rdoc-sources/FXBMPIcon.rb +12 -12
- data/rdoc-sources/FXBMPImage.rb +6 -6
- data/rdoc-sources/FXBitmap.rb +9 -9
- data/rdoc-sources/FXBitmapFrame.rb +3 -3
- data/rdoc-sources/FXBitmapView.rb +12 -12
- data/rdoc-sources/FXButton.rb +5 -5
- data/rdoc-sources/FXCanvas.rb +4 -4
- data/rdoc-sources/FXCheckButton.rb +7 -7
- data/rdoc-sources/FXChoiceBox.rb +16 -16
- data/rdoc-sources/FXColorBar.rb +9 -9
- data/rdoc-sources/FXColorDialog.rb +4 -4
- data/rdoc-sources/FXColorList.rb +1 -1
- data/rdoc-sources/FXColorRing.rb +4 -4
- data/rdoc-sources/FXColorSelector.rb +38 -38
- data/rdoc-sources/FXColorWell.rb +15 -15
- data/rdoc-sources/FXColorWheel.rb +8 -8
- data/rdoc-sources/FXComboBox.rb +24 -24
- data/rdoc-sources/FXCursor.rb +12 -12
- data/rdoc-sources/FXDC.rb +176 -176
- data/rdoc-sources/FXDCPrint.rb +20 -20
- data/rdoc-sources/FXDCWindow.rb +2 -2
- data/rdoc-sources/FXDataTarget.rb +1 -1
- data/rdoc-sources/FXDebugTarget.rb +1 -1
- data/rdoc-sources/FXDelegator.rb +2 -2
- data/rdoc-sources/FXDial.rb +9 -9
- data/rdoc-sources/FXDialogBox.rb +3 -3
- data/rdoc-sources/FXDict.rb +2 -3
- data/rdoc-sources/FXDirBox.rb +2 -2
- data/rdoc-sources/FXDirList.rb +14 -14
- data/rdoc-sources/FXDirSelector.rb +14 -14
- data/rdoc-sources/FXDockBar.rb +35 -35
- data/rdoc-sources/FXDockHandler.rb +2 -2
- data/rdoc-sources/FXDockSite.rb +11 -11
- data/rdoc-sources/FXDockTitle.rb +2 -2
- data/rdoc-sources/FXDocument.rb +2 -2
- data/rdoc-sources/FXDragCorner.rb +2 -2
- data/rdoc-sources/FXDrawable.rb +5 -5
- data/rdoc-sources/FXDriveBox.rb +3 -3
- data/rdoc-sources/FXFileDialog.rb +24 -24
- data/rdoc-sources/FXFileDict.rb +11 -11
- data/rdoc-sources/FXFileList.rb +25 -25
- data/rdoc-sources/FXFileSelector.rb +31 -31
- data/rdoc-sources/FXFileStream.rb +3 -3
- data/rdoc-sources/FXFoldingList.rb +76 -76
- data/rdoc-sources/FXFont.rb +133 -133
- data/rdoc-sources/FXFontDialog.rb +1 -1
- data/rdoc-sources/FXFontSelector.rb +14 -14
- data/rdoc-sources/FXFrame.rb +5 -5
- data/rdoc-sources/FXGIFCursor.rb +6 -6
- data/rdoc-sources/FXGIFIcon.rb +6 -6
- data/rdoc-sources/FXGIFImage.rb +5 -5
- data/rdoc-sources/FXGLContext.rb +1 -1
- data/rdoc-sources/FXGLObject.rb +8 -8
- data/rdoc-sources/FXGLShape.rb +23 -23
- data/rdoc-sources/FXGLViewer.rb +51 -51
- data/rdoc-sources/FXGLVisual.rb +1 -0
- data/rdoc-sources/FXGradientBar.rb +31 -31
- data/rdoc-sources/FXGroupBox.rb +6 -6
- data/rdoc-sources/FXHeader.rb +30 -33
- data/rdoc-sources/FXHorizontalFrame.rb +12 -12
- data/rdoc-sources/FXICOIcon.rb +14 -14
- data/rdoc-sources/FXICOImage.rb +5 -5
- data/rdoc-sources/FXIcon.rb +7 -7
- data/rdoc-sources/FXIconDict.rb +1 -0
- data/rdoc-sources/FXIconList.rb +60 -60
- data/rdoc-sources/FXId.rb +1 -1
- data/rdoc-sources/FXImage.rb +49 -49
- data/rdoc-sources/FXImageFrame.rb +12 -12
- data/rdoc-sources/FXImageView.rb +10 -10
- data/rdoc-sources/FXInputDialog.rb +4 -4
- data/rdoc-sources/FXJPGIcon.rb +13 -13
- data/rdoc-sources/FXJPGImage.rb +5 -5
- data/rdoc-sources/FXKnob.rb +12 -12
- data/rdoc-sources/FXLabel.rb +3 -3
- data/rdoc-sources/FXList.rb +31 -31
- data/rdoc-sources/FXListBox.rb +7 -7
- data/rdoc-sources/FXMDIChild.rb +24 -24
- data/rdoc-sources/FXMDIClient.rb +1 -1
- data/rdoc-sources/FXMatrix.rb +2 -2
- data/rdoc-sources/FXMemoryBuffer.rb +1 -1
- data/rdoc-sources/FXMemoryStream.rb +1 -1
- data/rdoc-sources/FXMenuButton.rb +20 -19
- data/rdoc-sources/FXMenuCaption.rb +9 -9
- data/rdoc-sources/FXMenuCascade.rb +1 -1
- data/rdoc-sources/FXMenuCheck.rb +2 -2
- data/rdoc-sources/FXMenuCommand.rb +1 -1
- data/rdoc-sources/FXMenuRadio.rb +2 -2
- data/rdoc-sources/FXMenuSeparator.rb +2 -2
- data/rdoc-sources/FXMenuTitle.rb +5 -5
- data/rdoc-sources/FXMessageBox.rb +16 -16
- data/rdoc-sources/FXOptionMenu.rb +14 -14
- data/rdoc-sources/FXPCXIcon.rb +12 -12
- data/rdoc-sources/FXPCXImage.rb +5 -5
- data/rdoc-sources/FXPNGIcon.rb +12 -12
- data/rdoc-sources/FXPNGImage.rb +5 -5
- data/rdoc-sources/FXPPMIcon.rb +6 -6
- data/rdoc-sources/FXPPMImage.rb +5 -5
- data/rdoc-sources/FXPacker.rb +4 -4
- data/rdoc-sources/FXPopup.rb +5 -5
- data/rdoc-sources/FXPrintDialog.rb +21 -21
- data/rdoc-sources/FXProgressBar.rb +10 -10
- data/rdoc-sources/FXProgressDialog.rb +3 -3
- data/rdoc-sources/FXQuatd.rb +19 -19
- data/rdoc-sources/FXQuatf.rb +23 -23
- data/rdoc-sources/FXRGBIcon.rb +13 -13
- data/rdoc-sources/FXRGBImage.rb +5 -5
- data/rdoc-sources/FXRadioButton.rb +10 -10
- data/rdoc-sources/FXRanged.rb +2 -2
- data/rdoc-sources/FXRangef.rb +2 -2
- data/rdoc-sources/FXRealSlider.rb +33 -33
- data/rdoc-sources/FXRealSpinner.rb +31 -31
- data/rdoc-sources/FXRecentFiles.rb +14 -14
- data/rdoc-sources/FXRectangle.rb +22 -22
- data/rdoc-sources/FXRegistry.rb +3 -3
- data/rdoc-sources/FXReplaceDialog.rb +20 -20
- data/rdoc-sources/FXRootWindow.rb +2 -2
- data/rdoc-sources/FXRuler.rb +28 -28
- data/rdoc-sources/FXRulerView.rb +5 -5
- data/rdoc-sources/FXScrollArea.rb +27 -27
- data/rdoc-sources/FXScrollBar.rb +26 -26
- data/rdoc-sources/FXScrollPane.rb +3 -3
- data/rdoc-sources/FXScrollWindow.rb +6 -6
- data/rdoc-sources/FXSearchDialog.rb +8 -8
- data/rdoc-sources/FXSeparator.rb +24 -24
- data/rdoc-sources/FXSettings.rb +44 -44
- data/rdoc-sources/FXShutter.rb +35 -35
- data/rdoc-sources/FXSize.rb +14 -14
- data/rdoc-sources/FXSlider.rb +33 -33
- data/rdoc-sources/FXSphered.rb +2 -2
- data/rdoc-sources/FXSpheref.rb +2 -2
- data/rdoc-sources/FXSpinner.rb +30 -30
- data/rdoc-sources/FXSplashWindow.rb +5 -5
- data/rdoc-sources/FXSplitter.rb +18 -18
- data/rdoc-sources/FXSpring.rb +15 -15
- data/rdoc-sources/FXStatusBar.rb +14 -14
- data/rdoc-sources/FXStatusLine.rb +7 -7
- data/rdoc-sources/FXStream.rb +20 -20
- data/rdoc-sources/FXSwitcher.rb +23 -23
- data/rdoc-sources/FXTGAIcon.rb +12 -12
- data/rdoc-sources/FXTGAImage.rb +5 -5
- data/rdoc-sources/FXTIFIcon.rb +13 -13
- data/rdoc-sources/FXTIFImage.rb +5 -5
- data/rdoc-sources/FXTabBar.rb +31 -31
- data/rdoc-sources/FXTabBook.rb +13 -13
- data/rdoc-sources/FXTabItem.rb +22 -22
- data/rdoc-sources/FXTable.rb +148 -148
- data/rdoc-sources/FXText.rb +91 -91
- data/rdoc-sources/FXTextField.rb +39 -39
- data/rdoc-sources/FXToggleButton.rb +32 -32
- data/rdoc-sources/FXToolBar.rb +25 -25
- data/rdoc-sources/FXToolBarGrip.rb +12 -12
- data/rdoc-sources/FXToolBarShell.rb +13 -13
- data/rdoc-sources/FXToolBarTab.rb +16 -16
- data/rdoc-sources/FXTopWindow.rb +18 -18
- data/rdoc-sources/FXTranslator.rb +1 -1
- data/rdoc-sources/FXTreeList.rb +66 -66
- data/rdoc-sources/FXTreeListBox.rb +20 -20
- data/rdoc-sources/FXTriStateButton.rb +23 -23
- data/rdoc-sources/FXVec2d.rb +1 -1
- data/rdoc-sources/FXVec2f.rb +1 -1
- data/rdoc-sources/FXVec3d.rb +1 -1
- data/rdoc-sources/FXVec3f.rb +1 -1
- data/rdoc-sources/FXVec4d.rb +1 -1
- data/rdoc-sources/FXVec4f.rb +1 -1
- data/rdoc-sources/FXVerticalFrame.rb +12 -12
- data/rdoc-sources/FXVisual.rb +19 -19
- data/rdoc-sources/FXWindow.rb +96 -96
- data/rdoc-sources/FXWizard.rb +9 -9
- data/rdoc-sources/FXXBMIcon.rb +7 -7
- data/rdoc-sources/FXXBMImage.rb +6 -6
- data/rdoc-sources/FXXPMIcon.rb +13 -13
- data/rdoc-sources/FXXPMImage.rb +5 -5
- data/rdoc-sources/Makefile +3 -3
- metadata +44 -31
- data/README +0 -39
- data/README.txt +0 -483
data/examples/rmagick.rb
ADDED
@@ -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
|
data/lib/1.8/fox16.so
CHANGED
Binary file
|
data/lib/1.9/fox16.so
CHANGED
Binary file
|
data/lib/fox16/canvas.rb
ADDED
@@ -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
|