というわけで、wxが何で実装されていて何にmapされているのか調べることした。まずは足回りはなんであるかを知ることからかな。高林哲氏のページに触れられているように、ネイティブなwindow描画システムをラップしてプラットフォーム非依存なAPIを提供するモノなので。
たなの中に寝ていたCross Platform Programming With wxWidgets を引っ張り出してきてパラパラしてみる。
同書の電子版、重め(7MB)。
cross~~のp8から引用。wxWidgetsは、portレイヤーを持っていて、そこで指定されるプリミティブな機能を各プラットフォームごとに実装している。
- M$ Windows : wxMSWで、win32 APIらしいです。
- Mac OS X : 選択肢はCocoa or Carbonです。それぞれwxCocoa, wxMacです。
OOoのCarbon移植のメモ。macに関しての情報ではほしいものですな。Carbonの利用はなくならないだろうという予想もありがたい。
現状Macminiに入っているのは、たぶんwxMacだと思う。事実、ipythonをつかって調べると
$ ipython
In [1] import wx
In [2] wx.PlatformInfo
('__WXMAC__',
'wxMac',
'wx-assertion-on',
'SWIG-1.3.29',
'mac-cg',
'mac-native-tb')
となる。
ん~~情報古め。- Carbon
- Appleが出しているCarbonのイベント処理に関するdocument
- MacOSXにおけるwxWidgetsでの開発方法 @ Malon,Inc
- OS X で wxGlade を使って wxWidgets によるクロスプラットフォームな GUI プログラムを作る準備 @ 141 WebLog
- wxCocoaは状況がよくわからない。googleのヒット件数も約3000件とwxMacの10分の1だし
MLでのwxCocoaはじめました宣言、まあ普通に入ってくるのはwxMacのほうだししばらく無視。
- Carbon
- Linux : GTK+/wxGTK, Xlib/wxX11, Motif/Lesstif/wxMotif、最後のwxMotifはどうでもいい。
EVT_PAINT
前出のCross platform ~~はflickerをなくすにはという観点に言及した上でpaintについて述べている(Chap5)
で、window systemによらずに汎用的に使われているテクニックを列挙する。
- doublebuffer : 小さいrectを複数回かけて画面に書くとちらつくのでいったんでかいbufferに書いてから画面に書き出す。
- invalidation rect : 全部を書き直すと無駄なので、書き直しが必要になった領域をrectで管理する。書き直しを要求するとき(wxではwxWindow::Refreshを呼び出すとき)に指定する。
ここから先はwx依存の話
- wxWindow::RefreshとwxWindow::Updateの意味。
wxWindow::Refreshを呼ぶとPaint Eventが発生する(その前にwxEVT_ERASE_BACKGROUNDが発生する、後述)。呼ばないといつPaintされるかわからない。自身のsizeに依存して表示内容が変わるようなwidgetをSizeしたときにはrefreshしてやらないとPaintが呼ばれないので、再描画のルーチンが走らない。
さらにwxWindow::UpdateをよんであげないとBufferの中身が画面に反映されない。どういうわけだか手元のLinux環境(Centos5.1 gnome)では、Updateがなくても大丈夫、本当はよくないのだろうけど。 - wxFULL_REPAINT_ON_RESIZE:
今回問題となったwidgetでは指定必須。
なぜならサイズが変わると中身が全部無効になるので、すべての書き直しが必要。縮尺の違う画像パーツをwindow上にのこされても意味なし。
で、最初はこの指定をしていなかったのだが、Linux/GTK+だったので現れなかった模様。Mac OS Xで動かしたときに、resize時windowに「ゴミ」が残るという形で発覚。 - wxEVT_ERASE_BACKGROUND:(p134)
wxWidgetsでいうところのwxEraseEvent。目的はプラットフォーム側がおこなうbackgroundのclearの方法を指定することにある。たとえばpaintが全面書き換えならclearしなくてもごみがwindowに表示されることはない。それどころかclearされるとちらつく。極端な場合だと「べろんべろんべろん」とclear->paintのサイクルが見えてしまう。
wxWindow::SetBackgourndColorはこのイベントのデフォルトのhandlerがwindowのrectをfillする際の色を指定している。だからpaintのhanderでwx.Brushをつかってbackgroundをfillするのとは意味が違う。結果としてできる外見がおなじになるかもしれないが。
残念ながらこのeventの話はwxPython in Actionの中には出てこない。とはいってもこの本の価値がさがることはまったくない。cross ~~とは方向性が違う本ですから。
さらにwxBG_STYLE_CUSTOMなるものをwxWindow::SetBackgroundStyleをつかって設定できるようだ。実装報告のスレッド in wx dev ML
この子は、もっとローレベルの書き換え、プラットフォームのwindow systemがfillすることを抑制できるようになる。SetBackgourndColorはwxWidget側がやっていたがそれとは別にwindow systemがやっているfillも存在するのだ。これをコントロールできる。なにが起こるかはプラットフォーム依存なはず。そしてちょっと見た限りではドキュメントが存在しない。orz
L9397 @ google code seach
これと同じようにほかのプラットフォームでSetBackgroundStyleしているところが見つかればよいのだが。
画面に画像ファイルを貼り付ける @ Megnumi221 , d.hatena
OnEraseBackgroundメソッドで背景をクリアするらしいが、なぜ必要なのかよく分からん...。
そういうことなんですよ。Megnumi221さん。
文章がだいぶ長くなってしまったのでプラットフォームごとの調査はまた別のページで。
0 件のコメント:
コメントを投稿