Round Corner Text Widget

Just wanted to share some cool text widgets with rounded corners. There are a lot of tricks you could use tile for which is not immediately apparent. In this case i use my tkpath package http://tclbitprint.sf.net/ to make the images but you can make them separately. I think there is a problem on XP using GDI+ where I didn't manage to add an alpha layer to the offscreen pixmaps, but since it works in the canvas which is using offscreen areas for drawing, I have made a mistake somewhere when creating the surfaces.

These examples are optimized for Mac. First two with slightly different appearance:

http://coccinella.sourceforge.net/images/RoundTextWidget.gif

The second text widget also draws a focus "rectangle":

http://coccinella.sourceforge.net/images/RoundTextWidgetFocus.gif

package require tkpath
package require Ttk

set str "All MSN Messenger wannabies:\nDid you know how to make text widgets with rounded corners?"
set size 32
set tkpath::antialias 1
set S [::tkp::surface new $size $size]
$S create prect 2 2 30 30 -rx 10 -fill white -stroke "#a19de2" \
  -strokewidth 2
set image [$S copy [image create photo]]
$S destroy

ttk::style element create RR.background image $image \
  -border {12 12 12 12} -padding {0} -sticky news
ttk::style layout RR.TEntry {
    RR.background -sticky news -children {
        Entry.padding -sticky news -children {
            Entry.textarea -sticky news
        }
    }
}
ttk::style map RR.TEntry  \
  -foreground {{background} "#363636" {} black}

toplevel .tt
set f .tt.f
ttk::frame $f -padding 20
pack $f -fill x
ttk::frame $f.cont -style RR.TEntry
pack $f.cont
text $f.t -wrap word -borderwidth 0 -highlightthickness 0 \
  -width 40 -height 6
bind $f.t <FocusIn>  [list $f.cont state focus]
bind $f.t <FocusOut> [list $f.cont state {!focus}]
pack $f.t -in $f.cont -padx 6 -pady 6 -fill both -expand 1

$f.t insert end $str

# WIth Aqua style focus ring.
set S [::tkp::surface new $size $size]
$S create prect 3 3 29 29 -rx 10 -fill white -stroke "#c3c3c3" \
  -strokewidth 2
set imborder [$S copy [image create photo]]
$S destroy

set S [::tkp::surface new $size $size]
$S create prect 3 3 29 29 -rx 10 -fill white -stroke "#c3c3c3" \
  -strokewidth 3
$S create prect 0.5 0.5 31.5 31.5 -rx 12 -stroke "#afc9e1"
$S create prect 1.5 1.5 30.5 30.5 -rx 11 -stroke "#93b8d9"
$S create prect 2.5 2.5 29.5 29.5 -rx 10 -stroke "#81a7ca"
set imfocus [$S copy [image create photo]]
$S destroy

ttk::style element create RRAqua.background image $imborder \
  -border {12 12 12 12} -padding {0} -sticky news 
  #-map [list {focus} $imfocus]
ttk::style layout RRAqua.TEntry {
    RRAqua.background -sticky news -children {
        Entry.padding -sticky news -children {
            Entry.textarea -sticky news
        }
    }
}
ttk::style map RRAqua.TEntry  \
  -foreground {{background} "#363636" {} black}

set f .tt.aqua
ttk::frame $f -padding 20
pack $f -fill x
ttk::frame $f.cont -style RRAqua.TEntry
pack $f.cont
text $f.t -wrap word -borderwidth 0 -highlightthickness 0 \
  -width 40 -height 6 -font {{Lucida Grande} 16}
bind $f.t <FocusIn>  [list $f.cont state focus]
bind $f.t <FocusOut> [list $f.cont state {!focus}]
pack $f.t -in $f.cont -padx 7 -pady 7 -fill both -expand 1

$f.t insert end $str