Swiby もどき
まるごとRuby! vol.1(isbn:9784844325796) の JRuby の紹介を呼んでいて、Swiby という Swing を扱うためのライブラリを知る。その DSL になんかちょっとくすぐられたので、VisualuRuby をラップしてそれっぽいものをでっちあげて見た。
こんな感じや、
api-ordinally.rb
require 'swiby' include Swiby window = Frame.new window.title = "Hello World" window.width = 200 window.height = 100 label = Label.new label.text = "Hello World" window.content = label window.visible = true
こんな感じで動く。
api-dsl.rb
require 'swiby' include Swiby frame do title "Hello World2" width 200 height 100 content do label do label "Hello World" end end visible true end
ライブラリ。Frame と Label しかないとか…どんだけ貧相なんだ。
コントロールの配置はめんどくなったので VRVertLayoutManager に丸投げ。
なので見た目がそれっぽいのはコントロールがいっこのときだけ。
…。
swiby.rb
require 'vr/vruby' require 'vr/vrcontrol' require 'vr/vrlayout' module Swiby def self.lazy_initializees @lazy_initializees ||= [] end at_exit do Swiby.lazy_initializees.each{|form| form.lazy_initialize } VRLocalScreen.messageloop end # # Components # class Frame < VRForm include VRVertLayoutManager def self.new VRLocalScreen.newform(nil, nil, self).tap do |form| Swiby.lazy_initializees << form end end def lazy_initialize create show self.swin_visible = visible end def construct if content [*content].each_with_index do |control, i| addControl(control.as_vr_class, "control#{i}", control.caption) end end end attr_accessor :content alias swin_visible= visible= attr_accessor :visible alias title= caption= alias width w alias height h def width=(w) move(x, y, w, h) end def height=(h) move(x, y, w, h) end end #class Frame class Label attr_accessor :text def as_vr_class VRStatic end def caption text end end #class Label # # DSL System # def frame(&block) Swiby::DSL::Frame.evaluate(&block).object end module_function :frame module DSL class DSLObject def self.evaluate(&block) new.tap do |i| i.instance_eval(&block) end end attr_reader :object end class Frame < DSLObject def initialize @object = Swiby::Frame.new end [:title, :width, :height, :visible].each do |name| define_method(name){|v| object.__send__("#{name}=", v) } end def content(&block) object.content = Content.evaluate(&block).object end end #class Frame class Content < DSLObject def initialize @object = [] end def label(&block) object << Label.evaluate(&block).object end end #class DSLObject class Label < DSLObject def initialize @object = Swiby::Label.new end def label(str) object.text = str end end #class Label end #module DSL end #module Swiby