Author: René Zaumseil <[email protected]>
State: Deferred
Type: Project
Vote: Done
Created: 26-Nov-2019
Post-History:
Keywords: Tk
Tcl-Version: 9.0
Tk-Branch: tip-556
This tip is deferred because I could not find a sponsor for it.
Abstract
This tip proposes to add the following oo class widget commands and functions to deal with options at the class and object level. A C function interface allows creation of new oo class like widgets.
New oo::class like widgets
::tko::toplevel pathName ?option value? ..
::tko::frame pathName ?option value? ..
::tko::labelframe pathName ?option value? ..
The new widgets will contain the same functionality like the original tk widgets. They are oo:class's and it is possible to add,change and delete methods and options dynamically. The widgets could also be used as oo superclass's.
The interface functions to build new widgets in C are described in
tko.3.md
.
Tcl class creation
::oo::class create ooclass { ::tko initclass }
The tko initclass function create on oo class with option handling.
::oo::class create widgetclass { ::tko initfrom tkoclass }
The tko initfrom function use tkoclass as superclass.
::oo::class create widgetclass { ::tko initwrap widget readonlyoptionlist ?commanlist? }
The tko initwrap function wraps an existing tk widget in an oo class widget.
Class functions
To provide dynamic option management at class level exists a ::tko function.
::tko initclass
::tko initfrom ?superclass?
::tko initwrap widget readonlyoptionlist ?commandlist?
::tko eventoption
::tko optiondef classname ?-option definitionlist? .. ?body?
::tko optiondel classname ?-option? ..
::tko optionget classname ?-option? ..
::tko optionhide classname ?-option? ..
::tko optionshow classname ?-option? ..
A detailed description can be found in
tko.n.md
.
Widget methods
To manage options on object level exists an _tko method.
my _tko optionadd -option definitionlist ?body?
my _tko optiondel -option ..
my _tko optionhide -option ..
my _tko optionshow -option ..
A detailed description can be found in
tko.n.md
.
Option definitionlist
In the definitionlist description below an entry with name flags can contain a combination of the following letters:
- "r" the option is readonly and can only be set on creation
- "h" The option is hidden from use in cget and configure methods.
The definitionlist can have one of the following forms:
- {-synonym flags}
Description of an synonym option. When -option is set then instead the provided -synonym option will be set.
- {dbname dbclass default flags}
Description of an option. If dbname or dbclass is not empty then the values will be used to search for an default option value in the option database. The search will need a Tk_Window and therefore this definition can only be used in an widget class. If both value are empty then the option definition can be used in an normal class create with tko initclass. default is the default value if no value can be found in the option database.
Rationale
Currently there is no megawidget support core package. These tip will go some steps in this direction. With widgets as oo::class's we can easyly extent existing widgets, just use it as a superclass. The provided functions and methods allow add, delete and changing of options at class and object level. The implementation can be used in C and in Tcl.
Implementation
A patch implementing these changes is available in the fossil repository in the tip-556 branch.
Documentation
Documentation is available in md-Format in the .../doc/ directory.
C interface
C-source interface files are in .../generic/tko/
. No functionality is currently exported.
tkoWidget.h
Tko_Widget C functions and definitions.The Tko_Widget*() functions should be available for extensions.
The Tko_Widget* enum and structures should be included in file "tk.h"
C sources
C-source code files are in .../generic/tko/
. The new files are added to the makefiles. The calls to the initialization functions are added in tkWindow.c
tkoFrame.c
tko::frame, tko::labelframe and tko::toplevel implementationtkoWidget.c
Tko_Widget function implementation
Tests
Test files are available in the .../tests/tko/ directory.
tkoFrame.test
tests from the tk frame.test file plus additional oo::class related tests
To compare the speed of the new widgets you can run the test frame-30.1. It will compare normal tk, ttk and tko widgets.
Examples
Ready to run tclkit binaries for Linux, Windows and Mac can be found here
#
# Configurable object
#
oo::class create A {
::tko initclass
}
A create a1
a1 configure ==>
# Add class option
::tko optiondef A -o1 {o1 O1 v1 {}} {set tko(-o1) x}
A create a2
a2 configure
==> {-o1 o1 O1 v1 v1}
# Add object option
oo::define A method mycmd {args} {my {*}$args}
a2 mycmd _tko optionadd -o2 {o2 O2 v2 {}} {variable tko; set tko(-o2) x}
a2 configure
==> {-o1 o1 O1 v1 v1} {-o2 o2 O2 v2 x}
#
# Wrap an existing widget
#
oo::class create B {
::tko initwrap frame {-class -container -colormap -visual} {}
}
B .b
lindex [.b configure] 0
==> {-background background Background SystemButtonFace SystemButtonFace}
#
# Create a new widget class.
#
oo::class create C {
::tko initfrom ::tko::frame
constructor {args} {next {*}$args}
destructor {next}
method mycmd {args} {my {*}$args}
}
# Hide all inherited frame options
::tko optionhide C {*}[::tko optionhide C]
::tko optionshow C
==> -class -visual -colormap -container -borderwidth ...
C .c
.c configure
==>
# Add a new option
oo::define C method -o1 {} {puts $tko(-o1)}
::tko optiondef C -o1 {o1 O1 v1 {}}
::tko optionhide C
==> -o1
# Add another option
::tko optiondef C -o2 {o2 O2 v2 {}} {puts $tko(-o2)}
::tko optionhide C
==> -o1 -o2
# Add options at object level:
C .c1
.c1 mycmd _tko optionadd -o3 {o3 O3 v3 {}} {my variable tko; puts $tko(-o3)}
.c1 configure
==> {-o1 o1 O1 v1 v1} {-o2 o2 O2 v2 v2} {-o3 o3 O3 v3 v3}
# Show all frame options again
.c1 mycmd _tko optionshow {*}[.c1 mycmd _tko optionshow]
llength [.c1 configure]
==> 24
# Intercept options
oo::define C method -width {} {
puts "[my cget -width]->$tko(-width)->[set tko(-width) 100]"
}
.c1 configure -width 1
==> 0->1->100
# Use option database for styles:
option add *background red
grid [tko::frame .f] -sticky nesw
grid [label .f.l -text abc]
grid columnconfigure . 1 -weight 1
option add *background blue
tko eventoption
Discussion
See also discussion at the wiki.
Open issues
Export functionality from
tkoWidget.h
The following function from
tkoWidget.c
should be an tcl oo function (tcl rfe 3ff0e9c37): Tcl_Obj *Widget_GetClassName(Tcl_Interp * interp,Tcl_Object object)Is it necessary to translate the documentation into man format?
It is currently not possible to use unique abbreviations of class method names p.e. "frame .f; .f conf" A workaround would be to add all those method names. May be this can be solved in tcl oo directly?
An oo widgets needs more time to create then an normal tk widget, nearly the same time to call functions and less time to destroy. But the time is comparable to tko widgets (see in tests/tko/tkoFrame.test test frame-30.1). This needs some investigation. The authors current assumption is the time is spent in calling "my -option" methods from inside C. Currently Tcl_EvalObjv() is used. Are there better ways?
The implementation of tko::toplevel has one hack. In tkWinMn.c tkWinWM.c will call TkInstallFromMenu() from file tkFrame.c for toplevels. Inside these function a struct Frame and memeber menuName will be used. We have to ensure that our structure has the same form as Frame. Therefore we place some dummy arguments in the structure.
Alternatives
See tip-558 and tip-560 here.
Use one of the existing megawidgets implemented in tcl.
Copyright
This document has been placed in the public domain.