user interface improvements

This commit is contained in:
Simon Gardling 2022-05-18 18:43:52 -04:00
parent 782d567302
commit 8ed749ef72
6 changed files with 190 additions and 109 deletions

12
Cargo.lock generated
View File

@ -659,7 +659,7 @@ checksum = "453440c271cf5577fd2a40e4942540cb7d0d2f85e27c8d07dd0023c925a67541"
[[package]]
name = "eframe"
version = "0.18.0"
source = "git+https://github.com/Titaniumtown/egui.git#ea25cc1a991610099ada8fe02f1c11ba708f77fd"
source = "git+https://github.com/Titaniumtown/egui.git#b5adf3b7ec16255873e7a610573a645719d02e89"
dependencies = [
"bytemuck",
"egui",
@ -679,7 +679,7 @@ dependencies = [
[[package]]
name = "egui"
version = "0.18.1"
source = "git+https://github.com/Titaniumtown/egui.git#ea25cc1a991610099ada8fe02f1c11ba708f77fd"
source = "git+https://github.com/Titaniumtown/egui.git#b5adf3b7ec16255873e7a610573a645719d02e89"
dependencies = [
"ahash",
"epaint",
@ -691,7 +691,7 @@ dependencies = [
[[package]]
name = "egui-winit"
version = "0.18.0"
source = "git+https://github.com/Titaniumtown/egui.git#ea25cc1a991610099ada8fe02f1c11ba708f77fd"
source = "git+https://github.com/Titaniumtown/egui.git#b5adf3b7ec16255873e7a610573a645719d02e89"
dependencies = [
"arboard",
"egui",
@ -705,7 +705,7 @@ dependencies = [
[[package]]
name = "egui_glow"
version = "0.18.1"
source = "git+https://github.com/Titaniumtown/egui.git#ea25cc1a991610099ada8fe02f1c11ba708f77fd"
source = "git+https://github.com/Titaniumtown/egui.git#b5adf3b7ec16255873e7a610573a645719d02e89"
dependencies = [
"bytemuck",
"egui",
@ -725,7 +725,7 @@ checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457"
[[package]]
name = "emath"
version = "0.18.0"
source = "git+https://github.com/Titaniumtown/egui.git#ea25cc1a991610099ada8fe02f1c11ba708f77fd"
source = "git+https://github.com/Titaniumtown/egui.git#b5adf3b7ec16255873e7a610573a645719d02e89"
dependencies = [
"bytemuck",
"serde",
@ -734,7 +734,7 @@ dependencies = [
[[package]]
name = "epaint"
version = "0.18.1"
source = "git+https://github.com/Titaniumtown/egui.git#ea25cc1a991610099ada8fe02f1c11ba708f77fd"
source = "git+https://github.com/Titaniumtown/egui.git#b5adf3b7ec16255873e7a610573a645719d02e89"
dependencies = [
"ab_glyph",
"ahash",

View File

@ -10,8 +10,7 @@
"- The 'Panel' button toggles if the side bar should be shown or not. This can also be accomplished by pressing the 'h' key.",
"- The 'Add Function' button adds a new function to be graphed. You can then configure that function in the side panel.",
"- The 'Help' button opens and closes this window!",
"- The 'Info' button provides information on the build currently running.",
"- The Sun/Moon button toggles Dark and Light mode."
"- The 'Info' button provides information on the build currently running."
],
"help_function": [
"(From Left to Right)",
@ -25,6 +24,7 @@
],
"welcome": [
"Welcome to the (Yet-to-be-named) Graphing Software!",
"",
"This project aims to provide an intuitive experience graphing mathematical functions with features such as Integration, Differentiation, Extrema, Roots, and much more! (see the Help Window for more details)"
]
}

View File

@ -22,6 +22,7 @@ mod function_entry;
mod function_manager;
mod math_app;
mod misc;
mod style;
mod widgets;
pub use crate::{

View File

@ -22,6 +22,7 @@ mod function_entry;
mod function_manager;
mod math_app;
mod misc;
mod style;
mod widgets;
// For running the program natively! (Because why not?)

View File

@ -6,7 +6,7 @@ use crate::misc::{dyn_mut_iter, option_vec_printer};
use eframe::App;
use egui::{
plot::Plot, style::Margin, Button, CentralPanel, ComboBox, Context, Frame, Key, Layout,
SidePanel, Slider, TopBottomPanel, Vec2, Visuals, Window,
SidePanel, Slider, TopBottomPanel, Vec2, Window,
};
use emath::{Align, Align2};
use epaint::Rounding;
@ -93,9 +93,6 @@ pub struct MathApp {
/// Contains the list of Areas calculated (the vector of f64) and time it took for the last frame (the Duration). Stored in a Tuple.
last_info: (Option<String>, Option<String>),
/// Whether or not dark mode is enabled
dark_mode: bool,
/// Stores opened windows/elements for later reference
opened: Opened,
@ -242,7 +239,12 @@ impl MathApp {
cc.egui_ctx.set_fonts(data.fonts);
// Set dark mode by default
cc.egui_ctx.set_visuals(Visuals::dark());
cc.egui_ctx.set_visuals(crate::style::STYLE);
// Set spacing
let mut style: egui::Style = (*cc.egui_ctx.style()).clone();
style.spacing = crate::style::SPACING;
cc.egui_ctx.set_style(style);
tracing::info!("Initialized! Took: {:?}", start.elapsed());
@ -254,7 +256,6 @@ impl MathApp {
functions: FunctionManager::default(),
last_info: (None, None),
dark_mode: true, // dark mode is default and is previously set
text: data.text,
opened: Opened::default(),
settings: Default::default(),
@ -440,25 +441,6 @@ impl App for MathApp {
.clicked(),
);
// Toggles dark/light mode
if ui
.add(Button::new(match self.dark_mode {
true => "🌞",
false => "🌙",
}))
.on_hover_text(match self.dark_mode {
true => "Turn the Lights on!",
false => "Turn the Lights off.",
})
.clicked()
{
ctx.set_visuals(match self.dark_mode {
true => Visuals::light(),
false => Visuals::dark(),
});
self.dark_mode.bitxor_assign(true);
}
// Display Area and time of last frame
if let Some(ref area) = self.last_info.0 {
ui.label(area);
@ -495,7 +477,8 @@ impl App for MathApp {
});
// Welcome window
Window::new("Welcome!")
if self.opened.welcome {
let welcome_response = Window::new("Welcome!")
.open(&mut self.opened.welcome)
.anchor(Align2::CENTER_CENTER, Vec2::ZERO)
.resizable(false)
@ -504,6 +487,14 @@ impl App for MathApp {
ui.label(self.text.welcome.clone());
});
if let Some(response) = welcome_response {
// if user clicks off welcome window, close it
if response.response.clicked_elsewhere() {
self.opened.welcome = false;
}
}
}
// Window with information about the build and current commit
Window::new("Info")
.open(&mut self.opened.info)
@ -523,16 +514,15 @@ impl App for MathApp {
self.side_panel(ctx);
}
// Central panel which contains the central plot (or an error created when
// parsing)
CentralPanel::default()
.frame(Frame {
const EMPTY_FRAME: Frame = Frame {
inner_margin: Margin::symmetric(0.0, 0.0),
rounding: Rounding::none(),
fill: ctx.style().visuals.window_fill(),
..Default::default()
})
.show(ctx, |ui| {
fill: crate::style::STYLE.window_fill(),
..Frame::none()
};
// Central panel which contains the central plot (or an error created when parsing)
CentralPanel::default().frame(EMPTY_FRAME).show(ctx, |ui| {
// Display an error if it exists
let errors_formatted: String = self
.functions
@ -543,9 +533,7 @@ impl App for MathApp {
.filter(|(_, error)| error.is_some())
.map(|(i, error)| {
// use unwrap_unchecked as None Errors are already filtered out
unsafe {
format!("(Function #{}) {}\n", i, error.as_ref().unwrap_unchecked())
}
unsafe { format!("(Function #{}) {}\n", i, error.as_ref().unwrap_unchecked()) }
})
.collect::<String>();

91
src/style.rs Normal file
View File

@ -0,0 +1,91 @@
use egui::{
style::{Margin, Selection, Spacing, WidgetVisuals, Widgets},
Visuals,
};
use emath::vec2;
use epaint::{Color32, Rounding, Shadow, Stroke};
const fn widgets_dark() -> Widgets {
Widgets {
noninteractive: WidgetVisuals {
bg_fill: Color32::from_gray(27), // window background
bg_stroke: Stroke::new(1.0, Color32::from_gray(60)), // separators, indentation lines, windows outlines
fg_stroke: Stroke::new(1.0, Color32::from_gray(140)), // normal text color
rounding: Rounding::same(2.0),
expansion: 0.0,
},
inactive: WidgetVisuals {
bg_fill: Color32::from_gray(60), // button background
bg_stroke: Stroke::default(),
fg_stroke: Stroke::new(1.0, Color32::from_gray(180)), // button text
rounding: Rounding::same(2.0),
expansion: 0.0,
},
hovered: WidgetVisuals {
bg_fill: Color32::from_gray(70),
bg_stroke: Stroke::new(1.0, Color32::from_gray(150)), // e.g. hover over window edge or button
fg_stroke: Stroke::new(1.5, Color32::from_gray(240)),
rounding: Rounding::same(3.0),
expansion: 1.0,
},
active: WidgetVisuals {
bg_fill: Color32::from_gray(55),
bg_stroke: Stroke::new(1.0, Color32::WHITE),
fg_stroke: Stroke::new(2.0, Color32::WHITE),
rounding: Rounding::same(2.0),
expansion: 1.0,
},
open: WidgetVisuals {
bg_fill: Color32::from_gray(27),
bg_stroke: Stroke::new(1.0, Color32::from_gray(60)),
fg_stroke: Stroke::new(1.0, Color32::from_gray(210)),
rounding: Rounding::same(2.0),
expansion: 0.0,
},
}
}
pub const STYLE: Visuals = dark();
pub const fn dark() -> Visuals {
Visuals {
dark_mode: true,
override_text_color: None,
widgets: widgets_dark(),
selection: Selection::default(),
hyperlink_color: Color32::from_rgb(90, 170, 255),
faint_bg_color: Color32::from_gray(35),
extreme_bg_color: Color32::from_gray(10), // e.g. TextEdit background
code_bg_color: Color32::from_gray(64),
window_rounding: Rounding::same(1.5),
window_shadow: Shadow::default(), // no shadow
popup_shadow: Shadow::default(), // no shadow
resize_corner_size: 12.0,
text_cursor_width: 2.0,
text_cursor_preview: false,
clip_rect_margin: 3.0, // should be at least half the size of the widest frame stroke + max WidgetVisuals::expansion
button_frame: true,
collapsing_header_frame: false,
}
}
pub const SPACING: Spacing = spacing();
pub const fn spacing() -> Spacing {
Spacing {
item_spacing: vec2(8.0, 3.0),
window_margin: Margin::same(6.0),
button_padding: vec2(4.0, 1.0),
indent: 18.0, // match checkbox/radio-button with `button_padding.x + icon_width + icon_spacing`
interact_size: vec2(40.0, 18.0),
slider_width: 100.0,
text_edit_width: 280.0,
icon_width: 14.0,
icon_width_inner: 8.0,
icon_spacing: 4.0,
tooltip_width: 600.0,
combo_height: 200.0,
scroll_bar_width: 8.0,
indent_ends_with_horizontal_line: false,
}
}