Tips On Creating Tcl/Tk-based Component

We usually need to make new GUI components using Tcl/Tk. It is because Tcl/Tk provides an easy GUI scripting compared to C++ . We can make user friendly interface easily complete with the mouse and keyboard event handling.

There are functions should be implemented on Tcl/Tk-based Components. The list can be seen in the source code of the bridge-tcl.tcl and bridge-tk.tk :

proc attribute_names_in_category {cat} { return [list] }
proc attribute_names {} { return [list] }
proc pin_names {} { return [list] }
proc relationship_names {} { return [list] }
proc bus_names {} { return [list] }
proc accessor_names {} { return [list] }
proc attribute_value {name} { return "" }

However, implementing each of them could took plenty of resource to write the same thing over and over. There are some point that can be optimized on each function. We can store attributes in an array that has word as the key. For example :

#declare variable
variable attributes
#set variable initial values
set attributes(height) 320
set attributes(width) 240

And then when we are going to used it, instead of using if else control like this :

proc set_attribute_value {attr value} {
global attributes

if {$attr == "width" } {
set attributes["width"] $value
return "ok"
}
if {$attr == "height" } {
set attributes["height"] $value
return "ok"
}
return "not_found"
}

we can use the search command to find the right index :

#contains list of attributes names
set attributes_names [list "width" "height" ]

proc set_attribute_value {attr value} {

global attributes attributes_names

if { [lsearch -exact $attributes_names $attr] >= 0} {
set attributes($attr) $value
return "ok"
}
return "not_found"
}

By that, the code will be shorter and more efficient. We can change the code easily when the new attributes is added, just need to add in the attributes_names list the name of the new attribute.

For retrieving the list of attributes name is easier too. Instead of writing :

proc attribute_names_in_category {cat} {
if { $cat == "setting" } then  {
return [ list "width" "height" ]
}
return [list]
}

We just need to write :

proc attribute_names_in_category {cat} {
global attributes_names
if { $cat == "setting" } then  {
return $attributes_names
}
return [list]
}

So when the new attributes added, no change has to be made on this part. Providing a better consistent code. The search is also implemented on retrieving the value of desired attribute.

This optimization using list of available names of attributes can be implemented too on the list of available pins and buses. Using list of names that can be searched through. I hope it will be useful.

Just reminder for myself and you, the keyword "global" should be written on the beginning of the procedure, because instead of creating a new local variable, it will try to find the global variable outside the procedure. The "global" keyword is needed to share the same variable reference across the code.