wxruby-ruby19 1.9.10-x86-mingw32 → 2.0.0-x86-mingw32

Sign up to get free protection for your applications and to get access to all the features.
@@ -5,16 +5,21 @@
5
5
  # * get_position()
6
6
  # * set_size(a_size)
7
7
  # * is_checked()
8
+ # * can_undo()
9
+ # * has_style(a_style)
8
10
  #
9
11
  # and so on. Methods that retrieve set, or query attributes of an object
10
- # are more normally in Ruby called simply by the attribute name:
12
+ # are more normally in Ruby called simply by the attribute name, or, in
13
+ # other cases, with a predicate method:
11
14
  #
12
- # * position()
13
- # * size = a_size
14
- # * checked?
15
+ # * pos = my_widget.position
16
+ # * my_widget.size = a_size
17
+ # * my_widget.checked?
18
+ # * my_widget.can_undo?
19
+ # * my_widget.has_style?
15
20
  #
16
21
  # This extension creates an alias for every WxRuby instance method that
17
- # begins with +get_+, +set_+ or +is_+. Note that if you are calling a
22
+ # begins with +get_+, +set_+, +is_+, +can_+ and +has_+. Note that if you are calling a
18
23
  # 'setter' method on self, you must explicitly send the message to self:
19
24
  #
20
25
  # # set's self size to be 100px by 100px
@@ -23,11 +28,18 @@
23
28
  # size = Wx::Size.new
24
29
 
25
30
  module WxRubyStyleAccessors
31
+ # Ruby-style method named are implemented by method-missing; if an
32
+ # unknown method is called, see if it is a rubyish name for a real
33
+ # method. In principle it would be possible to set up real aliases for
34
+ # them at start-up, but in practice this is far too slow for all the
35
+ # classes that need to be started up.
26
36
  def method_missing(sym, *args)
27
37
  case sym.to_s
28
- when /^(.*)\=$/
38
+ when /^(\w+)\=$/
29
39
  meth = "set_#{$1}"
30
- when /^(.*)\?$/
40
+ when /^((?:has|can)\w+)\?$/
41
+ meth = $1
42
+ when /^(\w+)\?$/
31
43
  meth = "is_#{$1}"
32
44
  else
33
45
  meth = "get_#{sym}"
@@ -25,6 +25,9 @@ class Wx::Bitmap
25
25
  new(img, depth)
26
26
  end
27
27
 
28
+ # Ruby methods that switch class are conventionally named to_foo
29
+ alias :to_image :convert_to_image
30
+
28
31
  # Redefine the initialize method so it raises an exception if a
29
32
  # non-existent file is given to the constructor; otherwise, wx Widgets
30
33
  # just carries on with an empty bitmap, which may cause faults
@@ -1,8 +1,4 @@
1
1
  class Wx::Clipboard
2
- # See if we like these better
3
- alias :place :set_data
4
- alias :fetch :get_data
5
-
6
2
  class << self
7
3
  # This is provided internally by the SWIG interface file, but all
8
4
  # public access should be via Clipboard.open; see below
@@ -29,4 +25,32 @@ class Wx::Clipboard
29
25
  clip.close if clip
30
26
  end
31
27
  end
28
+
29
+ # Need to do some internal record-keeping to protect data objects on
30
+ # the clipboard from garbage collection
31
+ @@__clip_data = []
32
+
33
+ # These methods affect the clipboard contents; each time, update the
34
+ # record with the changed data contents
35
+ wx_add_data = instance_method(:add_data)
36
+ define_method(:add_data) do | the_data |
37
+ @@__clip_data << the_data
38
+ wx_add_data.bind(self).call(the_data)
39
+ end
40
+
41
+ wx_clear = instance_method(:clear)
42
+ define_method(:clear) do
43
+ @@__clip_data.clear
44
+ wx_clear.bind(self).call
45
+ end
46
+
47
+ wx_set_data = instance_method(:set_data)
48
+ define_method(:set_data) do | the_data |
49
+ @@__clip_data = [ the_data ]
50
+ wx_set_data.bind(self).call(the_data)
51
+ end
52
+
53
+ # Aliases, more clearly expressive?
54
+ alias :place :set_data
55
+ alias :fetch :get_data
32
56
  end
@@ -17,6 +17,11 @@ class Wx::Image
17
17
  bmp.convert_to_image
18
18
  end
19
19
 
20
+ # Ruby methods that switch class are conventionally named to_foo
21
+ def to_bitmap
22
+ Wx::Bitmap.from_image(self)
23
+ end
24
+
20
25
  # Redefine the initialize method so it raises an exception if a
21
26
  # non-existent file is given to the constructor; otherwise, wx Widgets
22
27
  # just carries on with an invalid image, which may cause faults
@@ -2,20 +2,23 @@
2
2
  class Wx::ToolBar
3
3
  # Generic method to add items, supporting positional and named
4
4
  # arguments
5
- ADD_ITEM_PARAMS = [ Wx::Parameter[ :position, -1 ],
5
+ ADD_ITEM_PARAMS = [
6
+ Wx::Parameter[ :bitmap2, Wx::NULL_BITMAP ],
7
+ Wx::Parameter[ :position, -1 ],
6
8
  Wx::Parameter[ :id, -1 ],
7
9
  Wx::Parameter[ :label, "" ],
8
- Wx::Parameter[ :bitmap2, Wx::NULL_BITMAP ],
9
10
  Wx::Parameter[ :kind, Wx::ITEM_NORMAL ],
10
11
  Wx::Parameter[ :short_help, "" ],
11
12
  Wx::Parameter[ :long_help, "" ],
12
13
  Wx::Parameter[ :client_data, nil ] ]
13
14
 
14
- def add_item(bitmap, *mixed_args)
15
+ def add_item(bitmap1, *mixed_args)
15
16
  args = Wx::args_as_list(ADD_ITEM_PARAMS, *mixed_args)
16
17
 
18
+ bitmap2 = args.shift
17
19
  pos = args.shift
18
- args.insert(2, bitmap)
20
+ args.insert(2, bitmap1)
21
+ args.insert(3, bitmap2)
19
22
 
20
23
  # Call add_tool to append if default position
21
24
  if pos == -1
@@ -0,0 +1,7 @@
1
+ class Wx::Validator
2
+ # Default implementation of clone, may need to be over-ridden in
3
+ # custom subclasses should state variables need to be copied
4
+ def clone
5
+ self.class.new
6
+ end
7
+ end
@@ -246,8 +246,25 @@ Wx::define_keyword_ctors('FindReplaceDialog') do
246
246
  wx_ctor_params :style
247
247
  end
248
248
 
249
- # wxMultiChoiceDialog Dialog to get one or more selections from a list
250
- # wxSingleChoiceDialog Dialog to get a single selection from a list and return the string
249
+ # Dialog to get one or more selections from a list
250
+ Wx::define_keyword_ctors('MultiChoiceDialog') do
251
+ wx_ctor_params :message => ''
252
+ wx_ctor_params :caption => ''
253
+ wx_ctor_params :choices => []
254
+ wx_ctor_params :style => Wx::DEFAULT_DIALOG_STYLE|Wx::RESIZE_BORDER|
255
+ Wx::OK|Wx::CANCEL|Wx::CENTRE
256
+ wx_ctor_params :pos
257
+ end
258
+
259
+ # Dialog to get a single selection from a list and return the string
260
+ Wx::define_keyword_ctors('SingleChoiceDialog') do
261
+ wx_ctor_params :message => ''
262
+ wx_ctor_params :caption => ''
263
+ wx_ctor_params :choices => []
264
+ wx_ctor_params :style => Wx::DEFAULT_DIALOG_STYLE|Wx::RESIZE_BORDER|
265
+ Wx::OK|Wx::CANCEL|Wx::CENTRE
266
+ wx_ctor_params :pos
267
+ end
251
268
 
252
269
  # Dialog to get a single line of text from the user
253
270
  Wx::define_keyword_ctors('TextEntryDialog') do
@@ -1,3 +1,3 @@
1
1
  module Wx
2
- WXRUBY_VERSION = '1.9.10'
2
+ WXRUBY_VERSION = '2.0.0'
3
3
  end
Binary file
@@ -169,37 +169,37 @@ class SettingsPanel < Wx::Panel
169
169
 
170
170
 
171
171
  def update_colours()
172
- art = @frame.get_dock_art
172
+ art = @frame.dock_art
173
173
 
174
- col = art.get_color(Wx::AUI_DOCKART_BACKGROUND_COLOUR)
175
- @bckg_colour.set_bitmap_label( create_colour_bitmap(col) )
174
+ col = art.colour(Wx::AUI_DOCKART_BACKGROUND_COLOUR)
175
+ @bckg_colour.bitmap_label = ( create_colour_bitmap(col) )
176
176
 
177
- col = art.get_color(Wx::AUI_DOCKART_SASH_COLOUR)
178
- @sash_colour.set_bitmap_label( create_colour_bitmap(col) )
177
+ col = art.colour(Wx::AUI_DOCKART_SASH_COLOUR)
178
+ @sash_colour.bitmap_label = ( create_colour_bitmap(col) )
179
179
 
180
- col = art.get_color(Wx::AUI_DOCKART_INACTIVE_CAPTION_COLOUR)
181
- @capt_colour.set_bitmap_label( create_colour_bitmap(col) )
180
+ col = art.colour(Wx::AUI_DOCKART_INACTIVE_CAPTION_COLOUR)
181
+ @capt_colour.bitmap_label = ( create_colour_bitmap(col) )
182
182
 
183
- col = art.get_color(Wx::AUI_DOCKART_INACTIVE_CAPTION_GRADIENT_COLOUR)
184
- @capt_gradnt.set_bitmap_label( create_colour_bitmap(col) )
183
+ col = art.colour(Wx::AUI_DOCKART_INACTIVE_CAPTION_GRADIENT_COLOUR)
184
+ @capt_gradnt.bitmap_label = ( create_colour_bitmap(col) )
185
185
 
186
- col = art.get_color(Wx::AUI_DOCKART_INACTIVE_CAPTION_TEXT_COLOUR)
187
- @capt_text.set_bitmap_label( create_colour_bitmap(col) )
186
+ col = art.colour(Wx::AUI_DOCKART_INACTIVE_CAPTION_TEXT_COLOUR)
187
+ @capt_text.bitmap_label = ( create_colour_bitmap(col) )
188
188
 
189
- col = art.get_color(Wx::AUI_DOCKART_ACTIVE_CAPTION_COLOUR)
190
- @acap_colour.set_bitmap_label( create_colour_bitmap(col) )
189
+ col = art.colour(Wx::AUI_DOCKART_ACTIVE_CAPTION_COLOUR)
190
+ @acap_colour.bitmap_label = ( create_colour_bitmap(col) )
191
191
 
192
- col = art.get_color(Wx::AUI_DOCKART_ACTIVE_CAPTION_GRADIENT_COLOUR)
193
- @acap_gradnt.set_bitmap_label( create_colour_bitmap(col) )
192
+ col = art.colour(Wx::AUI_DOCKART_ACTIVE_CAPTION_GRADIENT_COLOUR)
193
+ @acap_gradnt.bitmap_label = ( create_colour_bitmap(col) )
194
194
 
195
- col = art.get_color(Wx::AUI_DOCKART_ACTIVE_CAPTION_TEXT_COLOUR)
196
- @acap_text.set_bitmap_label( create_colour_bitmap(col) )
195
+ col = art.colour(Wx::AUI_DOCKART_ACTIVE_CAPTION_TEXT_COLOUR)
196
+ @acap_text.bitmap_label = ( create_colour_bitmap(col) )
197
197
 
198
- col = art.get_color(Wx::AUI_DOCKART_SASH_COLOUR)
199
- @brdr_colour.set_bitmap_label( create_colour_bitmap(col) )
198
+ col = art.colour(Wx::AUI_DOCKART_SASH_COLOUR)
199
+ @brdr_colour.bitmap_label = ( create_colour_bitmap(col) )
200
200
 
201
- col = art.get_color(Wx::AUI_DOCKART_GRIPPER_COLOUR)
202
- @grip_colour.set_bitmap_label( create_colour_bitmap(col) )
201
+ col = art.colour(Wx::AUI_DOCKART_GRIPPER_COLOUR)
202
+ @grip_colour.bitmap_label = ( create_colour_bitmap(col) )
203
203
  end
204
204
 
205
205
  def on_pane_border_size(event)
@@ -41,7 +41,7 @@ class MyCalendar < CalendarCtrl
41
41
 
42
42
  def on_calendar_change(event)
43
43
  @date = event.date
44
- log_status("Selected date: #{@date.strftime('%Y-%M-%D')}")
44
+ log_status("Selected date: #{@date.strftime('%A %d %B %Y')}")
45
45
  end
46
46
 
47
47
  def on_cal_month_change
@@ -11,14 +11,20 @@ require 'wx'
11
11
  # This sample demonstrates how to draw an image from a file onto a
12
12
  # window. This one uses a small PNG file, but other formats such as JPEG
13
13
  # are supported - see documentation for more details.
14
+ #
15
+ # This sample uses the Wx::Bitmap class, which is a platform-specific
16
+ # representation of an image. This is the class that must be used to
17
+ # display an image, but see also Wx::Image, which allows a much wider
18
+ # range of manipulations (such as rescaling) and writing to files.
19
+
14
20
 
15
21
  class ImageFrame < Wx::Frame
16
22
  def initialize
17
23
  super(nil, :title => 'Simple image demo')
18
24
 
19
25
  # Load a PNG bitmap from a file for drawing
20
- img_file = File.join( File.dirname(__FILE__), 'paperclip.png')
21
- @bitmap = Wx::Bitmap.new(img_file, Wx::BITMAP_TYPE_PNG)
26
+ img_file = File.join( File.dirname(__FILE__), 'wxruby-logo.png')
27
+ @bitmap = Wx::Bitmap.new(img_file)
22
28
 
23
29
  # Set up the drawing to be done when the frame needs re-painting
24
30
  evt_paint :on_paint
@@ -26,7 +32,8 @@ class ImageFrame < Wx::Frame
26
32
 
27
33
  def on_paint
28
34
  paint do | dc |
29
- dc.draw_bitmap(@bitmap, 0, 0, false)
35
+ # Draw the bitmap at offset 10px, 10px, with no transparency
36
+ dc.draw_bitmap(@bitmap, 10, 10, false)
30
37
  end
31
38
  end
32
39
  end
@@ -0,0 +1,92 @@
1
+ #!/usr/bin/env ruby
2
+ # wxRuby2 Sample Code. Copyright (c) 2004-2008 wxRuby development team
3
+ # Freely reusable code: see SAMPLES-LICENSE.TXT for details
4
+ begin
5
+ require 'rubygems'
6
+ rescue LoadError
7
+ end
8
+ require 'wx'
9
+
10
+ # Bitmap sample (rewritten by Chauk-Mean Proum)
11
+
12
+ # This sample demonstrates how to draw the same image in various forms
13
+ # (original, mirrored, greyscaled and blurred).
14
+ #
15
+ # This sample uses :
16
+ # - Wx::Image, which allows a wide range of manipulations such as rescaling
17
+ # and writing to files.
18
+ # - Wx::Bitmap, which is a platform-specific representation of an image.
19
+ # This is the class that must be used to actually display an image.
20
+
21
+ class ImageFrame < Wx::Frame
22
+ def initialize
23
+ super(nil, :title => 'Simple image demo', :size => [600, 600])
24
+
25
+ # Create the various images from the bitmap file
26
+ img_file = File.join( File.dirname(__FILE__), 'ruby-logo.jpg')
27
+ @image = Wx::Image.new(img_file)
28
+ @mirrored_image = Wx::Image.new(img_file).mirror
29
+ @greyscaled_image = Wx::Image.new(img_file).convert_to_greyscale
30
+ @blurred_image = Wx::Image.new(img_file).blur(15)
31
+
32
+ # Create the corresponding bitmaps
33
+ compute_bitmaps
34
+
35
+ # Set up event handling
36
+ evt_size :on_size
37
+ evt_idle :on_idle
38
+ evt_paint :on_paint
39
+ end
40
+
41
+ # Create a bitmap for the specified image and size
42
+ def compute_bitmap image, width, height
43
+ rescaled_image = Wx::Image.new(image).rescale(width, height)
44
+ rescaled_image.to_bitmap
45
+ end
46
+
47
+ # Create the bitmaps corresponding to the images and with half the size of the frame
48
+ def compute_bitmaps
49
+ width = client_size.x / 2
50
+ height = client_size.y / 2
51
+ @bitmap1 = compute_bitmap(@image, width, height)
52
+ @bitmap2 = compute_bitmap(@mirrored_image, width, height)
53
+ @bitmap3 = compute_bitmap(@greyscaled_image, width, height)
54
+ @bitmap4 = compute_bitmap(@blurred_image, width, height)
55
+ @done = true
56
+ end
57
+
58
+ # Note to recompute the bitmaps on a resize
59
+ def on_size(event)
60
+ @done = false
61
+ event.skip
62
+ end
63
+
64
+ # Recompute the bitmaps if needed, then do a refresh
65
+ def on_idle
66
+ if not @done
67
+ compute_bitmaps
68
+ refresh
69
+ end
70
+ end
71
+
72
+ # Paint the frame with the bitmaps
73
+ def on_paint
74
+ paint do | dc |
75
+
76
+ if @done
77
+ width = client_size.x / 2
78
+ height = client_size.y / 2
79
+ dc.draw_bitmap(@bitmap1, 0, 0, false)
80
+ dc.draw_bitmap(@bitmap2, width, 0, false)
81
+ dc.draw_bitmap(@bitmap3, 0, height, false)
82
+ dc.draw_bitmap(@bitmap4, width, height, false)
83
+ end
84
+
85
+ end
86
+ end
87
+ end
88
+
89
+ Wx::App.run do
90
+ ImageFrame.new.show
91
+ end
92
+
@@ -0,0 +1,265 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # wxRuby2 Sample Code. Copyright (c) 2004-2009 wxRuby development team
4
+ # Freely reusable code: see SAMPLES-LICENSE.TXT for details
5
+
6
+ require 'wx'
7
+ include Wx
8
+ include Math
9
+
10
+ # This sample was originally written by Alex Fenton as an answer to Ruby
11
+ # Quiz #191, which challenged entrants to create an application which
12
+ # could draw images based on mathematical functions:
13
+ #
14
+ # http://rubyquiz.strd6.com/quizzes/191/
15
+ #
16
+ # To use the application, enter functions which take input values of x
17
+ # and y from 0 to 1, and return intensities of red, green and blue. If a
18
+ # bad function is entered, a cross is displayed; hover over this to get
19
+ # a hint on the problem.
20
+ #
21
+ # The sample demonstrates some uses of the Wx::Image class, a
22
+ # platform-independent representation of an image which can be
23
+ # manipulated (for example, resizing) and written to files in various
24
+ # formats. It also shows how an image's data can be written directly, by
25
+ # using Array#pack.
26
+
27
+ # A canvas that draws and displays a mathematically generated image
28
+ class MathsDrawing < Window
29
+ # The functions which return the colour components at each pixel
30
+ attr_writer :red, :green, :blue
31
+ # The time taken to render, whether re-rendering is needed, and the
32
+ # source image
33
+ attr_reader :render_time, :done, :img
34
+
35
+ def initialize(parent)
36
+ super(parent)
37
+ # Create a dummy image
38
+ @default_image = Image.new(1, 1)
39
+ @default_image.data = [255, 255, 255].pack('CCC')
40
+ @img = @default_image
41
+
42
+ @red = lambda { | x, y | 1 }
43
+ @green = lambda { | x, y | 1 }
44
+ @blue = lambda { | x, y | 1 }
45
+
46
+ @done = true
47
+
48
+ evt_size :on_size
49
+ evt_paint :on_paint
50
+ evt_idle :on_idle
51
+ end
52
+
53
+ # Paint the image on the screen. The actual image rendering is done in
54
+ # idle time, so that the GUI is responsive whilst redrawing - eg, when
55
+ # resized. Painting is done by quickly rescaling the cached image.
56
+ def on_paint
57
+ paint do | dc |
58
+ draw_img = @img.scale(client_size.x, client_size.y)
59
+ dc.draw_bitmap(draw_img.convert_to_bitmap, 0, 0, true)
60
+ end
61
+ end
62
+
63
+ # Regenerate the image if needed, then do a refresh
64
+ def on_idle
65
+ if not @done
66
+ @img = make_image
67
+ refresh
68
+ end
69
+ @done = true
70
+ end
71
+
72
+ # Note to regenerate the image if the canvas has been resized
73
+ def on_size(event)
74
+ @done = false
75
+ event.skip
76
+ end
77
+
78
+ # Call this to force a re-render - eg if the functions have changed
79
+ def redraw
80
+ @done = false
81
+ end
82
+
83
+ # Actually make the image
84
+ def make_image
85
+ size_x, size_y = client_size.x, client_size.y
86
+ if size_x < 1 or size_y < 1
87
+ return @default_image
88
+ end
89
+
90
+ start_time = Time.now
91
+ # The string holding raw image data
92
+ data = ''
93
+ x_factor = size_x.to_f
94
+ y_factor = size_y.to_f
95
+
96
+ # Input values from the range 0 to 1, with origin in the bottom left
97
+ (size_y - 1).downto(0) do | y |
98
+ the_y = y.to_f / y_factor
99
+ 0.upto(size_x - 1) do | x |
100
+ the_x = x.to_f / x_factor
101
+ red = @red.call(the_x, the_y) * 255
102
+ green = @green.call(the_x, the_y) * 255
103
+ blue = @blue.call(the_x, the_y) * 255
104
+ data << [red, green, blue].pack("CCC")
105
+ end
106
+ end
107
+ img = Image.new(size_x, size_y)
108
+ img.data = data
109
+ @render_time = Time.now - start_time
110
+ img
111
+ end
112
+ end
113
+
114
+ # A helper dialog for saving the image to a file
115
+ class SaveImageDialog < FileDialog
116
+ # The image file formats on offer
117
+ TYPES = [ [ "PNG file (*.png)|*.png", BITMAP_TYPE_PNG ],
118
+ [ "TIF file (*.tif)|*.tif", BITMAP_TYPE_TIF ],
119
+ [ "BMP file (*.bmp)|*.bmp", BITMAP_TYPE_BMP ] ]
120
+
121
+ WILDCARD = TYPES.map { | type | type.first }.join("|")
122
+
123
+ def initialize(parent)
124
+ super(parent, :wildcard => WILDCARD,
125
+ :message => 'Save Image',
126
+ :style => FD_SAVE|FD_OVERWRITE_PROMPT)
127
+ end
128
+
129
+ # Returns the Wx identifier for the selected image type.
130
+ def image_type
131
+ TYPES[filter_index].last
132
+ end
133
+ end
134
+
135
+ # A Panel for displaying the image and controls to manipulate it
136
+ class MathsPanel < Panel
137
+ # Set functions to some nice initial values
138
+ RED_INITIAL = "cos(x)"
139
+ GREEN_INITIAL = "cos(y ** x)"
140
+ BLUE_INITIAL = "(x ** 4) + ( y ** 3 ) - (4.5 * x ** 2 ) + ( y * 2)"
141
+
142
+ # Symbols to show correct and incorrect functions
143
+ TICK = "\xE2\x9C\x94"
144
+ CROSS = "\xE2\x9C\x98"
145
+
146
+ attr_reader :drawing
147
+
148
+ def initialize(parent)
149
+ super(parent)
150
+ self.sizer = VBoxSizer.new
151
+ # The canvas
152
+ @drawing = MathsDrawing.new(self)
153
+ sizer.add @drawing, 1, GROW
154
+
155
+ sizer.add Wx::StaticLine.new(self)
156
+
157
+ # The text controls for entering functions
158
+ grid_sz = FlexGridSizer.new(3, 8, 8)
159
+ grid_sz.add_growable_col(1, 1)
160
+
161
+ grid_sz.add StaticText.new(self, :label => "Red")
162
+ @red_tx = TextCtrl.new(self, :value => RED_INITIAL)
163
+ grid_sz.add @red_tx, 0, GROW
164
+ @red_err = StaticText.new(self, :label => TICK)
165
+ grid_sz.add @red_err, 0, ALIGN_CENTRE
166
+
167
+ grid_sz.add StaticText.new(self, :label => "Green")
168
+ @green_tx = TextCtrl.new(self, :value => GREEN_INITIAL)
169
+ grid_sz.add @green_tx, 0, GROW
170
+ @green_err = StaticText.new(self, :label => TICK)
171
+ grid_sz.add @green_err, 0, ALIGN_CENTRE
172
+
173
+ grid_sz.add StaticText.new(self, :label => "Blue")
174
+ @blue_tx = TextCtrl.new(self, :value => BLUE_INITIAL)
175
+ grid_sz.add @blue_tx, 0, GROW
176
+ @blue_err = StaticText.new(self, :label => TICK)
177
+ grid_sz.add @blue_err, 0, ALIGN_CENTRE
178
+
179
+ # Buttons to save and render
180
+ grid_sz.add nil
181
+ butt_sz = HBoxSizer.new
182
+ render_bt = Button.new(self, :label => "Render")
183
+ butt_sz.add render_bt, 0, Wx::RIGHT, 8
184
+ evt_button render_bt, :on_render
185
+
186
+ save_bt = Button.new(self, :label => "Save Image")
187
+ butt_sz.add save_bt, 0, Wx::RIGHT, 8
188
+ evt_button save_bt, :on_save
189
+
190
+ # Disable the buttons whilst redrawing
191
+ evt_update_ui(render_bt) { | evt | evt.enable(@drawing.done) }
192
+ evt_update_ui(save_bt) { | evt | evt.enable(@drawing.done) }
193
+ grid_sz.add butt_sz
194
+
195
+ # Add the controls sizer to the whole thing
196
+ sizer.add grid_sz, 0, GROW|ALL, 10
197
+
198
+ on_render
199
+ end
200
+
201
+ # Update the functions that generate the image, then re-render it
202
+ def on_render
203
+ @drawing.red = make_a_function(@red_tx.value, @red_err)
204
+ @drawing.green = make_a_function(@green_tx.value, @green_err)
205
+ @drawing.blue = make_a_function(@blue_tx.value, @blue_err)
206
+ @drawing.redraw
207
+ end
208
+
209
+ # Display a dialog to save the image to a file
210
+ def on_save
211
+ dlg = SaveImageDialog.new(parent)
212
+ if dlg.show_modal == ID_OK
213
+ @drawing.img.save_file(dlg.path, dlg.image_type)
214
+ end
215
+ end
216
+
217
+ # A function which doesn't do anything
218
+ NULL_FUNC = lambda { | x, y | 1 }
219
+
220
+ # Takes a string source +source+, returns a lambda. If the string
221
+ # source isn't valid, flag this in the GUI static text +error_outlet+
222
+ def make_a_function(source, error_outlet)
223
+ return NULL_FUNC if source.empty?
224
+ func = nil
225
+ begin
226
+ # Create the function and test it, to check for wrong names
227
+ func = eval "lambda { | x, y | #{source} }"
228
+ func.call(0, 0)
229
+ rescue Exception => e
230
+ error_outlet.label = CROSS
231
+ error_outlet.tool_tip = e.class.name + ":\n" +
232
+ e.message.sub(/^\(eval\):\d+: /, '')
233
+ return NULL_FUNC
234
+ end
235
+
236
+ # Things are good, note this and return the function
237
+ error_outlet.label = TICK
238
+ error_outlet.tool_tip = ''
239
+ func
240
+ end
241
+ end
242
+
243
+ class MathsFrame < Frame
244
+ def initialize
245
+ super(nil, :title => 'Maths drawing',
246
+ :size => [400, 500],
247
+ :pos => [50, 50])
248
+ sb = create_status_bar(1)
249
+ evt_update_ui sb, :on_update_status
250
+ @panel = MathsPanel.new(self)
251
+ end
252
+
253
+ def on_update_status
254
+ if @panel.drawing.done
255
+ pixels = @panel.drawing.client_size
256
+ msg = "[#{pixels.x} x #{pixels.y}] drawing completed in " +
257
+ "#{@panel.drawing.render_time}s"
258
+ status_bar.status_text = msg
259
+ end
260
+ end
261
+ end
262
+
263
+ App.run do
264
+ MathsFrame.new.show
265
+ end