Bad Crash on Attempt to Group Radio Buttons
Richard Gaskin
ambassador at fourthworld.com
Mon Aug 28 11:48:16 EDT 2017
Well, cantSelect is a step toward a solution for making multi-mode
regions within a window, as I noted just above the section of my post
you quoted:
Scott Raney added the cantSelect property after a long discussion
I had with him about building custom drawing environments.
I had originally suggested to him that we extend the tool property
to be local to groups (similar to the flexibility SuperCard provides
with the tool being local to a window, years later submitted to
RunRev as BZ#623)), and he found that interesting but more work than
was available at that moment in the release cycle.
So instead he came up with the cantSelect property as a workaround
to tide us over in the meantime.
<http://lists.runrev.com/pipermail/use-livecode/2017-August/241336.html>
But like any hastily-added workaround, in practice it turns out to be
only slightly less cumbersome than not having it at all, at least for
the original intended purpose.
Imagine a common drawing app such as you describe, with a drawing region
in a group occupying most of the window and a set of controls in a
toolbar group to change tools, select colors and line widths, etc.
Let's explore how this plays out:
1. Drag selection
At first glance things seem pretty nice, you can drag-select within the
drawing group, and also click the toolbar buttons.
But then you'll notice that the user can also drag a marquee in the
toolbar group, and though it won't allow selection of any of the
controls there (assuming they've all had their "cantSelect" set to true)
the ability to drag a selection marquee is odd and confusing.
2. Object creation
For manipulating existing objects within the drawing region group, the
setup works fine, allowing users to move and resize objects nicely.
And you have a toolbar that allows you to select object creation tools,
so you're excited by the prospect of dragging out new controls within
the drawing region.
Except you can't. Since tool modes are global in LC, when you choose
something like the graphic tool the entire window is the recipient of
the object creation gestures, and as such will create newly dragged out
objects above (outside) of the drawing region group.
Once created, this may only become confusing when the drawing region
group is scrolled.
If created in a position that overlaps the drawing region's scrollbar,
that they are above and outside the group is immediately evident.
We could turn on the editBackgound, but doing so will cause the toolbar
region and even the drawing region's own scrollbars to disappear.
A workaround is to trap newGraphic and relayer it, after first being
careful to set the relayerGroups to true and then set it back again when
you're done. This ultimately places the object within the group, but
doesn't explain to the user why the object was first seen overlapping
the scrollbar and extending beyond the drawing region, and is now
clipped within the drawing region. In the end the result is okay, but
each time they make an object near the edges of the drawing region the
app momentarily feels a bit broken.
3. Ancillary windows
Many apps will have other windows beyond the document, such as About,
Preferences, etc.
If you open those in non-toplevel modes (such as modeless) they're fine,
since LC's global tool mode only affects toplevel windows.
But often we have ancillary windows as toplevel, perhaps different views
to other data in the document (consider an inventory list reflecting
things drawn in the drawing window).
In such cases you'd have to carefully set the cantSelect of literally
every control in every stack other than the ones inside the drawing
region group, and even then you'd have to accept the user's ability to
drag-select marquees across the surface of any of them, even those where
such selection would not be in any way relevant.
Workaround to deal with the workaround:
After experiencing these and other challenges in trying to reproduce the
sort of SampleDraw app so easily made in SuperCard with its local tool
modes, the best workaround I've found is to not employ the cantSelect
workaround at all, since something more complete is needed.
Whether or not one uses the cantSelect for toolbar objects in a drawing
window, what's really needed is to turn off the global pointer tool and
use the browse tool whenever the pointer it outside of the drawing group.
I hadn't pursued this at first for fear of the user of seeing their
selected objects become deselected, sometimes annoying and other times
making it impossible to use a button or menu outside the drawing group
which would act on the selection.
But it turns out that MC/LC allows selection handles to be shown
regardless of the current global tool mode.
So the workaround for the workaround is to track mouseMove, and when the
mouse exits the drawing region you:
1. Get the selectedObjects
2. Change the global tool to browse tool
3. Walk through the previously-obtained list of selected objects
to set their selected property to true, restoring their
selection handles.
When the mouse re-enters the drawing region, reverse the process.
You'll probably want to put that into a pair of handlers that can be
conveniently called from anywhere (something like "SwitchToBrowse" and
"SwitchToPointer"), because you'll also need to call them on
suspendStack and resumeStack, and possibly in other contexts as well
depending on the particulars of your app.
All in all, it can become possible to make a drawing app that takes full
advantage of the pointer tool without having the emulate all the things
the pointer tool does within the browse tool.
But it still requires some diligence, clear thinking, and a bit more
code than in SuperCard, Gain Momentum, or other xTalks that provide
local tool modes.
And since LC has such wonderfully flexible groups, if tool modes were
local to groups rather than to windows as SC does, the possibilities for
easily crafting custom layout tools becomes even far more vast with no
greater complexity for the scripter.
But even as it is, it's not prohibitive, just not the sort of thing I'd
wish on newcomers.
The beauty of taking full advantage of the language's rich variety of
tool modes by localizing them made SuperCard's SampleDraw a very
inspiring example app, one of the things that got me so hooked on xTalks.
LC ships with many more examples (78 tutorials installed, last time I
counted), and they cover a lot of good ground. Just all in one tool mode.
And given the scope of knowledge needed to use other tool modes in
delivered apps, I wouldn't recommend making a tutorial for newcomers
like SampleDraw. Indeed, it's why I abandoned mine years ago. I can
make it, I just can't explain it. :)
--
Richard Gaskin
Fourth World Systems
Software Design and Development for the Desktop, Mobile, and the Web
____________________________________________________________________
Ambassador at FourthWorld.com http://www.FourthWorld.com
Sannyasin Brahmanathaswami wrote:
> Richard:
>
> Hmmm, this could be really useful
>
> a whole responsive palette of control on the side of a card, (instead of a separate palette stack) while continuing to dev in the main region. useful for dev.
>
> In fact doesn't this solve a core UX, that is not "ancient"by any means?:
>
> A drawing region with controls on the side/bottom. and all you have to do is turn on the pointer. (having preset all the other controls to cantSelect/AlwaysBrowseMode.)
>
> I actually have a use case for this right in front of me if it works on Mobile.
>
> BR
>
> On 8/27/17, 1:29 PM, "use-livecode on behalf of Richard Gaskin via use-livecode" <use-livecode-bounces at lists.runrev.com on behalf of use-livecode at lists.runrev.com> wrote:
>
> In addition to what Jacque noted there's something more that can be very
> important in some contexts:
>
> It doesn't just prevent the object from being acted on by the pointer
> tool, but moreover always acts as though its own object-local tool mode
> is the browse tool, regardless of whatever other tool is in effect.
>
> "CantSelect" is a very Raney name; "AlwaysBrowseMode" would be more
> descriptive.
>
> This means your object will get all the messages you'd expect to get
> with the browse tool regardless of the current global tool property, but
> only for that one object.
>
> This can be useful for contexts in which you want to allow the user to
> use the pointer tool, but also provide a toolbar or other controls they
> can use to select shapes, colors, etc.
>
More information about the use-livecode
mailing list