From 658e556a4ae5f1fa35d872a68b27799f83a68648 Mon Sep 17 00:00:00 2001 From: Mikolaj Wielgus Date: Mon, 6 Jan 2025 18:28:56 +0100 Subject: [PATCH] feat(egui): begin development of `egui-actions` crate The purpose of this new crate is to provide a system for managing actions that can be bound to a key and to derive `egui` menus to invoke them. I haven't moved all relevant code from `topola-egui` (in particular, `Switch` and `Trigger` structs) to this crate yet. --- crates/egui-actions/Cargo.toml | 17 ++++++++ crates/egui-actions/src/implementation.rs | 47 +++++++++++++++++++++++ crates/egui-actions/src/lib.rs | 14 +++++++ crates/topola-egui/Cargo.toml | 1 + crates/topola-egui/src/action.rs | 2 - crates/topola-egui/src/actions.rs | 15 +------- crates/topola-egui/src/menu_bar.rs | 1 - 7 files changed, 81 insertions(+), 16 deletions(-) create mode 100644 crates/egui-actions/Cargo.toml create mode 100644 crates/egui-actions/src/implementation.rs create mode 100644 crates/egui-actions/src/lib.rs diff --git a/crates/egui-actions/Cargo.toml b/crates/egui-actions/Cargo.toml new file mode 100644 index 0000000..8c91f32 --- /dev/null +++ b/crates/egui-actions/Cargo.toml @@ -0,0 +1,17 @@ +# SPDX-FileCopyrightText: 2024 Topola contributors +# +# SPDX-License-Identifier: MIT + +[package] +name = "egui-actions" +version = "0.1.0" +edition = "2021" + +[lib] +proc-macro = true + +[dependencies] +egui = "0.29" +proc-macro2 = "1.0" +quote = "1.0" +syn = "2.0" diff --git a/crates/egui-actions/src/implementation.rs b/crates/egui-actions/src/implementation.rs new file mode 100644 index 0000000..b56bf10 --- /dev/null +++ b/crates/egui-actions/src/implementation.rs @@ -0,0 +1,47 @@ +// SPDX-FileCopyrightText: 2025 Topola contributors +// +// SPDX-License-Identifier: MIT + +use proc_macro2::TokenStream; +use quote::quote; +use syn::{Data, DeriveInput, Field, Fields}; + +pub(super) fn impl_derive_actions(input: &DeriveInput) -> TokenStream { + let name = &input.ident; + let new_body = impl_new_body(&input.data); + + quote! { + impl #name { + pub fn new(tr: &Translator) -> Self { + #new_body + } + } + } +} + +pub(super) fn impl_new_body(data: &Data) -> TokenStream { + match data { + Data::Struct(data) => match &data.fields { + Fields::Named(fields) => { + let fields = fields.named.iter().map(impl_new_field); + + quote! { + Self { + #(#fields)* + } + } + } + _ => unimplemented!(), + }, + _ => unimplemented!(), + } +} + +pub(super) fn impl_new_field(field: &Field) -> TokenStream { + let name = &field.ident; + let typ = &field.ty; + + quote! { + #name: #typ::new(tr), + } +} diff --git a/crates/egui-actions/src/lib.rs b/crates/egui-actions/src/lib.rs new file mode 100644 index 0000000..4220e57 --- /dev/null +++ b/crates/egui-actions/src/lib.rs @@ -0,0 +1,14 @@ +// SPDX-FileCopyrightText: 2024 Topola contributors +// +// SPDX-License-Identifier: MIT + +use proc_macro::TokenStream; +use syn::DeriveInput; + +mod implementation; + +#[proc_macro_derive(Actions)] +pub fn derive_actions(input: TokenStream) -> TokenStream { + let input = syn::parse_macro_input!(input as DeriveInput); + implementation::impl_derive_actions(&input).into() +} diff --git a/crates/topola-egui/Cargo.toml b/crates/topola-egui/Cargo.toml index b98b204..0671db4 100644 --- a/crates/topola-egui/Cargo.toml +++ b/crates/topola-egui/Cargo.toml @@ -17,6 +17,7 @@ xdg-portal = ["rfd/async-std", "rfd/xdg-portal"] [dependencies] derive-getters.workspace = true egui = "0.29" +egui-actions.path = "../egui-actions" fluent-templates = "0.11" geo.workspace = true icu_experimental = "0.2" diff --git a/crates/topola-egui/src/action.rs b/crates/topola-egui/src/action.rs index 6effe39..fbddc57 100644 --- a/crates/topola-egui/src/action.rs +++ b/crates/topola-egui/src/action.rs @@ -32,7 +32,6 @@ impl Action { ) } - #[inline] pub fn into_trigger(self) -> Trigger { Trigger { action: self, @@ -40,7 +39,6 @@ impl Action { } } - #[inline(always)] pub fn into_switch(self) -> Switch { Switch { action: self } } diff --git a/crates/topola-egui/src/actions.rs b/crates/topola-egui/src/actions.rs index c9dfbdc..e760d8a 100644 --- a/crates/topola-egui/src/actions.rs +++ b/crates/topola-egui/src/actions.rs @@ -8,6 +8,7 @@ use crate::{ }; use egui::{Context, Ui}; +use egui_actions::Actions; use topola::autorouter::AutorouterOptions; pub struct FileActions { @@ -299,6 +300,7 @@ impl HelpActions { } } +#[derive(Actions)] pub struct Actions { pub file: FileActions, pub edit: EditActions, @@ -307,16 +309,3 @@ pub struct Actions { pub inspect: InspectActions, pub help: HelpActions, } - -impl Actions { - pub fn new(tr: &Translator) -> Self { - Self { - file: FileActions::new(tr), - edit: EditActions::new(tr), - place: PlaceActions::new(tr), - route: RouteActions::new(tr), - inspect: InspectActions::new(tr), - help: HelpActions::new(tr), - } - } -} diff --git a/crates/topola-egui/src/menu_bar.rs b/crates/topola-egui/src/menu_bar.rs index 1caeeed..b8b5232 100644 --- a/crates/topola-egui/src/menu_bar.rs +++ b/crates/topola-egui/src/menu_bar.rs @@ -15,7 +15,6 @@ use topola::{ }; use crate::{ - action::{Action, Switch, Trigger}, actions::Actions, app::{execute, handle_file}, translator::Translator,