From 1195c293567fddb26b2de02b8b460fa4a2e8ee7e Mon Sep 17 00:00:00 2001 From: Azriel Hoh Date: Tue, 6 Aug 2024 15:18:39 +1200 Subject: [PATCH 01/15] Add `outline-none` to tag nodes. --- crate/rt/src/into_graphviz_dot_src/info_graph.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crate/rt/src/into_graphviz_dot_src/info_graph.rs b/crate/rt/src/into_graphviz_dot_src/info_graph.rs index e693e3b..08643d0 100644 --- a/crate/rt/src/into_graphviz_dot_src/info_graph.rs +++ b/crate/rt/src/into_graphviz_dot_src/info_graph.rs @@ -797,7 +797,7 @@ fn tag_legend( margin = "{tag_margin_x:.3},{tag_margin_y:.3}" fontname = "liberationmono" fontsize = {tag_point_size} - class = "{tag_classes} {tag_peer_class}" + class = "{OUTLINE_NONE} {tag_classes} {tag_peer_class}" penwidth = 1 // invisible node for cluster to appear From 115ae325576b6ff40aa1d761480bdce414b77c18 Mon Sep 17 00:00:00 2001 From: Azriel Hoh Date: Tue, 6 Aug 2024 16:02:51 +1200 Subject: [PATCH 02/15] Reduce number of CSS classes generated for tag peers. --- crate/model/src/theme/css_class_merger.rs | 201 ++++++++++++++++------ 1 file changed, 147 insertions(+), 54 deletions(-) diff --git a/crate/model/src/theme/css_class_merger.rs b/crate/model/src/theme/css_class_merger.rs index ac321f3..b64a5df 100644 --- a/crate/model/src/theme/css_class_merger.rs +++ b/crate/model/src/theme/css_class_merger.rs @@ -80,6 +80,7 @@ impl CssClassMerger { defaults, specified, themeable, + style_for, ); Self::stroke_classes_append( &mut css_classes_builder, @@ -88,6 +89,7 @@ impl CssClassMerger { defaults, specified, themeable, + style_for, ); Self::fill_classes_append( &mut css_classes_builder, @@ -96,6 +98,7 @@ impl CssClassMerger { defaults, specified, themeable, + style_for, ); [ @@ -198,6 +201,7 @@ impl CssClassMerger { defaults, specified, themeable, + style_for, ); Self::stroke_classes_append( &mut css_classes_builder, @@ -206,6 +210,7 @@ impl CssClassMerger { defaults, specified, themeable, + style_for, ); Self::fill_classes_append( &mut css_classes_builder, @@ -214,6 +219,7 @@ impl CssClassMerger { defaults, specified, themeable, + style_for, ); Self::animation_classes(&mut css_classes_builder, defaults, specified); @@ -233,30 +239,39 @@ impl CssClassMerger { defaults: Option<&CssClassPartials>, specified: Option<&CssClassPartials>, themeable: &dyn Themeable, + style_for: StyleFor<'_>, ) { - let stroke_class_append_result = [ - StrokeParamGroupings::new_outline_normal(fn_outline_classes), - StrokeParamGroupings::new_outline_focus(fn_outline_classes), - StrokeParamGroupings::new_outline_hover(fn_outline_classes), - StrokeParamGroupings::new_outline_active(fn_outline_classes), - ] - .into_iter() - .fold( - Vec::new(), - |mut stroke_class_append_result_acc, css_classes_param_groupings| { - let stroke_class_append_result = Self::stroke_classes_highlight_state_append( + let stroke_class_append_result = match style_for { + StyleFor::Regular => { + let param_groupings = [ + StrokeParamGroupings::new_outline_normal(fn_outline_classes), + StrokeParamGroupings::new_outline_focus(fn_outline_classes), + StrokeParamGroupings::new_outline_hover(fn_outline_classes), + StrokeParamGroupings::new_outline_active(fn_outline_classes), + ] + .into_iter(); + Self::line_classes_fold( css_classes_builder, - &css_classes_param_groupings, defaults, specified, themeable, - ); + param_groupings, + ) + } - stroke_class_append_result_acc.push(stroke_class_append_result); + StyleFor::TagFocus(_) => { + let param_groupings = + [StrokeParamGroupings::new_outline_normal(fn_outline_classes)].into_iter(); - stroke_class_append_result_acc - }, - ); + Self::line_classes_fold( + css_classes_builder, + defaults, + specified, + themeable, + param_groupings, + ) + } + }; if !stroke_class_append_result .iter() @@ -310,31 +325,40 @@ impl CssClassMerger { defaults: Option<&CssClassPartials>, specified: Option<&CssClassPartials>, themeable: &dyn Themeable, + style_for: StyleFor<'_>, ) { - let stroke_class_append_result = [ - StrokeParamGroupings::new_stroke_normal(fn_stroke_classes), - StrokeParamGroupings::new_stroke_focus(fn_stroke_classes), - StrokeParamGroupings::new_stroke_focus_hover(fn_stroke_classes), - StrokeParamGroupings::new_stroke_hover(fn_stroke_classes), - StrokeParamGroupings::new_stroke_active(fn_stroke_classes), - ] - .into_iter() - .fold( - Vec::new(), - |mut stroke_class_append_result_acc, css_classes_param_groupings| { - let stroke_class_append_result = Self::stroke_classes_highlight_state_append( + let stroke_class_append_result = match style_for { + StyleFor::Regular => { + let param_groupings = [ + StrokeParamGroupings::new_stroke_normal(fn_stroke_classes), + StrokeParamGroupings::new_stroke_focus(fn_stroke_classes), + StrokeParamGroupings::new_stroke_focus_hover(fn_stroke_classes), + StrokeParamGroupings::new_stroke_hover(fn_stroke_classes), + StrokeParamGroupings::new_stroke_active(fn_stroke_classes), + ] + .into_iter(); + Self::line_classes_fold( css_classes_builder, - &css_classes_param_groupings, defaults, specified, themeable, - ); + param_groupings, + ) + } - stroke_class_append_result_acc.push(stroke_class_append_result); + StyleFor::TagFocus(_) => { + let param_groupings = + [StrokeParamGroupings::new_stroke_normal(fn_stroke_classes)].into_iter(); - stroke_class_append_result_acc - }, - ); + Self::line_classes_fold( + css_classes_builder, + defaults, + specified, + themeable, + param_groupings, + ) + } + }; if !stroke_class_append_result .iter() @@ -441,31 +465,40 @@ impl CssClassMerger { defaults: Option<&CssClassPartials>, specified: Option<&CssClassPartials>, themeable: &dyn Themeable, + style_for: StyleFor<'_>, ) { - let fill_class_append_result = [ - ColorParamGroupings::new_fill_normal(fn_fill_classes), - ColorParamGroupings::new_fill_focus(fn_fill_classes), - ColorParamGroupings::new_fill_focus_hover(fn_fill_classes), - ColorParamGroupings::new_fill_hover(fn_fill_classes), - ColorParamGroupings::new_fill_active(fn_fill_classes), - ] - .into_iter() - .fold( - Vec::new(), - |mut fill_class_append_result_acc, css_classes_param_groupings| { - let fill_class_append_result = Self::fill_classes_highlight_state_append( - css_classes_param_groupings, + let fill_class_append_result = match style_for { + StyleFor::Regular => { + let param_groupings = [ + ColorParamGroupings::new_fill_normal(fn_fill_classes), + ColorParamGroupings::new_fill_focus(fn_fill_classes), + ColorParamGroupings::new_fill_focus_hover(fn_fill_classes), + ColorParamGroupings::new_fill_hover(fn_fill_classes), + ColorParamGroupings::new_fill_active(fn_fill_classes), + ] + .into_iter(); + Self::fill_classes_fold( + css_classes_builder, defaults, specified, themeable, - css_classes_builder, - ); + param_groupings, + ) + } - fill_class_append_result_acc.push(fill_class_append_result); + StyleFor::TagFocus(_) => { + let param_groupings = + [ColorParamGroupings::new_fill_normal(fn_fill_classes)].into_iter(); - fill_class_append_result_acc - }, - ); + Self::fill_classes_fold( + css_classes_builder, + defaults, + specified, + themeable, + param_groupings, + ) + } + }; if !fill_class_append_result .iter() @@ -578,6 +611,66 @@ impl CssClassMerger { }); } } + + /// Since the param groupings are arrays of different sizes, we need to have + /// a generic function to cater for different concrete types. + fn line_classes_fold<'f, I>( + css_classes_builder: &mut CssClassesBuilder, + defaults: Option<&'f CssClassPartials>, + specified: Option<&'f CssClassPartials>, + themeable: &dyn Themeable, + param_groupings: I, + ) -> Vec> + where + I: Iterator>> + 'f, + { + param_groupings.fold( + Vec::new(), + |mut stroke_class_append_result_acc, css_classes_param_groupings| { + let stroke_class_append_result = Self::stroke_classes_highlight_state_append( + css_classes_builder, + &css_classes_param_groupings, + defaults, + specified, + themeable, + ); + + stroke_class_append_result_acc.push(stroke_class_append_result); + + stroke_class_append_result_acc + }, + ) + } + + /// Since the param groupings are arrays of different sizes, we need to have + /// a generic function to cater for different concrete types. + fn fill_classes_fold<'f, I>( + css_classes_builder: &mut CssClassesBuilder, + defaults: Option<&'f CssClassPartials>, + specified: Option<&'f CssClassPartials>, + themeable: &dyn Themeable, + param_groupings: I, + ) -> Vec> + where + I: Iterator>> + 'f, + { + param_groupings.fold( + Vec::new(), + |mut fill_class_append_result_acc, css_classes_param_groupings| { + let fill_class_append_result = Self::fill_classes_highlight_state_append( + css_classes_param_groupings, + defaults, + specified, + themeable, + css_classes_builder, + ); + + fill_class_append_result_acc.push(fill_class_append_result); + + fill_class_append_result_acc + }, + ) + } } /// Finds an attributes with multiple levels of fallbacks. From 2834ce10857fbf4bde40c59322b9b0a25eb79a04 Mon Sep 17 00:00:00 2001 From: Azriel Hoh Date: Tue, 6 Aug 2024 16:05:34 +1200 Subject: [PATCH 03/15] Rename `Stroke*` to `Line*` where it applies to both `Stroke` and `Outline`. --- crate/model/src/theme.rs | 4 +- crate/model/src/theme/css_class_merger.rs | 164 +++++++++--------- .../{stroke_params.rs => line_params.rs} | 20 ++- crate/model/src/theme/themeable.rs | 26 +-- crate/rt/src/info_graph_dot.rs | 116 ++++++------- crate/rt/src/info_graph_html.rs | 76 ++++---- 6 files changed, 184 insertions(+), 222 deletions(-) rename crate/model/src/theme/{stroke_params.rs => line_params.rs} (56%) diff --git a/crate/model/src/theme.rs b/crate/model/src/theme.rs index 76d8785..fcac620 100644 --- a/crate/model/src/theme.rs +++ b/crate/model/src/theme.rs @@ -12,7 +12,7 @@ pub use self::{ css_class_merger::CssClassMerger, css_class_partials::CssClassPartials, css_classes::CssClasses, css_classes_and_warnings::CssClassesAndWarnings, css_classes_builder::CssClassesBuilder, el_css_classes::ElCssClasses, - highlight_state::HighlightState, stroke_params::StrokeParams, style_for::StyleFor, + highlight_state::HighlightState, line_params::LineParams, style_for::StyleFor, theme_attr::ThemeAttr, theme_styles::ThemeStyles, theme_warnings::ThemeWarnings, themeable::Themeable, }; @@ -26,7 +26,7 @@ mod css_classes_and_warnings; mod css_classes_builder; mod el_css_classes; mod highlight_state; -mod stroke_params; +mod line_params; mod style_for; mod theme_attr; mod theme_styles; diff --git a/crate/model/src/theme/css_class_merger.rs b/crate/model/src/theme/css_class_merger.rs index b64a5df..df6febe 100644 --- a/crate/model/src/theme/css_class_merger.rs +++ b/crate/model/src/theme/css_class_merger.rs @@ -2,7 +2,7 @@ use crate::{ common::TagId, theme::{ ColorParams, CssClassPartials, CssClassesAndWarnings, CssClassesBuilder, HighlightState, - StrokeParams, StyleFor, ThemeAttr, ThemeWarnings, Themeable, + LineParams, StyleFor, ThemeAttr, ThemeWarnings, Themeable, }, }; @@ -55,14 +55,14 @@ impl CssClassMerger { let themeable_node_outline_classes = |themeable: &dyn Themeable, css_classes_builder: &mut CssClassesBuilder, - params: StrokeParams<'_>| { + params: LineParams<'_>| { themeable.node_outline_classes(css_classes_builder, params); }; let themeable_node_stroke_classes = |themeable: &dyn Themeable, css_classes_builder: &mut CssClassesBuilder, - params: StrokeParams<'_>| { + params: LineParams<'_>| { themeable.node_stroke_classes(css_classes_builder, params); }; @@ -176,14 +176,14 @@ impl CssClassMerger { let themeable_edge_outline_classes = |themeable: &dyn Themeable, css_classes_builder: &mut CssClassesBuilder, - params: StrokeParams<'_>| { + params: LineParams<'_>| { themeable.edge_outline_classes(css_classes_builder, params); }; let themeable_edge_stroke_classes = |themeable: &dyn Themeable, css_classes_builder: &mut CssClassesBuilder, - params: StrokeParams<'_>| { + params: LineParams<'_>| { themeable.edge_stroke_classes(css_classes_builder, params); }; @@ -235,19 +235,19 @@ impl CssClassMerger { fn outline_classes_append( css_classes_builder: &mut CssClassesBuilder, warnings: &mut ThemeWarnings, - fn_outline_classes: fn(&dyn Themeable, &mut CssClassesBuilder, StrokeParams<'_>), + fn_outline_classes: fn(&dyn Themeable, &mut CssClassesBuilder, LineParams<'_>), defaults: Option<&CssClassPartials>, specified: Option<&CssClassPartials>, themeable: &dyn Themeable, style_for: StyleFor<'_>, ) { - let stroke_class_append_result = match style_for { + let line_class_append_result = match style_for { StyleFor::Regular => { let param_groupings = [ - StrokeParamGroupings::new_outline_normal(fn_outline_classes), - StrokeParamGroupings::new_outline_focus(fn_outline_classes), - StrokeParamGroupings::new_outline_hover(fn_outline_classes), - StrokeParamGroupings::new_outline_active(fn_outline_classes), + LineParamGroupings::new_outline_normal(fn_outline_classes), + LineParamGroupings::new_outline_focus(fn_outline_classes), + LineParamGroupings::new_outline_hover(fn_outline_classes), + LineParamGroupings::new_outline_active(fn_outline_classes), ] .into_iter(); Self::line_classes_fold( @@ -261,7 +261,7 @@ impl CssClassMerger { StyleFor::TagFocus(_) => { let param_groupings = - [StrokeParamGroupings::new_outline_normal(fn_outline_classes)].into_iter(); + [LineParamGroupings::new_outline_normal(fn_outline_classes)].into_iter(); Self::line_classes_fold( css_classes_builder, @@ -273,21 +273,21 @@ impl CssClassMerger { } }; - if !stroke_class_append_result + if !line_class_append_result .iter() - .any(|stroke_class_append_result| { - matches!(stroke_class_append_result, StrokeClassAppendResult::Added) + .any(|line_class_append_result| { + matches!(line_class_append_result, LineClassAppendResult::Added) }) { - stroke_class_append_result + line_class_append_result .into_iter() - .for_each(|stroke_class_append_result| { - if let StrokeClassAppendResult::NoChange { + .for_each(|line_class_append_result| { + if let LineClassAppendResult::NoChange { style, width, color, shade, - } = stroke_class_append_result + } = line_class_append_result { warnings.insert(format!( "Outline attributes partially specified, \ @@ -321,20 +321,20 @@ impl CssClassMerger { fn stroke_classes_append( css_classes_builder: &mut CssClassesBuilder, warnings: &mut ThemeWarnings, - fn_stroke_classes: fn(&dyn Themeable, &mut CssClassesBuilder, StrokeParams<'_>), + fn_stroke_classes: fn(&dyn Themeable, &mut CssClassesBuilder, LineParams<'_>), defaults: Option<&CssClassPartials>, specified: Option<&CssClassPartials>, themeable: &dyn Themeable, style_for: StyleFor<'_>, ) { - let stroke_class_append_result = match style_for { + let line_class_append_result = match style_for { StyleFor::Regular => { let param_groupings = [ - StrokeParamGroupings::new_stroke_normal(fn_stroke_classes), - StrokeParamGroupings::new_stroke_focus(fn_stroke_classes), - StrokeParamGroupings::new_stroke_focus_hover(fn_stroke_classes), - StrokeParamGroupings::new_stroke_hover(fn_stroke_classes), - StrokeParamGroupings::new_stroke_active(fn_stroke_classes), + LineParamGroupings::new_stroke_normal(fn_stroke_classes), + LineParamGroupings::new_stroke_focus(fn_stroke_classes), + LineParamGroupings::new_stroke_focus_hover(fn_stroke_classes), + LineParamGroupings::new_stroke_hover(fn_stroke_classes), + LineParamGroupings::new_stroke_active(fn_stroke_classes), ] .into_iter(); Self::line_classes_fold( @@ -348,7 +348,7 @@ impl CssClassMerger { StyleFor::TagFocus(_) => { let param_groupings = - [StrokeParamGroupings::new_stroke_normal(fn_stroke_classes)].into_iter(); + [LineParamGroupings::new_stroke_normal(fn_stroke_classes)].into_iter(); Self::line_classes_fold( css_classes_builder, @@ -360,21 +360,21 @@ impl CssClassMerger { } }; - if !stroke_class_append_result + if !line_class_append_result .iter() - .any(|stroke_class_append_result| { - matches!(stroke_class_append_result, StrokeClassAppendResult::Added) + .any(|line_class_append_result| { + matches!(line_class_append_result, LineClassAppendResult::Added) }) { - stroke_class_append_result + line_class_append_result .into_iter() - .for_each(|stroke_class_append_result| { - if let StrokeClassAppendResult::NoChange { + .for_each(|line_class_append_result| { + if let LineClassAppendResult::NoChange { style, width, color, shade, - } = stroke_class_append_result + } = line_class_append_result { warnings.insert(format!( "Stroke attributes partially specified, \ @@ -405,49 +405,49 @@ impl CssClassMerger { /// Appends CSS classes for stroke styling for a given [`HighlightState`] to /// the CSS classes builder. - fn stroke_classes_highlight_state_append<'f1, 'f2: 'f1>( + fn line_classes_highlight_state_append<'f1, 'f2: 'f1>( css_classes_builder: &mut CssClassesBuilder, - css_classes_param_groupings: &StrokeParamGroupings>, + css_classes_param_groupings: &LineParamGroupings>, defaults: Option<&'f2 CssClassPartials>, specified: Option<&'f2 CssClassPartials>, themeable: &dyn Themeable, - ) -> StrokeClassAppendResult<'f2> { - let StrokeParamGroupings { + ) -> LineClassAppendResult<'f2> { + let LineParamGroupings { highlight_state, color_keys, shade_keys, - stroke_style_keys, - stroke_width_keys, + line_style_keys, + line_width_keys, fn_css_classes, } = css_classes_param_groupings; - let stroke_style = attr_value_find(stroke_style_keys, defaults, specified); - let stroke_width = attr_value_find(stroke_width_keys, defaults, specified); + let line_style = attr_value_find(line_style_keys, defaults, specified); + let line_width = attr_value_find(line_width_keys, defaults, specified); let color = attr_value_find(color_keys, defaults, specified); let shade = attr_value_find(shade_keys, defaults, specified); - match (stroke_style, stroke_width, color, shade) { - (None, None, None, None) => StrokeClassAppendResult::NoAttrsSpecified, + match (line_style, line_width, color, shade) { + (None, None, None, None) => LineClassAppendResult::NoAttrsSpecified, ( - Some((_stroke_style_attr, stroke_style)), - Some((_stroke_width_attr, stroke_width)), + Some((_line_style_attr, line_style)), + Some((_line_width_attr, line_width)), Some((_color_attr, color)), Some((_shade_attr, shade)), ) => { - let params = StrokeParams { + let params = LineParams { color_params: ColorParams { highlight_state: *highlight_state, color, shade, }, - stroke_width, - stroke_style, + line_width, + line_style, }; fn_css_classes(themeable, css_classes_builder, params); - StrokeClassAppendResult::Added + LineClassAppendResult::Added } - (style, width, color, shade) => StrokeClassAppendResult::NoChange { + (style, width, color, shade) => LineClassAppendResult::NoChange { style, width, color, @@ -620,14 +620,14 @@ impl CssClassMerger { specified: Option<&'f CssClassPartials>, themeable: &dyn Themeable, param_groupings: I, - ) -> Vec> + ) -> Vec> where - I: Iterator>> + 'f, + I: Iterator>> + 'f, { param_groupings.fold( Vec::new(), - |mut stroke_class_append_result_acc, css_classes_param_groupings| { - let stroke_class_append_result = Self::stroke_classes_highlight_state_append( + |mut line_class_append_result_acc, css_classes_param_groupings| { + let line_class_append_result = Self::line_classes_highlight_state_append( css_classes_builder, &css_classes_param_groupings, defaults, @@ -635,9 +635,9 @@ impl CssClassMerger { themeable, ); - stroke_class_append_result_acc.push(stroke_class_append_result); + line_class_append_result_acc.push(line_class_append_result); - stroke_class_append_result_acc + line_class_append_result_acc }, ) } @@ -794,19 +794,19 @@ impl ColorParamGroupings { } /// Groupings of parameters to generate CSS classes for colour shades. -struct StrokeParamGroupings { +struct LineParamGroupings { highlight_state: HighlightState, /// List of keys to fallback on. /// /// State specific color, state agnostic color, shape color. color_keys: &'static [ThemeAttr], shade_keys: &'static [ThemeAttr], - stroke_style_keys: &'static [ThemeAttr], - stroke_width_keys: &'static [ThemeAttr], + line_style_keys: &'static [ThemeAttr], + line_width_keys: &'static [ThemeAttr], fn_css_classes: fn(&dyn Themeable, &mut CssClassesBuilder, Params), } -impl StrokeParamGroupings { +impl LineParamGroupings { fn new_stroke_normal( fn_css_classes: fn(&dyn Themeable, &mut CssClassesBuilder, Params), ) -> Self { @@ -818,8 +818,8 @@ impl StrokeParamGroupings { ThemeAttr::ShapeColor, ], shade_keys: &[ThemeAttr::StrokeShadeNormal, ThemeAttr::StrokeShade], - stroke_style_keys: &[ThemeAttr::StrokeStyleNormal, ThemeAttr::StrokeStyle], - stroke_width_keys: &[ThemeAttr::StrokeWidth], + line_style_keys: &[ThemeAttr::StrokeStyleNormal, ThemeAttr::StrokeStyle], + line_width_keys: &[ThemeAttr::StrokeWidth], fn_css_classes, } } @@ -835,8 +835,8 @@ impl StrokeParamGroupings { ThemeAttr::ShapeColor, ], shade_keys: &[ThemeAttr::StrokeShadeFocus, ThemeAttr::StrokeShade], - stroke_style_keys: &[ThemeAttr::StrokeStyleFocus, ThemeAttr::StrokeStyle], - stroke_width_keys: &[ThemeAttr::StrokeWidth], + line_style_keys: &[ThemeAttr::StrokeStyleFocus, ThemeAttr::StrokeStyle], + line_width_keys: &[ThemeAttr::StrokeWidth], fn_css_classes, } } @@ -852,8 +852,8 @@ impl StrokeParamGroupings { ThemeAttr::ShapeColor, ], shade_keys: &[ThemeAttr::StrokeShadeHover, ThemeAttr::StrokeShade], - stroke_style_keys: &[ThemeAttr::StrokeStyleHover, ThemeAttr::StrokeStyle], - stroke_width_keys: &[ThemeAttr::StrokeWidth], + line_style_keys: &[ThemeAttr::StrokeStyleHover, ThemeAttr::StrokeStyle], + line_width_keys: &[ThemeAttr::StrokeWidth], fn_css_classes, } } @@ -869,8 +869,8 @@ impl StrokeParamGroupings { ThemeAttr::ShapeColor, ], shade_keys: &[ThemeAttr::StrokeShadeHover, ThemeAttr::StrokeShade], - stroke_style_keys: &[ThemeAttr::StrokeStyleHover, ThemeAttr::StrokeStyle], - stroke_width_keys: &[ThemeAttr::StrokeWidth], + line_style_keys: &[ThemeAttr::StrokeStyleHover, ThemeAttr::StrokeStyle], + line_width_keys: &[ThemeAttr::StrokeWidth], fn_css_classes, } } @@ -886,8 +886,8 @@ impl StrokeParamGroupings { ThemeAttr::ShapeColor, ], shade_keys: &[ThemeAttr::StrokeShadeActive, ThemeAttr::StrokeShade], - stroke_style_keys: &[ThemeAttr::StrokeStyleActive, ThemeAttr::StrokeStyle], - stroke_width_keys: &[ThemeAttr::StrokeWidth], + line_style_keys: &[ThemeAttr::StrokeStyleActive, ThemeAttr::StrokeStyle], + line_width_keys: &[ThemeAttr::StrokeWidth], fn_css_classes, } } @@ -899,8 +899,8 @@ impl StrokeParamGroupings { highlight_state: HighlightState::Normal, color_keys: &[ThemeAttr::OutlineColorNormal, ThemeAttr::OutlineColor], shade_keys: &[ThemeAttr::OutlineShadeNormal, ThemeAttr::OutlineShade], - stroke_style_keys: &[ThemeAttr::OutlineStyleNormal, ThemeAttr::OutlineStyle], - stroke_width_keys: &[ThemeAttr::OutlineWidth], + line_style_keys: &[ThemeAttr::OutlineStyleNormal, ThemeAttr::OutlineStyle], + line_width_keys: &[ThemeAttr::OutlineWidth], fn_css_classes, } } @@ -912,8 +912,8 @@ impl StrokeParamGroupings { highlight_state: HighlightState::Focus, color_keys: &[ThemeAttr::OutlineColorFocus, ThemeAttr::OutlineColor], shade_keys: &[ThemeAttr::OutlineShadeFocus, ThemeAttr::OutlineShade], - stroke_style_keys: &[ThemeAttr::OutlineStyleFocus, ThemeAttr::OutlineStyle], - stroke_width_keys: &[ThemeAttr::OutlineWidth], + line_style_keys: &[ThemeAttr::OutlineStyleFocus, ThemeAttr::OutlineStyle], + line_width_keys: &[ThemeAttr::OutlineWidth], fn_css_classes, } } @@ -925,8 +925,8 @@ impl StrokeParamGroupings { highlight_state: HighlightState::Hover, color_keys: &[ThemeAttr::OutlineColorHover, ThemeAttr::OutlineColor], shade_keys: &[ThemeAttr::OutlineShadeHover, ThemeAttr::OutlineShade], - stroke_style_keys: &[ThemeAttr::OutlineStyleHover, ThemeAttr::OutlineStyle], - stroke_width_keys: &[ThemeAttr::OutlineWidth], + line_style_keys: &[ThemeAttr::OutlineStyleHover, ThemeAttr::OutlineStyle], + line_width_keys: &[ThemeAttr::OutlineWidth], fn_css_classes, } } @@ -938,19 +938,21 @@ impl StrokeParamGroupings { highlight_state: HighlightState::Active, color_keys: &[ThemeAttr::OutlineColorActive, ThemeAttr::OutlineColor], shade_keys: &[ThemeAttr::OutlineShadeActive, ThemeAttr::OutlineShade], - stroke_style_keys: &[ThemeAttr::OutlineStyleActive, ThemeAttr::OutlineStyle], - stroke_width_keys: &[ThemeAttr::OutlineWidth], + line_style_keys: &[ThemeAttr::OutlineStyleActive, ThemeAttr::OutlineStyle], + line_width_keys: &[ThemeAttr::OutlineWidth], fn_css_classes, } } } -/// Stroke attributes that were specified but not used, due to not a complete +/// Line attributes that were specified but not used, due to not a complete /// set of attributes provided to compute a CSS class. /// +/// "Line" applies to both `stroke-*` and `outline-*` classes. +/// /// The `ThemeAttr` in each `NoChange` variant is the `ThemeAttr` that is /// specified, i.e. one of the fallbacks. -enum StrokeClassAppendResult<'value> { +enum LineClassAppendResult<'value> { Added, NoChange { style: Option<(ThemeAttr, &'value str)>, diff --git a/crate/model/src/theme/stroke_params.rs b/crate/model/src/theme/line_params.rs similarity index 56% rename from crate/model/src/theme/stroke_params.rs rename to crate/model/src/theme/line_params.rs index 29e5cc5..8ea8670 100644 --- a/crate/model/src/theme/stroke_params.rs +++ b/crate/model/src/theme/line_params.rs @@ -2,26 +2,28 @@ use crate::theme::ColorParams; /// Parameters to compute `CssClasses`. #[derive(Clone, Copy, Debug, PartialEq, Eq)] -pub struct StrokeParams<'params> { +pub struct LineParams<'params> { /// Parameters to compute colour related `CssClasses`. pub color_params: ColorParams<'params>, /// Width that the line should be, e.g. `"1"`. - pub stroke_width: &'params str, + /// + /// Corresponds to either `stroke-width` or `outline-width`. + pub line_width: &'params str, /// Style that the line should be, e.g. `"dashed"`. - pub stroke_style: &'params str, + pub line_style: &'params str, } -impl<'params> StrokeParams<'params> { - /// Returns a new `StrokeParams`. +impl<'params> LineParams<'params> { + /// Returns a new `LineParams`. pub fn new( color_params: ColorParams<'params>, - stroke_width: &'params str, - stroke_style: &'params str, + line_width: &'params str, + line_style: &'params str, ) -> Self { Self { color_params, - stroke_width, - stroke_style, + line_width, + line_style, } } } diff --git a/crate/model/src/theme/themeable.rs b/crate/model/src/theme/themeable.rs index 5adbdf0..6f62de7 100644 --- a/crate/model/src/theme/themeable.rs +++ b/crate/model/src/theme/themeable.rs @@ -1,6 +1,6 @@ use crate::{ common::{EdgeId, NodeId}, - theme::{ColorParams, CssClassesBuilder, StrokeParams}, + theme::{ColorParams, CssClassesBuilder, LineParams}, }; /// Types that can be rendered into a CSS compatible format, e.g. SVG or HTML @@ -21,12 +21,8 @@ pub trait Themeable { /// # Parameters /// /// * `builder`: The builder to append CSS classes. - /// * `stroke_params`: Parameters for the CSS utility class. - fn node_outline_classes( - &self, - builder: &mut CssClassesBuilder, - stroke_params: StrokeParams<'_>, - ); + /// * `line_params`: Parameters for the CSS utility class. + fn node_outline_classes(&self, builder: &mut CssClassesBuilder, line_params: LineParams<'_>); /// Appends the CSS classes that sets the line / border colour and style. /// @@ -38,8 +34,8 @@ pub trait Themeable { /// # Parameters /// /// * `builder`: The builder to append CSS classes. - /// * `stroke_params`: Parameters for the CSS utility class. - fn node_stroke_classes(&self, builder: &mut CssClassesBuilder, stroke_params: StrokeParams<'_>); + /// * `line_params`: Parameters for the CSS utility class. + fn node_stroke_classes(&self, builder: &mut CssClassesBuilder, line_params: LineParams<'_>); /// Appends the CSS classes that sets the background colour and style. /// @@ -69,12 +65,8 @@ pub trait Themeable { /// # Parameters /// /// * `builder`: The builder to append CSS classes. - /// * `stroke_params`: Parameters for the CSS utility class. - fn edge_outline_classes( - &self, - builder: &mut CssClassesBuilder, - stroke_params: StrokeParams<'_>, - ); + /// * `line_params`: Parameters for the CSS utility class. + fn edge_outline_classes(&self, builder: &mut CssClassesBuilder, line_params: LineParams<'_>); /// Appends the CSS classes that sets the stroke colour and style. /// @@ -86,8 +78,8 @@ pub trait Themeable { /// # Parameters /// /// * `builder`: The builder to append CSS classes. - /// * `stroke_params`: Parameters for the CSS utility class. - fn edge_stroke_classes(&self, builder: &mut CssClassesBuilder, stroke_params: StrokeParams<'_>); + /// * `line_params`: Parameters for the CSS utility class. + fn edge_stroke_classes(&self, builder: &mut CssClassesBuilder, line_params: LineParams<'_>); /// Appends the CSS classes that sets the background colour and style. /// diff --git a/crate/rt/src/info_graph_dot.rs b/crate/rt/src/info_graph_dot.rs index 81adf6e..4c95d3f 100644 --- a/crate/rt/src/info_graph_dot.rs +++ b/crate/rt/src/info_graph_dot.rs @@ -1,6 +1,6 @@ use dot_ix_model::{ common::{EdgeId, NodeId}, - theme::{ColorParams, CssClassesBuilder, HighlightState, StrokeParams, Themeable}, + theme::{ColorParams, CssClassesBuilder, HighlightState, LineParams, Themeable}, }; #[derive(Clone)] @@ -17,51 +17,43 @@ impl<'graph> Themeable for InfoGraphDot<'graph> { self.node_ids.iter().copied() } - fn node_outline_classes( - &self, - builder: &mut CssClassesBuilder, - stroke_params: StrokeParams<'_>, - ) { - let StrokeParams { + fn node_outline_classes(&self, builder: &mut CssClassesBuilder, line_params: LineParams<'_>) { + let LineParams { color_params, - stroke_width, - stroke_style, - } = stroke_params; + line_width, + line_style, + } = line_params; path_color_classes(builder, color_params, "outline"); outline_style_classes( builder, color_params.highlight_state, - stroke_width, - stroke_style, + line_width, + line_style, "[&>path]:", ); outline_style_classes( builder, color_params.highlight_state, - stroke_width, - stroke_style, + line_width, + line_style, "[&>ellipse]:", ); } - fn node_stroke_classes( - &self, - builder: &mut CssClassesBuilder, - stroke_params: StrokeParams<'_>, - ) { - let StrokeParams { + fn node_stroke_classes(&self, builder: &mut CssClassesBuilder, line_params: LineParams<'_>) { + let LineParams { color_params, - stroke_width, - stroke_style, - } = stroke_params; + line_width, + line_style, + } = line_params; path_color_classes(builder, color_params, "stroke"); border_style_classes( builder, color_params.highlight_state, - stroke_width, - stroke_style, + line_width, + line_style, ); } @@ -76,45 +68,37 @@ impl<'graph> Themeable for InfoGraphDot<'graph> { self.edge_ids.iter().copied() } - fn edge_outline_classes( - &self, - builder: &mut CssClassesBuilder, - stroke_params: StrokeParams<'_>, - ) { - let StrokeParams { + fn edge_outline_classes(&self, builder: &mut CssClassesBuilder, line_params: LineParams<'_>) { + let LineParams { color_params, - stroke_width, - stroke_style, - } = stroke_params; + line_width, + line_style, + } = line_params; el_color_classes(builder, color_params, "outline", ""); outline_style_classes( builder, color_params.highlight_state, - stroke_width, - stroke_style, + line_width, + line_style, "", ); } - fn edge_stroke_classes( - &self, - builder: &mut CssClassesBuilder, - stroke_params: StrokeParams<'_>, - ) { - let StrokeParams { + fn edge_stroke_classes(&self, builder: &mut CssClassesBuilder, line_params: LineParams<'_>) { + let LineParams { color_params, - stroke_width, - stroke_style, - } = stroke_params; + line_width, + line_style, + } = line_params; path_color_classes(builder, color_params, "stroke"); polygon_color_classes(builder, color_params, "stroke"); border_style_classes( builder, color_params.highlight_state, - stroke_width, - stroke_style, + line_width, + line_style, ); } @@ -128,18 +112,18 @@ impl<'graph> Themeable for InfoGraphDot<'graph> { fn outline_style_classes( builder: &mut CssClassesBuilder, highlight_state: HighlightState, - stroke_width: &str, - stroke_style: &str, + line_width: &str, + line_style: &str, el_prefix: &str, ) { let highlight_prefix = highlight_prefix(highlight_state); builder .append(&format!( - "{el_prefix}{highlight_prefix}outline-{stroke_width}" + "{el_prefix}{highlight_prefix}outline-{line_width}" )) .append(&format!( - "{el_prefix}{highlight_prefix}outline-{stroke_style}" + "{el_prefix}{highlight_prefix}outline-{line_style}" )); } @@ -147,26 +131,26 @@ fn outline_style_classes( fn border_style_classes( builder: &mut CssClassesBuilder, highlight_state: HighlightState, - stroke_width: &str, - stroke_style: &str, + line_width: &str, + line_style: &str, ) { let highlight_prefix = highlight_prefix(highlight_state); - match stroke_style { + match line_style { "none" => {} "solid" => { builder - .append(&format!("[&>path]:{highlight_prefix}stroke-{stroke_width}")) + .append(&format!("[&>path]:{highlight_prefix}stroke-{line_width}")) .append(&format!( - "[&>ellipse]:{highlight_prefix}stroke-{stroke_width}" + "[&>ellipse]:{highlight_prefix}stroke-{line_width}" )); } "dashed" => { builder - .append(&format!("[&>path]:{highlight_prefix}stroke-{stroke_width}")) + .append(&format!("[&>path]:{highlight_prefix}stroke-{line_width}")) .append(&format!("[&>path]:{highlight_prefix}[stroke-dasharray:3]")) .append(&format!( - "[&>ellipse]:{highlight_prefix}stroke-{stroke_width}" + "[&>ellipse]:{highlight_prefix}stroke-{line_width}" )) .append(&format!( "[&>ellipse]:{highlight_prefix}[stroke-dasharray:3]" @@ -174,26 +158,24 @@ fn border_style_classes( } "dotted" => { builder - .append(&format!("[&>path]:{highlight_prefix}stroke-{stroke_width}")) + .append(&format!("[&>path]:{highlight_prefix}stroke-{line_width}")) .append(&format!("[&>path]:{highlight_prefix}[stroke-dasharray:2]")) .append(&format!( - "[&>ellipse]:{highlight_prefix}stroke-{stroke_width}" + "[&>ellipse]:{highlight_prefix}stroke-{line_width}" )) .append(&format!( "[&>ellipse]:{highlight_prefix}[stroke-dasharray:2]" )); } - stroke_style if stroke_style.starts_with("dasharray:") => { + line_style if line_style.starts_with("dasharray:") => { builder - .append(&format!("[&>path]:{highlight_prefix}stroke-{stroke_width}")) + .append(&format!("[&>path]:{highlight_prefix}stroke-{line_width}")) + .append(&format!("[&>path]:{highlight_prefix}[stroke-{line_style}]")) .append(&format!( - "[&>path]:{highlight_prefix}[stroke-{stroke_style}]" + "[&>ellipse]:{highlight_prefix}stroke-{line_width}" )) .append(&format!( - "[&>ellipse]:{highlight_prefix}stroke-{stroke_width}" - )) - .append(&format!( - "[&>ellipse]:{highlight_prefix}[stroke-{stroke_style}]" + "[&>ellipse]:{highlight_prefix}[stroke-{line_style}]" )); } _ => {} diff --git a/crate/rt/src/info_graph_html.rs b/crate/rt/src/info_graph_html.rs index 70f827e..b8be31d 100644 --- a/crate/rt/src/info_graph_html.rs +++ b/crate/rt/src/info_graph_html.rs @@ -2,7 +2,7 @@ use std::borrow::Cow; use dot_ix_model::{ common::{EdgeId, NodeId}, - theme::{ColorParams, CssClassesBuilder, HighlightState, StrokeParams, Themeable}, + theme::{ColorParams, CssClassesBuilder, HighlightState, LineParams, Themeable}, }; #[derive(Clone)] @@ -19,43 +19,35 @@ impl<'graph> Themeable for InfoGraphHtml<'graph> { self.node_ids.iter().copied() } - fn node_outline_classes( - &self, - builder: &mut CssClassesBuilder, - stroke_params: StrokeParams<'_>, - ) { - let StrokeParams { + fn node_outline_classes(&self, builder: &mut CssClassesBuilder, line_params: LineParams<'_>) { + let LineParams { color_params, - stroke_width, + line_width, stroke_style, - } = stroke_params; + } = line_params; el_color_classes(builder, color_params, "outline"); stroke_style_classes( builder, color_params.highlight_state, - stroke_width, + line_width, stroke_style, "outline", ); } - fn node_stroke_classes( - &self, - builder: &mut CssClassesBuilder, - stroke_params: StrokeParams<'_>, - ) { - let StrokeParams { + fn node_stroke_classes(&self, builder: &mut CssClassesBuilder, line_params: LineParams<'_>) { + let LineParams { color_params, - stroke_width, + line_width, stroke_style, - } = stroke_params; + } = line_params; el_color_classes(builder, color_params, "border"); stroke_style_classes( builder, color_params.highlight_state, - stroke_width, + line_width, stroke_style, "border", ); @@ -72,43 +64,35 @@ impl<'graph> Themeable for InfoGraphHtml<'graph> { self.edge_ids.iter().copied() } - fn edge_outline_classes( - &self, - builder: &mut CssClassesBuilder, - stroke_params: StrokeParams<'_>, - ) { - let StrokeParams { + fn edge_outline_classes(&self, builder: &mut CssClassesBuilder, line_params: LineParams<'_>) { + let LineParams { color_params, - stroke_width, + line_width, stroke_style, - } = stroke_params; + } = line_params; el_color_classes(builder, color_params, "outline"); stroke_style_classes( builder, color_params.highlight_state, - stroke_width, + line_width, stroke_style, "outline", ); } - fn edge_stroke_classes( - &self, - builder: &mut CssClassesBuilder, - stroke_params: StrokeParams<'_>, - ) { - let StrokeParams { + fn edge_stroke_classes(&self, builder: &mut CssClassesBuilder, line_params: LineParams<'_>) { + let LineParams { color_params, - stroke_width, + line_width, stroke_style, - } = stroke_params; + } = line_params; el_color_classes(builder, color_params, "border"); stroke_style_classes( builder, color_params.highlight_state, - stroke_width, + line_width, stroke_style, "border", ); @@ -122,20 +106,20 @@ impl<'graph> Themeable for InfoGraphHtml<'graph> { fn stroke_style_classes( builder: &mut CssClassesBuilder, highlight_state: HighlightState, - stroke_width: &str, + line_width: &str, stroke_style: &str, stroke_prefix: &str, ) { let highlight_prefix = highlight_prefix(highlight_state); - let stroke_width = if stroke_style == "dotted" { - stroke_width_increment(stroke_width) + let line_width = if stroke_style == "dotted" { + line_width_increment(line_width) } else { - Cow::Borrowed(stroke_width) + Cow::Borrowed(line_width) }; builder .append(&format!( - "{highlight_prefix}{stroke_prefix}-[{stroke_width}px]" + "{highlight_prefix}{stroke_prefix}-[{line_width}px]" )) .append(&format!("{highlight_prefix}{stroke_prefix}-{stroke_style}")); } @@ -146,12 +130,12 @@ fn stroke_style_classes( /// differ: /// /// * SVG's stroke-1 looks similar to HTML's border-2 -fn stroke_width_increment(stroke_width: &str) -> Cow<'_, str> { - let (Ok(stroke_width) | Err(stroke_width)) = stroke_width +fn line_width_increment(line_width: &str) -> Cow<'_, str> { + let (Ok(line_width) | Err(line_width)) = line_width .parse::() .map(|w| Cow::Owned(w.saturating_add(1).to_string())) - .map_err(|_| Cow::Borrowed(stroke_width)); - stroke_width + .map_err(|_| Cow::Borrowed(line_width)); + line_width } fn el_color_classes( From 3929fa1ac0c379ab60c2d9a62f9598f07c49ced3 Mon Sep 17 00:00:00 2001 From: Azriel Hoh Date: Tue, 6 Aug 2024 16:31:43 +1200 Subject: [PATCH 04/15] Add `CssClassMergeParams` to reduce number of parameters passed. --- crate/model/src/theme/css_class_merger.rs | 171 +++++++++++----------- 1 file changed, 88 insertions(+), 83 deletions(-) diff --git a/crate/model/src/theme/css_class_merger.rs b/crate/model/src/theme/css_class_merger.rs index df6febe..7452040 100644 --- a/crate/model/src/theme/css_class_merger.rs +++ b/crate/model/src/theme/css_class_merger.rs @@ -21,7 +21,12 @@ impl CssClassMerger { where T: Themeable, { - Self::node_classes_calculate(defaults, specified, themeable, StyleFor::Regular) + let css_class_merge_params = CssClassMergeParams { + defaults, + specified, + themeable, + }; + Self::node_classes_calculate(css_class_merge_params, StyleFor::Regular) } /// Returns the CSS classes for a node associated with a tag. @@ -34,21 +39,21 @@ impl CssClassMerger { where T: Themeable, { - Self::node_classes_calculate(defaults, specified, themeable, StyleFor::TagFocus(tag_id)) + let css_class_merge_params = CssClassMergeParams { + defaults, + specified, + themeable, + }; + Self::node_classes_calculate(css_class_merge_params, StyleFor::TagFocus(tag_id)) } /// Returns the CSS classes for a node in a particular themeable rendering. /// /// This merges the specified themed values over the defaults. - fn node_classes_calculate( - defaults: Option<&CssClassPartials>, - specified: Option<&CssClassPartials>, - themeable: &T, + fn node_classes_calculate( + css_class_merge_params: CssClassMergeParams<'_>, style_for: StyleFor<'_>, - ) -> CssClassesAndWarnings - where - T: Themeable, - { + ) -> CssClassesAndWarnings { let mut css_classes_builder = CssClassesBuilder::new(style_for); let mut warnings = ThemeWarnings::new(); @@ -74,33 +79,33 @@ impl CssClassMerger { }; Self::outline_classes_append( + css_class_merge_params, &mut css_classes_builder, &mut warnings, themeable_node_outline_classes, - defaults, - specified, - themeable, style_for, ); Self::stroke_classes_append( + css_class_merge_params, &mut css_classes_builder, &mut warnings, themeable_node_stroke_classes, - defaults, - specified, - themeable, style_for, ); Self::fill_classes_append( + css_class_merge_params, &mut css_classes_builder, &mut warnings, themeable_node_fill_classes, - defaults, - specified, - themeable, style_for, ); + let CssClassMergeParams { + defaults, + specified, + themeable: _, + } = css_class_merge_params; + [ SpacingParamGroupings::new("px", &[ThemeAttr::PaddingX, ThemeAttr::Padding]), SpacingParamGroupings::new("py", &[ThemeAttr::PaddingY, ThemeAttr::Padding]), @@ -142,7 +147,12 @@ impl CssClassMerger { where T: Themeable, { - Self::edge_classes_calculate(defaults, specified, themeable, StyleFor::Regular) + let css_class_merge_params = CssClassMergeParams { + defaults, + specified, + themeable, + }; + Self::edge_classes_calculate(css_class_merge_params, StyleFor::Regular) } /// Returns the CSS classes for an edge associated with a tag. @@ -155,21 +165,21 @@ impl CssClassMerger { where T: Themeable, { - Self::edge_classes_calculate(defaults, specified, themeable, StyleFor::TagFocus(tag_id)) + let css_class_merge_params = CssClassMergeParams { + defaults, + specified, + themeable, + }; + Self::edge_classes_calculate(css_class_merge_params, StyleFor::TagFocus(tag_id)) } /// Returns the CSS classes for an edge in a particular themeable rendering. /// /// This merges the specified themed values over the defaults. - fn edge_classes_calculate( - defaults: Option<&CssClassPartials>, - specified: Option<&CssClassPartials>, - themeable: &T, + fn edge_classes_calculate( + css_class_merge_params: CssClassMergeParams<'_>, style_for: StyleFor<'_>, - ) -> CssClassesAndWarnings - where - T: Themeable, - { + ) -> CssClassesAndWarnings { let mut css_classes_builder = CssClassesBuilder::new(style_for); let mut warnings = ThemeWarnings::new(); @@ -195,33 +205,33 @@ impl CssClassMerger { }; Self::outline_classes_append( + css_class_merge_params, &mut css_classes_builder, &mut warnings, themeable_edge_outline_classes, - defaults, - specified, - themeable, style_for, ); Self::stroke_classes_append( + css_class_merge_params, &mut css_classes_builder, &mut warnings, themeable_edge_stroke_classes, - defaults, - specified, - themeable, style_for, ); Self::fill_classes_append( + css_class_merge_params, &mut css_classes_builder, &mut warnings, themeable_edge_fill_classes, - defaults, - specified, - themeable, style_for, ); + let CssClassMergeParams { + defaults, + specified, + themeable: _, + } = css_class_merge_params; + Self::animation_classes(&mut css_classes_builder, defaults, specified); Self::visibility_classes(&mut css_classes_builder, defaults, specified); Self::cursor_classes(&mut css_classes_builder, defaults, specified); @@ -233,12 +243,10 @@ impl CssClassMerger { } fn outline_classes_append( + css_class_merge_params: CssClassMergeParams<'_>, css_classes_builder: &mut CssClassesBuilder, warnings: &mut ThemeWarnings, fn_outline_classes: fn(&dyn Themeable, &mut CssClassesBuilder, LineParams<'_>), - defaults: Option<&CssClassPartials>, - specified: Option<&CssClassPartials>, - themeable: &dyn Themeable, style_for: StyleFor<'_>, ) { let line_class_append_result = match style_for { @@ -251,10 +259,8 @@ impl CssClassMerger { ] .into_iter(); Self::line_classes_fold( + css_class_merge_params, css_classes_builder, - defaults, - specified, - themeable, param_groupings, ) } @@ -264,10 +270,8 @@ impl CssClassMerger { [LineParamGroupings::new_outline_normal(fn_outline_classes)].into_iter(); Self::line_classes_fold( + css_class_merge_params, css_classes_builder, - defaults, - specified, - themeable, param_groupings, ) } @@ -319,12 +323,10 @@ impl CssClassMerger { /// Appends CSS classes for stroke styling for all [`HighlightState`]s to /// the CSS classes builder. fn stroke_classes_append( + css_class_merge_params: CssClassMergeParams<'_>, css_classes_builder: &mut CssClassesBuilder, warnings: &mut ThemeWarnings, fn_stroke_classes: fn(&dyn Themeable, &mut CssClassesBuilder, LineParams<'_>), - defaults: Option<&CssClassPartials>, - specified: Option<&CssClassPartials>, - themeable: &dyn Themeable, style_for: StyleFor<'_>, ) { let line_class_append_result = match style_for { @@ -338,10 +340,8 @@ impl CssClassMerger { ] .into_iter(); Self::line_classes_fold( + css_class_merge_params, css_classes_builder, - defaults, - specified, - themeable, param_groupings, ) } @@ -351,10 +351,8 @@ impl CssClassMerger { [LineParamGroupings::new_stroke_normal(fn_stroke_classes)].into_iter(); Self::line_classes_fold( + css_class_merge_params, css_classes_builder, - defaults, - specified, - themeable, param_groupings, ) } @@ -406,12 +404,16 @@ impl CssClassMerger { /// Appends CSS classes for stroke styling for a given [`HighlightState`] to /// the CSS classes builder. fn line_classes_highlight_state_append<'f1, 'f2: 'f1>( + css_class_merge_params: CssClassMergeParams<'f2>, css_classes_builder: &mut CssClassesBuilder, css_classes_param_groupings: &LineParamGroupings>, - defaults: Option<&'f2 CssClassPartials>, - specified: Option<&'f2 CssClassPartials>, - themeable: &dyn Themeable, ) -> LineClassAppendResult<'f2> { + let CssClassMergeParams { + defaults, + specified, + themeable, + } = css_class_merge_params; + let LineParamGroupings { highlight_state, color_keys, @@ -459,12 +461,10 @@ impl CssClassMerger { /// Appends CSS classes for fill styling for all [`HighlightState`]s to /// the CSS classes builder. fn fill_classes_append( + css_class_merge_params: CssClassMergeParams<'_>, css_classes_builder: &mut CssClassesBuilder, warnings: &mut ThemeWarnings, fn_fill_classes: fn(&dyn Themeable, &mut CssClassesBuilder, ColorParams<'_>), - defaults: Option<&CssClassPartials>, - specified: Option<&CssClassPartials>, - themeable: &dyn Themeable, style_for: StyleFor<'_>, ) { let fill_class_append_result = match style_for { @@ -478,10 +478,8 @@ impl CssClassMerger { ] .into_iter(); Self::fill_classes_fold( + css_class_merge_params, css_classes_builder, - defaults, - specified, - themeable, param_groupings, ) } @@ -491,10 +489,8 @@ impl CssClassMerger { [ColorParamGroupings::new_fill_normal(fn_fill_classes)].into_iter(); Self::fill_classes_fold( + css_class_merge_params, css_classes_builder, - defaults, - specified, - themeable, param_groupings, ) } @@ -533,12 +529,16 @@ impl CssClassMerger { /// Appends CSS classes for fill styling for a given [`HighlightState`]s to /// the CSS classes builder. fn fill_classes_highlight_state_append<'f1, 'f2: 'f1>( + css_class_merge_params: CssClassMergeParams<'f2>, css_classes_param_groupings: ColorParamGroupings>, - defaults: Option<&'f2 CssClassPartials>, - specified: Option<&'f2 CssClassPartials>, - themeable: &dyn Themeable, css_classes_builder: &mut CssClassesBuilder, ) -> FillClassAppendResult<'f2> { + let CssClassMergeParams { + defaults, + specified, + themeable, + } = css_class_merge_params; + let ColorParamGroupings { highlight_state, color_keys, @@ -615,10 +615,8 @@ impl CssClassMerger { /// Since the param groupings are arrays of different sizes, we need to have /// a generic function to cater for different concrete types. fn line_classes_fold<'f, I>( + css_class_merge_params: CssClassMergeParams<'f>, css_classes_builder: &mut CssClassesBuilder, - defaults: Option<&'f CssClassPartials>, - specified: Option<&'f CssClassPartials>, - themeable: &dyn Themeable, param_groupings: I, ) -> Vec> where @@ -628,11 +626,9 @@ impl CssClassMerger { Vec::new(), |mut line_class_append_result_acc, css_classes_param_groupings| { let line_class_append_result = Self::line_classes_highlight_state_append( + css_class_merge_params, css_classes_builder, &css_classes_param_groupings, - defaults, - specified, - themeable, ); line_class_append_result_acc.push(line_class_append_result); @@ -645,10 +641,8 @@ impl CssClassMerger { /// Since the param groupings are arrays of different sizes, we need to have /// a generic function to cater for different concrete types. fn fill_classes_fold<'f, I>( + css_class_merge_params: CssClassMergeParams<'f>, css_classes_builder: &mut CssClassesBuilder, - defaults: Option<&'f CssClassPartials>, - specified: Option<&'f CssClassPartials>, - themeable: &dyn Themeable, param_groupings: I, ) -> Vec> where @@ -658,10 +652,8 @@ impl CssClassMerger { Vec::new(), |mut fill_class_append_result_acc, css_classes_param_groupings| { let fill_class_append_result = Self::fill_classes_highlight_state_append( + css_class_merge_params, css_classes_param_groupings, - defaults, - specified, - themeable, css_classes_builder, ); @@ -698,7 +690,16 @@ fn attr_value_find<'attr>( }) } +/// Grouping of common parameters to reduce parameter count in methods. +#[derive(Clone, Copy)] +struct CssClassMergeParams<'params> { + defaults: Option<&'params CssClassPartials>, + specified: Option<&'params CssClassPartials>, + themeable: &'params dyn Themeable, +} + /// Groupings of parameters to generate CSS classes for spacing. +#[derive(Clone, Copy)] struct SpacingParamGroupings { spacing_prefix: &'static str, spacing_keys: &'static [ThemeAttr], @@ -714,6 +715,7 @@ impl SpacingParamGroupings { } /// Groupings of parameters to generate CSS classes for colour shades. +#[derive(Clone, Copy)] struct ColorParamGroupings { highlight_state: HighlightState, /// List of keys to fallback on. @@ -794,6 +796,7 @@ impl ColorParamGroupings { } /// Groupings of parameters to generate CSS classes for colour shades. +#[derive(Clone, Copy)] struct LineParamGroupings { highlight_state: HighlightState, /// List of keys to fallback on. @@ -952,6 +955,7 @@ impl LineParamGroupings { /// /// The `ThemeAttr` in each `NoChange` variant is the `ThemeAttr` that is /// specified, i.e. one of the fallbacks. +#[derive(Clone, Copy)] enum LineClassAppendResult<'value> { Added, NoChange { @@ -968,6 +972,7 @@ enum LineClassAppendResult<'value> { /// /// The `ThemeAttr` in each `NoChange` variant is the `ThemeAttr` that is /// specified, i.e. one of the fallbacks. +#[derive(Clone, Copy)] enum FillClassAppendResult<'value> { Added, NoChange { From 03608b387c47eccd9618fbb5cb2ac988688e4520 Mon Sep 17 00:00:00 2001 From: Azriel Hoh Date: Tue, 6 Aug 2024 19:40:12 +1200 Subject: [PATCH 05/15] Fix `stroke_style` -> `line_style` in `InfoGraphHtml`. --- crate/rt/src/info_graph_html.rs | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/crate/rt/src/info_graph_html.rs b/crate/rt/src/info_graph_html.rs index b8be31d..7a46fcc 100644 --- a/crate/rt/src/info_graph_html.rs +++ b/crate/rt/src/info_graph_html.rs @@ -23,15 +23,15 @@ impl<'graph> Themeable for InfoGraphHtml<'graph> { let LineParams { color_params, line_width, - stroke_style, + line_style, } = line_params; el_color_classes(builder, color_params, "outline"); - stroke_style_classes( + line_style_classes( builder, color_params.highlight_state, line_width, - stroke_style, + line_style, "outline", ); } @@ -40,15 +40,15 @@ impl<'graph> Themeable for InfoGraphHtml<'graph> { let LineParams { color_params, line_width, - stroke_style, + line_style, } = line_params; el_color_classes(builder, color_params, "border"); - stroke_style_classes( + line_style_classes( builder, color_params.highlight_state, line_width, - stroke_style, + line_style, "border", ); } @@ -68,15 +68,15 @@ impl<'graph> Themeable for InfoGraphHtml<'graph> { let LineParams { color_params, line_width, - stroke_style, + line_style, } = line_params; el_color_classes(builder, color_params, "outline"); - stroke_style_classes( + line_style_classes( builder, color_params.highlight_state, line_width, - stroke_style, + line_style, "outline", ); } @@ -85,15 +85,15 @@ impl<'graph> Themeable for InfoGraphHtml<'graph> { let LineParams { color_params, line_width, - stroke_style, + line_style, } = line_params; el_color_classes(builder, color_params, "border"); - stroke_style_classes( + line_style_classes( builder, color_params.highlight_state, line_width, - stroke_style, + line_style, "border", ); } @@ -103,15 +103,15 @@ impl<'graph> Themeable for InfoGraphHtml<'graph> { } } -fn stroke_style_classes( +fn line_style_classes( builder: &mut CssClassesBuilder, highlight_state: HighlightState, line_width: &str, - stroke_style: &str, + line_style: &str, stroke_prefix: &str, ) { let highlight_prefix = highlight_prefix(highlight_state); - let line_width = if stroke_style == "dotted" { + let line_width = if line_style == "dotted" { line_width_increment(line_width) } else { Cow::Borrowed(line_width) @@ -121,7 +121,7 @@ fn stroke_style_classes( .append(&format!( "{highlight_prefix}{stroke_prefix}-[{line_width}px]" )) - .append(&format!("{highlight_prefix}{stroke_prefix}-{stroke_style}")); + .append(&format!("{highlight_prefix}{stroke_prefix}-{line_style}")); } /// Increments 1 to the stroke width if parseable. From 471d2844b6274b2b664df44bf6fd8f75040e969f Mon Sep 17 00:00:00 2001 From: Azriel Hoh Date: Tue, 6 Aug 2024 20:13:04 +1200 Subject: [PATCH 06/15] Update `Themeable`s to generate classes with knowledge of node/edge id. --- crate/model/src/theme.rs | 29 ++-- crate/model/src/theme/css_class_merger.rs | 95 ++++++++----- crate/model/src/theme/themeable.rs | 44 +++++- crate/rt/src/info_graph_dot.rs | 126 +++++++++++------- crate/rt/src/info_graph_html.rs | 44 +++++- .../src/into_graphviz_dot_src/info_graph.rs | 6 +- workspace_tests/src/model/theme.rs | 81 +++++++---- 7 files changed, 295 insertions(+), 130 deletions(-) diff --git a/crate/model/src/theme.rs b/crate/model/src/theme.rs index fcac620..93b73bb 100644 --- a/crate/model/src/theme.rs +++ b/crate/model/src/theme.rs @@ -168,7 +168,6 @@ impl Theme { node_defaults }); - let mut theme = Self::default(); theme.insert(AnyIdOrDefaults::EdgeDefaults, { let mut edge_defaults = CssClassPartials::new(); @@ -274,17 +273,18 @@ impl Theme { T: Themeable, { let node_class_partials_defaults = self.get(&AnyIdOrDefaults::NodeDefaults); - themeable.node_ids().filter_map(move |node_id| { + themeable.node_ids().map(move |node_id| { let node_class_partials_specified = self.node_class_partials_specified(node_id); - let any_id = Some(AnyId::from(node_id.clone())); + let any_id = AnyId::from(node_id.clone()); let node_classes_and_warnings = CssClassMerger::node_classes( + &any_id, node_class_partials_defaults, node_class_partials_specified, themeable, ); - any_id.map(|any_id| (any_id, node_classes_and_warnings)) + (any_id, node_classes_and_warnings) }) } @@ -307,17 +307,18 @@ impl Theme { { let edge_class_partials_defaults = self.get(&AnyIdOrDefaults::EdgeDefaults); - themeable.edge_ids().filter_map(move |edge_id| { + themeable.edge_ids().map(move |edge_id| { let edge_class_partials_specified = self.edge_class_partials_specified(edge_id); - let any_id = Some(AnyId::from(edge_id.clone())); + let any_id = AnyId::from(edge_id.clone()); let edge_classes_and_warnings = CssClassMerger::edge_classes( + &any_id, edge_class_partials_defaults, edge_class_partials_specified, themeable, ); - any_id.map(|any_id| (any_id, edge_classes_and_warnings)) + (any_id, edge_classes_and_warnings) }) } @@ -393,18 +394,19 @@ impl Theme { T: Themeable, { let node_class_partials_defaults = self.get(&AnyIdOrDefaults::NodeDefaults); - themeable.node_ids().filter_map(move |node_id| { + themeable.node_ids().map(move |node_id| { let node_class_partials_specified = self.node_class_partials_specified(node_id); - let any_id = Some(AnyId::from(node_id.clone())); + let any_id = AnyId::from(node_id.clone()); let node_classes_and_warnings = CssClassMerger::node_tag_classes( + &any_id, node_class_partials_defaults, node_class_partials_specified, themeable, tag_id, ); - any_id.map(|any_id| (any_id, node_classes_and_warnings)) + (any_id, node_classes_and_warnings) }) } @@ -418,18 +420,19 @@ impl Theme { { let edge_class_partials_defaults = self.get(&AnyIdOrDefaults::EdgeDefaults); - themeable.edge_ids().filter_map(move |edge_id| { + themeable.edge_ids().map(move |edge_id| { let edge_class_partials_specified = self.edge_class_partials_specified(edge_id); - let any_id = Some(AnyId::from(edge_id.clone())); + let any_id = AnyId::from(edge_id.clone()); let edge_classes_and_warnings = CssClassMerger::edge_tag_classes( + &any_id, edge_class_partials_defaults, edge_class_partials_specified, themeable, tag_id, ); - any_id.map(|any_id| (any_id, edge_classes_and_warnings)) + (any_id, edge_classes_and_warnings) }) } } diff --git a/crate/model/src/theme/css_class_merger.rs b/crate/model/src/theme/css_class_merger.rs index 7452040..c7934f4 100644 --- a/crate/model/src/theme/css_class_merger.rs +++ b/crate/model/src/theme/css_class_merger.rs @@ -1,5 +1,5 @@ use crate::{ - common::TagId, + common::{AnyId, TagId}, theme::{ ColorParams, CssClassPartials, CssClassesAndWarnings, CssClassesBuilder, HighlightState, LineParams, StyleFor, ThemeAttr, ThemeWarnings, Themeable, @@ -14,6 +14,7 @@ impl CssClassMerger { /// /// This merges the specified themed values over the defaults. pub fn node_classes( + node_id: &AnyId, defaults: Option<&CssClassPartials>, specified: Option<&CssClassPartials>, themeable: &T, @@ -22,6 +23,7 @@ impl CssClassMerger { T: Themeable, { let css_class_merge_params = CssClassMergeParams { + any_id: node_id, defaults, specified, themeable, @@ -31,6 +33,7 @@ impl CssClassMerger { /// Returns the CSS classes for a node associated with a tag. pub fn node_tag_classes( + node_id: &AnyId, defaults: Option<&CssClassPartials>, specified: Option<&CssClassPartials>, themeable: &T, @@ -40,6 +43,7 @@ impl CssClassMerger { T: Themeable, { let css_class_merge_params = CssClassMergeParams { + any_id: node_id, defaults, specified, themeable, @@ -58,24 +62,27 @@ impl CssClassMerger { let mut warnings = ThemeWarnings::new(); let themeable_node_outline_classes = - |themeable: &dyn Themeable, + |node_id: &AnyId, + themeable: &dyn Themeable, css_classes_builder: &mut CssClassesBuilder, params: LineParams<'_>| { - themeable.node_outline_classes(css_classes_builder, params); + themeable.node_outline_classes(node_id, css_classes_builder, params); }; let themeable_node_stroke_classes = - |themeable: &dyn Themeable, + |node_id: &AnyId, + themeable: &dyn Themeable, css_classes_builder: &mut CssClassesBuilder, params: LineParams<'_>| { - themeable.node_stroke_classes(css_classes_builder, params); + themeable.node_stroke_classes(node_id, css_classes_builder, params); }; let themeable_node_fill_classes = - |themeable: &dyn Themeable, + |node_id: &AnyId, + themeable: &dyn Themeable, css_classes_builder: &mut CssClassesBuilder, params: ColorParams<'_>| { - themeable.node_fill_classes(css_classes_builder, params); + themeable.node_fill_classes(node_id, css_classes_builder, params); }; Self::outline_classes_append( @@ -101,6 +108,7 @@ impl CssClassMerger { ); let CssClassMergeParams { + any_id: _, defaults, specified, themeable: _, @@ -140,6 +148,7 @@ impl CssClassMerger { /// /// This merges the specified themed values over the defaults. pub fn edge_classes( + edge_id: &AnyId, defaults: Option<&CssClassPartials>, specified: Option<&CssClassPartials>, themeable: &T, @@ -148,6 +157,7 @@ impl CssClassMerger { T: Themeable, { let css_class_merge_params = CssClassMergeParams { + any_id: edge_id, defaults, specified, themeable, @@ -157,6 +167,7 @@ impl CssClassMerger { /// Returns the CSS classes for an edge associated with a tag. pub fn edge_tag_classes( + edge_id: &AnyId, defaults: Option<&CssClassPartials>, specified: Option<&CssClassPartials>, themeable: &T, @@ -166,6 +177,7 @@ impl CssClassMerger { T: Themeable, { let css_class_merge_params = CssClassMergeParams { + any_id: edge_id, defaults, specified, themeable, @@ -184,24 +196,27 @@ impl CssClassMerger { let mut warnings = ThemeWarnings::new(); let themeable_edge_outline_classes = - |themeable: &dyn Themeable, + |edge_id: &AnyId, + themeable: &dyn Themeable, css_classes_builder: &mut CssClassesBuilder, params: LineParams<'_>| { - themeable.edge_outline_classes(css_classes_builder, params); + themeable.edge_outline_classes(edge_id, css_classes_builder, params); }; let themeable_edge_stroke_classes = - |themeable: &dyn Themeable, + |edge_id: &AnyId, + themeable: &dyn Themeable, css_classes_builder: &mut CssClassesBuilder, params: LineParams<'_>| { - themeable.edge_stroke_classes(css_classes_builder, params); + themeable.edge_stroke_classes(edge_id, css_classes_builder, params); }; let themeable_edge_fill_classes = - |themeable: &dyn Themeable, + |edge_id: &AnyId, + themeable: &dyn Themeable, css_classes_builder: &mut CssClassesBuilder, params: ColorParams<'_>| { - themeable.edge_fill_classes(css_classes_builder, params); + themeable.edge_fill_classes(edge_id, css_classes_builder, params); }; Self::outline_classes_append( @@ -227,6 +242,7 @@ impl CssClassMerger { ); let CssClassMergeParams { + any_id: _, defaults, specified, themeable: _, @@ -246,7 +262,7 @@ impl CssClassMerger { css_class_merge_params: CssClassMergeParams<'_>, css_classes_builder: &mut CssClassesBuilder, warnings: &mut ThemeWarnings, - fn_outline_classes: fn(&dyn Themeable, &mut CssClassesBuilder, LineParams<'_>), + fn_outline_classes: fn(&AnyId, &dyn Themeable, &mut CssClassesBuilder, LineParams<'_>), style_for: StyleFor<'_>, ) { let line_class_append_result = match style_for { @@ -326,7 +342,7 @@ impl CssClassMerger { css_class_merge_params: CssClassMergeParams<'_>, css_classes_builder: &mut CssClassesBuilder, warnings: &mut ThemeWarnings, - fn_stroke_classes: fn(&dyn Themeable, &mut CssClassesBuilder, LineParams<'_>), + fn_stroke_classes: fn(&AnyId, &dyn Themeable, &mut CssClassesBuilder, LineParams<'_>), style_for: StyleFor<'_>, ) { let line_class_append_result = match style_for { @@ -409,6 +425,7 @@ impl CssClassMerger { css_classes_param_groupings: &LineParamGroupings>, ) -> LineClassAppendResult<'f2> { let CssClassMergeParams { + any_id, defaults, specified, themeable, @@ -446,7 +463,7 @@ impl CssClassMerger { line_style, }; - fn_css_classes(themeable, css_classes_builder, params); + fn_css_classes(any_id, themeable, css_classes_builder, params); LineClassAppendResult::Added } (style, width, color, shade) => LineClassAppendResult::NoChange { @@ -464,7 +481,7 @@ impl CssClassMerger { css_class_merge_params: CssClassMergeParams<'_>, css_classes_builder: &mut CssClassesBuilder, warnings: &mut ThemeWarnings, - fn_fill_classes: fn(&dyn Themeable, &mut CssClassesBuilder, ColorParams<'_>), + fn_fill_classes: fn(&AnyId, &dyn Themeable, &mut CssClassesBuilder, ColorParams<'_>), style_for: StyleFor<'_>, ) { let fill_class_append_result = match style_for { @@ -534,6 +551,7 @@ impl CssClassMerger { css_classes_builder: &mut CssClassesBuilder, ) -> FillClassAppendResult<'f2> { let CssClassMergeParams { + any_id, defaults, specified, themeable, @@ -557,7 +575,7 @@ impl CssClassMerger { color, shade, }; - fn_css_classes(themeable, css_classes_builder, params); + fn_css_classes(any_id, themeable, css_classes_builder, params); FillClassAppendResult::Added } (color, shade) => FillClassAppendResult::NoChange { color, shade }, @@ -693,6 +711,7 @@ fn attr_value_find<'attr>( /// Grouping of common parameters to reduce parameter count in methods. #[derive(Clone, Copy)] struct CssClassMergeParams<'params> { + any_id: &'params AnyId, defaults: Option<&'params CssClassPartials>, specified: Option<&'params CssClassPartials>, themeable: &'params dyn Themeable, @@ -723,11 +742,13 @@ struct ColorParamGroupings { /// State specific color, state agnostic color, shape color. color_keys: &'static [ThemeAttr], shade_keys: &'static [ThemeAttr], - fn_css_classes: fn(&dyn Themeable, &mut CssClassesBuilder, Params), + fn_css_classes: fn(&AnyId, &dyn Themeable, &mut CssClassesBuilder, Params), } impl ColorParamGroupings { - fn new_fill_normal(fn_css_classes: fn(&dyn Themeable, &mut CssClassesBuilder, Params)) -> Self { + fn new_fill_normal( + fn_css_classes: fn(&AnyId, &dyn Themeable, &mut CssClassesBuilder, Params), + ) -> Self { Self { highlight_state: HighlightState::Normal, color_keys: &[ @@ -740,7 +761,9 @@ impl ColorParamGroupings { } } - fn new_fill_focus(fn_css_classes: fn(&dyn Themeable, &mut CssClassesBuilder, Params)) -> Self { + fn new_fill_focus( + fn_css_classes: fn(&AnyId, &dyn Themeable, &mut CssClassesBuilder, Params), + ) -> Self { Self { highlight_state: HighlightState::Focus, color_keys: &[ @@ -754,7 +777,7 @@ impl ColorParamGroupings { } fn new_fill_focus_hover( - fn_css_classes: fn(&dyn Themeable, &mut CssClassesBuilder, Params), + fn_css_classes: fn(&AnyId, &dyn Themeable, &mut CssClassesBuilder, Params), ) -> Self { Self { highlight_state: HighlightState::FocusHover, @@ -768,7 +791,9 @@ impl ColorParamGroupings { } } - fn new_fill_hover(fn_css_classes: fn(&dyn Themeable, &mut CssClassesBuilder, Params)) -> Self { + fn new_fill_hover( + fn_css_classes: fn(&AnyId, &dyn Themeable, &mut CssClassesBuilder, Params), + ) -> Self { Self { highlight_state: HighlightState::Hover, color_keys: &[ @@ -781,7 +806,9 @@ impl ColorParamGroupings { } } - fn new_fill_active(fn_css_classes: fn(&dyn Themeable, &mut CssClassesBuilder, Params)) -> Self { + fn new_fill_active( + fn_css_classes: fn(&AnyId, &dyn Themeable, &mut CssClassesBuilder, Params), + ) -> Self { Self { highlight_state: HighlightState::Active, color_keys: &[ @@ -806,12 +833,12 @@ struct LineParamGroupings { shade_keys: &'static [ThemeAttr], line_style_keys: &'static [ThemeAttr], line_width_keys: &'static [ThemeAttr], - fn_css_classes: fn(&dyn Themeable, &mut CssClassesBuilder, Params), + fn_css_classes: fn(&AnyId, &dyn Themeable, &mut CssClassesBuilder, Params), } impl LineParamGroupings { fn new_stroke_normal( - fn_css_classes: fn(&dyn Themeable, &mut CssClassesBuilder, Params), + fn_css_classes: fn(&AnyId, &dyn Themeable, &mut CssClassesBuilder, Params), ) -> Self { Self { highlight_state: HighlightState::Normal, @@ -828,7 +855,7 @@ impl LineParamGroupings { } fn new_stroke_focus( - fn_css_classes: fn(&dyn Themeable, &mut CssClassesBuilder, Params), + fn_css_classes: fn(&AnyId, &dyn Themeable, &mut CssClassesBuilder, Params), ) -> Self { Self { highlight_state: HighlightState::Focus, @@ -845,7 +872,7 @@ impl LineParamGroupings { } fn new_stroke_focus_hover( - fn_css_classes: fn(&dyn Themeable, &mut CssClassesBuilder, Params), + fn_css_classes: fn(&AnyId, &dyn Themeable, &mut CssClassesBuilder, Params), ) -> Self { Self { highlight_state: HighlightState::FocusHover, @@ -862,7 +889,7 @@ impl LineParamGroupings { } fn new_stroke_hover( - fn_css_classes: fn(&dyn Themeable, &mut CssClassesBuilder, Params), + fn_css_classes: fn(&AnyId, &dyn Themeable, &mut CssClassesBuilder, Params), ) -> Self { Self { highlight_state: HighlightState::Hover, @@ -879,7 +906,7 @@ impl LineParamGroupings { } fn new_stroke_active( - fn_css_classes: fn(&dyn Themeable, &mut CssClassesBuilder, Params), + fn_css_classes: fn(&AnyId, &dyn Themeable, &mut CssClassesBuilder, Params), ) -> Self { Self { highlight_state: HighlightState::Active, @@ -896,7 +923,7 @@ impl LineParamGroupings { } fn new_outline_normal( - fn_css_classes: fn(&dyn Themeable, &mut CssClassesBuilder, Params), + fn_css_classes: fn(&AnyId, &dyn Themeable, &mut CssClassesBuilder, Params), ) -> Self { Self { highlight_state: HighlightState::Normal, @@ -909,7 +936,7 @@ impl LineParamGroupings { } fn new_outline_focus( - fn_css_classes: fn(&dyn Themeable, &mut CssClassesBuilder, Params), + fn_css_classes: fn(&AnyId, &dyn Themeable, &mut CssClassesBuilder, Params), ) -> Self { Self { highlight_state: HighlightState::Focus, @@ -922,7 +949,7 @@ impl LineParamGroupings { } fn new_outline_hover( - fn_css_classes: fn(&dyn Themeable, &mut CssClassesBuilder, Params), + fn_css_classes: fn(&AnyId, &dyn Themeable, &mut CssClassesBuilder, Params), ) -> Self { Self { highlight_state: HighlightState::Hover, @@ -935,7 +962,7 @@ impl LineParamGroupings { } fn new_outline_active( - fn_css_classes: fn(&dyn Themeable, &mut CssClassesBuilder, Params), + fn_css_classes: fn(&AnyId, &dyn Themeable, &mut CssClassesBuilder, Params), ) -> Self { Self { highlight_state: HighlightState::Active, diff --git a/crate/model/src/theme/themeable.rs b/crate/model/src/theme/themeable.rs index 6f62de7..a48123f 100644 --- a/crate/model/src/theme/themeable.rs +++ b/crate/model/src/theme/themeable.rs @@ -1,5 +1,5 @@ use crate::{ - common::{EdgeId, NodeId}, + common::{AnyId, EdgeId, NodeId}, theme::{ColorParams, CssClassesBuilder, LineParams}, }; @@ -22,7 +22,12 @@ pub trait Themeable { /// /// * `builder`: The builder to append CSS classes. /// * `line_params`: Parameters for the CSS utility class. - fn node_outline_classes(&self, builder: &mut CssClassesBuilder, line_params: LineParams<'_>); + fn node_outline_classes( + &self, + node_id: &AnyId, + builder: &mut CssClassesBuilder, + line_params: LineParams<'_>, + ); /// Appends the CSS classes that sets the line / border colour and style. /// @@ -35,7 +40,12 @@ pub trait Themeable { /// /// * `builder`: The builder to append CSS classes. /// * `line_params`: Parameters for the CSS utility class. - fn node_stroke_classes(&self, builder: &mut CssClassesBuilder, line_params: LineParams<'_>); + fn node_stroke_classes( + &self, + node_id: &AnyId, + builder: &mut CssClassesBuilder, + line_params: LineParams<'_>, + ); /// Appends the CSS classes that sets the background colour and style. /// @@ -48,7 +58,12 @@ pub trait Themeable { /// /// * `builder`: The builder to append CSS classes. /// * `color_params`: Parameters for the CSS utility class. - fn node_fill_classes(&self, builder: &mut CssClassesBuilder, color_params: ColorParams<'_>); + fn node_fill_classes( + &self, + node_id: &AnyId, + builder: &mut CssClassesBuilder, + color_params: ColorParams<'_>, + ); /// Returns the IDs of all edges of this themeable type. fn edge_ids(&self) -> impl Iterator @@ -66,7 +81,12 @@ pub trait Themeable { /// /// * `builder`: The builder to append CSS classes. /// * `line_params`: Parameters for the CSS utility class. - fn edge_outline_classes(&self, builder: &mut CssClassesBuilder, line_params: LineParams<'_>); + fn edge_outline_classes( + &self, + edge_id: &AnyId, + builder: &mut CssClassesBuilder, + line_params: LineParams<'_>, + ); /// Appends the CSS classes that sets the stroke colour and style. /// @@ -79,7 +99,12 @@ pub trait Themeable { /// /// * `builder`: The builder to append CSS classes. /// * `line_params`: Parameters for the CSS utility class. - fn edge_stroke_classes(&self, builder: &mut CssClassesBuilder, line_params: LineParams<'_>); + fn edge_stroke_classes( + &self, + edge_id: &AnyId, + builder: &mut CssClassesBuilder, + line_params: LineParams<'_>, + ); /// Appends the CSS classes that sets the background colour and style. /// @@ -92,5 +117,10 @@ pub trait Themeable { /// /// * `builder`: The builder to append CSS classes. /// * `color_params`: Parameters for the CSS utility class. - fn edge_fill_classes(&self, builder: &mut CssClassesBuilder, color_params: ColorParams<'_>); + fn edge_fill_classes( + &self, + edge_id: &AnyId, + builder: &mut CssClassesBuilder, + color_params: ColorParams<'_>, + ); } diff --git a/crate/rt/src/info_graph_dot.rs b/crate/rt/src/info_graph_dot.rs index 4c95d3f..62ebc98 100644 --- a/crate/rt/src/info_graph_dot.rs +++ b/crate/rt/src/info_graph_dot.rs @@ -1,14 +1,38 @@ +use std::collections::HashMap; + use dot_ix_model::{ - common::{EdgeId, NodeId}, + common::{AnyId, EdgeId, NodeHierarchy, NodeId}, + info_graph::GraphStyle, theme::{ColorParams, CssClassesBuilder, HighlightState, LineParams, Themeable}, }; #[derive(Clone)] pub struct InfoGraphDot<'graph> { + pub graph_style: GraphStyle, + pub node_id_to_hierarchy: &'graph HashMap<&'graph NodeId, &'graph NodeHierarchy>, pub node_ids: Vec<&'graph NodeId>, pub edge_ids: Vec<&'graph EdgeId>, } +impl<'graph> InfoGraphDot<'graph> { + fn el_prefix(&self, node_id: &AnyId) -> &str { + let is_cluster = self + .node_id_to_hierarchy + .get(node_id.as_str()) + .map(|hierarchy| !hierarchy.is_empty()) + .unwrap_or(false); + + if is_cluster { + return "[&>path]:"; + } + + match self.graph_style { + GraphStyle::Box => "[&>path]:", + GraphStyle::Circle => "[&>ellipse]:", + } + } +} + impl<'graph> Themeable for InfoGraphDot<'graph> { fn node_ids(&self) -> impl Iterator where @@ -17,48 +41,57 @@ impl<'graph> Themeable for InfoGraphDot<'graph> { self.node_ids.iter().copied() } - fn node_outline_classes(&self, builder: &mut CssClassesBuilder, line_params: LineParams<'_>) { + fn node_outline_classes( + &self, + node_id: &AnyId, + builder: &mut CssClassesBuilder, + line_params: LineParams<'_>, + ) { let LineParams { color_params, line_width, line_style, } = line_params; - path_color_classes(builder, color_params, "outline"); + path_color_classes(builder, color_params, "outline", self.el_prefix(node_id)); outline_style_classes( builder, color_params.highlight_state, line_width, line_style, - "[&>path]:", - ); - outline_style_classes( - builder, - color_params.highlight_state, - line_width, - line_style, - "[&>ellipse]:", + self.el_prefix(node_id), ); } - fn node_stroke_classes(&self, builder: &mut CssClassesBuilder, line_params: LineParams<'_>) { + fn node_stroke_classes( + &self, + node_id: &AnyId, + builder: &mut CssClassesBuilder, + line_params: LineParams<'_>, + ) { let LineParams { color_params, line_width, line_style, } = line_params; - path_color_classes(builder, color_params, "stroke"); + path_color_classes(builder, color_params, "stroke", self.el_prefix(node_id)); border_style_classes( builder, color_params.highlight_state, line_width, line_style, + self.el_prefix(node_id), ); } - fn node_fill_classes(&self, builder: &mut CssClassesBuilder, color_params: ColorParams<'_>) { - path_color_classes(builder, color_params, "fill"); + fn node_fill_classes( + &self, + node_id: &AnyId, + builder: &mut CssClassesBuilder, + color_params: ColorParams<'_>, + ) { + path_color_classes(builder, color_params, "fill", self.el_prefix(node_id)); } fn edge_ids(&self) -> impl Iterator @@ -68,7 +101,12 @@ impl<'graph> Themeable for InfoGraphDot<'graph> { self.edge_ids.iter().copied() } - fn edge_outline_classes(&self, builder: &mut CssClassesBuilder, line_params: LineParams<'_>) { + fn edge_outline_classes( + &self, + _edge_id: &AnyId, + builder: &mut CssClassesBuilder, + line_params: LineParams<'_>, + ) { let LineParams { color_params, line_width, @@ -85,24 +123,35 @@ impl<'graph> Themeable for InfoGraphDot<'graph> { ); } - fn edge_stroke_classes(&self, builder: &mut CssClassesBuilder, line_params: LineParams<'_>) { + fn edge_stroke_classes( + &self, + _edge_id: &AnyId, + builder: &mut CssClassesBuilder, + line_params: LineParams<'_>, + ) { let LineParams { color_params, line_width, line_style, } = line_params; - path_color_classes(builder, color_params, "stroke"); + path_color_classes(builder, color_params, "stroke", "[&>path]:"); polygon_color_classes(builder, color_params, "stroke"); border_style_classes( builder, color_params.highlight_state, line_width, line_style, + "[&>path]:", ); } - fn edge_fill_classes(&self, builder: &mut CssClassesBuilder, color_params: ColorParams<'_>) { + fn edge_fill_classes( + &self, + _edge_id: &AnyId, + builder: &mut CssClassesBuilder, + color_params: ColorParams<'_>, + ) { // deliberately don't have `"fill"` for `path`, because that adds a thin line // when the path is styled as dashed polygon_color_classes(builder, color_params, "fill"); @@ -133,52 +182,39 @@ fn border_style_classes( highlight_state: HighlightState, line_width: &str, line_style: &str, + el_prefix: &str, ) { let highlight_prefix = highlight_prefix(highlight_state); match line_style { "none" => {} "solid" => { - builder - .append(&format!("[&>path]:{highlight_prefix}stroke-{line_width}")) - .append(&format!( - "[&>ellipse]:{highlight_prefix}stroke-{line_width}" - )); + builder.append(&format!("{el_prefix}{highlight_prefix}stroke-{line_width}")); } "dashed" => { builder - .append(&format!("[&>path]:{highlight_prefix}stroke-{line_width}")) - .append(&format!("[&>path]:{highlight_prefix}[stroke-dasharray:3]")) - .append(&format!( - "[&>ellipse]:{highlight_prefix}stroke-{line_width}" - )) + .append(&format!("{el_prefix}{highlight_prefix}stroke-{line_width}")) .append(&format!( - "[&>ellipse]:{highlight_prefix}[stroke-dasharray:3]" + "{el_prefix}{highlight_prefix}[stroke-dasharray:3]" )); } "dotted" => { builder - .append(&format!("[&>path]:{highlight_prefix}stroke-{line_width}")) - .append(&format!("[&>path]:{highlight_prefix}[stroke-dasharray:2]")) - .append(&format!( - "[&>ellipse]:{highlight_prefix}stroke-{line_width}" - )) + .append(&format!("{el_prefix}{highlight_prefix}stroke-{line_width}")) .append(&format!( - "[&>ellipse]:{highlight_prefix}[stroke-dasharray:2]" + "{el_prefix}{highlight_prefix}[stroke-dasharray:2]" )); } line_style if line_style.starts_with("dasharray:") => { builder - .append(&format!("[&>path]:{highlight_prefix}stroke-{line_width}")) - .append(&format!("[&>path]:{highlight_prefix}[stroke-{line_style}]")) + .append(&format!("{el_prefix}{highlight_prefix}stroke-{line_width}")) .append(&format!( - "[&>ellipse]:{highlight_prefix}stroke-{line_width}" - )) - .append(&format!( - "[&>ellipse]:{highlight_prefix}[stroke-{line_style}]" + "{el_prefix}{highlight_prefix}[stroke-{line_style}]" )); } - _ => {} + _ => { + // TODO #29: warn user of unknown value. + } }; } @@ -186,9 +222,9 @@ fn path_color_classes( builder: &mut CssClassesBuilder, color_params: ColorParams<'_>, stroke_or_fill: &str, + el_prefix: &str, ) { - el_color_classes(builder, color_params, stroke_or_fill, "[&>path]:"); - el_color_classes(builder, color_params, stroke_or_fill, "[&>ellipse]:"); + el_color_classes(builder, color_params, stroke_or_fill, el_prefix); } fn polygon_color_classes( diff --git a/crate/rt/src/info_graph_html.rs b/crate/rt/src/info_graph_html.rs index 7a46fcc..b584cef 100644 --- a/crate/rt/src/info_graph_html.rs +++ b/crate/rt/src/info_graph_html.rs @@ -1,7 +1,7 @@ use std::borrow::Cow; use dot_ix_model::{ - common::{EdgeId, NodeId}, + common::{AnyId, EdgeId, NodeId}, theme::{ColorParams, CssClassesBuilder, HighlightState, LineParams, Themeable}, }; @@ -19,7 +19,12 @@ impl<'graph> Themeable for InfoGraphHtml<'graph> { self.node_ids.iter().copied() } - fn node_outline_classes(&self, builder: &mut CssClassesBuilder, line_params: LineParams<'_>) { + fn node_outline_classes( + &self, + _node_id: &AnyId, + builder: &mut CssClassesBuilder, + line_params: LineParams<'_>, + ) { let LineParams { color_params, line_width, @@ -36,7 +41,12 @@ impl<'graph> Themeable for InfoGraphHtml<'graph> { ); } - fn node_stroke_classes(&self, builder: &mut CssClassesBuilder, line_params: LineParams<'_>) { + fn node_stroke_classes( + &self, + _node_id: &AnyId, + builder: &mut CssClassesBuilder, + line_params: LineParams<'_>, + ) { let LineParams { color_params, line_width, @@ -53,7 +63,12 @@ impl<'graph> Themeable for InfoGraphHtml<'graph> { ); } - fn node_fill_classes(&self, builder: &mut CssClassesBuilder, color_params: ColorParams<'_>) { + fn node_fill_classes( + &self, + _node_id: &AnyId, + builder: &mut CssClassesBuilder, + color_params: ColorParams<'_>, + ) { el_color_classes(builder, color_params, "bg"); } @@ -64,7 +79,12 @@ impl<'graph> Themeable for InfoGraphHtml<'graph> { self.edge_ids.iter().copied() } - fn edge_outline_classes(&self, builder: &mut CssClassesBuilder, line_params: LineParams<'_>) { + fn edge_outline_classes( + &self, + _edge_id: &AnyId, + builder: &mut CssClassesBuilder, + line_params: LineParams<'_>, + ) { let LineParams { color_params, line_width, @@ -81,7 +101,12 @@ impl<'graph> Themeable for InfoGraphHtml<'graph> { ); } - fn edge_stroke_classes(&self, builder: &mut CssClassesBuilder, line_params: LineParams<'_>) { + fn edge_stroke_classes( + &self, + _edge_id: &AnyId, + builder: &mut CssClassesBuilder, + line_params: LineParams<'_>, + ) { let LineParams { color_params, line_width, @@ -98,7 +123,12 @@ impl<'graph> Themeable for InfoGraphHtml<'graph> { ); } - fn edge_fill_classes(&self, builder: &mut CssClassesBuilder, color_params: ColorParams<'_>) { + fn edge_fill_classes( + &self, + _edge_id: &AnyId, + builder: &mut CssClassesBuilder, + color_params: ColorParams<'_>, + ) { el_color_classes(builder, color_params, "bg"); } } diff --git a/crate/rt/src/into_graphviz_dot_src/info_graph.rs b/crate/rt/src/into_graphviz_dot_src/info_graph.rs index 08643d0..dee0623 100644 --- a/crate/rt/src/into_graphviz_dot_src/info_graph.rs +++ b/crate/rt/src/into_graphviz_dot_src/info_graph.rs @@ -93,17 +93,21 @@ const OUTLINE_NONE: &str = "outline-none"; /// [`tailwind-css`]: https://github.com/oovm/tailwind-rs impl IntoGraphvizDotSrc for &InfoGraph { fn into(self, theme: &GraphvizDotTheme) -> DotSrcAndStyles { + let graph_style = self.graph_style(); let graphviz_attrs = self.graphviz_attrs(); let graph_attrs = graph_attrs(theme, self.direction(), graphviz_attrs); - let node_attrs = node_attrs(self.graph_style(), theme); + let node_attrs = node_attrs(graph_style, theme); let edge_attrs = edge_attrs(graphviz_attrs, theme); let diagram_theme = self.theme(); // Build a map from `NodeId` to their `NodeHierarchy`, so that we don't have to // search for it every time we want to create an edge. let node_id_to_hierarchy = self.hierarchy_flat(); + let node_id_to_hierarchy = &node_id_to_hierarchy; let info_graph_dot = InfoGraphDot { + graph_style, + node_id_to_hierarchy, node_ids: node_id_to_hierarchy.keys().copied().collect::>(), edge_ids: self.edges().keys().collect::>(), }; diff --git a/workspace_tests/src/model/theme.rs b/workspace_tests/src/model/theme.rs index 6dd173d..6d46cb2 100644 --- a/workspace_tests/src/model/theme.rs +++ b/workspace_tests/src/model/theme.rs @@ -1,5 +1,9 @@ +use std::collections::HashMap; + use dot_ix::{ model::{ + common::NodeHierarchy, + info_graph::GraphStyle, node_id, tag_id, theme::{AnyIdOrDefaults, CssClassPartials, CssClasses, Theme, ThemeAttr}, }, @@ -48,6 +52,45 @@ fn base_theme_contains_node_defaults_and_edge_defaults() { assert_eq!(2, theme.len()); } +#[test] +fn tag_theme_default_contains_peer_focus_lime() { + let tag_theme = Theme::tag_base(); + let test_node_id = node_id!("my_node"); + let test_node_hierarchy = NodeHierarchy::new(); + let node_id_to_hierarchy = { + let mut node_id_to_hierarchy = HashMap::with_capacity(1); + node_id_to_hierarchy.insert(&test_node_id, &test_node_hierarchy); + node_id_to_hierarchy + }; + let node_id_to_hierarchy = &node_id_to_hierarchy; + let diagram_theme = Theme::new(); + let info_graph_dot = InfoGraphDot { + graph_style: GraphStyle::Box, + node_id_to_hierarchy, + node_ids: vec![&test_node_id], + edge_ids: vec![], + }; + let themeable = &info_graph_dot; + + let (tag_el_css_classes, theme_warnings) = + tag_theme.tag_el_css_classes(themeable, &diagram_theme, &tag_id!("tag_step_1")); + + let css_classes = tag_el_css_classes.get(test_node_id.as_str()); + assert_eq!( + Some(CssClasses::from( + "\ + peer-focus/tag_step_1:[&>path]:stroke-lime-500 \ + peer-focus/tag_step_1:[&>path]:stroke-2 \ + peer-focus/tag_step_1:[&>path]:fill-lime-200 \ + " + .to_string() + )) + .as_ref(), + css_classes, + "Theme warnings: `{theme_warnings:?}`", + ); +} + #[test] fn tag_theme_merge_resolves_node_outline() { let mut tag_theme = Theme::new(); @@ -61,48 +104,40 @@ fn tag_theme_merge_resolves_node_outline() { ]), ); let test_node_id = node_id!("my_node"); + let test_node_hierarchy = NodeHierarchy::new(); + let node_id_to_hierarchy = { + let mut node_id_to_hierarchy = HashMap::with_capacity(1); + node_id_to_hierarchy.insert(&test_node_id, &test_node_hierarchy); + node_id_to_hierarchy + }; + let node_id_to_hierarchy = &node_id_to_hierarchy; let diagram_theme = Theme::new(); let info_graph_dot = InfoGraphDot { + graph_style: GraphStyle::Circle, + node_id_to_hierarchy, node_ids: vec![&test_node_id], edge_ids: vec![], }; let themeable = &info_graph_dot; - let (tag_el_css_classes, _theme_warnings) = + let (tag_el_css_classes, theme_warnings) = tag_theme.tag_el_css_classes(themeable, &diagram_theme, &tag_id!("tag_step_1")); let css_classes = tag_el_css_classes.get(test_node_id.as_str()); assert_eq!( Some(CssClasses::from( "\ - peer-focus/tag_step_1:[&>path]:outline-red-600 \ peer-focus/tag_step_1:[&>ellipse]:outline-red-600 \ - peer-focus/tag_step_1:[&>path]:outline-[2px] \ - peer-focus/tag_step_1:[&>path]:outline-dashed \ peer-focus/tag_step_1:[&>ellipse]:outline-[2px] \ peer-focus/tag_step_1:[&>ellipse]:outline-dashed \ - peer-focus/tag_step_1:[&>path]:focus:outline-red-600 \ - peer-focus/tag_step_1:[&>ellipse]:focus:outline-red-600 \ - peer-focus/tag_step_1:[&>path]:focus:outline-[2px] \ - peer-focus/tag_step_1:[&>path]:focus:outline-dashed \ - peer-focus/tag_step_1:[&>ellipse]:focus:outline-[2px] \ - peer-focus/tag_step_1:[&>ellipse]:focus:outline-dashed \ - peer-focus/tag_step_1:[&>path]:hover:outline-red-600 \ - peer-focus/tag_step_1:[&>ellipse]:hover:outline-red-600 \ - peer-focus/tag_step_1:[&>path]:hover:outline-[2px] \ - peer-focus/tag_step_1:[&>path]:hover:outline-dashed \ - peer-focus/tag_step_1:[&>ellipse]:hover:outline-[2px] \ - peer-focus/tag_step_1:[&>ellipse]:hover:outline-dashed \ - peer-focus/tag_step_1:[&>path]:focus:active:outline-red-600 \ - peer-focus/tag_step_1:[&>ellipse]:focus:active:outline-red-600 \ - peer-focus/tag_step_1:[&>path]:focus:active:outline-[2px] \ - peer-focus/tag_step_1:[&>path]:focus:active:outline-dashed \ - peer-focus/tag_step_1:[&>ellipse]:focus:active:outline-[2px] \ - peer-focus/tag_step_1:[&>ellipse]:focus:active:outline-dashed \ + peer-focus/tag_step_1:[&>ellipse]:stroke-lime-500 \ + peer-focus/tag_step_1:[&>ellipse]:stroke-2 \ + peer-focus/tag_step_1:[&>ellipse]:fill-lime-200 \ " .to_string() )) .as_ref(), - css_classes + css_classes, + "Theme warnings: `{theme_warnings:?}`", ); } From b8e1e343340aad4e15ea298149f05f59760005bf Mon Sep 17 00:00:00 2001 From: Azriel Hoh Date: Tue, 6 Aug 2024 20:41:02 +1200 Subject: [PATCH 07/15] Extract `#[component]`s from playground `InfoGraph`. --- playground/src/app/info_graph.rs | 337 +++++++++++++++++-------------- 1 file changed, 188 insertions(+), 149 deletions(-) diff --git a/playground/src/app/info_graph.rs b/playground/src/app/info_graph.rs index 4c17dd6..7faf79e 100644 --- a/playground/src/app/info_graph.rs +++ b/playground/src/app/info_graph.rs @@ -8,7 +8,7 @@ use dot_ix::{ rt::IntoGraphvizDotSrc, web_components::{DotSvg, FlexDiag}, }; -use leptos::*; +use leptos::{ev::Event, *}; use crate::app::{TabLabel, TextEditor}; @@ -306,154 +306,21 @@ pub fn InfoGraph(diagram_only: ReadSignal) -> impl IntoView { view! {
-
- - - - - - // tab content - - - // tab content -