ConfigSpecs(3pm)

✨ ConfigSpecs β€” the Tk::ConfigSpecs manual, but make it cute ✨

okay bestie, pull up a chair 🫢 this is Tk::ConfigSpecs from the Perl docs, and it's literally all about defining how configure behaves for composite widgets. yes. that's the whole vibe. let's get into it πŸ’…


🌸 NAME 🌸

Tk::ConfigSpecs β€” Defining behaviour of configure for composite widgets. periodt. πŸ’–


✨ SYNOPSIS ✨

sub Populate
{
 my ($composite,$args) = @_;
 ...
 $composite->ConfigSpecs('-attribute' => [ where,dbName,dbClass,default ]);
 $composite->ConfigSpecs('-alias' => '-otherattribute');
 $composite->ConfigSpecs('DEFAULT' => [ where ]);
 $composite->ConfigSpecs($subwidget->ConfigSpecs);
 ...
}

$composite->configure(-attribute => value);

πŸ’œ DESCRIPTION πŸ’œ

The whole goal here? Make a composite widget's configure method look as much like a regular Tk widget's configure as it possibly can. iconic behaviour, honestly. πŸ‘‘

If you want the full description of that behaviour, go peek at Tk::options.

And to make that happen, the attributes that the composite as a whole accepts need to be defined. no cap.


πŸŽ€ Defining the ConfigSpecs for a class. πŸŽ€

Usually a widget is gonna have one or more calls that look exactly like this:

$composite->ConfigSpecs(-attribute => [where,dbName,dbClass,default]);

...and they live in its Populate method. When ConfigSpecs gets called this way (with arguments, bestie, with actual arguments), those arguments get used to construct β€” or to augment/replace β€” a hash table for the widget. πŸ’«

Heads up: you can pass more than one -option=>value pair in a single call. slay.

Also important: dbName, dbClass and default are only used by ConfigDefault (described further down πŸ‘‡) or to respond to 'inquiry' configure commands.

Now, where β€” it may be either one single value from the list below, or a whole list of such values wrapped in []. your choice, main character.

The currently permitted values of where are:

  • 'ADVERTISED' β€” Apply configure to advertised subwidgets. πŸ“’
  • 'DESCENDANTS' β€” Apply configure recursively to all descendants. the whole family tree. 🌳
  • 'CALLBACK' β€” Setting the attribute does Tk::Callback->new($value) before storing it in $composite->{Configure}{-attribute}. This is the appropriate move for -command => ... attributes that the composite handles itself and doesn't forward to a subwidget. (Example time: Tk::Tiler has -yscrollcommand so it can have a scrollbar attached. 🎒)

This may also be the first of several 'validating' keywords (think font, cursor, anchor and friends) that core Tk makes special for C code. πŸ‘€

  • 'CHILDREN' β€” Apply configure to all children. (Just so we're clear: children = the immediate descendants of a widget.) 🧸
  • 'METHOD' β€” Call $cw->attribute(value)

This is the most general case, fr fr. You just have a method of the composite class with the same name as the attribute. That method can do whatever validation it wants and have literally any side-effects you like. (Tho ngl, for more complex side-effects it's probably worth 'queueing' using afterIdle. πŸ’…)

  • 'PASSIVE' β€” Simply store the value in $composite->{Configure}{-attribute}.

This form is also a super useful placeholder for attributes you currently only handle at create time. 🫢

  • 'SELF' β€” Apply configure to the core widget (e.g. Frame) that's the basis of the composite. (This is the default behaviour for most attributes, which is what makes a simple Frame behave the way you'd expect.) ⚠️ But note β€” once you've specified ConfigSpecs for an attribute, you must explicitly include 'SELF' in the list if you want that attribute to apply to the composite itself. this avoids nasty infinite recursion problems. we do not want that. πŸ™ˆ
  • $reference (blessed) β€” Call $reference->configure(-attribute => value)

A common case is where $reference is a subwidget. 🧚

$reference may also be the result of

Tk::Config->new(setmethod,getmethod,args,...);

The Tk::Config class is what implements all the keyword types above. It has configure and cget methods, so higher-level code can always just call one of those methods on an object of some kind. easy. ✨

  • hash reference β€” Defining:
$cw->ConfigSpecs(
        ...
        -option => [ { -optionX=>$w1, -optionY=>[$w2, $w3] },
                        dbname dbclass default ],
        ...
        );

So $cw->configure(-option => value) actually does

$w1->configure(-optionX => value);
$w2->configure(-optionY => value);
$w3->configure(-optionY => value);

πŸ”₯

  • 'otherstring' β€” Call
$composite->Subwidget('otherstring')->configure( -attribute => value );

Okay so this one is here for backward compatibility with Tk-b5, but honestly? it's probably better to just use the subwidget reference directly. The only case for keeping this form around is to allow an extra layer of abstraction β€” like, maybe having a 'current' subwidget β€” and that's unproven. πŸ™ƒ

  • Aliases β€” ConfigSpecs( -alias => '-otherattribute' ) is what makes -alias equivalent to -otherattribute. For example, these aliases:
-fg => '-foreground',
-bg => '-background'

come provided automatically (if they weren't already specified). πŸ’–


πŸ¦‹ Delegating all options of a widget class to a subwidget πŸ¦‹

$composite->ConfigSpecs($subwidget->ConfigSpecs);

The above generates a list of composite ConfigSpecs arguments β€” one for each valid option in $subwidget's class β€” and delegates said option to $subwidget. Cute, right? πŸŽ€

See Tk::Widget and the widget method ConfigSpecs.

⚠️ And listen: duplicating composite ConfigSpecs and widget ConfigSpecs keys will yield undefined results. don't do it bestie.


🌈 Default values 🌈

When the Populate method returns, ConfigDefault gets called. Which calls

$composite->ConfigSpecs;

(with no arguments, babes) to return a reference to a hash. Entries in that hash take the form:

'-attribute' => [ where, dbName, dbClass, default ]

ConfigDefault ignores 'where' completely (and the DEFAULT entry too, bestie, don't even worry about it) and checks the 'options' database on the widget's behalf. And if an entry is present matching dbName/dbClass:

-attribute => value

...gets added to the list of options that new will eventually apply to the widget. Same energy the other way: if there's no match and default is defined, then this default value gets added. πŸ’«

Alias entries in the hash are used to convert user-specified values for the alias into values for the real attribute. πŸ”


⭐ New()-time configure ⭐

Once control returns to new, the list of user-supplied options β€” augmented by those from ConfigDefault β€” gets applied to the widget using the configure method below. πŸ‘‡

Widgets are most flexible and most Tk-like if they handle the majority of their attributes this way. fr. πŸ’…


πŸ’€ Configuring composites πŸ’€

Once all of the above has happened, calls of the form:

$composite->configure( -attribute => value );

should behave like any other widget as far as end-user code is concerned. no notes. πŸ‘‘

configure will be handled by Tk::Derived::configure like this:

$composite->ConfigSpecs;

...is called (with no arguments) to return a reference to a hash. Then -attribute is looked up in that hash. And if -attribute is not present in the hash, then 'DEFAULT' is looked for instead. (Aliases get tried as well, and they cause redirection to the aliased attribute. πŸ’«) The result should be a reference to a list like:

[ where, dbName, dbClass, default ]

At this stage only where is of interest β€” it maps to a list of object references (maybe only one, maybe many) for each one:

$object->configure( -attribute => value );

...is evaled. πŸ”₯


πŸ“ Inquiring attributes of composites πŸ“

$composite->cget( '-attribute' );

This is handled by Tk::Derived::cget in a similar manner to configure. At present, if where is a list of more than one object it gets ignored completely and the "cached" value in

$composite->{Configure}{-attribute}.

is returned. that's it, that's the tea. β˜•


😭 CAVEATS 😭

The -background and -foreground option values are automatically propagated down to all of the composite widget's children. And sometimes that's just... not what you want? especially if some subwidgets should use their own colour schemes, either via explicit options or via option database definitions. πŸ™ˆ

If that's the case for you, then just add:

-foreground => 'SELF',
-background => 'SELF',

to ConfigSpecs. fixed. πŸ’…

Also, full transparency: it's the author's intention to port as many of the "Tix" composite widgets as make sense. The mechanism described above may have to evolve in order to make that possible β€” although now that aliases are handled, the author thinks the above is sufficient. we'll see bestie 🫢


πŸ’– SEE ALSO πŸ’–

  • Tk::composite
  • Tk::options
  • Tk::Widget

okay and that's the whole page!! πŸŽ€βœ¨ this one came from the Perl docs, perl v5.40.1, dated 2025-04-13, and honestly? she ate. go forth and configure your composites, bestie β€” you've got this. mwah πŸ’‹πŸ’–πŸ¦‹

πŸ“¦ where this page comes from