Skip to content

Commit

Permalink
[2535] Make possible to hide the header separator in the view DSL
Browse files Browse the repository at this point in the history
Bug: #2535
Signed-off-by: Guillaume Coutable <guillaume.coutable@obeo.fr>
  • Loading branch information
gcoutable committed Nov 8, 2023
1 parent cdc3f59 commit a8490a9
Show file tree
Hide file tree
Showing 30 changed files with 237 additions and 21 deletions.
5 changes: 4 additions & 1 deletion CHANGELOG.adoc
Expand Up @@ -42,8 +42,11 @@ Update the graphql API accordingly.
- https://github.com/eclipse-sirius/sirius-web/issues/2516[#2516] [diagram] Add to the diagram core API the possibility to display the header separator when the inside label is a header.
It requires to add a `displayHeaderSeparatorProvider` to the _InsideLabelDescription_.
For the compatibility layer, the separator will always be displayed if the label is inside a node displaying its children has a list.
In a near future it will be possible to customize that value using the View DSL, but for now, the `displayHeaderSeparatorProvider` has the same value as `isHeaderProvider`.
Add the attribute `displayHeaderSeparator` to the graphql API.
- https://github.com/eclipse-sirius/sirius-web/issues/2535[#2535] [view] Add the possibility for the header separator to be displayed or hidden in the View DSL.
+
.Compartment with header without separator
image:doc/screenshots/compartmentWithHeaderWithoutSeparator.png[Compartment with header without separator,30%]

=== Dependency update

Expand Down
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Expand Up @@ -68,6 +68,7 @@ const toListNode = (
text: insideLabel.text,
iconURL: labelStyle.iconURL,
isHeader: insideLabel.isHeader,
displayHeaderSeparator: insideLabel.displayHeaderSeparator,
style: {
display: 'flex',
flexDirection: 'row',
Expand All @@ -82,7 +83,7 @@ const toListNode = (
const alignement = AlignmentMap[insideLabel.insideLabelLocation];
if (alignement.isPrimaryVerticalAlignment) {
if (alignement.primaryAlignment === 'TOP') {
if (insideLabel.displayHeaderSeparator) {
if (data.label.displayHeaderSeparator) {
data.label.style.borderBottom = `${style.borderSize}px ${style.borderStyle} ${style.borderColor}`;
}
data.style = { ...data.style, display: 'flex', flexDirection: 'column', justifyContent: 'flex-start' };
Expand Down
Expand Up @@ -68,6 +68,7 @@ const toRectangularNode = (
id: insideLabel.id,
text: insideLabel.text,
isHeader: insideLabel.isHeader,
displayHeaderSeparator: insideLabel.displayHeaderSeparator,
style: {
display: 'flex',
flexDirection: 'row',
Expand All @@ -83,7 +84,7 @@ const toRectangularNode = (
const alignement = AlignmentMap[insideLabel.insideLabelLocation];
if (alignement.isPrimaryVerticalAlignment) {
if (alignement.primaryAlignment === 'TOP') {
if (insideLabel.displayHeaderSeparator) {
if (data.label.displayHeaderSeparator) {
data.label.style.borderBottom = `${style.borderSize}px ${style.borderStyle} ${style.borderColor}`;
}
data.style = { ...data.style, display: 'flex', flexDirection: 'column', justifyContent: 'flex-start' };
Expand Down
Expand Up @@ -83,4 +83,5 @@ export interface Label {
iconURL: string[];
style: React.CSSProperties;
isHeader?: boolean;
displayHeaderSeparator?: boolean;
}
Expand Up @@ -92,7 +92,7 @@ export class ListNodeLayoutHandler implements INodeLayoutHandler<ListNodeData> {

const nodeIndex = findNodeIndex(visibleNodes, node.id);
const labelElement = document.getElementById(`${node.id}-label-${nodeIndex}`);
const withHeader = node.data.label?.isHeader;
const withHeader: boolean = node.data.label?.isHeader ?? false;

const borderNodes = directChildren.filter((node) => node.data.isBorderNode);
const directNodesChildren = directChildren.filter((child) => !child.data.isBorderNode);
Expand Down
Expand Up @@ -79,7 +79,8 @@ export class RectangleNodeLayoutHandler implements INodeLayoutHandler<Rectangula

const nodeIndex = findNodeIndex(visibleNodes, node.id);
const labelElement = document.getElementById(`${node.id}-label-${nodeIndex}`);
const withHeader = node.data.label?.isHeader ?? false;
const withHeader: boolean = node.data.label?.isHeader ?? false;
const displayHeaderSeparator: boolean = node.data.label?.displayHeaderSeparator ?? false;

const borderNodes = directChildren.filter((node) => node.data.isBorderNode);
const directNodesChildren = directChildren.filter((child) => !child.data.isBorderNode);
Expand All @@ -95,14 +96,22 @@ export class RectangleNodeLayoutHandler implements INodeLayoutHandler<Rectangula
} else if (previousNode) {
child.position = previousNode.position;
} else {
child.position = getChildNodePosition(visibleNodes, child, labelElement, withHeader, borderWidth);
child.position = getChildNodePosition(
visibleNodes,
child,
labelElement,
withHeader,
displayHeaderSeparator,
borderWidth
);
const previousSibling = directNodesChildren[index - 1];
if (previousSibling) {
child.position = getChildNodePosition(
visibleNodes,
child,
labelElement,
withHeader,
displayHeaderSeparator,
borderWidth,
previousSibling
);
Expand All @@ -126,7 +135,6 @@ export class RectangleNodeLayoutHandler implements INodeLayoutHandler<Rectangula
northBorderNodeFootprintWidth,
southBorderNodeFootprintWidth
) +
rectangularNodePadding * 2 +
borderWidth * 2;

// WARN: the label is not used for the height because children are already position under the label
Expand Down
Expand Up @@ -10,7 +10,7 @@
* Contributors:
* Obeo - initial API and implementation
*******************************************************************************/
import { Box, Node, Rect, boxToRect, rectToBox } from 'reactflow';
import { Box, Node, Rect, XYPosition, boxToRect, rectToBox } from 'reactflow';
import { Diagram, NodeData } from '../DiagramRenderer.types';
import {
getBorderNodeExtent,
Expand Down Expand Up @@ -67,15 +67,15 @@ export const getNodeOrMinHeight = (nodeHeight: number | undefined): number => {
return Math.max(nodeHeight ?? -Infinity, defaultHeight);
};

// WARN: should be moved in RectangularNodeLayoutHandler.ts
export const getChildNodePosition = (
allVisibleNodes: Node<NodeData>[],
child: Node<NodeData>,
labelElement: HTMLElement | null,
withHeader: boolean,
displayHeaderSeparator: boolean,
borderWidth: number,
previousSibling?: Node<NodeData>
) => {
): XYPosition => {
const maxWestBorderNodeWidth = getChildren(child, allVisibleNodes)
.filter(isWestBorderNode)
.map((borderNode) => getNodeFootprint(allVisibleNodes, borderNode).width || 0)
Expand All @@ -87,11 +87,11 @@ export const getChildNodePosition = (
.reduce((a, b) => Math.max(a, b), 0);

if (!previousSibling) {
const headerFootprint = withHeader ? labelElement?.getBoundingClientRect().height ?? 0 : 0;
const headerFootprint = labelElement ? getHeaderFootprint(labelElement, withHeader, displayHeaderSeparator) : 0;

return {
x: rectangularNodePadding + borderWidth + maxWestBorderNodeWidth,
y: borderWidth + headerFootprint + rectangularNodePadding + maxNorthBorderNodeHeight,
y: borderWidth + headerFootprint + maxNorthBorderNodeHeight,
};
} else {
const previousSiblingsMaxEastBorderNodeWidth = getChildren(previousSibling, allVisibleNodes)
Expand All @@ -111,6 +111,23 @@ export const getChildNodePosition = (
}
};

const getHeaderFootprint = (
labelElement: HTMLElement,
withHeader: boolean,
displayHeaderSeparator: boolean
): number => {
let headerFootprint = 0;

if (withHeader) {
headerFootprint = labelElement.getBoundingClientRect().height;
if (displayHeaderSeparator) {
headerFootprint += rectangularNodePadding;
}
}

return headerFootprint;
};

/**
* Returns the node footprint.
* It requires node border nodes to be positioned.
Expand Down Expand Up @@ -168,7 +185,7 @@ export const setBorderNodesPosition = (
borderNodes: Node<NodeData>[],
nodeToLayout: Node<NodeData>,
previousDiagram: Diagram | null
) => {
): void => {
const borderNodesEast = borderNodes.filter(isEastBorderNode);
borderNodesEast.forEach((child, index) => {
const previousBorderNode = (previousDiagram?.nodes ?? []).find((previousNode) => previousNode.id === child.id);
Expand Down
Expand Up @@ -63,6 +63,7 @@ public NodeDescription create() {
.borderColor(this.colorProvider.getColor("border_blue"))
.labelColor(this.colorProvider.getColor("label_white"))
.withHeader(false)
.displayHeaderSeparator(false)
.build())
.synchronizationPolicy(SynchronizationPolicy.UNSYNCHRONIZED)
.conditionalStyles(this.diagramBuilderHelper.newConditionalNodeStyle()
Expand All @@ -72,6 +73,7 @@ public NodeDescription create() {
.borderColor(this.colorProvider.getColor("border_green"))
.labelColor(this.colorProvider.getColor("label_white"))
.withHeader(false)
.displayHeaderSeparator(false)
.build())
.build())
.build();
Expand Down
Expand Up @@ -47,6 +47,7 @@ public NodeDescription create() {
nodeStyle.setBorderColor(this.colorProvider.getColor("border_blue_2"));
nodeStyle.setLabelColor(this.colorProvider.getColor("label_white"));
nodeStyle.setWithHeader(true);
nodeStyle.setDisplayHeaderSeparator(true);

var builder = new PapayaViewBuilder();
var domainType = builder.domainType(builder.entity("Interface"));
Expand Down
Expand Up @@ -46,6 +46,7 @@ public NodeDescription create() {
nodeStyle.setBorderColor(this.colorProvider.getColor("border_blue_3"));
nodeStyle.setLabelColor(this.colorProvider.getColor("label_black"));
nodeStyle.setWithHeader(true);
nodeStyle.setDisplayHeaderSeparator(false);

var builder = new PapayaViewBuilder();
var domainType = builder.domainType(builder.entity("Package"));
Expand Down
Expand Up @@ -48,6 +48,7 @@ public NodeDescription create() {
nodeStyle.setBorderColor(this.colorProvider.getColor("border_blue"));
nodeStyle.setLabelColor(this.colorProvider.getColor("label_white"));
nodeStyle.setWithHeader(true);
nodeStyle.setDisplayHeaderSeparator(true);

var nodeDescription = new PapayaViewBuilder().createNodeDescription("Class");
nodeDescription.setSemanticCandidatesExpression("aql:self.types");
Expand Down Expand Up @@ -138,6 +139,7 @@ private NodeDescription attributesNodeDescription() {
abstractNodeStyle.setBorderColor(this.colorProvider.getColor("border_green"));
abstractNodeStyle.setLabelColor(this.colorProvider.getColor("label_white"));
abstractNodeStyle.setWithHeader(false);
abstractNodeStyle.setDisplayHeaderSeparator(false);

var abstractConditionalNodeStyle = DiagramFactory.eINSTANCE.createConditionalNodeStyle();
abstractConditionalNodeStyle.setCondition("aql:self.abstract");
Expand Down Expand Up @@ -187,6 +189,7 @@ private NodeDescription operationsNodeDescription() {
abstractNodeStyle.setBorderColor(this.colorProvider.getColor("border_green"));
abstractNodeStyle.setLabelColor(this.colorProvider.getColor("label_white"));
abstractNodeStyle.setWithHeader(false);
abstractNodeStyle.setDisplayHeaderSeparator(false);

var abstractConditionalNodeStyle = DiagramFactory.eINSTANCE.createConditionalNodeStyle();
abstractConditionalNodeStyle.setCondition("aql:self.abstract");
Expand Down
Expand Up @@ -44,6 +44,7 @@ public NodeDescription create() {
nodeStyle.setBorderColor(this.colorProvider.getColor("border_blue_4"));
nodeStyle.setLabelColor(this.colorProvider.getColor("label_black"));
nodeStyle.setWithHeader(true);
nodeStyle.setDisplayHeaderSeparator(false);

var nodeDescription = new PapayaViewBuilder().createNodeDescription("Component");
nodeDescription.setSemanticCandidatesExpression("aql:self.components");
Expand Down
Expand Up @@ -41,6 +41,7 @@ public NodeDescription create() {
nodeStyle.setBorderColor(this.colorProvider.getColor("border_green_2"));
nodeStyle.setLabelColor(this.colorProvider.getColor("label_white"));
nodeStyle.setWithHeader(true);
nodeStyle.setDisplayHeaderSeparator(true);

var nodeDescription = new PapayaViewBuilder().createNodeDescription("Enum");
nodeDescription.setChildrenLayoutStrategy(DiagramFactory.eINSTANCE.createListLayoutStrategyDescription());
Expand Down
Expand Up @@ -42,6 +42,7 @@ public NodeDescription create() {
nodeStyle.setBorderColor(this.colorProvider.getColor("border_blue_2"));
nodeStyle.setLabelColor(this.colorProvider.getColor("label_white"));
nodeStyle.setWithHeader(true);
nodeStyle.setDisplayHeaderSeparator(true);

var nodeDescription = new PapayaViewBuilder().createNodeDescription("Interface");
nodeDescription.setSemanticCandidatesExpression("aql:self.types");
Expand Down
Expand Up @@ -46,6 +46,7 @@ public NodeDescription create() {
nodeStyle.setBorderColor(this.colorProvider.getColor("border_blue_3"));
nodeStyle.setLabelColor(this.colorProvider.getColor("label_black"));
nodeStyle.setWithHeader(true);
nodeStyle.setDisplayHeaderSeparator(false);

var nodeDescription = new PapayaViewBuilder().createNodeDescription("Package");
nodeDescription.setSemanticCandidatesExpression("aql:self.eContents()");
Expand Down
Expand Up @@ -43,6 +43,7 @@ public NodeDescription create() {
operationalActorNodeStyle.setBorderColor(this.colorProvider.getColor("border_gray"));
operationalActorNodeStyle.setLabelColor(this.colorProvider.getColor("label_black"));
operationalActorNodeStyle.setWithHeader(true);
operationalActorNodeStyle.setDisplayHeaderSeparator(false);

var operationalActorEmptyNodeStyle = DiagramFactory.eINSTANCE.createImageNodeStyleDescription();
operationalActorEmptyNodeStyle.setShape("4d9a22c0-dc36-31c9-bb6a-c18c66b51d93");
Expand Down
Expand Up @@ -43,6 +43,7 @@ public NodeDescription create() {
nodeStyle.setBorderColor(this.colorProvider.getColor("border_gray"));
nodeStyle.setLabelColor(this.colorProvider.getColor("label_black"));
nodeStyle.setWithHeader(true);
nodeStyle.setDisplayHeaderSeparator(false);

var builder = new PapayaViewBuilder();

Expand Down
Expand Up @@ -44,6 +44,7 @@ public NodeDescription create() {
nodeStyle.setBorderColor(this.colorProvider.getColor("border_gray_2"));
nodeStyle.setLabelColor(this.colorProvider.getColor("label_black"));
nodeStyle.setWithHeader(true);
nodeStyle.setDisplayHeaderSeparator(false);

var nodeDescription = new PapayaViewBuilder().createNodeDescription("OperationalPerimeter");
nodeDescription.setSemanticCandidatesExpression("aql:self.operationalPerimeters");
Expand Down
Expand Up @@ -188,5 +188,15 @@ public RectangularNodeStyleDescriptionBuilder withHeader(java.lang.Boolean value
return this;
}

/**
* Setter for DisplayHeaderSeparator.
*
* @generated
*/
public RectangularNodeStyleDescriptionBuilder displayHeaderSeparator(java.lang.Boolean value) {
this.getRectangularNodeStyleDescription().setDisplayHeaderSeparator(value);
return this;
}

}

Expand Up @@ -67,6 +67,7 @@ public List<IItemPropertyDescriptor> getPropertyDescriptors(Object object) {
this.addShowIconPropertyDescriptor(object);
this.addLabelIconPropertyDescriptor(object);
this.addWithHeaderPropertyDescriptor(object);
this.addDisplayHeaderSeparatorPropertyDescriptor(object);
}
return this.itemPropertyDescriptors;
}
Expand Down Expand Up @@ -244,6 +245,19 @@ protected void addWithHeaderPropertyDescriptor(Object object) {
DiagramPackage.Literals.RECTANGULAR_NODE_STYLE_DESCRIPTION__WITH_HEADER, true, false, false, ItemPropertyDescriptor.BOOLEAN_VALUE_IMAGE, null, null));
}

/**
* This adds a property descriptor for the Display Header Separator feature. <!-- begin-user-doc --> <!--
* end-user-doc -->
*
* @generated
*/
protected void addDisplayHeaderSeparatorPropertyDescriptor(Object object) {
this.itemPropertyDescriptors.add(this.createItemPropertyDescriptor(((ComposeableAdapterFactory) this.adapterFactory).getRootAdapterFactory(), this.getResourceLocator(),
this.getString("_UI_RectangularNodeStyleDescription_displayHeaderSeparator_feature"),
this.getString("_UI_PropertyDescriptor_description", "_UI_RectangularNodeStyleDescription_displayHeaderSeparator_feature", "_UI_RectangularNodeStyleDescription_type"),
DiagramPackage.Literals.RECTANGULAR_NODE_STYLE_DESCRIPTION__DISPLAY_HEADER_SEPARATOR, true, false, false, ItemPropertyDescriptor.BOOLEAN_VALUE_IMAGE, null, null));
}

/**
* This returns RectangularNodeStyleDescription.gif. <!-- begin-user-doc --> <!-- end-user-doc -->
*
Expand Down Expand Up @@ -302,6 +316,7 @@ public void notifyChanged(Notification notification) {
case DiagramPackage.RECTANGULAR_NODE_STYLE_DESCRIPTION__SHOW_ICON:
case DiagramPackage.RECTANGULAR_NODE_STYLE_DESCRIPTION__LABEL_ICON:
case DiagramPackage.RECTANGULAR_NODE_STYLE_DESCRIPTION__WITH_HEADER:
case DiagramPackage.RECTANGULAR_NODE_STYLE_DESCRIPTION__DISPLAY_HEADER_SEPARATOR:
this.fireNotifyChanged(new ViewerNotification(notification, notification.getNotifier(), false, true));
return;
}
Expand Down
@@ -1,23 +1,24 @@
################################################################################
# Copyright (c) 2021, 2023 Obeo.
# This program and the accompanying materials
# are made available under the terms of the Eclipse Public License v2.0
# which accompanies this distribution, and is available at
# https://www.eclipse.org/legal/epl-2.0/
#
#
# SPDX-License-Identifier: EPL-2.0
#
#
# Contributors:
# Obeo - initial API and implementation
#################################################################################

pluginName = Diagram Edit Support
providerName = www.example.org

_UI_CreateChild_text = {0}
_UI_CreateChild_text2 = {1} {0}
_UI_CreateChild_text3 = {1}
_UI_CreateChild_tooltip = Create New {0} Under {1} Feature
_UI_CreateChild_description = Create a new child of type {0} for the {1} feature of the selected {2}.
_UI_CreateSibling_description = Create a new sibling of type {0} for the selected {2}, under the {1} feature of their parent.

_UI_PropertyDescriptor_description = The {0} of the {1}
_UI_DiagramDescription_type = Diagram Description
_UI_DiagramElementDescription_type = Diagram Element Description
Expand Down Expand Up @@ -56,7 +57,9 @@ _UI_NodeToolSection_type = Node Tool Section
_UI_EdgeToolSection_type = Edge Tool Section
_UI_DropNodeTool_type = Drop Node Tool
_UI_Unknown_type = Object
_UI_Unknown_datatype = Value

_UI_Unknown_datatype= Value

_UI_DiagramDescription_autoLayout_feature = Auto Layout
_UI_DiagramDescription_palette_feature = Palette
_UI_DiagramDescription_nodeDescriptions_feature = Node Descriptions
Expand Down Expand Up @@ -99,6 +102,7 @@ _UI_NodeStyleDescription_showIcon_feature = Show Icon
_UI_NodeStyleDescription_labelIcon_feature = Label Icon
_UI_ConditionalNodeStyle_style_feature = Style
_UI_RectangularNodeStyleDescription_withHeader_feature = With Header
_UI_RectangularNodeStyleDescription_displayHeaderSeparator_feature = Display Header Separator
_UI_ImageNodeStyleDescription_shape_feature = Shape
_UI_EdgeStyle_lineStyle_feature = Line Style
_UI_EdgeStyle_sourceArrowStyle_feature = Source Arrow Style
Expand Down Expand Up @@ -144,6 +148,7 @@ _UI_NodeToolSection_edgeTools_feature = Edge Tools
_UI_EdgeToolSection_nodeTools_feature = Node Tools
_UI_DropNodeTool_acceptedNodeTypes_feature = Accepted Node Types
_UI_Unknown_feature = Unspecified

_UI_ArrowStyle_None_literal = None
_UI_ArrowStyle_OutputArrow_literal = OutputArrow
_UI_ArrowStyle_InputArrow_literal = InputArrow
Expand Down

0 comments on commit a8490a9

Please sign in to comment.