Clutter Box and Scroll

Clutter をチマチマやっているけど絶対値配置はやはり古い!
やはり BoxLayout で配置したい、スクロール機能も欲しい。

色々試して驚いた。
なんと Clutter はスクロールバーに相当するものが無い!

どうしても使いたいなら自分で作れってことでしょうか。
いや違う、そもそも Button Widget 相当すら無いではないか。
スマートフォンではいらないよね、そういうこと。

古臭い考え方をバッサリ捨てないと今の Mac と GNOME は使えない。
つか昔風に戻るなんてありえない、パソコン離れは加速する一方だし。

もしかしてスマートフォンのようなスクロールを想定しているのかも。
だったらやったろうジャン!

#!/usr/bin/gjs

const Clutter = imports.gi.Clutter;
const Lang = imports.lang;

const ListTest = new Lang.Class({
    Name: 'ListTest',
    Extends: Clutter.Stage,

    _init: function() {
        this.parent();
        let layout = new Clutter.BoxLayout({
            orientation: Clutter.Orientation.VERTICAL,
            spacing: 2
        });
        // ScrollActor
        this.scroll = new Clutter.ScrollActor({
            layout_manager: layout,
            scroll_mode: Clutter.ScrollMode.VERTICALLY,
            x_expand: true
        });
        // append
        for (let i=0; i<100; i++) {
            let m = new Clutter.Text({
                text: "TextLine: " + i,
                x_expand: true
            });
            m.set_background_color(Clutter.Color.new(255, 0, 0, 125));
            this.scroll.add_child(m);
        }
        // Scroll Action
        this.x_point = 0;
        this.y_point = 0;
        this.x_diff = 0;
        this.y_diff = 0;
        let gesture = new Clutter.GestureAction();
        gesture.connect("gesture-begin", Lang.bind(this, function(action, actor) {
            this.x_point = action.get_press_coords(0)[0] + this.x_diff;
            this.y_point = action.get_press_coords(0)[1] + this.y_diff;
            return true;
        }));
        gesture.connect("gesture-progress", Lang.bind(this, function(action, actor) {
            let x = action.get_motion_coords(0)[0];
            let y = action.get_motion_coords(0)[1];
            this.x_diff = this.x_point - x;
            this.y_diff = this.y_point - y
            let point = new Clutter.Point({
                x: this.x_diff,
                y: this.y_diff
            });
            this.scroll.scroll_to_point(point);
            return true;
        }));
        this.scroll.add_action(gesture);
        this.scroll.set_reactive(true);
        // this
        this.add_child(this.scroll);
        this.set_layout_manager(new Clutter.BoxLayout()); // Child Fill
        this.connect("hide", Clutter.main_quit);
        this.show_all();
    }
});

Clutter.init(null);
new ListTest();
Clutter.main();

scroll_actor

ClutterBoxLayout を使うことで GtkBox 相当のようだ。
これで fill, expand を利用したレイアウトができる。
しかし ClutterActor に割り当てなのか、GTK+ と随分違うなと。

子 Actor を親サイズに広げたい時は Child Fill の部分のように。
これだけで GtkWindow を使うのとと同じ感覚になる。

スクロールは上記で上手くいった。
スマートフォンみたいにマウスで掴んで動かした分だけスクロール。
やろうと思えば iPhone のような慣性やポヨンを入れることもできる。
でもあの動きは特許だったような…

このスクロールをパソコンで使うかというと疑問もあるけれど。
コマンドが優秀な Linux もタブレットの時代が、ってワカンネーけど。
GNOME プロジェクトはガッツリ備えているということでしょう。