アップグレード途中で KERNEL32.DLLのエラーが。 仕方が無いので、MS-DOSモードで起動して、i386\winnt.exeを実行する。 スマートドライブをインストールしてくれみたいなことを言われる。 何、それ?と思って、無視してインストールしたんだけど、 ふと、smartdrv.exe なるものを、昔、使っていたよなあと思い出して、 こんなことを懐しく思う人間は、もはや、少いのかも知れないと苦笑いする私。
なので、投票してきました。 ささだ候補の名前がなかったので、ささださんには投票しませんでした。 どうやら今日の選挙の候補ではなかったらしい。
冗談はこのくらいにしておきます。
魔がさしてインストール。
binutils-2.15 をインストール。
CFLAGS=-O2 ../configure make make install
gcc 3.4.3 をインストール。
CFLAGS=-O2 CXXFLAGS=-O2 CC=/usr/bin/gcc ../configure --enable-languiages=c,c++ \ --with-system-zlib --enable-threads --disable-version-specific-runtime-libs \ --disable-nls --without-included-gettext --without-catgets make CFLAGS=-O2 LIBCFLAGS=-O2 LIBCXXFLAGS=-O2 STAGE1_CFLAGS=-O2 BOOT_CFLAGS=-O2 bootstrap make install
--enable-sjlj-exceptions ってデフォルトで有効で、 不要なら --disable-sjlj-exceptions を指定するということに変わったのかな?
Rubyはコンパイルできました。
Linux上に、Cygwinのクロスコンパイル環境を作ろうとしたが敗北。 Cygwinのコンパイルは、できるっぽいのだけど、-mno-cygwin で敗北。 クロスコンパイル環境を作るために使ったのは、gcc-3.4.3じゃなくて、gcc-3.3.3。
Cygwinで駄目だったので、Mingw Programming Kitを参考に挑戦。 rpm をそのままインストールすると、Javaやら何やら使わないものまで入ってくるので。 Mingwのサイトから
binutils-2.15.91-20040904-1-src.tar.gz gcc-core-3.4.2-20040916-1-src.tar.gz gcc-g++-3.4.2-20040916-1-src.tar.gz mingw-runtime-3.7.tar.gz w32api-3.2.tar.gz
をダウンロード。
mkdir -p /usr/local/mingw32/i386-mingw32
tar zxvf w32api-3.2.tar.gz {lib,include}
tar zxvf mingw-runtime-3.7.tar.gz {lib,include}
mv lib /usr/local/mingw32/i386-mingw32
mv include /usr/local/mingw32/i386-mingw32
tar zxvf binutils-2.15.91-20040904-1-src.tar.gz
cd binutils-2.15.91-20040904-1
./configure --prefix=/usr/local/mingw32 --target=i386-mingw32 --disable-nls
make
make install
tar zxvf gcc-core-3.4.2-20040916-1-src.tar.gz
tar zxvf gcc-g++-3.4.2-20040916-1-src.tar.gz
cd gcc-3.4.2-20040916-1
CFLAGS=-O2 ./configure --prefix=/usr/local/mingw32 --disable-nls \
--enable-sjlj-exceptions --target=i386-mingw32
make
make install
とりあえず Rubyのコンパイルはできました。
./configure --prefix=/home/suke/wine/c/usr/local --enable-shared \ --host=i386-mingw32 --build=i686-pc-linux --target=i386-mingw32 make make install
一応 Wine 上で動きます。
理屈としては、extconf.rb が動いて、i386-mingw32-gcc でコンパイル、リンクすればいいはずなので、 i386-mingw32-gcc にPATHを通しておいてから、
ruby -I /home/suke/wine/c/usr/local/lib/ruby/1.8/i386-mingw32 \ -I /home/suke/wine/c/usr/local/lib/ruby/1.8 extconf.rb
ここで ruby は、Linux 上の普通に動く Ruby です。
ruby -v ruby 1.8.2 (2005-03-25) [i686-linux]
ちょっとかっこ悪いですが、Makefileを書き変えます。
ruby = /home/suke/wine/c/usr/local/bin/ruby を ruby = /usr/local/bin/ruby に変更
あとは、
make make install
で終わりです。
Wine 上でテストのダイアログ(test.rb)が動きました。
お昼前にartonさん、cuzicさんと待ち合わせて、昼食。 Firefoxの話とか、Excelの話とか、Win32OLEの話だとか...なんか他にも色々。
午後、Ruby Hot Topics の講演を聴く。 RoRの話。 コンソールの文字が小さくて読み取りづらかったのだが、簡単に動くWeb アプリケーションができるみたい。 その後、高橋さんの補足説明があった。このプレゼンが上手くて、ちょっと触ってみようかという気にさせられる。
続いて、明日は選挙なので、日本Rubyの会公認の、ささだ候補の選挙演説を聴く。 ひげもそって髪も切って小ざっぱりした感じで清潔感が漂ってます。 さすが、公認候補。 まさか、こんなところでWin32OLEが登場するとは思わなかったよ。 後で、ささださん本人に聞いたところでは、YARVがどうのこうのより、YARV(Ruby)からOfficeのソフトが動くデモを見せると 一般にはウケがいいんだそうな。 見事な選挙戦術ですな。
続けてHikiの話を聴く。 「見える化」という文字を見て、思わず、XPの平鍋さんを連想したのは私だけでしょうか。 Pluginによる機能拡張は面白かった。 あと、メールと連動する話とか。
RoRにしろ、Wikiにしろ、私のやる気が起きないのは、(私にとっての)有効な使い道を思いつかないから。 結局、インストールして動かしておしまいという気がする。 Wikiみたいなものだと、個人で使う分には、Howm で十分だし。
でも、インストールしてみないことには、何も始まらないのも事実。
そのあと、ブースを見て回る。 OpenOffice のブースがあって、戴いたパンフレットに「速い」と書いてあったので、 「速いんですか?」と聞くと「マシンが速ければ。」と回答されてしまう。 で、せっかくなので、気になっていた質問をする。
「Windows の OpenOfficeってCOMの機能というか、VBから使ったりすることはできるんですか?」と私。 「OpenOffice側がCreateObjectをすることはできないけど、VBなどからの利用はできます。」 「2.0だとTypeLibraryをサポートしてますか?」(←これが本題。) 「...ちょっとわかりません。」
という訳で、
WIN32OLE#ole_methods
などが、OpenOffice 2.0 で動くかどうか、今は「ちょっとわかりません。」 どこまで、RubyのWin32OLEで、OpenOfficeを操れるのかも不明です。 インストールして確認するのが一番早いのだけど、いろいろ事情がありまして...。
変な質問する奴だと思われたでしょうが、許してください。> OpenOffice の担当の人
RoRはダウンロードすらしてません。そう言えば、HikiもYARVも...。 何も知らないど素人として明日は臨みます。
マウスのボタンを押して離したときのイベントを拾うには、 Fox::SEL_LEFTBUTTONRELEASE を使います。 Fox::FXMainWindowだとイベントを拾えないっぽいので、例によって Fox::FXCanvasオブジェクトを使います。 X座標は Fox::FXEvent#click_x で、Y座標は Fox::FXEvent#click_y で取得できます。
require 'fox12'
def sel_paint(canvas, sender, sel, event)
Fox::FXDCWindow.new(canvas) do |dc|
dc.foreground = canvas.parent.backColor
dc.fillRectangle(0, 0, canvas.width, canvas.height)
end
end
def sel_leftbuttonrelease(sender, sel, event)
puts "x = #{event.click_x}, y = #{event.click_y}"
end
app = Fox::FXApp.new('Fox', 'mouse')
app.init(ARGV)
main = Fox::FXMainWindow.new(app, "mouse", nil, nil, Fox::DECOR_ALL, 0, 0, 200, 120)
canvas = Fox::FXCanvas.new(main, nil, 0, Fox::LAYOUT_FILL_X|Fox::LAYOUT_FILL_Y)
canvas.connect(Fox::SEL_PAINT) do |sender, sel, event|
sel_paint(canvas, sender, sel, event)
end
canvas.connect(Fox::SEL_LEFTBUTTONRELEASE) do |sender, sel, event|
sel_leftbuttonrelease(sender, sel, event)
end
main.show(Fox::PLACEMENT_SCREEN)
app.create()
app.run()
まあ、そういうことです。
四角を描くには、Fox::FXDCWindow#fillRectangle を使います。 四角の枠だけ描くには、Fox::FXDCWindow#drawRectangle を使います。 4つの引数は、順に四角の左上の頂点のX座標、Y座標、幅、高さを意味します。
require 'fox12'
require 'fox12/colors'
def sel_paint(canvas, sender, sel, event)
Fox::FXDCWindow.new(canvas) do |dc|
dc.foreground = canvas.parent.backColor
dc.fillRectangle(0, 0, canvas.width, canvas.height)
dc.foreground = Fox::FXColor::Black
dc.drawRectangle(20, 20, 20, 20)
dc.foreground = Fox::FXColor::Red
dc.fillRectangle(41, 21, 19, 19)
end
end
app = Fox::FXApp.new('FXRuby', 'test')
app.init(ARGV)
main = Fox::FXMainWindow.new(app, "test", nil, nil, Fox::DECOR_ALL, 0, 0, 200, 120)
canvas = Fox::FXCanvas.new(main, nil, 0, Fox::LAYOUT_FILL_X|Fox::LAYOUT_FILL_Y)
canvas.connect(Fox::SEL_PAINT) do |sender, sel, event|
sel_paint(canvas, sender, sel, event)
end
main.show(Fox::PLACEMENT_SCREEN)
app.create()
app.run()
情報ありがとうございます。 本当に7.0はあったのですね。 ダウンロードしてインストールしました。
うちの環境だと、何故か起動時に
There was an error while loading the plug-in 'PPKLite.api'. The plaug-in failed to initialize.
とエラーメッセージが出ます。 それを除けば、それなりに動いているみたいです。 スペースでスクロールもできています。
上のエラーメッセージについてGoogleに質問したところ、 PPKLite.api の名前を変更しておけばいいらしいんじゃないかなという情報らしきものがあるように思えたので (←この歯切れの悪さは、私の確信の無さを意味します。)
cd /usr/local/Adobe/Acrobat7.0/Reader/intellinux/plug_ins mv PPKLite.api PPKLite.api_error
としておきました(← 根拠は無いので、真似する人は自己責任でやってください)。
Adobe Acrobat Reader 7.0が出たらしいのでインストール。 ダウンロードのページは、以下にも、7.0 という感じなんだけど、ダウンロードしたファイルは linux-5010.tar.gz になっている。 インストールしてみたところ日本語もちゃんと見える。 でも、ヴァージョン情報は、5.0のまま。 freshmeatで見ても、7.0と言いつつダウンロードのファイルは、5.0っぽい。 まあ、読めるからいいとしよう。
線を描くには、Fox::FXDCWindow#drawLineを使います。 4つの引数は、順に、始点のX座標、Y座標、終点のX座標、Y座標になります。
require 'fox12'
require 'fox12/colors'
def sel_paint(canvas, sender, sel, event)
Fox::FXDCWindow.new(canvas) do |dc|
dc.foreground = canvas.parent.backColor
dc.fillRectangle(0, 0, canvas.width, canvas.height)
dc.foreground = Fox::FXColor::Black
4.times do |i|
dc.drawLine(20*(i+1),20, 20*(i+1), 80)
dc.drawLine(20, 20*(i+1), 80, 20*(i+1))
end
end
end
app = Fox::FXApp.new('FXRuby', 'test')
app.init(ARGV)
main = Fox::FXMainWindow.new(app, "test", nil, nil, Fox::DECOR_ALL, 0, 0, 200, 120)
canvas = Fox::FXCanvas.new(main, nil, 0, Fox::LAYOUT_FILL_X|Fox::LAYOUT_FILL_Y)
canvas.connect(Fox::SEL_PAINT) do |sender, sel, event|
sel_paint(canvas, sender, sel, event)
end
main.show(Fox::PLACEMENT_SCREEN)
app.create()
app.run()
により、このページのここ4日分くらいの情報が消えてしまいました。 まあ、大したことを書いている訳じゃないので。
トップページの更新日付の情報も一部変になってしまいました。 内容は昔のままで何も新しくなってません。
色を変えるには、Fox::FXDCWindow#foreground= メソッドを使います。 指定する色については、あらかじめ、require 'fox12/colors' としておくと便利です。 例えば、赤を指定したい場合は、Fox::FXColor::Redとします。 colors.rb の中で、Fox::FXColor::Red は以下のように定義されています。
Red = Fox.FXRGB(255, 0, 0)
実体としては、RGBの値をそれぞれ指定して、Fox.FXRGBメソッドを呼び出すだけです。 colors.rbを見ればわかりますが、かなり多くの色が、あらかじめ定義されています。
フォントを変えるには、Fox::FXDCWindow#font= メソッドを使います。 実際には、Fox::FXDCWindow#font= であらかじめフォントを指定しないとエラーになります。 デフォルトのフォントは無いみたいです。
require 'fox12'
require 'fox12/colors'
def sel_paint(canvas, sender, sel, event)
Fox::FXDCWindow.new(canvas) do |dc|
dc.foreground = canvas.parent.backColor
dc.fillRectangle(0, 0, canvas.width, canvas.height)
dc.foreground = Fox::FXColor::Red
dc.font=$font1
dc.drawText(20, 20, "Hello")
dc.font=$font2
dc.drawText(20, 60, "Hello")
end
end
app = Fox::FXApp.new('nono', 'test')
app.init(ARGV)
$font1 = Fox::FXFont.new(app, "times", 8)
$font1.create
$font2 = Fox::FXFont.new(app, "times", 24)
$font2.create
main = Fox::FXMainWindow.new(app, "test", nil, nil, Fox::DECOR_ALL, 0, 0, 200, 120)
canvas = Fox::FXCanvas.new(main, nil, 0, Fox::LAYOUT_FILL_X|Fox::LAYOUT_FILL_Y)
canvas.connect(Fox::SEL_PAINT) do |sender, sel, event|
sel_paint(canvas, sender, sel, event)
end
main.show(Fox::PLACEMENT_SCREEN)
app.create()
app.run()
なんか起動に異様に時間がかかるので、
./configure --disable-kde --disable-gnome --disable-xrender --disable-randr --disable-nls make make install
し直しました。
--disable-xbm
した方がさらに起動は速くなります。 でも、タイトルバーで日本語が文字化けするのも悲しいので、このままにします。
これは、これで面白いコンセプトのウィンドウマネージャです。 困ったことに、gnono のテストでウィンドウサイズが適切に変化するかどうかの確認ができません。 あと、VMWareを使ったときにどうなるのかちょっと気になります。
ある特定のウィンドウ(gnonoやtnonoやwnono on Wine や VMWare)だけは、 サイズ変更しないという指定ができれば、これを使うのもありかも知れないと思わないでもないです。
Fox::FXMainWindow に直接文字を描く方法がわかりません。 Fox::SEL_PAINT イベントを拾うことができるFox::FXCanvasを子ウィンドウとして作って そこに文字を描きます。 Fox::FXCanvas.new で子ウィンドウを作るときに、ウィンドウのスタイルを Fox::LAYOUT_FILL_X|Fox::LAYOUT_FILL_Y と指定しておくと、 勝手に親ウィンドウの大きさに広がってくれます。
require 'fox12'
require 'fox12/colors'
def sel_paint(canvas, sender, sel, event)
Fox::FXDCWindow.new(canvas) do |dc|
dc.foreground = canvas.parent.backColor
dc.fillRectangle(0, 0, canvas.width, canvas.height)
dc.foreground = Fox::FXColor::Black
dc.font=$font
dc.drawText(0, $font.fontHeight, "Hello")
end
end
app = Fox::FXApp.new('First', 'test')
app.init(ARGV)
$font = Fox::FXFont.new(app, "Sans", 14)
$font.create
main = Fox::FXMainWindow.new(app, "test", nil, nil, Fox::DECOR_ALL, 0, 0, 200, 120)
canvas = Fox::FXCanvas.new(main, nil, 0, Fox::LAYOUT_FILL_X|Fox::LAYOUT_FILL_Y)
canvas.connect(Fox::SEL_PAINT) do |sender, sel, event|
sel_paint(canvas, sender, sel, event)
end
main.show(Fox::PLACEMENT_SCREEN)
app.create()
app.run()
sel_paint メソッドの中で、dc.fillRectangle でFXCanvas全体を塗りつぶしてます。 実は、こうしないと透明になってしまい、後ろの画面が透けて見えてしまいます。 あと、デフォルトのフォントが無いらしく、dc.font=(Fox::FXDCWindow#font=) で明示的にフォントを指定してやらないとエラーになります。
文字の表示には、Fox::FXDCWindow#drawText を使います。 マニュアルだと、第1引数が左上のx座標、第2引数が左上のy座標と読めるのですが、 実際には、左下じゃないかと思われます。 第2引数を0にしてしまうと、文字が消えてしまいます。
FOX Toolkit 側のサンプルプログラム(tests/dctest.cpp)を修正してちょこっと試してみたら やっぱり左下っぽいので、FXRubyのバグという訳でもないと思います。
ちなみに、文字の背景色を指定する場合は、Fox::FXDCWindow#drawImageText を使います。
FXRuby も FOX も知りません。 文字を表示する前に何もないウィンドウを出すところから始めてみます。
require 'fox12'
app = Fox::FXApp.new('win', 'fox')
app.init(ARGV)
main = Fox::FXMainWindow.new(app, "win", nil, nil, Fox::DECOR_ALL, 0, 0, 200, 120)
main.show(Fox::PLACEMENT_SCREEN)
app.create()
app.run()
まず、Fox::FXApp.new で、Fox::FXAppオブジェクトを生成します。 第1引数と第2引数で指定するものが何なのかよくわかりません。 なんか、マニュアルを読むと、Window プログラミングの RegisterClass あたりで使うものを設定するのかなとも思われます。
その後、app.init(ARGV) で初期化処理をします。
Fox::FXMainWindow.new でメインウィンドウを生成します。 第2引数は、ウィンドウのタイトルで、第3引数と第4引数はアイコン、第5引数はウィンドウのスタイル 第6引数がx座標、第7引数がy座標、第8引数がウィンドウの幅、第9引数がウィンドウの高さになるようです。
第5引数のFox::DECOR_ALLの値は、タイトルバーがあって、 最大化できて最小化もできてクローズボタンがあって、リサイズできて... など、いくつかのスタイルの組み合わせになっているようです。
app.runでイベントループを開始します。
X Window のプログラミングの経験は無いので、それと比較することはできないのですが、 FXRuby に対する私の第一印象は、Windows プログラミングの影響を受けている極薄のラッパーです。
でも、FOX の X は X Window の X だそうなので、X Window プログラミングでも似たような感じなんでしょうか。 そもそも、Windows は、X Window を真似たものだったかな???
久々に見てみたら
Please note that 0.1.14 is actually fairly dated (and unmaintained) now, and the development series is quite stable.
とのことなので、 fluxbox-0.9.12 をダウンロードしてインストールしてみた。
./configure --disable-xft --disable-kde make make install
FOX 1.4 系に対応したFXRubyは無いみたいなので、 FOX Toolkitから、 fox-1.2.13.tar.gz をダウンロードしました。
tar zxvf fox-1.2.13.tar.gz cd fox-1.2.13 ./configure
なぜか utils 配下のリンクに失敗するので、utils/MakefileのLIBS を変更。
# LIBS = -ldl -lpthread -ljpeg -lpng -ltiff -lz -lbz2 -lm -lGL -lGLU LIBS = -ldl -lpthread -ljpeg -lpng -ltiff -lz -lbz2 -lm -lGL
あとは、普通です。
make make install
FXRubyから FXRuby 1.2.5を ダウンロードします。
tar zxvf FXRuby-1.2.5.tar.gz cd FXRuby-1.2.5 ruby install.rb config ruby install.rb setup ruby install.rb install
まあ、そういうことです。
Ruby/Tk で処理の途中で描画を強制的にさせる方法がわかりません。 なので、Solve Step by Step が動かず、メニューから消しました。 TkTimerか、TkRTTimer か Thread か使えばできるかも知れないと考えているのですが、具体的なイメージが浮かんできません。
Solve Step by Step は動作しませんが、それ以外は一応の格好がついたので、 nono 0.0.8を公開します。
例によって、念のため、断わっておきますが、gnono の g を t に変えただけじゃありませんから。
TkCanvasオブジェクトないのマウスの左ボタンクリックのイベントを拾うには、 TkCanvas#bind メソッドを使います。 TkCanvas#bind メソッドの第1引数の"1"がマウスの左ボタンクリックを意味します。 TkCanvas#bind メソッドの第2引数でイベントに対応する処理を Procオブジェクトで指定します。
Procオブジェクトは引数を1つ受けとるようにしておきます。 Procオブジェクトで受け取る引数は、TkEvent::Event オブジェクトで、マウスがクリックされた位置などの情報が含まれます。 クリックされた位置は、TkEvent::Event#x, TkEvent::Event#y で取り出すことができます。
require 'tk'
def lmouse_click(event)
puts "[x = #{event.x}, y = #{event.y}]"
end
c = TkCanvas.new {|x|
pack('fill' => 'x')
}
c.bind("1", proc{|event| lmouse_click(event)})
Tk.mainloop
まあ、そういうことです。
なんか知らない間に動かなくなっていたのだけど、最新版にしたら、動くようになった。
まあ、そういうことです。
これがわからなくて悩んでしまいました。
逆引きRuby/Tk にはボタンで大きさが変わる例があります。 残念ながら、紹介されている例だと、マウスで画面の端をつかんでウィンドウの大きさを変えたが最後、 ボタンを押してもウィンドウの大きさは変わらないのです。 試しに
Tk.root.width(l.width + 10)
とやっても変わりませんでした。
あれこれ探してようやく見つけたのが、Tk.root.geometry を使う方法です。 Tk.root.geometry の引数は、X Window Systemでお馴染みの 100x200+20+30 スタイルで指定します。 引数無しで呼び出すと現在のサイズと位置を取得してくれるみたいです。
require "tk"
l = TkLabel.new {
text "Hello!!"
pack
}
TkButton.new {
text "Wide"
command {
new_width = Tk.root.geometry.sub(/x.*$/, "").to_i + 10
Tk.root.geometry(new_width.to_s + Tk.root.geometry.sub(/[\d]+x/, "x"))
}
pack('fill' => 'x')
}
TkButton.new {
text "Narrow"
command {
new_width = Tk.root.geometry.sub(/x.*$/, "").to_i - 10
Tk.root.geometry(new_width.to_s + Tk.root.geometry.sub(/[\d]+x/, "x"))
}
pack('fill' => 'x')
}
Tk.mainloop
まあ、そういうことにしておきます。
1.1.3 からバージョンアップ。 「名前をつけて保存」がまともに動いている感じ。
TkcLine.new を使います。
require 'tk'
c = TkCanvas.new {|x|
pack('fill' => 'x')
}
4.times do |i|
TkcLine.new(c, 20*(i+1),20, 20*(i+1), 80)
TkcLine.new(c, 20, 20*(i+1), 80, 20*(i+1))
end
Tk.mainloop
TkcRectangle.new を使います。 四角の中を色づけするには、:fill を使います。 四角の枠の色を指定するには、:outline を使います。
require 'tk'
c = TkCanvas.new {|x|
pack('fill' => 'x')
}
TkcRectangle.new(c, 20, 20, 40, 40, :fill => "#FF0000")
TkcRectangle.new(c, 40, 20, 60, 40)
TkcRectangle.new(c, 80, 20, 100, 40, :outline => "#0000FF")
Tk.mainloop
TkcTextで文字の色を変えるには、:fill で色を指定します。 色の指定の仕方は、色を表す文字列を指定します。 また、CSSなどでもお馴染みのRGBの #RRGGBB 形式でも指定できます。
require "tk"
c = TkCanvas.new {|x|
pack('fill'=>'x')
}
TkcText.new(c, 40, 20, :text=>"Hello World", :fill=>"red")
TkcText.new(c, 40, 50, :text=>"Hello World", :fill=>"#0000FF")
Tk.mainloop
TkcTextで文字のフォントを指定するには、:font で指定します。 指定するフォントは、TkFont.new で生成するTkFontオブジェクトです。
require "tk"
c = TkCanvas.new {|x|
pack('fill'=>'x')
}
TkcText.new(c, 120, 20, :text=>"Hello World", :font=>TkFont.new("Times 24"))
Tk.mainloop
(2005-04-05 追記)フォントの指定は、必ずしもTkFontオブジェクトでなくてもいいことを教えていただきました。
TkcText.new(c, 120, 20, :text=>"Hello World", :font=>"Times 24")
または
TkcText.new(c, 120, 20, :text=>"Hello World", :font=>["Times", 24])
または
TkcText.new(c, 120, 20, :text=>"Hello World",
:font=>{:family=>"Times", :size=>24})
でも大丈夫です。
例によってTkLabelを使わないでTkCanvasの好きな位置に文字を表示します。
require "tk"
c = TkCanvas.new {|x|
pack('fill'=>'x')
}
TkcText.new(c, 40, 20, :text=>"Hello World")
Tk.mainloop
ここで注意しなくてはいけないのは、TkcText.newで指定する第二引数と第三引数の値です。 第二引数はx座標、第三引数はy座標を意味しますが 指定された位置は、表示する文字の開始位置ではありません。 表示する文字の中央の位置になります。 ですから、
TkcText.new(c, 0, 0, :text=>"Hello World")
などとすると、"World"の下半分しか表示されず、悲しい気持ちになります。
(2005-04-04 追記) anchor を使えば悲しい気持ちにならないということを教えていただきました。
require "tk"
c = TkCanvas.new {|x|
pack('fill'=>'x')
}
TkcText.new(c, 0, 0, :text=>"Hello World", :anchor=>:nw)
Tk.mainloop
ここで指定している :nw の n は北(上)を意味し、w は西(左)を意味します。 ここで、anchor を省略した
TkcText.new(c, 0, 0, :text=>"Hello World")
は
TkcText.new(c, 0, 0, :text=>"Hello World", :anchor => :center)
または
TkcText.new(c, 0, 0, :text=>"Hello World", :anchor => :c)
とした場合と同じになります。
準備してきたものを組み合わせてみました。 nono 0.0.7をリリースします。 念のため断っておきますが、wnono は gnonoとは別物です。 タイトルバーの gnono の g を w に変えただけじゃないかと疑ってはいけません。 ちゃんと本当に組み合わせてますから。
2月末には、840円の赤字プロジェクトになるはずだったのだが、そうはならなかった。 420円分を補填できた訳ではない。 単にプロジェクトリーダーがイラストロジック4月号の発売日をすっかり忘れていたためである。 今日、本屋でイラストロジックを手に取ったのだが、答え合わせをするのが面倒だと思い始めた。 立ち読みで答えをパラパラと眺めたのだが、何となく合ってそうだったので、それで良しとすることにした。 超難問の問題の答えも逆立ちした天才バカボンのパパで、正解みたいだった。
このプロジェクトに関連する出費の予定も入金の予定も今のところないので、 420円赤字プロジェクトのまま進行しそうな雰囲気である。
nonoは、アニメほど動きがある訳でもなく、デザインはダメダメだし、犬の愛らしさには敵わない(2005年3月5日現在)。
ようやく、どう使えばいいかわかってきたような気がします。 こんな感じではないかと思います。
require 'vr/vruby'
require 'vr/vrcontrol'
require 'vr/vrhandler'
require 'vr/vrmargin'
class MyPanel < VRCanvasPanel
def construct
@i = -1
@colors = [RGB(0, 0, 0)]
@rect = nil
end
def set_init
2.times do |i|
@canvas.drawLine(20*(i+2),20, 20*(i+2), 60)
@canvas.drawLine(20, 20*(i+2), 60, 20*(i+2))
end
@canvas.opaque = false
font = @screen.factory.newfont("Terminal", 20)
@canvas.setFont(font)
@canvas.drawText("1", 20+5, 40 + 1, 40, 79)
end
def self_paint
if @colors.size == 1
bkcolor = getPixel(4,4)
@colors.push(bkcolor)
createCanvas(80, 80, bkcolor)
set_init
end
super
end
include VRMouseFeasible
def self_lbuttonup(shift, x, y)
if 40 < x && x < 60 && 40 < y && y < 60
@i += 1
@i %= @colors.size
@canvas.setBrush(@colors[@i])
@canvas.fillRect(40, 40, 60, 60)
easyrefresh
end
end
def easyrefresh
dopaint {
self_paint
}
end
end
class MyForm < VRForm
include VRResizeSensitive
include VRMenuUseable
def construct
self.caption = "using dopaint"
addControl(VRStatic, "msg", "message", 10, 10, 60, 20, 1).
extend(VRMargin).initMargin(0, 0, 0, nil)
addControl(MyPanel, "panel", "").extend(VRMargin).initMargin(0,20,0,0)
end
def self_resize(w, h)
if @panel
@msg.move(0, 0, w, 20)
@panel.move(0, 0, w, h)
end
end
end
VRLocalScreen.start(MyForm, 200, 200, 250, 200)
今度こそ本当に。
SWin::Canvas オブジェクトを生成して、そこに図形と文字を描画します。
self_paint メソッドの内部では、描画する領域が指定されていない場合は、 SWin::Canvas に図形と文字を描画してまるごと画面にstretchでコピーします。
マウスのイベントが発生したら、再描画する領域をRectオブジェクトで生成して、画面の再描画を要求します。 このとき背景色で画面全体を塗りつぶしてしまわないように、refresh メソッドの引数は false にします。 self_paintメソッドでは、描画する領域が指定されている(Rectオブジェクトが存在する)ので その領域のところだけ、SWin::Canvas から画面にstretchでコピーします。
require 'vr/vruby'
require 'vr/vrcontrol'
require 'vr/vrhandler'
# 描画領域の範囲を指定するRectクラス
class Rect
attr_accessor :top, :bottom, :right, :left
def initialize(left, top, right, bottom)
@left = left
@top = top
@right = right
@bottom = bottom
end
end
class MyPanel < VRCanvasPanel
def construct
@i = -1
@colors = [RGB(0, 0, 0)]
@canvas = nil
@rect = nil
end
def self_paint
# SWin::Canvasオブジェクトが無かったらここで生成する。
if !@canvas
bkcolor = getPixel(4,4)
@colors.push(bkcolor)
createCanvas(80, 80, bkcolor)
@canvas = canvas
end
# 四角形をSWin::Canvasに描画する
@canvas.setBrush(@colors[@i])
@canvas.fillRect(40, 40, 60, 60)
if @rect
# 描画する領域が指定されていると、その部分だけ@canvasから画面に転送
stretch(@rect.left, @rect.top, @rect.right, @rect.bottom, @canvas,
@rect.left, @rect.top, @rect.right, @rect.bottom)
@rect = nil
else
# SWin::Canvasに線と文字を描画する。
2.times do |i|
@canvas.drawLine(20*(i+2),20, 20*(i+2), 60)
@canvas.drawLine(20, 20*(i+2), 60, 20*(i+2))
end
@canvas.opaque = false
font = @screen.factory.newfont("Terminal", 20)
@canvas.setFont(font)
@canvas.drawText("1", 20+5, 40 + 1, 40, 79)
# SWin:Canvas をまるごと画面に転送
stretch(0, 0, 80, 80, @canvas)
end
end
include VRMouseFeasible
def self_lbuttonup(shift, x, y)
if 40 < x && x < 60 && 40 < y && y < 60
@i += 1
@i %= @colors.size
# 領域指定
@rect = Rect.new(40,40,60,60)
# 背景色で描画し直さないで画面を再描画
refresh(false)
end
end
end
ちなみに、SWin::Canvasオブジェクトへの描画処理は、self_paint 以外のメソッドでも自由にできます。 SWin::Window(SWin::MyPanel)に描画するには、self_paint内部(WM_PAINTイベント処理の内部)でないといけません。 SWin::Canvasに描く方が柔軟に好きなタイミングで好きなように描くことができます。 self_paint内部でないといけないのは、stretch で実際にSWin::MyPanelに描く処理だけです。
今度こそ、ネタは揃ったので、後はネタを組み合わせるだけです。 と思ったら、 質問に答えていただいていたようで。 見落してました。