Thursday, December 30, 2010

gnocl::notify -new gnome widget

I was asked today to sort out an issue with the gnome package. In the process of doing so I noticed that the implementation of a gnome notify object was restricted to use as an option of a statusicon object. In all fairness, I've never seen it used in any other way, but.... I thought that I really ought take a look at completing the binding. So, I've just hacked together the first attempt. There's still quite a bit left to do, but it will appear like a widget allowing changes to be made until is the notification object is 'closed'.

Here's my test script.

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

package require Gnocl
package require GnoclGnome

set gui [gnocl::window]

set not [gnocl::notify \
    -appName GNOCL \
    -summary SUMMARY \
    -body BODY \
    -icon ICON \
    -sound bell.wav \
    -timeout 500 \
    -urgency critical \
    -attach $gui \
    -onClosed "%w Puts CLOSED"]

puts $not


Tuesday, December 21, 2010

gnocl::keyFile - Documentation Uploaded

Just uploaded some user documentation to the website. As always, there are still a few things to tidy up. I resolved the problems I was encountering delete or 'freeing' key-value lists. I'm getting some GLIB-CRITICAL warnings written to the console but there seems to be no imparement to the functionality.

Read / Save and Creating config files using gnocl::keyFile

I'm pretty well satisfied that this module is in a usable form. This morning I put together some Tcl proc to manage the creation of application config files. This is what I came up with;

#---------------
# test-keyfile.tcl
#---------------
# William J Giddings
# 21/12/2010
#---------------

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

package require Gnocl

#---------------
# read named ini file and create global config array
#---------------
# args:
#    fname    name of file to load
# notes:
#    resets any existing config array
# returns:
#    id of the created keyframe object
#---------------
proc config:read { {fname app.ini} } {
    global config
    array unset config

    set i 0
    set kf [gnocl::keyFile load $fname]

    foreach group [$kf get groups] {
        foreach key  [$kf get keys -group $group ] {
            set config($key) [$kf get value -group $group -key $key]
            incr i
        }
    }
    return $kf
}

#---------------
# Write current configuration setting to .ini file
#---------------
# args:
#    kf        keyfile object id
#    fname    name of the ini file to create
# notes:
#    key group memberships checked internally
# returns:
#    number of items written to keyfile
#---------------
proc config:write {kf {fname app.ini} } {
    global config
    set i 0

    foreach key [array names config] {
        foreach group [$kf get groups] {
            if { [$kf has -group $group -key $key ] } {
                $kf set value -group $group -key $key -value $config($key)
                incr i
            }
        }
    }
    $kf write $fname
    return i
}

#---------------
# Sets default configuration settings.
#---------------
# args:
#    fname        name of the ini file to create
#    defaults    list of entries in the form <group:key value>
# notes:
#    if no values set, then an empty ini file will be created
# returns:
#    id of newly created keyfile object
#---------------
proc config:new { {fname app.ini} {defaults {} } } {
    global config

    array unset config

    set kf [gnocl::keyFile new $fname]

    if {$defaults == {}} {return $kf}

    foreach {a b} $defaults {
        foreach {group key} [split $a :] {}
        $kf set value -group $group -key $key -value $b
        set config($key) $b
    }

    return $kf
}


#----------
# test code
#----------

set defaults {
    group_1:key_a 1
    group_1:key_b 2
    group_2:key_c 3
    group_2:key_d 4
    group_3:key_e 5
    group_3:key_f 6
    group_3:key_g 7
    }

set kf [config:new test.ini $defaults ]

config:write $kf test.ini



Monday, December 20, 2010

gnocl::keyFile module completed!

Had some more time this evening and so finished off this module. There's only one item left to resolve but this is not unique to this module -the 'clear' sub-command. The existing Gnocl support funcs are geared towards GObjects which are basically widgets. A GKeyFile or even a Pixbuf for that matter are not widget although they are commands in the same way as a text or button widget. So, a little more thought needs to go into completing this last piece of functionality. But, that doesn't stop the use of the command. Here's a test .ini file from my ScanDocs app.

[Program]
name=ScanDocs
version=0.0.1

[Files]
batchDir=/home/wjgiddings/Desktop/ScanDocs/batches
batchName=default
lastfile={}
outFileName={DUNDES (1984) Sacred Narrative - Readings in the Theory of Myth}
pageSize=125x197
path=/home/wjgiddings/Desktop/ScanDocs

[Scanner]
mode=Binary
resolution=300
format=bw
threshold=80
type=pnm

[Job]
autoscan=0
i=100
scanRate=2

[Process]
deskew=0
composite=0
split=1
clear=1
clearBottom=100
clearCentre=100
clearSides=100
clearTop=0
trim=0
trimBottom=250
trimSides=300
trimTop=0
turn=0

[Unpaper]
unpaper,in_start=1
unpaper,out_start=1


And here's a code snippet of how to read that data and assign it to an application config array placed in the global namespace.


#---------------
# test-keyfile.tcl
#---------------
# William J Giddings
# 20/12/2010
#---------------

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

package require Gnocl

set kf1 [gnocl::keyFile load scandocs.ini]

foreach group [$kf1 get groups] {
    foreach key  [$kf1 get keys -group $group ] {
        set config($key) [$kf1 get value -group $group -key $key]
    }
}

parray config


When changing key values, how to know which group the key belongs to?
 
set variable autoscan

foreach group [$kf1 get groups] {
    if { [$kf1 has -group $group -key $variable ] } {
        puts "$variable is in group $group"
    }
}




gnocl::keyFile -remove functionality

Today's task is now completed. Its now possible to inquire what groups are present in the .ini file and what they keynames are. The final step is to remove entries and to close any open files. The next steps are to review the syntax and to add the documentation.

Here's the test-script:

#---------------
# test-keyfile.tcl
#---------------
# William J Giddings, 28/12/2010
#---------------

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

package require Gnocl

set kf1 [gnocl::keyFile load sample_config.ini]

puts "1 [$kf1 get value -group Person -key name]"
puts "2 [$kf1 get value -key name -group Person ]"
puts "3 [$kf1 get value -group Person -key name]"
puts "4 [$kf1 get value -key name -group Person ]"
puts "5 [$kf1 get integer -key age -group Person ]"
puts "6 [$kf1 get value -key sex -group Person ]"
puts "6 [$kf1 get value -key sex -group Person -locale UK ]"
puts "7 [$kf1 get comment -group Person -key name ]"

$kf1 set comment -group Person -key name -value "HIDI HI, HO DI HO!! HEHE"
$kf1 set value -group NEW -key ENTRY -value HAPPY_CHRISTMAS

puts [$kf1 write sample_config.ini]


puts GROUPS>>[$kf1 get groups]
puts KEYS>>[$kf1 get keys -group Person]
puts KEYS>>[$kf1 get keys -group "Another Group"]

set name [$kf1 get value -group Person -key name]

gnocl::window -setSize 0.25 -child [gnocl::label -textVariable name]

# remove functionality
$kf1 remove group NEW
$kf1 remove group NEW -key ENTRY
$kf1 remove comment Person -key name

$kf1 set comment -group Person -key sex -value "THIS IS A NEW COMMENT"
puts [$kf1 write sample_config.ini]

gnocl::keyFile -getting lists of groups and keys

Today's task is now completed. Its now possible to inquire what groups are present in the .ini file and what they keynames are. The final step is to remove entries and to close any open files. Here's the test-script:

#---------------
# test-keyfile.tcl
#---------------
# William J Giddings, 28/12/2010
#---------------

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

package require Gnocl

set kf1 [gnocl::keyFile load sample_config.ini]

puts "1 [$kf1 get value -group Person -key name]"
puts "2 [$kf1 get value -key name -group Person ]"
puts "3 [$kf1 get value -group Person -key name]"
puts "4 [$kf1 get value -key name -group Person ]"
puts "5 [$kf1 get integer -key age -group Person ]"
puts "6 [$kf1 get value -key sex -group Person ]"
puts "6 [$kf1 get value -key sex -group Person -locale UK ]"
puts "7 [$kf1 get comment -group Person -key name ]"

$kf1 set comment -group Person -key name -value "HIDI HI, HO DI HO!! HEHE"

# this will add a new group and set a specific key value
$kf1 set value -group NEW -key ENTRY -value HAPPY_CHRISTMAS

puts [$kf1 write sample_config.ini]

# 20/12/2010
# retrieve info on groups and keys
puts GROUPS>>[$kf1 get groups]
puts KEYS>>[$kf1 get keys -group Person]
puts KEYS>>[$kf1 get keys -group "Another Group"]

# extract a value and use it!
set name [$kf1 get value -group Person -key name]

gnocl::window -setSize 0.25 -child [gnocl::label -textVariable name]

Sunday, December 19, 2010

gnocl::keyFile almost done

After this morning's coding session the package now has functionality to change values and write these changes to disk.  The next step is implementing some of the introspection functionality and its pretty-well complete.

Here's the test script updated to reflect changes:

#---------------
# test-keyfile.tcl
#---------------
# William J Giddings, 28/12/2010
#---------------

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

package require Gnocl

# 18/12/10 Additions
set kf1 [gnocl::keyFile load sample_config.ini]

puts "1 [$kf1 get value -group Person -key name]"
puts "2 [$kf1 get value -key name -group Person ]"
puts "3 [$kf1 get value -group Person -key name]"
puts "4 [$kf1 get value -key name -group Person ]"
puts "5 [$kf1 get integer -key age -group Person ]"
puts "6 [$kf1 get value -key sex -group Person ]"
puts "6 [$kf1 get value -key sex -group Person -locale UK ]"
puts "7 [$kf1 get comment -group Person -key name ]"

# 19/12/10 Additions
$kf1 set comment -group Person -key name -value "HIDI HI, HO DI HO!! HEHE"
$kf1 write sample_config.ini

# Next sub-command to implement
puts >>[$kf1 get groups]



Saturday, December 18, 2010

gnocl::keyFile -progress

Got the basics running now. Seeing as in TCL 'everything is a string' the process of retrieving and setting values in the Tcl side is simple. I've got the information retrieval side working well and some skeletal bits for adding values which I'll bash into shape tomorrow. Here's my sample_config.ini file:

# this is just an example
# there can be comments before the first group

[First Group]
Name=Key File Example\tthis value shows\nescaping
# localized strings are stored in multiple key-value pairs
Welcome=Hello

[Another Group]
Numbers=2;20;-200;0
Booleans=true;false;true;true

[Person]
#This is me!
name=William
sex=male
age=54

And the test script to access it.

#---------------
# test-keyfile.tcl
#---------------
# William J Giddings, 28/12/2010
#---------------

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

package require Gnocl

set kf1 [gnocl::keyFile load sample_config.ini]

puts "1 [$kf1 get string -group Person -key name]"
puts "2 [$kf1 get string -key name -group Person ]"
puts "3 [$kf1 get value -group Person -key name]"
puts "4 [$kf1 get value -key name -group Person ]"
puts "5 [$kf1 get string -key age -group Person ]"
puts "6 [$kf1 get string -key sex -group Person ]"
puts "6 [$kf1 get string -key sex -group Person -locale UK ]"
puts "7 [$kf1 get comment -group Person -key name ]"

new command gnocl::keyFile

The GLIBs provides functionality for the creation and manipulation of application configuration files. This task is already pretty easy to implement using Tcl list and dictionary functionality and hitherto I've used it all the time. But, having seen how useful this functionality is, I thought that it was time to implement the bindings. The way in which this is achieved is to treat such lists as objects so that multiple files can be opened for an application. This will allow the use of such lists to be more than simply an application config file. One of my pet apps is the scanning and creation of djvu ebooks. Sometimes the settings for a particular page need to be modified in order to get a good scan. Creating a config page for to control the page creation operation would be the better than an a 'one setting fits all' approach.

Thursday, November 18, 2010

Another distraction?

I regularly use ImageMagick to post-process documents scanned under the control of a Tcl script using the exec command. All works well, albeit a little slowly. So, I thought that I'd get a copy of TclMagick which didn't compile and so on and so on.... So, I thought that I'd put together my own package using those commands that I use most regularly. I'm so pleased with the result that I think I'll abandon the pixbufFilter module that I was experimenting with in favour of this new approach. I have the package running and able to implement the processes much more quickly than calling the convert command. What I need to explore now, however, is how to pipe GdkPixbuf data across to a wand object. -I think I see how this was done in TkMagic!

Here's the test script -oddly, the command to get an image height is really slow, why?

# test-gnoclWand.tcl

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

package require Gnocl
package require GnoclWand
set pb1 [gnocl::wand load pelican.png]

$pb1 swirl 1200
$pb1 resize 400 400
$pb1 save resize.png

set pb2 [gnocl::wand load image-0007.pnm]
$pb2 deskew
$pb2 save skew.tif
#puts "width = [$pb2 width]"
#puts "height = [$pb2 height]"

Sunday, November 14, 2010

gnocl::drawingArea

This little beastie got a whole lotta TLC today. Implemented most of the the gdk drawing functions only to find that these have been deprecated in Gtk +2.22 in favour of Cairo! No matter, the code will work and besides, there was already a cairo based module in the pipeline anyway!

#---------------
# test-drawingArea.tcl
#---------------
# William J Giddings
# 02-Nov-2010
#---------------

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

package require Gnocl

proc scanZone {} {

set da [gnocl::drawingArea]

$da option add [list \
    -onPointerMotion \
    -onButtonPress \
    -onButtonRelease \
    -onKeyPress \
    -onKeyRelease \
    -onExpose]

return $da
}

set sz [scanZone]

gnocl::window -child $sz

if {0} {
set pb [gnocl::pixBuf load -file EU_flag.jpg]
gnocl::window -child [gnocl::image -image "%?$pb"]
set pb [gnocl::pixBuf load -file wjg_icon.png]
}

$sz configure -onPointerMotion {

    #%w draw line [list %x 0 %x 10]
    #%w draw line [list 0 %y 10 %y ]

    set x1 [expr %x - 5] ; set y1 [expr %y - 5]
    set x2 [expr %x + 5] ; set y2 [expr %y - 5]
    set x3 [expr %x + 5] ; set y3 [expr %y + 5]
    set x4 [expr %x - 5] ; set y4 [expr %y + 5]

    #%w draw point [list %x %y]
    #%w draw points [list $x1 $y1 $x2 $y2 $x3 $y3 $x4 $y4]
    #%w draw lines [list $x1 $y1 %x %y $x2 $y2] ;#$x3 $y3 $x4 $y4 $x1 $y1]

    #%w draw pixbuf $pb -from [list %x %y 10 10] -to [list %x %y] -dither none -offset {0 0}
    #%w draw rectangle [list $x1 $y1 10 10] -filled 1

    #%w draw arc [list $x1 $y1 50 50 30 120] -filled 1
    #%w draw     polygon [list $x1 $y1 $x2 $y2 $x3 $y3 $x4 $y4] -filled 1

    set x1 %x ; set y1 [expr %y -10]
    set x2 %x ; set y2 [expr %y +10]
    set x3 [expr %x -10] ; set y3 %y
    set x4 [expr %x +10] ; set y4 %y

    #%w draw segments [list $x1 $y1 $x2 $y2 $x3 $y3 $x4 $y4]

    set y1    %y
    set x11 %x
    set x21 [expr %x + 50]
    set y2    [expr %y + 50]
    set x12 [expr %x - 50]
    set x22 [expr %x + 50]

    %w draw  trapezoids [list $y1 $x11 $x21 $y2 $x12 $x22 ]
    }

Saturday, November 13, 2010

Recent activity -Scripting...

The past couple of days has seen me gnocl scripting rather than working on core code. One pet project of mine is the automated creation of edocs and ebooks. Although I have an old version of AbbySoft Professional which runs on my laptop and an equally ancient version of Acrobat 6, I want to add docs as I work on my desktop machine. To do this I created a front Tcl/Gnocl front end to control the scanning, clean-up and cropping of scans, the conversion to DJVU with OCR and packing of graphics to a multipage TIF for later processing in FineReader. Everything works fine but my control script had been hacked to gether over the past year or more and so some rationalisation is in order. But, but, but... Who likes writing code from scratch all the time? Creating new basic GUIs is always a chore so I thought that I'd create something to the growing gnocl megawidgets package. Todays addition will build a container and add the main control elements for menus, toolbars, the main content area and status block. Names and aliases for these items is returned as a list for future modification. Its still all basic at the moment, but it make life easier. Perhaps I should include this with the next release? Well, here's the proc itself:

#---------------
# Create a boilerplate application window
#---------------
proc gnocl::default {args} {
# set some defaults here
set opts(menubar) ""
set opts(toolbar) ""
set opts(box) ""
set opts(status) ""
foreach {arg val} $args {
    switch -- $arg {
        -opt1 -
        -opt2 { append opts(menubar) "$arg $val " }
        -opt3 -
        -opt4 { append opts(toolbar) "$arg $val " }
        -opt5 -
        -opt6 { append opts(box) "$arg $val " }
        -opt7 -
        -opt8 { append opts(status) "$arg $val " }
        default { puts "WARNING: Invalid option $arg."    }
        }
}
set app(menuBar) [gnocl::menuBar]
set app(toolBar) [gnocl::toolBar]
set app(box) [gnocl::box]
set app(status) [gnocl::statusBar]
set app(container) [gnocl::box -orientation vertical]
$app(container) add $app(menuBar)
$app(container) add $app(toolBar)
$app(container) add $app(box) -fill {1 1} -expand 1
$app(container) add $app(status)
# create menus
# file i/0
# create menus
set app(menu,file) [gnocl::menu]
set app(menu,help) [gnocl::menu]
#attach items
$app(menuBar) add [gnocl::menuItem -text "%__File" -submenu $app(menu,file)]
$app(menuBar) add [gnocl::menuItem -text "%__Help" -submenu $app(menu,help)]
#add menu sub-items
$app(menu,file) add [gnocl::menuItem -text "%#Quit" -onClicked exit]
$app(menu,help) add [gnocl::menuItem -text "%__About" -onClicked {puts "About Gnocl"}]
# create toolbars
$app(toolBar) add item -text "Button1" -onClicked {puts Button1}
$app(toolBar) add space
$app(toolBar) add checkItem -text "Button2" -onToggled {puts Buton2}
#eval "set app(top) [gnocl::window -visible 1 -child $app(container) ]"
#$app(top) center
#eval "$app(top) configure $winArgs"
$app(status) push "Ready"
# return a list consiting of widget aliases and names
return [array get app]

}

Recent activity -Scripting...

The past couple of days has seen me gnocl scripting rather than working on core code. One pet project of mine is the automated creation of edocs and ebooks. Althought I have an old version of AbbySoft FineReader Professional which runs on my laptop and an equally ancient version of Acrobat 6 (on my Linux box I have PDF Studio which is brilliant value for money) I want to add docs as I work on my desktop machine. To do this I created a front Tcl/Gnocl front end to control the scanning, clean-up and cropping of scans, the conversion to DJVU with OCR and packing of graphics to a multipage TIF for later processing in AbbySoft FineReader.  Everything works fine but my control script have been hacked to gether over the past year or so and so some rationalisation is in order. But, but, but who likes writing code from scratch all the time! Creating new basic GUIs is always a chore so I thought that I'd create something to the growing gnocl megawidgets package. Todays addition will build a container and add the main control elements for menus, toolbars, the main content area and status block. Names and aliases for these items is returned as a list for future modification. Its still all basic at the moment, but it make life easier. Perhaps I should include this with the next release? Well, here's the proc itself:

#---------------
# Create a boilerplate application window
#---------------
proc gnocl::default {args} {

# set some defaults here
set opts(menubar) ""
set opts(toolbar) ""
set opts(box) ""
set opts(status) ""
 
# apportion values
foreach {arg val} $args {
    switch -- $arg {
        -opt1 -
        -opt2 { append opts(menubar) "$arg $val " }
        -opt3 -
        -opt4 { append opts(toolbar) "$arg $val " }
        -opt5 -
        -opt6 { append opts(box) "$arg $val " }
        -opt7 -
        -opt8 { append opts(status) "$arg $val " }
        default { puts "WARNING: Invalid option $arg."    }
        }
}

# create components
set app(menuBar) [gnocl::menuBar]
set app(toolBar) [gnocl::toolBar]
set app(box) [gnocl::box]
set app(status) [gnocl::statusBar]
set app(container) [gnocl::box -orientation vertical]
 
# assemble
$app(container) add $app(menuBar)
$app(container) add $app(toolBar)
$app(container) add $app(box) -fill {1 1} -expand 1
$app(container) add $app(status)
 
# create menus
# file i/0
# create menus
set app(menu,file) [gnocl::menu]
set app(menu,help) [gnocl::menu]
 
#attach items
$app(menuBar) add [gnocl::menuItem -text "%__File" -submenu $app(menu,file)]
$app(menuBar) add [gnocl::menuItem -text "%__Help" -submenu $app(menu,help)]
 
#add menu sub-items
$app(menu,file) add [gnocl::menuItem -text "%#Quit" -onClicked exit]
$app(menu,help) add [gnocl::menuItem -text "%__About" -onClicked {puts "About Gnocl"}]
 
# create toolbars
$app(toolBar) add item -text "Button1" -onClicked {puts Button1}
$app(toolBar) add space
$app(toolBar) add checkItem -text "Button2" -onToggled {puts Buton2}

#eval "set app(top) [gnocl::window -visible 1 -child $app(container) ]"
#$app(top) center
#eval "$app(top) configure $winArgs"
 
$app(status) push "Ready"
 
# return a list consiting of widget aliases and names
return [array get app]
}

Wednesday, November 10, 2010

gnocl::calendar

Given this module some attention today. Added some of the more package wide options to the module and created customised handler for setting the month. (For some odd reason months are are counted 0-11 whereas days are 1-31.) There's still a little more to do to this one including the addition of code to store diary details. Here's the working test script to show the range of options at work. The percentage substitution string item %e explores something that I've been toying with, the name of the signal/event that initiated the call. Ok, a script can keep its own internal trace but who knows, it might prove useful.

#---------------
# calendarTest.tcl
#---------------
# Author:   William J Giddings
# Date:     07/05/09
#---------------
#!/bin/sh
# the next line restarts using tclsh \
exec tclsh "$0" "$@"
#---------------

package require Gnocl

set cal [gnocl::calendar]

$cal configure -day 8 -month 7 -year 1956
$cal configure -rowHeight 1 -colWidth 1
$cal configure -monthChange 1
$cal configure -dayNames 1
$cal configure -details 1
$cal configure -heading 1
$cal configure -weekNumbers 1
$cal configure -font {Courier 12}
$cal configure -baseColor #ffffdd
$cal configure -sensitive 1
$cal configure -visible 1
$cal configure -tooltip "Calendar"

$cal configure -onDaySelected {puts "%e %d %m %y"}

$cal configure -onDoubleDaySelected {
    puts " %e %d %m %y"
    %w detail add -date [list %d %m %y] -text {birthday}
    }

$cal configure -onMonthChanged {puts "%e %d %m %y"}
$cal configure -onNextMonth {puts "%e %d %m %y"}
$cal configure -onNextYear {puts "%e %d %m %y"}
$cal configure -onPrevMonth {puts "%e %d %m %y"}
$cal configure -onPrevYear {puts "%e %d %m %y"}

gnocl::window -child $cal -title gnocl::calendar

gnocl::mainLoop

Wednesday, November 03, 2010

gnocl::layout and gnocl::aspectFrame

I've just added the modules for these two widgets. They are pretty obscure. The gnocl::layout object is a sort of mid between a frame and a drawing area and the gnocl::aspectFrame always forces a widget to keep its original aspect ratio. With the inclusion of these two new objects, I think that the bindings to the GTK+ 2.18 release which I'm compiling against is almost done. When all objects have some level of support, then I think it would be possible to notch up an other release - 0.9.96 or thereabouts.

Here's a test code snippet for these new widgets.


set lo [gnocl::layout -width 500 -height 4000]

set but1 [gnocl::button -text "Button"]
set but2 [gnocl::button -text "DEL $but1"]

set x 10

$lo add $but1 -x $x -y 10
$but1 configure -onClicked {$lo move %w -x [incr x 10] -y 10}

$lo add $but2 -x $x -y 50
$but2 configure -onClicked {$lo remove $but1}

gnocl::window -child $lo -title "Layout"

set but3 [gnocl::button -text "BUTTON-3" -onClicked {puts "HELLO [$af cget -xalign]" } ]
set af [gnocl::aspectFrame -child $but3 -xalign 0.5]
gnocl::window -child $af -title "Aspect Frame"

The gnocl::aspectFrame module has been quite interesting, as there are no  get-property functions for this object, I've had to take a peek at the Gtk+ sources. It was interesting, resulted in a long winded hack of the 'get' equivalent, which I promptly abandoned and handled the whole lot through pointers.




gnocl::drawingArea ----> working forward ---->

This mornings programming stint sees the bare bones in place now for drawing commands on the gnocl::drawingArea widget. I've also added pages in the docs for the cursor settings. The test script changes reflect the progress so far as a stroke based paint program begins to take shape.



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

package require Gnocl

# create and display the drawingArea widget
set da [gnocl::drawingArea]
gnocl::window -widthRequest 320 -heightRequest 200 -child $da

# add options...
$da option add -onPointerMotion
$da option add -onEnter
$da option add -onLeave
$da option add -onButtonPress
$da option add -onButtonRelease
$da option add [list -onKeyPress -onKeyRelease -onExpose]

# configure them
$da configure -onPointerMotion {addPoint %w %x %y}
$da configure -onEnter {puts "Enter -Hello!"}
$da configure -onLeave {puts "Leave -Bye!"}
$da configure -onButtonPress {
    puts "-- Start Drawing --"
    set draw 1
    $da configure -cursor pencil
    }
$da configure -onButtonRelease {
    puts "-- End Drawing --"
    set draw 0
    $da configure -cursor last
    }
$da configure -onKeyPress {puts "Press"}
$da configure -onKeyRelease {puts "Release"}
$da configure -onExpose {
    reDraw %w
    }

set draw 0
set points {}

proc addPoint { w x y } {
    if { $::draw } {
        lappend ::points [list $x $y]
        puts adding
        $w draw point [list $x $y]
    }
}

proc reDraw {w} {
    foreach point $::points {
        $w draw point $point
    }
}




gnocl::drawingArea -more progress

I'm really pleased with the progress that I've made with this module today. The test script below gives some indication of how its shaping up. I''ve just added the ability to pass a list the option add command. Think that I've done enough for today.


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

package require Gnocl

# create and display the drawingArea widget
set da [gnocl::drawingArea]
gnocl::window -widthRequest 320 -heightRequest 200 -child $da

# add options...
$da option add -onPointerMotion
$da option add -onEnter
$da option add -onLeave
$da option add [list -onButtonPress -onButtonRelease]
$da option add [list -onKeyPress -onKeyRelease -onExpose]

# configure them
$da configure -onPointerMotion {puts "%x %y"}
$da configure -onEnter {puts "Enter -Hello!"}
$da configure -onLeave {puts "Leave -Bye!"}
$da configure -onButtonPress {puts "You Clicked!"}
$da configure -onButtonRelease {puts "You Left-Go!"}
$da configure -onKeyPress {puts "Press"}
$da configure -onKeyRelease {puts "Release"}
$da configure -onExpose {puts "Exposed!"}

gnocl::mainLoop

Tuesday, November 02, 2010

gnocl::drawingArea -more work done

GtkDrawingArea is basically the blank canvas from which other widgets are built up. The developer decided what signals and properties are to be applied to the object. The basic module for the gnocl::drawingArea has been around for some time and today I got it all running a little more smoothly and now that remains is to hard-code into the module the various choices and options that can be added during run-time. Here's the test script to show how simply the process is working out.

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

package require Gnocl

# create and display the drawingArea widget
set da [gnocl::drawingArea]
gnocl::window -widthRequest 320 -heightRequest 200 -child $da

$da option add -onPointerMotion
$da configure -onPointerMotion {puts "%x %y YIPPEEE!!!"}
$da option add -onEnter
$da configure -onEnter {puts "Enter -Hello!"}
$da option add -onLeave
$da configure -onLeave {puts "Leave -Bye!"}
$da option add -onButtonPress
$da configure -onButtonPress {puts "You Clicked!"}

gnocl::mainLoop

There's still some way to go, more error checking, the ability add a list of options etc...

Also did some more tidying up of the gnocl::ruler code.







gnocl::volumeButton -done

Gave the gnocl::volumeButton a little bit of TLC tonight. Added signal handlers and options for a number of inherited properties. Getting this one to work as required some trial and error as only some of the inherited options are permitted but not indicated in the docs. No, screenshot as the popup prevents this. But, here's the test script...

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

package require Gnocl

set ent [gnocl::label -textVariable vol]
set vb [gnocl::volumeButton]
set box [gnocl::box]
$box add [list $vb $ent]

gnocl::window -child $box

$vb configure -value 1.0
$vb configure -onPopup {puts "popup %w"}
$vb configure -onPopdown {puts "popdown %w"}
$vb configure -onValueChanged {puts "valueChanged %w %v" ; set vol %v}
$vb configure -visible 1
$vb configure -sensitive 1
$vb configure -relief none
$vb configure -borderWidth 20
$vb configure -prelightBackgroundColor green 


gnocl::mainLoop

Monday, November 01, 2010

gnocl::iconView - adding items with labels

I've now created the structure to add options to the iconview add
command. This will be useful if some other info apart from a filepath is
needed. Also, in progress is the use of percentage markup strings. This
will enable the choice between file, stockitem and pixbuf sources. If
the specified icon is unavailable then a default item will be displayed.
Here's a sample of the test code...


set iv [gnocl::iconView \
    -columns 1 \

    -orientation vertical \

    -itemWidth 100 ]

gnocl::window \

    -title VERTICAL \

    -child $iv \

    -width 150 \

    -height 300 \

    -onDestroy {exit}


for {set i 1}  { $i <= 3} { incr i } {

  $iv add "%?im-0001.pnm" -label "item $i"
}
$iv add pointer.png -label pointer

$iv add upArrow.png -label up

$iv add downArrow.png -label down


And the result...








gnocl::infoBar -done!

Well, lets say 85% done. Enough for now anyway. This is a 'querky' sort of widget. The docs say:

GtkInfoBar is a widget that can be used to show messages to the user without showing a dialog. It is often temporarily shown at the top or bottom of a document. In contrast to GtkDialog, which has a horizontal action area at the bottom, GtkInfoBar has a vertical action area at the side.

Well. here's a screenshot and test script:



#---------------
# test-infobar.tcl
#---------------
# William J Giddings
# 01-Nov-2010
#---------------

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

package require Gnocl

set ib [gnocl::infoBar]

$ib configure -onResponse {
        switch -- %d \
            $but(OK)      {puts "You clicked the OK button."} \
            $but(CANCEL) {puts "You clicked the CANCEL button."} \
            default      {puts "You clicked something else!"}
         }

puts "$ib is a widget class: [$ib class]"

set box [gnocl::box]
set lab [gnocl::label -text "Add Extra Items Here!"]

$box add $lab -fill {1 0} -expand 1
$ib configure -child $box ;#-type info

set but(OK) [$ib add button OK]
set but(CANCEL) [$ib add button Cancel]

$ib configure -default 2

set txt [gnocl::text]
set frame [gnocl::box -orientation vertical]

$frame add $txt -fill {1 1} -expand 1
$frame add $ib

gnocl::window -child $frame

gnocl::infoBar -new module

Just added the bare bones module for the GtkInfoBar binding. This widget was introduced with Gtk+ 2.15. Hope to get a working demo finished before the end of the week.

Saturday, October 30, 2010

gnocl::iconView params structure

I've now created the structure to add options to the iconview add command. This will be useful if some other info apart from a filepath is needed. Also, in progress is the use of percentage markup strings. This will enable the choice between file, stockitem and pixbuf sources. If the specified icon is unavailable then a default item will be displayed. Here's a sample of the test code...

set iv [gnocl::iconView \
    -columns 1 \
    -orientation vertical \
    -itemWidth 100 ]

gnocl::window \
    -title VERTICAL \
    -child $iv \
    -width 150 \
    -height 300 \
    -onDestroy {exit}

for {set i 1}  { $i <= 3} { incr i } {
   $iv add "%?im-0001.pnm" -label "item $i"
}

$iv add pointer.png -label pointer
$iv add upArrow.png -label up
$iv add downArrow.png -label down


And the result...






Friday, October 29, 2010

gnocl::iconview -progressing

Done more work on adding items to the display. The code originally had a stub which  populated the widget, but now items can be added directly,

set iv [gnocl::iconView \
    -columns 2 \
    -orientation vertical ]

gnocl::window \
    -title VERTICAL \
    -child $iv \

$iv add pointer.png
$iv add upArrow.png
$iv add downArrow.png
$iv add logo.png

At the moment any graphic will be displayed at its original size and not resized to fit. Reflecting upon this and the fact that the GtkIconView widget can display any prededefined GtkTreeList, I think that I will after all, need to implement a parameter struct for this module. This is no hassle. Something for tomorrow....

Thursday, October 28, 2010

gnocl::iconview

Didn't need to create a param struct for the widget after all. I'd forgotten that for convenience the GtkIconView was already packed into a GtkScrolledWindow and all that I needed to do was to get the child for this item.

Wednesday, October 27, 2010

gnocl::iconView

Overlooked this one in my 'audit' earlier this month. Spent a couple of hours working on this module this evening. Why do that? Again, 'cause I want to use the widget in an app. I got the bare bones together and hacked together a stub that launched a demo widget. But, now it need polishing off. I've got all the propterty and signal options sorted out but now I need to revisit how the widget is registered. In fact I need to create a iconview struct to contrain pointers not just to the widget but to the scrollable window that its packed into. So, options will be set a creation but cannot yet be 'configured' to other settings or values. I'll handle this tomorrow night. The code 'as-is' has been uploaded to sourceforge.

Here's the test-script that I'm working with:

#---------------
# test_iconview.tcl
#---------------
# William J Giddings
# 27-Oct-2010
#---------------
# Notes:
#
#---------------

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

package require Gnocl


set iv [gnocl::iconView \
    -rowSpacing 1 \
    -reorderable 1 \
    -pixbufColumn 10 \
    -markupColumn 2 \
    -margin 10 \
    -itemWidth 60 \
    -itemPadding 0 \
    -columnSpacing 1 \
    -columns 4 ]

$iv configure -textColumn 1
$iv configure -tooltipColumn 1
$iv configure  \
    -onActivateCursorItem { puts "onActivateCursorItem" } \
    -onItemActivated { puts "onItemActivated" } \
    -onMoveCursor { puts "onMoveCursor" } \
    -onSelectAll { puts "onSelectAll" } \
    -onSelectCursorIem { puts "onSelectCursorIem" } \
    -onSelectionChanged { puts "onSelectionChanged" } \
    -onSetScrollAdjustments { puts "onSetScrollAdjustments" } \
    -onToggleCursorItem { puts "onToggleCursorItem" } \
    -onUnselectAll { puts "onUnselectAll" }

gnocl::window \
    -child $iv \
    -widthRequest 150 \
    -heightRequest 400
 

Friday, October 22, 2010

Built-in graphics

A while ago, after upgrading my distro from OpenSuse 11.2 to 11.3 I noticed that the Gnocl icon on my apps had vanished. Of course it had been installed as a shareable graphic. Its about time to add it to gnocl core so that it will always appear by default in the top left corner of all newly opened Gnocl windows.

gnocl::printOperation -unit option

Just implemented -unit option functionality, this will allow long and short keywords, millimeter/mm, inch/ins. pixel/px and point/pnt. Just looking at obtaining and manipulating the print status options. This module is certainly going to be a big one!


Thursday, October 21, 2010

gnocl::printOperation

Added the core structures to hand the configure and cget commands. And its running fine.
Took a look at the online docs and urgh! The gnocl::assistant page is in urgent need of completion.


Tuesday, October 19, 2010

gnocl::print ------ progressing

Did some more work on the print module today. First of all I reworked the registration of the print op. Originally it was registered along with the other widgets, but on reflection I felt that it should be named differently in the same way as pixBufs are. So, I had to add a pile of funcs to add a hashtable to handle print jobs. Another change that I made to the code was to use a pointer to a parameters structure rather than to the op itself. Ok, all of the relevant info regarding the print job will be held in a printersettings structure, but the use of the parameters structure means that all the relevant pointers and non-gtk option settings can be accessed through a single call rather than having too many messy globals floating about. Finally, added the basics for the developer docs. The module doesn't print anything yet even though there's well over 500 lines of code!

Friday, October 15, 2010

gnocl::print

Returned to the print binding today and put the code in place to handle the Gtk properties and signals for the GtkPrintOperation widget. I'm pretty well playing this one as I go along as I have to admit that I don't fully understand the whole process. In terms of requiring print functionality all that is ever needed for document processing is now probably catered for using the gnocl::abiword widget. The gnocl::text object could have a simple print command added to it for the purpose of simple listings. Rich formatted text is a different matter. Does an application need to draw directly to a canvas and then output the rasterized image to print? What about applications that generate their own reports, how are these to be directed to print?

MMMM.... more to think about. Still, carry on putting the pieces together.

Thursday, October 14, 2010

Development Audit

Earlier today I did a rather informal audit of the state of the implementation of Gnocl widget set. As my attention to coding is largely demand driven certain implementations are begun, brought to a 'what is required' state and then....  Well, left to looked at some indefinite future period. As I've nothing to draw my attention at the moment, the obvious activity in need of attention is those incomplete items. So, here's a list of what I have to finish.

1) Printing support, only the bare bones are present.
2) Undo/Redo script for text, support for d'n'd needs implementing.
3) Extension of Undo/Redo include text entry items.
4) Recent file choose button.

5) Tooltips work, but rely heavily upon deprecated code.

6) Canvas, add polyline arc and some other simple line primitives (eg. stars).
7) Pixbuf -complete image processing commands.
8) Cairo support -complete support for primitives.
9) Review splashscreen code.
10) Calendar

That should do for now.



Wednesday, October 06, 2010

gnocl::stockItem -finished!

In the end I decide against the creation of new stock items from pre-existing items. So, here's what a piece of test script and its screenshot looks like






#---------------
# test-stockitems.tcl
#---------------
# Created by William J Giddings
# 06-Oct-2010
#---------------

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

package require Gnocl
 

#----- create stock item from an existing buffer -----#
 set pb1 [gnocl::pixBuf load -file [pwd]/georgie.jpg]

gnocl::stockItem add \
    -label Georgie \
    -icon "%?$pb1"


#----- create stock item from disk objects  -----#
gnocl::stockItem add \
    -label News \
    -icon "%/[pwd]/news.png"

gnocl::stockItem add \
    -label White \
    -icon "%/[pwd]/night1.png"

gnocl::stockItem add \
    -label Black \
    -icon "%/[pwd]/night2.png"


 #----- display the whole lot  -----#
set box [gnocl::box]
set but1 [gnocl::button -icon "%#News" -text News]
set but2 [gnocl::button -icon "%#White" -text White]
set but3 [gnocl::button -icon "%#Black" -text Black]
set but4 [gnocl::button -icon "%#Georgie" -text Black]
$box add [list  $but1 $but2 $but3 $but4 ]
gnocl::window -child $box
gnocl::mainLoop

gnocl::stockItem

Gtk has support for stock items as well as loading graphics into containers. What has been needed for sometime is the creation of application specific stock items. This is now possible with the new gnocl::stockItem command. Although there's a lot of fiddly work done 'under the bonnet', the Tcl binding is quite simple:

gnocl::stockItem add -label News -icon [pwd]/news.png

The stock item can then be repeatedly accessed, all resizing etc out large graphics is all taken care of! For example:

set but4 [gnocl::button -icon "%#News" -text News]

The next step is to allow the creation of stockitems from pixbufs. This might be useful to someone for creating widget buttons that need refreshing.

Tuesday, October 05, 2010

gnocl::toggleButton new option -icon

Hitherto support for the gnocl::toggleButton was minimal. It displayed as text label and that was it. Like other widgets in its class, the togglebutton is also capable of displaying an icon. This it can now do via the new -icon option. All the ususal string formatting options apply.

Sunday, October 03, 2010

gnocl::toolbar menubutton item

Just finished putting the final touches together on implementing this new addition to the toolbar options. The Gtk+ toolbar menu button offers an interesting way of tackling things. As expected it provides the option to select items from a pull-down menu but it also allows a widget to be embedded in the menu item too. The only issue I had was getting the signal handlers working for the icon widget. Somehow I've got separate click signal handlers for both the widget and menu down arrow. Ok, there's a "show-menu" signal for the menu which is what is really called for, but who knows? It might be useful to someone so I'll leave it in.

It's late now (1am) and so I think its best to leave the documentation till the morning.

Saturday, September 25, 2010

gnocl::toolbar -updating

The toolbar has received my attention this week. Apart from the menubutton item requiring inclusion, the core of this module relies upon library functions deprecated since Gtk 2.4! Don't worry about script incompatibilities however as these are not an issue. I'm currently re-working the innards of this module to bring it up to date and when its completed the changes will only externally appear as a set of increased commands and options.



Monday, September 20, 2010

gnocl::abiwidget -job done!!

Well, I've now completed the implementation of all the available signal bindings supported by the Abiwidget API. There are some notable lacunae (gaps) in the level of support offered by the API is itself. Certain features that I would have expected such as document clear (rather than open a new Abiword window), document set-up, text highlighting, and direct table cel addressing would have been most desirable. As would direct access to print functions too! But, lets hope that there's more to come in this area as the last update to the module appears (maybe I'm wrong) to have been completed in 2007.

Anyway, here the latest screenshot showing entries and toggles providing feedback on the various settings of  the displayed text.




I quite like Abiword and will be exploring how to use it within some of my text processing applications. There are some 'quirks' such as the undo/redo operations and the canvas can leave drag lines a little when scrolling, but hey, that's something that can be lived with.

Finally, my gnocl megawidgets package has a rich text editing bar. This could do with revisting in order to enable it to be used in conjunction with with this new widget.




Sunday, September 19, 2010

gnocl::abiwidget signal bindings

After eating a great dinner cooked by my wife and watching tonight's episode of X-Factor, I came back to my machine and completed the first batch of signal bindings. These simply return boolean values - ideal for setting against variables to control button toggle  (i.e.. text formatting) or activation (i.e. undo/redo).

-onBold
-onItalic
-onUnderline
-onOverline
-onTopline
-onBottomline
-onSuperscript
-onSubscript
-onCanUndo
-onCanRedo
-onIsDirty
-onLeftAlign
-onCenterAlign
-onRightAlign
-onJustifyAlign
-onTextSelected
-onImageSelected
-onSelectionCleared
-onEnterSelection
-onLeaveSelection
-onTableState


The percentage substitution strings for these items current have two items %w (widget name) and %v value 0 or 1. It's probably an academic exercise only, but I think that I will add a further item. %t for signal/event type. But, that will have to wait till the morning.

The code is available from the SourceForge nightly build.

gnocl::widget -almost done ----- progress so far

The list below provides an overview of the current gnocl::abiwidget commands and any relevant subcommands. Looking at the abiwidget source code shows that there are no 'properties' as typically associated with Gtk+ widgets. This is understandable really as what appears to be here is access to the functionality branched into from the Abiword control loop. This is great as it results in speedy completion of this package. What is strikingly apparent is that there are (at least so far anyway) no options. Nor are there any styles. In practical terms this is a megawidget. Certain functionality is not directly obvious, print for example, but the default Abiword key bindings are still in place (Ctrl-P for instance will bring up the print dialog). Unless something else turns up when I read through the code, then such functionality might be evoked using a signal emit. Interestingly, I found no 'clear' function. Ctrl-N will result in a fully rendered Abiword window!

The next step for me is to implement signal handlers. These were probably set up for the management of toggle buttons etc. As there are are only three signal callback prototypes, again I think that this will be simple to complete.

As detailed documentation for the Abiwidget is practically none-existent, the behaviour of some of these commands needs a little more observation before deciding what's actually happening. Most of them, however, are self-explanatory.

    o load
    o save
    o clear (stub-only)
    o class
    o delete
    o undo
    o redo
    o cut
    o copy
    o paste
        o subcommand
            special

    o align
        o subcommand
            center
            justify
            right
            left

    o select
        o subcommands
            all
            block
            line
            word
            bob
            bod
            bol
            bow
            eob
            eod
            eol
            eow
            left
            right
            nextLine
            pageDown
            prevLine
            screenDown
            screenUp
            to

    o erase
        o subcommands
            bob
            bod
            bol
            bow
            eob
            eod
            eol
            eow
            left
            right

    o insert
        o subcommands
            data
            space
            table
            image

    o edit
        o subcommands
            header
            footer

    o file
        o subcommands
            open
            save

    o remove
        o subcommands
            header
            footer

    o toggle
        o subcommands
            bold
            underLine
            bottomLine
            insertMode
            italic
            overLine
            plain
            strike
            sub
            super
            topLine
            unindent
            bullets
            numbering

    o view
        o subcommands
            marks
            print
            normal
            onLine

    o moveto
        o subcommands
            bob
            bod
            bol
            bop
            bow
            eob
            eod
            eol
            eow
            left
            right
            nextLine
            nextPage
            nextScreen
            prevLine
            prevPage
            prevScreen

    o zoom
        o subcommands
            whole
            width

    o set
        o subcommands
            showMargin
            wordSelections
            fontName
            fontSize
            style
            textColor
            zoom
            page
            authors

    o get
        o subcommands
            showMargin
            wordSelections
            fontNames
            zoom
            page
            pageCount
            pointer
            authors

    o find
        o subcommands
            string
            prev
            next


Saturday, September 18, 2010

Progress, progress, progress.....

What a productive day! Most of the gnocl::abiwidget code completed now and I'm quite pleased with myself, so far 950 lines of (apparently) bug free code. I wish that implementing other packages such as the pixbuf were as easy.

In fact, most of the code is recycling a standard switch block but, there's lots of them and many are nested too.

I've already uploaded a nightly build to Sourceforge. So, here's the latest development screenshot. I think that its full of many of those expected features.... nice....