Issue with field margins when building a custom control based on a scrolling list field.

Anything beyond the basics in using the LiveCode language. Share your handlers, functions and magic here.

Moderators: FourthWorld, heatherlaine, Klaus, kevinmiller, robinmiller

Simon Knight
Posts: 854
Joined: Wed Nov 04, 2009 11:41 am
Location: Gunthorpe, North Lincs, UK

Issue with field margins when building a custom control based on a scrolling list field.

Post by Simon Knight » Tue Aug 01, 2023 7:43 am

Recently I have had an interest in being able to edit the lines of a scrolling list field. This is not possible with the standard control and a number of methods have been proposed in the past and with a bit of digging may be found in these forum pages.

I decided to build a "simple" custom control that places a second editable single line field over the line in the parent list when its double clicked on. This should be fairly simple but I am making a hash of it as I can not work out how to accurately position the line editing field or how to set its properties so that it exactly overlays the line in the parent list.

The issue I am trying to understand is how the "margins" property works and interacts with the "effective textheight" which its self is changed by the text size property (4/3 scaling). The dictionary describes that the margins property may be set as either a single integer or as a list of four (left,top,right,bottom). While this is true it appears to me that the engine also creates different top margins for each row in a list field. I'm guessing that the value is related to the effective textheight and or the textsize properties. Does anyone reading know how these are calculated?

I am attaching my incomplete but mostly working custom list control stack. The control has not been grouped yet and works as presented. Unfortunately in order to place the yellow editing field exactly over the desired line in the list I have had to employ a kludge of 5 pixels when calculation the top property of the line and also its top text margin. I need to know how to reliably calculate this value e.g. textsize/6 ?
ScrollListField.livecode.zip
Zipped stack with part complete list control
(3.9 KiB) Downloaded 77 times
Unzip and play.
best wishes

Simon
best wishes
Skids

stam
Posts: 2776
Joined: Sun Jun 04, 2006 9:39 pm
Location: London, UK

Re: Issue with field margins when building a custom control based on a scrolling list field.

Post by stam » Tue Aug 01, 2023 8:55 am

Hi Simon
It’s not an answer to your question, but: why not just use a data grid which already has all this functionality built in? What you’re asking for is essentially inline editing of a row, which is part of the DG’s standard feature set

I realise there is a learning curve with the DG, but the rewards are great and even with newer controls, the DG still holds its own, so the learning curve is worth it.

And, at the end of the day, the effort is unlikely to be more than rolling your own, at least to get a professional looking end result…

I understand the need to use simpler tools and create your own, but I also strongly feel one should always strive to use the best tool for the job at hand… and inherently lazy so if I have access to a tool that will do the job well, I will usually avoid the extra effort to replicate this on my own ;)

Simon Knight
Posts: 854
Joined: Wed Nov 04, 2009 11:41 am
Location: Gunthorpe, North Lincs, UK

Re: Issue with field margins when building a custom control based on a scrolling list field.

Post by Simon Knight » Tue Aug 01, 2023 9:53 am

why not just use a data grid which already has all this functionality built in?
or the polygrid....

I suppose the simple answer is because I want to find out how they work and may be employed but in detail its complicated.

Trevore DeVore did an amazing job in creating the datagrid. However, because it was built to be a general purpose tool he was forced to add many features that deal with more edge conditions. The upshot is that a datagrid adds a lot of baggage if it is only being used in a simple way. They are difficult to copy and move between projects and require masses of documentation. I also find, and it may just but me, that they are very easy to break. Worse when broken, with often quite simple coding errors, it is common to find them and the IDE suffering from what I call a silent failure. A silent failure is where messages seem to get lost and where code errors are not posted in the IDE which just grinds to a halt or just puts up the spinning beachball. A Datagrid is "just" a custom control that was partially integrated into Runtime Revolution and is still with us.

So I have a rather love hate relationship with them.

I'm not sure why there is not more discussion about custom controls and techniques used in building them. In this example I read elsewhere about the method of doing the edit in an overlaid field so thought I would give it a try. Along the way I thought I would find out more about the "humble" field and expand my understanding. So far all I have managed is to realise that it is far more complex than it first looks and that some very pretty and useful controls may be created using it:
tablelab.livecode.zip
Scott Rossi's table lab
(7.9 KiB) Downloaded 74 times
and
striped_list_field 2.livecode.zip
Scott Rossi's striped list
(154.53 KiB) Downloaded 66 times
I could probably jaw on but shouldn't as the dog wants his walk.

Back later,
best wishes
Simon
best wishes
Skids

stam
Posts: 2776
Joined: Sun Jun 04, 2006 9:39 pm
Location: London, UK

Re: Issue with field margins when building a custom control based on a scrolling list field.

Post by stam » Tue Aug 01, 2023 10:34 am

Simon Knight wrote:
Tue Aug 01, 2023 9:53 am
or the polygrid....
I might be wrong but I don't think that either PolyGrid or PolyList have built in methods for inline editing, whereas the DataGrid does, hence my comment. It does this by doing what you're trying to do (create an adhoc field) but the heavy lifting is done for you (perhaps studying the datagrid code may help your efforts).

I guess it's down to what you're striving to do: Create an app or create a custom control for the sake of it...

My light experimentation in the area has shown me that while many more things are possible with the simple Field control than one would first imagine, it requires a lot of extra coding to bend it to your will and perform reliably, to the point where learning the DG is less effort.

I've certainly been very impressed with Bernd's and Scott's efforts modifying the tableField, but I've always found the DG performs better for me and easier to maintain apps with, easier to modify at a later date etc, so after toying with these solutions I've always gone back to using the DG.

What is certain however, is that with large data sets the humble tableField performs worse than any other list control.
For example, check out the speedTest.livecode stack in the examples > polygrid folder that comes with LiveCode_Enhancements if you've purchased: loading 10,000 lines takes just 9 ms in PG, 67 ms in DG but 197 ms in a simple edit field (not formatted as a table, just TSV text). What this tells me is that even if one would be able to make this into a perfect imitation of a datagrid, it still wouldn't be as performant - so why do this...?

I like PolyGrid and PolyList and do use these, but their feature sets are only a subset of what the DataGrid does even though they offer features DG doesn't, so I often use all of these... so far I haven't found a need to use a tableField...

And yeah on the face of it the DG is more complex than a simple tableField, but is it really that much more complex than a heavily modified tableField?

Simon Knight
Posts: 854
Joined: Wed Nov 04, 2009 11:41 am
Location: Gunthorpe, North Lincs, UK

Re: Issue with field margins when building a custom control based on a scrolling list field.

Post by Simon Knight » Tue Aug 01, 2023 11:15 am

I agree that a datagrid is the way to go when displaying large data sets but when only a short list is required then I am happy to play. For example it struck while I was in discussions with the dog that my code could be placed in a behavior button which could be used by multiple short lists all using the one edit field. I just need to work out what happens with the line margins. the advantage with this approach is that its uses thirty odd lines of active code.

I suppose I could open up a datagrid and or Bernd's modtablefield to see how they calculate the position their respective fieldeditors.

S
best wishes
Skids

bn
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 4036
Joined: Sun Jan 07, 2007 9:12 pm
Location: Bochum, Germany

Re: Issue with field margins when building a custom control based on a scrolling list field.

Post by bn » Tue Aug 01, 2023 12:28 pm

Simon,

I "hacked" your first stack and it seems to behave...

Have a look at the code. I also prepared it for vScrolling in case it gets too tall.

Kind regards
Bernd
Attachments
ListFieldDemonstration_Modified.livecode.zip
(4.94 KiB) Downloaded 73 times

dunbarx
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 9785
Joined: Wed May 06, 2009 2:28 pm
Location: New York, NY

Re: Issue with field margins when building a custom control based on a scrolling list field.

Post by dunbarx » Tue Aug 01, 2023 2:24 pm

Simon.

The extra field you use seems to work just fine for me. It aligns properly, and any edits I make in it are "loaded" into the underlying line perfectly. If I double-click on an empty line below, again, it all works just fine.

Please say again what is wrong with this.

Craig

Simon Knight
Posts: 854
Joined: Wed Nov 04, 2009 11:41 am
Location: Gunthorpe, North Lincs, UK

Re: Issue with field margins when building a custom control based on a scrolling list field.

Post by Simon Knight » Wed Aug 02, 2023 8:04 am

Craig,
The issue with my code is that I have had to manually discover that I need to add 5 pixels to the vertical location of my edit field:

Code: Select all

######### KLUDGE ######### 
   
   put 5 into tKludge
   
   ######### KLUDGE #########
   
   //Calculate the top posn of the line
   put tTopOfLines + (tLineNo*tCellHt) + tKludge into tLineTop
If the borderwidth is changed my list field editor will be revealed in the wrong position and it is likely that the identification of the line clicked will be wrong depending on where vertically in the line the click is made and how different the border size is from the one I initially set.

So, in short, I have created a one off control but not a general purpose one.

Simon
Attachments
Screenshot 2023-08-02 at 06.47.59.png
Object inspector - text
Screenshot 2023-08-02 at 06.47.59.png (19.96 KiB) Viewed 6772 times
best wishes
Skids

Simon Knight
Posts: 854
Joined: Wed Nov 04, 2009 11:41 am
Location: Gunthorpe, North Lincs, UK

Re: Issue with field margins when building a custom control based on a scrolling list field.

Post by Simon Knight » Wed Aug 02, 2023 8:05 am

Ooops please ignore the screenshot above.
best wishes
Skids

Simon Knight
Posts: 854
Joined: Wed Nov 04, 2009 11:41 am
Location: Gunthorpe, North Lincs, UK

Re: Issue with field margins when building a custom control based on a scrolling list field.

Post by Simon Knight » Wed Aug 02, 2023 9:02 am

Bernd,

Genius, thank you!

The calculation of the vertical position of the top line is far more complex than I imagined and would have taken me days if not weeks to edge towards which rather confirms Stam's point made above : use a datagrid !

For those who have not yet looked at Bernd's code corrections here is the crucial new handler :

Code: Select all

function getTopOfFirstLine
  -----
  local tKorr,tTopOfFirstLine
  local tTextSize,tRegularTextHeight,tDiff
  -----

   -- now calculate the position of the first base line of the first line of the field. = first horizontal divider from top
   put the effective textSize of me into tTextSize
   -- find out difference between automatic textheight and manually set textHeight
   -- formula according to documentation
   put trunc(4/3*tTextSize) into tRegularTextHeight
   put the effective textHeight of me - tRegularTextHeight into tDiff

   -- the height of first line is not the textHeight but changes according to the font size/topMargin, borderwidth
   -- formula found by experimentation
   put round (((tTextSize - 22) * 1/3)) into tKorr

   put max ((the top of me  + the effective textSize of me + the borderWidth of me  \
               + the topMargin of me + tKorr + tDiff ) - (the effective textHeight of me), the top of me) into tTopOfFirstLine
   return tTopOfFirstLine
end getTopOfFirstLine
I have experimented and have been unable to create a situation where tDiff is not zero but I guess there must be a case where it goes non zero.

I very much doubt I would have ever derived tKorr or the calculation of tTopOfFirstLine : its such a pity that this is not documented in formal documentation.

Thanks again,

Simon
best wishes
Skids

bn
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 4036
Joined: Sun Jan 07, 2007 9:12 pm
Location: Bochum, Germany

Re: Issue with field margins when building a custom control based on a scrolling list field.

Post by bn » Wed Aug 02, 2023 9:41 am

Simon,

thank you. I remember when I did "getTopOfFirstLine" that it took me a _lot_ of head scratching...

I found one flaw: when clicking above the first line it currently can position the Editor field above the first line.

This avoids it in handler mouseDoubleDoown add the conditional.

Code: Select all

   put getTopOfFirstLine() into tTopOfLines -- New
   
   put item 2 of (the mouseloc) into tMouseYcoOrd
   if tMouseYcoOrd < tTopOfLines then -- if click is above first line exit
      exit mouseDoubleDown
   end if
Kind regards
Bernd

Simon Knight
Posts: 854
Joined: Wed Nov 04, 2009 11:41 am
Location: Gunthorpe, North Lincs, UK

Re: Issue with field margins when building a custom control based on a scrolling list field.

Post by Simon Knight » Wed Aug 02, 2023 12:44 pm

Bernd,

I had not seen that problem. I notice that a error creeps in when the border size is less than 5 but its not a great issue, but I will try and work out what is going on.

Simon
best wishes
Skids

bn
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 4036
Joined: Sun Jan 07, 2007 9:12 pm
Location: Bochum, Germany

Re: Issue with field margins when building a custom control based on a scrolling list field.

Post by bn » Wed Aug 02, 2023 2:06 pm

Simon Knight wrote:
Wed Aug 02, 2023 12:44 pm
Bernd,
I notice that a error creeps in when the border size is less than 5 but its not a great issue, but I will try and work out what is going on.
Try this:

Code: Select all

function getTopOfFirstLine
   -----
   local tKorr,tTopOfFirstLine
   local tTextSize,tRegularTextHeight,tDiff, tEdge
   -----
   
   -- now calculate the position of the first base line of the first line of the field. = first horizontal divider from top
   put the effective textSize of me into tTextSize
   -- find out difference between automatic textheight and manually set textHeight
   -- formula according to documentation
   put trunc(4/3*tTextSize) into tRegularTextHeight
   put the effective textHeight of me - tRegularTextHeight into tDiff
   
   -- the height of first line is not the textHeight but changes according to the font size/topMargin, borderwidth
   -- formula found by experimentation
   put round (((tTextSize - 22) * 1/3)) into tKorr
   
   put max ((the top of me  + the effective textSize of me + the borderWidth of me  \
         + the topMargin of me + tKorr + tDiff ) - (the effective textHeight of me), the top of me) into tTopOfFirstLine
   
   -- an edge case: if the sum of topMargin and borderwidth is below 7 then it needs a negative offset.
   -- e.g. borderwidth 0 and topMargin 6
   -- added using LC 9.6.9, tested back to LC 8.1.3
   put the topMargin of me + the borderWidth of me into tEdge
   if tEdge < 7 then
      add (tEdge - 7) to tTopOfFirstLine
   end if
   
   return tTopOfFirstLine
end getTopOfFirstLine
I only noticed this today after going through all settings again down to 0 for BorderWidth and topMargin.
(see edge case)

Kind regard
Bernd

Simon Knight
Posts: 854
Joined: Wed Nov 04, 2009 11:41 am
Location: Gunthorpe, North Lincs, UK

Re: Issue with field margins when building a custom control based on a scrolling list field.

Post by Simon Knight » Wed Aug 02, 2023 4:44 pm

Bernd,

How do you do it? I've been trying to use the mouseloc to work out where the top of a row starts in an attempt to work out how the low values of border and width interact but at small text/border/margin sizes I'm struggling to position the mouse accurately.

Your new code works on version 10 dp4.

I have just seen this in the dictionary
If the object's showBorder property is false, the borderWidth property has no effect.
I don't think it is correct at least on version 10 .

Here are two screen shots of the test stack. I have view invisible items switched on to always show the location of the LineEditor field. In the first shot the line editor is over the first row in the list and the list has a border of zero.
Screenshot 2023-08-02 at 16.39.10.png
BorderWidth set to zero
In the second shot the border width has been changed to 30.
Screenshot 2023-08-02 at 16.36.10.png
BorderWidth set to 30.
Screenshot 2023-08-02 at 16.36.10.png (8.97 KiB) Viewed 6692 times
In both shots the showBorder is off.
Screenshot 2023-08-02 at 16.41.13.png
ShowBorder is false.
Just wondering if I should post a documentation bug report.
Simon
best wishes
Skids

Simon Knight
Posts: 854
Joined: Wed Nov 04, 2009 11:41 am
Location: Gunthorpe, North Lincs, UK

Re: Issue with field margins when building a custom control based on a scrolling list field.

Post by Simon Knight » Wed Aug 02, 2023 5:08 pm

Ooops - I managed to mix up the two screen shots sorry,

I have just noticed this happens if border and margins are both set to zero (text is 11) :
Screenshot 2023-08-02 at 16.48.45.png
Partially missing first line
Screenshot 2023-08-02 at 16.48.45.png (6.36 KiB) Viewed 6688 times
What logic is being employed and why?

Also just found this command :

Code: Select all

function getTopOfFirstLine
   return item 2 of the formattedRect of Line 1 of field "MyNewList"
end getTopOfFirstLine
S
best wishes
Skids

Post Reply

Return to “Talking LiveCode”