{"id":26895867,"url":"https://github.com/mittelmark/oowidgets","last_synced_at":"2026-01-08T08:36:48.852Z","repository":{"id":144633179,"uuid":"615977100","full_name":"mittelmark/oowidgets","owner":"mittelmark","description":"Megawidget creation package using TclOO","archived":false,"fork":false,"pushed_at":"2025-03-06T07:49:09.000Z","size":992,"stargazers_count":2,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-06T08:32:40.719Z","etag":null,"topics":["megawidget","tcl","tcltk","tk"],"latest_commit_sha":null,"homepage":"https://wiki.tcl-lang.org/page/oowidgets","language":"Tcl","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mittelmark.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-03-19T08:50:07.000Z","updated_at":"2025-03-06T07:49:12.000Z","dependencies_parsed_at":null,"dependency_job_id":"ed1ff9d6-6dcc-4d71-9842-02b67e8828f8","html_url":"https://github.com/mittelmark/oowidgets","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mittelmark%2Foowidgets","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mittelmark%2Foowidgets/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mittelmark%2Foowidgets/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mittelmark%2Foowidgets/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mittelmark","download_url":"https://codeload.github.com/mittelmark/oowidgets/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246574850,"owners_count":20799221,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["megawidget","tcl","tcltk","tk"],"created_at":"2025-04-01T02:58:54.941Z","updated_at":"2026-01-08T08:36:48.824Z","avatar_url":"https://github.com/mittelmark.png","language":"Tcl","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![License](https://img.shields.io/badge/license-BSD3-lightgray.svg)](https://github.com/mittelmark/oowidgets/blob/main/LICENSE)\n[![Release](https://img.shields.io/github/v/release/mittelmark/oowidgets.svg?label=current+release)](https://github.com/mittelmark/oowidgets/releases)\n![Downloads](https://img.shields.io/github/downloads/mittelmark/oowidgets/total)\n![Commits](https://img.shields.io/github/commits-since/mittelmark/oowidgets/latest)\n\n# oowidgets\n\nPackage for creating megawidgets using TclOO (WIP).\n\n**Files:**\n\n- [oowidgets/oowidgets.tcl](oowidgets/oowidgets.tcl) - implementation\n- [oowidgets/pkgIndex.tcl](oowidgets/pkgIndex.tcl) - the package file\n- [samples/flash.tcl](samples/flash.tcl) - some sample code to create widgets\n\n**Links:**\n\n- [Tutorial](https://htmlpreview.github.io/?https://raw.githubusercontent.com/mittelmark/oowidgets/master/tutorial.html)\n- [Manual](https://htmlpreview.github.io/?https://raw.githubusercontent.com/mittelmark/oowidgets/master/oowidgets/oowidgets.html)\n- [Download](https://github.com/mittelmark/oowidgets/archive/refs/heads/main.zip)\n- [Wiki](https://wiki.tcl-lang.org/page/oowidgets)\n\n**Usage:**\n\n```\noowidgets::widget CLASSNAME CODE\n```\n\nThis will create a command classname where all letters are lower case. The\nclassname must have at least one uppercase letter to distinguish it from the\nTcl command name. Here an example:\n\n```\npackage require oowidgets\nnamespace eval ::flash { }\noowidgets::widget ::flash::Label {\n    constructor {path args} {\n        my install ttk::label $path -flashtime 200\n        my configure {*}$args\n    }\n    method flash {} {\n        set fg [my cget -foreground]\n        for {set i 0} {$i \u003c 10} {incr i} {\n            my configure -foreground blue\n            update idletasks\n            after [my cget -flashtime]\n            my configure -foreground $fg\n            update idletasks\n            after [my cget -flashtime]\n        }\n    }\n}\n```\n\nThis widget can be then used for instance like this:\n\n```\nset fl [flash::label .fl -text \"FlashLabel\" -flashtime 50 -anchor center]\npack $fl -side top -padx 10 -pady 10 -fill both -expand true\n$fl flash\n```\n\nFor more examples, including creating composite widgets, using mixins, see the [tutorial](https://htmlpreview.github.io/?https://raw.githubusercontent.com/mittelmark/oowidgets/master/tutorial.html)\n\nThere is a sample project which uses `TclOO` and `oowidgets` to create mega widgets. Here commands delivered in a package paul to demonstrate the different programming concepts inheritance, composition and mixins:\n\n- [paul::basegui :blue_book:](https://htmlpreview.github.io/?https://raw.githubusercontent.com/mittelmark/oowidgets/master/paul/basegui.html) - \n  base class to build Tk applications, [code](paul/basegui.tcl) \n- [paul::cbmixins :blue_book:](https://htmlpreview.github.io/?https://raw.githubusercontent.com/mittelmark/oowidgets/master/paul/cbmixins.html) - \n  mixin  classes  for the  `ttk::combobox`  to extend  its  functionality  like\n  filtering or history addition [code](paul/cbmixins.tcl) \n- [paul::dlabel :blue_book:](https://htmlpreview.github.io/?https://raw.githubusercontent.com/mittelmark/oowidgets/master/paul/dlabel.html) - \n  using inheritance to create changed `ttk::label` with dynamic fontsize,  [code](paul/dlabel.tcl) \n- [paul::history :blue_book:](https://htmlpreview.github.io/?https://raw.githubusercontent.com/mittelmark/oowidgets/master/paul/history.html) - \n  class to provide history facilities to applications,  [code](paul/history.tcl) \n- [paul::htext :blue_book:](https://htmlpreview.github.io/?https://raw.githubusercontent.com/mittelmark/oowidgets/master/paul/htext.html) - \n  composite widget providing a simple hypertext text widget to add help to Tk applications,  [code](paul/htext.tcl) \n- [paul::imedit :blue_book:](https://htmlpreview.github.io/?https://raw.githubusercontent.com/mittelmark/oowidgets/master/paul/imedit.html) - \n  show case using composition of composed widgets like `paul::labentry`, `tk.Text` and `ttk.Label` to create a larger megawidget,  [code](paul/imedit.tcl) \n- [paul::labentry :blue_book:](https://htmlpreview.github.io/?https://raw.githubusercontent.com/mittelmark/oowidgets/master/paul/labentry.html) - \n   using composition to combine a `ttk::label` and and `ttk::entry` widget\n   [code](paul/labentry.tcl) \n- [paul::notebook :blue_book:](https://htmlpreview.github.io/?https://raw.githubusercontent.com/mittelmark/oowidgets/master/paul/notebook.html) - \n   using inheritance to extend a `ttk::notebook` with new functionalities to label and to move tabs   [code](paul/notebook.tcl) \n- [paul::rotext :blue_book:](https://htmlpreview.github.io/?https://raw.githubusercontent.com/mittelmark/oowidgets/master/paul/rotext.html) - \n  read only text widget, useful for help pages for instance  [code](paul/rotext.tcl) \n- [paul::statusbar :blue_book:](https://htmlpreview.github.io/?https://raw.githubusercontent.com/mittelmark/oowidgets/master/paul/statusbar.html) - \n   composite widget based on a `ttk::frame`, a `ttk::label` and a `ttk::progessbar`,  \n   [code](paul/statusbar.tcl) \n- [paul::txmixins :blue_book:](https://htmlpreview.github.io/?https://raw.githubusercontent.com/mittelmark/oowidgets/master/paul/txmixins.html) - \n   mixin classes for the `tk::text` widget to extend its functions  [code](paul/txmixins.tcl) \n- [paul::tvmixins :blue_book:](https://htmlpreview.github.io/?https://raw.githubusercontent.com/mittelmark/oowidgets/master/paul/tvmixins.html) - \n   mixin classes for the `ttk::treeview` widget to extend its functions  [code](paul/tvmixins.tcl) \n\nPS: package name inspired by some wiki code about creating megawidgets with TclOO from which a lot of code was \"stolen\" ...\n\n**License:** BSD \n\n**Snit vs oowidgets**\n\nHere an example widget ins snit, the above mentioned `dlabel` a `ttk::label` with dynamic font-size adaptation, looks like this:\n\n![](images/dlabel.png)\n\nHere the snit code:\n\n```{.tcl}\npackage require snit\nnamespace eval dgw { }\nsnit::widget  dgw::dlabel {\n    component label\n    option -text \"Default\"\n    delegate method * to label\n    delegate option * to label\n    option -font \"\"\n    constructor {args} {\n        install label using ttk::label $win.lbl {*}$args\n        $self configurelist $args\n        if {$options(-font) eq \"\"} {\n            set mfont [font create {*}[font configure TkDefaultFont]]\n            $label configure -font $mfont\n            set options(-font) $mfont\n        }\n        pack $label -side top -fill both -expand yes -padx 10 -pady 10\n        bind  $label \u003cConfigure\u003e [mymethod ConfigureBinding %W %w %h] \n    }\n    method AdjustFont {width height} {\n        set cw [font measure $options(-font) $options(-text)]\n        set ch [font metrics $options(-font)]\n        set size [font configure $options(-font) -size]\n        # shrink\n        set shrink false\n        while {true} {\n            set cw [font measure $options(-font) $options(-text)]\n            set ch [font metrics $options(-font)]\n            set size [font configure $options(-font) -size]\n\n            if {$cw \u003c $width \u0026\u0026 $ch \u003c $height} {\n                break\n            }\n            incr size -2\n            font configure $options(-font) -size $size\n            set shrink true\n        }\n        # grow\n        while {!$shrink} {\n            set cw [font measure $options(-font) $options(-text)]\n            set ch [font metrics $options(-font)]\n            set size [font configure $options(-font) -size]\n            if {$cw \u003e $width || $ch \u003e $height} {\n                incr size -2 ;#set back\n                font configure $options(-font) -size $size\n                break\n            }\n            incr size 2\n            font configure $options(-font) -size $size\n        }\n    }\n    \n    method ConfigureBinding {mwin width height} {\n        bind $mwin \u003cConfigure\u003e {}\n        $self AdjustFont $width $height\n        after idle [list bind $mwin \u003cConfigure\u003e [mymethod ConfigureBinding %W %w %h]]\n    }\n}\n```\n\nAnd here the oowidget code:\n\n```{.tcl}\npackage require oowidgets\nnamespace eval paul { }\n\noowidgets::widget ::paul::Dlabel {\n    variable label\n    constructor {path args} {\n        my install ttk::label $path \\\n              -font [font create {*}[font configure TkDefaultFont]] \\\n              -text Default\n        my configure {*}$args\n        set label $path\n        bind  $label \u003cConfigure\u003e [callback ConfigureBinding %W %w %h] \n    }\n    method AdjustFont {width height} {\n        set cw [font measure [my cget -font] [my cget -text]]\n        set ch [font metrics [my cget -font]]\n        set size [font configure [my cget -font] -size]\n        # shrink\n        set shrink false\n        while {true} {\n            set cw [font measure [my cget -font] [my cget -text]]\n            set ch [font metrics [my cget -font]]\n            set size [font configure [my cget -font] -size]\n\n            if {$cw \u003c $width \u0026\u0026 $ch \u003c $height} {\n                break\n            }\n            incr size -2\n            font configure [my cget -font] -size $size\n            set shrink true\n        }\n        # grow\n        while {!$shrink} {\n            set cw [font measure [my cget -font] [my cget -text]]\n            set ch [font metrics [my cget -font]]\n            set size [font configure [my cget -font] -size]\n            if {$cw \u003e $width || $ch \u003e $height} {\n                incr size -2 ;#set back\n                font configure [my cget -font] -size $size\n                break\n            }\n            incr size 2\n            font configure [my cget -font] -size $size\n        }\n    }\n    method ConfigureBinding {mwin width height} {\n        bind $mwin \u003cConfigure\u003e {}\n        my AdjustFont $width $height\n        after idle [list bind $mwin \u003cConfigure\u003e [callback ConfigureBinding %W %w %h]]\n    }\n}\n\n```\n\nThe main differences using `oowidgets`:\n\n- no hull widget, just direct install of ttk::label without a frame\n- snit: `$self configurelist $args` - oowidgets: `my configure {*}$args`\n- all methods and options are automatically delegated to this main widget as there is no hull widget\n- not using an options array but `my cget`\n\nLet's give an other example, the famous readonly text widget, \n[here the snitcode](https://wiki.tcl-lang.org/page/Snit%27s+Not+Incr+Tcl) \nfrom the dark old times when no OOP was in the Tcl core reimplemented with oowidgets:\n\n```{.tcl}\npackage require oowidgets\nnamespace eval ::test { }\n::oowidgets::widget ::test::Rotext {\n    variable textw\n    constructor {path args} {\n        # we need the real widget (underline at the end)\n        set textw ${path}_\n        # Create the text widget; turn off its insert cursor\n        my install tk::text $path -insertwidth 0 -border 5 -relief flat\n        my configure {*}$args\n    }\n    # Disable the text widget's insert and delete methods\n    # to make this readonly even if the user writes text.\n    method insert {args} { } \n    method delete {args} { }\n    # programmatically we can still insert and delete ...\n    method ins {args} { $textw insert {*}$args  }\n    method del {args} { $textw delete {*}$args  }\n}\n```\n\n## CHANGES\n\n- 2024-12-29 : 0.4.0 Making it Tcl 9 ready\n- 2025-02-20 : 0.5.0\n    - new public method mixin to add classes to the current object\n    - new protected method option to create widget options\n    - new paul widgets imedit, labentry and treeview mixins\n    - sample application \"Lisi - graphics made easy\" to test the code extensively\n    \n## TODO's\n\n- delegate method?\n- component declaration?\n- snit compatibility?\n- Tcl 9 check (done)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmittelmark%2Foowidgets","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmittelmark%2Foowidgets","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmittelmark%2Foowidgets/lists"}