Skip to content

Commit 4fc3396

Browse files
authored
Merge pull request #34 from dmackdev/refactor-style
Refactor `JsonTreeStyle`
2 parents 587e99b + b1ac2aa commit 4fc3396

File tree

10 files changed

+89
-76
lines changed

10 files changed

+89
-76
lines changed

README.md

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -28,16 +28,16 @@ JsonTree::new("simple-tree", &value).show(ui);
2828

2929
// Customised:
3030
let response = JsonTree::new("customised-tree", &value)
31-
.style(JsonTreeStyle {
32-
visuals: Some(JsonTreeVisuals {
33-
bool_color: Color32::YELLOW,
34-
..Default::default()
35-
}),
36-
..Default::default()
37-
})
31+
.style(
32+
JsonTreeStyle::new()
33+
.abbreviate_root(true) // Show {...} when the root object is collapsed.
34+
.toggle_buttons_state(ToggleButtonsState::VisibleDisabled)
35+
.visuals(JsonTreeVisuals {
36+
bool_color: Color32::YELLOW,
37+
..Default::default()
38+
}),
39+
)
3840
.default_expand(DefaultExpand::All)
39-
.abbreviate_root(true) // Show {...} when the root object is collapsed.
40-
.toggle_buttons_state(ToggleButtonsState::VisibleDisabled)
4141
.on_render(|ui, ctx| {
4242
// Customise rendering of the JsonTree, and/or handle interactions.
4343
match ctx {

examples/demo/src/apps/editor.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use egui_json_tree::{
1111
DefaultRender, RenderBaseValueContext, RenderContext, RenderExpandableDelimiterContext,
1212
RenderPropertyContext,
1313
},
14-
DefaultExpand, JsonTree,
14+
DefaultExpand, JsonTree, JsonTreeStyle,
1515
};
1616
use serde_json::Value;
1717

@@ -437,8 +437,8 @@ impl Show for JsonEditorExample {
437437
ui.add_space(10.0);
438438

439439
JsonTree::new(self.title(), &self.value)
440-
.abbreviate_root(true)
441440
.default_expand(DefaultExpand::All)
441+
.style(JsonTreeStyle::new().abbreviate_root(true))
442442
.on_render(|ui, context| self.editor.show(ui, &self.value, context))
443443
.show(ui);
444444

examples/demo/src/apps/toggle_buttons.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use egui::Ui;
2-
use egui_json_tree::{DefaultExpand, JsonTree, ToggleButtonsState};
2+
use egui_json_tree::{DefaultExpand, JsonTree, JsonTreeStyle, ToggleButtonsState};
33
use serde_json::Value;
44

55
use super::Show;
@@ -49,7 +49,7 @@ impl Show for ToggleButtonsCustomisationDemo {
4949

5050
JsonTree::new(self.title(), &self.value)
5151
.default_expand(DefaultExpand::All)
52-
.toggle_buttons_state(self.toggle_buttons_state)
52+
.style(JsonTreeStyle::new().toggle_buttons_state(self.toggle_buttons_state))
5353
.show(ui);
5454
});
5555
}

src/lib.rs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -23,16 +23,16 @@
2323
//!
2424
//! // Customised:
2525
//! let response = JsonTree::new("customised-tree", &value)
26-
//! .style(JsonTreeStyle {
27-
//! visuals: Some(JsonTreeVisuals {
28-
//! bool_color: Color32::YELLOW,
29-
//! ..Default::default()
30-
//! }),
31-
//! ..Default::default()
32-
//! })
26+
//! .style(
27+
//! JsonTreeStyle::new()
28+
//! .abbreviate_root(true) // Show {...} when the root object is collapsed.
29+
//! .toggle_buttons_state(ToggleButtonsState::VisibleDisabled)
30+
//! .visuals(JsonTreeVisuals {
31+
//! bool_color: Color32::YELLOW,
32+
//! ..Default::default()
33+
//! }),
34+
//! )
3335
//! .default_expand(DefaultExpand::All)
34-
//! .abbreviate_root(true) // Show {...} when the root object is collapsed.
35-
//! .toggle_buttons_state(ToggleButtonsState::VisibleDisabled)
3636
//! .on_render(|ui, ctx| {
3737
//! // Customise rendering of the JsonTree, and/or handle interactions.
3838
//! match ctx {

src/node.rs

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,12 @@ impl<'a, T: ToJsonTreeValue> JsonTreeNode<'a, T> {
4545
persistent_id.with(tree_id.with(path_segments))
4646
};
4747

48+
let style = config.style.unwrap_or_default();
49+
let default_expand = config.default_expand.unwrap_or_default();
50+
4851
let mut path_id_map = HashMap::new();
4952

50-
let (default_expand, search_term) = match config.default_expand {
53+
let (default_expand, search_term) = match default_expand {
5154
DefaultExpand::All => (InnerExpand::All, None),
5255
DefaultExpand::None => (InnerExpand::None, None),
5356
DefaultExpand::ToLevel(l) => (InnerExpand::ToLevel(l), None),
@@ -58,7 +61,7 @@ impl<'a, T: ToJsonTreeValue> JsonTreeNode<'a, T> {
5861
let paths = search_term
5962
.as_ref()
6063
.map(|search_term| {
61-
search_term.find_matching_paths_in(self.value, config.abbreviate_root)
64+
search_term.find_matching_paths_in(self.value, style.abbreviate_root)
6265
})
6366
.unwrap_or_default();
6467
(InnerExpand::Paths(paths), search_term)
@@ -69,17 +72,15 @@ impl<'a, T: ToJsonTreeValue> JsonTreeNode<'a, T> {
6972

7073
let node_config = JsonTreeNodeConfig {
7174
default_expand,
72-
abbreviate_root: config.abbreviate_root,
73-
style: config.style,
75+
style,
7476
search_term,
75-
toggle_buttons_state: config.toggle_buttons_state,
7677
};
7778

7879
// Wrap in a vertical layout in case this tree is placed directly in a horizontal layout,
7980
// which does not allow indent layouts as direct children.
8081
ui.vertical(|ui| {
8182
// Centres the collapsing header icon.
82-
ui.spacing_mut().interact_size.y = node_config.style.font_id(ui).size;
83+
ui.spacing_mut().interact_size.y = node_config.style.resolve_font_id(ui).size;
8384

8485
self.show_impl(
8586
ui,
@@ -176,10 +177,8 @@ fn show_expandable<'a, 'b, T: ToJsonTreeValue>(
176177
) {
177178
let JsonTreeNodeConfig {
178179
default_expand,
179-
abbreviate_root,
180180
style,
181181
search_term,
182-
toggle_buttons_state,
183182
} = config;
184183

185184
let delimiters = match expandable.expandable_type {
@@ -204,14 +203,14 @@ fn show_expandable<'a, 'b, T: ToJsonTreeValue>(
204203
let header_res = ui.horizontal_wrapped(|ui| {
205204
ui.spacing_mut().item_spacing.x = 0.0;
206205

207-
if let Some(enabled) = toggle_buttons_state.enabled() {
206+
if let Some(enabled) = style.toggle_buttons_state.enabled() {
208207
ui.add_enabled_ui(enabled, |ui| {
209208
state.show_toggle_button(ui, paint_default_icon)
210209
});
211210
}
212211

213212
if path_segments.is_empty() && !is_expanded {
214-
if *abbreviate_root {
213+
if style.abbreviate_root {
215214
renderer.render_expandable_delimiter(
216215
ui,
217216
RenderExpandableDelimiterContext {
@@ -381,7 +380,7 @@ fn show_expandable<'a, 'b, T: ToJsonTreeValue>(
381380
}
382381
});
383382

384-
let toggle_buttons_hidden = *toggle_buttons_state == ToggleButtonsState::Hidden;
383+
let toggle_buttons_hidden = style.toggle_buttons_state == ToggleButtonsState::Hidden;
385384
if toggle_buttons_hidden {
386385
ui.visuals_mut().indent_has_left_vline = true;
387386
ui.spacing_mut().indent = (ui.spacing().icon_width + ui.spacing().icon_spacing) / 2.0;
@@ -450,10 +449,8 @@ fn show_expandable<'a, 'b, T: ToJsonTreeValue>(
450449

451450
struct JsonTreeNodeConfig<'a> {
452451
default_expand: InnerExpand<'a>,
453-
abbreviate_root: bool,
454452
style: JsonTreeStyle,
455453
search_term: Option<SearchTerm>,
456-
toggle_buttons_state: ToggleButtonsState,
457454
}
458455

459456
#[derive(Debug, Clone)]

src/render.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -279,11 +279,11 @@ fn render_value(
279279
) -> Response {
280280
let job = ui.ctx().memory_mut(|mem| {
281281
mem.caches.cache::<ValueLayoutJobCreatorCache>().get((
282-
style.visuals(ui),
282+
style.resolve_visuals(ui),
283283
value_str,
284284
value_type,
285285
search_term,
286-
&style.font_id(ui),
286+
&style.resolve_font_id(ui),
287287
))
288288
});
289289

@@ -356,10 +356,10 @@ fn render_property(
356356
) -> Response {
357357
let job = ui.ctx().memory_mut(|mem| {
358358
mem.caches.cache::<PropertyLayoutJobCreatorCache>().get((
359-
style.visuals(ui),
359+
style.resolve_visuals(ui),
360360
property,
361361
search_term,
362-
&style.font_id(ui),
362+
&style.resolve_font_id(ui),
363363
))
364364
});
365365

@@ -442,9 +442,9 @@ fn render_delimiter(ui: &mut Ui, style: &JsonTreeStyle, delimiter_str: &str) ->
442442
append(
443443
&mut job,
444444
delimiter_str,
445-
style.visuals(ui).punctuation_color,
445+
style.resolve_visuals(ui).punctuation_color,
446446
None,
447-
&style.font_id(ui),
447+
&style.resolve_font_id(ui),
448448
);
449449
render_job(ui, job)
450450
}

src/style.rs

Lines changed: 41 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,54 @@
11
use egui::{Color32, FontId, TextStyle, Ui};
22

3-
use crate::value::BaseValueType;
3+
use crate::{value::BaseValueType, ToggleButtonsState};
44

55
/// Styling configuration to control the appearance of the [`JsonTree`](crate::JsonTree).
66
#[derive(Debug, Clone, Hash, Default)]
77
pub struct JsonTreeStyle {
8-
/// The colors to use. If not set, defaults to either a dark or light color scheme, depending on [`egui::Visuals::dark_mode`].
98
pub visuals: Option<JsonTreeVisuals>,
10-
/// The font to use. If not set, defaults to `TextStyle::Monospace.resolve(ui.style())`.
119
pub font_id: Option<FontId>,
10+
pub abbreviate_root: bool,
11+
pub toggle_buttons_state: ToggleButtonsState,
1212
}
1313

1414
impl JsonTreeStyle {
15+
pub fn new() -> Self {
16+
Self::default()
17+
}
18+
19+
/// The colors to use. Defaults to either a dark or light color scheme, depending on [`egui::Visuals::dark_mode`].
20+
pub fn visuals(mut self, visuals: JsonTreeVisuals) -> Self {
21+
self.visuals = Some(visuals);
22+
self
23+
}
24+
25+
/// The font to use. Defaults to `TextStyle::Monospace.resolve(ui.style())`.
26+
pub fn font_id(mut self, font_id: FontId) -> Self {
27+
self.font_id = Some(font_id);
28+
self
29+
}
30+
31+
/// Override whether a root array/object should show direct child elements when collapsed.
32+
///
33+
/// If `true`, a collapsed root object would render as: `{...}`.
34+
///
35+
/// If `false`, a collapsed root object would render as: `{ "foo": "bar", "baz": {...} }`.
36+
///
37+
/// Defaults to `false`.
38+
pub fn abbreviate_root(mut self, abbreviate_root: bool) -> Self {
39+
self.abbreviate_root = abbreviate_root;
40+
self
41+
}
42+
43+
/// Override the visibility and interactivity of the toggle buttons for expanding/collapsing objects and arrays.
44+
/// Defaults to [`ToggleButtonsState::VisibleEnabled`].
45+
pub fn toggle_buttons_state(mut self, toggle_buttons_state: ToggleButtonsState) -> Self {
46+
self.toggle_buttons_state = toggle_buttons_state;
47+
self
48+
}
49+
1550
/// Resolves the [`JsonTreeVisuals`] color scheme to use.
16-
pub fn visuals(&self, ui: &Ui) -> &JsonTreeVisuals {
51+
pub(crate) fn resolve_visuals(&self, ui: &Ui) -> &JsonTreeVisuals {
1752
if let Some(visuals) = &self.visuals {
1853
visuals
1954
} else if ui.visuals().dark_mode {
@@ -23,7 +58,8 @@ impl JsonTreeStyle {
2358
}
2459
}
2560

26-
pub(crate) fn font_id(&self, ui: &Ui) -> FontId {
61+
/// Resolves the [`FontId`] to use.
62+
pub(crate) fn resolve_font_id(&self, ui: &Ui) -> FontId {
2763
if let Some(font_id) = &self.font_id {
2864
font_id.clone()
2965
} else {

src/toggle_buttons_state.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/// Setting for the visibility and interactivity of the toggle buttons for expanding/collapsing objects and arrays.
2-
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
2+
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
33
pub enum ToggleButtonsState {
44
#[default]
55
VisibleEnabled,

src/tree.rs

Lines changed: 5 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -2,27 +2,23 @@ use crate::{
22
node::JsonTreeNode,
33
render::{JsonTreeRenderer, RenderContext},
44
value::ToJsonTreeValue,
5-
DefaultExpand, JsonTreeResponse, JsonTreeStyle, ToggleButtonsState,
5+
DefaultExpand, JsonTreeResponse, JsonTreeStyle,
66
};
77
use egui::{Id, Ui};
88
use std::hash::Hash;
99

1010
pub(crate) struct JsonTreeConfig<'a, T: ToJsonTreeValue> {
11-
pub(crate) style: JsonTreeStyle,
12-
pub(crate) default_expand: DefaultExpand<'a>,
13-
pub(crate) abbreviate_root: bool,
11+
pub(crate) style: Option<JsonTreeStyle>,
12+
pub(crate) default_expand: Option<DefaultExpand<'a>>,
1413
pub(crate) renderer: JsonTreeRenderer<'a, T>,
15-
pub(crate) toggle_buttons_state: ToggleButtonsState,
1614
}
1715

1816
impl<'a, T: ToJsonTreeValue> Default for JsonTreeConfig<'a, T> {
1917
fn default() -> Self {
2018
Self {
2119
style: Default::default(),
2220
default_expand: Default::default(),
23-
abbreviate_root: Default::default(),
2421
renderer: Default::default(),
25-
toggle_buttons_state: Default::default(),
2622
}
2723
}
2824
}
@@ -48,13 +44,13 @@ impl<'a, T: ToJsonTreeValue> JsonTree<'a, T> {
4844

4945
/// Override colors for JSON syntax highlighting, and search match highlighting.
5046
pub fn style(mut self, style: JsonTreeStyle) -> Self {
51-
self.config.style = style;
47+
self.config.style = Some(style);
5248
self
5349
}
5450

5551
/// Override how the [`JsonTree`] expands arrays/objects by default.
5652
pub fn default_expand(mut self, default_expand: DefaultExpand<'a>) -> Self {
57-
self.config.default_expand = default_expand;
53+
self.config.default_expand = Some(default_expand);
5854
self
5955
}
6056

@@ -97,22 +93,6 @@ impl<'a, T: ToJsonTreeValue> JsonTree<'a, T> {
9793
self
9894
}
9995

100-
/// Override whether a root array/object should show direct child elements when collapsed.
101-
///
102-
/// If called with `true`, a collapsed root object would render as: `{...}`.
103-
///
104-
/// Otherwise, a collapsed root object would render as: `{ "foo": "bar", "baz": {...} }`.
105-
pub fn abbreviate_root(mut self, abbreviate_root: bool) -> Self {
106-
self.config.abbreviate_root = abbreviate_root;
107-
self
108-
}
109-
110-
/// Override the visibility and interactivity of the toggle buttons for expanding/collapsing objects and arrays.
111-
pub fn toggle_buttons_state(mut self, toggle_buttons_state: ToggleButtonsState) -> Self {
112-
self.config.toggle_buttons_state = toggle_buttons_state;
113-
self
114-
}
115-
11696
/// Show the JSON tree visualisation within the `Ui`.
11797
pub fn show(self, ui: &mut Ui) -> JsonTreeResponse {
11898
JsonTreeNode::new(self.id, self.value).show_with_config(ui, self.config)

tests/json_tree_test.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use std::sync::Arc;
22

33
use egui::{mutex::Mutex, CentralPanel, Context, FontDefinitions, Style};
4-
use egui_json_tree::{render::RenderContext, DefaultExpand, JsonTree};
4+
use egui_json_tree::{render::RenderContext, DefaultExpand, JsonTree, JsonTreeStyle};
55
#[cfg(feature = "serde_json")]
66
use serde_json::{json, Value};
77

@@ -541,7 +541,7 @@ fn json_tree_reset_expanded() {
541541
CentralPanel::default().show(ctx, |ui| {
542542
JsonTree::new(id, &value)
543543
.default_expand(DefaultExpand::All)
544-
.abbreviate_root(true)
544+
.style(JsonTreeStyle::new().abbreviate_root(true))
545545
.on_render(|_, render_ctx| {
546546
actual.push(render_ctx.into());
547547
})
@@ -561,7 +561,7 @@ fn json_tree_reset_expanded() {
561561
CentralPanel::default().show(ctx, |ui| {
562562
JsonTree::new(id, &value)
563563
.default_expand(DefaultExpand::None)
564-
.abbreviate_root(true)
564+
.style(JsonTreeStyle::new().abbreviate_root(true))
565565
.on_render(|_, render_ctx| {
566566
actual.push(render_ctx.into());
567567
})
@@ -581,7 +581,7 @@ fn json_tree_reset_expanded() {
581581
CentralPanel::default().show(ctx, |ui| {
582582
JsonTree::new(id, &value)
583583
.default_expand(DefaultExpand::None)
584-
.abbreviate_root(true)
584+
.style(JsonTreeStyle::new().abbreviate_root(true))
585585
.on_render(|_, render_ctx| {
586586
actual.push(render_ctx.into());
587587
})

0 commit comments

Comments
 (0)