Add light mode
This commit is contained in:
parent
c536e1b0da
commit
a19fd7b780
12 changed files with 230 additions and 67 deletions
|
@ -331,7 +331,7 @@ impl Prepared {
|
||||||
ui.painter().add(paint::Shape::Rect {
|
ui.painter().add(paint::Shape::Rect {
|
||||||
rect: outer_scroll_rect,
|
rect: outer_scroll_rect,
|
||||||
corner_radius,
|
corner_radius,
|
||||||
fill: ui.visuals().dark_bg_color,
|
fill: ui.visuals().extreme_bg_color,
|
||||||
stroke: Default::default(),
|
stroke: Default::default(),
|
||||||
// fill: visuals.bg_fill,
|
// fill: visuals.bg_fill,
|
||||||
// stroke: visuals.bg_stroke,
|
// stroke: visuals.bg_stroke,
|
||||||
|
|
|
@ -38,6 +38,7 @@ impl State {
|
||||||
|
|
||||||
pub(crate) struct GridLayout {
|
pub(crate) struct GridLayout {
|
||||||
ctx: CtxRef,
|
ctx: CtxRef,
|
||||||
|
style: std::sync::Arc<Style>,
|
||||||
id: Id,
|
id: Id,
|
||||||
|
|
||||||
/// State previous frame (if any).
|
/// State previous frame (if any).
|
||||||
|
@ -61,6 +62,7 @@ impl GridLayout {
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
ctx: ui.ctx().clone(),
|
ctx: ui.ctx().clone(),
|
||||||
|
style: ui.style().clone(),
|
||||||
id,
|
id,
|
||||||
prev_state,
|
prev_state,
|
||||||
curr_state: State::default(),
|
curr_state: State::default(),
|
||||||
|
@ -125,8 +127,8 @@ impl GridLayout {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn advance(&mut self, cursor: &mut Pos2, frame_rect: Rect, widget_rect: Rect) {
|
pub(crate) fn advance(&mut self, cursor: &mut Pos2, frame_rect: Rect, widget_rect: Rect) {
|
||||||
let debug_expand_width = self.ctx.style().visuals.debug_expand_width;
|
let debug_expand_width = self.style.visuals.debug_expand_width;
|
||||||
let debug_expand_height = self.ctx.style().visuals.debug_expand_height;
|
let debug_expand_height = self.style.visuals.debug_expand_height;
|
||||||
if debug_expand_width || debug_expand_height {
|
if debug_expand_width || debug_expand_height {
|
||||||
let rect = widget_rect;
|
let rect = widget_rect;
|
||||||
let too_wide = rect.width() > self.prev_col_width(self.col);
|
let too_wide = rect.width() > self.prev_col_width(self.col);
|
||||||
|
@ -173,8 +175,12 @@ impl GridLayout {
|
||||||
let rect = Rect::from_min_size(*cursor, size);
|
let rect = Rect::from_min_size(*cursor, size);
|
||||||
let rect = rect.expand2(0.5 * self.spacing.y * Vec2::Y);
|
let rect = rect.expand2(0.5 * self.spacing.y * Vec2::Y);
|
||||||
let rect = rect.expand2(2.0 * Vec2::X); // HACK: just looks better with some spacing on the sides
|
let rect = rect.expand2(2.0 * Vec2::X); // HACK: just looks better with some spacing on the sides
|
||||||
let color = Rgba::from_white_alpha(0.0075);
|
|
||||||
// let color = Rgba::from_black_alpha(0.2);
|
let color = if self.style.visuals.dark_mode {
|
||||||
|
Rgba::from_white_alpha(0.0075)
|
||||||
|
} else {
|
||||||
|
Rgba::from_black_alpha(0.075)
|
||||||
|
};
|
||||||
painter.rect_filled(rect, 2.0, color);
|
painter.rect_filled(rect, 2.0, color);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,7 +42,7 @@ impl BarState {
|
||||||
/// In the latter case you may want to wrap it in `Frame`.
|
/// In the latter case you may want to wrap it in `Frame`.
|
||||||
pub fn bar<R>(ui: &mut Ui, add_contents: impl FnOnce(&mut Ui) -> R) -> (R, Response) {
|
pub fn bar<R>(ui: &mut Ui, add_contents: impl FnOnce(&mut Ui) -> R) -> (R, Response) {
|
||||||
ui.horizontal(|ui| {
|
ui.horizontal(|ui| {
|
||||||
let mut style = ui.style().clone();
|
let mut style = (**ui.style()).clone();
|
||||||
style.spacing.button_padding = vec2(2.0, 0.0);
|
style.spacing.button_padding = vec2(2.0, 0.0);
|
||||||
// style.visuals.widgets.active.bg_fill = Color32::TRANSPARENT;
|
// style.visuals.widgets.active.bg_fill = Color32::TRANSPARENT;
|
||||||
style.visuals.widgets.active.bg_stroke = Stroke::none();
|
style.visuals.widgets.active.bg_stroke = Stroke::none();
|
||||||
|
@ -102,7 +102,7 @@ fn menu_impl<'c>(
|
||||||
|
|
||||||
area.show(ui.ctx(), |ui| {
|
area.show(ui.ctx(), |ui| {
|
||||||
frame.show(ui, |ui| {
|
frame.show(ui, |ui| {
|
||||||
let mut style = ui.style().clone();
|
let mut style = (**ui.style()).clone();
|
||||||
style.spacing.button_padding = vec2(2.0, 0.0);
|
style.spacing.button_padding = vec2(2.0, 0.0);
|
||||||
// style.visuals.widgets.active.bg_fill = Color32::TRANSPARENT;
|
// style.visuals.widgets.active.bg_fill = Color32::TRANSPARENT;
|
||||||
style.visuals.widgets.active.bg_stroke = Stroke::none();
|
style.visuals.widgets.active.bg_stroke = Stroke::none();
|
||||||
|
|
|
@ -111,6 +111,10 @@ pub struct Interaction {
|
||||||
#[cfg_attr(feature = "persistence", derive(serde::Deserialize, serde::Serialize))]
|
#[cfg_attr(feature = "persistence", derive(serde::Deserialize, serde::Serialize))]
|
||||||
#[cfg_attr(feature = "persistence", serde(default))]
|
#[cfg_attr(feature = "persistence", serde(default))]
|
||||||
pub struct Visuals {
|
pub struct Visuals {
|
||||||
|
/// If true, the visuals are overall dark with light text.
|
||||||
|
/// If false, the visuals are overall light with dark text.
|
||||||
|
pub dark_mode: bool,
|
||||||
|
|
||||||
/// Override default text color for all text.
|
/// Override default text color for all text.
|
||||||
///
|
///
|
||||||
/// This is great for setting the color of text for any widget.
|
/// This is great for setting the color of text for any widget.
|
||||||
|
@ -131,9 +135,10 @@ pub struct Visuals {
|
||||||
|
|
||||||
pub selection: Selection,
|
pub selection: Selection,
|
||||||
|
|
||||||
/// e.g. the background of the slider or text edit,
|
/// Very dark or light color (for corresponding theme).
|
||||||
/// needs to look different from other interactive stuff.
|
/// Used as the background of text edits, scroll bars and others things
|
||||||
pub dark_bg_color: Color32, // TODO: remove, rename, or clarify what it is for
|
/// that needs to look different from other interactive stuff.
|
||||||
|
pub extreme_bg_color: Color32,
|
||||||
|
|
||||||
/// The color used for `Hyperlink`,
|
/// The color used for `Hyperlink`,
|
||||||
pub hyperlink_color: Color32,
|
pub hyperlink_color: Color32,
|
||||||
|
@ -286,17 +291,18 @@ impl Default for Interaction {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Visuals {
|
impl Visuals {
|
||||||
fn default() -> Self {
|
pub fn dark() -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
dark_mode: true,
|
||||||
override_text_color: None,
|
override_text_color: None,
|
||||||
widgets: Default::default(),
|
widgets: Widgets::default(),
|
||||||
selection: Default::default(),
|
selection: Selection::default(),
|
||||||
dark_bg_color: Color32::from_gray(10),
|
extreme_bg_color: Color32::from_gray(10),
|
||||||
hyperlink_color: Color32::from_rgb(90, 170, 255),
|
hyperlink_color: Color32::from_rgb(90, 170, 255),
|
||||||
code_bg_color: Color32::from_gray(64),
|
code_bg_color: Color32::from_gray(64),
|
||||||
window_corner_radius: 10.0,
|
window_corner_radius: 10.0,
|
||||||
window_shadow: Shadow::big(),
|
window_shadow: Shadow::big_dark(),
|
||||||
resize_corner_size: 12.0,
|
resize_corner_size: 12.0,
|
||||||
text_cursor_width: 2.0,
|
text_cursor_width: 2.0,
|
||||||
clip_rect_margin: 3.0, // should be at least half the size of the widest frame stroke + max WidgetVisuals::expansion
|
clip_rect_margin: 3.0, // should be at least half the size of the widest frame stroke + max WidgetVisuals::expansion
|
||||||
|
@ -305,10 +311,29 @@ impl Default for Visuals {
|
||||||
debug_resize: false,
|
debug_resize: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn light() -> Self {
|
||||||
|
Self {
|
||||||
|
dark_mode: false,
|
||||||
|
widgets: Widgets::light(),
|
||||||
|
selection: Selection::light(),
|
||||||
|
extreme_bg_color: Color32::from_gray(235), // TODO: rename
|
||||||
|
hyperlink_color: Color32::from_rgb(0, 133, 218),
|
||||||
|
code_bg_color: Color32::from_gray(200),
|
||||||
|
window_shadow: Shadow::big_light(),
|
||||||
|
..Self::dark()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Selection {
|
impl Default for Visuals {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
|
Self::dark()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Selection {
|
||||||
|
fn dark() -> Self {
|
||||||
Self {
|
Self {
|
||||||
bg_fill: Rgba::from_rgb(0.0, 0.5, 1.0)
|
bg_fill: Rgba::from_rgb(0.0, 0.5, 1.0)
|
||||||
.additive()
|
.additive()
|
||||||
|
@ -317,53 +342,106 @@ impl Default for Selection {
|
||||||
stroke: Stroke::new(1.0, Rgba::from_rgb(0.3, 0.6, 1.0)),
|
stroke: Stroke::new(1.0, Rgba::from_rgb(0.3, 0.6, 1.0)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
fn light() -> Self {
|
||||||
|
Self {
|
||||||
|
bg_fill: Rgba::from_rgb(0.0, 0.5, 1.0).multiply(0.5).into(),
|
||||||
|
stroke: Stroke::new(1.0, Rgba::from_rgb(0.3, 0.6, 1.0)),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Widgets {
|
impl Default for Selection {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
|
Self::dark()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Widgets {
|
||||||
|
pub fn dark() -> Self {
|
||||||
Self {
|
Self {
|
||||||
noninteractive: WidgetVisuals {
|
noninteractive: WidgetVisuals {
|
||||||
bg_stroke: Stroke::new(1.0, Color32::from_gray(65)), // window outline
|
bg_stroke: Stroke::new(1.0, Color32::from_gray(65)), // window outline
|
||||||
bg_fill: Color32::from_gray(30), // window background
|
bg_fill: Color32::from_gray(30), // window background
|
||||||
corner_radius: 4.0,
|
|
||||||
|
|
||||||
fg_stroke: Stroke::new(1.0, Color32::from_gray(160)), // text color
|
fg_stroke: Stroke::new(1.0, Color32::from_gray(160)), // text color
|
||||||
|
corner_radius: 4.0,
|
||||||
expansion: 0.0,
|
expansion: 0.0,
|
||||||
},
|
},
|
||||||
disabled: WidgetVisuals {
|
disabled: WidgetVisuals {
|
||||||
bg_fill: Color32::from_gray(40), // Should look grayed out
|
bg_fill: Color32::from_gray(40), // Should look grayed out
|
||||||
bg_stroke: Stroke::new(1.0, Color32::from_gray(70)),
|
bg_stroke: Stroke::new(1.0, Color32::from_gray(70)),
|
||||||
corner_radius: 4.0,
|
|
||||||
|
|
||||||
fg_stroke: Stroke::new(1.0, Color32::from_gray(140)), // Should look grayed out
|
fg_stroke: Stroke::new(1.0, Color32::from_gray(140)), // Should look grayed out
|
||||||
|
corner_radius: 4.0,
|
||||||
expansion: 0.0,
|
expansion: 0.0,
|
||||||
},
|
},
|
||||||
inactive: WidgetVisuals {
|
inactive: WidgetVisuals {
|
||||||
bg_fill: Color32::from_gray(70),
|
bg_fill: Color32::from_gray(70),
|
||||||
bg_stroke: Default::default(),
|
bg_stroke: Default::default(),
|
||||||
corner_radius: 4.0,
|
|
||||||
|
|
||||||
fg_stroke: Stroke::new(1.0, Color32::from_gray(200)), // Should NOT look grayed out!
|
fg_stroke: Stroke::new(1.0, Color32::from_gray(200)), // Should NOT look grayed out!
|
||||||
|
corner_radius: 4.0,
|
||||||
expansion: 0.0,
|
expansion: 0.0,
|
||||||
},
|
},
|
||||||
hovered: WidgetVisuals {
|
hovered: WidgetVisuals {
|
||||||
bg_fill: Color32::from_gray(80),
|
bg_fill: Color32::from_gray(80),
|
||||||
bg_stroke: Stroke::new(1.0, Color32::from_gray(150)), // e.g. hover over window edge or button
|
bg_stroke: Stroke::new(1.0, Color32::from_gray(150)), // e.g. hover over window edge or button
|
||||||
corner_radius: 4.0,
|
|
||||||
|
|
||||||
fg_stroke: Stroke::new(1.5, Color32::from_gray(240)),
|
fg_stroke: Stroke::new(1.5, Color32::from_gray(240)),
|
||||||
|
corner_radius: 4.0,
|
||||||
expansion: 1.0,
|
expansion: 1.0,
|
||||||
},
|
},
|
||||||
active: WidgetVisuals {
|
active: WidgetVisuals {
|
||||||
bg_fill: Color32::from_gray(90),
|
bg_fill: Color32::from_gray(90),
|
||||||
bg_stroke: Stroke::new(1.0, Color32::WHITE),
|
bg_stroke: Stroke::new(1.0, Color32::WHITE),
|
||||||
corner_radius: 4.0,
|
|
||||||
|
|
||||||
fg_stroke: Stroke::new(2.0, Color32::WHITE),
|
fg_stroke: Stroke::new(2.0, Color32::WHITE),
|
||||||
|
corner_radius: 4.0,
|
||||||
expansion: 2.0,
|
expansion: 2.0,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn light() -> Self {
|
||||||
|
Self {
|
||||||
|
noninteractive: WidgetVisuals {
|
||||||
|
bg_stroke: Stroke::new(1.0, Color32::from_gray(180)), // window outline
|
||||||
|
bg_fill: Color32::from_gray(220), // window background
|
||||||
|
fg_stroke: Stroke::new(1.0, Color32::from_gray(70)), // text color
|
||||||
|
corner_radius: 4.0,
|
||||||
|
expansion: 0.0,
|
||||||
|
},
|
||||||
|
disabled: WidgetVisuals {
|
||||||
|
bg_fill: Color32::from_gray(215), // Should look grayed out
|
||||||
|
bg_stroke: Stroke::new(1.0, Color32::from_gray(185)),
|
||||||
|
fg_stroke: Stroke::new(1.0, Color32::from_gray(115)), // Should look grayed out
|
||||||
|
corner_radius: 4.0,
|
||||||
|
expansion: 0.0,
|
||||||
|
},
|
||||||
|
inactive: WidgetVisuals {
|
||||||
|
bg_fill: Color32::from_gray(195),
|
||||||
|
bg_stroke: Default::default(),
|
||||||
|
fg_stroke: Stroke::new(1.0, Color32::from_gray(55)), // Should NOT look grayed out!
|
||||||
|
corner_radius: 4.0,
|
||||||
|
expansion: 0.0,
|
||||||
|
},
|
||||||
|
hovered: WidgetVisuals {
|
||||||
|
bg_fill: Color32::from_gray(175),
|
||||||
|
bg_stroke: Stroke::new(1.0, Color32::from_gray(105)), // e.g. hover over window edge or button
|
||||||
|
fg_stroke: Stroke::new(2.0, Color32::BLACK),
|
||||||
|
corner_radius: 4.0,
|
||||||
|
expansion: 1.0,
|
||||||
|
},
|
||||||
|
active: WidgetVisuals {
|
||||||
|
bg_fill: Color32::from_gray(165),
|
||||||
|
bg_stroke: Stroke::new(1.0, Color32::BLACK),
|
||||||
|
fg_stroke: Stroke::new(2.0, Color32::BLACK),
|
||||||
|
corner_radius: 4.0,
|
||||||
|
expansion: 2.0,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for Widgets {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::dark()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
@ -372,8 +450,6 @@ use crate::{widgets::*, Ui};
|
||||||
|
|
||||||
impl Style {
|
impl Style {
|
||||||
pub fn ui(&mut self, ui: &mut crate::Ui) {
|
pub fn ui(&mut self, ui: &mut crate::Ui) {
|
||||||
crate::reset_button(ui, self);
|
|
||||||
|
|
||||||
let Self {
|
let Self {
|
||||||
body_text_style,
|
body_text_style,
|
||||||
spacing,
|
spacing,
|
||||||
|
@ -381,6 +457,9 @@ impl Style {
|
||||||
visuals,
|
visuals,
|
||||||
animation_time,
|
animation_time,
|
||||||
} = self;
|
} = self;
|
||||||
|
|
||||||
|
visuals.light_dark_radio_buttons(ui);
|
||||||
|
|
||||||
ui.horizontal(|ui| {
|
ui.horizontal(|ui| {
|
||||||
ui.label("Default text style:");
|
ui.label("Default text style:");
|
||||||
for &value in &[TextStyle::Body, TextStyle::Monospace] {
|
for &value in &[TextStyle::Body, TextStyle::Monospace] {
|
||||||
|
@ -391,13 +470,13 @@ impl Style {
|
||||||
ui.collapsing("☝ Interaction", |ui| interaction.ui(ui));
|
ui.collapsing("☝ Interaction", |ui| interaction.ui(ui));
|
||||||
ui.collapsing("🎨 Visuals", |ui| visuals.ui(ui));
|
ui.collapsing("🎨 Visuals", |ui| visuals.ui(ui));
|
||||||
ui.add(Slider::f32(animation_time, 0.0..=1.0).text("animation_time"));
|
ui.add(Slider::f32(animation_time, 0.0..=1.0).text("animation_time"));
|
||||||
|
|
||||||
|
ui.vertical_centered(|ui| reset_button(ui, self));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Spacing {
|
impl Spacing {
|
||||||
pub fn ui(&mut self, ui: &mut crate::Ui) {
|
pub fn ui(&mut self, ui: &mut crate::Ui) {
|
||||||
crate::reset_button(ui, self);
|
|
||||||
|
|
||||||
let Self {
|
let Self {
|
||||||
item_spacing,
|
item_spacing,
|
||||||
window_padding,
|
window_padding,
|
||||||
|
@ -422,13 +501,13 @@ impl Spacing {
|
||||||
ui.add(Slider::f32(icon_width, 0.0..=60.0).text("icon_width"));
|
ui.add(Slider::f32(icon_width, 0.0..=60.0).text("icon_width"));
|
||||||
ui.add(Slider::f32(icon_spacing, 0.0..=10.0).text("icon_spacing"));
|
ui.add(Slider::f32(icon_spacing, 0.0..=10.0).text("icon_spacing"));
|
||||||
ui.add(Slider::f32(tooltip_width, 0.0..=10.0).text("tooltip_width"));
|
ui.add(Slider::f32(tooltip_width, 0.0..=10.0).text("tooltip_width"));
|
||||||
|
|
||||||
|
ui.vertical_centered(|ui| reset_button(ui, self));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Interaction {
|
impl Interaction {
|
||||||
pub fn ui(&mut self, ui: &mut crate::Ui) {
|
pub fn ui(&mut self, ui: &mut crate::Ui) {
|
||||||
crate::reset_button(ui, self);
|
|
||||||
|
|
||||||
let Self {
|
let Self {
|
||||||
resize_grab_radius_side,
|
resize_grab_radius_side,
|
||||||
resize_grab_radius_corner,
|
resize_grab_radius_corner,
|
||||||
|
@ -437,13 +516,13 @@ impl Interaction {
|
||||||
ui.add(
|
ui.add(
|
||||||
Slider::f32(resize_grab_radius_corner, 0.0..=20.0).text("resize_grab_radius_corner"),
|
Slider::f32(resize_grab_radius_corner, 0.0..=20.0).text("resize_grab_radius_corner"),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
ui.vertical_centered(|ui| reset_button(ui, self));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Widgets {
|
impl Widgets {
|
||||||
pub fn ui(&mut self, ui: &mut crate::Ui) {
|
pub fn ui(&mut self, ui: &mut crate::Ui) {
|
||||||
crate::reset_button(ui, self);
|
|
||||||
|
|
||||||
let Self {
|
let Self {
|
||||||
active,
|
active,
|
||||||
hovered,
|
hovered,
|
||||||
|
@ -472,6 +551,8 @@ impl Widgets {
|
||||||
ui.label("The style of a widget as you are clicking or dragging it.");
|
ui.label("The style of a widget as you are clicking or dragging it.");
|
||||||
active.ui(ui)
|
active.ui(ui)
|
||||||
});
|
});
|
||||||
|
|
||||||
|
ui.vertical_centered(|ui| reset_button(ui, self));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -503,14 +584,47 @@ impl WidgetVisuals {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Visuals {
|
impl Visuals {
|
||||||
pub fn ui(&mut self, ui: &mut crate::Ui) {
|
/// Show radio-buttons to switch between light and dark mode.
|
||||||
crate::reset_button(ui, self);
|
pub fn light_dark_radio_buttons(&mut self, ui: &mut crate::Ui) {
|
||||||
|
ui.group(|ui| {
|
||||||
|
ui.horizontal(|ui| {
|
||||||
|
ui.radio_value(self, Self::light(), "☀ Light");
|
||||||
|
ui.radio_value(self, Self::dark(), "🌙 Dark");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Show small toggle-button for light and dark mode.
|
||||||
|
#[must_use]
|
||||||
|
pub fn light_dark_small_toggle_button(&self, ui: &mut crate::Ui) -> Option<Self> {
|
||||||
|
#![allow(clippy::collapsible_if)]
|
||||||
|
if self.dark_mode {
|
||||||
|
if ui
|
||||||
|
.add(Button::new("☀").frame(false))
|
||||||
|
.on_hover_text("Switch to light mode")
|
||||||
|
.clicked()
|
||||||
|
{
|
||||||
|
return Some(Self::light());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if ui
|
||||||
|
.add(Button::new("🌙").frame(false))
|
||||||
|
.on_hover_text("Switch to dark mode")
|
||||||
|
.clicked()
|
||||||
|
{
|
||||||
|
return Some(Self::dark());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn ui(&mut self, ui: &mut crate::Ui) {
|
||||||
let Self {
|
let Self {
|
||||||
|
dark_mode: _,
|
||||||
override_text_color: _,
|
override_text_color: _,
|
||||||
widgets,
|
widgets,
|
||||||
selection,
|
selection,
|
||||||
dark_bg_color,
|
extreme_bg_color,
|
||||||
hyperlink_color,
|
hyperlink_color,
|
||||||
code_bg_color,
|
code_bg_color,
|
||||||
window_corner_radius,
|
window_corner_radius,
|
||||||
|
@ -525,25 +639,42 @@ impl Visuals {
|
||||||
|
|
||||||
ui.collapsing("widgets", |ui| widgets.ui(ui));
|
ui.collapsing("widgets", |ui| widgets.ui(ui));
|
||||||
ui.collapsing("selection", |ui| selection.ui(ui));
|
ui.collapsing("selection", |ui| selection.ui(ui));
|
||||||
ui_color(ui, dark_bg_color, "dark_bg_color");
|
|
||||||
|
ui.group(|ui| {
|
||||||
|
ui.label("Window");
|
||||||
|
// Common shortcuts
|
||||||
|
ui_color(ui, &mut widgets.noninteractive.bg_fill, "Fill");
|
||||||
|
stroke_ui(ui, &mut widgets.noninteractive.bg_stroke, "Outline");
|
||||||
|
ui.add(Slider::f32(window_corner_radius, 0.0..=20.0).text("Corner Radius"));
|
||||||
|
shadow_ui(ui, window_shadow, "Shadow");
|
||||||
|
});
|
||||||
|
ui_color(
|
||||||
|
ui,
|
||||||
|
&mut widgets.noninteractive.fg_stroke.color,
|
||||||
|
"Text color",
|
||||||
|
);
|
||||||
|
|
||||||
|
ui_color(ui, extreme_bg_color, "extreme_bg_color");
|
||||||
ui_color(ui, hyperlink_color, "hyperlink_color");
|
ui_color(ui, hyperlink_color, "hyperlink_color");
|
||||||
ui_color(ui, code_bg_color, "code_bg_color");
|
ui_color(ui, code_bg_color, "code_bg_color");
|
||||||
ui.add(Slider::f32(window_corner_radius, 0.0..=20.0).text("window_corner_radius"));
|
|
||||||
shadow_ui(ui, window_shadow, "Window shadow:");
|
|
||||||
ui.add(Slider::f32(resize_corner_size, 0.0..=20.0).text("resize_corner_size"));
|
ui.add(Slider::f32(resize_corner_size, 0.0..=20.0).text("resize_corner_size"));
|
||||||
ui.add(Slider::f32(text_cursor_width, 0.0..=2.0).text("text_cursor_width"));
|
ui.add(Slider::f32(text_cursor_width, 0.0..=2.0).text("text_cursor_width"));
|
||||||
ui.add(Slider::f32(clip_rect_margin, 0.0..=20.0).text("clip_rect_margin"));
|
ui.add(Slider::f32(clip_rect_margin, 0.0..=20.0).text("clip_rect_margin"));
|
||||||
|
|
||||||
ui.label("DEBUG:");
|
ui.group(|ui| {
|
||||||
ui.checkbox(
|
ui.label("DEBUG:");
|
||||||
debug_expand_width,
|
ui.checkbox(
|
||||||
"Show which widgets make their parent wider",
|
debug_expand_width,
|
||||||
);
|
"Show which widgets make their parent wider",
|
||||||
ui.checkbox(
|
);
|
||||||
debug_expand_height,
|
ui.checkbox(
|
||||||
"Show which widgets make their parent higher",
|
debug_expand_height,
|
||||||
);
|
"Show which widgets make their parent higher",
|
||||||
ui.checkbox(debug_resize, "Debug Resize");
|
);
|
||||||
|
ui.checkbox(debug_resize, "Debug Resize");
|
||||||
|
});
|
||||||
|
|
||||||
|
ui.vertical_centered(|ui| reset_button(ui, self));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// #![warn(missing_docs)]
|
// #![warn(missing_docs)]
|
||||||
|
|
||||||
use std::{hash::Hash, sync::Arc};
|
use std::hash::Hash;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
color::*, containers::*, layout::*, mutex::MutexGuard, paint::text::Fonts, placer::Placer,
|
color::*, containers::*, layout::*, mutex::MutexGuard, paint::text::Fonts, placer::Placer,
|
||||||
|
@ -42,7 +42,7 @@ pub struct Ui {
|
||||||
/// The `Style` (visuals, spacing, etc) of this ui.
|
/// The `Style` (visuals, spacing, etc) of this ui.
|
||||||
/// Commonly many `Ui`:s share the same `Style`.
|
/// Commonly many `Ui`:s share the same `Style`.
|
||||||
/// The `Ui` implements copy-on-write for this.
|
/// The `Ui` implements copy-on-write for this.
|
||||||
style: Arc<Style>,
|
style: std::sync::Arc<Style>,
|
||||||
|
|
||||||
/// Handles the `Ui` size and the placement of new widgets.
|
/// Handles the `Ui` size and the placement of new widgets.
|
||||||
placer: Placer,
|
placer: Placer,
|
||||||
|
@ -93,18 +93,18 @@ impl Ui {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Style options for this `Ui` and its children.
|
/// Style options for this `Ui` and its children.
|
||||||
pub fn style(&self) -> &Style {
|
pub fn style(&self) -> &std::sync::Arc<Style> {
|
||||||
&self.style
|
&self.style
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Mutably borrow internal `Style`.
|
/// Mutably borrow internal `Style`.
|
||||||
/// Changes apply to this `Ui` and its subsequent children.
|
/// Changes apply to this `Ui` and its subsequent children.
|
||||||
pub fn style_mut(&mut self) -> &mut Style {
|
pub fn style_mut(&mut self) -> &mut Style {
|
||||||
Arc::make_mut(&mut self.style) // clone-on-write
|
std::sync::Arc::make_mut(&mut self.style) // clone-on-write
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Changes apply to this `Ui` and its subsequent children.
|
/// Changes apply to this `Ui` and its subsequent children.
|
||||||
pub fn set_style(&mut self, style: impl Into<Arc<Style>>) {
|
pub fn set_style(&mut self, style: impl Into<std::sync::Arc<Style>>) {
|
||||||
self.style = style.into();
|
self.style = style.into();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -306,7 +306,7 @@ impl<'a> Slider<'a> {
|
||||||
|
|
||||||
fill: ui.visuals().widgets.inactive.bg_fill,
|
fill: ui.visuals().widgets.inactive.bg_fill,
|
||||||
// fill: visuals.bg_fill,
|
// fill: visuals.bg_fill,
|
||||||
// fill: ui.visuals().dark_bg_color,
|
// fill: ui.visuals().extreme_bg_color,
|
||||||
stroke: Default::default(),
|
stroke: Default::default(),
|
||||||
// stroke: visuals.bg_stroke,
|
// stroke: visuals.bg_stroke,
|
||||||
// stroke: ui.visuals().widgets.inactive.bg_stroke,
|
// stroke: ui.visuals().widgets.inactive.bg_stroke,
|
||||||
|
|
|
@ -245,14 +245,14 @@ impl<'t> Widget for TextEdit<'t> {
|
||||||
rect: frame_rect,
|
rect: frame_rect,
|
||||||
corner_radius: visuals.corner_radius,
|
corner_radius: visuals.corner_radius,
|
||||||
// fill: ui.visuals().selection.bg_fill,
|
// fill: ui.visuals().selection.bg_fill,
|
||||||
fill: ui.visuals().dark_bg_color,
|
fill: ui.visuals().extreme_bg_color,
|
||||||
stroke: ui.visuals().selection.stroke,
|
stroke: ui.visuals().selection.stroke,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Shape::Rect {
|
Shape::Rect {
|
||||||
rect: frame_rect,
|
rect: frame_rect,
|
||||||
corner_radius: visuals.corner_radius,
|
corner_radius: visuals.corner_radius,
|
||||||
fill: ui.visuals().dark_bg_color,
|
fill: ui.visuals().extreme_bg_color,
|
||||||
stroke: visuals.bg_stroke, // TODO: we want to show something here, or a text-edit field doesn't "pop".
|
stroke: visuals.bg_stroke, // TODO: we want to show something here, or a text-edit field doesn't "pop".
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -101,6 +101,13 @@ impl DemoWindows {
|
||||||
show_menu_bar(ui);
|
show_menu_bar(ui);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Just get a background to put the windows on instead of using whatever the clear color is
|
||||||
|
let frame = egui::Frame {
|
||||||
|
fill: ctx.style().visuals.extreme_bg_color,
|
||||||
|
..egui::Frame::none()
|
||||||
|
};
|
||||||
|
egui::CentralPanel::default().frame(frame).show(ctx, |_| {});
|
||||||
|
|
||||||
self.windows(ctx);
|
self.windows(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -59,7 +59,6 @@ impl FractalClock {
|
||||||
ui.expand_to_include_rect(painter.clip_rect());
|
ui.expand_to_include_rect(painter.clip_rect());
|
||||||
|
|
||||||
Frame::popup(ui.style())
|
Frame::popup(ui.style())
|
||||||
.fill(Rgba::from_luminance_alpha(0.02, 0.5).into())
|
|
||||||
.stroke(Stroke::none())
|
.stroke(Stroke::none())
|
||||||
.show(ui, |ui| {
|
.show(ui, |ui| {
|
||||||
ui.set_max_width(270.0);
|
ui.set_max_width(270.0);
|
||||||
|
|
|
@ -72,12 +72,13 @@ impl FrameHistory {
|
||||||
let mut shapes = vec![Shape::Rect {
|
let mut shapes = vec![Shape::Rect {
|
||||||
rect,
|
rect,
|
||||||
corner_radius: style.corner_radius,
|
corner_radius: style.corner_radius,
|
||||||
fill: ui.visuals().dark_bg_color,
|
fill: ui.visuals().extreme_bg_color,
|
||||||
stroke: ui.style().noninteractive().bg_stroke,
|
stroke: ui.style().noninteractive().bg_stroke,
|
||||||
}];
|
}];
|
||||||
|
|
||||||
let rect = rect.shrink(4.0);
|
let rect = rect.shrink(4.0);
|
||||||
let line_stroke = Stroke::new(1.0, Color32::from_additive_luminance(128));
|
let color = ui.visuals().text_color();
|
||||||
|
let line_stroke = Stroke::new(1.0, color);
|
||||||
|
|
||||||
if let Some(pointer_pos) = ui.input().pointer.tooltip_pos() {
|
if let Some(pointer_pos) = ui.input().pointer.tooltip_pos() {
|
||||||
if rect.contains(pointer_pos) {
|
if rect.contains(pointer_pos) {
|
||||||
|
@ -94,12 +95,12 @@ impl FrameHistory {
|
||||||
egui::Align2::LEFT_BOTTOM,
|
egui::Align2::LEFT_BOTTOM,
|
||||||
text,
|
text,
|
||||||
TextStyle::Monospace,
|
TextStyle::Monospace,
|
||||||
Color32::WHITE,
|
color,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let circle_color = Color32::from_additive_luminance(196);
|
let circle_color = color;
|
||||||
let radius = 2.0;
|
let radius = 2.0;
|
||||||
let right_side_time = ui.input().time; // Time at right side of screen
|
let right_side_time = ui.input().time; // Time at right side of screen
|
||||||
|
|
||||||
|
|
|
@ -69,6 +69,8 @@ impl epi::App for WrapApp {
|
||||||
// A menu-bar is a horizontal layout with some special styles applied.
|
// A menu-bar is a horizontal layout with some special styles applied.
|
||||||
// egui::menu::bar(ui, |ui| {
|
// egui::menu::bar(ui, |ui| {
|
||||||
ui.horizontal_wrapped(|ui| {
|
ui.horizontal_wrapped(|ui| {
|
||||||
|
dark_light_mode_switch(ui);
|
||||||
|
|
||||||
ui.checkbox(&mut self.backend_panel.open, "💻 Backend");
|
ui.checkbox(&mut self.backend_panel.open, "💻 Backend");
|
||||||
ui.separator();
|
ui.separator();
|
||||||
|
|
||||||
|
@ -130,6 +132,15 @@ fn clock_button(ui: &mut egui::Ui, seconds_since_midnight: f64) -> egui::Respons
|
||||||
ui.add(egui::Button::new(time).text_style(egui::TextStyle::Monospace))
|
ui.add(egui::Button::new(time).text_style(egui::TextStyle::Monospace))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Show a button to switch to/from dark/light mode (globally).
|
||||||
|
fn dark_light_mode_switch(ui: &mut egui::Ui) {
|
||||||
|
let style: egui::Style = (*ui.ctx().style()).clone();
|
||||||
|
let new_visuals = style.visuals.light_dark_small_toggle_button(ui);
|
||||||
|
if let Some(visuals) = new_visuals {
|
||||||
|
ui.ctx().set_style(egui::Style { visuals, ..style });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
/// How often we repaint the demo app by default
|
/// How often we repaint the demo app by default
|
||||||
|
|
|
@ -22,14 +22,22 @@ impl Shadow {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Windows
|
/// Subtle and nice on dark backgrounds
|
||||||
pub fn big() -> Self {
|
pub fn big_dark() -> Self {
|
||||||
Self {
|
Self {
|
||||||
extrusion: 32.0,
|
extrusion: 32.0,
|
||||||
color: Color32::from_black_alpha(96),
|
color: Color32::from_black_alpha(96),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Subtle and nice on white backgrounds
|
||||||
|
pub fn big_light() -> Self {
|
||||||
|
Self {
|
||||||
|
extrusion: 32.0,
|
||||||
|
color: Color32::from_black_alpha(40),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn tessellate(&self, rect: emath::Rect, corner_radius: f32) -> Mesh {
|
pub fn tessellate(&self, rect: emath::Rect, corner_radius: f32) -> Mesh {
|
||||||
// tessellator.clip_rect = clip_rect; // TODO: culling
|
// tessellator.clip_rect = clip_rect; // TODO: culling
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue