miyako/miyako_ext.rb
# Miyako拡張クラス
=begin
Miyako Extention Library v0.6
Copyright (C) 2006 Cyross Makoto
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
=end
module Miyako
class RasterScroll < Effect
def initialize(sspr, dspr = nil)
super
@lines = 0
@h = @src.h
@size = 0
@angle = 0
@sangle = 0
@dangle = 0
@fade_out = false
@fo_size = 0
end
def start(w, *param)
super
@lines = @param[0]
@size = @param[1]
@sangle = @param[2]
@dangle = @param[3]
@h = @h / @lines
@fade_out = false
@fo_size = 0
end
def update(screen)
@angle = @sangle
@h.times{|y|
rsx = @size * Math.sin(@angle)
SDL.blitSurface(@src.bitmap, @src.ox, @src.oy + y * @lines, @src.ow, @lines, screen, @src.x + rsx, @src.y + y * @lines)
@angle = @angle + @dangle
}
if @cnt == 0
if @fade_out
@fo_cnt -= 1
return if @fo_cnt != 0
@size = @size - @fo_size
@fo_cnt = @fo_wait
@effecting = false if @size <= 0
end
@sangle = (@sangle + 1) % 360
@cnt = @wait
else
@cnt = @cnt - 1
end
end
def fade_out(fs, fw)
@fo_size = fs
@fo_wait = fw
@fo_cnt = @fo_wait
@fade_out = true
end
end
class Comps # コンポーネント管理クラス
@@common_comps = Hash.new
def Comps.[](name)
if @@common_comps.has_key?(name) == false
throw MiyakoError.new("Not Registered Common Component name! : #{name}")
end
@@common_comps[name]
end
def Comps.[]=(name, value)
@@common_comps[name] = value
end
def Comps.delete(name)
return if @@common_comps.has_key?(name) == false
@@common_comps.delete(name)
end
def Comps.reset
@@common_comps = Hash.new
end
def Comps.listup
l = "<<Common Component>>\n"
l += @@common_comps.keys.sort.map{|k| k.to_s + " / " + @@common_comps[k].class.to_s}.join("\n")
return l
end
def initialize
@local_comps = Hash.new
end
def [](name)
if @local_comps.has_key?(name)
return @local_comps[name]
end
if @@common_comps.has_key?(name)
return @@common_comps[name]
end
throw MiyakoError.new("Not Registered Common and Local Component name! : #{name}")
end
def []=(name, value)
@local_comps[name] = value
end
def delete(name)
return if @local_comps.has_key?(name) == false
@local_comps.delete(name)
end
def reset
@local_comps = Hash.new
end
def listup
l = Comps.listup + "<<Local Component : #{name}>>\n"
l += @local_comps.keys.sort.map{|k| k.to_s + " / " + @local_comps[k].class.to_s}.join("\n")
return l
end
end
class Slides # スライド集
@@names = Array.new
@@name_to_slides = Hash.new
def init(name)
@titles = Array.new
@manager = Hash.new
@@names.push(name)
@@name_to_slides[name] = self
end
def initialize(name)
init(name)
end
def [](title)
return @manager[title] if title.kind_of?(String)
end
def add(title, slide)
if title.kind_of?(String) && slide.kind_of?(Slide)
@manager[title] = slide
@titles.push(title)
end
end
def delete(title)
if title.kind_of?(String)
@manager.delete(title)
@titles.remove(title)
end
end
def pickup(slides)
self.hide
self.show(slides)
end
def show(p = 0)
if p.kind_of?(Integer)
return if @titles.length == 0 || p >= @titles.length
@manager[@titles[p]].show
elsif p.kind_of?(String)
return unless @manager.has_key?(p)
@manager.keys.each{|k| @manager[k].hide }
@manager[p].show
elsif p.kind_of?(Array)
p = p.collect{|s| @manager.has_key?(s) }
return if p == []
@manager.keys.each{|k| @manager[k].hide }
p.each{|s| show(s)}
end
end
def hide(slides = nil)
if slides == nil
@manager.keys.each{|k| @manager[k].hide }
elsif slides.kind_of?(String)
@manager[slides].hide
elsif slides.kind_of?(Array)
slides.each{|s| @manager[s].hide if s.kind_of?(String) }
end
end
def get_name_list
return @titles
end
def dispose
@manager.clear
@titles.clear
end
def Slides.get_name_list
return @@names
end
def Slides.get_slides(p)
if p.kind_of?(String)
return @@name_to_slides[p] if @@name_to_slides.key?(p)
elsif p.kind_of?(Integer)
return @@name_to_slides[@@names[p]] if p < @@names.length
end
end
end
class Slide # スライド
extend Forwardable
def init(w, h, dp, c, a)
@slide = Sprite.new([w, h], nil)
@dp = dp
@color = c
@alpha = a
@comps = Hash.new
@titles = Array.new
@slide.bitmap.fill_rect(0, 0, w, h, @color)
@slide.dp = @dp
@slide.alpha = @alpha
end
def initialize(w, h, dp=-1, c=[255,255,255], a=255)
init(w, h, dp, c, a)
end
def add(title, sprite)
return unless title.kind_of?(String) && sprite.kind_of?(Sprite)
return if @comps.has_key?(title)
@comps[title] = sprite
@comps[title].visible = false
@comps[title].snap(@slide)
@titles.push(title)
end
def [](title)
return nil unless title.kind_of?(String) || @comps.has_key?(title)
return @comps[title]
end
def show
@comps.keys.each{|k| @comps[k].visible = true }
@slide.visible = true
end
def hide
@comps.keys.each{|k| @comps[k].visible = false }
@slide.visible = false
end
def set_color(c)
@color = c
@slide.bitmap.fill_rect(0, 0, w, h, @color)
end
def set_alpha(a)
@alpha = a
@comps.keys.each{|k| @comps[k].alpha = @alpha }
@slide.alpha = @alpha
end
def locate(x, y)
@slide.set_offset(x, y)
@slide.calc_layout
end
def_delegators(:@slide, :x, :y)
def_delegators(:@slide, :calc_layout, :enable_layout, :disenable_layout)
def_delegators(:@slide, :set_side_x, :set_side_y, :set_side)
def_delegators(:@slide, :set_base_size, :reset_base_size, :set_base_point)
def_delegators(:@slide, :set_offset_x, :set_offset_y, :set_offset, :reset_offset)
def_delegators(:@slide, :get_layout_x, :get_layout_y, :get_layout, :get_side, :get_base)
def_delegators(:@slide, :get_offset, :get_offset_x, :get_offset_y)
def_delegators(:@slide, :move, :set_layout, :reset_layout, :centering)
def_delegators(:@slide, :set_base_size, :reset_base_size, :set_base_point)
def_delegators(:@slide, :snap, :reset_snap, :add_snap_child, :delete_snap_child)
def_delegators(:@slide, :get_snap_children, :set_snap_children, :get_snap_sprite)
def_delegators(:@slide, :set_snap_sprite, :rect)
def slide_to_sprite
sprite = Sprite.new([@slide.w, @slide.h], nil)
sprite.bitmap.fill_rect(0, 0, sprite.w, sprite.h, @color)
comps = @comps.values.sort{|a, b| a.dp <=> b.dp && a.id <=> b.id }
comps.each{|c|
if c != nil
SDL.blitSurface(c.bitmap, c.ox, c.oy, c.ow, c.oh, sprite.bitmap, c.x - @slide.x, c.y - @slide.y)
end
}
return sprite
end
def dispose
@comps.clear
@slide.dispose
end
def get_sprite_list
return @titles
end
end
class Dice # サイコロ
VMAX = 4
@@dice_bmp = nil
attr_reader :x, :y, :sx, :sy, :dp, :margin
def initialize(a)
@amount = a
@dices = Array.new
@dnums = Array.new
@x = 0
@y = 0
@sx = 4
@sy = 4
@dp = 100
@margin = 4
@wait = 0
@wcnt = 0
@dicing = false
@have_result = false
@bgcolor = [0, 0, 0]
@balpha = 128
@@dice_bmp = Bitmap.load("dice.png") if @@dice_bmp == nil
@amount.times{|i|
@dices.push(Sprite.new(@@dice_bmp, Point.new(0, 0)))
@dices[i].dp = @dp
@dices[i].oh = @dices[i].w
@dices[i].x = @x + @margin + (@dices[i].ow + @sx) * (i % VMAX)
@dices[i].y = @y + @margin + (@dices[i].oh + @sy) * (i / VMAX)
@dnums.push(0)
}
sh = @dices.length / VMAX + 1
sw = @dices.length > VMAX ? VMAX : @dices.length
w = @dices[0].ow * sw + @sx * (sw - 1) + @margin * 2
h = @dices[0].oh * sh + @sy * (sh - 1) + @margin * 2
@max = @dices[0].h / @dices[0].oh
@bg = Sprite.new([w, h], nil)
@bg.x = @x
@bg.y = @y
@bg.dp = @dp - 1
@bg.bitmap.fillRect(0, 0, @bg.w, @bg.h, @bgcolor)
@bg.alpha = @balpha
end
def start(wait = 0)
@wait = wait
@wcnt = wait
@dnums.length.times{|d|
@dnums[d] = rand(@max)
@dices[d].oy = @dices[d].oh * @dnums[d]
}
@dicing = true
end
def update
if @dicing && Input::pushed?(Input::BTN1)
@have_result = true
@dicing = false
return
end
if @wcnt == 0
@dnums.length.times{|d|
@dnums[d] = rand(@max)
@dices[d].oy = @dices[d].oh * @dnums[d]
}
@wcnt = @wait
else
@wcnt -= 1
end
end
def stop
@have_result = true if @dicing
@dicing = false
end
def x=(x)
@x = x
@dnums.length.times{|d|
@dices[d].x = @x + @margin + (@dices[d].ow + @sx) * (d % VMAX)
}
@bg.x = @x
end
def y=(y)
@y = y
@dnums.length.times{|d|
@dices[d].y = @y + @margin + (@dices[d].oh + @sy) * (d / VMAX)
}
@bg.y = @y
end
def dp=(dp)
@dp = dp
@dices.each{|dc|
dc.dp = @dp
}
@bg.dp = @dp - 1
end
def setBG(color, alpha)
@bgcolor = color
@bgalpha = alpha
@bg.bitmap.fillRect(0, 0, @bg.w, @bg.h, @bgcolor)
@bg.alpha = @balpha
end
def show
return if @dices == nil
@dices.each{|dc|
dc.visible = true
}
@bg.visible = true
end
def hide
return if @dices == nil
@dices.each{|dc|
dc.visible = false
}
@bg.visible = false
end
def dicing?
@dicing
end
def have_result?
@have_result
end
def result
return @dnums.inject(0){|r, i| r + i + 1}
end
def result_array
return @dnums.map{|n| n + 1}
end
def reset
@dnums.length.times{|d|
@dnums[d] = 0
@dices[d].oy = 0
}
@reset_result
end
def reset_result
@have_result = false
end
def size
[@bg.w, @bg.h]
end
end
class MessageBox
extend Forwardable
CURSOR_SIZE = 24
patterns = 4
cursor_other = Rect.new(0, 0, 1, 1)
cursor_back = Rect.new(0, CURSOR_SIZE, CURSOR_SIZE, CURSOR_SIZE)
wait = Rect.new(CURSOR_SIZE * 1, 0, CURSOR_SIZE, CURSOR_SIZE)
cursor = Rect.new(CURSOR_SIZE * 2, 0, CURSOR_SIZE, CURSOR_SIZE)
page = Rect.new(CURSOR_SIZE * 3, 0, CURSOR_SIZE, CURSOR_SIZE)
@@wparam = WindowParameter.new(
"cursors.png",
cursor_other,
cursor_other,
cursor_other,
cursor_other,
cursor_other,
cursor_other,
cursor_other,
cursor_other,
cursor_back
)
@@cparam = CursorParameter.new(
"cursors.png",
wait, patterns,
cursor, patterns,
page, patterns
)
def reset_select
@selecting = false
@have_result = false
@res = 0
@selects = 0
@select2label = Array.new
@have_label = false
@label = ""
end
def reset
@have_stuff = false
@p = -1
@eot = false
@pause = false
@wait = 0
@cnt = 0
@sleep = 0
# 2006.05.13 Cyross
@code = Yuki::Direction::EOT
reset_select
end
def initialize(size = Size.new(640, 480), params = @@cparam, font = Font.system_font, fontsize = 24)
@params = params
@prts = @params.get_parts
@font = font
@fontsize = fontsize
@font.size = @fontsize
@box = TextBox.new(size, @params, 255, false, 0)
@box.bgColor = [0, 0, 0]
@box.bgAlpha = 0
@box.x = 0
@box.y = 0
@box.font = @font
@box.msg.separate = true
@box.pauseType = 1
@box.pauseWait = 0
@vars = Yuki::Variables.new
@cmds = nil
@have_show_image = false
@have_hide_image = false
reset
end
def setBG(color, alpha)
@box.bgColor = color
@box.bgAlpha = alpha
end
def draw_text(str, wait = 0)
reset
@box.msg.text = str
@wait = wait
@have_stuff = true
end
def stuff(fname, wait = 0)
raise MiyakoError.new("file not found : #{fname}") if File.exist?(fname) == false
reset
@wait = wait
line = ""
File.open(fname, "r"){|f|
while f.eof? == false
l = f.readline.chomp.toutf8
next if l =~ /^[\s\t]+/ # empty line
next if l =~ /^#/ # comment
line += l
end
}
@box.msg.text = line
@have_result = false
@selecting = false
@have_stuff = true
end
def set_commands(filename)
@cmds = Commands.new(filename)
end
def update
if @selecting
if Input.pushed?(Input::BTN1)
@selecting = false
@have_result = true
@have_label = true if @select2label.length > 0 # command only
@box.cursorVisible = false
@vars.var[0] = @res
@selects = 0
return
end
dx, dy = Input.pushedAmount
@res = (@res + @selects + dy) % @selects
@box.cursorY = @y + @res * @box.font.size
elsif @sleep > 0
@sleep -= 1
return
elsif @box.pause?
@box.pause = false if Input.pushed?(Input::BTN1)
elsif @have_stuff == false
return
elsif @cnt == 0
@have_show_image = false
@have_hide_image = false
ct = @box.msg.nextmsg
# 2006.05.13 Cyross
@code = ct.code
if ct.code == Yuki::Direction::EOT
@eot = true
return
elsif ct.code == Yuki::Direction::CHAR
@box.msg.push(ct)
@cnt = @wait
return
elsif ct.code == Yuki::Direction::PAUSE
@box.pause = true
return
elsif ct.code == Yuki::Direction::FONTCOLOR
@box.msg.push(ct)
return
elsif ct.code == Yuki::Direction::FONTSIZE
@box.msg.push(ct)
return
elsif ct.code == Yuki::Direction::CR
@box.cr
return
elsif ct.code == Yuki::Direction::CLEAR
@box.clear
return
elsif ct.code == Yuki::Direction::MESWAIT
@wait = ct.data
@cnt = @wait
return
elsif ct.code == Yuki::Direction::SLEEP
@sleep = ct.data
return
elsif ct.code == Yuki::Direction::LOCATE
@box.locate(ct.data[0], ct.data[1])
return
elsif ct.code == Yuki::Direction::YESNO
yes_no
return
elsif ct.code == Yuki::Direction::COMMAND
command(ct.data)
return
elsif ct.code == Yuki::Direction::LABEL
@label = ct.data
@have_label = true
return
elsif ct.code == Yuki::Direction::EXPR
r = @vars.exec(ct.data[0])
return @box.msg.push(Yuki::Direction.new(Yuki::Direction::CHAR, "#{r}")) if ct.data[1]
elsif ct.code == Yuki::Direction::SOUND
snd = Audio::SE.new(ct.data[0])
snd.setVolume(ct.data[1])
snd.play
if ct.data[2]
while snd.playing? do
end
end
return
elsif ct.code == Yuki::Direction::SHOW
@vars.var[0] = ct.data
return
elsif ct.code == Yuki::Direction::HIDE
@vars.var[0] = ct.data
return
else
@box.msg.push(ct)
@cnt = @wait
return
end
else
@cnt = @cnt - 1
end
end
def yes_no
return if @selecting || @dicing
reset_select
@box.msg.push(Yuki::Direction.cr)
@box.msg.push(Yuki::Direction.locate(@params.cursor[0].w, nil))
@box.msg.push(Yuki::Direction.new(Yuki::Direction::CHAR, "はい"))
@box.msg.push(Yuki::Direction.cr)
@box.msg.push(Yuki::Direction.locate(@params.cursor[0].w, nil))
@box.msg.push(Yuki::Direction.new(Yuki::Direction::CHAR, "いいえ"))
@box.msg.push(Yuki::Direction.cr)
@selecting = true
@have_result = false
@box.cursorDir = :d
@y = @box.locateY + @fontsize
@box.cursorX = @box.locateX
@box.cursorY = @y
@box.cursorVisible = true
@selects = 2
end
def command(clabel)
return if @selecting || @dicing
reset_select
cnt = 0
@cmds[clabel][:list].each{|c|
if @vars.exec(c["condition"])
@box.msg.push(Yuki::Direction.cr)
@box.msg.push(Yuki::Direction.locate(@params.select_cursor[:r].w, nil))
@box.msg.push(Yuki::Direction.new(Yuki::Direction::CHAR, c["name"]))
@select2label.push(c["label"])
cnt += 1
end
}
return if cnt == 0
@box.msg.push(Yuki::Direction.cr)
@selecting = true
@have_result = false
@have_label = false
@box.cursorDir = :d
@y = @box.locateY + @fontsize
@box.cursorX = @box.locateX
@box.cursorY = @y
@box.cursorVisible = true
@selects = cnt
end
def visible
return @box.visible
end
def visible=(f)
@box.visible = f
end
def show
@box.show
end
def hide
@box.hide
end
def text_separate?
@box.msg.separate
end
def text_separate=(f)
@box.msg.separate = f
end
def eot?
return @eot
end
def have_result?
return @have_result
end
def have_label?
return @have_label
end
def result
return @res
end
def get_label
return @label if @label != ""
return "" if @select2label.length == 0
return @select2label[@res]
end
def have_show_image?
return @have_show_image
end
def have_hide_image?
return @have_hide_image
end
# 2006.05.13 Cyross
attr_reader :code
def_delegators(:@box, :pauseWait, :pauseWait=)
def_delegators(:@box, :cr, :clear, :dp, :dp=)
def_delegators(:@box, :clientW, :clientH, :x, :x=, :y, :y=)
end
module W_Params
@@w_param = WindowParameter.new(
"win_base.png", # ウィンドウイメージ名
Rect.new( 0, 0, 16, 16), # 左上
Rect.new( 16, 0, 16, 16), # 上
Rect.new( 32, 0, 16, 16), # 右上
Rect.new( 0, 16, 16, 16), # 左
Rect.new( 32, 16, 16, 16), # 右
Rect.new( 0, 32, 16, 16), # 左下
Rect.new( 16, 32, 16, 16), # 下
Rect.new( 32, 32, 16, 16), # 右下
Rect.new( 48, 0, 32, 32) # クライアント
)
@@c_param = CursorParameter.new(
"win_base.png", # ウィンドウイメージ名
Rect.new( 80, 0, 16, 16), 4, # ウェイト、パターン数
Rect.new( 96, 0, 16, 16), 4, # カーソル、パターン数
Rect.new(160, 0, 16, 16), 4 # ページカーソル、パターン数
)
end
class ScinarioWindowDirector < Yuki::Director
@@event_name << :select_name
def initialize(box_m, box_y, box_c, mw, mh, cw, ch)
super(box_m)
@box.set_layout(:center, :bottom)
@x = 0
@y = 0
@w = mw
@h = mh
@cw = cw
@ch = ch
@msg_stack = Array.new
@yn = box_y
@yn.set_layout(:right, :top)
@cm = box_c
@cm.set_layout(:right, :top)
@ptr = 0
@mod = 0
@select2name = nil
@yn_selecting = false
@cm_selecting = false
end
def reset_locate
@x = 0
@y = 0
end
def push_command(n)
@cm.clear
n.times{|i|
@cm.msg.push(Yuki::Direction.cr) if @cm.kind_of?(TextBox)
@cm.msg.push(Yuki::Direction.locate(@cm.cursor_params.select_cursor[:r].w, nil))
@cm.msg.push(Yuki::Direction.new(Yuki::Direction::CHAR, @select2name[@ptr+i][0,@cw*2]))
@cm.msg.push(Yuki::Direction.cr) if @cm.kind_of?(Window)
}
@cm.msg.push(Yuki::Direction.cr) if @cm.kind_of?(TextBox)
end
def move(n, d)
p = n % @ch
if n == 0 && d == 1
@ptr = 0
push_command(@selects > @ch ? @ch : @selects)
elsif p == 0 && d == 1
@ptr += @ch
d = @selects - @ptr
push_command(d == @mod ? d : @ch)
elsif n == @selects - 1 && d == -1
@ptr = @selects - @mod
push_command(@mod)
elsif p == @ch -1 && d == -1
@ptr -= @ch
push_command(@ch)
end
@cm.cursorY = @y + p * @cm.font.line_skip
end
def update
@@event_name.each{|r| @event[r] = nil }
@anim.keys.each{|a| @var[a].update if @anim[a] }
if @yn_selecting
if Miyako::Input.pushed?(Miyako::Input::BTN1)
@event[:select_result] = @res
@event[:yn_scenario] = @yn2scenario[@res]
@yn.hide
@yn.cursorVisible = false
@yn_selecting = false
clear_select_array
@box.clear
return
elsif Miyako::Input.pushed?(Miyako::Input::BTN2)
@event[:select_result] = 1 # No
@event[:yn_scenario] = @yn2scenario[1] if @yn2scenario
@yn.hide
@yn.cursorVisible = false
@yn_selecting = false
clear_select_array
@box.clear
return
end
dx, dy = Miyako::Input.pushedAmount
@res = (@res + @selects + dy) % @selects
@yn.cursorY = @y + @res * @yn.font.line_skip
return
end
if @cm_selecting
if Input.pushed?(Input::BTN1)
r = @select2num[@res]
@event[:select_result] = r
@event[:next_label] = @select2label[r]
@event[:select_scenario] = @select2scenario[r]
@event[:select_name] = @select2name[r]
@cm.hide
@cm.cursorVisible = false
@cm_selecting = false
clear_select_array
@box.clear
return
elsif @cansel && Input.pushed?(Input::BTN2)
@event[:cansel_scenario] = @cansel
@event[:cansel] = true
@cm.hide
@cm.cursorVisible = false
@cm_selecting = false
clear_select_array
@box.clear
return
end
dx, dy = Input.pushedAmount
@res = (@res + @selects + dy) % @selects
move(@res, dy)
return
elsif @sleep && @sleep.waiting?
return
elsif @box.pause?
if Miyako::Input.pushed?(Miyako::Input::BTN1)
@box.pause = false
@event[:pause_cansel] = true
end
elsif @eot
return
elsif @wait.finish?
message_loop
end
end
def reset_select
@res = 0
@ptr = 0
end
def init_window(window, selects)
window.cursorDir = :r # left
@y = window.textMarginTop + window.locateY + (window.font.line_skip - window.cursor_params.select_cursor[:r].h) / 2
@y += window.font.line_skip if window.kind_of?(Miyako::TextBox)
window.cursorX = @box.textMarginLeft + window.locateX
window.cursorY = @y
@res = 0
@selects = selects
end
def show_window(window)
window.show
window.cursorVisible = true
end
def yes_no(ynscenarios)
return if @yn_selecting
@yn2scenario = ynscenarios
@yn.clear
@yn.msg.push(Yuki::Direction.cr) if @yn.kind_of?(Miyako::TextBox)
@yn.msg.push(Yuki::Direction.locate(@yn.cursor_params.select_cursor[:r].w, nil))
@yn.msg.push(Yuki::Direction.new(Yuki::Direction::CHAR, "はい"))
@yn.msg.push(Yuki::Direction.cr)
@yn.msg.push(Yuki::Direction.locate(@yn.cursor_params.select_cursor[:r].w, nil))
@yn.msg.push(Yuki::Direction.new(Yuki::Direction::CHAR, "いいえ"))
@yn.msg.push(Yuki::Direction.cr)
init_window(@yn, 2)
show_window(@yn)
@yn_selecting = true
end
def command(clabel)
return if @cm_selecting
@select2scenario = Array.new
@select2name = Array.new
@select2label = Array.new
@select2num = Array.new
cnt = 0
@title = @cmds[clabel][:title]
@cansel = @cmds[clabel][:cansel]
@cmds[clabel][:list].each_with_index{|c, i|
if @var.exec(c["condition"])
@select2name.push(c["name"])
@select2label.push(c["label"])
@select2scenario.push(c["scenario"])
@select2num.push(i)
cnt += 1
end
}
return if cnt == 0
push_command(cnt>@ch ? @ch : cnt)
init_window(@cm, cnt)
@ptr = 0
@mod = @selects % @ch
@mod = @ch if @mod == 0
unless @title == ""
@box.msg.push(Yuki::Direction.new(Yuki::Direction::CHAR, @title, :setting))
@box.msg.push(Yuki::Direction.cr)
end
show_window(@cm)
@cm_selecting = true
end
def message_loop
begin
@message = @msg_stack.shift || @box.msg.nextmsg
@code2method[@message.code].call(@message.data)
end while @message.type == :setting
end
def process_char(data)
slen = data.split(//).size
if @x + slen < @w
@box.msg.push(Yuki::Direction.new(Yuki::Direction::CHAR, data, :setting))
@x += slen
data = nil
else
l = slen + @x - @w
if l > 0
str = data[0, l]
@box.msg.push(Yuki::Direction.new(Yuki::Direction::CHAR, str, :setting))
end
@x = 0
@y += 1
if @y == @h - 1
@msg_stack.push(Yuki::Direction.new(Yuki::Direction::PAUSE))
@msg_stack.push(Yuki::Direction.new(Yuki::Direction::CLEAR))
@y = 0
else
@box.cr
end
data = data[l..data.length-1]
@msg_stack.push(Yuki::Direction.new(Yuki::Direction::CHAR, data, :setting)) if data
end
@wait.start
end
def process_clear(data)
@box.clear
@x = 0
@y = 0
end
def process_cr(data)
@x = 0
@y += 1
if @y == @h - 1
@msg_stack.push(Yuki::Direction.new(Yuki::Direction::PAUSE))
@msg_stack.push(Yuki::Direction.new(Yuki::Direction::CLEAR))
@y = 0
else
@box.cr
end
end
def process_eot(data)
super
@x = 0
@y = 0
end
end
class ScinarioWindow
extend Forwardable
include W_Params
def initialize(mw, mh, cw, ch, size=16, font=Font.sans_serif, alpha = 128)
@mw = mw
@mh = mh
font.size = size
ww = font.size * @mw
hh = font.line_skip * @mh
@win_m = Window.new([ww, hh], @@w_param, @@c_param, alpha, false, 1.2)
@win_m.font = font
@win_m.pauseWait = 0.5
@win_m.dp = 100
@cw = cw
@ch = ch
ww = font.size * @cw
hh = font.line_skip * @ch
@win_c = Window.new([ww, hh], @@w_param, @@c_param, alpha, false, 1.2)
@win_c.font = font
@win_c.dp = 105
@win_c.cursorWait = 0.5
yw = font.size * 6
yh = font.line_skip * 2
@win_y = Window.new([yw, yh], @@w_param, @@c_param, alpha, false, 1.2)
@win_y.font = font
@win_y.dp = 105
@win_y.cursorWait = 0.5
@dir = ScinarioWindowDirector.new(@win_m, @win_y, @win_c, @mw, @mh, @cw, @ch)
@dir.text_separate = true
@yn_value = -1
@cm_value = -1
end
def update
@dir.update
end
def pause?
return @dir.event[:pause]
end
def cansel_pause?
return @dir.event[:cansel_pause]
end
def load(filename)
@dir.set_plot(filename)
end
def scenario(name = :Main)
@dir.scenario(name)
end
def start(str = nil)
@dir.clear
@dir.set_text(str) if str
@dir.start
end
def result
return @dir.event[:select_result]
end
def next_name
return @dir.event[:select_name]
end
def next_scenario
return @dir.event[:select_scenario] || @dir.event[:yn_scenario]
end
def next_label
return @dir.event[:next_label]
end
def_delegators(:@win_m, :visible)
def_delegators(:@dir, :eot?, :show, :hide, :var)
def_delegators(:@win_m, :calc_layout, :set_layout, :enable_layout, :disenable_layout, :set_side_x, :set_side_y)
def_delegators(:@win_m, :set_side, :set_base_size, :reset_base_size, :set_base_point, :snap, :reset_snap, :add_snap_child, :delete_snap_child, :set_base)
def_delegators(:@win_m, :reset_base, :set_offset_x, :set_offset_y, :set_offset, :reset_offset, :reset_layout, :centering, :move, :move_to)
def_delegators(:@win_m, :get_layout_x, :get_layout_y, :get_layout, :get_side, :get_base)
def_delegators(:@win_m, :get_offset, :get_offset_x, :get_offset_y)
end
end