Thread from comp.lang.tcl (2 replies)

How do I pack a megawidget?
Posted by Luc <luc@sep.invalid> 3 months ago

I know y'all gonna hate this question because I'm not showing much code,
but I am really more interested in concepts than code.

I made a package. It's supposed to be a megawidget. I haven't snitted it
yet. I can't snit it without understanding where I am supposed to go
with it. So here is the problem.

package require giggles

set of $::w.outerframe
frame $of -height 100
pack $of -fill both -expand 1

set gg $of.giggles
::giggles::giggles $gg -guifont "Arial 14" -geometry pack
pack $gg -fill both -expand 1

And it works. The prototype megawidget is inserted into my test parent
application.

The problem is, commenting out the last 'pack' line makes no difference.
The megawidget still shows. (Also, funny that apparently it's redundant 
but nothing clashes.) And of course that is not standard widget behavior.

Of course, I am packing everything in the megawidget. But if I don't, 
then what? I can't just leave it hanging because if I do, then the 
author of the parent widget will have to inspect the code of the 
megawidget to figure out what he is supposed to pack to get it all 
working which, again, is not standard widget behavior, it's actually
pretty stupid. I have to expose something. Something that will take
the 'pack' command from the parent application and make the entire 
megawidget come together, with all of its components.

How do I do that?

-- 
Luc
>>

Click on article to view all threads in comp.lang.tcl
Re: How do I pack a megawidget?
Posted by saito <saitology9@gmail.com> 3 months ago

On 7/3/2024 12:59 PM, Luc wrote:
> I know y'all gonna hate this question because I'm not showing much code,
> but I am really more interested in concepts than code.
> 
> I made a package. It's supposed to be a megawidget. I haven't snitted it
> yet. I can't snit it without understanding where I am supposed to go
> with it. So here is the problem.
> 
> package require giggles
> 
> set of $::w.outerframe
> frame $of -height 100
> pack $of -fill both -expand 1
> 
> set gg $of.giggles
> ::giggles::giggles $gg -guifont "Arial 14" -geometry pack
> pack $gg -fill both -expand 1
> 
> And it works. The prototype megawidget is inserted into my test parent
> application.
> 
> The problem is, commenting out the last 'pack' line makes no difference.
> The megawidget still shows. (Also, funny that apparently it's redundant
> but nothing clashes.) And of course that is not standard widget behavior.
> 

The reason giggles gets displayed automatically is because it has no 
layering between gg and its internal widgets.  I think you can easily 
solve this by including an additional frame containing your megawidget 
with all of its sub widgets packed as you want.  Then you let the user 
of your megawidget do the final packing.  This way they giggles 
instances won't automatically show and your users remain in charge of 
their visibility.


Click on article to view all threads in comp.lang.tcl
Re: How do I pack a megawidget?
Posted by Rich <rich@example.invalid> 3 months ago

Luc <luc@sep.invalid> wrote:
> I know y'all gonna hate this question because I'm not showing much code,
> but I am really more interested in concepts than code.
> 
> I made a package. It's supposed to be a megawidget. I haven't snitted it
> yet. I can't snit it without understanding where I am supposed to go
> with it. So here is the problem.
> 
> package require giggles
> 
> set of $::w.outerframe
> frame $of -height 100
> pack $of -fill both -expand 1
> 
> set gg $of.giggles
> ::giggles::giggles $gg -guifont "Arial 14" -geometry pack
> pack $gg -fill both -expand 1
> 
> And it works. The prototype megawidget is inserted into my test parent
> application.
> 
> The problem is, commenting out the last 'pack' line makes no difference.
> The megawidget still shows. (Also, funny that apparently it's redundant 
> but nothing clashes.) And of course that is not standard widget behavior.
> 
> Of course, I am packing everything in the megawidget. But if I don't, 
> then what? I can't just leave it hanging because if I do, then the 
> author of the parent widget will have to inspect the code of the 
> megawidget to figure out what he is supposed to pack to get it all 
> working which, again, is not standard widget behavior, it's actually
> pretty stupid. I have to expose something. Something that will take
> the 'pack' command from the parent application and make the entire 
> megawidget come together, with all of its components.
> 
> How do I do that?

You have at least two choices:

1) You document "giggles" to require a user of "giggles" creates a 
frame widget, and passes it into your "giggles" call, and you pack 
everything into that frame.  It looks, from the above code, like this 
is the option you have chosen.  But, this makes your megawidget 
different from the Tk native widgets.  You don't pass a "frame" to 
"text" and have "text" build a "text widget" inside that frame.

2) You redesign "giggles" that it receives a "window path name" and it 
creates a frame of that path name, and then packs everything that makes 
up a "giggles" into that new frame, and then "giggles" returns the name 
of that frame. This makes the megawidget more native like, because you 
pass a name of a window that does not yet exist, and the "giggles" call 
creates a window of that name.

#2 is also the part where Snit helps, because left to its own devices, 
that frame is just a regular Tk frame, and the only configure/cget 
options it understands are those for frames.  Snit lets you build this 
as a window heirarchy (this will only look right with a monospaced 
font, and note, I'm making this up):

gframe
     |--label
     |--inner frame
     |            |--text widget
     |            |--scrollbar
     |--label

What Snit helps with is allowing "gframe" to be the name of your window 
(.something.something.gframe) and also a command for "driving" the 
widget.  Snit lets you redirect calls to .abc.gframe for say "insert" 
to actually be delivered to the buried text widget 
(.abc.gframe.inner frame.text widget)[1] so that users can call:

..abc.gframe insert end "This is extra text"

And have it really call:

..abc.gframe.inner frame.text widget insert end "This is extra text"

Without you having to manually do the command renamings necessary to 
make that magic happen.



[1] Yes, Tk window paths can't have spaces in reality -- this is just 
an explanation of one of the things Snit does for you if you use it to 
build a megawidget.

Click on article to view all threads in comp.lang.tcl