ruby/tkを設定ウインドウに使いたい。

日本語の入力をしたいと思い ruby/tk を試した。
インストールは
sudo apt-get install libtcltk-ruby

Tk.mainloopを終わらせた後に、再度Tk.mainloopだと、エラーがでる。
やっと見つけた。
http://bibibi.info/d/20071213.html
なんとか、Okだ。
Tk.chooseColorを使うとエラーがでる。
これは、保留だ。
で、

text = ''
TkCore::INTERP.restart
TkLabel.new(nil, 'text'=>'Input Text.').pack
entry = TkEntry.new.pack
TkButton.new(nil, 'text'=>'OK', 'command'=>proc{ text = entry.value; Tk.exit}).pack
Tk.mainloop
text

こんな感じで使う。
ruby/tkを設定用のウインドウに使うのは、楽でいいなと思う。
これで、使いかってのよさが、上がった。


#!usr/bin/env ruby

require 'rubygems'
require 'sdl'
require 'cairo'
require 'tk'

class EventHandle
def initialize(hash)
struct = Struct.new(:event,:const,:method)
@handle = {}
hash.each do |key,value|
event,const = key
if const
if event == SDL::Event::KeyDown || event == SDL::Event::KeyUp
@handle[struct.new(event,const,:sym)] = value
elsif event == SDL::Event::MouseButtonDown || event == SDL::Event::MouseButtonUp
@handle[struct.new(event,const,:button)] = value
end
else
@handle[struct.new(event)] = value
end
end
end

def match?(key,event)
if key.const
event.kind_of?(key.event) && key.const == event.method(key.method).call
else
event.kind_of?(key.event)
end
end

def handling(event)
@handle.each do |key,value|
return value.call(event) if match?(key,event)
end
nil
end
end

class Display
attr_reader :text

def initialize(screen)
@screen = screen
@x,@y = 20,20
end

def text=(text)
@text = text
@width,@height = 300,80
@stride = Cairo::Format.stride_for_width(C_FORMAT,@width)
@surface = SDL::Surface.new_from(image.data,@width,@height,32,@stride,R,G,B,A)
end

def image
img = Cairo::ImageSurface.new(C_FORMAT,@width,@height)
Cairo::Context.new(img) do |c|
c.set_source_color(Cairo::Color::LIGHT_SEA_GREEN)
c.font_size = 30
c.move_to(20,30)
c.show_text(@text)
end
img
end

def update
@screen.put(@surface,@x,@y)
end
end

class Label
attr_writer :x,:y
attr_reader :handle

def initialize(screen)
@screen = screen
@handle = EventHandle.new(
SDL::Event::MouseMotion => proc{|event| mouse_motion(event)},
[SDL::Event::MouseButtonDown,SDL::Mouse::BUTTON_LEFT] => proc{|event| mouse_button_down(event)},
[SDL::Event::MouseButtonUp,SDL::Mouse::BUTTON_LEFT] => proc{|event| mouse_motion(event)}
)
end

def text=(text)
@text = text
@width,@height = 80,30
@stride = Cairo::Format.stride_for_width(C_FORMAT,@width)
@surface = {}
@surface_key = :up
{
:on => Cairo::Color::YELLOW,
:up => Cairo::Color::SNOW,
:down => Cairo::Color::RED
}.each do |key,value|
@color = value
@surface[key] = SDL::Surface.new_from(image.data,@width,@height,32,@stride,R,G,B,A)
end
end

def image
img = Cairo::ImageSurface.new(C_FORMAT,@width,@height)
Cairo::Context.new(img) do |c|
c.set_source_color(@color)
c.font_size = 20
c.move_to(0,20)
c.show_text(@text)
end
img
end

def collide_point?(x,y)
@x < x && @x + @width > x && @y < y && @y + @height > y
end

def mouse_motion(event)
if collide_point?(event.x,event.y)
@surface_key = :on
else
@surface_key = :up
end
nil
end

def mouse_button_down(event)
if collide_point?(event.x,event.y)
@surface_key = :down
return action
end
nil
end

def action
nil
end

def update
@screen.put(@surface[@surface_key],@x,@y)
end
end

class Label_text < Label
def initialize(screen)
super
@x,@y = 20,80
self.text = "文字入力"
end

def action
text = ''
TkCore::INTERP.restart
TkLabel.new(nil, 'text'=>'Input Text.').pack
entry = TkEntry.new.pack
TkButton.new(nil, 'text'=>'OK', 'command'=>proc{ text = entry.value; Tk.exit}).pack
Tk.mainloop
text
end
end

class Label_exit < Label
def initialize(screen)
super
@x,@y = 180,80
self.text = "終了"
end
def action
exit
end
end

class Phase
def initialize(screen)
@screen = screen
@display = Display.new(@screen)
@display.text = "Tk Input"
@controls = []
@controls << Label_text.new(@screen)
@controls << Label_exit.new(@screen)
@handle = EventHandle.new(
SDL::Event::Quit => proc{exit},
[SDL::Event::KeyDown,SDL::Key::ESCAPE] => proc{exit}
)
end

def update
@screen.fill_rect(0,0,@screen.w,@screen.h,[0,0,0])
@display.update
@controls.each do |obj|
obj.update
end
end

def handling(event)
@handle.handling(event)
@controls.each do |obj|
if text = obj.handle.handling(event)
@display.text = text
end
end
end

def run
loop do
while event=SDL::Event.poll
handling(event)
end
update
@screen.flip
SDL.delay(50)
end
end
end

C_FORMAT = Cairo::FORMAT_ARGB32
R,G,B,A = 0x00FF0000,0x0000FF00,0x000000FF,0xFF000000
SDL.init(SDL::INIT_EVERYTHING)
SDL::WM.set_caption("Tk Input","")
screen = SDL::setVideoMode(300,120,16,SDL::SWSURFACE)
Phase.new(screen).run
[PR]
by gaziya | 2011-02-04 20:33