Search code examples
rustslint

How to forcefully set window size on window creation


I have the following full Rust code:

use slint::{ComponentHandle, PhysicalSize, Weak};
use std::fs;
extern crate slint;

fn main() {
    let app: App = App::new().unwrap(); 
    let weak: Weak<App> = app.as_weak();
    let size: PhysicalSize = PhysicalSize::new(1920, 1080);
    
    println!("Set size");
    weak.upgrade().unwrap().window().set_size(size);
    //println!("Set fullscreen");
    //weak.upgrade().unwrap().window().set_fullscreen(true);

    let upload_weak: Weak<App> = weak.clone();
    app.on_upload_file_clicked(move || {
        let _app: App = upload_weak.upgrade().unwrap();
        println!("Doing stuff :P");
    });

    let update_weak: Weak<App> = weak.clone();
    set_app_vars(data_check(), update_weak);

    app.run().unwrap();
}

fn data_check() -> bool {
    let paths_it = fs::read_dir("storage/").unwrap();
    let paths_cnt = fs::read_dir("storage/").unwrap();
    let data_found: bool;

    if paths_cnt.count() > 0 {
        for path in paths_it {
            println!("Type: {:?}", path.unwrap().file_type());
        }
        data_found = true;
    } else {
        println!("No storage files found.");
        data_found = false;
    }
    data_found
}

fn set_app_vars(is_data: bool, weak: Weak<App>) {
    let app: App = weak.upgrade().unwrap();
    app.set_data_exists(is_data);
}

slint::slint! {
    import { Button, VerticalBox, HorizontalBox } from "std-widgets.slint";
    export component App inherits Window {
        in property <bool> data_exists;
        callback upload_file_clicked <=> upload_btn.clicked;

        VerticalBox {
            Text {
                text: data_exists ? "Found existing data, loading..." : "Please upload an MBOX or JSON file."; }
            HorizontalBox {
                upload_btn := Button { text: "Upload"; }
            }
        }
    }
}

I want the window that is launched by app.run().unwrap() in main() to launch at a specific resolution. As it stands, I cant set the size of the app window unless I move that logic into the "on click" portion of the code, meaning the user would have to click the "upload" button for the resolution to update – not ideal.

So far I have tried moving the "set size" method to after the app.run().unwrap() in main(), but it appears that it is blocking, so nothing happens until after the window is already closed.

I have also put it before the app.run().unwrap(), but since the window does not exist, it cannot set the size. At least this is what I assume, since calling weak.unwrap().window().size() at this point returns a PhysicalSize value of { 0, 0 }.


Solution

  • Personally I would simply define the startup size of the window like so:

    slint::slint! {
        import { Button, VerticalBox, HorizontalBox } from "std-widgets.slint";
        export component App inherits Window {
            width: 1920px;
            height: 1080px;
    
            in property <bool> data_exists;
            callback upload_file_clicked <=> upload_btn.clicked;
    
            VerticalBox {
                Text {
                    text: data_exists ? "Found existing data, loading..." : "Please upload an MBOX or JSON file."; }
                HorizontalBox {
                    upload_btn := Button { text: "Upload"; }
                }
            }
        }
    }
    

    If you need to set it from Rust code, you can create an in-out property like so:

    slint::slint! {
        import { Button, VerticalBox, HorizontalBox } from "std-widgets.slint";
        export component App inherits Window {
            in-out property <int> window_width;
            in-out property <int> window_height;
    
            width: window_width * 1px;
            height: window_height * 1px;
    
            in property <bool> data_exists;
            callback upload_file_clicked <=> upload_btn.clicked;
    
            VerticalBox {
                Text {
                    text: data_exists ? "Found existing data, loading..." : "Please upload an MBOX or JSON file."; }
                HorizontalBox {
                    upload_btn := Button { text: "Upload"; }
                }
            }
        }
    }
    

    that can be used from your Rust code like this:

    
    let app: App = App::new().unwrap();
    let weak: Weak<App> = app.as_weak();
    let size: PhysicalSize = PhysicalSize::new(1920, 1080);
    
    println!(
        "Original size: ({}, {})",
        app.get_window_width(),
        app.get_window_height()
    );
    
    println!("Set size");
    app.set_window_height(size.height as i32);
    app.set_window_width(size.width as i32);
    
    ...
    

    Btw.: I have no idea why the SLint Language below does not work as expected (it kind of feels like a bug to me):

    slint::slint! {
        import { Button, VerticalBox, HorizontalBox } from "std-widgets.slint";
        export component App inherits Window {
            in-out property window_width <=> self.width;
            in-out property window_height <=> self.height;
    
            in property <bool> data_exists;
            callback upload_file_clicked <=> upload_btn.clicked;
    
            VerticalBox {
                Text {
                    text: data_exists ? "Found existing data, loading..." : "Please upload an MBOX or JSON file."; }
                HorizontalBox {
                    upload_btn := Button { text: "Upload"; }
                }
            }
        }
    }