gtk-rs Set maximum size of window

370 Views Asked by At

Is it possible to set the maximum size for a window in gtk-rs? When reading the documentation I can find lots of options to set the minimum window size and the default window size however I can not find any options to set the maximum window size.

It does appear that there are some options for window size management however I am having some trouble identifying how they are supposed to be used. When looking at the measure trait for widgets (I thought it might be possible to set a max size for all widgets) there is a link to GtkWidget’s geometry management section however it 404's

Setting the window as fullscreen does stop it expanding across multiple screens but it also takes away the menu bar causing me to have to force close the app to get it off the screen. Maximize is similar to full screen but keeps the menu bar. When using either of these options the content does not wrap to the window size. It just goes off the screen with no scroll bar.

I have a code example below that demonstrates the problem by using a very long label to have the window break across multiple screens or just to an inappropriate size if your screen is big enough to hold the label.

use gtk::prelude::*;
use gtk::{Application, ApplicationWindow, Button, Orientation};
use std::sync::{Arc, Mutex};
const APP_ID: &str = "org.gtk_rs.HelloWorld3";

fn main() {
    let app = Application::builder().application_id(APP_ID).build();
    app.connect_activate(build_ui);
    app.run();
}

fn build_ui(app: &Application) {
    let button = Button::builder()
        .label("Press me!")
        .margin_top(12)
        .margin_bottom(12)
        .margin_start(12)
        .margin_end(12)
        .build();

    let label = gtk::Label::new(Some("this is a very long string that will change the size of the window to a size that is impossible to use..................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................."));

    let label_box = gtk::Box::builder()
        .orientation(Orientation::Vertical)
        .margin_top(12)
        .margin_bottom(12)
        .build();
    label_box.append(&label);

    label_box.set_visible(false);

    let button_box = gtk::Box::builder()
        .orientation(Orientation::Vertical)
        .margin_top(12)
        .margin_bottom(12)
        .build();
    button_box.append(&button);
    button_box.append(&label_box);

    let window = ApplicationWindow::builder()
        .application(app)
        .title("My GTK App")
        .child(&button_box)
        .default_width(360)
        .default_height(720)
        
        .build();

    window.present();
    //window.fullscreen(); // uncomment this to see the fullscreen option.

    button.connect_clicked(move |button| {
        if label_box.get_visible() == false {
            label_box.set_visible(true);
        }
        else {
            // this makes the label invisible but does not revert screen size.
            label_box.set_visible(false);
        }
    });
}

How do I limit the size a gtk-rs window can grow to or to wrap the content to the window size? Is it possible to limit the size of widgets if not the window itself?

EDIT: I have used a label to illustrate the problem here as it is a simple way to demonstrate the problem. There is a method to set the max width of a label but it's only for labels. I would like to limit the size of all widgets.

2

There are 2 best solutions below

0
On

I would go with the advice of 김평강 and use a ScrolledWindow.

Here is your code extended with a ScrolledWindow. The child can be any Widget as desired:

use gtk::prelude::*;
use gtk::{Application, ApplicationWindow, Button, Orientation};

const APP_ID: &str = "org.gtk_rs.HelloWorld3";

fn main() {
    let app = Application::builder().application_id(APP_ID).build();
    app.connect_activate(build_ui);
    app.run();
}

fn build_ui(app: &Application) {
    let button = Button::builder()
        .label("Press me!")
        .margin_top(12)
        .margin_bottom(12)
        .margin_start(12)
        .margin_end(12)
        .build();

    let label = gtk::Label::new(Some("this is a very long string that will change the size of the window to a size that is impossible to use..................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................."));

    let label_box = gtk::Box::builder()
        .orientation(Orientation::Vertical)
        .margin_top(12)
        .margin_bottom(12)
        .build();
    label_box.append(&label);

    label_box.set_visible(false);

    let button_box = gtk::Box::builder()
        .orientation(Orientation::Vertical)
        .margin_top(12)
        .margin_bottom(12)
        .build();
    button_box.append(&button);

    let scrollable_container = gtk::ScrolledWindow::builder()
        .child(&label_box)
        .build();
    button_box.append(&scrollable_container);

    let window = ApplicationWindow::builder()
        .application(app)
        .title("My GTK App")
        .child(&button_box)
        .default_width(360)
        .default_height(720)
        
        .build();

    window.present();
    //window.fullscreen(); // uncomment this to see the fullscreen option.

    button.connect_clicked(move |_button| {
        if label_box.get_visible() == false {
            label_box.set_visible(true);
        }
        else {
            // this makes the label invisible but does not revert screen size.
            label_box.set_visible(false);
        }
    });
}
2
On

Use gtk::ScrolledWindow like so:

use gtk::prelude::*;
use gtk::{Application, ApplicationWindow, Button, Orientation};

const APP_ID: &str = "org.gtk_rs.HelloWorld3";

fn main() {
    let app = Application::builder().application_id(APP_ID).build();
    app.connect_activate(build_ui);
    app.run();
}

fn build_ui(app: &Application) {
    let button = Button::builder()
        .label("Press me!")
        .margin_top(12)
        .margin_bottom(12)
        .margin_start(12)
        .margin_end(12)
        .build();

    let label = gtk::Label::new(Some("this is a very long string that will change the size of the window to a size that is impossible to use..................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................."));

    // create scrolled window and add label
    let adjustment: Option<&gtk::Adjustment> = None;
    let scrolled_window = gtk::ScrolledWindow::new(adjustment, adjustment);
    scrolled_window.set_policy(gtk::PolicyType::Automatic, gtk::PolicyType::Never);
    scrolled_window.add(&label);

    let label_box = gtk::Box::builder()
        .orientation(Orientation::Vertical)
        .margin_top(12)
        .margin_bottom(12)
        .build();
    label_box.pack_end(&scrolled_window, true, true, 0);

    label_box.set_visible(false);

    let button_box = gtk::Box::builder()
        .orientation(Orientation::Vertical)
        .margin_top(12)
        .margin_bottom(12)
        .build();
    button_box.pack_end(&button, true, true, 0);
    button_box.pack_end(&label_box, true, true, 0);

    let window = ApplicationWindow::builder()
        .application(app)
        .title("My GTK App")
        .child(&button_box)
        .default_width(360)
        .default_height(720)
        .build();

    window.present();
    //window.fullscreen(); // uncomment this to see the fullscreen option.
    window.show_all();
    button.connect_clicked(move |_button| {
        if label_box.get_visible() == false {
            label_box.set_visible(true);
        } else {
            // this makes the label invisible but does not revert screen size.
            label_box.set_visible(false);
        }
    });
}