1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

SlintAdvent Calendar 2024

Day 12

Slint のウィンドウサイズの変更を Rust 側で取得する

Last updated at Posted at 2024-12-11

はじめに

この記事は Slint Advent Calendar 2024 12日目の記事です。

昨日は @gony さんによる Slintでモーダルダイアログを実現する という記事でした。

Slint ではまだモーダルはサポートされていないようですが、きっとそのうちされるでしょう。

Windows 限定ではありますが、自前で頑張ってる人もいました。


今日は.slint で生成したウィンドウのサイズの変更を Rust 側で検知する方法です。

ウィンドウのサイズをプロパティにする

まずは SlintPad で以下のコードを試してみましょう。

// サイズを保持する構造体を定義する
export struct Size {
    width: length,
    height: length,
}

export component AppWindow inherits Window {
    // デフォルトの大きさを指定
    preferred-width: 1280px;
    preferred-height: 720px;

    // ウィンドウのサイズを Size 構造体型のプロパティで保持する
    out property<Size> window-size: { width: root.width, height: root.height };

    label := Text {
        // ウィンドウの横幅と高さを表示する
        text: "\{root.window-size.width / 1px} x \{root.window-size.height / 1px}";
    }
}

サイズ用の構造体 Size を定義し、window-size というプロパティとその値の関係を宣言しています。

ここではその値を Text に表示しています。

String 型は文字列中に \{...}と書くと、その中を評価して文字に置換してくれます。

なお、length 型はそのまま指定すると、

Error: Cannot convert length to string. Devide by 1px to convert to a plain number

というエラーになるため、指示どおり 1px で割ることで数値に変換しています。

ウィンドウのプロパティが変更されたらなにかをする

つぎに、以下のコードを SlintPad で試してみます。

// サイズを保持する構造体を定義する
export struct Size {
    width: length,
    height: length,
}

export component AppWindow inherits Window {
    // デフォルトの大きさを指定
    preferred-width: 1280px;
    preferred-height: 720px;

    // ウィンドウのサイズを Size 構造体型のプロパティで保持する
    out property<Size> window-size: { width: root.width, height: root.height };

    // 上記のウィンドウのサイズに変更があったら、ラベルにウィンドウの横幅と高さを表示する
    changed window-size => { label.text = "\{root.window-size.width / 1px} x \{root.window-size.height / 1px}"; }

    label := Text {}
}

動作は以前と同じですが、プロパティバインディングではなく、Slint 1.8.0 で導入されたばかりの プロパティの変更ハンドラ で表示を更新しています。

コールバックで通知する

.slint 側でコールバックを定義し、ウィンドウサイズが変更されたら呼ぶようにし、Rust 側でそれを受けて処理をするようにします。

SlintPad で以下のコードを試します。

// サイズを保持する構造体を定義する
export struct Size {
    width: length,
    height: length,
}

export component AppWindow inherits Window {
    // デフォルトの大きさを指定
    preferred-width: 1280px;
    preferred-height: 720px;

    // ウィンドウのサイズを Size 構造体型のプロパティで保持する
    out property<Size> window-size: { width: root.width, height: root.height };

    // ウィンドウのサイズが変更された際のコールバック
    callback window-size-changed;

    // 上記のウィンドウのサイズに変更があったら、コールバックを呼ぶ
    changed window-size => { window-size-changed(); }
}

今回は、.slint 上には表示されません。 main.rs 側で変更を検知し、処理を行います。

use std::error::Error;

slint::include_modules!();

fn main() -> Result<(), Box<dyn Error>> {
    let ui = AppWindow::new()?;

    // ウィンドウの初期サイズをプロパティから取得する
    let size = ui.get_window_size();
    println!("Initial Window Size: {}x{}", size.width, size.height);

    let ui_handle = ui.as_weak().unwrap();
    // ウィンドウサイズが変更されたら処理を行う
    ui.on_window_size_changed(move || {
        let size = ui_handle.get_window_size();
        // 標準出力に出す
        println!("Window Size Changed: {}x{}", size.width, size.height);
    });

    ui.run()?;

    Ok(())
}

ソースコードの一式を以下で公開したので、手元で試したい人は参考にしてください。

おわりに

今回は、.slint で作成したウィンドウのサイズとその変更を、バックエンドの Rust 側で取得や検知する方法を調査しました。

明日は @hermit4 さんがによる Slint言語入門(4) 構文について(続2) です。お楽しみに!

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?