TIP 556: Add oo like widgets to Tk

Login
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:

The definitionlist can have one of the following forms:

Description of an synonym option. When -option is set then instead the provided -synonym option will be set.

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.

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

Tests

Test files are available in the .../tests/tko/ directory.

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

Alternatives

Copyright

This document has been placed in the public domain.