I decided to whip up an 'ez-fox' implementation, just to see what it
would be like to use.

Turns out it's not much of an improvement over using Fox normally (due
to the way that fox makes you provide so much information to the
constructor). It looks slightly prettier, but not much.

The following implementation does, however, allow the use of basically
the whole Fox library in an EzGtk kind of way. It should be able to
translate easily to GTK to do the automagical stuff.

-----

require 'fox'

class EzFox
  def initialize
    @current = @theApp = Fox::FXApp.new
    @theApp.create
  end
  def use(object)
    temp, @current = @current, object
    yield object if block_given?
    @current = temp
  end
  def run
    @theApp.run
  end
  def createAndUse(clazz, *args, &proc)
    object = clazz.new(@current, *args)
    object.create
    @current.recalc if @current.respond_to? :recalc
    use object, &proc
    object
  end
  
  # Automagically create class creation methods and instance method
proxies
  # Should probably include an explicit list of classes, as this will
include things such as FXPoint, which wont work
  classes = Fox.constants.select { |x| x[0..1] == 'FX'}.collect { |x|
Fox.const_get(x) }.select { |x| x.class == Class }
  classes.each { |clazz|
    name = nil
    if /^Fox::FX[0-9]/ === clazz.to_s
      numbers = ['zero', 'one', 'two', 'three', 'four', 'five', 'six',
'seven', 'eight', 'nine']
      name = numbers[clazz.to_s[7..7].to_i] 
    else
      name = clazz.to_s[7..7].downcase
    end
    name = name + clazz.to_s[8..-1]
    class_eval %Q{
      def #{name} *args, &proc
        createAndUse #{clazz}, *args, &proc
      end
    }
  }
  classes.collect { |x| x.instance_methods; }.flatten.uniq.collect {
|name|
    if method_defined? name
      next
    elsif /=$/ === name
      class_eval %Q{
        def #{name}(value)
          @current.#{name}(value)
        end
      }
    else
      class_eval %Q{
        def #{name}(*args, &proc)
          @current.#{name}(*args) { |*args| proc.call *args if proc}
        end
      }
    end
  }
end

class Impl < EzFox
  include Fox
  def initialize
    super
    mainWindow("Window", nil, nil, DECOR_ALL, 0, 0, 400, 400) {
      show(PLACEMENT_SCREEN)
      verticalFrame (LAYOUT_FILL_X|LAYOUT_FILL_Y) {
        4.times { |x|
          button("button#{x}", nil, nil, 0,
BUTTON_NORMAL|LAYOUT_FILL_X|LAYOUT_FILL_Y) {
          }
        }
        use(FXButton.new(@current, "manually created button", nil, nil,
0, BUTTON_NORMAL|LAYOUT_FILL_X|LAYOUT_FILL_Y)) {
          create
          connect(SEL_COMMAND) { puts "manually created button pressed"
}
        }
      }
    }
  end
end

Impl.new.run

-----

For comparison, the following could would do the same thing in Fox
normally:

class Impl
  include Fox
  def initialize
    FXApp.new { |@theApp|
      FXMainWindow.new(theApp, "Window", nil, nil, DECOR_ALL, 0, 0, 400,
400) { |@mainWindow|
        FXVerticalFrame.new(@mainWindow, LAYOUT_FILL_X|LAYOUT_FILL_Y) {
|verticalFrame|
          4.times { |x|
            FXButton.new(verticalFrame, "button#{x}", nil, nil, 0,
BUTTON_NORMAL|LAYOUT_FILL_X|LAYOUT_FILL_Y)
          }
          FXButton.new(@current, "manually created button", nil, nil, 0,
BUTTON_NORMAL|LAYOUT_FILL_X|LAYOUT_FILL_Y) { |button|
            button.connect(SEL_COMMAND) { puts "manually created button
pressed" }
        }
      }
      theApp.create
      @mainWindow.show(PLACEMENT_SCREEN)
    }
  end
  def run
    @theApp.run
  end
end
#####################################################################################
This email has been scanned by MailMarshal, an email content filter.
#####################################################################################