From 8c2244fc588b2b527bf575d2e4be0f9cb643c3b3 Mon Sep 17 00:00:00 2001 From: Max Kasperowski Date: Fri, 8 Nov 2024 15:36:28 +0100 Subject: [PATCH 1/2] Add a synthesis hook to configure top-down layout for SCCharts --- ....sccharts.ui.synthesis.hooks.SynthesisHook | 1 + .../synthesis/hooks/TopdownLayoutHook.xtend | 117 ++++++++++++++++++ 2 files changed, 118 insertions(+) create mode 100644 plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/hooks/TopdownLayoutHook.xtend diff --git a/plugins/de.cau.cs.kieler.sccharts.ui/META-INF/services/de.cau.cs.kieler.sccharts.ui.synthesis.hooks.SynthesisHook b/plugins/de.cau.cs.kieler.sccharts.ui/META-INF/services/de.cau.cs.kieler.sccharts.ui.synthesis.hooks.SynthesisHook index b78459e206..6d5bcbeb9a 100644 --- a/plugins/de.cau.cs.kieler.sccharts.ui/META-INF/services/de.cau.cs.kieler.sccharts.ui.synthesis.hooks.SynthesisHook +++ b/plugins/de.cau.cs.kieler.sccharts.ui/META-INF/services/de.cau.cs.kieler.sccharts.ui.synthesis.hooks.SynthesisHook @@ -8,6 +8,7 @@ de.cau.cs.kieler.sccharts.ui.synthesis.hooks.HideAnnotationHook de.cau.cs.kieler.sccharts.ui.synthesis.hooks.LabelPlacementSideHook de.cau.cs.kieler.sccharts.ui.synthesis.hooks.LabelShorteningHook de.cau.cs.kieler.sccharts.ui.synthesis.hooks.SynthesisAnnotationHook +de.cau.cs.kieler.sccharts.ui.synthesis.hooks.TopdownLayoutHook de.cau.cs.kieler.sccharts.ui.synthesis.hooks.LayoutHook de.cau.cs.kieler.sccharts.ui.synthesis.hooks.ExpandCollapseHook de.cau.cs.kieler.sccharts.ui.synthesis.hooks.ColorAnnotationHook diff --git a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/hooks/TopdownLayoutHook.xtend b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/hooks/TopdownLayoutHook.xtend new file mode 100644 index 0000000000..18539b0199 --- /dev/null +++ b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/hooks/TopdownLayoutHook.xtend @@ -0,0 +1,117 @@ +/* + * KIELER - Kiel Integrated Environment for Layout Eclipse RichClient + * + * http://rtsys.informatik.uni-kiel.de/kieler + * + * Copyright 2024 by + * + Kiel University + * + Department of Computer Science + * + Real-Time and Embedded Systems Group + * + * This code is provided under the terms of the Eclipse Public License (EPL). + */ +package de.cau.cs.kieler.sccharts.ui.synthesis.hooks + +import de.cau.cs.kieler.klighd.SynthesisOption +import de.cau.cs.kieler.klighd.kgraph.KNode +import de.cau.cs.kieler.klighd.krendering.ViewSynthesisShared +import de.cau.cs.kieler.sccharts.Region +import de.cau.cs.kieler.sccharts.Scope +import de.cau.cs.kieler.sccharts.State +import de.cau.cs.kieler.sccharts.ui.synthesis.GeneralSynthesisOptions +import java.util.EnumSet +import org.eclipse.elk.core.options.ContentAlignment +import org.eclipse.elk.core.options.CoreOptions +import org.eclipse.elk.core.options.SizeConstraint +import org.eclipse.elk.core.options.TopdownNodeTypes + +import static extension de.cau.cs.kieler.klighd.syntheses.DiagramSyntheses.* + +/** + * Hook that configures SCCharts to be laid out using top-down layout instead of bottom-up layout. + * + * @author mka + * + */ + @ViewSynthesisShared +class TopdownLayoutHook extends SynthesisHook { + + /** Action ID */ + public static final String ID = "de.cau.cs.kieler.sccharts.ui.synthesis.hooks.TopdownLayoutHook"; + + public static final SynthesisOption USE_TOPDOWN_LAYOUT = + SynthesisOption.createCheckOption(TopdownLayoutHook, "Topdown Layout", false) + .setCategory(GeneralSynthesisOptions::LAYOUT) + + public static final SynthesisOption TOPDOWN_HIERARCHICAL_NODE_WIDTH = + SynthesisOption.createRangeOption("Topdown Hierarchical Node Width", 50.0f, 5000.0f, 1.0f, 150.0f) + .setCategory(GeneralSynthesisOptions::LAYOUT) + + public static final SynthesisOption TOPDOWN_HIERARCHICAL_NODE_ASPECT_RATIO = + SynthesisOption.createRangeOption("Topdown Hierarchical Node Aspect Ratio", 0.2f, 5.0f, 0.01f, 1.41f) + .setCategory(GeneralSynthesisOptions::LAYOUT) + + public static final SynthesisOption SCALE_CAP = + SynthesisOption.createCheckOption(TopdownLayoutHook, "Enable Scale Cap", true) + .setCategory(GeneralSynthesisOptions::LAYOUT) + + +// public static final SynthesisOption + + override getDisplayedSynthesisOptions() { + return #[ + USE_TOPDOWN_LAYOUT, SCALE_CAP, TOPDOWN_HIERARCHICAL_NODE_WIDTH, TOPDOWN_HIERARCHICAL_NODE_ASPECT_RATIO + ] + } + + override processState(State state, KNode node) { + + node.setProperty(CoreOptions::TOPDOWN_LAYOUT, USE_TOPDOWN_LAYOUT.booleanValue) + if (USE_TOPDOWN_LAYOUT.booleanValue) { + node.setLayoutOption(CoreOptions::NODE_SIZE_CONSTRAINTS, EnumSet.noneOf(SizeConstraint)) + node.setLayoutOption(CoreOptions::NODE_SIZE_FIXED_GRAPH_SIZE, true) + node.setLayoutOption(CoreOptions::TOPDOWN_NODE_TYPE, TopdownNodeTypes.HIERARCHICAL_NODE) + node.setLayoutOption(CoreOptions::TOPDOWN_HIERARCHICAL_NODE_WIDTH, TOPDOWN_HIERARCHICAL_NODE_WIDTH.floatValue as double) + node.setLayoutOption(CoreOptions::TOPDOWN_HIERARCHICAL_NODE_ASPECT_RATIO, TOPDOWN_HIERARCHICAL_NODE_ASPECT_RATIO.floatValue as double) + node.setLayoutOption(CoreOptions::CONTENT_ALIGNMENT, EnumSet.of(ContentAlignment.V_CENTER, ContentAlignment.H_CENTER)) + + if (SCALE_CAP.booleanValue) { + node.setLayoutOption(CoreOptions::TOPDOWN_SCALE_CAP, 1.0) + } else { + node.setLayoutOption(CoreOptions::TOPDOWN_SCALE_CAP, Double.MAX_VALUE) + } + } + } + + override processRegion(Region region, KNode node) { + node.setProperty(CoreOptions::TOPDOWN_LAYOUT, USE_TOPDOWN_LAYOUT.booleanValue) + + if (USE_TOPDOWN_LAYOUT.booleanValue) { + node.setLayoutOption(CoreOptions::NODE_SIZE_FIXED_GRAPH_SIZE, true) + node.setLayoutOption(CoreOptions::TOPDOWN_NODE_TYPE, TopdownNodeTypes.HIERARCHICAL_NODE) + node.setLayoutOption(CoreOptions::TOPDOWN_HIERARCHICAL_NODE_WIDTH, TOPDOWN_HIERARCHICAL_NODE_WIDTH.floatValue as double) + node.setLayoutOption(CoreOptions::TOPDOWN_HIERARCHICAL_NODE_ASPECT_RATIO, TOPDOWN_HIERARCHICAL_NODE_ASPECT_RATIO.floatValue as double) + node.setLayoutOption(CoreOptions::CONTENT_ALIGNMENT, EnumSet.of(ContentAlignment.V_CENTER, ContentAlignment.H_CENTER)) + if (SCALE_CAP.booleanValue) { + node.setLayoutOption(CoreOptions::TOPDOWN_SCALE_CAP, 1.0) + } else { + node.setLayoutOption(CoreOptions::TOPDOWN_SCALE_CAP, Double.MAX_VALUE) + } + } + } + + override start(Scope scope, KNode node) { + node.setProperty(CoreOptions::TOPDOWN_LAYOUT, USE_TOPDOWN_LAYOUT.booleanValue) + if (USE_TOPDOWN_LAYOUT.booleanValue) { + node.setLayoutOption(CoreOptions::NODE_SIZE_FIXED_GRAPH_SIZE, true) + node.setLayoutOption(CoreOptions::TOPDOWN_NODE_TYPE, TopdownNodeTypes.ROOT_NODE) + node.setLayoutOption(CoreOptions::TOPDOWN_HIERARCHICAL_NODE_WIDTH, TOPDOWN_HIERARCHICAL_NODE_WIDTH.floatValue as double) + node.setLayoutOption(CoreOptions::TOPDOWN_HIERARCHICAL_NODE_ASPECT_RATIO, TOPDOWN_HIERARCHICAL_NODE_ASPECT_RATIO.floatValue as double) + if (SCALE_CAP.booleanValue) { + node.setLayoutOption(CoreOptions::TOPDOWN_SCALE_CAP, 1.0) + } else { + node.setLayoutOption(CoreOptions::TOPDOWN_SCALE_CAP, Double.MAX_VALUE) + } + } + } +} \ No newline at end of file From 9c87360ff334bca0c7df3f54e047014cddef8699 Mon Sep 17 00:00:00 2001 From: Max Kasperowski Date: Tue, 12 Nov 2024 14:01:09 +0100 Subject: [PATCH 2/2] PR feedback --- .../synthesis/hooks/TopdownLayoutHook.xtend | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/hooks/TopdownLayoutHook.xtend b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/hooks/TopdownLayoutHook.xtend index 18539b0199..edea34dcfa 100644 --- a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/hooks/TopdownLayoutHook.xtend +++ b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/hooks/TopdownLayoutHook.xtend @@ -42,21 +42,24 @@ class TopdownLayoutHook extends SynthesisHook { public static final SynthesisOption USE_TOPDOWN_LAYOUT = SynthesisOption.createCheckOption(TopdownLayoutHook, "Topdown Layout", false) .setCategory(GeneralSynthesisOptions::LAYOUT) + .description = "Use top-down layout instead of bottom-up layout to generate the diagram." - public static final SynthesisOption TOPDOWN_HIERARCHICAL_NODE_WIDTH = - SynthesisOption.createRangeOption("Topdown Hierarchical Node Width", 50.0f, 5000.0f, 1.0f, 150.0f) + public static final SynthesisOption SCALE_CAP = + SynthesisOption.createCheckOption(TopdownLayoutHook, "Enable Scale Cap", true) .setCategory(GeneralSynthesisOptions::LAYOUT) + .description = "If the scale cap is enabled, elements will only be scaled down. Otherwise they will be + scaled up to fill all the available space." - public static final SynthesisOption TOPDOWN_HIERARCHICAL_NODE_ASPECT_RATIO = - SynthesisOption.createRangeOption("Topdown Hierarchical Node Aspect Ratio", 0.2f, 5.0f, 0.01f, 1.41f) + public static final SynthesisOption TOPDOWN_HIERARCHICAL_NODE_WIDTH = + SynthesisOption.createRangeOption(TopdownLayoutHook, "Topdown Hierarchical Node Width", 50.0f, 5000.0f, 1.0f, 150.0f) .setCategory(GeneralSynthesisOptions::LAYOUT) + .description = "The fixed width to assign to all hierarchical nodes." - public static final SynthesisOption SCALE_CAP = - SynthesisOption.createCheckOption(TopdownLayoutHook, "Enable Scale Cap", true) + public static final SynthesisOption TOPDOWN_HIERARCHICAL_NODE_ASPECT_RATIO = + SynthesisOption.createRangeOption(TopdownLayoutHook, "Topdown Hierarchical Node Aspect Ratio", 0.2f, 5.0f, 0.01f, 1.41f) .setCategory(GeneralSynthesisOptions::LAYOUT) + .description = "The aspect ratio all hierarchical nodes should have. Determines the height of the nodes." - -// public static final SynthesisOption override getDisplayedSynthesisOptions() { return #[