Updated 2013-09-01 23:42:27 by RLE

Demonstration of Wiklets

Notable Features of Wiklets

  • A Wiklet is a Tclet whose source code and execution mechanism are provided by a Wiki page
  • Several Wiklets may coexist on the same Wiki page
  • The Tcl source code for a Wiklet is carried in one or more "pre-formatted" text blocks on the Wiki page
  • Source code in a "pre-formatted" text block may be used by more than one Wiklet
  • The first line of a "pre-formatted" text block determines whether and how the block contributes to the source code of the page's Wiklets. It also determines how the Wiklet is executed (not at all, in a separate window, or embedded in the Wiki page).

At the time of writing (2006-06-22),

  • the pages http://wiki.tcl.tk/16093 and http://www.kerlin.net/22 have the same Wiki-markup source.
  • the version of Wikit that serves the first URL does not display Wiklets. The second URL is a page saved from a server with a patched version of Wikit, and does display Wiklets.
  • The patched version of Wikit is available as a starkit from [1]. The patch (against the current starkit and CVS of Wikit, which are identical) is at [2].
  • For further discussion of Wiklets, see [3]

The Tclets shown on this page as Wiklets are copied from the Tcl Developer Xchange and the Tcler's Wiki. If you cannot see the Wiklets, please make sure that you are viewing http://www.kerlin.net/22 and that you have the Tcl Browser Plugin correctly installed.

Draggable Text Demo from the Tcl Developer Xchange, at http://www.tcl.tk/software/plugin/draghello.html

You can move the text around by clicking it with the left mouse button and dragging the mouse:
 # wiklet 3 300 200 embed
 proc dragstart {w x y} {
    global draglocation

    catch {unset draglocation}
    set draglocation(obj) [$w find closest $x $y]
    set draglocation(x) $x
    set draglocation(y) $y
 }
 proc dragit {w x y} {
    global draglocation

    if {$draglocation(obj) != ""} {
        set dx [expr {$x - $draglocation(x)}]
        set dy [expr {$y - $draglocation(y)}]
        $w move $draglocation(obj) $dx $dy
        set draglocation(x) $x
        set draglocation(y) $y
    }
 }
 canvas .c -bg bisque
 .c create text 50 50 -text Hello -font {Times 18 bold} -tag movable -fill red
 .c create text 100 100 -text World -font {Times 18} -tag movable -fill blue
 .c bind movable <Button-1>  {dragstart %W %x %y}
 .c bind movable <B1-Motion> {dragit    %W %x %y}
 pack .c -fill both -expand 1

Kaleidoscope by Richard Suchenwirth, from http://wiki.tcl.tk/12385

The following block of code is loaded by two independent Wiklets (numbered 1 and 4). The Wiklet launchers are lower down the page, where the individual Wiklets are defined.
 # wiklet {1 4}
 package require Tk

 proc kaleidoscope w {
    $w delete all
    foreach color {red green blue yellow magenta cyan} {
        random'triangle $w $color
    }
    foreach item [$w find withtag ori] {
        $w raise $item
        set item2 [poly'copy $w $item 1 -1]
        foreach angle {60 120 180 240 300} {
            poly'rotate $w [poly'copy $w $item] $angle
            poly'rotate $w [poly'copy $w $item2] $angle
        }
    }
 }
 proc random'triangle {w color} {
    set x0 [expr     {rand()*150-75}]
    set y0 [expr     {rand()*150-75}]
    set x1 [expr {$x0+rand()*150-75}]
    set y1 [expr {$y0+rand()*150-75}]
    set x2 [expr {$x1+rand()*150-75}]
    set y2 [expr {$y1+rand()*150-75}]
    $w create poly $x0 $y0 $x1 $y1 $x2 $y2 -fill $color \
         -tag ori
 }
 proc poly'rotate {w item angle} {
    set delta [expr {$angle/180.*acos(-1)}]
    foreach {x y} [$w coords $item] {
        set r [expr {hypot($y,$x)}]
        set a [expr {atan2($y,$x)+$delta}]
        lappend coords [expr {cos($a)*$r}] [expr {sin($a)*$r}]
    }
    $w coords $item $coords
 }
 proc poly'copy {w item {fx 1} {fy 1}} {
    foreach {x y} [$w coords $item] {
        lappend coords [expr {$x*$fx}] [expr {$y*$fy}]
    }
    $w create poly $coords -fill [$w itemcget $item -fill] \
        -stipple [$w itemcget $item -stipple]
 }

Here are two independent Kaleidoscope Wiklets. The block of code above is loaded by each Wiklet. The Wiklets differ in their unshared code (below): in this example they have different screen sizes.

Click on the 200x200 Wiklet to generate a new pattern:
 # wiklet 1 200 200 embed
 pack [canvas .c -width 200 -height 200 -background white]
 .c config -scrollregion {-100 -100 100 100}
 kaleidoscope .c
 bind .c <1> {kaleidoscope %W}

Click on the 250x250 Wiklet to generate a new pattern:
 # wiklet 4 250 250 embed
 pack [canvas .c -width 250 -height 250 -background white]
 .c config -scrollregion {-125 -125 125 125}
 kaleidoscope .c
 bind .c <1> {kaleidoscope %W}

#-- Development helpers, including how to make screenshots:
 # not part of the wiklet!
 bind . <Escape> {exec wish $argv0 &; exit}
 bind . <F1>     {console show}
 set n 0
 bind . <F2>     {
    package req Img; [image create photo -data .c] write kal[incr n].gif
 }

TkRose by Keith Vetter, from http://wiki.tcl.tk/8295

This Wiklet is not embedded in this page, because it is best seen in a large window. Click the link to open it in a new window - the application is resizable if your browser permits this (most do, even though the Wiklet code that opens the window specifies resizable=no).

I had to remove the 'about' box to make the application run as a Tclet (it was designed as a standalone application), so for the avoidance of doubt I will repeat that TkRose is the work of Keith Vetter and is published at http://wiki.tcl.tk/8295
 # wiklet 2 550 400
 #################################################################
 #
 # Tkrose.tcl -- draws a rosette with various number of lobes.
 # Each lobe has 2nd derivative smoothness with the next lobe.
 # Keith Vetter
 #
 # KPV Oct 14, 1994 - original version for class UCB CS285
 # KPV Jan 29, 2003 - cleaned up, rewrote display logic for faster machines
 # KJN Jun 22, 2006 - about box removed to make the app run as a Tclet
 #

 package require Tk
 array set S {lobes 12 next 2 power 100 lwidth 5 color black}

 proc DoDisplay {} {
    global S

    wm title . TkRose
    option add *Scale.highlightThickness 0
    option add *Scale.relief ridge
    option add *Scale.orient horizontal
    pack [frame .top -relief raised -bd 2] -side top -fill x
    pack [frame .bottom] -side bottom -fill x
    canvas .c -relief raised -borderwidth 4 -height 700 -width 612
    pack .c -side top -expand 1 -fill both

    set colors {red orange yellow green blue cyan purple violet white}
    lappend colors [.c cget -bg] black
    foreach color $colors {
        radiobutton .top.b$color -width 1 -padx 0 -pady 0 -bg $color \
            -variable S(color) -value $color \
            -command [list .c itemconfig rose -fill $color]
        bind .top.b$color <3> [list .c config -bg $color]
    }
    eval pack [winfo children .top] -side left -fill y

    scale .sLobes -from 3 -to 50 -label "Lobes" -variable S(lobes) \
        -command DrawRosette
    scale .sLWidth -from 1 -to 40 -label "Line Width" -variable S(lwidth) \
        -command {.c itemconfig rose -width }
    scale .sNext -from 1 -to [expr {($S(lobes)-1)/2}] -label Interval \
        -variable S(next) -command DrawRosette
    scale .sPower -from 1 -to 100 -label "Power (%)" -variable S(power) \
        -command DrawRosette
    pack .sLobes .sNext .sPower .sLWidth -in .bottom -side left
    catch {image create photo ::img::blank -width 1 -height 1}
    button .about -image ::img::blank -highlightthickness 0 -command {
      #  Sorry, had to comment this out because it opens a toplevel which is not allowed in a Tclet
      #  tk_messageBox -title "About" -message "by Keith Vetter\nJanuary, 2003"}
    place .about -in .bottom -relx 1 -rely 0 -anchor ne
    update
    bind .c <Configure> DrawRosette
 }
 #+###############################################################
 #
 # DrawRosette -- routine that actually draws the rosette.
 #
 proc DrawRosette {args} {
    global S

    .c delete rose                              ;# Erase old picture
    set cx [expr {[winfo width .c] / 2}]        ;# Center of the canvas
    set cy [expr {[winfo height .c] / 2}]
    set sc [expr {.8 * ($cx < $cy ? $cx : $cy)}];# Scaling factor
    set pow [expr {$S(power) / 100.0}]

    set n $S(lobes)                             ;# How mnay lobes
    set k $S(next)                              ;# Number of lobes over

    set beta [expr 360.0 / $n]                  ;# Center of each lobe
    set gamma [expr 180 - $k*360.0/$n]          ;# Arc area of each lobe
    set r2d [expr 3.14159/180]                  ;# Degrees into radians factor
    .sNext config -to [expr {($S(lobes)-1)/2}]

    for {set l 0} {$l < $n} {incr l} {          ;# For each lobe
        set xy [list $cx $cy]                   ;# Coordinates for the lobe
        for {set theta 0} {$theta < $gamma} {incr theta} { ;# Polar angle

            set a [expr {$theta * 180.0 / $gamma}] ;# Angle in 0-180 range
            set a1 [expr {$theta + $l*$beta - $gamma/2}]

            set r [expr {sin ($a * $r2d)}]      ;# Distance from center
            if {$pow != 1} {
                set r [expr {pow($r,$pow)}]     ;# Adjust the distance
            }
            set x [expr {$r * cos ($a1 * $r2d)}] ;# Cartesian coordinates
            set y [expr {$r * sin ($a1 * $r2d)}]

            set x [expr {$x * $sc + $cx}]       ;# Scale and shift
            set y [expr {-$y * $sc + $cy}]
            lappend xy $x $y
        }
        lappend xy $cx $cy
        .c create line $xy -fill $S(color) -tag rose -width $S(lwidth)
    }
 }
 DoDisplay
 DrawRosette

Here's a mangled Wiklet Instruction that the server catches
 # wiklet {1 2
 # deliberately bad command - an invalid list

Here's another
 # wiklet \{ 84 36 embed
 # deliberately bad command - a valid list with an element that is an invalid list

If you are viewing this page at http://www.kerlin.net/22, then the links below will not do anything useful. http://www.kerlin.net/22 is a static page saved from a server with the Wiklet-enabled patched version of Wikit, but kerlin.net does not itself serve Wikit.