Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added examples for ComboBox, SelectableLabel and Layouts #1635

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ members = [
"examples/puffin_profiler",
"examples/retained_image",
"examples/svg",
"examples/selection",
"examples/layout",
]

[profile.dev]
Expand Down
12 changes: 12 additions & 0 deletions examples/layout/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
[package]
name = "layout"
version = "0.1.0"
authors = ["Mattia Maldini <[email protected]>"]
license = "MIT OR Apache-2.0"
edition = "2021"
rust-version = "1.60"
publish = false


[dependencies]
eframe = { path = "../../eframe" }
3 changes: 3 additions & 0 deletions examples/layout/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```sh
cargo run -p layout
```
135 changes: 135 additions & 0 deletions examples/layout/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")] // hide console window on Windows in release

use eframe::egui;

fn main() {
let options = eframe::NativeOptions {
initial_window_size: Some(egui::Vec2::new(480., 480.)),
..eframe::NativeOptions::default()
};
eframe::run_native(
"My egui Layout example",
options,
Box::new(|_cc| Box::new(MyApp::default())),
);
}

#[derive(Default)]
struct MyApp {}

impl eframe::App for MyApp {
fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) {
#[derive(Hash)]
enum MyId {
ScrollArea1,
ScrollArea2,
ScrollArea3,
ScrollAreaN(usize),
}

egui::CentralPanel::default().show(ctx, |ui| {
ui.heading("My egui Layout example");

ui.add_space(16.);
egui::ScrollArea::horizontal()
.auto_shrink([true, true])
.max_height(16.)
.show(ui, |ui| {
ui.with_layout(egui::Layout::left_to_right(), |ui| {
for i in 0..8 {
ui.label(format!("Horizontal label {}", i));
}
});
});

ui.add_space(16.);
// Multiple scrollareas require an explicit id with `push_id`
ui.push_id(MyId::ScrollArea1, |ui| {
egui::ScrollArea::horizontal()
.auto_shrink([true, true])
.max_height(16.)
.show(ui, |ui| {
ui.with_layout(egui::Layout::right_to_left(), |ui| {
for i in 0..8 {
ui.label(format!("Horizontal label {}", i));
}
});
});
});

ui.add_space(16.);
ui.push_id(MyId::ScrollArea2, |ui| {
ui.with_layout(egui::Layout::left_to_right(), |ui| {
for i in 0..4 {
ui.push_id(MyId::ScrollAreaN(i), |ui| {
egui::ScrollArea::vertical()
.auto_shrink([true, false])
.max_height(64.)
.show(ui, |ui| {
// Layouts can be easily nested
ui.with_layout(
egui::Layout::top_down(egui::Align::LEFT),
|ui| {
for i in 0..8 {
ui.label(format!("Vertical label {}", i));
}
},
);
});
});
}
});
});

ui.push_id(MyId::ScrollArea3, |ui| {
egui::ScrollArea::vertical()
.auto_shrink([false, false])
.max_height(128.)
.show(ui, |ui| {
// This vertical layout has centered and shrunk objects
ui.with_layout(egui::Layout::top_down(egui::Align::Center), |ui| {
for i in 0..4 {
if ui.button(format!("Centered button {}", i)).clicked() {
println!("Clicked {}!", i);
};
}
});

ui.with_layout(
egui::Layout::top_down_justified(egui::Align::Center),
|ui| {
for i in 0..4 {
if ui
.button(format!("Centered&justified button {}", i))
.clicked()
{
println!("Clicked {}!", i);
};
}
},
);

ui.with_layout(
egui::Layout::top_down_justified(egui::Align::RIGHT),
|ui| {
for i in 0..4 {
if ui.button(format!("Right&justified button {}", i)).clicked()
{
println!("Clicked {}!", i);
};
}
},
);

ui.with_layout(egui::Layout::top_down(egui::Align::LEFT), |ui| {
for i in 0..4 {
if ui.button(format!("Left button {}", i)).clicked() {
println!("Clicked {}!", i);
};
}
});
});
});
});
}
}
12 changes: 12 additions & 0 deletions examples/selection/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
[package]
name = "selection"
version = "0.1.0"
authors = ["Mattia Maldini <[email protected]>"]
license = "MIT OR Apache-2.0"
edition = "2021"
rust-version = "1.60"
publish = false


[dependencies]
eframe = { path = "../../eframe" }
3 changes: 3 additions & 0 deletions examples/selection/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```sh
cargo run -p selection
```
125 changes: 125 additions & 0 deletions examples/selection/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")] // hide console window on Windows in release

use eframe::egui;
use std::fmt;

const STRING_OPTIONS: [&str; 8] = [
"Option 1", "Option 2", "Option 3", "Option 4", "Option 5", "Option 6", "Option 7", "Option 8",
];

fn main() {
let options = eframe::NativeOptions::default();
eframe::run_native(
"My egui Selection example",
options,
Box::new(|_cc| Box::new(MyApp::default())),
);
}

// Derive debut to conver to string and PartialEq to be comparable and allow the combobox to distinguish the selected option
#[derive(Debug, PartialEq, Clone, Copy)]
enum MyOption {
First,
Second,
Third,
}

impl fmt::Display for MyOption {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Debug::fmt(self, f)
}
}

struct MyApp {
option: MyOption,
string_option: String,
int_option: usize,
}

impl Default for MyApp {
fn default() -> Self {
Self {
option: MyOption::First,
string_option: String::from(""),
int_option: 0,
}
}
}

impl eframe::App for MyApp {
fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) {
egui::CentralPanel::default().show(ctx, |ui| {
ui.heading("My egui Selection example (ComboBox/SelectableLabel)");

ui.add_space(16.);

egui::ComboBox::from_label(format!("Currently selected enum: {}", self.option)) // When created from a label the text will b shown on the side of the combobox
.selected_text(self.option.to_string()) // This is the currently selected option (in text form)
.show_ui(ui, |ui| { // In this closure the various options can be added
for option in [MyOption::First, MyOption::Second, MyOption::Third] {
// The first parameter is a mutable reference to allow the choice to be modified when the user selects
// something else. The second parameter is the actual value of the option (to be compared with the currently)
// selected one to allow egui to highlight the correct label. The third parameter is the string to show.
ui.selectable_value(&mut self.option, option, option.to_string());
}
});

ui.label("These options are selectable just like the combobox before them");
for option in [MyOption::First, MyOption::Second, MyOption::Third] {
// SelectableLabel is a similar widget; it works like a button that can be checked. Here it serves the
// purpose of a radio button, with a single option being selected at any time
if ui
.add(egui::SelectableLabel::new(
self.option == option,
option.to_string(),
))
.clicked()
{
self.option = option;
}
}

ui.add_space(16.);

egui::ComboBox::from_label(format!(
"Currently selected string: {}",
self.string_option
))
.selected_text(self.string_option.clone())
.show_ui(ui, |ui| {
for option in STRING_OPTIONS {
// Selectable values can be anything: enums, strings or integers - as long as they can be compared and have a text repersentation
ui.selectable_value(&mut self.string_option, option.into(), option);
}
});

ui.label("When creating these options the 'clicked' condition is not checked, so they simply display the choice without being interactable");
egui::ScrollArea::vertical()
.auto_shrink([true, false])
.max_height(64.)
.show(ui, |ui| {
for option in STRING_OPTIONS {
ui.add(egui::SelectableLabel::new(
self.string_option == option,
option,
));
}
});

ui.add_space(16.);

ui.label(format!("Currently selected number: {}", self.int_option));
egui::ComboBox::from_id_source(0)
.selected_text(self.int_option.to_string())
.show_ui(ui, |ui| {
for option in 0..3 {
ui.selectable_value(
&mut self.int_option,
option,
(option as u32).to_string(),
);
}
});
});
}
}