aleksanteri, 6th of March 2008. I made this little color selector in a few hours when I was bored. Now I got it finished and decided to post it here :)
2016-01-05: a simplified and abbreviated version (0.2) has been added below.
# we need tk. package require Tk ################################################################################ # procedures - the stuff working in the background ################################################################################ proc colorup {amount} { # clear the entrybox .viewhex delete 0 end # get hexadecimal numbers set red [dectohex [.red get]] set green [dectohex [.green get]] set blue [dectohex [.blue get]] # build the color code set rgb "#$red$green$blue" # display the color code .view configure -bg $rgb .viewhex insert end $rgb } proc entryup {} { set rgb [.viewhex get] # check length of $rgb switch -- [string length $rgb] { 7 { # 7 - #rrggbb. check that # is the first character regexp {(.).+} $rgb -> hashchar if { $hashchar != "#"} { return 1; } } 4 { # 4 - #rgb. check syntax and extend it if [regexp {#(.)(.)(.)} $rgb -> num1 num2 num3] { set rgb "#$num1$num1$num2$num2$num3$num3" } else { return 1; } } default { # neither 7 or 4. we quit here return 1; } } # extract $red, $green and $blue from $rgb regexp {#(..)(..)(..)} $rgb -> red green blue # convert $red, $green and $blue from dec to hex set red [hextodec $red] set green [hextodec $green] set blue [hextodec $blue] # set the scales' values .red set $red .green set $green .blue set $blue } proc dectohex {amount} { # initialize $sixteens set sixteens 0 # make $sixteens $amount / 16, and $amount the remainder of it while {$amount >= 16} { set sixteens [expr $sixteens + 1] set amount [expr $amount - 16] } # change amounts into hex switch -- $amount { 15 { set amount F; } 14 { set amount E; } 13 { set amount D; } 12 { set amount C; } 11 { set amount B; } 10 { set amount A; } 0 - 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 { } default { set amount 0; } } switch -- $sixteens { 15 { set sixteens F; } 14 { set sixteens E; } 13 { set sixteens D; } 12 { set sixteens C; } 11 { set sixteens B; } 10 { set sixteens A; } 0 - 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 { } default { set sixteens 0; } } # return the amount back return $sixteens$amount } proc hextodec {amount} { # separate the two chars from each other regexp {(.)(.)} $amount -> num1 num2 # convert switch -- $num1 { F - f { set num1 15; } E - e { set num1 14; } D - d { set num1 13; } C - c { set num1 12; } B - b { set num1 11; } A - a { set num1 10; } 0 - 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 { } default { set num1 0; } } switch -- $num2 { F - f { set num2 15; } E - e { set num2 14; } D - d { set num2 13; } C - c { set num2 12; } B - b { set num2 11; } A - a { set num2 10; } 0 - 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 { } default { set num2 0; } } # build the number and return it return [expr ($num1 * 16) + $num2] } ################################################################################ # gui code ################################################################################ # set the window title wm title . "colorsel 0.1" # labels label .redlabel -text "Red" label .greenlabel -text "Green" label .bluelabel -text "Blue" # scales scale .red -from 0 -to 255 -length 350 -orient horizontal -command "colorup" scale .green -from 0 -to 255 -length 350 -orient horizontal -command "colorup" scale .blue -from 0 -to 255 -length 350 -orient horizontal -command "colorup" # color canvas canvas .view -bg #000000 -width 128 -height 64 # hexacode entry .viewhex -width 12 .viewhex insert end "#000000" # grid all these up grid .redlabel -row 0 -column 0 grid .greenlabel -row 1 -column 0 grid .bluelabel -row 2 -column 0 grid .red -row 0 -column 1 grid .green -row 1 -column 1 grid .blue -row 2 -column 1 grid .view -row 0 -column 2 -rowspan 2 grid .viewhex -row 2 -column 2 # bind the entrybox to [entryup] bind .viewhex <KeyRelease> entryup
This version does a little less unnecessary processing, but is wart-compatible with the original.
package require Tk proc colorup amount { .viewhex delete 0 end set rgb # # get hexadecimal numbers and build the color code append rgb [format %02X [.red get]] append rgb [format %02X [.green get]] append rgb [format %02X [.blue get]] # display the color code .view configure -bg $rgb .viewhex insert end $rgb } proc entryup {} { set rgb [.viewhex get] switch -regexp -matchvar m $rgb { {^#([[:xdigit:]]{2})([[:xdigit:]]{2})([[:xdigit:]]{2})$} { set values [lrange $m 1 end] } {^#([[:xdigit:]])([[:xdigit:]])([[:xdigit:]])$} { set values [lmap x [lrange $m 1 end] {string cat $x $x}] } default {return 1} } foreach w {.red .green .blue} val $values { $w set [scan $val %x] } } # gui code # set the window title wm title . "colorsel 0.2" # labels label .redlabel -text Red label .greenlabel -text Green label .bluelabel -text Blue # scales scale .red -from 0 -to 255 -length 350 -orient horizontal -command colorup scale .green -from 0 -to 255 -length 350 -orient horizontal -command colorup scale .blue -from 0 -to 255 -length 350 -orient horizontal -command colorup # color canvas canvas .view -bg #000000 -width 128 -height 64 # hexacode entry .viewhex -width 12 # grid all these up grid .redlabel .red .view grid .greenlabel .green ^ grid .bluelabel .blue .viewhex # bind the entrybox to [entryup] bind .viewhex <KeyRelease> entryup