Page 1 of 2

Composed Widgets limitations

Posted: Tue Sep 01, 2020 1:56 pm
by PaulDaMacMan
So it seems there are some limitations in LCB / Widgets / Composed Widgets that I've been unaware of (because I've mostly been concentrating my efforts on FFI ). If there are any workarounds please feel free to enlighten me!
1) There is no equivalent of LCS' mouse() function for checking if the mouse is "down" in LCB
2) In a composed widgets, once a child widget is 'focused' or clicked on, control is not passed to another child widget until the mouse button is released, essentially blocking any messages, such as 'OnMouseEnter', from being sent to any other child widget.
3) The only way to pass information between child widgets is via the parent widget getting and setting properties in the child widgets or by passing information to the LCS engine via 'execute script', declaring a global variable, and then retrieving that global again via 'execute script'.
Am I correct in these assumptions?

Re: Composed Widgets limitations

Posted: Thu Sep 03, 2020 2:08 am
by mwieder
1. Check the LCB dictionary for the OnMouseDown message.And the other OnMouse... messages.
OIC - do you mean checking whether the mouse is down without waiting to handle an OnMouseDown message?

[Update:] have you tried "if the mouse is down"? I know it's not in the dictionary, but neither is "the mouse position" and that works.

3. Widgets can pass messages around. Are you referring to variables inside a widget? You can use getters and setters for that.

Re: Composed Widgets limitations

Posted: Thu Sep 03, 2020 4:12 am
by PaulDaMacMan
mwieder wrote:
Thu Sep 03, 2020 2:08 am
1. Check the LCB dictionary for the OnMouseDown message.And the other OnMouse... messages.
OIC - do you mean checking whether the mouse is down without waiting to handle an OnMouseDown message?

[Update:] have you tried "if the mouse is down"? I know it's not in the dictionary, but neither is "the mouse position" and that works.

3. Widgets can pass messages around. Are you referring to variables inside a widget? You can use getters and setters for that.
Yeah, I'm already using OnMouseDown/Up/Enter/etc., the OIC thing is what I was looking for, I want to check if the mouse is already "down" when the Child widget is entered OnMouseEnter() or maybe a OnMouseStillDown() if there was one... and no, I haven't tried anything that's not in the LCB dictionary.
It's not clear how "Widgets can pass messages around", if I could pass OnMouseDown/Up to all child widgets simultaneously that would probably do the trick. I did try to use variable / properties to share the state of the mouse button across child widgets, but logging that shows it only triggers for the child widget that the mouse down started on.

What seems to happen (at least on macOS) is that while the mouse button is still pressed down, OnMouseLeave() is triggered for the child widget you originally moused down on, but OnMouseEnter() for a different child widget does not get triggered. It does trigger as expected as long as a mouse button is not pressed, but not while one is pressed. This might be a bug?

I think I'm going to just skip using Composed Widgets with this project.

Re: Composed Widgets limitations

Posted: Fri Sep 04, 2020 3:54 am
by PaulDaMacMan
Maybe this visual will help explain what I'm trying for:
Screen Shot 2020-09-03 at 10.44.46 PM.png
Each "octave" of what will be a "Mouse Piano" is a Child Widget (purposely spaced with a gap for this visual), each made up of an array of path / "piano key" objects, in a Composed Widget (8 octaves here but the amount of octaves would be a settable property). I need to be able to track if the mouse is "still down" as the cursor enters the next octave child widget.

Re: Composed Widgets limitations

Posted: Fri Sep 04, 2020 5:05 am
by mwieder
Heh. I was going to suggest using OnMouseEnter and checking for the mouse being down, but I see that's not going to work.
Yeah - this seems to me like a bug worth reporting.

Re: Composed Widgets limitations

Posted: Fri Sep 04, 2020 9:19 pm
by PaulDaMacMan
mwieder wrote:
Fri Sep 04, 2020 5:05 am
Heh. I was going to suggest using OnMouseEnter and checking for the mouse being down, but I see that's not going to work.
Yeah - this seems to me like a bug worth reporting.
Well the ( current ) click button IS in the dictionary but I just tried to use the 'current' form and it throws this message:
executing at 4:11:14 PM
LCB Error 'the current click button' is not implemented yet
Object Tests
LCB File multioctavepianotest2.lcb
LCB Line 224
So it would seem that part of the puzzle isn't so much a bug as it is that LiveCode Builder is still a work in progress and they haven't yet completed the if the mouse is "down" equivalent for LCB.

Re: Composed Widgets limitations

Posted: Fri Sep 04, 2020 10:54 pm
by bn
Well the ( current ) click button IS in the dictionary but I just tried to use the 'current' form and it throws this message:

executing at 4:11:14 PM
LCB Error 'the current click button' is not implemented yet
Object Tests
LCB File multioctavepianotest2.lcb
LCB Line 224
What if you would handle all code in the parent script and use the target to see which child receives the message? See example in dictionary for target how the messages go from the child widget to the parent widget.
I never have used child widgets though.

I handle "mouseStillDown" by setting a script local variable to true on OnMouseDown and then test in "OnMouseMove" if the script local is true.

Code: Select all

public handler OnMouseDown() returns nothing
   put true into mMouseIsDown
   
public handler onMouseUp() returns nothing
   put false into mMouseIsDown
      
public handler onMouseCancel()
   -- if mouse is released outside of card
   put false into mMouseIsDown
 
 public handler OnMouseMove()
    if mMouseIsDown then
 
Kind regards
Bernd

Re: Composed Widgets limitations

Posted: Sun Sep 06, 2020 3:32 am
by bwmilby
Not having viewed the widget code, I may be way off. I would think it would be better to have ‘octaves’ as a property for the widget (or notes) and just draw the requested number in the base widget instead of composing them like you are describing.

Re: Composed Widgets limitations

Posted: Sun Sep 06, 2020 6:47 pm
by PaulDaMacMan
bn wrote:
Fri Sep 04, 2020 10:54 pm

What if you would handle all code in the parent script and use the target to see which child receives the message? See example in dictionary for target how the messages go from the child widget to the parent widget.
I never have used child widgets though.
I have tried this route. The child widget that started the MouseDown is the only Target while the mouse is Still-Down, until the Mouse button is released. If the mouse is not down at all then it behaves as expected.
I handle "mouseStillDown" by setting a script local variable to true on OnMouseDown and then test in "OnMouseMove" if the script local is true.
My single octave widget (which is the child widget, and already works fine own it's own) uses this method to track, and I've already tried getting and setting each child widget's mMouseIsDown property from the parent widget, and handling the OnMouse... messages from the parent. The root problem seems to be the former 'The Target' behavior while the mouse is still-down, and the fact that 'current click button' is not yet implemented.

Re: Composed Widgets limitations

Posted: Sun Sep 06, 2020 7:03 pm
by PaulDaMacMan
bwmilby wrote:
Sun Sep 06, 2020 3:32 am
Not having viewed the widget code, I may be way off. I would think it would be better to have ‘octaves’ as a property for the widget (or notes) and just draw the requested number in the base widget instead of composing them like you are describing.
I'm probably going to just implement it as multiple individual non-composed widgets of different-amounts-of-octave sizes, or like you said, create an Octave object and then make instances across in a single widget. This is something I was already experimenting with but found it difficult to get paths positioned just right so that they still look good at different resized heights and widths. It may be easier to start with an SVG graphic that has the full 127 key range.

I have a property mOctave which determines the note range of each octave, each piano key has a note offset value from that base value of the octave, 'middle C' octave starts a 60, so the 'C' key has an offset value of 0, C# is 1, D is 2 etc. and then pitch values are calculated something like (mOctave*12)+tBlackKey["noteoffset"]

I have a working single octave widget, I wanted to use compose to create as many octaves as desired (up to 10.5 octaves / 127 pitches available in standard MIDI) setting the mOctave property for each child widget, which works fine, the problem is only when the mouse is still-down going from one child widget "octave" to another.

As a side note, I've also created the same before in the LCS + graphic objects, but wanted to reimplement it in LCB, mostly as a Widget learning exercize.

Here is the code if you want to look:
https://github.com/PaulMcClernan/LCB_PianoWidget/
Ignore "Test" as it is just some experiments.

The fact that there is no mention in the LCB dictionary of the 'current' form of 'the click button' not yet being implemented is a 'Docs' bug at the very least.

Re: Composed Widgets limitations

Posted: Sun Sep 06, 2020 11:24 pm
by seaniepie
https://github.com/livecode/livecode/bl ... events.cpp

Line 190 there is a Todo remark from 5years ago by MarkW

Line 935 on are some Click button references linked to Line 190 on. Worth a look at for your own interest.

LCB, much like the rest of LC, is abandon-ware. Don’t expect a fix any time this century. :roll:

Re: Composed Widgets limitations

Posted: Mon Sep 07, 2020 12:17 am
by PaulDaMacMan
seaniepie wrote:
Sun Sep 06, 2020 11:24 pm
https://github.com/livecode/livecode/bl ... events.cpp

Line 190 there is a Todo remark from 5years ago by MarkW

Line 935 on are some Click button references linked to Line 190 on. Worth a look at for your own interest.

LCB, much like the rest of LC, is abandon-ware. Don’t expect a fix any time this century. :roll:
:(
Well it's a small staff that seems stretched thin and so I can understand, but it is open-source so if I learned enough C++ and how to poll the mouse on every platform, I suppose I could fix it. At least it is robust enough that I have options for working around that. I think when I get some time, I'll at least do a pull request on 'the (current) click button' to add the note about it still not being implemented yet. Might save someone else some of their time. I've seen a few more errors elsewhere in the LCB docs. The docs for LCB in general are not very good IMO.

Re: Composed Widgets limitations

Posted: Mon Sep 07, 2020 4:32 am
by mwieder
Sean- that section of code at line 190 (and all the rest of the WIDGET_KEYBOARD_FOCUS code)deals with the keyboard focus. I'm not sure it would affect the mouse messages.
But there's an interesting section at line 337 that might well have to do with why the messages are different while the mouse is down.

Code: Select all

       if (t_focused_changed)
        {
            // If a widget is handling a mouse press event then we want to inform
            // the grabbed widget about enter / leave, but it keeps getting all the
            // move events.
            if (t_focused_widget != m_mouse_grab)
                mouseLeave(m_mouse_grab);
            else if (m_mouse_focus != m_mouse_grab)
                mouseEnter(m_mouse_grab);
        }

Re: Composed Widgets limitations

Posted: Mon Sep 07, 2020 5:01 am
by seaniepie
Oops, oh yeah, my bad. I’d gone back to the wrong todo when I was going between this forum and the hub. I actually meant line 415 which deals with drag messages.

But you are right. That whole region from 289-389 should deal with it and appears to be correct.

Re: Composed Widgets limitations

Posted: Tue Sep 08, 2020 10:03 pm
by mwieder
Not sure about that.
Shouldn't there be a mouseEnter() after the mouseLeave() at line 341?
Otherwise it looks like the event_mfocus() just returns True and we're done.
Lines 364-366 look like they're doing the right thing, but only if the mouse isn't already down.
I'd add a

Code: Select all

mouseEnter(m_mouse_focus);
after line 341 (with curly braces of course for the conditional) to fix it.

Disclaimer: this is my first time looking into this section of code, so I could be way off base.