Egui Spacing from corners and anchor buttons

Hello there! I'm new in Rust and in egui and I have difficulties with that.

I can't understand how I can get spacing from corners at buttons. There was first problem.

The second problem is that I want to anchor one button to the left edge, the second to the right edge, and also in the center should be the label as shown on the screenshot

The third one is that the top bar isn't width justify or how I can explain it. Not all width is being used

  1. I have:

  2. Goal:

1 Like

For 1 problem, I tried to use:

    ui.style_mut().spacing.indent = 16.;
    ui.style_mut().spacing.item_spacing = vec2(16., 16.0);

In

ui.horizontal()

Okay, I figured out what to do in first problem

You should use

        .panel()
        .frame()
        .inner_margin(<Margin here, for example Margin::symmetric(16, 10)>)

this a layout problem, not a styling problem. you code mainly affect the styles, it has small effect on the layout flow.

unfortunately, doing layout with immediate mode GUI is not as flexible or convenient as we hoped, and complex layouts often requires some insights on how the layouting algorithm works. even so, some layout is inherently difficult or impossible to calculate with a single pass algorithm.

fortunately, for this particular case, it's not that difficult, but it does require some layout tricks. to make two buttons spread apart, you can wrap the second button in a right-to-left layout context, and finally wrap the label in the middle with centered_and_justified, something like:

ui.horizontal(|ui| {
	if ui.button("left").clicked() {
		eprintln!("left button clicked");
	}
	ui.with_layout(Layout::right_to_left(Align::Center), |ui| {
		if ui.button("right").clicked() {
			eprintln!("right button clicked");
		}
		ui.centered_and_justified(|ui| {
			ui.label("I'm in the center");
		})
	});
});

as for the top bar, it's not so simple though, I don't know if there's better way to achieve the expected result, other than to manually calculate and allocate the layout,
note this can be tricky when the size of the widgets varies depending on the text length.

here's an sketch how to get something similar to your drawing:

ui.horizontal(|ui| {
	// the image to the left end
	ui.image(logo);
	// swith to right-to-left layout
	ui.with_layout(Layout::right_to_left(Align::Center), |ui| {
		// the date/time to the right end
		ui.label(format_date_time());
		// manually allocate remaining space to individual widigets
		let remaining = ui.available_size();
		let size1 = Vec2::new(remaining.x * 0.6, remaining.y);
		let size2 = Vec2::new(remaining.x * 0.4, remaining.y);
		// add the middle widgets
		// note: we are still inside a right-to-left layout
		ui.add_sized(size1, Label::new("I'm on the right"));
		ui.add_sized(size2, Label::new("I'm on the left"));
	});
});
1 Like

Thx for detailed help. Helped me a lot to understand how layouts work

1 Like