Bob,

This is nice trick (and code) to use an overlayed button to get a widget to respond to standard messages. Impressive!

I really think that Livecode Ltd. needs to prioritize adding a set of "standard" object messages to every current widget to address these 3 bugs (and their generalization to all other widgets):
https://quality.livecode.com/show_bug.cgi?id=24458
https://quality.livecode.com/show_bug.cgi?id=24437
https://quality.livecode.com/show_bug.cgi?id=24429

Every widget should be able to handle OR pass  through (just like every Livecode field, button, scrollbar, etc.) resizeControl, mouseEnter, mouseWithin, mouseLeave, mouseDown, mouseDoubleDown, mouseStillDown, mouseUp, mouseDoubleUp, and probably a bunch more.


On 12/29/2023 5:39 PM, Bob Sneidar via use-livecode wrote:
I have a kind of custom group composed of a segmented widget and a transparent 
button the exact size of the widget, the purpose of which is to be able to 
handle messages that are otherwise not sent to the widget. In fact almost NO 
messages are sent to a widget, a source of some consternation from users of 
this list.

There are three issues with this, the first being that if there is a button on 
top of a widget, then no messages get sent directly from the engine to the 
widget at all! The second is that if I add more segments or resize the widget, 
the width of the overlay button also needs to match. The third issue is that if 
I click on the overlay button, I need to know, as in the case of a mouse click 
which segment was clicked on.

To this end I wrote some handlers for the widget and the overlay button which 
allow you to handle any messages a button might receive and then process them 
for the widget. This is of course just a basic framework. The important 
handlers are resizeControl and the getProp clickedTab.

Unfortunately, and although changing the size of the widget will send the 
resizeContol message to t he widget, editing the width in the widget’s 
properties palette does NOT send the message. The upshot is that if you make 
changes to a widget, you can simply run the resizeControl handler to clean 
things up.

In my case I always want the widget segments to be the same size, and I always 
want the widget to be centered on the card. YMMV. You could get even fancier if 
you wanted and calculate the formattedWidth of the segment names, add a little 
air around them, then set the width of the widget to the sum of those, and then 
the minimum segment widths to those formattedWidths. But manipulating the 
minimum segment widths to get the correct width for each segment is something I 
have not fathomed. I wish they had given us a property for the *actual* segment 
widths.

For the widget itself I have these handlers:

on hiliteChanged
    put the hilitedItemNames of me into tTabName
    put the itemNames of me into tTabList
    tabChanged tTabName, tTabList
end hiliteChanged

on tabChanged pTab, pTabList
    -- your code here
end tabChanged

on resizeControl
    wait until the mouse is up with messages
    put the long id of me into tMyID
    put wordOffset("card", tMyID) +1 into tPos
    put word tPos to -1 of tMyID into tParentCard
    put the width of widget "TabBar" into tWidth
    put tWidth / the itemCount of widget "TabBar" into tSegmentWidth
repeat with i = 1 to the itemCount of widget "TabBar"
       put tSegmentWidth into item i of tSegmentWidths
    end repeat
set the itemMinExtents of widget "TabBar" to tSegmentWidths -- center the widget left to right
    put the loc of widget "TabBar" into tTabLoc
    put the loc of tParentCard into tCardLoc
    put item 1 of tCardLoc into item 1 of tTabLoc
    set the loc of widget "TabBar" to tTabLoc
-- set the rect of the overlay button to match
    set the rect of button "btnTabOverlay" to the rect of widget "TabBar"
end resizeControl


Then for the overlay button:

on mouseUp
    put the clickedTab of me into tTab
    set the hilitedItemNames of widget "TabBar" to tTab
end mouseUp

on mouseDoubleUp
    put the clickedTab of me into tTab
-- your code here
end mouseDoubleUp

getProp clickedTab
    put the clickLoc into tClickLoc
    put the itemNames of widget "TabBar" into tTabNames
    put the rect of widget "TabBar" into tTabRect
    put item 3 of tTabRect - item 1 of tTabRect into tTabWidth
    put the itemCount of widget "TabBar" into tTabCount
    put tTabWidth / tTabCount into tSegmentWidth
repeat with i = 1 to tTabCount
       put round(item 1 of tTabRect + (tSegmentWidth * i)) into tSegmentBounds
if item 1 of tClickLoc <= tSegmentBounds then
          put item i of tTabNames into tTab
          exit repeat
       end if
    end repeat
put the itemMinExtents of widget "TabBar" into tExtents
    return tTab
end clickedTab


_______________________________________________
use-livecode mailing list
use-livecode@lists.runrev.com
Please visit this url to subscribe, unsubscribe and manage your subscription 
preferences:
http://lists.runrev.com/mailman/listinfo/use-livecode


_______________________________________________
use-livecode mailing list
use-livecode@lists.runrev.com
Please visit this url to subscribe, unsubscribe and manage your subscription 
preferences:
http://lists.runrev.com/mailman/listinfo/use-livecode

Reply via email to