Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[doc] Add support for styled labels in view model for trees #3989

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

jerome-obeo
Copy link
Contributor

Pull request template

General purpose

What is the main goal of this pull request?

  • Bug fixes
  • New features
  • Documentation
  • Cleanup
  • Tests
  • Build / releng

Project management

  • Has the pull request been added to the relevant project and milestone? (Only if you know that your work is part of a specific iteration such as the current one)
  • Have the priority: and pr: labels been added to the pull request? (In case of doubt, start with the labels priority: low and pr: to review later)
  • Have the relevant issues been added to the pull request?
  • Have the relevant labels been added to the issues? (area:, difficulty:, type:)
  • Have the relevant issues been added to the same project and milestone as the pull request?
  • Has the CHANGELOG.adoc been updated to reference the relevant issues?
  • Have the relevant API breaks been described in the CHANGELOG.adoc? (Including changes in the GraphQL API)
  • In case of a change with a visual impact, are there any screenshots in the CHANGELOG.adoc? For example in doc/screenshots/2022.5.0-my-new-feature.png

Architectural decision records (ADR)

  • Does the title of the commit contributing the ADR start with [doc]?
  • Are the ADRs mentioned in the relevant section of the CHANGELOG.adoc?

Dependencies

  • Are the new / upgraded dependencies mentioned in the relevant section of the CHANGELOG.adoc?
  • Are the new dependencies justified in the CHANGELOG.adoc?

Frontend

This section is not relevant if your contribution does not come with changes to the frontend.

General purpose

  • Is the code properly tested? (Plain old JavaScript tests for business code and tests based on React Testing Library for the components)

Typing

We need to improve the typing of our code, as such, we require every contribution to come with proper TypeScript typing for both changes contributing new files and those modifying existing files.
Please ensure that the following statements are true for each file created or modified (this may require you to improve code outside of your contribution).

  • Variables have a proper type
  • Functions’ arguments have a proper type
  • Functions’ return type are specified
  • Hooks are properly typed:
    • useMutation<DATA_TYPE, VARIABLE_TYPE>(…)
    • useQuery<DATA_TYPE, VARIABLE_TYPE>(…)
    • useSubscription<DATA_TYPE, VARIABLE_TYPE>(…)
    • useMachine<CONTEXT_TYPE, EVENTS_TYPE>(…)
    • useState<STATE_TYPE>(…)
  • All components have a proper typing for their props
  • No useless optional chaining with ?. (if the GraphQL API specifies that a field cannot be null, do not treat it has potentially null for example)
  • Nullable values have a proper type (for example let diagram: Diagram | null = null;)

Backend

This section is not relevant if your contribution does not come with changes to the backend.

General purpose

  • Are all the event handlers tested?
  • Are the event processor tested?
  • Is the business code (services) tested?
  • Are diagram layout changes tested?

Architecture

  • Are data structure classes properly separated from behavioral classes?
  • Are all the relevant fields final?
  • Is any data structure mutable? If so, please write a comment indicating why
  • Are behavioral classes either stateless or side effect free?

Review

How to test this PR?

Please describe here the various use cases to test this pull request

  • Has the Kiwi TCMS test suite been updated with tests for this contribution?

@jerome-obeo jerome-obeo force-pushed the jgo/doc/add_adr_for_supporting_styled_label_in_tree_description branch from b6df9a5 to 4cbaabd Compare September 11, 2024 13:20
@sbegaudeau sbegaudeau added this to the 2024.11.0 milestone Sep 13, 2024
Comment on lines 25 to 36
The first additional owned property (``stylePalette``) holds all text styles that are defined in this tree specification.
This is a sort of catalog of all defined style that could be used (or not) for a particular tree item label (or one of its part).
We do prefer wrap all text styles in a dedicated property to avoid to mix them with other part of the tree specification (such as menu actions in a further work).
A similar approach has been followed for storing colors in a palette inside diagrams specification.
This property will be automatically created for each tree specification.

The second owned property (``labelStyles``) is the actual set of styles that are used for displaying labels in this tree specification.

```
StylePalette {
textStyles : TextStyleDescription [0..*]
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My first gripe with this is that none of this is particularly relevant to sole the problem described. It does not matter at all to support styled labels. It may be useful but it's definitely not the heart of the issue nor required. This is completely optional, start the ADR by the core of the solution.

The first major problem is defining the solution not how to organize it.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure what you mean?

For me the purpose of the "advanced" ADR was to agree on the technical stuff now, so afterward we could be autonomous with Florian?


=== Tree view DSL

Currently, the tree view DSL, ``TreeDescription`` only has the ``treeItemLabelExpression`` that returns the string to display regarding the given ``self`` element.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you really make that work while keeping a single treeItemLabelExpression?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The idea was that this expression would be used if ConditionalStyle predicate returns false.
I think in most use cases, users would not define style for their items and use the default style provided by the appplication (maybe I'm wrong). So by having this fallback mechanism it would reduce the complexity of defining a TreeDescription.

}

StyledLabelFragment {
labelExpression: InterpretedExpression<string>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is there another label expression here? I mean I understand this one, not the other one DiagramDescription#treeItemLabelExpression

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See above

Comment on lines 72 to 76
The styles applied to labels (or portions of label) are named and conditional and they hold an ordered list of styled label fragments.
In case the evaluation of its ``conditionExpression`` returns ``false`` no one of embedded fragments will be considered and an unstyled label will be used using the ``treeItemLabelExpression`` result.
If ``conditionExpression`` returns ``true``, fragments are considered in the specified order.
Each of them specifies the style of a sub-part of the label.
The ``labelExpression`` of the fragment should return the string itself and the style to apply is given through the reference of an actual TextStyleDescription through the ``style`` property.
Copy link
Member

@sbegaudeau sbegaudeau Sep 13, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think that it can realistically work for a couple of reason:

  • I would need to both define a label and another version of the label in case I want to have some fragments
  • This is not dynamic enough to be usable
  • You can't just consider the order the fragment like that, it won't work, you can't really sort all. The potential use case of a metamodel using one list.

Consider some my current use cases with the Papaya metamodel. It's a bit like a metamodel of the Java language. How can I, with your API create a description to let me specific the color for those examples:

Method types

  • I have some operations with parameters, there can be any number of parameters in the operations of my models from 0 to god knows how many.
  • I want the type of each value and the return type of the method in blue
  • I want to support displaying the parenthesis in grey
Capture d’écran 2024-09-13 à 15 00 41 Capture d’écran 2024-09-13 à 15 00 45

Keyword and generic types

  • I have classes, interfaces and records which can have generic types
  • They can have any number of generic type whatsoever
  • I want to support displaying keywords in purple
  • I want to support displaying generic types in light blue
  • I want to support displaying < and > in grey
Capture d’écran 2024-09-13 à 15 00 49 Capture d’écran 2024-09-13 à 15 01 05 Capture d’écran 2024-09-13 à 15 01 10

And finally, I don't want to manually define all the potential combinations of all the potential use cases. So in the case of my operations, I don't want to create a fragment for all the potential number of parameters in an operations that can appear. Just try to order all the fragments to make it work, it's not viable.

Unless I missed something, and I would be happy to be proved wrong, this approach cannot possibly work beyond basic use cases. With this approach based on conditional style, you are taking an existing solution (a hammer) and you are looking for a nail but it won't work.

I think you need to start using complex examples as the target to reach and stay focused on how to express potential solutions. You can't assume that the specifier will know at build time the number of fragments that will be required, models expressed by end users are too complex for such assumptions. You may need to start taking inspiration from our work on dynamic mappings in the form DSL which encountered the same issue. You could end up with something like this:

  • A new field TreeDescription#labelDescriptions: LabelDescription[1..*]
TreeItemLabelDescription {
  name: Identifier
  preconditionExpression: InterpretedExpression<boolean>
  children: TreeItemLabelElementDescription[1..*] // TreeItemLabelElementDescription is abstract
}
ForTreeItemLabelElementDescription extends TreeItemLabelElementDescription {
  iterator: String
  iterableExpression: InterpretedExpression<List<Object>>
  children: TreeItemLabelElementDescription[1..*]
}
IfTreeItemLabelElementDescription extends TreeItemLabelElementDescription {
  predicateExpression: InterpretedExpression<boolean>
  children: TreeItemLabelElementDescription[1..*]
}
TreeItemLabelFragmentDescription extends TreeItemLabelElementDescription {
  labelExpression: string
  colorExpression: InterpretedExpression<string>
  // All the other properties, it's not that relevant
}

With this, you could end up supporting the operation example like that:

Capture d’écran 2024-09-13 à 15 00 45
TreeDescription {
  labelDescriptions: [
    LabelDescription {
      name: "Operation"
      preconditionExpression: "aql:self.eClass() = papaya::Operation"
      children: [
        TreeItemLabelFragmentDescription {
          labelExpression: "aql:self.name"
          colorExpression: "black"
        },

        TreeItemLabelFragmentDescription {
          labelExpression: "("
          colorExpression: "grey"
        },

        ForTreeItemLabelElementDescription {
          iterator: "parameter"
          iterableExpression: "aql:self.parameters"
          children: [
            TreeItemLabelFragmentDescription{
              labelExpression: "aql:parameter.name",
              colorExpression: "black"
            },
            TreeItemLabelFragmentDescription{
              labelExpression: "aql:parameter.type.name",
              colorExpression: "blue"
            },
            IfTreeItemLabelElementDescription{
              predicateExpression: "aql:self.parameters.indexOf(parameter) <> (self.parameters.size() -1))
              children: [
                TreeItemLabelFragmentDescription{
                  labelExpression: ","
                  colorExpression: "black"
                }
              ]
            },
          ]
        },

        TreeItemLabelFragmentDescription {
          labelExpression: ")"
          colorExpression: "grey"
        },

        TreeItemLabelFragmentDescription {
          labelExpression: ":"
          colorExpression: "black"
        },

        TreeItemLabelFragmentDescription {
          labelExpression: "aql:self.type.name"
          colorExpression: "blue"
        },
      ]
    }
  ]
}

(I know, I'm not considering spaces but it's simple to add)

Now unless you can prove me that your solution can work to create the labels that I have given you as an example, prove me that my solution here cannot work even for my most complex examples. The first thing I care about is not creating a palette of TextStyle, it's completely optional, I want a solution which can work for complex use cases.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I totally agree with you solution for complex labels. But initial the Form DSL dit not provide the dynamic mapping at the begining so this solution would have been a first step (and sufficient for our use case). Afteward, we could have added the dynamic item to express the if and loop feature.

I agree that the complex example should be taken in consideration now to avoid any API break in the future. So you examples are good to keep in mind but it was not our intention to handle them as a first step.

Do you think that a first stage that do not handle complexe example as your is acceptable, or should we implement it now? (I'm affraid for my budget)

As a first step, we could introduce an abstract class that would allow us to extend with dynamic concepts afterwards?

Moreover, in our solution we add the capacity to express a meaninfull style. For example, as a specifier I want to create a Read Only style that display a text in italic and grey (or any another combination). Then I want to be able to reuse that style in many different scenario. The fact to link the the precondition, labe expression and the definition of the style make them not really reusable. It would mean for the specifier to dupplicate many time the colorExpression, isItalicExpresion and so on.

For example, in your example the "Black" style is repeated a lot of time. With our solution we would have a TextStyleDescription name "Default Style" with difine this "Black Color". Then it would be referenced any time needed.

Comment on lines 78 to 102
=== Backend

As far as ``isBoldExpression`` and ``isItalicExpression`` expressions are concerned, we need to add two boolean flags in the class ``StyledStringFragmentStyle`` to handle those style features.
``org.eclipse.sirius.components.emf.services.StyledStringConverter`` should also be updated to set those flags to ``false`` as the default value since this features are not present in EMF edit styles.

The graphQL type ``StyledStringFragmentStyle`` in trees/tree.graphqls should be updated with new flags to be able to retrieve those style features in the frontend code.

``ViewTreeDescriptionConverter`` should be updated to take into account the ``treeItemStyledLabel`` property from the view description.
The function passed to the ``treeItemLabelProvider`` of the tree description should be changed to return the correct ``StyledString`` according to the evaluation of the ``conditionExpression`` of the ``treeItemStyledLabel``.
If the condition is not valid, we need to build the StyledString from the ``treeItemLabelExpression`` evaluation, otherwise it is built using contained fragments.

=== Frontend

The type ``GQLStyledStringFragmentStyle`` should be updated to reflect the change in the graphQL type in the backend code.
The StyledLabel react component should be updated to handle new bold and italic style contained in the fragments.

== Status

Work in progress

== Consequences

The ``org.eclipse.sirius.components.emf.services.StyledStringConverter`` class which is in charge of converting an EMF style into a Sirius web one might have to be updated in the future.
We suspect that the URI of the font may contain flags for expressing the bold or italic style.
If this is verified, extraction of that information from the URI to the new flags should have to be made.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All this is fine and nice but completely secondary to bring support for existing styled labels in the tree DSL. That's about improving what exists today, ok. It's an entirely different matter.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes we could have created a second ADR for those but we wanted you to give us all your feedback in one time to reduce the loop cost.

@sbegaudeau
Copy link
Member

Capture d’écran 2024-09-13 à 15 01 05

Just to try another use case, something like the image above could then be expressed like that:

TreeDescription {
  labelDescriptions: [
    LabelDescription {
      name: "Class"
      preconditionExpression: "aql:self.eClass() = papaya::Interface"
      children: [
        TreeItemLabelFragmentDescription {
          labelExpression: "aql:self.visibility + ' '"
          colorExpression: "purple"
        },

        TreeItemLabelFragmentDescription {
          labelExpression: "interface "
          colorExpression: "purple"
        },


        TreeItemLabelFragmentDescription {
          labelExpression: "aql:self.name"
          colorExpression: "black"
        },

        IfTreeItemLabelElementDescription{
          predicateExpression: "aql:self.genericTypes.size() > 0"
          children: [
            TreeItemLabelFragmentDescription {
              labelExpression: "<"
              colorExpression: "grey"
            },

            ForTreeItemLabelElementDescription {
              iterator: "genericType"
              iterableExpression: "aql:self.genericTypes"
              children: [
                TreeItemLabelFragmentDescription{
                  labelExpression: "aql:genericType.name + ' '",
                  colorExpression: "turquoise"
                },
                IfTreeItemLabelElementDescription{
                  predicateExpression: "aql:self.genericTypes.indexOf(genericType) <> (self.genericTypes.size() -1))
                  children: [
                    TreeItemLabelFragmentDescription{
                      labelExpression: ","
                      colorExpression: "black"
                    }
                  ]
                },
              ]
            },

            TreeItemLabelFragmentDescription {
              labelExpression: ">"
              colorExpression: "grey"
            },
          ]
        },

        IfTreeItemLabelElementDescription{
          predicateExpression: "aql:self.extends.size() > 0"
          children: [
            TreeItemLabelFragmentDescription {
              labelExpression: " extends "
              colorExpression: "purple"
            },

            ForTreeItemLabelElementDescription {
              iterator: "extendedInterface"
              iterableExpression: "aql:self.extends"
              children: [
                TreeItemLabelFragmentDescription{
                  labelExpression: "aql:extendedInterface.name + ' '",
                  colorExpression: "black"
                },

                // FAILURE

                IfTreeItemLabelElementDescription{
                  predicateExpression: "aql:self.extendeds.indexOf(extendedInterface) <> (self.extends.size() -1))
                  children: [
                    TreeItemLabelFragmentDescription{
                      labelExpression: ","
                      colorExpression: "black"
                    }
                  ]
                },
              ]
            },
          ]
        }

      ]
    }
  ]
}

And here you have a failure of my language! It cannot create recursively the same structure. I cannot express in a generic way something like this:

Capture d’écran 2024-09-13 à 15 46 08

So the next issue to be solved, is an issue of reusability but not the reusability of the style, it does not matter since it does not prevent me from creating what I need but instead a reusability of the logic to match what I want to express.

@sbegaudeau
Copy link
Member

sbegaudeau commented Sep 13, 2024

This is something that we have solved already with the reusability of NodeDescription as children. For example for a component diagram where components can be children of themselves. But there is one critical difference in our case, we need to control the order which is not the case in a diagram (nobody cares about the order of both NodeDescription#childrenDescriptions and NodeDescription#reusedChildNodeDescriptions). So the solution needs to be different, something like this maybe:

ReusedTreeItemLabelElementDescription extends TreeItemLabelElementDescription {
  elements: TreeItemLabelElementDescription[0..*]
}

to let us create something like that:

TreeDescription {
  labelDescriptions: [
    LabelDescription {
      name: "Class"
      preconditionExpression: "aql:self.eClass() = papaya::Interface"
      children: [
        TreeItemLabelFragmentDescription {
          labelExpression: "aql:self.visibility + ' '"
          colorExpression: "purple"
        },

        TreeItemLabelFragmentDescription {
          labelExpression: "interface "
          colorExpression: "purple"
        },


        TreeItemLabelFragmentDescription {
          labelExpression: "aql:self.name"
          colorExpression: "black"
        },

        IfTreeItemLabelElementDescription{
          predicateExpression: "aql:self.genericTypes.size() > 0"
          children: [
            TreeItemLabelFragmentDescription {
              labelExpression: "<"
              colorExpression: "grey"
            },

            ForTreeItemLabelElementDescription {
              iterator: "genericType"
              iterableExpression: "aql:self.genericTypes"
              children: [
                TreeItemLabelFragmentDescription{
                  labelExpression: "aql:genericType.name + ' '",
                  colorExpression: "turquoise"
                },
                IfTreeItemLabelElementDescription{
                  predicateExpression: "aql:self.genericTypes.indexOf(genericType) <> (self.genericTypes.size() -1))
                  children: [
                    TreeItemLabelFragmentDescription{
                      labelExpression: ","
                      colorExpression: "black"
                    }
                  ]
                },
              ]
            },

            TreeItemLabelFragmentDescription {
              labelExpression: ">"
              colorExpression: "grey"
            },
          ]
        },

        IfTreeItemLabelElementDescription{
          predicateExpression: "aql:self.extends.size() > 0"
          children: [
            TreeItemLabelFragmentDescription {
              labelExpression: " extends "
              colorExpression: "purple"
            },

            ForTreeItemLabelElementDescription {
              iterator: "extendedInterface"
              iterableExpression: "aql:self.extends"
              children: [
                ReusedItemLabelFragmentDescription{
                   element: non containment reference to the name, the generic types, the extends etc.
                },

                IfTreeItemLabelElementDescription{
                  predicateExpression: "aql:self.extendeds.indexOf(extendedInterface) <> (self.extends.size() -1))
                  children: [
                    TreeItemLabelFragmentDescription{
                      labelExpression: ","
                      colorExpression: "black"
                    }
                  ]
                },
              ]
            },
          ]
        }

      ]
    }
  ]
}

This would work.

Since it should allow us to reuse pretty much anything, I don't think we even need a palette for styles at all.

@sbegaudeau
Copy link
Member

With this latest solution, I can:

  • Use fragments conditionally thanks to the "If"
  • Use a dynamic number of fragments thanks to the "For"
  • Reuse any number of parts of another label thanks to the "Reuse"
  • Create recursive labels thanks to the "Reuse"

Is there any use case that I'm missing?

@adaussy
Copy link
Contributor

adaussy commented Sep 13, 2024

Capture d’écran 2024-09-13 à 15 01 05 Just to try another use case, something like the image above could then be expressed like that:
TreeDescription {
  labelDescriptions: [
    LabelDescription {
      name: "Class"
      preconditionExpression: "aql:self.eClass() = papaya::Interface"
      children: [
        TreeItemLabelFragmentDescription {
          labelExpression: "aql:self.visibility + ' '"
          colorExpression: "purple"
        },

        TreeItemLabelFragmentDescription {
          labelExpression: "interface "
          colorExpression: "purple"
        },


        TreeItemLabelFragmentDescription {
          labelExpression: "aql:self.name"
          colorExpression: "black"
        },

        IfTreeItemLabelElementDescription{
          predicateExpression: "aql:self.genericTypes.size() > 0"
          children: [
            TreeItemLabelFragmentDescription {
              labelExpression: "<"
              colorExpression: "grey"
            },

            ForTreeItemLabelElementDescription {
              iterator: "genericType"
              iterableExpression: "aql:self.genericTypes"
              children: [
                TreeItemLabelFragmentDescription{
                  labelExpression: "aql:genericType.name + ' '",
                  colorExpression: "turquoise"
                },
                IfTreeItemLabelElementDescription{
                  predicateExpression: "aql:self.genericTypes.indexOf(genericType) <> (self.genericTypes.size() -1))
                  children: [
                    TreeItemLabelFragmentDescription{
                      labelExpression: ","
                      colorExpression: "black"
                    }
                  ]
                },
              ]
            },

            TreeItemLabelFragmentDescription {
              labelExpression: ">"
              colorExpression: "grey"
            },
          ]
        },

        IfTreeItemLabelElementDescription{
          predicateExpression: "aql:self.extends.size() > 0"
          children: [
            TreeItemLabelFragmentDescription {
              labelExpression: " extends "
              colorExpression: "purple"
            },

            ForTreeItemLabelElementDescription {
              iterator: "extendedInterface"
              iterableExpression: "aql:self.extends"
              children: [
                TreeItemLabelFragmentDescription{
                  labelExpression: "aql:extendedInterface.name + ' '",
                  colorExpression: "black"
                },

                // FAILURE

                IfTreeItemLabelElementDescription{
                  predicateExpression: "aql:self.extendeds.indexOf(extendedInterface) <> (self.extends.size() -1))
                  children: [
                    TreeItemLabelFragmentDescription{
                      labelExpression: ","
                      colorExpression: "black"
                    }
                  ]
                },
              ]
            },
          ]
        }

      ]
    }
  ]
}

And here you have a failure of my language! It cannot create recursively the same structure. I cannot express in a generic way something like this:

Capture d’écran 2024-09-13 à 15 46 08 So the next issue to be solved, is an issue of reusability but not the reusability of the style, it does not matter since it does not prevent me from creating what I need but instead a reusability of the logic to match what I want to express.

Again in the diagram DSL, the reused mapping was introduce as a second step.

I'm really not sure to have the budget to handle all those case in my current projet. I guess we need to discuss that.

@adaussy
Copy link
Contributor

adaussy commented Sep 13, 2024

With this latest solution, I can:

  • Use fragments conditionally thanks to the "If"
  • Use a dynamic number of fragments thanks to the "For"
  • Reuse any number of parts of another label thanks to the "Reuse"
  • Create recursive labels thanks to the "Reuse"

Is there any use case that I'm missing?

No I think you got it all, but do you think that we could split this development effort in several steps?

@adaussy
Copy link
Contributor

adaussy commented Sep 13, 2024

We are going to rewrite this ADR taking your remarks in consideration but I need to understand if you are expecting us to implements all those features or if we could split the effort to stop when we have everthing we need; or you want all those feature in one PR?

@jerome-obeo jerome-obeo force-pushed the jgo/doc/add_adr_for_supporting_styled_label_in_tree_description branch from 4cbaabd to 44c7544 Compare September 16, 2024 12:55
@jerome-obeo
Copy link
Contributor Author

I rewrote the ADR to fit with the comments:

  • only one property in TreeDescription for expressing style descriptions.
  • handle complex control flow for fragment description (if, for, and reuse)
  • fragments reference TextStyledDescription that are stored inside a root TextStylePalette similar to ColorPalette
  • remove some details aside from the main work (for instance missing text style properties bold and italic)


TreeItemLabelFragmentDescription extends TreeItemLabelElementDescription {
labelExpression: String
style: TextStyleDescription [0..1]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please specifiy it is non containment reference

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done


=== Usage example

The following style description handles the operation with argument' and returned types in blue.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typo after argument

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

children: [
TreeItemLabelFragmentDescription {
labelExpression: "aql:self.name"
style: TextStyleDescription {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess here it would be more a reference to a BackLabelStyle TextStyleDescription

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

@jerome-obeo jerome-obeo force-pushed the jgo/doc/add_adr_for_supporting_styled_label_in_tree_description branch from 44c7544 to 8168a8c Compare September 16, 2024 15:06
@jerome-obeo jerome-obeo force-pushed the jgo/doc/add_adr_for_supporting_styled_label_in_tree_description branch 2 times, most recently from 468303e to 87af093 Compare September 25, 2024 15:04
@jerome-obeo jerome-obeo force-pushed the jgo/doc/add_adr_for_supporting_styled_label_in_tree_description branch from 87af093 to b8320a3 Compare September 27, 2024 13:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants