プログラミング気分ではないし Mac でも。
たまにしか使わないとキーボードショートカットを忘れる…
ええいソレなら
Mac OS と GNOME キーボード操作対応表 – L’Isola di Niente
ということでこんなページを作った。
多分もう仕事以外で Windows は使わないからページ整理のついでだが。
しかしこうしてみると本当に同じような進化をしているよね。
今後キーボードを使う OS はこんな感じに収束されるのだろう。
プログラミング気分ではないし Mac でも。
たまにしか使わないとキーボードショートカットを忘れる…
ええいソレなら
Mac OS と GNOME キーボード操作対応表 – L’Isola di Niente
ということでこんなページを作った。
多分もう仕事以外で Windows は使わないからページ整理のついでだが。
しかしこうしてみると本当に同じような進化をしているよね。
今後キーボードを使う OS はこんな感じに収束されるのだろう。
今回は 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_Z_AXIS が Clutter.RotateAxis 内の所で迷ったけど上手くいった。
ここで指定した軸を中心に 3D でグルグル回すことができるんだね。
add_actor の順番どおりで重なっていくようだ。
これを利用すれば簡易 3D アニメーションなら簡単に作れそう。
モデリングは、今は解らない。
そうそう、ClutterScore を self にくっつけるのを忘れないようにね。
こうしないとガベージコレクションで破棄されちゃうので。
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()
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()
GtkWidget の GtkLabel 等とは違い背景透過のようです。
書き換えできるようにしてみたけど GtkEntry のようにはなりません。
クリックでフォーカスが持てないし日本語入力もできない。
まあそういう使い方ではないということでしょう。
Clutter も PyGObject では do_* の接頭子でオーバーライドできるようです。
なんか直感だけでここまで解ったぞと。
WPF と違い部品 Widget は無いけど GtkWindow に乗せられるので問題ない。
いや、スマホの普及を見るとそういう考えがもう古いのかな。
しかし devhelp 3.18 は Ctrl+G で次を検索しないのか?
Ctrl+クリックで別タブもできない、凄く使い辛いんですけど。
タイトルどおりのモノを作っているので覚書。
実は GtkHeaderBar って Widget を置けるはずがない所に描写している。
なのでこんなことがおこります。
いきなり少し違うけど PyGObject のオーバーライドバグ。
def do_size_allocate(self, allocation):
pass
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)
外枠とタイトルバーの大きさの二倍が加算されてしまうようです。
Box を噛ませてその Box の大きさに合わせてなら問題ないようだ。
GtkHeaderBar さえ使わなければコレでもいいんですけどね。
それと draw シグナルは絶対に処理してはいけない。
def do_draw(self, cr):
pass
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()
GtkHeaderBar とダークテーマが実装できた。
次はシークバーだな、また色々出るんだろうな…
だから楽しいんだYO!