Message Sent when Resizing Widgets: Workaround

Paul Dupuis paul at researchware.com
Fri Dec 29 17:53:56 EST 2023


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 at lists.runrev.com
> Please visit this url to subscribe, unsubscribe and manage your subscription preferences:
> http://lists.runrev.com/mailman/listinfo/use-livecode




More information about the use-livecode mailing list