TextBox
Together, these proposals are intended to support a ‘TextBox’ behavior similar to PowerPoint.
- Add margin to TextBlock.
- Add a Height property to either TextBlock or TextAnnotation
- Add text frame shape to TextAnnotation2d.
- We should remove either TextBlock.justification or TextAnnotation.Anchor.horizontal. They are redundant
Also, I think we need to seriously consider how we will implement leaders and how they attach to text. I have some ideas.
The Drawing Production team stands ready to help.
@pmconne, @claudiaareneee , @SheetalNair , @Alfonso-Martello
Related to Issue: Text Leader
We should remove either TextBlock.justification or TextAnnotation.Anchor.horizontal. They are redundant
Please explain why you consider them redundant. Anchor point is orthogonal to text justification.
Add a Height property to either TextBlock or TextAnnotation
Is this to control the height of the text frame shape? If not, please explain your motivation.
Add margin to TextBlock.
Is this to control the width of the text frame shape? If not, please explain your motivation.
Also, I think we need to seriously consider how we will implement leaders and how they attach to text. I have some ideas.
Please elaborate. FWIW, @jffmarker had concepts of AnnotationFrameStyle and AnnotationLeaderStyle in the C++ implementation of text annotations which to my understanding were never used.
@Josh-Schifter, I made these issues:
- #7675
- #7676
- #7677 (not an exact overlap, but could be reworked)
Could these help explain the motivations?
Could these help explain the motivations?
Not really. They all specify what you want on a technical level, not why you (or users) want it, except for a mention of legibility on the fillColor one.
It seems like most of the issues you previously filed and now Josh has enumerated in this issue's description revolve around this concept of a "TextBox". I'm trying to understand what problem(s) you intend to solve by introducing a "TextBox behavior similar to PowerPoint". Your fillColor issue mentions possibly using an oval shape instead of a box - is that also a kind of "TextBox"?
I'm not trying to be difficult. I want to make sure we nail down what a TextBox is and what it's used for before we get into "TextBlocks should have X" level of detail?
In C++ land, I was still trying to mimic primarily what MicroStation and AutoCAD had in terms of text. If you're going for a PowerPoint-type presentation, what I had is probably insufficient since that wasn't my intent.
Basically yes, we're trying produce a powerpoint-esc sort of workflow. These work items are to help make that happen. Here's what that means and a bit of justification.
We're working on drawing production, so let's look at a sheet:
Image source - both come from the same video
Notice a couple things:
- There are a variety of text elements. Many of them are contained with in a shape whether that's a circle, square, triangle, or cloud.
- That text has a bit of a buffer around it, or margin.
- When text overlaps on the drawing, sometimes a background is added for clarity.
What we aim to do is enable users to make things like this.
Some considerations:
- While the shapes/borders could be an independent element. It would be better if they were part of the text element itself. If for nothing else than logical grouping. It would also help with actions like copy and paste, selection, etc.
- We could also do something like the dimensions we have. Logically, however, the borders and margins are directly related to the text and nothing else. Our dimenions have other logic for arrows, length, etc., that are not relevant to the text at all.
- Powerpoint already does this. Their workflow is fairly intuitive, tried, and tested. This is why we're sort of using it as a blueprint.
@Josh-Schifter, am I missing anything or did I get anything wrong?
PowerPoint has both a "text box" and "shapes" that can have text in them... which one are you trying to mimic?
We are not trying to mimic PowerPoint. Claudia's comments are dead on. This is not a new thing. Think about notes in MicroStation for a moment. It was a Frankenstein that we cobbled together despite the lack of underlying text support. The image shows the different frames supported by notes in MicroStation. There is no reason for Note to be a different element type from Text. In fact, I think it makes things more difficult for users and for developers.
Similar comments for tables. Yes, I can make text inside table cells work well despite lack of underlying support. However, things will fit together easier if I can rely on the text to position itself within the table cell, rather than having to do it in the table code.
We have an opportunity now for text to natively support frames, rather than tacking them on as an afterthought.
A Note in MicroStation consists of three elements, Frame, Text, and Leader. My hope is that we have good enough support in text that we can combine Frame and Text into a single element type. Honestly, those two interact in a very intimate way as described above.
I've done a lot of thinking about also combining Leaders and I'm not convinced those should be part of the same element. For several reasons I would like to include Leaders, but I'm leaning toward keeping them separate.
Please explain why you consider them redundant. Anchor point is orthogonal to text justification.
As implemented they are orthogonal, however I contend that users will never want a mismatch between them. To understand my point, I think it helps to consider that all text lives inside a rectangle (like a table cell). The anchor point is supposed to specify the most natural point around which to make manipulations. I contend there is no value in making manipulations around a point distant from the text. Example, in the image below, what value is there in rotating this text around the right edge?
Example two, in a table I use the anchor point for 'cell alignment' and it works great for that as long as I always set the justification to match. If I don't, then the results are non-intuitive. I contend users will complain that the first cell looks like it is aligned to the left... it is not.
In MicroStation, to avoid this I take the justification from the text editor and use it to override the alignment of the cell. In fact, I literally just reproduced a bug caused by the two being in disagreement.
Last argument is that the additional flexibility just adds complexity. Other apps don't allow it. Users don't need it. Why have it?
Proposition:
- Remove
TextAnnotation.anchor. - Add
TextAnnotation.verticalAlignment: "top" | "middle" | "bottom" - Remove
TextBlock.justification - Add
Paragraph.justification: "left" | "right" | "center" | "justify"
Reasoning:
We want to be able to support multiple justifications within one text block. We honestly don't need to expose an anchor point. All we need is one origin, the width, and the height. I think the original reasoning for having an anchor point was to have a way to set a stationary point that we could attach a leader line to. We do still need this functionality but I propose we do this another way. I don't have a solution, but I think we can do better than what's in microstation.
in the image below, what value is there in rotating this text around the right edge?
Get rid of the extraneous padding on the right-hand side (let the layout routine compute minimum width instead) and I could certainly see the use in having left-justified text rotate about a pivot point on the right edge.
Anchor point in general doesn't seem very applicable to text inside table cells as the table is going to control the rotation.
@jffmarker thoughts on removing anchor point and inferring it from vertical/horizontal text alignment?
Outside the context of tables... what if you want a block of text to be left-justified, but positioned to the left side of an element; you'd want the anchor to be on the right, but justified to the left. How often will someone want this? I dunno... but that would be a reason to have an anchor concept distinct from justification. If you didn't have this concept, the user could place with a left anchor, and then snap to the right edge of the text box to position it if you didn't have this concept. From my Mstn days, the origin / insertion point / anchor point always had special meaning in terms of how to transform text or make it view independent, because it was the only point the user actually interactively placed and had control over. If text is now always in a shape (e.g. box), then the shape is what the user places, not the anchor point... so perhaps the concept is superseded. I guess in summary, distinct anchor gives the most flexibility... but at a complexity cost... given workarounds, perhaps it's not worth it.
The situation Jeff described. Seems reasonable to me.
Anchor point in general doesn't seem very applicable to text inside table cells as the table is going to control the rotation.
Anchor point + margins would be convenient for positioning text within a table cell. All I would need is to specify one of the nine locations around a table cell. That would be drop dead easy. That said, I can also query for the text width and height and then compute whatever origin is required by the API.
For the record, I don't persist the anchor point, it is computed on the fly.
- We should remove either TextBlock.justification or TextAnnotation.Anchor.horizontal. They are redundant
@Josh-Schifter have we come to a consensus that we don't want to do this?
- Add text frame shape to TextAnnotation2d.
I agree that having the frame be part of the annotation makes sense. I worry about the cmobinatorial explosion of all the different kinds of shapes people are going to want us to support (including custom shapes? stroked line styles? etc?)
We should remove either TextBlock.justification or TextAnnotation.Anchor.horizontal. They are redundant @Josh-Schifter have we come to a consensus that we don't want to do this?
Yes. When I made that suggestion I was overly focused on tables.
I agree that having the frame be part of the annotation makes sense. I worry about the cmobinatorial explosion of all the different kinds of shapes people are going to want us to support (including custom shapes? stroked line styles? etc?)
Our starting plan is to stick with a smallish set of pre-canned shapes (less than 10). We will vet these shapes with the domain PMs for our initial customers. I would like to defer any work on custom shapes just for practical reasons.
Alright, I've been working on issue #7677 and it has turned into adding frames as well as fill to text annotations. The idea is that frames will be used in combination with leader lines.
I have code that works, but the question is where to put it. So I wanted to open the floor to discussions on it. I have a couple proposals currently.
Proposal 1: Add methods to core/common geometry builders
- The
GeometryStreamBuilderandElementGeometry.Builderclasses have anappendTextBlockmethod already. - We could add a new
appendTextAnnotationmethod that calls:-
appendTextBlock: existing method, leave this unchanged -
appendLeaderLine: new method, could be called directly for stand alone leader lines -
appendFrame: new method, could be called directly for things like tables, etc.
-
- Would add the following files to common:
-
TextAnnotationGeometryProps -
FrameGeometryProps -
FrameGeometry -
LeaderLineGeometryProps -
LeaderLineGeometry
-
| Pros | Cons |
|---|---|
| Fits within existing infrastructure | Would add more clutter to the fundamental GeometryStreamBuilder and ElementGeometry.Builder classes |
| No new paradigms or patters | Could explode these basic classes with less generic code |
| Fairly straightforward |
Proposal 2: Add a new ‘stroker’ layer to core
- The purpose is to combine
TextLayoutResultwith graphics and reduce calls to the backend. Specifically reducing duplicate calls to:-
computeLayoutTextBlockResult -
produceTextAnnotationGeometry
-
- This is a layer that currently doesn’t exist in core. We would be introducing a new pattern.
- In common, we would add a new class:
TextAnnotationStroker - We would need two versions:
-
ElementGeometry.Builder: called from backend -
GeometryStream: called wherever
-
-
TextAnnotationElementandTextDecorationwould call this instead ofGeometryStreamBuilder - We would likely refactor or remove
appendTextBlockto require use of the new stroker - We will probably need to make similar files listed in Proposal 1 still.
| Pros | Cons |
|---|---|
Would keep GeometryStreamBuilder and ElementGeometry.Builder classes cleaner |
Introduces a new pattern |
| Adds more files and boilerplate code |
We could do both proposal 1 and 2. Eventually we might want to pull our deminsion code into core. Proposal 2 would be a gateway for adding the stroker pattern that our deminsions use to core.