Closed kernelkind closed 3 weeks ago
100% agree with this.
The global style is stored in Options::style
, and I suggest we split that into three fields:
struct Options {
pub dark_mode_style: Arc<Style>,
pub light_mode_style: Arc<Style>,
pub theme: Theme, // Dark or Light
pub follow_system_theme: bool, // Change [`Self::theme`] based on `RawInput::system_theme`?
…
}
with enum Theme { Dark, Light }
(move the one in eframe
into egui
).
Then move IntegrationInfo::system_theme
into RawInput
.
PRs welcome!
Please also refer to issue #4312 while working.
@rustbasic Do you have an minimal example that I can run to verify that visuals_mut works as expected for you?
@rustbasic Do you have an minimal example that I can run to verify that visuals_mut works as expected for you?
If you call dark()
or light()
to change the theme, both will be initialized.
I think you need to save the settings for both of them separately so that they don't get initialized.
If you do it like the example, once the settings are set, it will be initialized when you change the theme.
Since the recent update, even the settings are initialized once.
Since text_cursor
is easy to check with your eyes, I used text_cursor
in the example.
use eframe::egui::*;
fn main() -> eframe::Result {
let options = eframe::NativeOptions {
viewport: egui::ViewportBuilder::default().with_inner_size([800.0, 600.0]),
..Default::default()
};
eframe::run_native(
"My egui App",
options,
Box::new(|_cc| Ok(Box::<MyApp>::default())),
)
}
#[derive(Default)]
struct MyApp {
text: String,
startup_complete: bool,
}
impl eframe::App for MyApp {
fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) {
egui::CentralPanel::default().show(ctx, |ui| {
self.startup(ui);
ui.horizontal(|ui| {
ui.text_edit_multiline(&mut self.text);
});
ui.separator();
ctx.settings_ui(ui);
});
}
}
impl MyApp {
fn startup(&mut self, ui: &mut Ui) {
if self.startup_complete {
return;
}
self.startup_complete = true;
ui.visuals_mut().text_cursor.on_duration = 2.0;
ui.visuals_mut().text_cursor.off_duration = 0.1;
}
}
If I'm not mistaken, ui.visuals_mut()
changes the visuals for the current UI and its children only. Since UIs are created per-frame you immediately lose any changes on the next frame.
If you want a change to the visuals to be permanent you have two options:
Context
: ctx.style_mut(|style| style.visuals.foo = bar);
ui.visuals_mut().foo = bar;
once per frame.Currently, if you have eframe configured to follow the system theme (on by default) it will override the visuals when the system theme changes and you lose your changes to the visuals. This will be fixed as soon as #4744 lands.
Yes, I think there are some ambiguous parts because I made the example in a hurry. If the following is added at the example, it seems to be the example I was trying to make.
let mut style = ui.style_mut().clone();
ui.ctx().set_style(style);
What I want is that I want the Dark and Light modes to not be reset to the default value when I change them. I think #4744 will solve it because it changes the settings for both. I haven't tested #4744 yet.
Thank you.
@rustbasic Yes, this should indeed be fixed by #4744.
With this PR you can either make changes to the dark or light style using set_dark_style
/ set_light_style
. If you want to make changes to both, then there's a handy style_mut()
function that lets you update both in one go.
Is your feature request related to a problem? Please describe. Currently, when the system theme changes, the
Visuals
theme is switched to the hard-codedegui::Visuals::dark()
oregui::Visuals::light()
. I would like for there to be an option to use customVisuals
for dark and light themes.This seems to be where the system theme change is detected and the egui visuals are set: https://github.com/emilk/egui/blob/c3f386aa301f26106397c4e14434bd5a734ba6b6/crates/eframe/src/native/epi_integration.rs#L271
And this seems to be where the hard-coded
Visuals
are set: https://github.com/emilk/egui/blob/c3f386aa301f26106397c4e14434bd5a734ba6b6/crates/eframe/src/epi.rs#L501-L506Describe the solution you'd like There should be some way to pass a
Visuals
that corresponds to the dark theme, and anotherVisuals
which corresponds to the light theme. Then, when a theme change is needed, those custom themes would be used instead of the hard-codedegui::Visuals::dark()
oregui::Visuals::light()
.Describe alternatives you've considered None
Additional context I am working on https://github.com/damus-io/notedeck and we would like to support custom theming at some point. It's not a high priority at the moment, and I would be open to submitting a PR for this feature in the future.