Posts

Showing posts from 2013

gnocl::widget - new command 'attach'

Image
The menu widget allows for the organization of menu items into rows and columns. This can now be achieved using the 'attach' sub-command. Where required, menu items can be allow to span multiple rows or columns. The syntax for this this command is:

<widget-id> attach <menuitem-id> row col <options>

The possible options are -rowSpan (int) and -colSpan (int). 

Menu items are only expanded to fill actual rows and columns. So, if the last item requests a spacing of 2 rows, it will only be allocated the space required for its default rendering.

Modifications available in nightly build.

The following test code shows this in operation:

# test-menu-attach.tcl
#!/bin/sh
# the next line restarts using tclsh \
exec tclsh "$0" "$@"


package require Gnocl

set menu [gnocl::menu]

$menu add [gnocl::menuItem -text "%#New" -onClicked {puts "That's new"}]
$menu add [gnocl::menuSeparator]
$menu add [gnocl::menuItem -text "%#Quit" -onClick…

gnocl::tree & gnocl::list -highlighting columns

Image
Its possible to use Ctrl-F to launch an interactive search of entries contained within a tree or list view. Prior to any search, however, the column needs to be preselected. This mornings coding session has fixed a couple of issues within the gnocl core modules to enable this process to be done interactively under Tcl control. A single click on a cell in an view can now result in the column being preselected and highlighted. The following example script shows how its done. Get the nightly build for all the updates.

# test-me.tcl
#!/bin/sh
# the next line restarts using tclsh \
exec tclsh "$0" "$@"

package require Gnocl

set chn2indic:mappings(conjuncts) {
阿呵 āha
阿訶 āha
爍鉢 śva
悉吉利 skri
室佛 śva
地利 dhri
穆帝 mukta
佛囉 pra
帝利 tre
}

#---------------
# view and edit specific lists
#---------------
#
proc chn2indix:view:call_back {w c} {
    set last [$w cget -searchColumn]
    $w columnConfigure $last -background white
    $w columnConfigure $c -background grey
    $w configure -searchColumn $c

    # …

gnocl::tree boolean toggling -solved!

Image
Just completed the job of bringing the button toggling into the main code module. Took longer than I anticipated. The logic of it all was straight forward but, for some unknown reason, the Gtk+ libraries kept rejecting booleans typed variables for the value setting! So, these were set to uint and all works well!



gnocl::tree issues around toggling booleans

Image
The gnocl::tree and gnocl::list widgets automatically set tick boxes for columns identified as containing boolean data.  The present distribution (0.9.96) will cause a warning if a tree view is created, data added but no callback script set for the column containing the toggle item. Furthermore, the Gtk library code does not automatically toggle the cell widget anyway! This is something to add into the gnocl core and so I've added this to the 'todo' list.

So, when a script has the following type of widget declaration...

set tree [gnocl::tree \
-treeLines 1 \
-ruleHint 1 \
-types {string boolean} \
-titles {"Mapping Source" "Select"}]

Make sure that this configuration follows immeadiately...

$tree columnConfigure 1 -onToggled {
if { [%w get %p %c] } {
%w cellConfigure %p %c -value 0
} else {
%w cellConfigure %p %c -value 1
}
}



gnocl::text tag rollover effects

Image
Suprisingly, to me at least, tag rollover is not standard feature of the GtkTextTag. I've had Tcl a solution for some time now but always felt that this needed to be moved in to the package code itself. Whilst implementing rollover effects isn't difficult, matters would be made easier if the widget internals offered tag signals which tracked motion in and out of the tag rather than giving the simpler 'event' event binding. Well, its sorted now and the following test script illustrates how it works. There's a little more tweeking that can be done to the source code to allow similar changes to the rollover tag background colour. Finally,  runtime changes to the rollover colour setting (default = red) for the script will affect all instances of text widgets within a script.

# tagRollover.tcl

#!/bin/sh
# the next line restarts using tclsh \
exec tclsh "$0" "$@"

package require Gnocl

set text [gnocl::text ]

$text configure -rollOverColor red

# whenever the p…

gnocl::label -last of the signal bindings done!

Image
Just added the last two signal bindings for this widget.
-onActivateCurrentLink
-onActivateLink
Nightly build updated.

gnocl::label -more options added

Image
With the ability to copy text from the label widget being added, the widget can report a number of events. Those added today include: -onPopulatePopup, -onCopyClipboard, -onMoveCursor.

Available in today's 'nightly-build'.



Running the Gnome 'yelp' Help System from Tcl/Gnocl applications.

Image
I implemented some yelp help pages a while ago for my major app. After installing, however, the pages would load but not the graphics. When calling yelp all that needs to be passed is the directory containing all the pages, graphics, media etc. that are part of the help. To resolve this I resorted to launching a separate shell script to handle the help system. So, good-bye to:

set app(baseDir) $ENV(home)/help
exec yelp $app(baseDir)/help &

and hello to

exec my_yelp.sh &

Where my_yelp.sh is nothing more complex than

cd $HOME/help
yelp ./


Its a lot of work!

Image
Decided add to the ability to get more feedback from the gnocl package. The implementation of the cget command across the various widgets is still a little patchy and I've just added a new command, 'options' to all the widgets which will return a list of valid switches. With well over 50  modules to update this is a lot of work! Its taken me about 5hrs so far!
Following that I will add a similar command to obtain the valid widget and contents (e.g. text tags) sub-commands. For some widgets with just a handful of options and commands it something of an overkill but, then comes the task of updating the documentation.
I've completed most of the support in place for using pango markup strings in the text widget. The set of available tags is pre-defined, but quite extensive. Just a little more work in this area before the handling of <span.. </span> will work properly. Added this is a new toolbar with all the necessary buttons for the pango markup in place.


Dockable side toolbars

Image
Gtk offers a dockable toolbar but this cannot be re-docked elsewhere on screen. The screenshot below shows a possible workaround using notebook groups. As the toolbar must be configured as either horizontal or vertical whenever a new page is dropped onto a notebook, then the toolbar will be automatically re-oriented. The accompanying script is basically for proof of principle rather than a realistic package.





proc addToolBarItems {tb} {
    foreach item {Open Close New Cut Paste Copy} {
        $tb add item -icon %#$item
    }
}


set container [gnocl::box]
set table [gnocl::table]
$container add $table -fill {1 1} -expand 1

set nb(1) [gnocl::notebook -groupId 1 -onPageAdded { %c configure -orientation %d } -data horizontal]
set nb(2) [gnocl::notebook -groupId 1 -tabPosition left -onPageAdded { %c configure -orientation %d } -data vertical]
set nb(3) [gnocl::notebook -groupId 1 -tabPosition right -onPageAdded { %c configure -orientation %d } -data vertical]
set nb(4) [gnocl::notebook -groupId 1 -onP…

Recent Enhancements

Image
Added the following enhancements to the nightly build code.

2013-07:
   gnocl::notebook
        o new options
            -data
        o added extra percentage subtitution strings to -onPageAdded, -onPageRemoved
            %c child
            %n page number
            %d data

2013-06:
    gnocl::toolBar
        o configure/cget -orientation now works

gnocl::label cget

Image
Fixed bug that appeared in the label widget cget subcommand after the move over to using LabelParams in the source code. At the moment cget -text returns the text without markup. Next step is to test for markup and return markup string if applicable.

gnocl::box remove command debugged

Image
Problems with the remove child command resolved. This will be more useful when toggling the display of UI items. If the -visible option is used to manipulate object, space will still be allocated for the hidden object. This may be acceptable at times, but in large, complex layouts hiding already packed widgets may alter the overall window sizing or affect the relative sizing of other containers such as the gnocl::paned widget.

Test script:

#!/bin/sh
# the next line restarts using tclsh \
exec tclsh "$0" "$@"

package require Gnocl

proc swap_parent {w} {
    global box

    set p [$w parent]
    if {$p eq $box(1)} {
        $box(1) remove $w
        $box(2) add $w -fill {1 1} -expand 1
    } else {
        $box(2) remove $w
        $box(1) add $w -fill {1 1} -expand 1
    }
}


set box(1) [gnocl::box]
set box(2) [gnocl::box]

set win(1) [gnocl::window -title "Window #1" -x 100 -child $box(1) -width 200 -height 100]
set win(2) [gnocl::window -title "Window #2" -x 400 -…

gnocl::label new options -background and -foreground

Image
Spent a couple of hours today hacking this feature together. Ordinarily the base colour of a label is defined by the system style and can be overidden. Alternatively, it's possible to use markup strings. But... what if the text is set through a traced variable?
It is possible to modify the default pango settings for the label and modify these during runtime. It was fiddly to implement but now it works. To achieve similar result in the past required embedding the label into an eventBox.

Here's some demo code...


#!/bin/sh
# the next line restarts using tclsh \
exec tclsh "$0" "$@"

package require Gnocl

set lab [gnocl::label -text hello -baseFont {Sans 25} -foreground white -background blue]
set box [gnocl::eventBox -child $lab -background red]
gnocl::window -child $box -setSize 0.125

Recent Code Changes

Image
Haven't posted anything to the blog recently, so here's a summary of the code changes made over the past month.

gnocl::box
added commands, reorder, addStart
corrected bugs in addBegin command

gnocl::paned
fixed bug in -onHandleMoved option
new options
-onButtonPress
-onButtonRelease
-tooltip

gnocl::expander
new option
-onActivate

gnocl::text
resolved problems with tag sub-command "ranges"

New megawidget gnocl::richtextToolBar

Image
A while ago added I development code to handle pango markup in gnocl::text widgets. The next step, I felt, was adding a toolbar megawidget which would do all the necessary widget application with no extra scripting. Its working fine so far. I'll need to create some custom icons for the buttons and compile these into the sources but this should be straightforward. Perhaps the name of widget needs revising, its a bit too long. Anyway, here's my test script.

#--------------------------
# test_gtk_richTextToolBar.tcl
#--------------------------
#!/bin/sh
#\
exec tclsh "$0" "$@"

package require Gnocl

set txt [gnocl::text -wrapMode word -markupTags 1]
set rtbar [gnocl::richTextToolBar -text $txt]
set vbox [gnocl::vBox]

$txt lorem

$vbox add $rtbar
$vbox add $txt -fill {1 1} -expand 1

gnocl::window -child $vbox -setSize 0.3

Converting between different colour formats

Image
Excluding the use of named Unix colours, Gtk+ employs three numeric ways of describing colours: rgb, hex and decimal. The choice of modes is largely determined by the library being wrapped. Cairo, for instance, only accepts colours in decimal formats. Some conversion is handled in the gnocl sources but, here's a package of proc which will convert between all three formats and also make allowances for the extra alpha channel.

#---------------
# colour-conversions.tcl
#---------------
# William J Giddings
# 04-Mar-2013
#---------------
# Notes:
# Manipulate colour expresions.
#---------------

#---------------
# convert integer RGBA values to hexadecimal
#---------------
#
proc RGB2hex {clr} {    
    if { [llength $clr] == 4 } {
        scan $clr "%d %d %d %d" r g b a
        return [format "#%02x%02x%02x%02x" $r $g $b $a]
    } else {
        scan $clr "%d %d %d" r g b
        return [format "#%02x%02x%02x" $r $g $b]  
    }
    return -1
}

#---------------
# convert…

Automating the widget creation process.

Image
I spent a couple of hours this morning working out a Tcl script that will create the basic components for custom widgets. There are so many repetitive elements converting a few hundred lines of C code which, if one has to edit it all by hand, takes up too much time. I'm also quite notorious for being unable to spot spelling and grammar errors and so any extra help is always welcome. The way in which the module generator works is create create a sub-directory in the src folder, create the necessary *.h, *.c and readme (working on the autodocs pages next) and then patches the Makefile and the files gnocl.c and gnocl.h in readiness for the first compile.

When I've got this to work properly, moving the whole lot into a separate, standalone Tcl/Gnocl app would be the best next move. In this case the main gnocl package can give bindings to the core Gtk+ widget set and any custom extras in a unique package that can be loaded as required.

gnocl::level

Image
This morning I took a look at the task of adding more custom widgets to the gnocl tool-kit. What has always capture my imagination is the 'recording' and 'playback' level indicators typically found in sound recording apps. Now, I've no real idea of what should be looked for in such widget other than it should flash on and off, rise up and down and occasionally go into a red zone. So, I've added some experimental code to see how it should be pieced together and it looks like fun. There is still some way to go in order to make all the options configurable and the widget resizeable. If anyone's interested in the making serious use of it, please give me feedback and then I can enhance the code in a more meaningful way. Here's a screen shot and demo script.



# test-level.tcl

#!./bin/sh
#\
exec tclsh "$0" "$@"

package require Gnocl

proc display {} {
    global lev
    set hb(1) [gnocl::hBox]
        for {set i 0} {$i<20} {incr i} {
      …

gnocl::labelEntry

Image
The currently nightly build has code for some useful megawidgets which yet need fully documenting. One of these is the gnocl::labelEntry. Apart from having a label and entry the re is also the possibility of adding a child widget. This type of object can certainly be made in gnocl from simpler components, but this higher level of abstraction just makes life that much easier!

Here's a screen shot and sample script.



# test-le.tcl
#!/bin/sh \
exec tclsh "$0" "$@"

package require Gnocl

set app(find,regexp) 1

set cb(1) [gnocl::checkButton \
    -text "regexp" \
    -variable app(find,regexp)]

set le(1) [gnocl::labelEntry \
    -text "Search For:" \
    -variable app(find) \
    -primaryIcon "%#Paste" \
    -secondaryIcon "%#Clear" \
    -onIconPress {puts "Yo!"}]

$le(1) configure \
    -child $cb(1)       

gnocl::window \
    -child $le(1) \
    -title "gnocl::labelEntry"


Switching the display of the Gnome desktop icons.

Image
I am a minimalist. Some clutter makes be uncomfortable and lots of its makes me utterly confused. So, when it gets to the point where my desktop has a mountain of icons on it something has to go -its usually my temper but those icons can be hidden. The usual approach is to dig into the Gnome Configuration Editor to switch the Nautilus preferences. That's fine once or twice, but what if we want immediate de-clutter? The gnoclGconf package offers a solution. Here's a simple script to handle the job.



# toggle desktop icons

#!./bin/sh
#\
exec tclsh "$0" "$@"

package require Gnocl
package require GnoclGconf

gnocl::gconf set /apps/nautilus/preferences/show_desktop \
    [gnocl::toggle [gnocl::gconf get /apps/nautilus/preferences/show_desktop] ] \
    -type boolean

exit

Dropping this into my $HOME/bin directory means that I can use this as a command from any terminal. For more convenience I've added a panel launcher. So, now we see it, now we don't! Bye bothersome i…

Checking to see which entry has the active input focus.

Image
Gtk provides no simple way telling a calling program which entry widget contains the active keyboard focus. Specific widgets can be interrogated as to whether they possess keyboard input focus on either a global scale or simply within their own toplevel window. My own pet project is working on the translation of Chinese texts and the api of my translation editor will have multiple editable widgets on screen at any one time. Up till now I've used focus events to set a global variable identifying which widget has focus, but there are other ways. Today I just added the hasToplevelFocus and has hasGlobalFocus commands to the gnocl::text widget. There always was, of course the option to use cget -hasFocus. Here's my test script.

#---------------
# test-chinese-punct-toolbar.tcl
#---------------
#
#!/bin/sh
#\
exec tclsh "$0" "$@"

package require Gnocl

#---------------
# insert punc mark it currently active text
#---------------
proc do_chn_punc { mark } {

    foreach w $::te…

gnocl::cairo - moving forward

Image
Spent some time last night working on the proposed gnocl::cairo package. I've got most of the innards working now and the next step will be wrapping the gdk core api into the mixture. Cairo is certainly fast even on my old 32-bit workstation. By default, my development code wants always to work on bitmaps but, of course, Cairo will work on a variety of surfaces. Apart from pixbufs, the additional objects include svn, png, ps, pdf, some other windows, mac and X formats and gdk drawables such as windows. The code is expanding rapidly but, it's getting there!

Today's Added Functionality

Image
This is the summary of today's work on the Gnocl sourcecode.

2013-01:
    gnocl::winfo
        o new subcommand
            exists
    gnocl::notebook
        o new options
            -startWidget
            -endWidget
            -onDestroy
    gnocl::label
        o new option
            -onDestroy

Improving Notebook Tearoff Functionality

Image
The Gtk+ libraries provide the necessary support to detach notebook tabs in order to attach them to other notebooks in the same group or to place them in floating windows. This is fine. But, what happens when a floating palette is destroyed? Well, the notebook and any pages that it contains will be lost too. Unfortunately, the Gtk+ libs do not re-attach pages to any original note book when other notebooks in the group are deleted. In otherwords, pages will be lost and it up the application to create new instances. The following script shows how to do it. It relies upon the gnocl::winfo exists sub-command, which has only just been added. So, anyone trying out this script will need to use the nightly build dated 16-Jan-13 or later.

# test-notebook-tearoff.tcl
#!/bin/sh \
exec tclsh "$0" "$@"

package require Gnocl

#---------------
# create notebook contents
#---------------
#
proc addStuff {} {

    set notebook1 [gnocl::notebook \
        -scrollable 1 \
        -tabPosition left…