Last active
July 8, 2024 19:09
-
-
Save matthewjberger/0485fe9f94a489f46acb30efc579d4f8 to your computer and use it in GitHub Desktop.
egui enum dropdown selection in rust
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// This is a macro that can generate the egui enum dropdown pattern for a c-style Rust enum | |
// meaning it contains only fieldless, unit variants | |
#[macro_export] | |
macro_rules! generate_enum { | |
( | |
$name:ident { | |
$($variant:ident),* $(,)? | |
} | |
) => { | |
#[derive(Debug, Clone, Default, serde::Deserialize, serde::Serialize, PartialEq)] | |
pub enum $name { | |
#[default] | |
$($variant),* | |
} | |
impl std::fmt::Display for $name { | |
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | |
match self { | |
$(Self::$variant => write!(f, "{}", stringify!($variant)),)* | |
} | |
} | |
} | |
impl $name { | |
pub fn ui(&self, ui: &mut egui::Ui) { | |
ui.label(format!("{}", self)); | |
} | |
pub fn ui_mut(&mut self, ui: &mut egui::Ui) { | |
egui::ComboBox::from_id_source(ui.next_auto_id()) | |
.selected_text(format!("{}", self)) | |
.show_ui(ui, |ui| { | |
$( | |
if ui.selectable_value(self, $name::$variant, stringify!($variant)).clicked() { | |
*self = $name::$variant; | |
} | |
)* | |
}); | |
} | |
} | |
} | |
} | |
generate_enum! { | |
Color { | |
Red, | |
Green, | |
Blue, | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#[derive(Debug, Clone, Default, PartialEq)] | |
pub enum Color { | |
#[default] | |
Red, | |
Green, | |
Blue, | |
} | |
impl Color { | |
pub fn variant_names() -> Vec<String> { | |
vec![ | |
Color::Red.to_string(), | |
Color::Green.to_string(), | |
Color::Blue.to_string(), | |
] | |
} | |
} | |
impl std::fmt::Display for Color { | |
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | |
match self { | |
Color::Red => write!(f, "{}", "Red"), | |
Color::Green => write!(f, "{}", "Green"), | |
Color::Blue => write!(f, "{}", "Blue"), | |
} | |
} | |
} | |
impl Color { | |
pub fn ui(&mut self, ui: &mut egui::Ui) { | |
ui.label(format!("{self}")); | |
} | |
pub fn ui_mut(&mut self, ui: &mut egui::Ui) { | |
egui::ComboBox::from_id_source(ui.next_auto_id()) | |
.selected_text(format!("{self}")) | |
.show_ui(ui, |ui| { | |
Color::variant_names().iter().for_each(|variant| { | |
ui.vertical(|ui| match variant { | |
_ if variant == &Color::Red.to_string() => { | |
if ui | |
.selectable_value(self, Color::Red, Color::Red.to_string()) | |
.clicked() | |
{ | |
*self = Color::Red; | |
} | |
} | |
_ if variant == &Color::Green.to_string() => { | |
if ui | |
.selectable_value(self, Color::Green, Color::Green.to_string()) | |
.clicked() | |
{ | |
*self = Color::Green; | |
} | |
} | |
_ if variant == &Color::Blue.to_string() => { | |
if ui | |
.selectable_value(self, Color::Blue, Color::Blue.to_string()) | |
.clicked() | |
{ | |
*self = Color::Blue; | |
} | |
} | |
_ => {} | |
}); | |
}); | |
}); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment