Skip to main content

Posts

Showing posts from 2012

gnocl::cairo instropection

The gnocl::cairo command is not intended to be some form of canvas object, but a means of drawing onto images for display on screen used perhaps in the creation of widgets or images. Bearing in mind the relatively small number of actions required for this task, it's reasonable to assume that the overhead of making multiple calls to the gnocl::cairo command is a worthwhile compromise. In response to the problem of how to get the extents of rendered text back from Cairo I came up with the solution highlighted in the following code: set pb(1) [gnocl::pixBuf new -width 256 -height 256] set myString "Peter Piper picked a peck of pickled peppers." set actions "     select_font_face {Sans normal bold}     set_font_size 15.0     text_extents $myString"   array set extents [gnocl::cairo $pb(1) -actions $actions] In the example above, the following values were obtained. extents(height)    = 14.0 extents(width)     = 320.0 extents(x_advance) = 322.0 extents(x_bearing) = 1.

New Pacakge gnocl::cairo

The process of tidying up the development code prior to a release increment has led me to weeding out some unused or difficult to maintain functions. One of these was the cairo.c module. This was experimental block of code which was an offshoot of developing the gnocl::splashscreen widget.  But, with the transition to Gtk3 on the horizon, all drawing operations will be performed by Cairo and so I thought that it was a good opportunity to make use of some of that old code. Hence, a new package. There's still way to go before it's finished and I'm still working on drawing to pixbufs but things are looking good. Here's the syntax for the command: gnocl::cairo <drawable-id> -actions <script> Where the script is simply a list of cairo operations.  Here's a snippet from my test script. set actions " # {sample set-line-join} set_line_width 40.96 move_to {76.8 84.48} rel_line_to {51.2 -51.2} rel_line_to {51.2 51.2} set_line_join miter stroke move_t

gnocl::button -align

Yesterday I was playing with the Glade interface designer and noticed that the UI included buttons with icons whose contents were left aligned. The Gnocl default is centred and I thought that a gnocl::button -align option might be useful. The button icon and label sub-widgets are in turn held within a GtkHBox and positioned by a GtkAlignment container. It was a relatively simple task to create the code to add the alignment option. For the present, plain text will remain centred. Here's my test script. # test-buttonAlign.tcl #!/bin/sh # the next line restarts using tclsh \ exec tclsh "$0" "$@" package require Gnocl proc gnocl::buttonBox { {str <<TITLE>>} b} {     set box(1) [gnocl::box -orientation vertical -padding 0 ]     set but(1) [gnocl::button -icon %#Remove -text $str -align centre]     set box(2) [gnocl::box -orientation vertical -padding 0 ]     $box(1) add $but(1) -fill {1 1}     $box(1) add $box(2)     $box(2) add $b     $box(1) configure -

Getting Closer to Gnocl 0.9.97

Over the past few months a lot of modifications have been made to the development code to warrant a release increment albeit just by 0.0.01! Before this happens, it would be useful to hear from any (?) Gnocl users out there who are using the package and what they expect to see. Foremost, some feedback from users working with glade/builder files would be useful. The code for loading the xml files is something of a load and it might be more suited to branching out into a separate Gnocl family package. What would also be useful is any bug or performance reports from users. Many thanks...

gnocl::tooltip trigger

Did a little more to the demo script to show how the "trigger" sub-command actually works. # test-tooltip.tcl #! /bin/sh/ #\ exec tclsh "$0" "$@" package require Gnocl set lab(1) [gnocl::label -text "TANNOY" ] set lab(2) [ gnocl::label -text "CAMPER 1" -tooltip " Hi-Di-Hi!!! " ] set lab(3) [ gnocl::label -text "CAMPER 2" -tooltip "quiet" ] set box [gnocl::box -orientation  vertical ] $box add $lab(1) -expand 1 -fill {1 1} $box add $lab(2) -expand 1 -fill {1 1} $box add $lab(3) -expand 1 -fill {1 1} set main [gnocl::window -title "Rise-n-Shine" -child $box -setSize 0.125] #--------------- # create custom tooltip #--------------- # proc myToolTip {} {         # create custom tooltip window     set lab [gnocl::label -text " Ho-Di-Ho " -xPad 10]     set im [gnocl::image -image %#About ]     set box [gnocl::box -borderWidth 1 -shadow in]         $box add $im     $box add $lab     # keep cop

Entry widget undo/redo in Tcl.

Hacked together a simple proof of method script to implement Undo/Redo functionality for the gnocl::entry widget. There are some improvements that can be done such as overloading the basic entry widget to allow undo/redo as a widget command. Keyboard bindings are fully there too. I'll take a look at these at a later time. #--------------- # entryundo($ent)Redo.tcl #--------------- # Created by William J Giddings # October, 2012 #--------------- # Description: # Demonstrates simple entry undo($ent)/redo functionality. #--------------- # Notes: # cd /Desktop/GnoclEdit_2/undo($ent)er/wjgstuff # # This version has a single buffer to show edit history # #--------------- # basic Tcl/Gnocl Script #! /bin/sh/ #\ exec tclsh "$0" "$@" package require Gnocl #--------------- # #--------------- # proc entry:resetUndo {ent } {     global undo idx     set idx($ent) -1     set undo($ent) "" } #--------------- # #---------------

Customized Tooltip Windows

Gtk allows the user to create custom tooltips which might include mixed items such as icons, images and text. The recent addition of the gnocl::tooltip command to allows such things to be done. The following test script shows how its done. # test-tooltip.tcl #! /bin/sh/ #\ exec tclsh "$0" "$@" package require Gnocl set lab(1) [ gnocl::label -text "LABEL 1" -tooltip "I'm label #1" ] set lab(2) [ gnocl::label -text "LABEL 2" -tooltip "I'm label #2" ] set box [gnocl::box] $box add $lab(1) -expand 1 -fill {1 1} $box add $lab(2) -expand 1 -fill {1 1} set main [gnocl::window -title main -tooltip "HELLO WORLD!" -child $box -setSize 0.25] #--------------- # create custom tooltip #--------------- # proc myToolTip {} {         # create custom tooltip window     set lab [gnocl::label -text HIDIHI -xPad 10]     set im [gnocl::image -image %#About ]     set box [gnocl::box -borderWidth 1 -shadow in]         $box add $i

Text Zooming

The widgets in the Tk package have the really nifty sub-command cget which enables the settings for widget options to be extracted. Implementation of cget functionality within Gnocl is patchy for the most part as in most cases custom code needs to be added to extract settings. I've just added cget -baseFont for the text widget. This means that simple text zooming can be implemented in conjunction with the -onScroll option. #--------------- # text widget zoom #--------------- # arguments #    w    text widget id #    d    direction of scroll, ie up or down. #    s    state of keytboard modifiers, must be Ctrl+scroll to run. # returns #    nil proc TextZoom {w d s} {     if { [$w class] != "text" } { return -1 }     set fnt "[$w cget -baseFont]"     set fsize [lindex $fnt 1]   if {$s != 4} { return }   switch $d {       up { incr fsize 2 }       down {incr fsize -2 }       }     lset fnt 1 $fsize       eval $w configure -baseFont [list $fnt] }

gnocl::text new option -variable

All of the standard entry widgets have a -variable option much like those encountered in Tk. This means that setting the value of a widget will cause a named variable to contain a copy of this data. The idea of using the -variable option lies in the ease of setting application wide settings or the setting or obtaining  values from a data entry form. The only exception to this was the text widget. I've been working on a forms based dictionary and glossary edit library which needed something more than the standard gnocl::entry. After hacking around with Tcl scripts to gather data from a text widget I decided to work on the C-side of things. This required a little bit of tweaking of the C sourcecode which, as it would turn out, was an easier approach than scripting. It should be pointed out, however, that only plain unicode text will be copied. Any tags or invisible text will not be captured. Here's the test script I used to work through the implementation. #---------------

gnocl::label new option -resizable

If the label widget is used for well, labelling other widgets, the overall size of the label is pretty-well fixed and then only to a few number of words. But, the Gtk+ label is much more powerful than this. Because the widget is a container for pango text, its a really useful, high-speed alternative to the gnocl::text widget for the display of extensive pieces of text. Added to this, the use of pango markup, which is pretty well the same as a standard html string, makes run time formatting a something of a breeze.

gnocl::label new options

Just added two new options to the label widget, -mnemonicText and -mnemonicWidget. Whilst these titles are straight from the GtkWidget api, perhaps they need renaming before adding to the distribution. Basically, these options allow fields to be accessed using quick keyboard routes. Something that has been lacking to date. Here's the script that I'm experimenting with: #--------------- # test-mnemonic.tcl #--------------- #!/bin/sh #\ exec tclsh "$0" "$@" package require Gnocl proc labelEntry {str var} {     upvar $var v     set box [gnocl::box]     set ent [gnocl::entry -sizeGroup a]     set lab [gnocl::label -align right -widthGroup aa -mnemonicText $str -mnemonicWidget $ent]     $box add $lab     $box add $ent     return $box } set str(1) PRAJNA set str(2) KARUNA set str(3) MAITRI set box [gnocl::box -orientation vertical] $box add [labelEntry _Prajna str(1)] $box add [labelEntry _Karuna str(2)] $box add [labelEntry _Maitri str(3)] gnocl::window -child

Setting tree/list column header widget

Just added a new option to the gnocl::tree/gnocl::list columnConfigure sub-command to allow embedded widgets. #--------------- # test-columnWidget.tcl #--------------- #!/bin/sh #\ exec tclsh "$0" "$@" package require Gnocl set tree [gnocl::tree \     -types {string integer} \     -titles {"" "# of Legs"}] $tree add {} {Mamals Birds Bugs} $tree add 0 {{Cat 4} {Dog 4} {Human 2}}   foreach {paro pred} [$tree add 1 {Parrots Predator}] {}   $tree add $paro {{Cockatoo 2} {Amazone 2}} $tree add $pred {{Hawk 2} {Eagle 2}} $tree expand \     -path "1" \     -recursive 1 gnocl::window \     -title "Tree" \     -child $tree \     -defaultWidth 300 \ set but(1) [gnocl::button -text HIDIHI] $tree columnConfigure 1 -widget $but(1)

gnocl::text -- getSelectionBounds

Just added new command to the text widget functionality to retrieve the bounds of the text buffer selection. If there is no selection, then an empty string is returned, otherwise there is a list of four integers, in the form startRow startCol endRow endCol. #--------------- # test-selectionBounds.tcl #--------------- #!/bin/sh #\ exec tclsh "$0" "$@" package require Gnocl set txt [gnocl::text -wrapMode word] $txt configure -onButtonRelease {     puts [%w getSelectionBounds]     } $txt lorem     gnocl::window -child $txt -setSize 0.25

gnocl::setStyle -new command

Gtk regards many widget properties as part of a system theme and are called 'style properties' and are not generally accessible via the Gtk+ api. The defaults for the widget can be over-ridden during run time and the loading of a resource file is an example of this. An alternative route, one in which only single changes are intended, can be taken using the new gnocl::setStyle command. This takes three arguments, the specific widget name, the style property name and the value to be assigned.  By default the widget names are NULL strings and, at present, can only be set following widget creation. One useful trick is to name the widget with its own gnocl id. The following script and screenshot show the command at work. #--------------- # test-style.tcl #--------------- #!/bin/sh #\ exec tclsh "$0" "$@" package require Gnocl set ent(1) [gnocl::entry -name b1 -value "Gnocl"] set ent(2) [gnocl::entry -name b2 -value "Gnocl"] set ent(3) [gnocl::

gnocl::progress -visible * NOW WORKING

In the Gtk2+ Libs the "visible" property in GtkProgress widget is not implemented. In order todo this the commands gtk_widget_show and  gtk_widget_hide have to be called. Hitherto it was possible to set the gnocl::progresssBar -visible option but it would have no effect. This has now been remedied. It will respond as expected.

Working with application preferences using gnocl::keyFile

Its easy enough to load/save script settings as some form of serialization on an array, but what if we want to conform to Gtk+ standards and save settings as an *.ini file? The following script shows how this can be done. #--------------- # test-keyfile.tcl #--------------- # William J Giddings, 19/05/2012 #--------------- #!/bin/sh #\ exec tclsh "$0" "$@" package require Gnocl #--------------- # manipulate application preferences #--------------- # preferences stored in global two-dimensional array name "prefs" # array names are equivalent to the group/key pairings required for keyFile #--------------- # args #    cmd        one of load, edit, save #    keyfile    name of keyfile to load/save, ignored for edit # returns #   none #--------------- proc preferences {cmd {keyFile {} } } {  global prefs  switch $cmd {     load {         set kf [gnocl::keyFile load $keyFile]         set prefs(comment) [$kf get comment]                 foreach group [$kf get

pango markup functionality

The arrangement for creating markup strings from the contents of text widget is almost complete. I've just got to add some extra toolbar buttons for the remaining settings and then the job will be done! Here's a screenshot.

gnocl::toolbar cget

Did a little more work on the gnocl::toolbar to implement the cget function. Not fully implemented as any cget implementation needs a lots of wrapping to get the job done! All changes posted to SF in today's NB.

gnocl::text pango markup

Getting closer towards some working code. I've expanded the list of automatically created pango style text tags to include those which are possible using the GtkTextView widget. One nice feature in pango, ie using unique strikethrough colours isn't available as a text tag attribute. The fg/bg colours are restricted at the moment to red, green, blue, cyan, magenta, yellow, black, gray and white. Apart from the default theme font, the other two settings are serif and sans. Setting unique values for these would not be an impossibility, but these can be created on the fly as normal text tags in a Tcl script.  

Obtaining Pango Markup Strings -80% done!

Got this Tcl formatting pango markup strings based upon predefined tags in a gnocl::text widget. At the moment a core set of tags is intialized by setting the -markupTags option to '1'. Like many instances of machine produced code the markup strings are lengthy! But it works. When I have the time I'll look at implementing a C version of the proc an incorporating it into the gnocl sources. At that point it might be worth considering the creation of a new gnocl widget for the task as a separate package. #--------------- # obtain markup strings from gnocl::text object #--------------- # args: #    txt    gnocl text widget containing rich text # return #    string with suitable pango markups # notes: #    initialize preset markup tags in widget using the -markupTags 1 option proc gnocl:text_pango {txt} {     set str ""     for {set line 0} {$line < [$txt getLineCount]} {incr line} {         set char 0         while  {$char < [$txt getLineLength $line]} {        

Working on Tcl script to convert gnoc::text tags into pango markup strings.

Getting working pango strings from text widget contents is not a simple issue, the various Gtk/Gnome programming sites contain many references to the possibility but.. Ok, the purposes are different - pango is only for marking up short strings. I want, however to edit pango formatted gnocl::list/tree strings in my text editor. At the moment my solution is working, albeit with rather long, messy mark-up sequences. Why? Pango doesn't allow tags to be overlapped. For example: tag1On asdasd tag2On asdasdad tag1Off sasdasd tag2Off Would produce an error. This would have to be: tag1On asdasd tag2On asdasdad tag2Off tag1Off tag2On sasdasd tag2Off So far my solution has been to create markups for each character in a string. The next step is simplifying that string.

Substring markup

I find the Tcl string map subcommand very useful and use it quite extensively in text manipulation. Here's an example of where I wanted to highlight substrings within a piece of text using pango markup. #--------------- # test-substring-markup.tcl #--------------- #!/bin/sh #\ exec tclsh "$0" "$@" package require Gnocl #--------------- # search for str2 in str1, then add pango markup formatting #--------------- proc markup_substring {str1 str2 format} {     # add necessary quote marks around property values     set format [string map [list = =\" { } {" }] "$format "]     set str3 "<span $format>$str2</span>" ;#"     return [string map [list $str2 $str3] $str1 ] } set lab [gnocl::label] gnocl::window -child $lab -setSize 0.25 # set string text set str "how now brown cow" # markup first word set str [markup_substring $str brown "foreground=red weight=bold background=yellow"] # cascaded markup is po

Removed imageviewer reference in base distribution.

Whilst the GtkImageViewer widget is a pretty nice tool to use, its not built from default Gtk libraries and requires extra dependencies to be installed before successful compilation can be obtained. With this in mind, the gnocl::imageViewer command has been branched off into a package in its own right. This should enable most users to recompile with the minimal amount of fuss.

Removing widgets from gnocl::box containers

Hitherto it has been possible to add widgets to a box but not to remove them, perhaps for repacking or hiding. The addition of the remove command to the gnocl::box object will now allow this to be done.  Here's a demo script: #!/bin/sh # the next line restarts using tclsh \ exec tclsh "$0" "$@" package require Gnocl set title "Shared Buffer" set tb [gnocl::textBuffer] set tv(1) [gnocl::text -wrapMode word -buffer $tb] set tv(2) [gnocl::text -wrapMode word -baseColor #FDFDB3 -buffer $tb] $tv(1) lorem # create maincontainer set box(main) [gnocl::box \     -orientation vertical \     -align topLeft]     set box(texts) [gnocl::box \     -orientation vertical \     -children [list $tv(1)] \     -fill {1 1} \     -expand 1]  # create toolBar  set split 0  set toolBar [gnocl::toolBar]  $toolBar add widget [gnocl::toggleButton \     -variable split \     -text "Split" \     -onToggled {         if {$split} {             $box(texts) add $tv(2) -fill {

gnocl::menuItem: new option -data and new sub-command cget

I'm working on a script that requires popup menus to be built proceedurall and on-the-fly. As a result, there are a number of parameters that I want to send to the popup callback but without the expense of creating and managing global variables or namespaces. This is where the widget -data option comes in. It means that data strings can be conveniently grouped together with a widget, managed throught the Gtk libraries which is totally (hopefully!) secure. The following code-snipetts shows how it can be used.   #--------------- ## display popup menu #--------------- #\code proc doTagPopup {args} {         gnocl::setOpts [list a 1 b 2 c 3]     gnocl::setOpts $args         puts "a= $a b= $b c= $c"     puts "w = $w ; t = $t ; n =$n"         foreach {arg val} $args { puts "$arg = [set [string trimleft $arg -]]" }     #set matches OM|MANI|PADME|HUM|HRIH     if {$t == "buttonPress" && $b == "3" } {                 # these may need

Talk to me Linux!

Just hacked together a simple proc to read text strings aloud using the espeak Linux command. Its good fun. It also shows how useful the gnocl::setOpts command  can be. #--------------- # espeak.tcl #--------------- ## \file # File documentation. #\verbatim #!/bin/sh #\ exec tclsh "$0" "$@" #\endverbatim package require Gnocl ## # -f <text file> #       Text file to speak # -a <integer> #       Amplitude, 0 to 200, default is 100 # -g <integer> #       Word gap. Pause between words, units of 10mS at the default speed # -l <integer> #       Line length. If not zero (which is the default), consider #       lines less than this length as end-of-clause # -p <integer> #       Pitch adjustment, 0 to 99, default is 50 # -s <integer> #       Speed in words per minute, 80 to 390, default is 170 # -v <voice name> #       Use voice file of this name from espeak-data/voices # -w <wave file name> #       Write output to this WAV fi

gnocl::dialog new options

Just added -height, -width, -x and -y options to the gnocl::dialog widget.

gnocl::setOpts -new command

Sometimes I want to set a block of variables within procedure either as a set of defaults or as variables passed to a proc as options. Hitherto I've used a tcl proc to do this work but thought it high time to add this utility to the gnocl core. Ok, its not strictly graphics but it does make writing event handlers easier. Take the following for example: doTagPopup -w %w -t %t -n %n -b %b -x %X -y %Y -matches OM|MANI|PADME|HUM|HRIH The -w options can be used to create local variables. Here's a test snippet: proc test-setOpts {args} {      gnocl::setOpts $args     puts "$x $y $z"       gnocl::setOpts [list j 4 k 5 l 6]     puts "$j $k $l" } test-setOpts -x 1 -y 2 -z 3 In the first call the args string is parsed and values set en bloc. The leading '-' will be stripped away. In the second example, a paired list is given from which values will be set.

Getting text tag ranges

Completed code for returning a list of the ranges of a text tag within a gnocl::text widget. widgetId tag ranges tagName

Implmenting text tag popup menus

Here's a short script to show how to get popup menus appearing for text tag objects. #--------------- # texttag-popup.tcl #--------------- #!/bin/sh #\ exec tclsh "$0" "$@" package require Gnocl set txt [gnocl::text -wrapMode word] gnocl::window -child $txt -setSize 0.25 #--------------- # display popup menu #--------------- proc doTagPopup {args} {         foreach {arg val} $args { set [string trimleft $arg "-"] $val }     if {$t == "buttonPress" && $b == "3" } {                 # these may need runtime re-definition         proc doHello {} {puts hello}         proc doGoodBye {} {puts goodbye}                 set menu [gnocl::menu -title "menu" -tearoff 0]         $menu add [gnocl::menuItem -text "Hello" -onClicked doHello]         $menu add [gnocl::menuItem -text "Goodbye" -onClicked doGoodBye]         $menu popup $x $y                 #proc doHello {} {}         #proc doGoodBye {} {}         

Another simple error fixed -gnocl::dialog

The gnocl::dialog command has been throwing out a 'message-type' warning. The cause of this has now been removed.

gnocl::dialog -messy closure fixed

The glib warnings put to the console when the dialog is closed has now been fixed.

gnocl::dialog

Made some enhancements here today.  Added the Gtk "other" option  to the range of dialog types, i.e. no icon. But more significantly, implemented automatic setting of type to "other" if the -child option set. Hiitherto, the gnocl::dialog was simply a means of giving yes/no feedback. Now, however, it's more useful for the setting of parameters and other forms of settings. Here's a snippet from my current coding project which requires export to Abiword format. The following proc will build a dialog for the setting of vars. The code is not complete, but shows how the gnocl::dialog enhancements are working. #--------------- # set file export properties #--------------- # Args # # Return #--------------- proc abi:properties {} {     global metaData     global pageSetup         set nb [gnocl::notebook]     # file metadata     set box(1) [gnocl::box -orientation vertical]     foreach name [lsort [array names metaData]] {         $box(1) add [gnocl::labelEntry \    

gnocl::text serialization

The GTK libs include a means of serlizaing/deserializing the contents of a GtkTextBuffer but the documentation on how to craft such handlers is basically non-existent. There is one package OSXCART which will load save a buffer as an rtf which is often discussed but the process of building such handlers is cumbersome and need to be built into the gnocl sources themselves. The whole process is more speedily handled on the Tcl side using the various tag sub-commands which will provide all the necessary information. How does the process work? Each row and column of the text is parsed firsly for changes in tag states (ie on or off) and the for the text content. If a new tag is added, its name is kept in a list of applied tags. The text is then accumulated until a further tag state change occurs whereupon firstly the tag and then text changes are written an output string. The text accumulator is then reset to empty and so the process continues. If a tag is turned off, the reverse occurs; th

Release 0.9.96

Just uploaded the latest stable release to Sourceforge. It been some time since the last major release and a of enhancements have been made. For me the next milestone was implementing the recentFiles functionality available through Gtk+. This is working, although a lot more options and commands need to be implemented for the gnocl::recentManager widget. Having said that, though, I can see that bulk of the functionality would only be rarely used. Regular readers of this blog may have noticed that the posts have reduced over the past few months. This isn't due to any loss of interest in Gnocl, far from it! I've also been working on my own translation tools which, I have to say, is the basic fuel which keeps the development work going. Over the past four years or so that I've been working on Gnocl an awful lot of code has been added to the sources. Code that not only provide Tcl access to Gtk resources but provides a whole lot of advanced features which makes coding a breeze.