title: Apollo チュートリアル
Author: NISHIO Mizuho
mailto: mzh@portnet.ne.jp

1. コントロールの配置とサイズ その2
  
  今回は多くのコントロールを配置する時に便利なクラスを紹介します。

1.1. その1(UI::Hbox)

  %href: http://www.ruby-lang.org/gtk/ Ruby/GTK% のGtk::HBoxにあたるクラスがUI::Hboxと言えば、その機能を推測できる人がいるかもしれません。ちなみにUI::HboxはVCLに存在しないクラスです。

  %href: ./rb/pack1.rb pack1.rb%

--ruby
001  require 'phi'
002  require 'rgui/ui'
003  
004  form = RGUI::Form.new(:form1, 'formです')
005  
006  btn1 = Phi::Button.new(form, :button1, 'その1')
007  btn2 = Phi::Button.new(form, :button2, 'その2')
008  btn3 = Phi::Button.new(form, :button3, 'その3')
009  
010  hbox = UI::Hbox.new([btn1, btn2, btn3], 10)
011  
012  form.add(hbox)
013    
014  btn1.on_click = proc do
015    form.layout
016  end
017  
018  btn2.on_click = proc do
019    form.layout
020  end
021  
022  btn3.on_click = proc do
023    form.layout
024  end
025  form.show
026  Phi.mainloop
--

  このスクリプトを実行すると、%href: img/pack1-1.png このような% ウィンドウがあらわれます。

1.1.1. 解説
  2行目の require 'rgui/ui' はおまじないです。これから説明するパッキングを行うコントロールを使う時に必要になります。

  4〜8行ではフォームやボタンの生成を行っています。ここでは4行目が今までのようにPhi::Formではなく、RGUI::Formになっていることに注意してください。これも一種のおまじないです。

  10行目の hbox = UI::Hbox.new が先ほど述べたパッキングを行うコントロールを生成している行です。UI::Hboxというのは他のコントロールをのせるための透明な枠のようなもので、自分自身は何も画面に表示されませんが、自分の上にあるコントロールの配置を水平方向に自動的に変更することができます。「水平方向に自動的に変更」というのはコントロールの高さをそろえ、それぞれのコントロールの間隔を一定にするということです。パッキングというのは上のようなコントロールの配置のことを指します。

  ここでは UI::Hbox.new の第1引数である[btn1, btn2, btn3] の三つがパッキングのコントロールに配置されます。

  12行目は form.add( RGUI::Form#add ) でパッキングコントロールをフォームに載せています。今までのようにコントロール生成時に親コントロールを決めていないので、違和感を感じるかもしれません。

  パッキングコントロールを使えば自動的に配置を変更することは出来ますが、上の図のようにそのままではUI::Hboxの上のコントロールの配置は変更されません。コントロールの配置を変更するにはPhi::Hboxの親であるフォームの form.layout( RGUI::Form#layout ) を実行する必要があります。

  上のスクリプトでは14〜24行目で三つのボタンのうちどれかが押された時に form.layout が実行されるようにしていますので、上のスクリプトを実行してボタンが押された時に配置が変更されるかどうか確認してみてください。 

  RGUI::Form#layout はフォームのサイズが変更された時にコントロールの配置を自動的に変更したい時に役立ちます。実例として、上のスクリプトを実行してフォームの大きさを変更してから、ボタンを押した時の図を載せておきます。%href: img/pack1-2.png 図%

  最後にUI::Hbox.newの引数について少し述べます。UI::Hbox.newの第1引数は Array (配列)のオブジェクトで、その要素は自動的に配置を変更したいコントロールになります。Array の添え字の小さいものから順に左から並べられます。第2引数は自動的に配置が変更される時のコントロールの間隔になります。例えば、この値を0にすると、コントロールは隙間なく横に並ぶことになります。

1.1.1. クラスとメソッド
: 組み込みクラス
* Array

: RGUI::Form#
* RGUI::Form.new
* RGUI::Form#add
* RGUI::Form#layout

: UI::Hbox#
* UI::Hbox.new

1.2. その2(入れ子)

  %href: ./rb/pack2.rb pack2.rb%

--ruby
001  require 'phi'
002  require 'rgui/ui'
003  
004  form = RGUI::Form.new(:form1, 'formです')
005  
006  btn1 = Phi::Button.new(form, :button1, 'ボタンその1')
007  btn2 = Phi::Button.new(form, :button2, 'ボタンその2')
008  btn3 = Phi::Button.new(form, :button3, 'ボタンその3')
009  btn_vbox = UI::Vbox.new([btn1, btn2, btn3], 5)
010  
011  lbl1 = Phi::Label.new(form, :label1, 'ラベルその1')
012  lbl2 = Phi::Label.new(form, :label2, 'ラベルその2')
013  lbl_hbox = UI::Hbox.new([lbl1, lbl2], 10)
014  
015  radio1 = Phi::RadioButton.new(form, :radio_btn1, 'ラジオボタンその1')
016  radio2 = Phi::RadioButton.new(form, :radio_btn2, 'ラジオボタンその2')
017  radio_hbox = UI::Hbox.new([radio1, radio2], 5)
018  
019  lbl3 = Phi::Label.new(form, :label3, 'ラベルその3')
020  speed1 = Phi::SpeedButton.new(form, :speed_btn1, 'スピードボタンその1')
021  speed1.flat = true
022  other_hbox = UI::Hbox.new([lbl3, speed1], 5)
023  
024  vbox = UI::Vbox.new([lbl_hbox, radio_hbox, other_hbox])
025  hbox = UI::Hbox.new([btn_vbox, vbox])
026    
027  form.add(hbox)
028  form.on_resize = proc do
029    form.layout
030  end
031  form.show
032  Phi.mainloop
--
  このスクリプトを実行すると、%href: img/pack2.png このような% ウィンドウがあらわれます。

1.2.1. 解説
  逆から説明していきますが、多分その方が分かりやすいと思います。

  27行目ではformにhboxを格納しています。

  25行目ではformに格納されたhboxにbtn_vboxとvboxを横に並べています。図にするとこういう感じでしょうか。

--html
<img src='img/pack2-1.png'>
--

  24行目ではlbl_hbox、radio_hbox、other_hboxの三つをvboxに縦に格納しています。図にすると下のようになります。

--html
<img src='img/pack2-2.png'>
--
  
  9、13、17、22行目ではそれぞれのボックスにボタンやラベルを格納しています。

  最後、28〜30行ではフォームの大きさが変更された時にコントロールの配置が変更されるようにしています。この部分は起動時にも実行されるので、上の図のようにコントロールの配置が変更された状態でウィンドウが現れます。

1.2.1. クラスやメソッド
: UI::Vbox#
* UI::Vbox.new

: RGUI::Form#
* RGUI::Form#on_resize ( Phi::Control#on_resize )
