mieki256's diary



2016/01/16() [n年前の日記]

#1 [dxruby][dxrubyws] DXRubyWSで画像を表示してみるテスト

DXRubyWSで画像を表示してみたい。

_doc/tutorial01.txt を眺めれば、画像の表示はできるのだけど、できればウインドウに ―― WSWindow で表示してみたい。どうやれば表示できるのかなと。

_sample/rubima3.rb を参考にすれば表示できそうな予感。試してみたり。

_image_load_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::ImageWindow.new(@x_pos, @y_pos, w + 48, h + 48, bsname)
      WS.desktop.add_control(wdw)
      wdw.image = img

      @x_pos += 32
      @y_pos += 32
    end
  end

  # 画像を表示するだけのウインドウクラス
  class ImageWindow < WSWindow

    attr_accessor :image

    def initialize(*args)
      super
      @image = nil
    end

    def draw
      x = (client.image.width - @image.width) / 2
      y = (client.image.height - @image.height) / 2
      client.image.draw(x, y, @image) if @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
image_load_test.png
表示できたっぽい。たぶん、無駄な行がたくさんありそうな気もするけれど…。

ウインドウのタイトルバーの閉じるボタンを無効にしたい。 :

画像読み込みボタンが置いてあるウインドウの、閉じるボタンを無効にしたかったのだけど。 _lib/StandardGUI/window.rb を眺めていて、もしかするとコレかなと思えてきたので試してみたら、非表示になってくれた。
  # タイトルバー上の閉じるボタンを無効化
  self.window_title.close_button = false

ただ、ウインドウは ―― WSWindow は、ESCキーでウインドウを閉じる仕様にもなっているようで。ESCキーで閉じる仕様を無効にするにはどうしたら…。こんな感じでいいのだろうか。
  # ESCキーで閉じないようにする
  @key_handler.delete(K_ESCAPE)
WSWindow が持ってる、@key_handler というハッシュに、どのキー入力を受け付けるかが登録されてるっぽいので、K_ESCAPE だけ delete してみたら、一応無効になってくれたように見える。

#2 [dxruby][dxrubyws] DXRubyWSでスクロールバーを表示させたい

DXRubyWS でスクロールバーを表示させたい。ウインドウ内に表示しきれないサイズの何かを表示してる時は、スクロールバーでスクロールを可能にしたいわけで。

これも、 _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
scrollbar_test.png
一応表示できたように見える。たぶん。
スクロールバー.total_size に画像横幅、縦幅をそのまま与えると、画像の全てを表示できなかったので、勘で、16ドット加えた値を指定してみたり。それだと、画像が全て表示された。おそらく、縦スクロールバーの横幅が16ドット、横スクロールバーの縦幅が16ドットだったりするだろうから、その分を加えると合ってくれるのかなと。自信無いけど。もしかすると、スクロールバーの幅が16ドットになるとは限らない可能性もあるから、スクロールバーの幅を取得して、ソレを加えるような書き方をしたほうがいいのかもしれない。

最初、画像表示ウインドウの draw をオーバーライドしたのだけど、それだと画像が表示されなくて。rubima3.rb では、draw ではなく render をオーバーライドしてたので、それに従ってみたら画像が表示された。このあたり、自分は仕組みがまだ分かってないです。

ここまでメモってから気が付いたけど、 _lib/StandardGUI/scrollbar.rb の中に、WSScrollableContainer というクラスがある…。コレを使えばもっと短く書けるのだろうか。

以上、1 日分です。

過去ログ表示

Prev - 2016/01 - Next
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31

カテゴリで表示

検索機能は Namazu for hns で提供されています。(詳細指定/ヘルプ


注意: 現在使用の日記自動生成システムは Version 2.19.6 です。
公開されている日記自動生成システムは Version 2.19.5 です。

Powered by hns-2.19.6, HyperNikkiSystem Project