Message Sent when Resizing Widgets: Workaround
Bob Sneidar
bobsneidar at iotecdigital.com
Fri Dec 29 17:39:24 EST 2023
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
More information about the use-livecode
mailing list