gtk.gdk.Display.get_pointer

Y901x-0.2.3 は大失敗だった。

motion-notify-event で処理しているから VideoArea 領域を外れたら認識しない。
つまり 16:9 の動画を 16:10 ディスプレイで表示した場合とかでは下に黒帯が出る。
その黒帯部分では領域外なので motion を認識なんてするはずがない。
つまりフルスクリーンでのコントローラは出ないわけだ。

んー Cinema では WM_MOUSEMOVE で計算してやっていたんだけどなぁ。
GTK+ ではレイアウタなので超ややこしいし、WindowsAPI の GetCapture みたく…
ってソレどうやるの?面倒なので Timer で処理するようにしよう。

# GetCursolPos
a, x, y, b = gtk.gdk.display_get_default().get_pointer()

で x と y にスクリーン座標で現在のマウスカーソル位置が取得できるようだ。
a は gtk.gdk.Screen、b は Shift や Ctrl の Mask、ここでは使わないのでダミー。
この値を元に処理したらとりあえずディスプレイより横長動画でも処理できた。

せっかくタイマー処理でマウスカーソル位置を取得しているんだからカーソル消去も。
只の Y901 からの伝統で通常時でも画面上は静止状態マウスカーソルを一秒後に消す。
っっって、GTK+ で WindowsAPI の ShowCursor(FALSE); ってどうするの?

gtk.gdk.Cursor

の下のほうに普通に書いていた、つまり自分で作らないといけないんだね。
これが解れば処理方法自体は同じなので Python コードにて書き換えるだけだ。
ということで細かい処理は Y901x のコードを見てもらうとして簡単に。

class Y901window(dbus.service.Object):
    def __init__(self, bus_name):
        # ...
        self.mousepoint = [0, 0]
        self.invisiblecount = 0;
        # Create invisible cursor
        pixmap = gtk.gdk.Pixmap(None, 1, 1, 1)
        color = gtk.gdk.Color()
        self.noncursor = gtk.gdk.Cursor(pixmap, pixmap, color, color, 0, 0)

省略しすぎかな、とにかくタイマーで

    def on_timer(self):
        # ...
        # GetCursolPos
        a, x, y, b = gtk.gdk.display_get_default().get_pointer()
        # FullScreen at Controler
        if self.fullobj:
            if self.fullobj.y_pos < y:
                self.fullobj.show_all()
            else:
                self.fullobj.hide()
        # Cursor Auto Invisible
        if self.mousepoint[0] == x and self.mousepoint[1] == y:
            if self.invisiblecount < 5:
                self.invisiblecount += 1
            else:
                self.video_window.window.set_cursor(self.noncursor)
        else:
            self.invisiblecount = 0;
            self.mousepoint[0] = x
            self.mousepoint[1] = y
            self.video_window.window.set_cursor(None)
        # return True is Repeat
        return self.is_playing

と時間表示とフルスクリーンコントローラとカーソル消去を全部やってみた。
とりあえずこれでつじつまが合っている、かなり Windows 用 Y901(Cinema) を再現できた。
ということで Y901x-0.2.4 公開しました。
やっぱり全然人増えねぇ、Windows 用のようにいかないわな。

gtk.Widget.reparent

いいかげんに Y901x もフルスクリーンでコントローラを出すようにしよう。

方法は色々あるんだが、一番簡単なのは show() hide() だけで済ませる方法。
しかしこれではムービー画面が拡大縮小されてみったくない。
WMP12 や Cinema のように浮き上がらせて表示させる、の方法は解らない…

オーソドックスに下からヒョッコリ出てくる方法にでもとりあえずやっとこう。
これも方法が沢山あるけど別ウインドウを作って被せるのが一番簡単だろう。

とりあえずコントローラ用の gtk.Window を gtk.WINDOW_POPUP 指定で作成。
gtk.Widget の reparent() メソッドで parent の gtk.Box をコッチに変更。
unparent() set_parent() を使うとうまくいかなかった、つか実態が消滅するんだが。

parent を変更すると property が消える、パッキング情報は Box 側が持つんだから当然か。
.NET Framework の WPF なら子オブジェクト側が持っているんだよね、色々あってややこしい。
なので set_child_packing メソッドでパッキング情報を追加するのを忘れずにと。

んでディスプレイサイズを取得して…ってどうやるのだ?

ぱぇぽぃ2 ? Blog Archive ? デスクトッププロパティ

なんだ、自分でやっていたや。
でも Python の勉強を始めたばかりな頃にやったことなんで効率悪すぎる。
wnck を使えば簡単だけど KDE 対応でまた…
ということで、何か他の方法は無いか探したら恐るべきコードを発見。

pygtkだけ でスクリーンショットをとる

何コレ、たったこれだけ(八行)で本当に全画面スクリーンショットアプリが完成!
PyGtk 恐るべし、gnome-screenshot が強力すぎて自分で作ろうとは思わないけど。

つーか画面サイズを調べるのって get_geometry() メソッドを呼ぶだけだったのか。
やはり知識が無いと無駄なコードを書くことを自分で証明した。

とにかくコレでディスプレイサイズがゲットできたので作ってしまえだ。
表示後でないと gtk.Widget.allocation.height が取れないのをどうするか悩む。

ごまかしたらイマイチなコードになっちゃった、けど開発途中なんだからいいや。
後マウスカーソルを消す処理もいれたいけど出したいからこのまんま出してしまえ(ぉい!
具体的なコードは Y901x の common.py の CFullCtrl class を見てくれ。
更新毎に少しずつマトモなコードになる、多分。

ということで Y901x-0.2.3 を公開しました、本サイトからぞうぞ。
listbox 表示状態を記憶せず毎回表示していたのも修正した、今まで何故気がつかない…

だから Linux 用を作ったところで全然金にも人気にもならないなんて解っているよ。
いいじゃないか、作りたいんだから。

diary

Event Structures
か。

GDK イベントの取得とリサイズ
の「イベント構造体」リンク先が消えていたので覚書、英語ページになっちゃったけど。

本当に Web はケタ外れな勢いで変化している、だから
「今の状態で最新及び未確定な未来以外の情報はいらない」
を凄く遠回しで形にしたツイッなんとかが勢力を伸ばしたのは今考えれば当然だったのかな。
古い考えのままなのに人気に便乗した人達のおかげでなるようになったわけだが。

【2ch】ニュー速クオリティ:Windows 8 コンセプトデスクトップ公開 究極のデスクトップを求めていく

唖然としてくれ、Ubuntu でページ内検索してもまったく引っかからない。
本屋さんのパソコン雑誌コーナーであれだけ勢力を伸ばしておいてさえもこの結果。
メインで linux を使っている人なんて実は全然おらんってことだ。
解っていたけど、画面スクロールしていくと悲しくなるばかり。

GoogleOS って名前が出ているけどココに書き込みしているような人が使う可能性は完全にゼロ。
古い古い Windows とチョッピリ操作性が違うだけで拒否反応をする人しか日本人にはいないんだよ。
Mac でさえ興味だけ、Mandriva なんて次回は日本語用ローカライズさえ怪しいかも…

 * 上下矢印キー(ボリューム調節等)でフォーカスが移らないように
 * 何も再生されていない状態の選択ディレクトリを glib.USER_DIRECTORY_VIDEOS に

をついさっき Y901x でやったけどコレだけで更新もアレだなぁ…
公開するかどうかも怪しい Y901w との整合性もあるし、コッチは Aero 全開でいきたいし。
でなければ新しいアプリなんて作る意味すらない、古い OS 用なら古いアプリを使えばいいだけだ。
作る側と使う側のギャップは埋まるどころか開くばかり、個人オンラインソフトが廃れたのも当然か。

どうでもいいが、在日(チョンじゃない)外国人の iPhone 普及率に最近気がついてビビった。
そういえばガラケーというよりケータイサイトって日本語しか無いんだよね、そりゃ当然なのか。
日本独自なケータイ文化が廃れるのも時間の問題か、今は何をやればいいか全然ワカンネ。

Python2.6 format

知らなかったけど Python 2.6 から format メソッドが使えるんだね。
3.0 系だけだと今まで思っていたよ、IronPython 2.6 も同様。

"{0}: {1}+{2}={3}".format("calc", 1, 2, 1+2)

"%s: %d+%d=%d" % ("calc", 1, 2, 1+2)

のように値に対する書式指定がいらない、くらいしかメリットは無いけど。

引数の順番が変更できたり同一の値を参照…なんてやる人少ないだろうし。
少なくとも C# からプログラミングに入った人なら判りやすいのではないかと。
今は「どっちでもいい」なので好きなほうで書けばいいわけだ。
ただ書き方ごときにあーだこーだなら Ru…(以下略

しかし春の陽気のせいかヤル気が出ない…
Y901w はもう現行 Cinema のまんまでいいじゃないかとか…
とはいえ今になってコードを見ると自身で寒いので全部書き直したいし…
なんんてやっていたら全然進まねぇや、そろそろ Windows 用を何か作らないと干されそう。

Default argument

Python という言語は関数のオーバーロードができない。
何って、つまり引数が違うだけで同じ関数名を利用する多重定義のことである。
慣れると関数やメソッド量を少しでも減らそうとよく利用するようになる。

だからといっていくつも別名の関数を用意するのは効率が悪い。
結果似たようなことができるデフォルト引数を利用するようになるわけだ。

ん、そういえば C++ や C# もデフォルト引数って使えたよな。
色々な言語を行ったり来たりしている私は同じように書いたほうがいいのでは?
それにデフォルト引数のほうがコードの記述量が減らせるメリットがある。
コンパイル後の機械語では似たような結果になるのだろうけど…

コードが短くできるのは魅力なので C++ や C# でもデフォルト引数をなるべくやろう。
オーバーロードはよく使うから覚えているけどデフォルト引数は C++ でどう書くの。
一つの cpp 内での書き方なら簡単に見つかる、Python とまったく同じか。

けど別ファイルにするには?
やってみた。

Tool.h

#pragma once
extern int messagebox(HWND hWnd, LPCWSTR msg, LONG button=MB_OK, LONG icon=MB_ICONEXCLAMATION);

Tool.cpp

#include "StdAfx.h"
#include "Tool.h"

#define MSG_TITLE L"確認 - Y901w"

int messagebox(HWND hWnd, LPCWSTR msg, LONG button, LONG icon)
{
	return MessageBox(hWnd, msg, MSG_TITLE, button | icon | MB_SYSTEMMODAL);
}

を用意してメインウインドウで使ってみる。

#include "Tool.h"
//略
messagebox(hWnd, L"ウニコード", MB_OKCANCEL);

extern 宣言で使う場合は extern 宣言のほうにだけデフォルトを書けばいいようだ。
本当は名前空間か class で static にするほうがイイと思うけどコレが一番簡単。
Python のように自作関数は小文字と掟を作っておけば間違えることも無いだろう。

しかし今になって昔のコードを見るとメンバ変数に m_ を付けていないとかで迷う。
自分が書いたコードなのに似たような変数名をローカル変数にしていたら迷ってしかたがない。
だから m_ プリフィクスみたいな書き方を推奨しているのね、そうなることが解っているから。
Python の self 強制って実はありがたいと思った、C++ も this 強制でいいくらいだ。