[REQ] Control selection during browse mode
Moderators: FourthWorld, heatherlaine, Klaus, kevinmiller, robinmiller
Re: [REQ] Control selection during browse mode
Emily.
I uploaded the wrong version of the stack.
This one supports both the upperLeft and lowerRight corners. Can you add the other two?
Craig
I uploaded the wrong version of the stack.
This one supports both the upperLeft and lowerRight corners. Can you add the other two?
Craig
Re: [REQ] Control selection during browse mode
How would the app know which control to rename or edit without selecting it first? The selection handles also provide feedback for the user.
I suspect Emily isn't a beginner and just needs some general direction. I recall some pretty sophisticated answers in previous topics.
Jacqueline Landman Gay | jacque at hyperactivesw dot com
HyperActive Software | http://www.hyperactivesw.com
HyperActive Software | http://www.hyperactivesw.com
Re: [REQ] Control selection during browse mode
Jacque.
Emily wants only the browse tool.
If you select a control under script, er, control, the handles that appear do not allow the browse tool any interaction at all. The control is indeed selected, but not modifiable.
You may make a point that without selecting, the user only knows which control is in play by virtue of the proximity of the cursor. That is something that may well need to be addressed. Emily?
I do not know what experience Emily has. But with LC I believe she is a newbie.
Emily?
Craig
Emily wants only the browse tool.
If you select a control under script, er, control, the handles that appear do not allow the browse tool any interaction at all. The control is indeed selected, but not modifiable.
You may make a point that without selecting, the user only knows which control is in play by virtue of the proximity of the cursor. That is something that may well need to be addressed. Emily?
I do not know what experience Emily has. But with LC I believe she is a newbie.
Emily?
Craig
-
- VIP Livecode Opensource Backer
- Posts: 10043
- Joined: Sat Apr 08, 2006 7:05 am
- Contact:
Re: [REQ] Control selection during browse mode
What she wants is to make a custom layout environment.
What she needs is two tool modes, Browse and Pointer, available at the same time depending on mouse location. If you've read her posts in the past, she's quite facile and very experienced in other languages and development in general. Given her demonstrated experience I feel confident that her priority here is more about finding an efficient solution than any personal preference for how to go about getting it.
With LC's limitation of having the tool property be only global (as opposed to assignable by group; see BZ#234), this requires us to decide whether we want the global property to be Browse with custom handling to allow Pointer behavior, or the other way around.
In my discussions on this with Dr Raney in '99 (I had freshly moved from SuperCard, where I made a LOT of custom layout environments, including an updated SampleDraw app they included in the package, like MacDraw but with more features), I had requested how Emily-Elizabeth initially conceptualized this: the global tool is Browse, with Pointer behavior somehow affecting only the drawing region.
What we got instead was the opposite, where we can use Pointer as the global tool mode, with any regions (groups or discrete controls) we like specifiable as delivering Browse tool behavior, by setting the cantSelect for those Browse regions to true.
While this is a bit less intuitive and much less convenient, I trust Dr Raney had good reason for making this implementation choice (sometimes what the engine needs to do to keep track of messaging is more complex than we want to know).
Regardless how it was arrived at, it is the solution the engine provides for mixing Browse and Pointer tool modes within a given window, and as such has been the recommended solution for most UIs of this type since it was introduced so long ago.
Richard Gaskin
LiveCode development, training, and consulting services: Fourth World Systems
LiveCode Group on Facebook
LiveCode Group on LinkedIn
LiveCode development, training, and consulting services: Fourth World Systems
LiveCode Group on Facebook
LiveCode Group on LinkedIn
Re: [REQ] Control selection during browse mode
@Richard, Jacque.
So I did a little research into Emily's posts here, and though having only 30, she does indeed seem to know a bit about LC. Further, the topics she is involved in are hardly beginners ones.
@Emily.
I owe you yet another apology.
That said, since the issues we are having here are UI issues, as opposed to strictly LC issues, where do we stand with getting this built and not breaking every protocol in the Apple HIG?
Craig
So I did a little research into Emily's posts here, and though having only 30, she does indeed seem to know a bit about LC. Further, the topics she is involved in are hardly beginners ones.
@Emily.
I owe you yet another apology.
That said, since the issues we are having here are UI issues, as opposed to strictly LC issues, where do we stand with getting this built and not breaking every protocol in the Apple HIG?

Craig
Re: [REQ] Control selection during browse mode
Richard.
Whether that is grown-up behavior is another story. But that sort of thing suits me just fine.
Craig
I think, assuming the scope does not increase dramatically, that all can be done with the browse tool. A simple click can bring up a dialog to change the text of the target, dragging near a corner can nicely resize, and clicking and dragging can set the loc.What she needs is two tool modes, Browse and Pointer, available at the same time depending on mouse location
Whether that is grown-up behavior is another story. But that sort of thing suits me just fine.
Craig
Re: [REQ] Control selection during browse mode
Just playing around, here is the latest stack using only the browse tool.
It resizes, moves and can set the text of the two fields present. It has nothing to do with the right way to do what it does.
Craig
Deleted, needed tiny upgrade...
And slightly updated:
It resizes, moves and can set the text of the two fields present. It has nothing to do with the right way to do what it does.
Craig
Deleted, needed tiny upgrade...
And slightly updated:
Last edited by dunbarx on Fri Dec 16, 2022 3:56 pm, edited 1 time in total.
-
- VIP Livecode Opensource Backer
- Posts: 10043
- Joined: Sat Apr 08, 2006 7:05 am
- Contact:
Re: [REQ] Control selection during browse mode
...and then there's the selection marquee, selection handles, etc.dunbarx wrote: ↑Thu Dec 15, 2022 9:16 pmRichard.I think, assuming the scope does not increase dramatically, that all can be done with the browse tool. A simple click can bring up a dialog to change the text of the target, dragging near a corner can nicely resize, and clicking and dragging can set the loc.What she needs is two tool modes, Browse and Pointer, available at the same time depending on mouse location
If you need to ship something that does this you're free to do it however you like. I've shipped commercial products using the method the engine inventor provided for me.
Richard Gaskin
LiveCode development, training, and consulting services: Fourth World Systems
LiveCode Group on Facebook
LiveCode Group on LinkedIn
LiveCode development, training, and consulting services: Fourth World Systems
LiveCode Group on Facebook
LiveCode Group on LinkedIn
-
- Posts: 101
- Joined: Mon Jan 03, 2022 7:10 pm
Re: [REQ] Control selection during browse mode
Craig, thank you for all the work you have done, but as has been mentioned in this thread this is a "kludge" and it feels like it (no offence to your code, it's just the way it feels in LiveCode). Seeing as I wanted exactly what the pointer tool does, I kludged that in to doing what I needed it to do (also mentioned in this thread).
I appreciate everyone's hard work and discussion on the topic
I appreciate everyone's hard work and discussion on the topic

Re: [REQ] Control selection during browse mode
Emily.
I like kludges because they are not in any box.
I do what I did for you strictly for fun and to push the borders.
But if you do now accept the pointer tool, what "kludge" did you need to, er, kludge something together?
Craig
I like kludges because they are not in any box.
I do what I did for you strictly for fun and to push the borders.
But if you do now accept the pointer tool, what "kludge" did you need to, er, kludge something together?
Craig
Re: [REQ] Control selection during browse mode
Emily and Richard. Possible Jacque.
I agree that a common process such as resizing ought to show some sort of indication as to the control of interest. My stack gadgetry does not, but recall that I am simply playing with the original restrictions set forth in the very title of this thread.
We already know that selecting objects under script control shows handles on those objects, though those handles are for show only, not accessible to the cursor for resizing. Who cares? Select as you will, and use my kludge to resize anyway.
Recall that I am doing this for fun and exercise; my guiding principle was no pointers. I am the one who mentioned kludges.
Emily, why did you decide to restrict the environment to the browse tool in the first place? You must have had some vision that set you down that path.
Craig
I agree that a common process such as resizing ought to show some sort of indication as to the control of interest. My stack gadgetry does not, but recall that I am simply playing with the original restrictions set forth in the very title of this thread.
We already know that selecting objects under script control shows handles on those objects, though those handles are for show only, not accessible to the cursor for resizing. Who cares? Select as you will, and use my kludge to resize anyway.
Recall that I am doing this for fun and exercise; my guiding principle was no pointers. I am the one who mentioned kludges.
Emily, why did you decide to restrict the environment to the browse tool in the first place? You must have had some vision that set you down that path.
Craig
Re: [REQ] Control selection during browse mode
I too have this requirement - to provide endusers with the possibility of creating custom cards/layouts, so have a vested interest in this.
I think I largely succeeded in emulating many aspects of the edit mode, but in browse mode. This is a first attempt and no doubt can be improved further but I'm happy that so far you can do the following in a more intuitive way (from the user's point of view):
- Click an object to select it, click the card to deselect
- grab the object to move it around
- grab any of the 8 drag markers to deform it in the chosen vector (ie topLeft, top, topRight, left, right, etc)
- change the cursor to reflect that you can either drag or resize if over a drag handle
The only thing I haven't yet done is to provide for multiple selections but think I'll have that done in the next day or so (actual real work permitting)
My setup has 4 components:
- a custom property on the card that informs whether or not we want to resize/reposition objects (the editControls of the card)
- a custom property on each object to identify it as something that can/should be resizable if the card is set to that mode (the isEditable of the object)
- a short card script that deselects all objects that may be selected; and also prepares fields to be selected (in default state these cannot be)
- a behaviour script that is assigned to the behaviour of any object we want to treat as resizeable - this is the meat of it.
the behaviour script basically checks to see if the clickLoc is within 4 pixels of any of the 8 drag handles or if it's in the 'body' of the object, changes cursor appropriately to give visual feedback of potential actions and either grabs or resizes according to which drag handle is dragged.
The card script has a command to deselect all objects and to prepare fields for selection as in browse mode you have to lock the text etc to make it selectable on click:
Finally I have a toggle on the card to change it from non-editable to editable mode:
Should be a minor change to allow shift-click for multiple selections. Seems to work well this far, but not very extensively tested...
test stack attached, the behaviour script is the script of a substack. Any object added to the card, and that should be resizeable needs to be given a custom property isEditable = true and be assigned the behaviour script, then should be editable directly in browse mode. No doubt this can be refactored further...
Regards
Stam
I think I largely succeeded in emulating many aspects of the edit mode, but in browse mode. This is a first attempt and no doubt can be improved further but I'm happy that so far you can do the following in a more intuitive way (from the user's point of view):
- Click an object to select it, click the card to deselect
- grab the object to move it around
- grab any of the 8 drag markers to deform it in the chosen vector (ie topLeft, top, topRight, left, right, etc)
- change the cursor to reflect that you can either drag or resize if over a drag handle
The only thing I haven't yet done is to provide for multiple selections but think I'll have that done in the next day or so (actual real work permitting)
My setup has 4 components:
- a custom property on the card that informs whether or not we want to resize/reposition objects (the editControls of the card)
- a custom property on each object to identify it as something that can/should be resizable if the card is set to that mode (the isEditable of the object)
- a short card script that deselects all objects that may be selected; and also prepares fields to be selected (in default state these cannot be)
- a behaviour script that is assigned to the behaviour of any object we want to treat as resizeable - this is the meat of it.
the behaviour script basically checks to see if the clickLoc is within 4 pixels of any of the 8 drag handles or if it's in the 'body' of the object, changes cursor appropriately to give visual feedback of potential actions and either grabs or resizes according to which drag handle is dragged.
Code: Select all
local sRect, sClickAreasA, sClickedArea
/* clickareas array - clicking a drag handle will assign one of elements 1-8 to sClickedArea:
1: topLeft, 2: topCentre, 3: topRight
4: midLeft, 5: midRight
6: bottomLeft, 7: bottomCentre, 8: bottomRight
if the clickLoc is in none of the above then sClickedArea is 'grab'
*/
on mouseDown
if the editControls of this card then
setClickable true
put getClickLocation(the clickLoc) into sClickedArea
end if
if sClickedArea = "grab" then grab me
end mouseDown
command setClickable pMode // bool
if pMode = true then
if the uSelected of me then exit setClickable
send "unSelectAll" to this card
setCursor
select me
set the uSelected of me to true
else
if not the uSelected of me then exit setClickable
resetCursor
set the uSelected of me to false
end if
end setClickable
command clearClickAreas // reset drag handle rect definitions
put empty into sClickAreasA
end clearClickAreas
command setClickAreas // get a 9 pixel rect around each of the 8 drag handles
lock screen
set the rect of the templateGraphic to "0,0,9,9"
set the style of the templateGraphic to "rectangle"
set the visible of the templateGraphic to false
create graphic "temp"
reset the templateGraphic
// 1 - topleft
set the loc of graphic "temp" to the topleft of me
put the rect of graphic "temp" into sClickAreasA[1]
// 2 - topCentre
set the loc of graphic "temp" to item 1 of the loc of me, the top of me
put the rect of graphic "temp" into sClickAreasA[2]
// 3 - topRight
set the loc of graphic "temp" to the topRight of me
put the rect of graphic "temp" into sClickAreasA[3]
// 4 - midLeft
set the loc of graphic "temp" to the left of me, item 2 of the loc of me
put the rect of graphic "temp" into sClickAreasA[4]
// 5 - midRight
set the loc of graphic "temp" to the right of me, item 2 of the loc of me
put the rect of graphic "temp" into sClickAreasA[5]
// 6 - bottomLeft
set the loc of graphic "temp" to the bottomLeft of me
put the rect of graphic "temp" into sClickAreasA[6]
// 7 - bottomCentre
set the loc of graphic "temp" to item 1 of the loc of me, the bottom of me
put the rect of graphic "temp" into sClickAreasA[7]
// 8 - bottomRight
set the loc of graphic "temp" to the bottomRight of me
put the rect of graphic "temp" into sClickAreasA[8]
//
delete graphic "temp"
end setClickAreas
function getClickLocation pClickLocation // define which drag handle is clicked
local tLocation
if pClickLocation is within sClickAreasA[1] then
return "topLeft"
else if pClickLocation is within sClickAreasA[2] then
return "topCentre"
else if pClickLocation is within sClickAreasA[3] then
return "topRight"
else if pClickLocation is within sClickAreasA[4] then
return "midLeft"
else if pClickLocation is within sClickAreasA[5] then
return "midRight"
else if pClickLocation is within sClickAreasA[6] then
return "bottomLeft"
else if pClickLocation is within sClickAreasA[7] then
return "bottomCentre"
else if pClickLocation is within sClickAreasA[8] then
return "bottomRight"
else
return "grab"
end if
end getClickLocation
on mouseEnter
setClickAreas
setCursor
end mouseEnter
command setCursor
if not the editControls of this card then
resetcursor
exit setCursor
end if
set the lockCursor to true
set the cursor to hand
repeat with x = 1 to 8
if the mouseLoc is within sClickAreasA[x] and the uSelected of me then
set the cursor to cross
exit repeat
end if
set the cursor to hand
end repeat
end setCursor
command resetCursor
set the lockCursor to false
set the cursor to arrow
end resetCursor
on mouseMove
setCursor
if the mouse is down then
local tRect
lock screen
put the rect of me into tRect
if sClickedArea = "grab" then pass mouseMove
switch sClickedArea
case "topLeft"
put item 1 of the mouseLoc into item 1 of tRect
put item 2 of the mouseLoc into item 2 of tRect
break
case "topCentre"
put item 2 of the mouseLoc into item 2 of tRect
break
case "topRight"
put item 1 of the mouseLoc into item 3 of tRect
put item 2 of the mouseLoc into item 2 of tRect
break
case "midleft"
put item 1 of the mouseLoc into item 1 of tRect
break
case "midRight"
put item 1 of the mouseLoc into item 3 of tRect
break
case "bottomLeft"
put item 1 of the mouseLoc into item 1 of tRect
put item 2 of the mouseLoc into item 4 of tRect
break
case "bottomCentre"
put item 2 of the mouseLoc into item 4 of tRect
break
case "bottomRight"
put item 1 of the mouseLoc into item 3 of tRect
put item 2 of the mouseLoc into item 4 of tRect
break
end switch
set the rect of me to tRect
end if
end mouseMove
on mouseLeave
resetCursor
end mouseLeave
Code: Select all
on mouseDown
unSelectAll
end mouseDown
command unSelectAll
repeat with x = 1 to the number of controls of this card
if the isEditable of control x of this card then
dispatch "setClickable" to control x of this card with false
end if
end repeat
select empty
end unSelectAll
command prepFields
repeat with x = 1 to the number of fields
if the isEditable of field x then
set the traversalOn of field x to not the editControls of me
set the lockText of field x to the editControls of me
end if
end repeat
end prepFields
Code: Select all
on hiliteChanged
set the editControls of this card to the hilite of me
unselectAll
prepFields
end hiliteChanged
test stack attached, the behaviour script is the script of a substack. Any object added to the card, and that should be resizeable needs to be given a custom property isEditable = true and be assigned the behaviour script, then should be editable directly in browse mode. No doubt this can be refactored further...
Regards
Stam
- Attachments
-
- editableControls.livecode.zip
- (2.8 KiB) Downloaded 172 times
Last edited by stam on Fri Dec 16, 2022 6:43 pm, edited 1 time in total.
-
- Posts: 101
- Joined: Mon Jan 03, 2022 7:10 pm
Re: [REQ] Control selection during browse mode
Stam, nicely done 

-
- VIP Livecode Opensource Backer
- Posts: 10043
- Joined: Sat Apr 08, 2006 7:05 am
- Contact:
Re: [REQ] Control selection during browse mode
It's possible to reproduce many engine-provided behaviors in a custom scripted implementation. We can also write our own amortization functions, craft our own HTTP handlers using sockets directly, and even create buttons from images if we like.
And I've done all of those. But rarely.
In each case I've asked myself what is the compelling benefit of taking on the expense of rolling my own rather than just using what's provided in the box for the purpose.
It varies from app to app. Most of the time I generally avoid reinventing provided wheels. But there are times when I've had to increase costs by choosing to craft a custom implementation because of some nuance not provided in the engine-based solution. I weigh such decisions very carefully, having been in this biz long enough to know the protracted cost of technical debt.
In this discussion of emulating built-in tool modes that have been a foundational part of xTalks since HC 1.0, it may be worth reviewing one of the more complete implementations I've ever seen in our community, Ken Ray's Stykz:
https://www.stykz.net
I was in touch with Ken throughout much of that development process, and can answer many questions about how he pulled it off, and why. And for anything I can't answer I can see if he can spare a moment to drop in here if needed.
For the WHY of his pointer tool implementation, at the heart of that decision was inverse kinematics. Stykz makes stick figure animations, and doing so efficiently requires the underlying code to maintain relationships between the parts of a figure (forearm connected to upper arm, shoulder to torso, etc.). When moving a selected part of a figure, app-specific intelligence is needed to maintain the figure's functional integrity.
Obviously that's far beyond what the humble Pointer tool does, since the built-in tool mode was designed to provide only behaviors of the sort we commonly see in drawing apps like MacDraw, Illustrator, Inkscape, etc.
So given the highly specialized needs of his app, Ken bit the bullet hard, and crafted one of the finest Pointer tool emulations I've ever seen.
For the HOW of it, he maintains multiple groups for each control. Some include the parts of the stick figure itself, grouped in ways that make the logic of linking their kinematics manageable.
Another set of groups is used to maintain the selection handles, one set of handles per object, where each handle is a graphic object. These are within a master group both to show/hide them easily, but mostly to keep the handles on top in the layer order, so that no figure element obscures use of a handle.
The selection marquee is done as you'd expect, a rectangle graphic object shown when the mouse is down outside of any control and moved beyond a reasonable slop rect to distinguish drags from clicks. When the mouse is eventually released, the code compares the rect of the marquee graphic to every user-made object to determine intersection, and then shows the selection handle group for that object (or set of objects, since many things users interact with in Stykz as a single object are implementated under the hood as a collection of objects in a group).
There are other details, but this at least provides an overview of the sort of things we will encounter when we choose to reproduce engine-provided behavior in bespoke script.
Given the level of effort needed to meet user expectations for something as common as a Pointer tool mode, maybe the most valuable part of this outline is the depth he explored first before attempting this. Only when all engine-provided solutions were identified as insufficient for the needs of this specific app did he decide to undertake the considerable effort to reproduce in script what the engine team worked so hard for so long to provide for us.
Ken and I sometimes joke about making t-shirts that read:
Know the engine.
Trust the engine.
Use the engine.
And I've done all of those. But rarely.
In each case I've asked myself what is the compelling benefit of taking on the expense of rolling my own rather than just using what's provided in the box for the purpose.
It varies from app to app. Most of the time I generally avoid reinventing provided wheels. But there are times when I've had to increase costs by choosing to craft a custom implementation because of some nuance not provided in the engine-based solution. I weigh such decisions very carefully, having been in this biz long enough to know the protracted cost of technical debt.
In this discussion of emulating built-in tool modes that have been a foundational part of xTalks since HC 1.0, it may be worth reviewing one of the more complete implementations I've ever seen in our community, Ken Ray's Stykz:
https://www.stykz.net
I was in touch with Ken throughout much of that development process, and can answer many questions about how he pulled it off, and why. And for anything I can't answer I can see if he can spare a moment to drop in here if needed.
For the WHY of his pointer tool implementation, at the heart of that decision was inverse kinematics. Stykz makes stick figure animations, and doing so efficiently requires the underlying code to maintain relationships between the parts of a figure (forearm connected to upper arm, shoulder to torso, etc.). When moving a selected part of a figure, app-specific intelligence is needed to maintain the figure's functional integrity.
Obviously that's far beyond what the humble Pointer tool does, since the built-in tool mode was designed to provide only behaviors of the sort we commonly see in drawing apps like MacDraw, Illustrator, Inkscape, etc.
So given the highly specialized needs of his app, Ken bit the bullet hard, and crafted one of the finest Pointer tool emulations I've ever seen.
For the HOW of it, he maintains multiple groups for each control. Some include the parts of the stick figure itself, grouped in ways that make the logic of linking their kinematics manageable.
Another set of groups is used to maintain the selection handles, one set of handles per object, where each handle is a graphic object. These are within a master group both to show/hide them easily, but mostly to keep the handles on top in the layer order, so that no figure element obscures use of a handle.
The selection marquee is done as you'd expect, a rectangle graphic object shown when the mouse is down outside of any control and moved beyond a reasonable slop rect to distinguish drags from clicks. When the mouse is eventually released, the code compares the rect of the marquee graphic to every user-made object to determine intersection, and then shows the selection handle group for that object (or set of objects, since many things users interact with in Stykz as a single object are implementated under the hood as a collection of objects in a group).
There are other details, but this at least provides an overview of the sort of things we will encounter when we choose to reproduce engine-provided behavior in bespoke script.
Given the level of effort needed to meet user expectations for something as common as a Pointer tool mode, maybe the most valuable part of this outline is the depth he explored first before attempting this. Only when all engine-provided solutions were identified as insufficient for the needs of this specific app did he decide to undertake the considerable effort to reproduce in script what the engine team worked so hard for so long to provide for us.
Ken and I sometimes joke about making t-shirts that read:
Know the engine.
Trust the engine.
Use the engine.
Richard Gaskin
LiveCode development, training, and consulting services: Fourth World Systems
LiveCode Group on Facebook
LiveCode Group on LinkedIn
LiveCode development, training, and consulting services: Fourth World Systems
LiveCode Group on Facebook
LiveCode Group on LinkedIn
Re: [REQ] Control selection during browse mode
Thanks Richard - always enjoy your insights and anecdotes.
But now I’m confused - is it possible to use the pointer tool in standalone? If that’s the case I definitely would use that and not bother rolling my own!
It never crossed my mind to try using pointer tool in a standalone as it always appeared to be a IDE tool to me, but will definitely try that if you say that’s possible!
S.
But now I’m confused - is it possible to use the pointer tool in standalone? If that’s the case I definitely would use that and not bother rolling my own!
It never crossed my mind to try using pointer tool in a standalone as it always appeared to be a IDE tool to me, but will definitely try that if you say that’s possible!
S.