Clutter は魅力的ではあるが描写の全部を自前で用意する必要がある。
つまり GtkButton, GtkListView のような Widget は無い。
それなら ClutterActor を GtkContainer 上に pack できればよくね?
やってみると普通に拒否、全くの別物だからそりゃ当然の話だ。
しかし GNOME3 自体はしっかり連携している。
知らないだけで何か方法があるはずだ。
/usr/lib64/girepository-1.0
をよく見ると GtkClutter というものがある。
Clutter Gtk integration on Vimeo
WPF のような新規ウイジェットではなく GTK+ をエフェクトするみたい。
そりゃ GTK+3 自体が新規だし元から連携していてもおかしくない。
Clutter-Gtk 1.0.2 Reference Manual
どうやら GtkClutterWindow は GtkWindow のサブクラス。
ClutterActor が表面に張り付いている状態って認識でいいのかな?
Python からは get_stage() で ClutterStage が取得できそうである。
#!/usr/bin/env python
#-*- coding:utf-8 -*-
import sys
from gi.repository import Gtk, Clutter, GtkClutter, ClutterX11
def quit(widget, data=None):
Gtk.main_quit()
#ClutterX11.set_use_argb_visual(True)
#ClutterX11.set_display(ClutterX11.get_default_display())
#ClutterX11.disable_event_retrieval()
Clutter.init(sys.argv)
w = GtkClutter.Window()
w.connect("destroy", quit)
w.set_title("GtkClutter.Window")
w.resize(300, 200)
stage = w.get_stage()
stage.set_size(300.0, 200.0)
w.show_all()
Gtk.main()
WARNING 出まくり、初期化とか色々やってみたけど駄目だった。
とりあえず get_stage() だけはできている、使い方が悪いのだろう。
ついでにこの場合 delete-event ではなく destroy 指定でないと終了しない。
直感でやっても上手くいかない、もっと良い方法は無いだろうかと検索。
gtk_clutter_embed_new ()
で作成した Object なら Gtk+ コンテナに入れられるようだ。
試すと上手くいったので ClutterGst でやってみる。
#!/usr/bin/env python
#-*- coding:utf-8 -*-
import sys
from gi.repository import Gtk, Clutter, GtkClutter, ClutterGst
class ClutterEmbedTest(Gtk.Window):
def __init__(self):
Gtk.Window.__init__(self)
# Video Texture
tx = ClutterGst.VideoTexture()
tx.set_uri("file:///home/sasakima-nao/movie/bike/ninjya1000_1.mp4")
# Create the Clutter Widget
embed = GtkClutter.Embed.new()
embed.connect("size-allocate", self.on_size_allocate, tx)
# ClutterStage
stage = embed.get_stage()
stage.add_actor(tx)
# Buttons
play = Gtk.Button(stock=Gtk.STOCK_MEDIA_PLAY)
play.connect("clicked", self.on_play, tx)
# packing
vbox = Gtk.VBox()
vbox.pack_start(embed, True, True, 0)
vbox.pack_start(play, False, False, 0)
self.add(vbox)
self.set_title("ClutterEmbedTest")
self.connect("delete-event", self.on_quit)
self.show_all()
def on_size_allocate(self, widget, allocation, tx):
w = widget.get_allocation().width
h = widget.get_allocation().height
tx.set_size(w, h)
def on_play(self, widget, tx):
tx.set_playing(True)
def on_quit(self, widget, data=None):
Gtk.main_quit()
if __name__ == '__main__':
# initialized
Clutter.init(sys.argv)
ClutterGst.init(0, "")
ClutterEmbedTest()
Gtk.main()
よしコレなら何も警告は出ない。
警告が出ないようガンバった WPF 3.0 アプリが 3.5 で無意味にされた過去が…
初心者はワケワカだろうけど、こんな苦労も数年後には無意味になるのでしょう。
やはり親ウインドウサイズに連動しないので size-allocate シグナルを利用。
ClutterActor のサイズは float だけど int のままサイズ変更できた。
コレで GTK+ Widget と ClutterActor の共存アプリケーションができる。
アスペクト比保持とかはどうやるんだろう?
というか最初のビデオでは GTK+ widget にエフェクトが掛かっていたような…
まだ先は長い、リファレンスマニュアル無しで作るのは狂気だがコレが楽しい。


