0Pricing
Learn Rust Coding · Lesson

Widgets and Layout

Build buttons, inputs, and panels.

Widgets and Layout is a free Learn Rust Coding lesson on CoddyKit — lesson 2 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the Learn Rust Coding learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.

The Widget Palette

egui ships a rich set of built-in widgets: labels, headings, buttons, checkboxes, radio buttons, sliders, drag values, text edits, combo boxes, and more.

Each is a method on Ui and returns a Response. You compose UIs by calling them in sequence rather than instantiating classes.

ui.heading("Settings");
ui.checkbox(&mut self.dark, "Dark mode");
ui.add(egui::Slider::new(&mut self.volume, 0.0..=1.0).text("Volume"));
ui.text_edit_singleline(&mut self.name);

ui.add and the Widget Trait

Convenience methods like ui.button wrap richer widget structs. For configurable widgets you build the struct and pass it to ui.add.

Anything implementing the Widget trait works with ui.add, including your own custom widgets. This is the extensible core of egui's API.

let slider = egui::Slider::new(&mut self.zoom, 0.5..=4.0)
    .logarithmic(true)
    .suffix("x");
let resp = ui.add(slider);
if resp.changed() { self.rerender(); }

Vertical and Horizontal Layout

By default a Ui lays widgets out top-to-bottom. Call ui.horizontal(|ui| ...) to place them left-to-right within a row.

These layout closures nest freely, letting you build rows of columns and columns of rows from plain Rust control flow.

ui.horizontal(|ui| {
    ui.label("Name:");
    ui.text_edit_singleline(&mut self.name);
});
ui.vertical(|ui| {
    ui.button("One");
    ui.button("Two");
});

Columns

For evenly-spaced multi-column layouts, ui.columns(n, |cols| ...) gives you a slice of Ui values, one per column.

Each column gets equal width and you add widgets into cols[i]. This is handy for side-by-side panels or forms.

ui.columns(2, |cols| {
    cols[0].label("Left column");
    cols[0].button("A");
    cols[1].label("Right column");
    cols[1].button("B");
});

Panels

Top-level structure comes from panels: TopBottomPanel for menu bars and status bars, SidePanel for navigation, and CentralPanel for the main content.

Add side and top panels first; the CentralPanel fills whatever space remains. Order matters because each panel claims its edge.

egui::TopBottomPanel::top("bar").show(ctx, |ui| {
    ui.label("Menu");
});
egui::SidePanel::left("nav").show(ctx, |ui| {
    ui.label("Sidebar");
});
egui::CentralPanel::default().show(ctx, |ui| {
    ui.label("Main content");
});

Scrolling Areas

When content exceeds the available space, wrap it in a ScrollArea. It clips overflow and adds scrollbars automatically.

Use .auto_shrink([false, false]) to make it fill the region rather than shrinking to content, and .stick_to_bottom(true) for log views.

egui::ScrollArea::vertical()
    .auto_shrink([false, false])
    .show(ui, |ui| {
        for line in &self.log {
            ui.label(line);
        }
    });

Grids for Forms

egui::Grid aligns widgets into a tidy table of rows and columns — ideal for label/value forms.

Add cells left to right and call ui.end_row() to start the next row. egui keeps columns aligned across rows automatically.

egui::Grid::new("form").num_columns(2).show(ui, |ui| {
    ui.label("Host");
    ui.text_edit_singleline(&mut self.host);
    ui.end_row();
    ui.label("Port");
    ui.add(egui::DragValue::new(&mut self.port));
    ui.end_row();
});

Spacing and Alignment

Fine control comes from spacing helpers: ui.add_space(pixels) inserts a gap, and ui.separator() draws a divider line.

To align content, use ui.with_layout(Layout::right_to_left(Align::Center), |ui| ...), which is the idiom for pushing buttons to the right edge of a row.

ui.horizontal(|ui| {
    ui.label("Title");
    ui.with_layout(egui::Layout::right_to_left(egui::Align::Center), |ui| {
        ui.button("Close");
    });
});

Floating Windows

Beyond panels, egui::Window creates a movable, resizable floating window inside your app. It is great for tool palettes and dialogs.

Bind its visibility to a bool with .open(&mut self.show) so the close button toggles your state.

egui::Window::new("Inspector")
    .open(&mut self.show_inspector)
    .resizable(true)
    .show(ctx, |ui| {
        ui.label("Properties...");
    });

Styling and Visuals

The look of every widget is governed by ctx.style() and its Visuals. Switch themes with ctx.set_visuals(egui::Visuals::dark()) or light().

You can tweak spacing, rounding, and colors globally by mutating the style, giving the whole app a consistent custom appearance.

ctx.set_visuals(if self.dark {
    egui::Visuals::dark()
} else {
    egui::Visuals::light()
});

Composing It All

Real apps nest these primitives: a top panel menu, a left side panel of navigation, and a central panel containing a grid inside a scroll area.

Because layout is just nested closures and ordinary control flow, restructuring a screen is a code edit, not a tree-surgery operation.

Quick Check

Which panel should you add last?

Recap

egui offers labels, sliders, text edits, and more — all methods on Ui returning a Response, with ui.add for configurable widgets.

Layout is built from nested closures: horizontal, vertical, columns, Grid, and ScrollArea. Panels and Window define top-level structure, and Visuals control styling. Next: managing application state cleanly.

Frequently asked questions

Is the “Widgets and Layout” lesson free?

Yes — the full text of “Widgets and Layout” is free to read here on the web, and the Learn Rust Coding course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the Learn Rust Coding course, upgrade to CoddyKit PRO.

What will I learn in “Widgets and Layout”?

Build buttons, inputs, and panels. You practise Learn Rust Coding with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.

Do I need any experience to start Learn Rust Coding?

No prior experience is required. Learn Rust Coding on CoddyKit is structured for beginners through advanced learners; this is — lesson 2 of 4, so you can start here or from the beginning and move at your own pace.

How long does the “Widgets and Layout” lesson take?

Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.

Can I write and run code in this Learn Rust Coding lesson?

Yes. Every Learn Rust Coding lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.

All lessons in this course

  1. Immediate-Mode UI Basics
  2. Widgets and Layout
  3. Managing App State
  4. Packaging a Desktop App
← Back to Learn Rust Coding