fxruby 1.6.5 → 1.6.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.
- data/doc/apes02.html +2 -2
- data/doc/apes03.html +1 -1
- data/doc/book.html +1 -1
- data/doc/changes.html +55 -21
- data/doc/differences.html +9 -9
- data/doc/implementation.html +1 -1
- data/doc/library.html +5 -5
- data/doc/opengl.html +5 -5
- data/doc/pt02.html +1 -1
- data/doc/scintilla.html +4 -4
- data/doc/subversion.html +1 -1
- data/examples/accell.rb +36 -0
- data/examples/babelfish.rb +6 -9
- data/examples/bounce.rb +5 -4
- data/examples/button.rb +19 -21
- data/examples/datatarget.rb +9 -8
- data/examples/dctest.rb +7 -13
- data/examples/dialog.rb +12 -16
- data/examples/dilbert.rb +4 -4
- data/examples/dirlist.rb +6 -5
- data/examples/dragdrop.rb +30 -33
- data/examples/dragsource.rb +22 -22
- data/examples/dropsite.rb +16 -17
- data/examples/foursplit.rb +8 -13
- data/examples/gltest.rb +21 -24
- data/examples/glviewer.rb +56 -58
- data/examples/header.rb +25 -25
- data/examples/iconlist.rb +12 -8
- data/examples/image.rb +36 -34
- data/examples/imageviewer.rb +44 -43
- data/examples/inputs.rb +15 -15
- data/examples/mditest.rb +6 -5
- data/examples/pig.rb +1 -0
- data/examples/raabrowser.rb +31 -40
- data/examples/ratio.rb +27 -16
- data/examples/rulerview.rb +4 -3
- data/examples/scribble.rb +14 -17
- data/examples/shutter.rb +10 -9
- data/examples/splitter.rb +7 -6
- data/examples/tabbook.rb +59 -17
- data/examples/table.rb +12 -16
- data/ext/fox16/FXRuby.cpp +2 -2
- data/lib/fox16/glshapes.rb +6 -6
- data/lib/fox16/iterators.rb +13 -8
- data/lib/fox16/kwargs.rb +604 -380
- data/lib/fox16/version.rb +1 -1
- data/tests/TC_FXTreeList.rb +13 -13
- data/tests/TC_FXTreeListBox.rb +3 -3
- metadata +4 -3
data/examples/dragdrop.rb
CHANGED
@@ -1,29 +1,31 @@
|
|
1
1
|
require 'fox16'
|
2
|
+
require 'fox16/kwargs'
|
2
3
|
|
3
4
|
include Fox
|
4
5
|
|
5
6
|
class DragDropWindow < FXMainWindow
|
7
|
+
|
6
8
|
def initialize(anApp)
|
7
9
|
# Initialize base class
|
8
|
-
super(anApp, "Drag and Drop",
|
10
|
+
super(anApp, "Drag and Drop", :opts => DECOR_ALL, :width => 400, :height => 300)
|
9
11
|
|
10
12
|
# Fill main window with canvas
|
11
|
-
@canvas = FXCanvas.new(self,
|
13
|
+
@canvas = FXCanvas.new(self, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y)
|
12
14
|
@canvas.backColor = "red"
|
13
15
|
|
14
16
|
# Enable canvas for drag-and-drop messages
|
15
17
|
@canvas.dropEnable
|
16
18
|
|
17
19
|
# Handle expose events on the canvas
|
18
|
-
@canvas.connect(SEL_PAINT)
|
19
|
-
FXDCWindow.new(@canvas, event)
|
20
|
+
@canvas.connect(SEL_PAINT) do |sender, sel, event|
|
21
|
+
FXDCWindow.new(@canvas, event) do |dc|
|
20
22
|
dc.foreground = @canvas.backColor
|
21
23
|
dc.fillRectangle(event.rect.x, event.rect.y, event.rect.w, event.rect.h)
|
22
|
-
|
23
|
-
|
24
|
+
end
|
25
|
+
end
|
24
26
|
|
25
27
|
# Handle left button press
|
26
|
-
@canvas.connect(SEL_LEFTBUTTONPRESS)
|
28
|
+
@canvas.connect(SEL_LEFTBUTTONPRESS) do
|
27
29
|
#
|
28
30
|
# Capture (grab) the mouse when the button goes down, so that all future
|
29
31
|
# mouse events will be reported to this widget, even if those events occur
|
@@ -34,49 +36,44 @@ class DragDropWindow < FXMainWindow
|
|
34
36
|
# Advertise which drag types we can offer
|
35
37
|
dragTypes = [FXWindow.colorType]
|
36
38
|
@canvas.beginDrag(dragTypes)
|
37
|
-
|
39
|
+
end
|
38
40
|
|
39
41
|
# Handle mouse motion events
|
40
|
-
@canvas.connect(SEL_MOTION)
|
42
|
+
@canvas.connect(SEL_MOTION) do |sender, sel, event|
|
41
43
|
if @canvas.dragging?
|
42
44
|
@canvas.handleDrag(event.root_x, event.root_y)
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
45
|
+
unless @canvas.didAccept == DRAG_REJECT
|
46
|
+
@canvas.dragCursor = getApp().getDefaultCursor(DEF_SWATCH_CURSOR)
|
47
|
+
else
|
48
|
+
@canvas.dragCursor = getApp().getDefaultCursor(DEF_DNDSTOP_CURSOR)
|
49
|
+
end
|
48
50
|
end
|
49
|
-
|
51
|
+
end
|
50
52
|
|
51
53
|
# Handle SEL_DND_MOTION messages from the canvas
|
52
|
-
@canvas.connect(SEL_DND_MOTION)
|
53
|
-
if @canvas.offeredDNDType?(FROM_DRAGNDROP, FXWindow.colorType)
|
54
|
-
|
55
|
-
end
|
56
|
-
}
|
54
|
+
@canvas.connect(SEL_DND_MOTION) do
|
55
|
+
@canvas.acceptDrop if @canvas.offeredDNDType?(FROM_DRAGNDROP, FXWindow.colorType)
|
56
|
+
end
|
57
57
|
|
58
58
|
# Handle left button release
|
59
|
-
@canvas.connect(SEL_LEFTBUTTONRELEASE)
|
59
|
+
@canvas.connect(SEL_LEFTBUTTONRELEASE) do
|
60
60
|
@canvas.ungrab
|
61
61
|
@canvas.endDrag
|
62
|
-
|
62
|
+
end
|
63
63
|
|
64
64
|
# Handle SEL_DND_DROP message from the canvas
|
65
|
-
@canvas.connect(SEL_DND_DROP)
|
65
|
+
@canvas.connect(SEL_DND_DROP) do
|
66
66
|
# Try to obtain the data as color values first
|
67
67
|
data = @canvas.getDNDData(FROM_DRAGNDROP, FXWindow.colorType)
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
}
|
68
|
+
|
69
|
+
# Update canvas background color
|
70
|
+
@canvas.backColor = Fox.fxdecodeColorData(data) unless data.nil?
|
71
|
+
end
|
73
72
|
|
74
73
|
# Handle request for DND data
|
75
|
-
@canvas.connect(SEL_DND_REQUEST)
|
76
|
-
if event.target == FXWindow.colorType
|
77
|
-
|
78
|
-
end
|
79
|
-
}
|
74
|
+
@canvas.connect(SEL_DND_REQUEST) do |sender, sel, event|
|
75
|
+
@canvas.setDNDData(FROM_DRAGNDROP, FXWindow.colorType, Fox.fxencodeColorData(@canvas.backColor)) if event.target == FXWindow.colorType
|
76
|
+
end
|
80
77
|
end
|
81
78
|
|
82
79
|
def create
|
data/examples/dragsource.rb
CHANGED
@@ -1,26 +1,28 @@
|
|
1
1
|
require 'fox16'
|
2
|
+
require 'fox16/kwargs'
|
2
3
|
|
3
4
|
include Fox
|
4
5
|
|
5
6
|
class DragSource < FXMainWindow
|
7
|
+
|
6
8
|
def initialize(anApp)
|
7
9
|
# Initialize base class
|
8
|
-
super(anApp, "Drag Source",
|
10
|
+
super(anApp, "Drag Source", :opts => DECOR_ALL, :width => 400, :height => 300)
|
9
11
|
|
10
12
|
# Fill main window with canvas
|
11
|
-
@canvas = FXCanvas.new(self,
|
13
|
+
@canvas = FXCanvas.new(self, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y)
|
12
14
|
@canvas.backColor = "red"
|
13
15
|
|
14
16
|
# Handle expose events on the canvas
|
15
|
-
@canvas.connect(SEL_PAINT)
|
16
|
-
FXDCWindow.new(@canvas, event)
|
17
|
+
@canvas.connect(SEL_PAINT) do |sender, sel, event|
|
18
|
+
FXDCWindow.new(@canvas, event) do |dc|
|
17
19
|
dc.foreground = @canvas.backColor
|
18
20
|
dc.fillRectangle(event.rect.x, event.rect.y, event.rect.w, event.rect.h)
|
19
|
-
|
20
|
-
|
21
|
+
end
|
22
|
+
end
|
21
23
|
|
22
24
|
# Handle left button press
|
23
|
-
@canvas.connect(SEL_LEFTBUTTONPRESS)
|
25
|
+
@canvas.connect(SEL_LEFTBUTTONPRESS) do
|
24
26
|
#
|
25
27
|
# Capture (grab) the mouse when the button goes down, so that all future
|
26
28
|
# mouse events will be reported to this widget, even if those events occur
|
@@ -31,32 +33,30 @@ class DragSource < FXMainWindow
|
|
31
33
|
# Advertise which drag types we can offer
|
32
34
|
dragTypes = [FXWindow.colorType]
|
33
35
|
@canvas.beginDrag(dragTypes)
|
34
|
-
|
36
|
+
end
|
35
37
|
|
36
38
|
# Handle mouse motion events
|
37
|
-
@canvas.connect(SEL_MOTION)
|
39
|
+
@canvas.connect(SEL_MOTION) do |sender, sel, event|
|
38
40
|
if @canvas.dragging?
|
39
41
|
@canvas.handleDrag(event.root_x, event.root_y)
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
42
|
+
unless @canvas.didAccept == DRAG_REJECT
|
43
|
+
@canvas.dragCursor = getApp().getDefaultCursor(DEF_SWATCH_CURSOR)
|
44
|
+
else
|
45
|
+
@canvas.dragCursor = getApp().getDefaultCursor(DEF_DNDSTOP_CURSOR)
|
46
|
+
end
|
45
47
|
end
|
46
|
-
|
48
|
+
end
|
47
49
|
|
48
50
|
# Handle left button release
|
49
|
-
@canvas.connect(SEL_LEFTBUTTONRELEASE)
|
51
|
+
@canvas.connect(SEL_LEFTBUTTONRELEASE) do
|
50
52
|
@canvas.ungrab
|
51
53
|
@canvas.endDrag
|
52
|
-
|
54
|
+
end
|
53
55
|
|
54
56
|
# Handle request for DND data
|
55
|
-
@canvas.connect(SEL_DND_REQUEST)
|
56
|
-
if event.target == FXWindow.colorType
|
57
|
-
|
58
|
-
end
|
59
|
-
}
|
57
|
+
@canvas.connect(SEL_DND_REQUEST) do |sender, sel, event|
|
58
|
+
@canvas.setDNDData(FROM_DRAGNDROP, FXWindow.colorType, Fox.fxencodeColorData(@canvas.backColor)) if event.target == FXWindow.colorType
|
59
|
+
end
|
60
60
|
end
|
61
61
|
|
62
62
|
def create
|
data/examples/dropsite.rb
CHANGED
@@ -1,42 +1,41 @@
|
|
1
1
|
require 'fox16'
|
2
|
+
require 'fox16/kwargs'
|
2
3
|
|
3
4
|
include Fox
|
4
5
|
|
5
6
|
class DropSite < FXMainWindow
|
7
|
+
|
6
8
|
def initialize(anApp)
|
7
9
|
# Initialize base class
|
8
|
-
super(anApp, "Drop Site"
|
10
|
+
super(anApp, "Drop Site",:opts => DECOR_ALL, :width => 400, :height => 300)
|
9
11
|
|
10
12
|
# Fill main window with canvas
|
11
|
-
@canvas = FXCanvas.new(self,
|
13
|
+
@canvas = FXCanvas.new(self, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y)
|
12
14
|
|
13
15
|
# Handle expose events on the canvas
|
14
|
-
@canvas.connect(SEL_PAINT)
|
15
|
-
FXDCWindow.new(@canvas, event)
|
16
|
+
@canvas.connect(SEL_PAINT) do |sender, sel, event|
|
17
|
+
FXDCWindow.new(@canvas, event) do |dc|
|
16
18
|
dc.foreground = @canvas.backColor
|
17
19
|
dc.fillRectangle(event.rect.x, event.rect.y, event.rect.w, event.rect.h)
|
18
|
-
|
19
|
-
|
20
|
+
end
|
21
|
+
end
|
20
22
|
|
21
23
|
# Enable canvas for drag-and-drop messages
|
22
24
|
@canvas.dropEnable
|
23
25
|
|
24
26
|
# Handle SEL_DND_MOTION messages from the canvas
|
25
|
-
@canvas.connect(SEL_DND_MOTION)
|
26
|
-
if @canvas.offeredDNDType?(FROM_DRAGNDROP, FXWindow.colorType)
|
27
|
-
|
28
|
-
end
|
29
|
-
}
|
27
|
+
@canvas.connect(SEL_DND_MOTION) do
|
28
|
+
@canvas.acceptDrop if @canvas.offeredDNDType?(FROM_DRAGNDROP, FXWindow.colorType)
|
29
|
+
end
|
30
30
|
|
31
31
|
# Handle SEL_DND_DROP message from the canvas
|
32
|
-
@canvas.connect(SEL_DND_DROP)
|
32
|
+
@canvas.connect(SEL_DND_DROP) do
|
33
33
|
# Try to obtain the data as color values first
|
34
34
|
data = @canvas.getDNDData(FROM_DRAGNDROP, FXWindow.colorType)
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
}
|
35
|
+
|
36
|
+
# Update canvas background color
|
37
|
+
@canvas.backColor = Fox.fxdecodeColorData(data) unless data.nil?
|
38
|
+
end
|
40
39
|
end
|
41
40
|
|
42
41
|
def create
|
data/examples/foursplit.rb
CHANGED
@@ -1,13 +1,14 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
3
|
require 'fox16'
|
4
|
+
require 'fox16/kwargs'
|
4
5
|
|
5
6
|
include Fox
|
6
7
|
|
7
8
|
class FourSplitWindow < FXMainWindow
|
8
9
|
def initialize(app)
|
9
10
|
# Call the base class initialize() first
|
10
|
-
super(app, "4-Way Splitter Test",
|
11
|
+
super(app, "4-Way Splitter Test", :opts => DECOR_ALL, :width => 800, :height => 600)
|
11
12
|
|
12
13
|
# Menu bar, along the top
|
13
14
|
menubar = FXMenuBar.new(self, LAYOUT_SIDE_TOP|LAYOUT_FILL_X)
|
@@ -47,14 +48,11 @@ class FourSplitWindow < FXMainWindow
|
|
47
48
|
# but the fourth is itself another 4-splitter. There is no
|
48
49
|
# restriction on nesting these kinds of widgets.
|
49
50
|
|
50
|
-
FXButton.new(splitter, "Top &Left\tThis splitter tracks",
|
51
|
-
nil, 0, FRAME_RAISED|FRAME_THICK)
|
51
|
+
FXButton.new(splitter, "Top &Left\tThis splitter tracks", :opts => FRAME_RAISED|FRAME_THICK)
|
52
52
|
|
53
|
-
FXButton.new(splitter, "Top &Right\tThis splitter tracks",
|
54
|
-
nil, 0, FRAME_RAISED|FRAME_THICK)
|
53
|
+
FXButton.new(splitter, "Top &Right\tThis splitter tracks", :opts => FRAME_RAISED|FRAME_THICK)
|
55
54
|
|
56
|
-
FXButton.new(splitter, "&Bottom Left\tThis splitter tracks",
|
57
|
-
nil, 0, FRAME_SUNKEN|FRAME_THICK)
|
55
|
+
FXButton.new(splitter, "&Bottom Left\tThis splitter tracks", :opts => FRAME_SUNKEN|FRAME_THICK)
|
58
56
|
|
59
57
|
subsplitter = FX4Splitter.new(splitter, LAYOUT_FILL_X|LAYOUT_FILL_Y)
|
60
58
|
|
@@ -66,20 +64,17 @@ class FourSplitWindow < FXMainWindow
|
|
66
64
|
end
|
67
65
|
|
68
66
|
button = FXButton.new(subsplitter,
|
69
|
-
"the&y CAN\tThis splitter does NOT track",
|
70
|
-
nil, 0, FRAME_SUNKEN|FRAME_THICK)
|
67
|
+
"the&y CAN\tThis splitter does NOT track", :opts => FRAME_SUNKEN|FRAME_THICK)
|
71
68
|
button.backColor = FXRGB(128, 0, 0)
|
72
69
|
button.textColor = FXRGB(255, 255, 255)
|
73
70
|
|
74
71
|
button = FXButton.new(subsplitter,
|
75
|
-
"be &NESTED\tThis splitter does NOT track",
|
76
|
-
nil, 0, FRAME_SUNKEN|FRAME_THICK)
|
72
|
+
"be &NESTED\tThis splitter does NOT track", :opts => FRAME_SUNKEN|FRAME_THICK)
|
77
73
|
button.backColor = FXRGB(0, 0, 200)
|
78
74
|
button.textColor = FXRGB(255, 255, 255)
|
79
75
|
|
80
76
|
button = FXButton.new(subsplitter,
|
81
|
-
"&arbitrarily!\tThis splitter does NOT track",
|
82
|
-
nil, 0, FRAME_SUNKEN|FRAME_THICK)
|
77
|
+
"&arbitrarily!\tThis splitter does NOT track", :opts => FRAME_SUNKEN|FRAME_THICK)
|
83
78
|
button.backColor = FXRGB(128, 128, 0)
|
84
79
|
button.textColor = FXRGB(255, 255, 255)
|
85
80
|
|
data/examples/gltest.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
3
|
require 'fox16'
|
4
|
+
require 'fox16/kwargs'
|
4
5
|
begin
|
5
6
|
require 'opengl'
|
6
7
|
rescue LoadError
|
@@ -193,7 +194,7 @@ class GLTestWindow < FXMainWindow
|
|
193
194
|
|
194
195
|
def initialize(app)
|
195
196
|
# Invoke the base class initializer
|
196
|
-
super(app, "OpenGL Test Application",
|
197
|
+
super(app, "OpenGL Test Application", :opts => DECOR_ALL, :width => 800, :height => 600)
|
197
198
|
|
198
199
|
# Construct the main window elements
|
199
200
|
frame = FXHorizontalFrame.new(self, LAYOUT_SIDE_TOP|LAYOUT_FILL_X|LAYOUT_FILL_Y)
|
@@ -223,17 +224,14 @@ class GLTestWindow < FXMainWindow
|
|
223
224
|
@glvisual = FXGLVisual.new(getApp(), VISUAL_DOUBLEBUFFER)
|
224
225
|
|
225
226
|
# Drawing glcanvas
|
226
|
-
@glcanvas = FXGLCanvas.new(glpanel, @glvisual,
|
227
|
-
|
228
|
-
@glcanvas.connect(
|
229
|
-
drawScene
|
230
|
-
}
|
231
|
-
@glcanvas.connect(SEL_CONFIGURE) {
|
227
|
+
@glcanvas = FXGLCanvas.new(glpanel, @glvisual, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y|LAYOUT_TOP|LAYOUT_LEFT)
|
228
|
+
@glcanvas.connect(SEL_PAINT) { drawScene }
|
229
|
+
@glcanvas.connect(SEL_CONFIGURE) do
|
232
230
|
if @glcanvas.makeCurrent
|
233
231
|
GL.Viewport(0, 0, @glcanvas.width, @glcanvas.height)
|
234
232
|
@glcanvas.makeNonCurrent
|
235
233
|
end
|
236
|
-
|
234
|
+
end
|
237
235
|
|
238
236
|
# Right pane for the buttons
|
239
237
|
buttonFrame = FXVerticalFrame.new(frame, LAYOUT_FILL_Y|LAYOUT_TOP|LAYOUT_LEFT)
|
@@ -251,37 +249,36 @@ class GLTestWindow < FXMainWindow
|
|
251
249
|
spinTimerBtn = FXButton.new(buttonFrame, "Spin &Timer\tSpin using interval timers\nNote the app blocks until the interal has elapsed...",nil,nil,0,FRAME_THICK|FRAME_RAISED|LAYOUT_FILL_X|LAYOUT_TOP|LAYOUT_LEFT)
|
252
250
|
spinTimerBtn.padLeft, spinTimerBtn.padRight = 10, 10
|
253
251
|
spinTimerBtn.padTop, spinTimerBtn.padBottom = 5, 5
|
254
|
-
spinTimerBtn.connect(SEL_COMMAND)
|
252
|
+
spinTimerBtn.connect(SEL_COMMAND) do
|
255
253
|
@spinning = true
|
256
254
|
@timer = getApp().addTimeout(TIMER_INTERVAL, method(:onTimeout))
|
257
|
-
|
258
|
-
spinTimerBtn.connect(SEL_UPDATE)
|
255
|
+
end
|
256
|
+
spinTimerBtn.connect(SEL_UPDATE) do |sender, sel, ptr|
|
259
257
|
@spinning ? sender.disable : sender.enable
|
260
|
-
|
258
|
+
end
|
261
259
|
|
262
260
|
# Spin according to chore
|
263
261
|
spinChoreBtn = FXButton.new(buttonFrame,
|
264
262
|
"Spin &Chore\tSpin as fast as possible using chores\nNote even though the
|
265
263
|
app is very responsive, it never blocks;\nthere is always something to
|
266
|
-
do...",
|
267
|
-
nil, 0, FRAME_THICK|FRAME_RAISED|LAYOUT_FILL_X|LAYOUT_TOP|LAYOUT_LEFT)
|
264
|
+
do...", :opts => FRAME_THICK|FRAME_RAISED|LAYOUT_FILL_X|LAYOUT_TOP|LAYOUT_LEFT)
|
268
265
|
spinChoreBtn.padLeft, spinChoreBtn.padRight = 10, 10
|
269
266
|
spinChoreBtn.padTop, spinChoreBtn.padBottom = 5, 5
|
270
|
-
spinChoreBtn.connect(SEL_COMMAND)
|
267
|
+
spinChoreBtn.connect(SEL_COMMAND) do
|
271
268
|
@spinning = true
|
272
269
|
@chore = getApp().addChore(method(:onChore))
|
273
|
-
|
274
|
-
spinChoreBtn.connect(SEL_UPDATE)
|
270
|
+
end
|
271
|
+
spinChoreBtn.connect(SEL_UPDATE) do |sender, sel, ptr|
|
275
272
|
@spinning ? sender.disable : sender.enable
|
276
|
-
|
273
|
+
end
|
277
274
|
|
278
275
|
# Stop spinning
|
279
276
|
stopBtn = FXButton.new(buttonFrame,
|
280
|
-
"&Stop Spin\tStop this mad spinning, I'm getting dizzy",
|
281
|
-
|
277
|
+
"&Stop Spin\tStop this mad spinning, I'm getting dizzy",
|
278
|
+
:opts => FRAME_THICK|FRAME_RAISED|LAYOUT_FILL_X|LAYOUT_TOP|LAYOUT_LEFT)
|
282
279
|
stopBtn.padLeft, stopBtn.padRight = 10, 10
|
283
280
|
stopBtn.padTop, stopBtn.padBottom = 5, 5
|
284
|
-
stopBtn.connect(SEL_COMMAND)
|
281
|
+
stopBtn.connect(SEL_COMMAND) do
|
285
282
|
@spinning = false
|
286
283
|
if @timer
|
287
284
|
getApp().removeTimeout(@timer)
|
@@ -291,10 +288,10 @@ class GLTestWindow < FXMainWindow
|
|
291
288
|
getApp().removeChore(@chore)
|
292
289
|
@chore = nil
|
293
290
|
end
|
294
|
-
|
295
|
-
stopBtn.connect(SEL_UPDATE)
|
291
|
+
end
|
292
|
+
stopBtn.connect(SEL_UPDATE) do |sender, sel, ptr|
|
296
293
|
@spinning ? sender.enable : sender.disable
|
297
|
-
|
294
|
+
end
|
298
295
|
|
299
296
|
# Exit button
|
300
297
|
exitBtn = FXButton.new(buttonFrame, "&Exit\tExit the application", nil,
|
data/examples/glviewer.rb
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
require 'fox16'
|
4
4
|
require 'fox16/responder'
|
5
|
+
require 'fox16/kwargs'
|
5
6
|
begin
|
6
7
|
require 'fox16/glshapes'
|
7
8
|
rescue LoadError
|
@@ -23,67 +24,67 @@ class TabBook < FXTabBook
|
|
23
24
|
"Angles\tCamera Angles\tSwitch to camera angles panel.")
|
24
25
|
|
25
26
|
# Angles page
|
26
|
-
angles = FXMatrix.new(panels, 3,
|
27
|
-
MATRIX_BY_COLUMNS|LAYOUT_FILL_Y|LAYOUT_TOP|LAYOUT_LEFT
|
28
|
-
|
29
|
-
angles.padRight = 10
|
30
|
-
angles.padTop = 10
|
31
|
-
angles.padBottom = 10
|
27
|
+
angles = FXMatrix.new(panels, 3,
|
28
|
+
:opts => FRAME_THICK|FRAME_RAISED|MATRIX_BY_COLUMNS|LAYOUT_FILL_Y|LAYOUT_TOP|LAYOUT_LEFT,
|
29
|
+
:padding => 10)
|
32
30
|
|
33
31
|
FXLabel.new(angles, "X:")
|
34
|
-
FXTextField.new(angles, 6,
|
32
|
+
FXTextField.new(angles, 6,
|
33
|
+
mdiclient, FXGLViewer::ID_ROLL,
|
35
34
|
TEXTFIELD_INTEGER|JUSTIFY_RIGHT|FRAME_SUNKEN|FRAME_THICK)
|
36
|
-
x_dial = FXDial.new(angles,
|
37
|
-
|
38
|
-
|
39
|
-
|
35
|
+
x_dial = FXDial.new(angles,
|
36
|
+
mdiclient, FXGLViewer::ID_DIAL_X,
|
37
|
+
:opts => FRAME_SUNKEN|FRAME_THICK|DIAL_CYCLIC|DIAL_HORIZONTAL|LAYOUT_FIX_WIDTH|LAYOUT_FIX_HEIGHT|LAYOUT_CENTER_Y,
|
38
|
+
:width => 160, :height => 14, :padding => 0)
|
40
39
|
x_dial.tipText = "Rotate about X"
|
41
40
|
x_dial.notchOffset = 900
|
42
41
|
|
43
42
|
FXLabel.new(angles, "Y:")
|
44
|
-
FXTextField.new(angles, 6,
|
43
|
+
FXTextField.new(angles, 6,
|
44
|
+
mdiclient, FXGLViewer::ID_PITCH,
|
45
45
|
TEXTFIELD_INTEGER|JUSTIFY_RIGHT|FRAME_SUNKEN|FRAME_THICK)
|
46
|
-
y_dial = FXDial.new(angles,
|
47
|
-
|
48
|
-
|
49
|
-
|
46
|
+
y_dial = FXDial.new(angles,
|
47
|
+
mdiclient, FXGLViewer::ID_DIAL_Y,
|
48
|
+
:opts => FRAME_SUNKEN|FRAME_THICK|DIAL_CYCLIC|DIAL_HORIZONTAL|LAYOUT_FIX_WIDTH|LAYOUT_FIX_HEIGHT|LAYOUT_CENTER_Y,
|
49
|
+
:width => 160, :height => 14, :padding => 0)
|
50
50
|
y_dial.tipText = "Rotate about Y"
|
51
51
|
y_dial.notchOffset = 900
|
52
52
|
|
53
53
|
FXLabel.new(angles, "Z:")
|
54
|
-
FXTextField.new(angles, 6,
|
54
|
+
FXTextField.new(angles, 6,
|
55
|
+
mdiclient, FXGLViewer::ID_YAW,
|
55
56
|
TEXTFIELD_INTEGER|JUSTIFY_RIGHT|FRAME_SUNKEN|FRAME_THICK)
|
56
|
-
z_dial = FXDial.new(angles,
|
57
|
-
|
58
|
-
|
59
|
-
|
57
|
+
z_dial = FXDial.new(angles,
|
58
|
+
mdiclient, FXGLViewer::ID_DIAL_Z,
|
59
|
+
:opts => FRAME_SUNKEN|FRAME_THICK|DIAL_CYCLIC|DIAL_HORIZONTAL|LAYOUT_FIX_WIDTH|LAYOUT_FIX_HEIGHT|LAYOUT_CENTER_Y,
|
60
|
+
:width => 160, :height => 14, :padding => 0)
|
60
61
|
z_dial.tipText = "Rotate about Z"
|
61
62
|
z_dial.notchOffset = 900
|
62
63
|
|
63
64
|
FXLabel.new(angles, "FOV:")
|
64
65
|
fov = FXTextField.new(angles, 5, mdiclient, FXGLViewer::ID_FOV,
|
65
66
|
JUSTIFY_RIGHT|FRAME_SUNKEN|FRAME_THICK)
|
66
|
-
FXFrame.new(angles,
|
67
|
+
FXFrame.new(angles, :opts => FRAME_NONE)
|
67
68
|
fov.tipText = "Field of view"
|
68
69
|
|
69
70
|
FXLabel.new(angles, "Zoom:")
|
70
71
|
zz = FXTextField.new(angles, 5, mdiclient, FXGLViewer::ID_ZOOM,
|
71
72
|
JUSTIFY_RIGHT|FRAME_SUNKEN|FRAME_THICK)
|
72
|
-
FXFrame.new(angles,
|
73
|
+
FXFrame.new(angles, :opts => FRAME_NONE)
|
73
74
|
zz.tipText = "Zooming"
|
74
75
|
|
75
76
|
FXLabel.new(angles, "Scale X:")
|
76
77
|
FXTextField.new(angles, 5, mdiclient, FXGLViewer::ID_SCALE_X,
|
77
78
|
JUSTIFY_RIGHT|FRAME_SUNKEN|FRAME_THICK)
|
78
|
-
FXFrame.new(angles,
|
79
|
+
FXFrame.new(angles, :opts => FRAME_NONE)
|
79
80
|
FXLabel.new(angles, "Scale Y:")
|
80
81
|
FXTextField.new(angles, 5, mdiclient, FXGLViewer::ID_SCALE_Y,
|
81
82
|
JUSTIFY_RIGHT|FRAME_SUNKEN|FRAME_THICK)
|
82
|
-
FXFrame.new(angles,
|
83
|
+
FXFrame.new(angles, :opts => FRAME_NONE)
|
83
84
|
FXLabel.new(angles, "Scale Z:")
|
84
85
|
FXTextField.new(angles, 5, mdiclient, FXGLViewer::ID_SCALE_Z,
|
85
86
|
JUSTIFY_RIGHT|FRAME_SUNKEN|FRAME_THICK)
|
86
|
-
FXFrame.new(angles,
|
87
|
+
FXFrame.new(angles, :opts => FRAME_NONE)
|
87
88
|
end
|
88
89
|
|
89
90
|
def createColorsPage(panels, mdiclient)
|
@@ -91,33 +92,30 @@ class TabBook < FXTabBook
|
|
91
92
|
FXTabItem.new(panels, "Colors\tColors\tSwitch to color panel.")
|
92
93
|
|
93
94
|
# Colors page
|
94
|
-
colors = FXMatrix.new(panels, 2,
|
95
|
-
FRAME_RAISED|LAYOUT_FILL_Y|LAYOUT_CENTER_X|LAYOUT_TOP|LAYOUT_LEFT
|
96
|
-
|
97
|
-
colors.padRight = 10
|
98
|
-
colors.padTop = 10
|
99
|
-
colors.padBottom = 10
|
95
|
+
colors = FXMatrix.new(panels, 2,
|
96
|
+
MATRIX_BY_COLUMNS|FRAME_THICK|FRAME_RAISED|LAYOUT_FILL_Y|LAYOUT_CENTER_X|LAYOUT_TOP|LAYOUT_LEFT,
|
97
|
+
:padding => 10)
|
100
98
|
FXLabel.new(colors, "Background:", nil,
|
101
99
|
LAYOUT_RIGHT|LAYOUT_CENTER_Y|JUSTIFY_RIGHT)
|
102
100
|
FXColorWell.new(colors, 0, mdiclient, FXGLViewer::ID_BACK_COLOR,
|
103
|
-
COLORWELL_OPAQUEONLY|LAYOUT_TOP|LAYOUT_LEFT,
|
101
|
+
COLORWELL_OPAQUEONLY|LAYOUT_TOP|LAYOUT_LEFT, :padding => 0)
|
104
102
|
FXLabel.new(colors, "Ambient:", nil,
|
105
103
|
LAYOUT_RIGHT|LAYOUT_CENTER_Y|JUSTIFY_RIGHT)
|
106
104
|
FXColorWell.new(colors, 0, mdiclient, FXGLViewer::ID_AMBIENT_COLOR,
|
107
|
-
COLORWELL_OPAQUEONLY|LAYOUT_TOP|LAYOUT_LEFT,
|
105
|
+
COLORWELL_OPAQUEONLY|LAYOUT_TOP|LAYOUT_LEFT, :padding => 0)
|
108
106
|
|
109
107
|
FXLabel.new(colors, "Light Amb:", nil,
|
110
108
|
LAYOUT_RIGHT|LAYOUT_CENTER_Y|JUSTIFY_RIGHT)
|
111
109
|
FXColorWell.new(colors, 0, mdiclient, FXGLViewer::ID_LIGHT_AMBIENT,
|
112
|
-
COLORWELL_OPAQUEONLY|LAYOUT_TOP|LAYOUT_LEFT,
|
110
|
+
COLORWELL_OPAQUEONLY|LAYOUT_TOP|LAYOUT_LEFT, :padding => 0)
|
113
111
|
FXLabel.new(colors, "Light Diff:", nil,
|
114
112
|
LAYOUT_RIGHT|LAYOUT_CENTER_Y|JUSTIFY_RIGHT)
|
115
113
|
FXColorWell.new(colors, 0, mdiclient, FXGLViewer::ID_LIGHT_DIFFUSE,
|
116
|
-
COLORWELL_OPAQUEONLY|LAYOUT_TOP|LAYOUT_LEFT,
|
114
|
+
COLORWELL_OPAQUEONLY|LAYOUT_TOP|LAYOUT_LEFT, :padding => 0)
|
117
115
|
FXLabel.new(colors, "Light Spec:", nil,
|
118
116
|
LAYOUT_RIGHT|LAYOUT_CENTER_Y|JUSTIFY_RIGHT)
|
119
117
|
FXColorWell.new(colors, 0, mdiclient, FXGLViewer::ID_LIGHT_SPECULAR,
|
120
|
-
COLORWELL_OPAQUEONLY|LAYOUT_TOP|LAYOUT_LEFT,
|
118
|
+
COLORWELL_OPAQUEONLY|LAYOUT_TOP|LAYOUT_LEFT, :padding => 0)
|
121
119
|
end
|
122
120
|
|
123
121
|
def createSwitchesPage(panels, mdiclient)
|
@@ -125,12 +123,9 @@ class TabBook < FXTabBook
|
|
125
123
|
FXTabItem.new(panels, "Settings\tSettings\tSwitche to settings panel.")
|
126
124
|
|
127
125
|
# Settings page
|
128
|
-
settings = FXVerticalFrame.new(panels,
|
129
|
-
LAYOUT_FILL_Y|LAYOUT_CENTER_X|LAYOUT_TOP|LAYOUT_LEFT
|
130
|
-
|
131
|
-
settings.padRight = 10
|
132
|
-
settings.padTop = 10
|
133
|
-
settings.padBottom = 10
|
126
|
+
settings = FXVerticalFrame.new(panels,
|
127
|
+
FRAME_THICK|FRAME_RAISED|LAYOUT_FILL_Y|LAYOUT_CENTER_X|LAYOUT_TOP|LAYOUT_LEFT,
|
128
|
+
:padding => 10)
|
134
129
|
FXCheckButton.new(settings, "Lighting", mdiclient, FXGLViewer::ID_LIGHTING,
|
135
130
|
ICON_BEFORE_TEXT)
|
136
131
|
FXCheckButton.new(settings, "Fog", mdiclient, FXGLViewer::ID_FOG,
|
@@ -161,9 +156,9 @@ class GLViewWindow < FXMainWindow
|
|
161
156
|
begin
|
162
157
|
filename = File.join("icons", filename) + ".png"
|
163
158
|
icon = nil
|
164
|
-
File.open(filename, "rb")
|
159
|
+
File.open(filename, "rb") do |f|
|
165
160
|
icon = FXPNGIcon.new(getApp(), f.read)
|
166
|
-
|
161
|
+
end
|
167
162
|
icon
|
168
163
|
rescue
|
169
164
|
raise RuntimeError, "Couldn't load icon: #{filename}"
|
@@ -172,7 +167,7 @@ class GLViewWindow < FXMainWindow
|
|
172
167
|
|
173
168
|
def initialize(app)
|
174
169
|
# Initialize base class first
|
175
|
-
super(app, "OpenGL Example Application",
|
170
|
+
super(app, "OpenGL Example Application", :opts => DECOR_ALL, :width => 800, :height => 600)
|
176
171
|
|
177
172
|
# Define message identifiers for this class
|
178
173
|
|
@@ -194,22 +189,25 @@ class GLViewWindow < FXMainWindow
|
|
194
189
|
FXHorizontalSeparator.new(self,
|
195
190
|
LAYOUT_SIDE_TOP|SEPARATOR_GROOVE|LAYOUT_FILL_X);
|
196
191
|
toolbar = FXToolBar.new(self, LAYOUT_SIDE_TOP|LAYOUT_FILL_X,
|
197
|
-
|
192
|
+
:padLeft => 4, :padRight => 4, :padTop => 0, :padBottom => 0,
|
193
|
+
:hSpacing => 0, :vSpacing => 0)
|
198
194
|
|
199
195
|
# Make status bar
|
200
196
|
statusbar = FXStatusBar.new(self,
|
201
197
|
LAYOUT_SIDE_BOTTOM|LAYOUT_FILL_X|STATUSBAR_WITH_DRAGCORNER)
|
202
198
|
|
203
199
|
# The good old penguin, what would we be without it?
|
204
|
-
FXButton.new(statusbar,
|
200
|
+
FXButton.new(statusbar,
|
201
|
+
"\tHello, I'm Tux...\nThe symbol for the Linux Operating System.\nAnd all it stands for.",
|
202
|
+
:icon => peng, :opts => LAYOUT_RIGHT)
|
205
203
|
|
206
204
|
# Contents
|
207
205
|
frame = FXHorizontalFrame.new(self,
|
208
|
-
LAYOUT_SIDE_TOP|LAYOUT_FILL_X|LAYOUT_FILL_Y,
|
206
|
+
LAYOUT_SIDE_TOP|LAYOUT_FILL_X|LAYOUT_FILL_Y, :padding => 0, :hSpacing => 0, :vSpacing => 0)
|
209
207
|
|
210
208
|
# Nice sunken box around GL viewer
|
211
209
|
box = FXVerticalFrame.new(frame,
|
212
|
-
FRAME_SUNKEN|FRAME_THICK|LAYOUT_FILL_X|LAYOUT_FILL_Y,
|
210
|
+
FRAME_SUNKEN|FRAME_THICK|LAYOUT_FILL_X|LAYOUT_FILL_Y, :padding => 0)
|
213
211
|
|
214
212
|
# MDI Client
|
215
213
|
@mdiclient = FXMDIClient.new(box, LAYOUT_FILL_X|LAYOUT_FILL_Y)
|
@@ -299,14 +297,14 @@ class GLViewWindow < FXMainWindow
|
|
299
297
|
|
300
298
|
# Print
|
301
299
|
FXFrame.new(toolbar,
|
302
|
-
LAYOUT_TOP|LAYOUT_LEFT|LAYOUT_FIX_WIDTH|LAYOUT_FIX_HEIGHT,
|
300
|
+
LAYOUT_TOP|LAYOUT_LEFT|LAYOUT_FIX_WIDTH|LAYOUT_FIX_HEIGHT, :width => 4, :height => 20)
|
303
301
|
FXButton.new(toolbar, "\tPrint Image\tPrint shapshot image.",
|
304
302
|
loadIcon("printicon"), @mdiclient, FXGLViewer::ID_PRINT_IMAGE,
|
305
303
|
BUTTON_AUTOGRAY|FRAME_THICK|FRAME_RAISED|LAYOUT_TOP|LAYOUT_LEFT)
|
306
304
|
|
307
305
|
# Editing
|
308
306
|
FXFrame.new(toolbar,
|
309
|
-
LAYOUT_TOP|LAYOUT_LEFT|LAYOUT_FIX_WIDTH|LAYOUT_FIX_HEIGHT,
|
307
|
+
LAYOUT_TOP|LAYOUT_LEFT|LAYOUT_FIX_WIDTH|LAYOUT_FIX_HEIGHT, :width => 4, :height => 20)
|
310
308
|
FXButton.new(toolbar, "\tCut", loadIcon("cut"), @mdiclient,
|
311
309
|
FXGLViewer::ID_CUT_SEL, (BUTTON_AUTOGRAY|FRAME_THICK|FRAME_RAISED|
|
312
310
|
LAYOUT_TOP|LAYOUT_LEFT))
|
@@ -319,7 +317,7 @@ class GLViewWindow < FXMainWindow
|
|
319
317
|
|
320
318
|
# Projections
|
321
319
|
FXFrame.new(toolbar, (LAYOUT_TOP|LAYOUT_LEFT|
|
322
|
-
LAYOUT_FIX_WIDTH|LAYOUT_FIX_HEIGHT),
|
320
|
+
LAYOUT_FIX_WIDTH|LAYOUT_FIX_HEIGHT), :width => 8, :height => 20)
|
323
321
|
FXButton.new(toolbar, "\tPerspective\tSwitch to perspective projection.",
|
324
322
|
loadIcon("perspective"), @mdiclient, FXGLViewer::ID_PERSPECTIVE,
|
325
323
|
BUTTON_AUTOGRAY|FRAME_THICK|FRAME_RAISED|LAYOUT_TOP|LAYOUT_LEFT)
|
@@ -329,7 +327,7 @@ class GLViewWindow < FXMainWindow
|
|
329
327
|
|
330
328
|
# Shading model
|
331
329
|
FXFrame.new(toolbar, (LAYOUT_TOP|LAYOUT_LEFT|LAYOUT_FIX_WIDTH|
|
332
|
-
LAYOUT_FIX_HEIGHT),
|
330
|
+
LAYOUT_FIX_HEIGHT), :width => 8, :height => 20)
|
333
331
|
FXButton.new(toolbar, "\tNo shading\tTurn light sources off.",
|
334
332
|
loadIcon("nolight"), @mdiclient, FXGLShape::ID_SHADEOFF,
|
335
333
|
BUTTON_AUTOGRAY|FRAME_THICK|FRAME_RAISED|LAYOUT_TOP|LAYOUT_LEFT)
|
@@ -340,14 +338,14 @@ class GLViewWindow < FXMainWindow
|
|
340
338
|
loadIcon("smoothlight"), @mdiclient, FXGLShape::ID_SHADESMOOTH,
|
341
339
|
BUTTON_AUTOGRAY|FRAME_THICK|FRAME_RAISED|LAYOUT_TOP|LAYOUT_LEFT)
|
342
340
|
FXFrame.new(toolbar, (LAYOUT_TOP|LAYOUT_LEFT|LAYOUT_FIX_WIDTH|
|
343
|
-
LAYOUT_FIX_HEIGHT),
|
341
|
+
LAYOUT_FIX_HEIGHT), :width => 8, :height => 20)
|
344
342
|
FXToggleButton.new(toolbar, "\tToggle Light\tToggle light source.", nil,
|
345
343
|
loadIcon("nolight"), loadIcon("light"), nil, 0,
|
346
344
|
FRAME_THICK|FRAME_RAISED|LAYOUT_TOP|LAYOUT_LEFT)
|
347
345
|
|
348
346
|
# View orientation
|
349
347
|
FXFrame.new(toolbar, (LAYOUT_TOP|LAYOUT_LEFT|LAYOUT_FIX_WIDTH|
|
350
|
-
LAYOUT_FIX_HEIGHT),
|
348
|
+
LAYOUT_FIX_HEIGHT), :width => 8, :height => 20)
|
351
349
|
FXButton.new(toolbar, "\tFront View\tView objects from the front.",
|
352
350
|
loadIcon("frontview"), @mdiclient, FXGLViewer::ID_FRONT,
|
353
351
|
BUTTON_AUTOGRAY|FRAME_THICK|FRAME_RAISED|LAYOUT_TOP|LAYOUT_LEFT)
|
@@ -369,7 +367,7 @@ class GLViewWindow < FXMainWindow
|
|
369
367
|
|
370
368
|
# Miscellaneous buttons
|
371
369
|
FXFrame.new(toolbar, (LAYOUT_TOP|LAYOUT_LEFT|LAYOUT_FIX_WIDTH|
|
372
|
-
LAYOUT_FIX_HEIGHT),
|
370
|
+
LAYOUT_FIX_HEIGHT), :width => 8, :height => 20)
|
373
371
|
FXButton.new(toolbar, nil, loadIcon("zoom"), nil, 0,
|
374
372
|
FRAME_THICK|FRAME_RAISED|LAYOUT_TOP|LAYOUT_LEFT)
|
375
373
|
FXButton.new(toolbar, "\tColors\tDisplay color dialog.",
|
@@ -382,7 +380,7 @@ class GLViewWindow < FXMainWindow
|
|
382
380
|
|
383
381
|
# Dangerous delete a bit on the side
|
384
382
|
FXFrame.new(toolbar, (LAYOUT_TOP|LAYOUT_LEFT|LAYOUT_FIX_WIDTH|
|
385
|
-
LAYOUT_FIX_HEIGHT),
|
383
|
+
LAYOUT_FIX_HEIGHT), :width => 10, :height => 20)
|
386
384
|
FXButton.new(toolbar, "\tDelete\tDelete the selected object.",
|
387
385
|
loadIcon("kill"), @mdiclient, FXGLViewer::ID_DELETE_SEL,
|
388
386
|
BUTTON_AUTOGRAY|FRAME_THICK|FRAME_RAISED|LAYOUT_TOP|LAYOUT_LEFT)
|