There's no need to write a custom container; to do what you described, you can simply use Grid
.
Using Grid
As you probably know, the Grid
container is made up of rows and columns. A single widget can take up multiple rows and columns. Thus, if you want one widget to span 2/3 of the window and the other to span 1/3 of it, you can use three columns of a Grid
, and make the first widget cover two columns while the second widget covers just one.
In order to do this, you use the width
and height
arguments of Grid.attach()
. For example, this widget will span two columns:
grid.attach(
&widget,
0, // X position (column)
0, // Y position (row)
2, // width (in columns)
1 // height (in rows)
);
Now in order for the column proportions to be correct, you also need to set the columns homogeneous:
grid.set_column_homogeneous(true);
The same principles can be applied to rows too.
Example
All that being said, here is a simple working example with a Button
and an Entry
. The Button
(on the left) takes up 2/3 of the width of the window, while the Entry
(on the right) takes up only 1/3.
use gtk::prelude::*;
use gtk;
/// Create the window and all its widgets
fn create_window(app: >k::Application) {
// The main window
let window = gtk::ApplicationWindow::builder()
.application(app)
.title("Example")
.build();
window.set_position(gtk::WindowPosition::Center);
// A Grid
let grid = gtk::Grid::new();
grid.set_column_homogeneous(true); // Makes sure the columns are proportional
window.add(&grid);
// A button that's 2 columns wide
let button = gtk::Button::with_label("2/3 of the window");
grid.attach(&button, 0, 0, 2, 1);
// An entry that's only 1 column wide
let entry = gtk::Entry::builder()
.placeholder_text("1/3 of the window")
.build();
grid.attach(&entry, 2, 0, 1, 1);
// Show all the widgets after creation
window.show_all();
}
fn main() {
// Create the application
let app = gtk::Application::builder()
.application_id("rust.example.app")
.build();
app.connect_activate(create_window);
app.run();
}