From 6d21f45bf2aca5140d2427d5f178dda0c7b42d62 Mon Sep 17 00:00:00 2001 From: dmackdev Date: Fri, 20 Sep 2024 19:10:33 +0100 Subject: [PATCH 1/5] explicitly paint the `CollapsingState` toggle icon, so it can be overriden --- src/node.rs | 355 ++++++++++++++++++++++++++-------------------------- 1 file changed, 178 insertions(+), 177 deletions(-) diff --git a/src/node.rs b/src/node.rs index d14b13a..e707055 100644 --- a/src/node.rs +++ b/src/node.rs @@ -1,6 +1,9 @@ use std::collections::{HashMap, HashSet}; -use egui::{collapsing_header::CollapsingState, Id, Ui}; +use egui::{ + collapsing_header::{paint_default_icon, CollapsingState}, + Id, Ui, +}; use crate::{ delimiters::{SpacingDelimiter, ARRAY_DELIMITERS, OBJECT_DELIMITERS}, @@ -193,223 +196,221 @@ fn show_expandable<'a, 'b, T: ToJsonTreeValue>( .entry(path_segments.to_vec()) .or_insert_with(|| make_persistent_id(path_segments)); - let state = CollapsingState::load_with_default_open(ui.ctx(), id_source, default_open); + let mut state = CollapsingState::load_with_default_open(ui.ctx(), id_source, default_open); let is_expanded = state.is_open(); - state - .show_header(ui, |ui| { - ui.horizontal_wrapped(|ui| { - ui.spacing_mut().item_spacing.x = 0.0; + let header_res = ui.horizontal_wrapped(|ui| { + ui.spacing_mut().item_spacing.x = 0.0; + state.show_toggle_button(ui, paint_default_icon); - if path_segments.is_empty() && !is_expanded { - if *abbreviate_root { - renderer.render_expandable_delimiter( - ui, - RenderExpandableDelimiterContext { - delimiter: delimiters.collapsed, - value: expandable.value, - pointer: JsonPointer(path_segments), - style, - }, - ); - return; - } + if path_segments.is_empty() && !is_expanded { + if *abbreviate_root { + renderer.render_expandable_delimiter( + ui, + RenderExpandableDelimiterContext { + delimiter: delimiters.collapsed, + value: expandable.value, + pointer: JsonPointer(path_segments), + style, + }, + ); + return; + } + + renderer.render_expandable_delimiter( + ui, + RenderExpandableDelimiterContext { + delimiter: delimiters.opening, + value: expandable.value, + pointer: JsonPointer(path_segments), + style, + }, + ); + renderer.render_spacing_delimiter( + ui, + RenderSpacingDelimiterContext { + delimiter: SpacingDelimiter::Empty, + style, + }, + ); + + let entries_len = expandable.entries.len(); + + for (idx, (property, elem)) in expandable.entries.iter().enumerate() { + path_segments.push(*property); - renderer.render_expandable_delimiter( + // Don't show array indices when the array is collapsed. + if matches!(expandable.expandable_type, ExpandableType::Object) { + renderer.render_property( ui, - RenderExpandableDelimiterContext { - delimiter: delimiters.opening, - value: expandable.value, + RenderPropertyContext { + property: *property, + value: elem, pointer: JsonPointer(path_segments), style, + search_term: search_term.as_ref(), }, ); renderer.render_spacing_delimiter( ui, RenderSpacingDelimiterContext { - delimiter: SpacingDelimiter::Empty, + delimiter: SpacingDelimiter::Colon, style, }, ); + } - let entries_len = expandable.entries.len(); - - for (idx, (property, elem)) in expandable.entries.iter().enumerate() { - path_segments.push(*property); - - // Don't show array indices when the array is collapsed. - if matches!(expandable.expandable_type, ExpandableType::Object) { - renderer.render_property( - ui, - RenderPropertyContext { - property: *property, - value: elem, - pointer: JsonPointer(path_segments), - style, - search_term: search_term.as_ref(), - }, - ); - renderer.render_spacing_delimiter( - ui, - RenderSpacingDelimiterContext { - delimiter: SpacingDelimiter::Colon, - style, - }, - ); - } - - match elem.to_json_tree_value() { - JsonTreeValue::Base(value, display_value, value_type) => { - renderer.render_value( - ui, - RenderBaseValueContext { - value, - display_value, - value_type, - pointer: JsonPointer(path_segments), - style, - search_term: search_term.as_ref(), - }, - ); - } - JsonTreeValue::Expandable(entries, expandable_type) => { - let nested_delimiters = match expandable_type { - ExpandableType::Array => &ARRAY_DELIMITERS, - ExpandableType::Object => &OBJECT_DELIMITERS, - }; - - let delimiter = if entries.is_empty() { - nested_delimiters.collapsed_empty - } else { - nested_delimiters.collapsed - }; - - renderer.render_expandable_delimiter( - ui, - RenderExpandableDelimiterContext { - delimiter, - value: elem, - pointer: JsonPointer(path_segments), - style, - }, - ); - } - }; - - let spacing = if idx == entries_len - 1 { - SpacingDelimiter::Empty - } else { - SpacingDelimiter::Comma - }; - - renderer.render_spacing_delimiter( - ui, - RenderSpacingDelimiterContext { - delimiter: spacing, - style, - }, - ); - - path_segments.pop(); - } - - renderer.render_expandable_delimiter( - ui, - RenderExpandableDelimiterContext { - delimiter: delimiters.closing, - value: expandable.value, - pointer: JsonPointer(path_segments), - style, - }, - ); - } else { - if let Some(property) = expandable.parent { - renderer.render_property( + match elem.to_json_tree_value() { + JsonTreeValue::Base(value, display_value, value_type) => { + renderer.render_value( ui, - RenderPropertyContext { - property, - value: expandable.value, + RenderBaseValueContext { + value, + display_value, + value_type, pointer: JsonPointer(path_segments), style, - search_term: config.search_term.as_ref(), - }, - ); - renderer.render_spacing_delimiter( - ui, - RenderSpacingDelimiterContext { - delimiter: SpacingDelimiter::Colon, - style, + search_term: search_term.as_ref(), }, ); } + JsonTreeValue::Expandable(entries, expandable_type) => { + let nested_delimiters = match expandable_type { + ExpandableType::Array => &ARRAY_DELIMITERS, + ExpandableType::Object => &OBJECT_DELIMITERS, + }; - if is_expanded { - renderer.render_expandable_delimiter( - ui, - RenderExpandableDelimiterContext { - delimiter: delimiters.opening, - value: expandable.value, - pointer: JsonPointer(path_segments), - style, - }, - ); - } else { - let delimiter = if expandable.entries.is_empty() { - delimiters.collapsed_empty + let delimiter = if entries.is_empty() { + nested_delimiters.collapsed_empty } else { - delimiters.collapsed + nested_delimiters.collapsed }; + renderer.render_expandable_delimiter( ui, RenderExpandableDelimiterContext { delimiter, - value: expandable.value, + value: elem, pointer: JsonPointer(path_segments), style, }, ); } - } - }); - }) - .body(|ui| { - for (property, elem) in expandable.entries { - let is_expandable = elem.is_expandable(); - - path_segments.push(property); - - let mut add_nested_tree = |ui: &mut Ui| { - let nested_tree = JsonTreeNode { - id: expandable.id, - value: elem, - parent: Some(property), - }; - - nested_tree.show_impl( - ui, - path_segments, - path_id_map, - make_persistent_id, - config, - renderer, - ); }; - if is_expandable { - add_nested_tree(ui); + let spacing = if idx == entries_len - 1 { + SpacingDelimiter::Empty } else { - ui.scope(|ui| { - ui.visuals_mut().indent_has_left_vline = false; - ui.spacing_mut().indent = - ui.spacing().icon_width + ui.spacing().icon_spacing; + SpacingDelimiter::Comma + }; - ui.indent(id_source, add_nested_tree); - }); - } + renderer.render_spacing_delimiter( + ui, + RenderSpacingDelimiterContext { + delimiter: spacing, + style, + }, + ); path_segments.pop(); } - }); + + renderer.render_expandable_delimiter( + ui, + RenderExpandableDelimiterContext { + delimiter: delimiters.closing, + value: expandable.value, + pointer: JsonPointer(path_segments), + style, + }, + ); + } else { + if let Some(property) = expandable.parent { + renderer.render_property( + ui, + RenderPropertyContext { + property, + value: expandable.value, + pointer: JsonPointer(path_segments), + style, + search_term: config.search_term.as_ref(), + }, + ); + renderer.render_spacing_delimiter( + ui, + RenderSpacingDelimiterContext { + delimiter: SpacingDelimiter::Colon, + style, + }, + ); + } + + if is_expanded { + renderer.render_expandable_delimiter( + ui, + RenderExpandableDelimiterContext { + delimiter: delimiters.opening, + value: expandable.value, + pointer: JsonPointer(path_segments), + style, + }, + ); + } else { + let delimiter = if expandable.entries.is_empty() { + delimiters.collapsed_empty + } else { + delimiters.collapsed + }; + renderer.render_expandable_delimiter( + ui, + RenderExpandableDelimiterContext { + delimiter, + value: expandable.value, + pointer: JsonPointer(path_segments), + style, + }, + ); + } + } + }); + + state.show_body_indented(&header_res.response, ui, |ui| { + for (property, elem) in expandable.entries { + let is_expandable = elem.is_expandable(); + + path_segments.push(property); + + let mut add_nested_tree = |ui: &mut Ui| { + let nested_tree = JsonTreeNode { + id: expandable.id, + value: elem, + parent: Some(property), + }; + + nested_tree.show_impl( + ui, + path_segments, + path_id_map, + make_persistent_id, + config, + renderer, + ); + }; + + if is_expandable { + add_nested_tree(ui); + } else { + ui.scope(|ui| { + ui.visuals_mut().indent_has_left_vline = false; + ui.spacing_mut().indent = ui.spacing().icon_width + ui.spacing().icon_spacing; + + ui.indent(id_source, add_nested_tree); + }); + } + + path_segments.pop(); + } + }); if is_expanded { ui.horizontal_wrapped(|ui| { From 0336fbcd779eedd101ece1fab77031b3d33144d9 Mon Sep 17 00:00:00 2001 From: dmackdev Date: Fri, 27 Sep 2024 07:40:02 +0200 Subject: [PATCH 2/5] add `JsonTree` builder method to control toggle icon interactivity --- examples/demo.rs | 26 +++++++++++++++++++++++++- src/node.rs | 8 +++++++- src/tree.rs | 7 +++++++ 3 files changed, 39 insertions(+), 2 deletions(-) diff --git a/examples/demo.rs b/examples/demo.rs index 6a5c1a7..d375ec7 100644 --- a/examples/demo.rs +++ b/examples/demo.rs @@ -625,6 +625,29 @@ impl Show for JsonEditorExample { } } +struct NonInteractiveDemo { + value: Value, +} + +impl NonInteractiveDemo { + fn new(value: Value) -> Self { + Self { value } + } +} + +impl Show for NonInteractiveDemo { + fn title(&self) -> &'static str { + "Non Interactive" + } + + fn show(&mut self, ui: &mut Ui) { + JsonTree::new(self.title(), &self.value) + .default_expand(DefaultExpand::All) + .enable_icons(false) + .show(ui); + } +} + struct DemoApp { examples: Vec>, open_example_idx: Option, @@ -655,7 +678,8 @@ impl Default for DemoApp { Box::new(CustomExample::new("Custom Input")), Box::new(SearchExample::new(complex_object.clone())), Box::new(CopyToClipboardExample::new(complex_object.clone())), - Box::new(JsonEditorExample::new(complex_object)), + Box::new(JsonEditorExample::new(complex_object.clone())), + Box::new(NonInteractiveDemo::new(complex_object)), ], open_example_idx: None, } diff --git a/src/node.rs b/src/node.rs index e707055..68785ac 100644 --- a/src/node.rs +++ b/src/node.rs @@ -72,6 +72,7 @@ impl<'a, T: ToJsonTreeValue> JsonTreeNode<'a, T> { abbreviate_root: config.abbreviate_root, style: config.style, search_term, + enable_icons: config.enable_icons, }; // Wrap in a vertical layout in case this tree is placed directly in a horizontal layout, @@ -178,6 +179,7 @@ fn show_expandable<'a, 'b, T: ToJsonTreeValue>( abbreviate_root, style, search_term, + enable_icons, } = config; let delimiters = match expandable.expandable_type { @@ -201,7 +203,10 @@ fn show_expandable<'a, 'b, T: ToJsonTreeValue>( let header_res = ui.horizontal_wrapped(|ui| { ui.spacing_mut().item_spacing.x = 0.0; - state.show_toggle_button(ui, paint_default_icon); + + ui.add_enabled_ui(*enable_icons, |ui| { + state.show_toggle_button(ui, paint_default_icon); + }); if path_segments.is_empty() && !is_expanded { if *abbreviate_root { @@ -434,6 +439,7 @@ struct JsonTreeNodeConfig<'a> { abbreviate_root: bool, style: JsonTreeStyle, search_term: Option, + enable_icons: bool, } #[derive(Debug, Clone)] diff --git a/src/tree.rs b/src/tree.rs index d5e4382..e1a3875 100644 --- a/src/tree.rs +++ b/src/tree.rs @@ -12,6 +12,7 @@ pub(crate) struct JsonTreeConfig<'a, T: ToJsonTreeValue> { pub(crate) default_expand: DefaultExpand<'a>, pub(crate) abbreviate_root: bool, pub(crate) renderer: JsonTreeRenderer<'a, T>, + pub(crate) enable_icons: bool, } impl<'a, T: ToJsonTreeValue> Default for JsonTreeConfig<'a, T> { @@ -21,6 +22,7 @@ impl<'a, T: ToJsonTreeValue> Default for JsonTreeConfig<'a, T> { default_expand: Default::default(), abbreviate_root: Default::default(), renderer: Default::default(), + enable_icons: true, } } } @@ -105,6 +107,11 @@ impl<'a, T: ToJsonTreeValue> JsonTree<'a, T> { self } + pub fn enable_icons(mut self, enable_icons: bool) -> Self { + self.config.enable_icons = enable_icons; + self + } + /// Show the JSON tree visualisation within the `Ui`. pub fn show(self, ui: &mut Ui) -> JsonTreeResponse { JsonTreeNode::new(self.id, self.value).show_with_config(ui, self.config) From 7e8ea39bfeb09c60feb6765cab7b82b8772a6ef8 Mon Sep 17 00:00:00 2001 From: dmackdev Date: Fri, 4 Oct 2024 15:06:13 +0100 Subject: [PATCH 3/5] add ToggleButtonsState to control toggle button visibility and interactivity --- examples/demo.rs | 46 ++++++++++++++++++++++++++++--------- src/lib.rs | 2 ++ src/node.rs | 33 ++++++++++++++++++-------- src/toggle_buttons_state.rs | 18 +++++++++++++++ src/tree.rs | 11 +++++---- 5 files changed, 84 insertions(+), 26 deletions(-) create mode 100644 src/toggle_buttons_state.rs diff --git a/examples/demo.rs b/examples/demo.rs index d375ec7..0be0181 100644 --- a/examples/demo.rs +++ b/examples/demo.rs @@ -12,7 +12,7 @@ use egui_json_tree::{ DefaultRender, RenderBaseValueContext, RenderContext, RenderExpandableDelimiterContext, RenderPropertyContext, }, - DefaultExpand, JsonTree, + DefaultExpand, JsonTree, ToggleButtonsState, }; use serde_json::{json, Value}; @@ -625,26 +625,50 @@ impl Show for JsonEditorExample { } } -struct NonInteractiveDemo { +struct ToggleButtonsCustomisationDemo { value: Value, + toggle_buttons_state: ToggleButtonsState, } -impl NonInteractiveDemo { +impl ToggleButtonsCustomisationDemo { fn new(value: Value) -> Self { - Self { value } + Self { + value, + toggle_buttons_state: Default::default(), + } } } -impl Show for NonInteractiveDemo { +impl Show for ToggleButtonsCustomisationDemo { fn title(&self) -> &'static str { - "Non Interactive" + "Toggle Buttons Customisation" } fn show(&mut self, ui: &mut Ui) { - JsonTree::new(self.title(), &self.value) - .default_expand(DefaultExpand::All) - .enable_icons(false) - .show(ui); + ui.vertical(|ui| { + ui.horizontal(|ui| { + ui.selectable_value( + &mut self.toggle_buttons_state, + ToggleButtonsState::VisibleEnabled, + "Visible and enabled", + ); + ui.selectable_value( + &mut self.toggle_buttons_state, + ToggleButtonsState::VisibleDisabled, + "Visible and disabled", + ); + ui.selectable_value( + &mut self.toggle_buttons_state, + ToggleButtonsState::Hidden, + "Hidden", + ); + }); + + JsonTree::new("show", &self.value) + .default_expand(DefaultExpand::All) + .toggle_buttons_state(self.toggle_buttons_state) + .show(ui); + }); } } @@ -679,7 +703,7 @@ impl Default for DemoApp { Box::new(SearchExample::new(complex_object.clone())), Box::new(CopyToClipboardExample::new(complex_object.clone())), Box::new(JsonEditorExample::new(complex_object.clone())), - Box::new(NonInteractiveDemo::new(complex_object)), + Box::new(ToggleButtonsCustomisationDemo::new(complex_object)), ], open_example_idx: None, } diff --git a/src/lib.rs b/src/lib.rs index fa45c2f..d7b91eb 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -76,6 +76,7 @@ mod node; mod response; mod search; mod style; +mod toggle_buttons_state; mod tree; pub mod delimiters; @@ -86,4 +87,5 @@ pub mod value; pub use default_expand::DefaultExpand; pub use response::JsonTreeResponse; pub use style::JsonTreeStyle; +pub use toggle_buttons_state::ToggleButtonsState; pub use tree::JsonTree; diff --git a/src/node.rs b/src/node.rs index 68785ac..ff6c39f 100644 --- a/src/node.rs +++ b/src/node.rs @@ -16,7 +16,7 @@ use crate::{ search::SearchTerm, tree::JsonTreeConfig, value::{ExpandableType, JsonTreeValue, ToJsonTreeValue}, - DefaultExpand, JsonTreeStyle, + DefaultExpand, JsonTreeStyle, ToggleButtonsState, }; pub(crate) struct JsonTreeNode<'a, T: ToJsonTreeValue> { @@ -72,7 +72,7 @@ impl<'a, T: ToJsonTreeValue> JsonTreeNode<'a, T> { abbreviate_root: config.abbreviate_root, style: config.style, search_term, - enable_icons: config.enable_icons, + toggle_buttons_state: config.toggle_buttons_state, }; // Wrap in a vertical layout in case this tree is placed directly in a horizontal layout, @@ -179,7 +179,7 @@ fn show_expandable<'a, 'b, T: ToJsonTreeValue>( abbreviate_root, style, search_term, - enable_icons, + toggle_buttons_state, } = config; let delimiters = match expandable.expandable_type { @@ -204,9 +204,11 @@ fn show_expandable<'a, 'b, T: ToJsonTreeValue>( let header_res = ui.horizontal_wrapped(|ui| { ui.spacing_mut().item_spacing.x = 0.0; - ui.add_enabled_ui(*enable_icons, |ui| { - state.show_toggle_button(ui, paint_default_icon); - }); + if let Some(enabled) = toggle_buttons_state.enabled() { + ui.add_enabled_ui(enabled, |ui| { + state.show_toggle_button(ui, paint_default_icon) + }); + } if path_segments.is_empty() && !is_expanded { if *abbreviate_root { @@ -379,6 +381,11 @@ fn show_expandable<'a, 'b, T: ToJsonTreeValue>( } }); + if *toggle_buttons_state == ToggleButtonsState::Hidden { + ui.visuals_mut().indent_has_left_vline = true; + ui.spacing_mut().indent = (ui.spacing().icon_width + ui.spacing().icon_spacing) / 2.0; + } + state.show_body_indented(&header_res.response, ui, |ui| { for (property, elem) in expandable.entries { let is_expandable = elem.is_expandable(); @@ -402,13 +409,17 @@ fn show_expandable<'a, 'b, T: ToJsonTreeValue>( ); }; - if is_expandable { + if is_expandable && *toggle_buttons_state != ToggleButtonsState::Hidden { add_nested_tree(ui); } else { ui.scope(|ui| { ui.visuals_mut().indent_has_left_vline = false; ui.spacing_mut().indent = ui.spacing().icon_width + ui.spacing().icon_spacing; + if *toggle_buttons_state == ToggleButtonsState::Hidden { + ui.spacing_mut().indent /= 2.0; + } + ui.indent(id_source, add_nested_tree); }); } @@ -419,8 +430,10 @@ fn show_expandable<'a, 'b, T: ToJsonTreeValue>( if is_expanded { ui.horizontal_wrapped(|ui| { - let indent = ui.spacing().icon_width / 2.0; - ui.add_space(indent); + if *toggle_buttons_state != ToggleButtonsState::Hidden { + let indent = ui.spacing().icon_width / 2.0; + ui.add_space(indent); + } renderer.render_expandable_delimiter( ui, RenderExpandableDelimiterContext { @@ -439,7 +452,7 @@ struct JsonTreeNodeConfig<'a> { abbreviate_root: bool, style: JsonTreeStyle, search_term: Option, - enable_icons: bool, + toggle_buttons_state: ToggleButtonsState, } #[derive(Debug, Clone)] diff --git a/src/toggle_buttons_state.rs b/src/toggle_buttons_state.rs new file mode 100644 index 0000000..21aba55 --- /dev/null +++ b/src/toggle_buttons_state.rs @@ -0,0 +1,18 @@ +/// Setting for the visibility and interactivity of the toggle buttons for expanding/collapsing objects and arrays. +#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)] +pub enum ToggleButtonsState { + #[default] + VisibleEnabled, + VisibleDisabled, + Hidden, +} + +impl ToggleButtonsState { + pub(crate) fn enabled(&self) -> Option { + match self { + ToggleButtonsState::VisibleEnabled => Some(true), + ToggleButtonsState::VisibleDisabled => Some(false), + ToggleButtonsState::Hidden => None, + } + } +} diff --git a/src/tree.rs b/src/tree.rs index e1a3875..31b5870 100644 --- a/src/tree.rs +++ b/src/tree.rs @@ -2,7 +2,7 @@ use crate::{ node::JsonTreeNode, render::{JsonTreeRenderer, RenderContext}, value::ToJsonTreeValue, - DefaultExpand, JsonTreeResponse, JsonTreeStyle, + DefaultExpand, JsonTreeResponse, JsonTreeStyle, ToggleButtonsState, }; use egui::{Id, Ui}; use std::hash::Hash; @@ -12,7 +12,7 @@ pub(crate) struct JsonTreeConfig<'a, T: ToJsonTreeValue> { pub(crate) default_expand: DefaultExpand<'a>, pub(crate) abbreviate_root: bool, pub(crate) renderer: JsonTreeRenderer<'a, T>, - pub(crate) enable_icons: bool, + pub(crate) toggle_buttons_state: ToggleButtonsState, } impl<'a, T: ToJsonTreeValue> Default for JsonTreeConfig<'a, T> { @@ -22,7 +22,7 @@ impl<'a, T: ToJsonTreeValue> Default for JsonTreeConfig<'a, T> { default_expand: Default::default(), abbreviate_root: Default::default(), renderer: Default::default(), - enable_icons: true, + toggle_buttons_state: Default::default(), } } } @@ -107,8 +107,9 @@ impl<'a, T: ToJsonTreeValue> JsonTree<'a, T> { self } - pub fn enable_icons(mut self, enable_icons: bool) -> Self { - self.config.enable_icons = enable_icons; + /// Override the visibility and interactivity of the toggle buttons for expanding/collapsing objects and arrays. + pub fn toggle_buttons_state(mut self, toggle_buttons_state: ToggleButtonsState) -> Self { + self.config.toggle_buttons_state = toggle_buttons_state; self } From a6308d8cfdeaafa8617f1e5446ad7ada64041956 Mon Sep 17 00:00:00 2001 From: dmackdev Date: Sat, 5 Oct 2024 12:40:46 +0100 Subject: [PATCH 4/5] extract and reuse var --- src/node.rs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/node.rs b/src/node.rs index ff6c39f..0967d1e 100644 --- a/src/node.rs +++ b/src/node.rs @@ -381,7 +381,8 @@ fn show_expandable<'a, 'b, T: ToJsonTreeValue>( } }); - if *toggle_buttons_state == ToggleButtonsState::Hidden { + let toggle_buttons_hidden = *toggle_buttons_state == ToggleButtonsState::Hidden; + if toggle_buttons_hidden { ui.visuals_mut().indent_has_left_vline = true; ui.spacing_mut().indent = (ui.spacing().icon_width + ui.spacing().icon_spacing) / 2.0; } @@ -409,14 +410,14 @@ fn show_expandable<'a, 'b, T: ToJsonTreeValue>( ); }; - if is_expandable && *toggle_buttons_state != ToggleButtonsState::Hidden { + if is_expandable && !toggle_buttons_hidden { add_nested_tree(ui); } else { ui.scope(|ui| { ui.visuals_mut().indent_has_left_vline = false; ui.spacing_mut().indent = ui.spacing().icon_width + ui.spacing().icon_spacing; - if *toggle_buttons_state == ToggleButtonsState::Hidden { + if toggle_buttons_hidden { ui.spacing_mut().indent /= 2.0; } @@ -430,7 +431,7 @@ fn show_expandable<'a, 'b, T: ToJsonTreeValue>( if is_expanded { ui.horizontal_wrapped(|ui| { - if *toggle_buttons_state != ToggleButtonsState::Hidden { + if !toggle_buttons_hidden { let indent = ui.spacing().icon_width / 2.0; ui.add_space(indent); } From 13fdac0e7b63797dae07d653c23689afc651c3a2 Mon Sep 17 00:00:00 2001 From: dmackdev Date: Sat, 5 Oct 2024 12:49:02 +0100 Subject: [PATCH 5/5] add toggle_buttons_state usage to docs code examples --- README.md | 1 + src/lib.rs | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 6f93bab..daeb551 100644 --- a/README.md +++ b/README.md @@ -28,6 +28,7 @@ let response = JsonTree::new("customised-tree", &value) }) .default_expand(DefaultExpand::All) .abbreviate_root(true) // Show {...} when the root object is collapsed. + .toggle_buttons_state(ToggleButtonsState::VisibleDisabled) .on_render(|ui, ctx| { // Customise rendering of the JsonTree, and/or handle interactions. match ctx { diff --git a/src/lib.rs b/src/lib.rs index d7b91eb..98407e1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -8,7 +8,7 @@ //! # DefaultRender, RenderBaseValueContext, RenderContext, RenderExpandableDelimiterContext, //! # RenderPropertyContext, //! # }, -//! # DefaultExpand, JsonTree, JsonTreeStyle +//! # DefaultExpand, JsonTree, JsonTreeStyle, ToggleButtonsState //! # }; //! # egui::__run_test_ui(|ui| { //! let value = serde_json::json!({ "foo": "bar", "fizz": [1, 2, 3]}); @@ -24,6 +24,7 @@ //! }) //! .default_expand(DefaultExpand::All) //! .abbreviate_root(true) // Show {...} when the root object is collapsed. +//! .toggle_buttons_state(ToggleButtonsState::VisibleDisabled) //! .on_render(|ui, ctx| { //! // Customise rendering of the JsonTree, and/or handle interactions. //! match ctx {