Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # Pantree documentation
- #
- # Purpose
- # Make nested paned windows simpler to setup and maintain.
- # Main pain point to address is the combined complexity from:
- # - Geometry specification
- # - Window addressing
- # - Content definition
- #
- # Design
- # There are two APIs:
- # - The pantree proc(edure)
- # - The recipe dict(orionary)
- #
- # Pantree proc parses a list specifying:
- # - Split orientation; v(ertical) or h(orizontal)
- # - Frame content; either a recipe or a pantree specification (recursion)
- # - Initial weights of frame content, increasing with a '+' postfix
- #
- # A recipe is a proc creating a window. Recipes are user defined.
- #
- # Example
- # This pantree specification:
- # h d+ {v t+ x}
- #
- # Results in a window layout looking something like this:
- # /-------\
- # |dddd|tt|
- # |dddd|tt|
- # |dddd|tt|
- # |dddd|--|
- # |dddd|xx|
- # \-------/
- #
- # Detailed explanation:
- # - User defined recipes: d=diagram, t=table, x=text
- # - Names may be any number of characters, but must not include characters [.+] or collide with split words [vh]
- # - 'h' is a split horizontally oriented. What follows is a list of nested pantree specifications
- # - 'd+' is a recipe of type 'd' (diagram), weight 2 (+ means 'plus 1')
- # - {h t++ x} is a pantree specification
- # - 'v' is a split vertically oriented
- # - 't++' is a recipe of type 't' (table), weight 3 (++ means 'plus 2')
- # - 'x' is a recipe of type 'x' (text), weight 1
- #
- # Window addressing starts at 1.
- # Vertical split count from left most window.
- # Horizontal split count from top most window.
- # When nesting pantree creates child windows addressable by 'x.y' where 'x' is the parent address and 'y' is the name of a the child window.
- #
- # In the example the addresses for frame contents are:
- # - d=1
- # - t=2.1
- # - x=2.2
- #
- # APIs
- #
- # pantree, procedure
- # pantree root spec
- #
- # root: Name of the panedwindow to create, e.g. ".my_pantree".
- #
- # spec: Pantree specification.
- #
- # Returns: Weight of spec. Used internally.
- #
- # recipe, dictionary
- # Key is the identifier for a recipe used in a pantree spec.
- # Value is a procedure taking a single window name argument.
- # An example of a recipe creating a button with text:
- # proc mybutton name { ttk::button $name -text hello }
- #
- # Deployment
- # It's recommended to copy pantree.tcl into your project, since:
- # - Pantree has no package dependencies.
- # - API and implementation is unlikely to change.
- # - Pantree can be loaded any number of times into the same source, under any namespace.
- #
- # Other
- #
- # 'Pantree' is short for 'tree of panned windows'
- #
- # A pantree can be made of a single user defined recipe
- #
- # It's perfectly fine having window weight ratios of 9/19, you just need many many '+'
- # Source code
- # Copyright Andreas Urban...
- # License MIT...
- # Documentation: See README.txt
- package require Tcl 8.6
- package require Tk
- proc pantree {root spec} {
- variable recipe
- set subs [lassign $spec weighted_content]
- set content [regsub -all \\+ $weighted_content {}]
- set weight [expr {[string length $weighted_content] - [string length $content] + 1}]
- if {$content == {v} || $content == {h}} {
- if {[llength $subs] < 2} { error {pantree spec has too few subs} }
- set address 1
- set split_type [dict get {v vertical h horizontal} $content]
- ttk::panedwindow $root -orient $split_type
- set sub_weights {}
- foreach sub $subs {
- set full_address "${root}.${address}"
- $root add $full_address -weight [pantree $full_address $sub]
- incr address
- }
- } elseif {[dict exists $recipe $content]} {
- [dict get $recipe $content] $root
- } else {
- error "content '$content' is invalid"
- }
- return $weight;
- }
- set recipe [dict create]
- # Test section
- wm geometry . 1920x1080; # 53%
- #wm geometry . 320x240; # 77%
- proc mybutton name {
- ttk::button $name -text {hello button}
- }
- proc mylabel name {
- ttk::label $name -text {hello label} -background orange
- }
- proc mytext name {
- ttk::label $name -text {hello text} -background green
- }
- dict append recipe t mytext
- dict append recipe l mylabel
- dict append recipe b mybutton
- pantree .my_pantree {h t+ {v l+ b}}
- place .my_pantree -relwidth 1.0 -relheight 1.0
- update
- puts "left width: '[winfo width .my_pantree.1]"
- puts "right width: '[winfo width .my_pantree.2]"
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement