gtk.Widget.allocation.height

4/18 に gtk.Widget.allocation.height が表示後でないと取得できないと書いた。
で、フルスクリーンコントローラを一旦表示するまで 50px という仮に値を入れてごまかした。

いや、よく考えたらフルスクリーンコントローラ自体のサイズを得る必要は無かった。
フルスクリーンにする前に既に toolbox, statusbar は表示されているのだから。

ということでやってみたら縦サイズが 1 に、あれ?
そうか、parent 変更すると property が消えて非表示扱いになるんだった。

ということはオブジェクト作成側で調べてパラメータで渡す…
のコードを一度書いてみたけれど何故か気に入らない、なるべくパーツ側で処理したい。
もっと上手い方法は…と考えてみたらこうすりゃいいじゃんと思いついた。

class CFullCtrl(gtk.Window):
    """
        Full Screen Controrer
    """
    def __init__(self, parent, box, parent2, bar):
        """
            GtkWindow at GTK_WINDOW_POPUP
        """
        gtk.Window.__init__(self, gtk.WINDOW_POPUP)
        # memory pointer
        self.p1 = parent
        self.p2 = parent2
        self.box = box
        self.bar = bar
        # Get Desktop Window Geometry
        root = gtk.gdk.get_default_root_window()
        x, y, w, h, d = root.get_geometry()
        # move and resize
        self.set_size_request(w, -1)
        self.y_pos = h - box.allocation.height - bar.allocation.height
        self.move(0, self.y_pos)
        # Change parent
        vbox = gtk.VBox()
        self.box.reparent(vbox)
        self.bar.reparent(vbox)
        vbox.show_all()
        self.add(vbox)
        self.connect("destroy", self.on_destroy)

    def on_destroy(self, widget, event=None):
        """
            Return Parent
        """
        self.box.reparent(self.p1)
        self.p1.set_child_packing(self.box, False, True, 0, gtk.PACK_END)
        self.bar.reparent(self.p2)
        self.p2.set_child_packing(self.bar, False, False, 0, gtk.PACK_START)
        return True

そうだよ、parent 変更する前に値を調べておけばいいじゃないの。
後はフルスクリーン切り替え時に作成や削除をやればつじつまが合うじゃないか。

def change_fullscreen(self):
    if self.fullscreen:
        self.fullscreen = False
        self.w.window.unfullscreen()
        self.w.unfullscreen()
        self.fullobj.destroy()
        self.fullobj = None
        self.w.resize(self.fullsize[0], self.fullsize[1])
    else:
        self.fullscreen = True
        cx, cy = self.w.get_size()
        self.fullsize[0] = cx
        self.fullsize[1] = cy
        self.fullobj = CFullCtrl(
                self.hbox_ctrl,
                self.toolbox,
                self.vbox_main,
                self.statusbar
            )
        self.w.fullscreen()
        self.w.window.fullscreen()

こんな感じの関数を作ればいいしパラメータも増やさずにすんだ。
しかしよく考えたらパーツ作成のパラメータは本体ポインタのみでいいような気がしてきた。
アトリビュートやメンバ関数はそのポインタから得ることができるのだから。

class CStatusBar(gtk.VBox):
    def __init__(self, owner, arg):
        self._win = owner.w
        self._owner = owner
        gtk.VBox.__init__(self)

みたいな感じで、後は self._owner 経由で本体 class のメンバを参照できる。
というか本体のコードをなるべく少なくしたいのですよ、後々のメンテナンスを考えると。
ラムダ式とかは数学系の人は好んで使うようだけどメンテが多いアプリでは怖くて使えませんわ。
ちなみに Windows 用の Y901 最終版は本体コードだけで九千行、この手では短いほうだ。

他、再生停止でマウスカーソルを表示させるのを忘れていた。
ということで Y901x-0.2.5 公開、作った本人以外に使っている人がいるかどうか知らない。