Text list ‘cellrectangle’ oddity

This is weird.

I wrote a procedure to trap a mouse click on a text list object, check if it an option-click and, if so, create a temporary text editor object on top of the clicked cell to allow it to be edited in place:

fileglobal CellRectangle
let ClickPosition=info("click")
let X=info("matrixcolumn")
let Y=info("matrixrow")
if optionclick()
        objectaction "ThisList","CellRectangle",Y,X,CellRectangle
        CellRectangle=rectangleadjust(xytoxy(CellRectangle,"w","f"),-2,-5,2,5)
        newformobject "RectangleShapeObject",
            "color",htmlrgb("ffeeaa"),
            "rectangle",CellRectangle
        newformobject "TextEditorObject",
            "$BorderBottomMargin","2 px",
            "$BorderTopMargin","2 px",
            "$TextEditorBorderStyle","Bezel",
            "$TextEditorDontWrap","1",
            "$TextEditorFocusRing","0",
            "$TextEditorTerminateReturn","1",
            "$TextEditorTerminateTab","1",
            "$TextEditorTerminateUpDown","1",
            "$TextEditorTriggerFinished","1",
            "$TextEditorUpdateVariableEveryKey","1",
            "FieldName","ThisTrackTitle",
            "Procedure","call TrackEditingDone",
            "rectangle",CellRectangle
// (etc.)

(call TrackEditingDone later deletes the text editor object as soon as editing is terminated, and writes the variable to the database cell.)

This all worked perfectly — until I tried it with a long scrolling text list. It still works fine near the top of the list, but as soon as it’s scrolled, option-clicking on a cell no longer caused the text editor object to appear.

Investigating further, it appears that once the text list is scrolled, the cell rectangle returned by the objectaction statement has negative co-ordinates.

The cell rectangle is returned in window-relative co-ordinates and the mouse click in screen-relative co-ordinates, but when I insert this line after the objectaction command to compare the two in the same co-ordinate system:

message "CellRectangle (window to screen):"+¶+"Top: "+rtop(xytoxy(CellRectangle,"w","s"))+¶+"Bottom: "+rbottom(xytoxy(CellRectangle,"w","s"))+¶+¶+"Mouse (screen): y="+v(ClickPosition)

if I click on one of the first few rows in the text list when it’s not scrolled I get this credible result, showing that the mouse click lay between the top and bottom of the reported co-ordinates of the 22px-high cell (the row height for my text list):

but if I scroll the list down to the middle and click on, for instance, the 70th cell out of 300, this is the result:

So (a) it is no longer correctly reported as a 22px-high rectangle (top and bottom y-co-ordinates are equal) and (b) the y-co-ordinates are negative — thus my text editor object was created off-screen.

Has anyone else noticed this?

(Panorama X 10.2.0.b33 (4268), macOS 13.4.1, M1 Max)

Further to the above:

It’s not just the top and bottom y-co-ordinates returned by objectaction object,"cellrectangle" that are invalid, but also left and right x-co-ordinates too (at least sometimes.)

However, objectaction object,"columnrectangle" always seems to return the correct left and right x-co-ordinates of the column containing a text list cell, even when it is scrolled, although the top and bottom y-co-ordinates of the column will be invalid in that case. And objectaction object,"rowrectangle" always seems to return the correct top and bottom y-co-ordinates of the row containing the cell, although the left and right x-co-ordinates of the row will be invalid if the list is scrolled.

Had columnrectangle and rowrectangle returned a rectangle with four correct co-ordinates in each case, the rectangle for the cell could have been found using:

local RowRectangle,ColumnRectangle,CellRectangle
objectaction parameter(1),"rowrectangle",info("matrixrow"),RowRectangle
objectaction parameter(1),"columnrectangle",info("matrixcolumn"),ColumnRectangle
CellRectangle=intersectionrectangle(RowRectangle,ColumnRectangle)

Since only half the co-ordinates of each are valid, the necessary fix is:

local RowRectangle,ColumnRectangle,CellRectangle
objectaction parameter(1),"rowrectangle",info("matrixrow"),RowRectangle
objectaction parameter(1),"columnrectangle",info("matrixcolumn"),ColumnRectangle
CellRectangle=rectangle(
    rtop(RowRectangle),
    rleft(ColumnRectangle),
    rbottom(RowRectangle),
    rright(ColumnRectangle)
)

which is not as quick or elegant as:

local CellRectangle
objectaction parameter(1),"cellrectangle",info("matrixrow"),info("matrixcolumn"),CellRectangle

but at least it works.

Note that, for an arbitrary row and column the rectangle returned might be wholly or partially outside the current viewport of the text list, depending where it is scrolled, but will be correct in relation to those cells which are visible. However, by definition info("matrixrow") and info("matrixcolumn") refer to cells clicked on, and therefore visible within, the current text list viewport, and a click on a partially visible row at the top or bottom of the viewport causes the list to be scrolled to show the whole row. However, in cases where the list may also scroll horizontally, a click on a cell in a partially visible column doesn’t correspondingly cause the list to scroll horizontally to make the whole column visible — that one column might, after all, be wider than the text list object or even the window containing it. Therefore the cell rectangle returned by the fix above should have top and bottom y-co-ordinates wholly within the visible viewport of the text list, but left and/or right x-co-ordinates might not be. This is analogous to the behaviour of the data sheet, in which double-clicking a partially visible cell to edit it results in a text editor object extending left or right beyond the data sheet window.