2016/01/16(土) [n年前の日記]
#2 [dxruby][dxrubyws] DXRubyWSでスクロールバーを表示させたい
DXRubyWS でスクロールバーを表示させたい。ウインドウ内に表示しきれないサイズの何かを表示してる時は、スクロールバーでスクロールを可能にしたいわけで。
これも、 _sample/rubima3.rb を参考にして試してみたり。
_scrollbar_test.rb
スクロールバー.total_size に画像横幅、縦幅をそのまま与えると、画像の全てを表示できなかったので、勘で、16ドット加えた値を指定してみたり。それだと、画像が全て表示された。おそらく、縦スクロールバーの横幅が16ドット、横スクロールバーの縦幅が16ドットだったりするだろうから、その分を加えると合ってくれるのかなと。自信無いけど。もしかすると、スクロールバーの幅が16ドットになるとは限らない可能性もあるから、スクロールバーの幅を取得して、ソレを加えるような書き方をしたほうがいいのかもしれない。
最初、画像表示ウインドウの draw をオーバーライドしたのだけど、それだと画像が表示されなくて。rubima3.rb では、draw ではなく render をオーバーライドしてたので、それに従ってみたら画像が表示された。このあたり、自分は仕組みがまだ分かってないです。
ここまでメモってから気が付いたけど、 _lib/StandardGUI/scrollbar.rb の中に、WSScrollableContainer というクラスがある…。コレを使えばもっと短く書けるのだろうか。
これも、 _sample/rubima3.rb を参考にして試してみたり。
_scrollbar_test.rb
# 画像を読み込んで表示してみるテスト
# スクロールバーを追加してみる
require_relative 'lib/dxrubyws'
require_relative 'lib/standardgui'
module WS
# 画像選択ウインドウクラス
class ImageSelectWindow < WSWindow
# コンストラクタ。初期化処理
def initialize(*args)
super
# ボタンを生成して登録
x, y, w, h = 4, 4, 120, 24
@btn = WSButton.new(x, y, w, h, "画像読み込み")
client.add_control(@btn)
@btn.add_handler(:click, self.method(:on_click))
# タイトルバー上の閉じるボタンを無効化
self.window_title.close_button = false
# ESCキーで閉じないようにする
@key_handler.delete(K_ESCAPE)
# 次のウインドウ発生位置
@x_pos = self.x
@y_pos = self.y + self.height
end
# ボタンを押した時の処理
def on_click(obj, tx, ty)
# ファイル選択ダイアログを開いてみる
filters = [
["画像ファイル(*.png;*.jpg;*.bmp)", "*.png;*.jpg;*.bmp"],
["すべてのファイル(*.*)", "*.*"]
]
filepath = Window.openFilename(filters, "画像ファイルを選択")
create_image_window(filepath) if filepath
end
# 画像を表示するウインドウを生成して画面に追加
def create_image_window(filepath)
img = Image.load(filepath)
w, h = img.width, img.height
bsname = File.basename(filepath)
wdw = WS::ImageWithScrollBarWindow.new(@x_pos, @y_pos, 320, 240, bsname)
wdw.set_image(img)
WS.desktop.add_control(wdw)
@x_pos += 32
@y_pos += 32
end
end
# 画像を表示するだけのウインドウクラス
class ImageWithScrollBarWindow < WSWindow
attr_accessor :image
def initialize(*args)
super
@v_pos = 0
@h_pos = 0
@image = Image.new(512, 512)
w, h = self.width, self.height
# 縦スクロールバー
vsb = WSVScrollBar.new(w - 20, 0, 16, h)
client.add_control(vsb, :vsb)
vsb.total_size = 512 + 16 # 全体サイズ
vsb.shift_qty = 32 # ボタンを押した時に動く量
vsb.view_size = client.height # 表示範囲
# スライダーを動かした時の処理
vsb.add_handler(:slide) { |obj, pos| @v_pos = pos }
# 横スクロールバー
hsb = WSHScrollBar.new(0, h - 20, w - 16, 16)
client.add_control(hsb, :hsb)
hsb.total_size = 512 + 16 # 全体サイズ
hsb.shift_qty = 32 # ボタンを押した時に動く量
hsb.view_size = client.width # 表示範囲
# スライダーを動かした時の処理
hsb.add_handler(:slide) { |obj, pos| @h_pos = pos }
# 画像
wsimg = WSImage.new(0, 0, 512, 512)
wsimg.image = RenderTarget.new(512, 512)
client.add_control(wsimg, :wsimg)
# リサイズされた時の処理
wsimg.add_handler(:resize) do
wsimg.image.resize(wsimg.width, wsimg.height)
hsb.view_size = client.width
vsb.view_size = client.height
end
# マウスホイール入力時の処理
wsimg.add_handler(:mouse_wheel_up) { vsb.slide(-32 * 3) }
wsimg.add_handler(:mouse_wheel_down) { vsb.slide(32 * 3) }
# オートレイアウトで画像表示部やスクロールバーを調整してもらう
client.layout(:vbox) do
# 縦方向に並べる
layout(:hbox) do
# 横方向に並べる
add wsimg, true, true # 横サイズも縦サイズも可変
add vsb, false, true # 横サイズは固定、縦サイズは可変
end
add hsb, true, false # 横サイズは可変、縦サイズは固定
end
end
# 画像を設定
def set_image(img)
@image = img
# スクロールバーに与える全体サイズ値を更新
client.hsb.total_size = img.width + 16
client.vsb.total_size = img.height + 16
end
# renderをオーバーライドすれば描画されるが、
# drawをオーバーライドすると描画されない
def render
client.wsimg.image.draw(-@h_pos, -@v_pos, @image)
super
end
end
end
Window.width, Window.height = 1024, 600
wdw = WS::ImageSelectWindow.new(8, 8, 200, 56, "ImageSelectWindow")
WS.desktop.add_control(wdw)
Window.loop do
WS.update
end
一応表示できたように見える。たぶん。
- WSHScrollBar と WSVScrollBar が、スクロールバーらしい。
- スクロールバーは、total_size、shift_qty、view_size を持つ。
- total_size は、スクロールバーでスクロールさせる何か、の幅を指定するらしい。例えば画像の縦幅が512ドットだったら、total_size も512を指定する、のではないか。たぶん。
- shift_qty は、上ボタンや下ボタンをクリックしたときにスクロールさせる量。
- view_size は、ちょっとわからなかった。とりあえず、client.width や client.height を与えておくものらしい。
- スクロールバーのスライダーを動かすと、:slide シグナルが来るらしい。
- スクロールバー.slide(数値) で、与えた数値分、スクロールバーを動かせる模様。
- オートレイアウトで、スクロールさせたい何かとスクロールバーをレイアウトできる。
- オートレイアウトは、入れ子にできるらしい。上記のサンプルでは、横方向に、画像と縦スクロールバーを並べ、更にソレを縦に並べて、横スクロールバーが下に並ぶように指定してるつもり。
スクロールバー.total_size に画像横幅、縦幅をそのまま与えると、画像の全てを表示できなかったので、勘で、16ドット加えた値を指定してみたり。それだと、画像が全て表示された。おそらく、縦スクロールバーの横幅が16ドット、横スクロールバーの縦幅が16ドットだったりするだろうから、その分を加えると合ってくれるのかなと。自信無いけど。もしかすると、スクロールバーの幅が16ドットになるとは限らない可能性もあるから、スクロールバーの幅を取得して、ソレを加えるような書き方をしたほうがいいのかもしれない。
最初、画像表示ウインドウの draw をオーバーライドしたのだけど、それだと画像が表示されなくて。rubima3.rb では、draw ではなく render をオーバーライドしてたので、それに従ってみたら画像が表示された。このあたり、自分は仕組みがまだ分かってないです。
ここまでメモってから気が付いたけど、 _lib/StandardGUI/scrollbar.rb の中に、WSScrollableContainer というクラスがある…。コレを使えばもっと短く書けるのだろうか。
[ ツッコむ ]
以上です。
