投稿者「sasakima-nao」のアーカイブ

Clutter Timeline

今回は Clutter で図形を書き、ついでに動かしてみよう。
年末で超忙しいので更新が遅くてごめん。

Clutter: a beginner’s tutorial | TuxRadar Linux

こんな感じらしい。
少しずつ試してみよう。

別のページで見かけたけどウインドウを閉じるのは hide シグナルのほうがいいみたい。
PyGObject で書く時はこんな感じかな。

#!/usr/bin/env python3

import gi, sys
gi.require_version('Clutter', '1.0')

from gi.repository import Clutter

class ClText(Clutter.Stage):
    def __init__(self):
        Clutter.Stage.__init__(self)
        # ClutterRectangle Green
        rectcolor = Clutter.Color.new(0, 255, 0, 255)
        rect = Clutter.Rectangle.new_with_color(rectcolor)
        rect.set_size(100, 50)
        rect.set_position(50, 20)
        self.add_actor(rect)
        # ClutterRectangle Blue
        rectcolor = Clutter.Color.new(0, 0, 255, 127)
        self.rect = Clutter.Rectangle.new_with_color(rectcolor)
        self.rect.set_size(50, 100)
        self.rect.set_position(40, 30)
        self.add_actor(self.rect)
        # Timeline
        self.rotation = 0
        timeline = Clutter.Timeline.new(500)
        timeline.connect("new-frame", self.on_new_frame)
        self.sorce = Clutter.Score.new();
        self.sorce.set_loop(True)
        self.sorce.append(None, timeline)
        self.sorce.start()
        # self
        windowcolor = Clutter.Color.new(255, 0, 0, 255)
        self.set_color(windowcolor)
        self.set_title("Test")
        self.set_user_resizable(True)
        self.set_size(320, 240)
        self.show_all()

    #def do_delete_event(self, event):
    #    Clutter.main_quit()

    def do_hide(self):
        Clutter.main_quit()

    def on_new_frame(self, num, data):
        self.rotation += 0.3
        self.rect.set_rotation(Clutter.RotateAxis.X_AXIS, self.rotation, 0, 0, 0)

Clutter.init(sys.argv)
ClText()
Clutter.main()

clutter_rotate

CLUTTER_Z_AXIS が Clutter.RotateAxis 内の所で迷ったけど上手くいった。
ここで指定した軸を中心に 3D でグルグル回すことができるんだね。

add_actor の順番どおりで重なっていくようだ。
これを利用すれば簡易 3D アニメーションなら簡単に作れそう。
モデリングは、今は解らない。

そうそう、ClutterScore を self にくっつけるのを忘れないようにね。
こうしないとガベージコレクションで破棄されちゃうので。

Clutter (GNOME)

ClutterGst で動画関連をヤル前に。
Clutter 自体の基本をおさらい、つか完全に忘れているわ筆者は。
その前に Clutter とは。

Projects/Clutter – GNOME Wiki!

GNOME プロジェクトの作っている OpenGL ES ツールキット。
Windows の WPF のようなもの、方向性は違うみたいだけど。
iOS,Mac の Metal といい、今のグラフィックはリッチです。

筆者の MacBook Air は中古の 2011 なので El Capitan の恩恵が無い…
持ち運び用途で買ったんだから別にどうだってイイモン!
Windows は一年以上寝ている、自動更新が恐ろしいので起動すらしたくない。

まあそれはどうでもよくて。
WPF みたいなものなので普通にウインドウが作れます。

#!/usr/bin/env python3

import gi, sys
gi.require_version('Clutter', '1.0')

from gi.repository import Clutter

# initialized
Clutter.init(sys.argv)

def on_delete_event(stage, event):
    Clutter.main_quit()

#stage = Clutter.Stage.get_default() # delete 1.10
stage = Clutter.Stage.new()
stage.connect("delete-event", on_delete_event)
stage.set_title("Hello Clutter")
stage.set_user_resizable(True)
stage.show()
Clutter.main()

clutter_window

GtkWindow とは違い[閉じる]ボタンで Window は閉じる。
けど clutter_main_quit() を呼ばないとプロセスが残るので注意。
よく見ると GtkWindow とは影が違うことに気が付く。
X で描写しているのではないということがこれで判ります。

ウインドウだけではしょうがないので文字列を表示します。
ついでに書き換えできるように。

#!/usr/bin/env python3

import gi, sys
gi.require_version('Clutter', '1.0')

from gi.repository import Clutter

class ClText(Clutter.Stage):
    def __init__(self):
        Clutter.Stage.__init__(self)
        # ClutterText
        edit = Clutter.Text.new()
        edit.set_text("Hello ClutterText")
        edit.set_editable(True)
        self.add_child(edit)
        self.set_key_focus(edit)
        # self
        color = Clutter.Color.new(255, 0, 0, 255)
        self.set_color(color)
        self.set_title("Test")
        self.set_user_resizable(True)
        self.set_size(320, 240)
        self.show_all()

    def do_delete_event(self, event):
        Clutter.main_quit()

Clutter.init(sys.argv)
ClText()
Clutter.main()

clutter_text

GtkWidget の GtkLabel 等とは違い背景透過のようです。
書き換えできるようにしてみたけど GtkEntry のようにはなりません。
クリックでフォーカスが持てないし日本語入力もできない。
まあそういう使い方ではないということでしょう。

Clutter も PyGObject では do_* の接頭子でオーバーライドできるようです。
なんか直感だけでここまで解ったぞと。

WPF と違い部品 Widget は無いけど GtkWindow に乗せられるので問題ない。
いや、スマホの普及を見るとそういう考えがもう古いのかな。

しかし devhelp 3.18 は Ctrl+G で次を検索しないのか?
Ctrl+クリックで別タブもできない、凄く使い辛いんですけど。

ClutterGst 3.0 and GtkHeaderBar

タイトルどおりのモノを作っているので覚書。
実は GtkHeaderBar って Widget を置けるはずがない所に描写している。
なのでこんなことがおこります。

いきなり少し違うけど PyGObject のオーバーライドバグ。

def do_size_allocate(self, allocation):
    pass

ovverride_error

BUG って出るんだね、親切になったもんだ。
connect メソッドなら普通にコネクトできる。

ただ本体の大きさで ClutterActor のサイズを合わせると

class ClPlayer(Gtk.Window):
    def __init__(self):
        Gtk.Window.__init__(self)
        # etc...
        self.connect("size-allocate", self.on_size_allocate)

    def on_size_allocate(self, widget, allocation):
        self.actor.set_width(allocation.width)
        self.actor.set_height(allocation.height)

allocate_size

外枠とタイトルバーの大きさの二倍が加算されてしまうようです。
Box を噛ませてその Box の大きさに合わせてなら問題ないようだ。
GtkHeaderBar さえ使わなければコレでもいいんですけどね。

それと draw シグナルは絶対に処理してはいけない。

def do_draw(self, cr):
    pass

gtkheaderbar_draw

GtkHeaderBar が真っ黒なレゴになってしまいます。
描写処理は Clutter で行うようにする。

そんなこんなで色々困ったことが起こったけどなんとかなった。

#!/usr/bin/env python3

import sys, gi
gi.require_version("Gtk", "3.0")
gi.require_version("ClutterGst", "3.0")
gi.require_version("GtkClutter", "1.0")

from gi.repository import Gtk, Gdk, ClutterGst, GtkClutter, Clutter

# Own Change
URI = "file:///home/sasakima-nao/movie/kawasaki_h2r.mp4"

class ClPlayer(Gtk.Window):

    def __init__(self):
        Gtk.Window.__init__(self)
        # Dark Theme
        settings = Gtk.Settings.get_default()
        settings.props.gtk_application_prefer_dark_theme = True
        # GtkHeaderBar
        self.hbar = Gtk.HeaderBar()
        self.hbar.set_show_close_button(True)
        self.set_titlebar(self.hbar)
        # Full Screen Button
        fullbutton = Gtk.Button.new()
        image_full = Gtk.Image.new_from_icon_name("view-fullscreen-symbolic", Gtk.IconSize.MENU)
        fullbutton.set_image(image_full)
        self.hbar.pack_end(fullbutton)
        # new
        self.actor = Clutter.Actor.new()
        self.content = ClutterGst.Aspectratio.new()
        self.player = ClutterGst.Playback.new()
        # set
        self.content.set_player(self.player)
        self.actor.set_content(self.content)
        # add
        embed = GtkClutter.Embed()
        stage = embed.get_stage()
        stage.add_child(self.actor)
        # box
        vbox = Gtk.Box.new(Gtk.Orientation.VERTICAL, 0)
        vbox.pack_start(embed, True, True, 0)
        vbox.connect("size-allocate", self.on_vbox_size_allocate)
        self.add(vbox)
        # play
        self.player.set_uri(URI)
        self.player.set_playing(True)
        # show
        self.show_all()

    def do_delete_event(self, event):
        Gtk.main_quit()

    def on_vbox_size_allocate(self, vbox, allocation):
        """
            Fit a Clutter.Actor
        """
        self.actor.set_width(allocation.width)
        self.actor.set_height(allocation.height)

GtkClutter.init(sys.argv)
ClutterGst.init(sys.argv)

win = ClPlayer()
Gtk.main()

gst_headerbar

GtkHeaderBar とダークテーマが実装できた。
次はシークバーだな、また色々出るんだろうな…
だから楽しいんだYO!

ClutterGst 3.0 with Python

ClutterGst PyGI | PaePoi

以前こんなのを書いたけど

Clutter Gst 3.0.14 Reference Manual: Clutter Gst 3.0.14 Reference Manual

ClutterGst.VideoTexture なんて 3.0 の現在ではもう無い。
今はどうすれば ClutterGst を扱えるのかな?

そういえば Sushi は Gjs だったな。
一応、Sushi は Nautilus にて Space Key でプレビューするアプリね。
Fedora には最初から入っているよ。
だったらコイツのコードを参考にすればいいじゃないか。

sushi_gst

って VideoTexture のまんまや!
Nautilus で動画をプレビューすると緑色でやはり表示できない。

[sushi] viewer: gst: port to ClutterGst 3.0

見つけた、十月にはコミットされているはずなんだけどなぁ。
自力で置き換えして試してみる、Gjs は面倒だから Python で。

#!/usr/bin/env python3

import sys, gi
gi.require_version("Gtk", "3.0")
gi.require_version("ClutterGst", "3.0")
gi.require_version("GtkClutter", "1.0")

from gi.repository import Gtk, Gdk, ClutterGst, GtkClutter, Clutter

class ClPlayer(Gtk.Window):

    def __init__(self):
        Gtk.Window.__init__(self)
        # new
        self.actor = Clutter.Actor.new()
        self.content = ClutterGst.Aspectratio.new()
        self.player = ClutterGst.Playback.new()
        # set
        self.content.set_player(self.player)
        self.actor.set_content(self.content)
        self.actor.show()
        # size
        self.actor.set_width(320)
        self.actor.set_height(180)
        # add
        self.embed = GtkClutter.Embed()
        self.stage = self.embed.get_stage()
        self.stage.add_child(self.actor)
        self.add(self.embed)
        # play
        self.player.set_uri("file:///home/sasakima-nao/movie/kawasaki_h2r.mp4")
        self.player.set_playing(True)
        # show
        self.resize(320, 180)
        self.show_all()


    def do_delete_event(self, event):
        Gtk.main_quit()

#Clutter.init(sys.argv) # Error
GtkClutter.init(sys.argv)
ClutterGst.init(sys.argv)

win = ClPlayer()
Gtk.main()

cluttergst3

思っていたより簡単だった。
よしコレで我が Y901x の GtkHeaderBar 化に取り掛かりできそうだ。
いやまあ、いいかげんに自分で気になってきたので。

実は今まで Ubuntu 環境での Clutter がよく解らないので避けていた。
GNOME プロジェクトの成果物依存から脱却したいココは絶対に導入しないだろうし。

Ubuntu Sushi その1 – Nautilusでプレビューを行うアプリの紹介・Sushiの使い方 – kledgeb

でも Sushi を入れるだけで依存関係から必要な環境がそろうようだ。
だったら Clutter も問題ないか、多分まだ 3.0 じゃない気がするけど。

eog and Gedit 3.18 Plugin

うーん困った、って何が?

Eye of GNOME って見た目のショボさとは裏腹にかなり優秀である。
SVG 画像を綺麗に拡大できるだけでなく実はディレクトリ監視も行っている。

eog で画像を表示した状態で同一ディレクトリのファイルを別アプリからリネーム。
すると eog のリストへ即座に繁栄され矢印キーやスライドショーにも適用される。
ただ即時繁栄のためサムネイル画像がまだ作成されていない状態になってしまう。
サムネイル表示(F9)を出していないと気にならないけど。

なので今まで自作リネームプラグインはサムネイル画像を自前で入れ替えしていた。
それが 3.18 で上手く動作しない、仕様変更されたようだ。

どうも remove_image が無効になっているだけっぽいけどよく解らない。
とりあえず即元にもどせるようコメントアウトでしばらく様子見。

eog318_remove_image

Gedit はやはり gi.require_version 追記だけだった。
しかし eog もそうだけど Peas のバージョン指定もいるようだ。
Peas はソースで使っていないし 1.0 しかないのに、将来の伏線かな?

ついでに、筆者は Gedit Plugin を 4 つ公開しているのですが。
一つに書いただけで警告は出なくなった、おいおい…
まあ全部に書いたけどね。

gedit318_peas

というわけでプラグイン 3.18 版を公開。
最後に。

kuroe

いえーい、無課金なのにクロエ・ルメールを最終進化できるぞい!
貯めた炭酸を全部使った甲斐があった(ウチ姫はどうした!