namespace eval ::stickies {
variable stickies
array set stickies {
Font "Verdana 9"
Count 0
Animate 1
Padding {2 15 2 2}
DefaultWidth 175
DefaultHeight 150
MenuFont "Tahoma 8"
Background "#ffff80"
StickyPopup ".stickyPopup"
StickyPrefix ".sticky"
BorderBackground "#ffdf00"
}
}
proc ::stickies::init {} {
variable stickies
package require Tk 8.4
set m [menu $stickies(StickyPopup) -tearoff 0 -font $stickies(MenuFont)]
$m add command -label "Delete Note" \
-command ::stickies::DeleteSticky -font "$stickies(MenuFont) bold"
if {[string equal $::tcl_platform(platform) "windows"]} {
if {[package vsatisfies $::tk_patchLevel 8.4.8]} {
$m add command -label "Set Transparency" \
-command ::stickies::SetTransparency -font "$stickies(MenuFont)"
}
$m add separator
$m add checkbutton -label "Always on Top" \
-command ::stickies::AlwaysOnTop
}
}
proc ::stickies::NewSticky {} {
variable stickies
set top $stickies(StickyPrefix)[incr stickies(Count)]
set stickies($top,ontop) 0
toplevel $top -background $stickies(BorderBackground)
wm withdraw $top
update idletasks
wm geometry $top 1x1
wm override $top 1
bind $top <3> [list ::stickies::PostPopup $top %X %Y]
bindtags $top [list $top Toplevel $top StickyNote all]
bind StickyNote <1> [list ::stickies::GrabSticky %W %X %Y]
bind StickyNote <Motion> [list ::stickies::StickyMotion %W %X %Y]
bind StickyNote <B1-Motion> [list ::stickies::DragSticky %W %X %Y]
set padding $stickies(Padding)
text $top.t -relief flat -background $stickies(Background) \
-font $stickies(Font) -wrap word
pack $top.t -expand 1 -fill both \
-padx [list [lindex $padding 0] [lindex $padding 2]] \
-pady [list [lindex $padding 1] [lindex $padding 3]]
if {$stickies(Animate)} {
::stickies::AnimateSticky $top
} else {
wm geometry $top $stickies(DefaultWidth)x$stickies(DefaultHeight)
}
wm deiconify $top
focus $top.t
}
proc ::stickies::AnimateSticky { window {w 0} {h 0} } {
variable stickies
wm deiconify $window
incr w 10
incr h 10
if {$w > $stickies(DefaultWidth)} { set w $stickies(DefaultWidth) }
if {$h > $stickies(DefaultHeight)} { set h $stickies(DefaultHeight) }
wm geometry $window ${w}x${h}
update idletasks
if {$w != $stickies(DefaultWidth) || $h != $stickies(DefaultHeight)} {
after 5 [list ::stickies::AnimateSticky $window $w $h]
}
return
}
proc ::stickies::PostPopup { window X Y } {
variable stickies
set stickies(ActiveSticky) $window
$stickies(StickyPopup) post $X $Y
}
proc ::stickies::DeleteSticky { {window ""} } {
variable stickies
if {![string length $window]} { set window $stickies(ActiveSticky) }
destroy $window
}
proc ::stickies::SetTransparency { {window ""} } {
variable stickies
if {![string length $window]} { set window $stickies(ActiveSticky) }
set top $stickies(StickyPrefix)__set_transparency
toplevel $top
wm title $top "Set Transparency"
wm withdraw $top
wm geometry $top +[winfo x $window]+[winfo y $window]
wm resizable $top 0 0
set ::stickies::alpha [wm attributes $window -alpha]
scale $top.scale -orient horizontal -from 0.0 -to 1.0 \
-width 10 -length 150 -resolution .01 -showvalue 0 \
-variable ::stickies::alpha \
-command [list ::stickies::SetWindowAlpha $window]
pack $top.scale -side left -expand 1 -fill both
button $top.ok -text "OK" -width 10 -command [list destroy $top]
pack $top.ok -side left
$stickies(StickyPopup) unpost
update idletasks
wm deiconify $top
}
proc ::stickies::SetWindowAlpha { window value } {
wm attributes $window -alpha $value
update idletasks
}
proc ::stickies::AlwaysOnTop { {window ""} } {
variable stickies
if {![string length $window]} { set window $stickies(ActiveSticky) }
set stickies($window,ontop) [expr $stickies($window,ontop) ? 0 : 1]
puts "$window - $stickies($window,ontop)"
wm attributes $window -topmost $stickies($window,ontop)
puts "$window - $stickies($window,ontop) - [wm attributes $window]"
$stickies(StickyPopup) unpost
update idletasks
}
proc ::stickies::StickyMotion { window X Y } {
variable stickies
set minX [winfo x $window]
set minY [winfo y $window]
set maxX [expr {$minX + [winfo width $window]}]
set maxY [expr {$minY + [winfo height $window]}]
set x1 [expr {$X - 8}]
set x2 [expr {$X + 8}]
set y1 [expr {$Y - 4}]
set y2 [expr {$Y + 4}]
set cursor ""
set stickies(dir) ""
if {$x1 < $minX} {
set cursor sb_h_double_arrow
set stickies(dir) w
}
if {$x2 > $maxX} {
set cursor sb_h_double_arrow
set stickies(dir) e
}
if {$y1 < $minY} {
set cursor sb_v_double_arrow
set stickies(dir) n
}
if {$y2 > $maxY} {
set cursor sb_v_double_arrow
set stickies(dir) s
}
if {$x2 > $maxX && $y2 > $maxY} {
set cursor size_nw_se
set stickies(dir) se
}
if {$x1 < $minX && $y1 < $minY} {
set cursor size_nw_se
set stickies(dir) nw
}
if {$x2 > $maxX && $y1 < $minY} {
set cursor size_ne_sw
set stickies(dir) ne
}
if {$x1 < $minX && $y2 > $maxY} {
set cursor size_ne_sw
set stickies(dir) sw
}
$window configure -cursor $cursor
update idletasks
}
proc ::stickies::GrabSticky { window X Y } {
variable stickies
if {![string length $stickies(dir)]} {
set stickies(Xoffset) [expr {[winfo x $window] - $X}]
set stickies(Yoffset) [expr {[winfo y $window] - $Y}]
} else {
set stickies(Xoffset) $X
set stickies(Yoffset) $Y
}
set stickies(x) [winfo x $window]
set stickies(y) [winfo y $window]
set stickies(width) [winfo width $window]
set stickies(height) [winfo height $window]
}
proc ::stickies::DragSticky { window X Y } {
variable stickies
if {![string length $stickies(dir)]} {
set x [expr {$X + $stickies(Xoffset)}]
set y [expr {$Y + $stickies(Yoffset)}]
wm geometry $window +${x}+${y}
return
}
set adjX [expr {$X - $stickies(Xoffset)}]
set adjY [expr {$Y - $stickies(Yoffset)}]
set x $stickies(x)
set y $stickies(y)
set width $stickies(width)
set height $stickies(height)
switch -- $stickies(dir) {
"n" {
set y $Y
set height [expr {$stickies(height) - $adjY}]
}
"e" {
set width [expr {$stickies(width) + $adjX}]
}
"s" {
set height [expr {$stickies(height) + $adjY}]
}
"se" {
set width [expr {$stickies(width) + $adjX}]
set height [expr {$stickies(height) + $adjY}]
}
}
if {$width <= 0 || $height <= 0} { return }
wm geometry $window ${width}x${height}+${x}+${y}
update idletasks
}
## A little demo code.
::stickies::init
button .b -text "New Sticky" -command ::stickies::NewSticky
pack .b -expand 1 -fill bothMG Dec 16th - Very nice, DC. This code could be really useful in a wide variety of applications, IMHO, as well as being a great example for people. One thing that would make it more useful, though, is if you could keep an entry for the sticky notes in the taskbar when it's used on Windows, so they don't get lost if -topmost isn't on. Anyone know if there's a way to do that? I tried the [wm attributes -toolwindow] option, and [wm transient], but neither worked...
ABU 5-Oct-2005 - Sticky 1.0 announceABU 28-Nov-2005 - Sticky 2.0 announceBased on the original work of Damon, this is a screenshot of my little big application
Sticky allows you to stick small pieces of paper over your desktop.- You can use it to write down your notes.
- You can easily move, resize, change the colors and fonts used in these sticky-notes.
- All the sticky-notes are automatically saved on exiting (see .sticky.ini in your home directory)
set DataDir [expr { $tcl_platform(platform) eq "windows" ? \
[file join $env(USERPROFILE) "Application Data" "APPNAME"] : \
[file normalize "~/.APPNAME"] \
}]escargo 7 May 2007 - I started using a Windows desktop manager, Yod'm 3D. The virtual desktops appear to confuse Stickies so that it disappears. Is there an easy way to extract all the information in all the notes? I didn't find anything obvious in .sticky.ini.
ABU 9 May 2007 - It's not so difficult. Since ".sticky.ini" is not a pure data file, but it's a simple tcl-script, all we need is to redefine the "stickyNote create ..." command, and ignore all others commands ("wm ...").Here is a script
# dummy declaration
namespace eval stickyNote {}
# disable the "wm" command
rename wm _wm
proc wm args {}
proc stickyNote { createCmd objID args } {
puts "#######################################"
foreach {op val} $args {
# better to remove trailing blancs
set val [string trim $val]
puts "<$op><$val>"
}
puts "#######################################"
}
source [file join ~ .sticky.ini]ABU 30 Mar 2013 All previous versions of sticky are now available at [3].

