Multi-line cells in lists: showVerticalTabs property?

Moderators: FourthWorld, heatherlaine, Klaus, kevinmiller, LCMark

FourthWorld
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 9824
Joined: Sat Apr 08, 2006 7:05 am
Location: Los Angeles
Contact:

Multi-line cells in lists: showVerticalTabs property?

Post by FourthWorld » Mon Aug 12, 2013 3:48 pm

The new field object is very close to what I need in terms of multiple apparent lines per paragraph, with two exceptions.
Currently, if one includes vertical tabs in a line "(VT", 0x11), in some circumstances they will be rendered as new lines.

The docs say this is governed by the dontWrap property: when true VTs are rendered as before as just non-printable characters, but when false they're rendered as new lines.

This is a good start, but making this rendering dependent on dontWrap has two limitations:

1. It requires us to set the dontWrap to true on any field where we want rendering to appear consistent with all earlier versions of LC, and indeed all earlier xTalks. The Message Box, for example, doesn't have its dontWrap set so there's no way to see the data as as it used to be rendered, with VTs and CRs being visually indistinguishable.

2. It prevents us from having HTML-style lists, in which a given cell may contain more than one line, e.g.:

Code: Select all

   -----------------------------
   r1item1 | r1item2a | r1item3
           | r1item2b |
           | r2item2c |
   -----------------------------
   r2item1 | r2item2a | r2item3
           | r2item2b |
   -----------------------------
   r3item1 | r3item2a | r3item3
   -----------------------------
   r4item1 | r4item2a | r4item3
           | r4item2b |
   -----------------------------
How difficult would it be to add a showVerticalTabs property for fields (maybe with a synonym of showVTs)?

Perhaps this could be implemented such that its default would follow the current convention; that is, when dontWrap is set, the showVTs gets set to reflect what we currently have.

But by making this an independent setting we would then have the freedom to turn off the rendering of VTs as new lines in normal fields, and gain the ability to have multi-line cells in list fields.

The latter is something I sorely need very soon, so I would very much appreciate any input from those of you familiar with the engine in a position to advice on this feasibility.
Richard Gaskin
LiveCode development, training, and consulting services: Fourth World Systems
LiveCode Group on Facebook
LiveCode Group on LinkedIn

monte
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 1564
Joined: Fri Jan 13, 2012 1:47 am
Contact:

Re: Multi-line cells in lists: showVerticalTabs property?

Post by monte » Mon Aug 12, 2013 11:28 pm

Wouldn't you want dontWrap on a list field?
LiveCode User Group on Facebook : http://FaceBook.com/groups/LiveCodeUsers/

FourthWorld
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 9824
Joined: Sat Apr 08, 2006 7:05 am
Location: Los Angeles
Contact:

Re: Multi-line cells in lists: showVerticalTabs property?

Post by FourthWorld » Mon Aug 12, 2013 11:34 pm

monte wrote:Wouldn't you want dontWrap on a list field?
Yep, which is why the current implementation won't provide us with multi-line cells. Right now, turning on dontWrap turns off the rendering of VTs as line ending.

I feel we're quite close on this to something akin to the HTML-style lists people have been clamoring for, but just one step short of actually having them.
Richard Gaskin
LiveCode development, training, and consulting services: Fourth World Systems
LiveCode Group on Facebook
LiveCode Group on LinkedIn

monte
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 1564
Joined: Fri Jan 13, 2012 1:47 am
Contact:

Re: Multi-line cells in lists: showVerticalTabs property?

Post by monte » Tue Aug 13, 2013 12:43 am

OK, must have misread what you were saying and reversed it ;-)

Just at first glance the text rendering stuff looks a little too complicated for me to do for fun unless @runrevmark can give me some clues where to start looking for this.
LiveCode User Group on Facebook : http://FaceBook.com/groups/LiveCodeUsers/

FourthWorld
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 9824
Joined: Sat Apr 08, 2006 7:05 am
Location: Los Angeles
Contact:

Re: Multi-line cells in lists: showVerticalTabs property?

Post by FourthWorld » Tue Aug 13, 2013 1:26 am

Thanks for taking a look at it. Hopefully Mark will be able to offer some guidance on this.
Richard Gaskin
LiveCode development, training, and consulting services: Fourth World Systems
LiveCode Group on Facebook
LiveCode Group on LinkedIn

monte
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 1564
Joined: Fri Jan 13, 2012 1:47 am
Contact:

Re: Multi-line cells in lists: showVerticalTabs property?

Post by monte » Tue Aug 13, 2013 3:42 am

I spent a more minutes with the engine over lunch and I think what you want is somewhere between MCParagraph::flow and MCParagraph::noflow. Each MCParagraph has a linked list of MCLines. Not lines as we would think of them but visible lines of text I think. noflow is called when dontWrap is true and it reduces the linked list down to one node. So what I think you want is for noflow to optionally only remove MCLines that are the result of wrapping and not remove those that are the result of vertical tab... however, there's something called an MCBlock that's involved and I'm not sure how yet.
LiveCode User Group on Facebook : http://FaceBook.com/groups/LiveCodeUsers/

FourthWorld
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 9824
Joined: Sat Apr 08, 2006 7:05 am
Location: Los Angeles
Contact:

Re: Multi-line cells in lists: showVerticalTabs property?

Post by FourthWorld » Tue Aug 13, 2013 3:48 am

Monte, I really appreciate your taking the time to explore this. I realize you may or may not be able to do this,but it's comforting to see that the goal seems as interesting to you as it does to me.
Richard Gaskin
LiveCode development, training, and consulting services: Fourth World Systems
LiveCode Group on Facebook
LiveCode Group on LinkedIn

monte
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 1564
Joined: Fri Jan 13, 2012 1:47 am
Contact:

Re: Multi-line cells in lists: showVerticalTabs property?

Post by monte » Tue Aug 13, 2013 4:13 am

I realize you may or may not be able to do this
A challenge! Now I have to do it ;-)
LiveCode User Group on Facebook : http://FaceBook.com/groups/LiveCodeUsers/

FourthWorld
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 9824
Joined: Sat Apr 08, 2006 7:05 am
Location: Los Angeles
Contact:

Re: Multi-line cells in lists: showVerticalTabs property?

Post by FourthWorld » Tue Aug 13, 2013 5:02 am

monte wrote:
I realize you may or may not be able to do this
A challenge! Now I have to do it ;-)
I didn't mean it as a challenge (though happy if it motivates!); I was merely respecting your time.

If you pull this off I owe you dinner in San Diego next September.
Richard Gaskin
LiveCode development, training, and consulting services: Fourth World Systems
LiveCode Group on Facebook
LiveCode Group on LinkedIn

monte
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 1564
Joined: Fri Jan 13, 2012 1:47 am
Contact:

Re: Multi-line cells in lists: showVerticalTabs property?

Post by monte » Tue Aug 13, 2013 5:19 am

I know mate... dinner sounds good! I can spend it trying to convince you to move to Tasmania instead of New Zealand ;-)

Still tossing up San Diego but it's highly likely I'll be there.
LiveCode User Group on Facebook : http://FaceBook.com/groups/LiveCodeUsers/

monte
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 1564
Joined: Fri Jan 13, 2012 1:47 am
Contact:

Re: Multi-line cells in lists: showVerticalTabs property?

Post by monte » Tue Aug 13, 2013 8:40 am

After examining the code a little while longer I found a couple of interesting things:
- the engine stops you from having wrapping on list fields for no apparent reason. I turned this off and it seems the list field still works with wrapped lines...
- setting vGrid to true stops you from having wrapping

What I'm thinking here is dontWrap false on tables should permit wrapping in cells. My initial experiments (consisting of commenting out 4 lines of code) indicate that the idea has promise. The main issues I see are:
- the vertical tab char is drawn as well as causing a break
- text longer than the tabstop doesn't seem to wrap just yet which would be nice too
- the line break breaks the whole line rather than just the line in the cell:

Code: Select all

set the text of fld 1 to "hello"&numToChar(11)&"world"&tab&"something"&numToChar(11)&"else"

------------------------------------------
| hello            |                     |
| world            | something           |
| else             |                     |
------------------------------------------
I'm not actually positive that we can resolve this easily without making each cell an independent paragraph. Perhaps @runrevmark has thoughts on that?

The original problem mentioned lists though so I wonder if you might be satisfied by the following which seems to work fine (until you turn on vGrid) with my changes:

Code: Select all

set the text of fld 2 to "hello"&tab&"world"&numToChar(11)&tab&"else"&cr&"new line"

------------------------------------------
| hello            | world               |
|                  | else                |
------------------------------------------
| new line         |                     |
------------------------------------------
LiveCode User Group on Facebook : http://FaceBook.com/groups/LiveCodeUsers/

LCMark
Livecode Staff Member
Livecode Staff Member
Posts: 1208
Joined: Thu Apr 11, 2013 11:27 am

Re: Multi-line cells in lists: showVerticalTabs property?

Post by LCMark » Tue Aug 13, 2013 1:01 pm

Okay so I think there are several things here...

The easiest to deal with is the situation with listBehavior and dontWrap - the fact that listBehavior true iff dontWrap is true is very much legacy from before 5.5. Prior to 5.5 there were various 'optimizations' in place to deal with dontWrap at the MCField level, these were removed when dontWrap became a paragraph property because they no longer made any sense (nor were they making any difference to performance before then). Thus, I can't see an issue with making it so that whilst setting listBehavior true should set dontWrap true (for backwards compatibility), you should be able to turn dontWrap off even if listBehavior is already true (i.e. remove the code in the P_DONT_WRAP setprop in MCField). [ Indeed, you can essentially turn off dontWrap for a list field at the moment - by setting dontWrap false for each paragraph - thus the current forcing of dontWrap to true when setting listBehavior true doesn't make sense any more ].

In regards to the relatively recent processing of VT, I must confess I hadn't considered backward compatibility problems that this might have introduced. So it would be good to know a bit more details as to the problems this change has introduced and whether a compatibility flag is actually required here, or whether it would be better to introduce a field property like 'showNonPrintingChars' (which would render the appropriate symbols for paragraph separators, line separators and tabs, whilst keeping the behavior the control characters intact). This would certainly serve the data display aspect perhaps better than the old behavior (as it would be consistent across platforms, and not be a side-effect of whether the font had the given characters at the correct code points).

In terms of dontWrap turning off VT processing then the current behavior is mainly a side-effect of the architecture of the field - I considered VT to be equivalent to wrapping (it is processed in MCParagraph::flow() and callees which is where word-breaking is done) but this is perhaps not quite correct. So, what situations would you not want VTs to act as explicit line breaks - are there any real-world use-cases?

Putting my 'keeping an eye to the future' hat on and generalizing, I guess what I'm asking is that should line breaking and word wrapping be treated separately, or should they be considered the same thing. Indeed, thinking about the processes you go through when laying out text, in full generality various choices come into play at several points (pretty much none of which you have control over at the moment):
  1. Text is broken into lines by explicit line breaks to generate explicitly broken lines (explicit breaking)
  2. The explicitly broken lines are then wrapped by adding implicit line breaks to generate implicitly broken lines (implicit breaking)
  3. If any implicitly broken lines do not fit in the available space then they are processed again to find a break point within them (fallback implicit breaking)
  4. The fully broken lines are then fit to the available space (fitting)
  5. The fully broken lines are then finally aligned to the available space (alignment)
At point (1), there is only a boolean option - whether to ignore explicit line breaks or not (perhaps a ignoreExplicitBreaks property).
At point (2), there are the following potential options (perhaps a wrapMode property):
  1. none - no implicit breaks (this is dontWrap = true)
  2. char - break at characters
  3. hypen - break at hypenation points
  4. word - break at words (this is dontWrap = false)
At point (3), we are left with lines that are still too long to fit so they can potentially be wrapped again to make them fit with the same options as above (perhaps a fallbackWrapMode property). [ So, for example if the wrapMode were word, and the fallbackWrapMode were char for a word that was too long to fit on a single line, it would be wrapped by adding an implicit break at the appropriate char to make sure it fits - this is the behavior of most word-processors, and the current field behavior is wrapMode = "word", fallbackWrapMode = "none" ].
At point (4), we are left to what to do with overlong lines that cannot be divided by any further (perhaps a fitMode property):
  1. scroll - the width of the line is the full width of the contents
  2. clip - the width of the line is the width of the container, and the line is clipped when drawn
  3. front - keep the front of the text, and replace as much of the back as needed with an ellipsis and clip to the width of the container
  4. middle - keep as much of the front and back of the text as possible and replace the middle with an ellipsis and clip to the width of the container
  5. back - keep the back of the text, and replace as much of the front as needed with an ellipsis and clip to the with of the container
At point (5), we are using the 'textAlign' property to position the resulting fragment appropriately relative to the layout width. (Here 'scroll' is essentially the current behavior which I think is actually not very useful as it interacts badly with alignment - you can see this if you have overly long lines in a paragraph what has right or center alignment set - a little more thought is perhaps needed there).

For a point of reference, the choices you are stuck with in the current field are either:
  • dontWrap == true - ignoreExplicitBreaks is true, wrapMode is none, fallbackWrapMode is none, fitMode is scroll
  • dontWrap == false - ignoreExplicitBreaks is false, wrapMode is word, fallbackWrapMode is none, fitMode is scroll
Okay, so after all that, certainly adding something like an 'ignoreExplicitBreaks' property (at the field and paragraph level) which is independent of dontWrap would fit into the layout process quite logically and succintly without any unpleasant interactions.

So, going back to the implementation aspect of things. Enabling explicit break processing in non-vGrid mode is simple as I think Monte has discovered - 'noflow()' is only called if dontWrap is true and ignoreExplicitBreaks is true, flow() is called in all other cases but if dontWrap is true, then word-wrapping should not take place.

Getting it to work *correctly* in vGrid mode is substantially more difficult. As it turns out I was looking at the nightmare that is the MCLine/MCParagraph interaction the other day when fixing a couple of bugs (and optimizing word wrapping - which is now about twice as fast as it was before). Really the data structure that is MCLine is wrong for what we want to do here. At the moment an MCLine is a linked list of MCBlocks which represent the beginning and end of that implicitly broken line and in order to form this list it has to break the blocks at the implicit break points (which is not only ugly but also really quite inefficient); furthermore doing things like this means that it is not possible for lines to represent text that is out of the order that it is in the field. The latter is essentially what is required in order to do cell layout with wrapping (and explicit breaking) *and* handle right to left text. On top of this, the handling of tabs is essentially being done in entirely the wrong place for table rendering - it is currently done at the block level, whereas that should already have been shaken out in the layout process when generating MCLines. My thinking on the topic had got as far as deciding that MCLine should be a list of cells, which each cell a list of lines, and each line a list of ranges of text that index into the paragraph - but as yet I've not looked at how that impacts rendering, measuring and layout...

monte
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 1564
Joined: Fri Jan 13, 2012 1:47 am
Contact:

Re: Multi-line cells in lists: showVerticalTabs property?

Post by monte » Tue Aug 13, 2013 9:44 pm

OK, So the main question I have is do you need vGrid @FourthWorld? If not then I should be able to send a pull request relatively quickly. Everything beyond @runrevmark's point 1 appears to be significant refactoring though.
LiveCode User Group on Facebook : http://FaceBook.com/groups/LiveCodeUsers/

FourthWorld
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 9824
Joined: Sat Apr 08, 2006 7:05 am
Location: Los Angeles
Contact:

Re: Multi-line cells in lists: showVerticalTabs property?

Post by FourthWorld » Wed Aug 14, 2013 1:53 am

monte wrote:OK, So the main question I have is do you need vGrid @FourthWorld? If not then I should be able to send a pull request relatively quickly. Everything beyond @runrevmark's point 1 appears to be significant refactoring though.
I 'm glad you're confident about it. I'm still digesting the implications of Mark's post. :)

In brief, to get a multi-line table I need some way to align the columns, and currently that's handled by the vGrid. If there's some other way to do it I''m not picky, I use what I can.

Did I understand your question correctly?

@RunRevMark: Thanks for taking the time to explore this.
Richard Gaskin
LiveCode development, training, and consulting services: Fourth World Systems
LiveCode Group on Facebook
LiveCode Group on LinkedIn

monte
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 1564
Joined: Fri Jan 13, 2012 1:47 am
Contact:

Re: Multi-line cells in lists: showVerticalTabs property?

Post by monte » Wed Aug 14, 2013 4:07 am

FourthWorld wrote:I 'm glad you're confident about it. I'm still digesting the implications of Mark's post. :)
He certainly put some reading material out yesterday ;-)
FourthWorld wrote:In brief, to get a multi-line table I need some way to align the columns, and currently that's handled by the vGrid. If there's some other way to do it I''m not picky, I use what I can.
Well without vGrid you would need to ensure all your data fit within the tabstops to make sure it stayed aligned. If you did that you could I think use hGrid and draw two vertical line graphics for vGrid look.
FourthWorld wrote:Did I understand your question correctly?
I think so
LiveCode User Group on Facebook : http://FaceBook.com/groups/LiveCodeUsers/

Locked

Return to “Engine Contributors”