[uniquename] - 2012aug06 Way back around 1998 when I was first learning the Tcl-Tk language, I would do web searches on keyword strings such as 'usr bin wish button' or 'usr bin wish scale rgb' to find examples of complete Tcl-Tk scripts --- because the code 'snippets' in Tcl-Tk books and tutorials were not very helpful in creating 'production' scripts (relatively quickly). In doing those kinds of web searches, I ran across a Tcl-Tk script that offered a nice, simple color selector GUI consisting of 3 'scale' widgets for setting RGB values (from 0 to 255) --- along with a 'frame' widget color-swatch for dynamically showing the color as the user moved any of the three scale-sliders with the left mouse button. I used the word 'non-obfuscated' in the title of this page because many of the color selectors that I have seen are quite confusing. They hit my eyes with so many features --- color shaded disks, RGB sliders, HS-whatever sliders, etc. etc. --- that I get a headache (and waste too much time) trying to figure out how to use them. This color selector is so simple that it is obvious 'from the git-go' how to use it. And yet it has done all that I need it to do in all the 'use cases' that I have encountered so far. The original script was posted in a web page for a computer science class, probably by a professor or student at an Australian university (USQ = the University of Southern Queensland). When I tried going back to the web page around 2004, I found it was gone. So I am glad that I 'harvested' that script code before it disappeared into that great bit bucket in the sky. (The URL for that dearly-departed Australian web page is in the comments of the code below.) ------ '''Changes to the Australian script :''' I changed the original script quite a bit. Some of the changes that I can remember are: 1) The 'place' geometry manager was originally used in the script. I '''switched to''' the '''pack''' command. 2) The original script showed the current RGB value in '#rrggbb' hex format, in a label widget. Like the color swatch, the hex values changed dynamically as the sliders were moved with the mouse. I '''changed''' the '''label widget to a text widget''', so that one could copy-and-paste the hex-string with a 'left mouse button swipe' for the 'copy' and a middle-mouse-button click for the 'drop' ('paste') --- handy for pasting into a text editor window containing some Tk code or some HTML code. I also '''added''' a text widget to show the RGB values (between 0 and 255) as '''percents''' (between 0 and 100). 3) Using a '''pack forget''' command technique, I made a '''Toggle-Side button''' on the GUI so that I could quickly switch the color swatch from one side of the GUI to the other. 4) I made a '''"put_vars" proc''' that uses 'puts' to output the current RGB values (decimal and hex), when a 'UseIt' button is clicked --- so that I can use the color selector GUI within shell scripts and within other Tcl-Tk scripts --- to pass a selected RGB value back to the calling script. 5) There are a lot of changes that I made to the script to share parameter setting code that is used in other Tk scripts of mine. 6) The '''font setting code''' was '''updated''' to use the newer constructs in Tk that came in 8.x releases of Tk. 7) I '''added''' some '''argc,argv''' code to, optionally, accept initial RGB values from the command line. 8) I added some 'catch' statements to, optionally, '''accept''' initial '''RGB''' values '''from environment variables''' --- R255, G255, B255. 9) I added some 'catch' statements to, optionally, accept window and window-icon titles from environment variables --- and to, optionally, accept window geometry (location or location-and-size) from an environment variable. Here is an image of the resultant color selector GUI. [colorSelectorGUI_screenshot_572x194.png] After I retired and started assembling the software in my 'Freedom Environment' software system (see [http://www.freedomenv.com]), I used the color selector Tk script as a palette-color setting utility in the 'xpg', 'feAppMenus, and 'feHandyTools' subsystems of my Freedom Environment software. I provide all that FE code as free and open source code. A lot of the FE Tcl-Tk scripts (such as the code for the 'xpg' utility) are really too long for a page on this Tcl-Tk wiki. But the code for the color-selector utility is probably no longer than some of the longer scripts that have been presented here. So, to help make sure that the code from that Australian professor (along with my enhancements) does not disappear into the Internet Graveyard of Dead Links, here is a resurrection of the code. I have 'left in' many of my comments that explain the usage of the GUI and the structure and intent of the code. In my FE subsystems, I use some Tk 'include' files in my Tk scripts to provide some parameter setting that is shared with other utility scripts. I have replaced the corresponding 'source' statements with the essential Tk statements from those 'include' code-files. (Some of the 'include' statements involving parameters for 'listbox' and 'entry' and 'message' widgets, widgets not used in this GUI, may be left in this code --- but commented, for the most part. Those statments can be useful if other GUIs are made using this code as a starting point.) As I do with all my Tk scripts, I have put the four main pack parameters --- '-side', '-anchor', '-fill', '-expand' --- on the 'pack' command for the various frames and widgets. That helps me when I am initially testing the behavior of a GUI (the various widgets within it) as I resize the main window. For this particular GUI, I have used the statement ====== wm resizeable . 0 0 ====== to make the window (and its widgets) a fixed size --- since I have found no advantage in having the color swatch change size --- and no advantage to having the scale widgets change size. However, if anyone sees an advantage to allowing the GUI to change size, they can comment the 'wm resizeable' statement --- and then experiment with the '-side', '-anchor', '-fill', and '-expand' parameters on the 'pack' commands for the various widgets --- to get the widget behavior that they want. (Since I did some experimenting with the GUI before making it non-resizable, the pack parameters in this code are probably at reasonable settings. So if you comment out the 'wm resizeable' statement, the GUI elements may resize --- or not resize --- nicely as you change window size.) ====== #!/usr/bin/wish -f ## ##+####################################################################### ## NOTE: ## If the 'wish' interpreter is in another directory, like ## /usr/local/bin, you, as root, can make a soft-link from 'wish' there ## to /usr/bin/wish --- with a command like ## ln -s /usr/bin/local/wish /usr/bin/wish ## The form of this command: ## ln -s ##+####################################################################### ## Tk SCRIPT NAME: select_RGBcolor_standAlone.tk ## ## (also called 'sho_colorvals_via_sliders3rgb.tk') ## ## ('stand-alone' version --- no 'source' statements) ## (3 'scale' widgets for RGB colors) ## ## WHERE: in $FEDIR_TKGUIS = $FEDIR/tkGUIs ## ## where $FEDIR is the installation ## directory of an FE subsystem. ## Ref: www.freedomenv.com ##+####################################################################### ## PURPOSE: This TkGUI script provides a GUI for selecting Red-Green-Blue ## values, from 0 thru 255, via slider bars. ## ## For any slider bar change, this GUI script ## immediately shows the color as the background color of a ## frame widget (a 'color swatch') in a corner of the GUI ## window (covering about 20% of the window). ## ## Also the GUI shows the current color's hex (and per-cent) ## RGB values in two small text widgets about 12 characters long. ## ## SOME USES: ## ## 1) Useful in determining color specification in decimal ## or hex values to MATCH A GIVEN COLOR. (The user can drag ## this GUI to a portion of the screen, and use the slider bars ## to find color matches. Similarly, bring an image viewer ## window next to the GUI.) ## ## 2) Also useful in DETERMINING SUITABLE BACKGROUND COLORS ## for black/white text. ## ## 3) IN A SHELL SCRIPT OR ANOTHER TK SCRIPT, this Tk script can ## ACT AS A COLOR SELECTOR by passing the current color to stdout ## (in decimal and hex), when the OK/UseIt button is clicked. ## Example output string: 0 156 255 009CFF ## ##+####################################################################### ## SOURCE (and CREDIT-TO): ## ## This script was based on an example from Australia (circa 1999) at ## http://www.sci.usq.edu.au/~devoil/66309/tut2.html ## (Author's name unknown. The script may have been based on the Tk ## color selector GUI that was announced by Ousterhout around 1996. ## It may have been intended as a simplification of that GUI.) ## ## The 'place' commands in the Australian script were replaced by ## 'pack' commands. Also the per-cents display was added. ## ## The 'ToggleSide' button was added, to be able to switch the ## color swatch to the left side of the GUI. That helps, for ## example, when trying to find a color that matches the left ## side of the screen (the desktop background). ## ## The hex-RGB-code used to be shown in a label widget. ## It is now shown in a text widget so that the user can ## mouse-copy-and-paste the hex-RGB-code into another window, ## such as a text-editor window editing an HTML page or a ## Tk script. ## ##+##################################################################### ## CALLED BY: 'make_chest.tk' in $FEDIR_TKGUIS ## and 'shofil.tk' (the core of the 'xpg' utility) ## and probably by more FE scripts in the future. ##+##################################################################### ## INPUTS: The user slides the slider bars. Initial RGB vals can be set ## as described in the next section, 'CALL FORMAT'. ## ## OUTPUT: The color-swatch and hex-and-percent RGB values displayed on ## the Tk window. ## ## Also the last RGB slider settings are passed to stdout ## as a string giving decimal and hex values of the color. ## ## Sample output string: 0 156 255 009CFF ## ##+##################################################################### ## CALL FORMAT: ## ## $FEDIR_TKGUIS/sho_colorvals_via_sliders3rgb.tk [r255 g255 b255] ## ## where r255 g255 b255 represent integers between 0 and 255, ## and the values are ignored if there are not exactly three. ## If no values are entered, the defaults are 0 156 255 or ## some such triplet. ## ## OR ## ## use env vars R255, G255, B255 to initialize the sliders. ## ----------------------------------------------------------------------- ## EXAMPLE CALLS in a shell script: ## (Could also be called in a tcl-tk script. ## See the tcl-tk scripts mentioned in the ## 'CALLED BY' section above.) ## ## 1) R255=0 ## G255=156 ## B255=255 ## export R255 G255 B2555 ## ## TEMP=`$FEDIR_TKGUIS/sho_colorvals_via_sliders3rgb.tk` ## OR ## 2) ## TEMP=`$FEDIR_TKGUIS/sho_colorvals_via_sliders3rgb.tk 80 156 255` ## or ## TEMP=`$FEDIR_TKGUIS/sho_colorvals_via_sliders3rgb.tk` ## ## ## (Note: The values in TEMP can be extracted with a command like ## 'cut' or 'awk'.) ##+######################################################################## ## 'CANONICAL' STRUCTURE OF THIS CODE: ## ## 0) Set general window parms (win-name,win-position,color-scheme, ## fonts, widget-geom-parms,win-size-control). ## 1a) Define ALL frames (and sub-frames). ## 1b) Pack ALL the frames and sub-frames. ## 2) Define & pack all widgets in the frames. ## ## 3) Define key and mouse/touchpad/touch-sensitive-screen action ## BINDINGS, if needed. ## 4) Define PROCS, if needed. ## 5) Additional GUI INITIALIZATION (typically with one or two ## procs in section 4), if needed. ## ##+################################# ## The code structure in more detail, for this particular script: ## ## 1a) Define ALL frames: ## Top-level : 'fRsliders', 'fRpreview' , 'fRbottom' ## Sub-frames: 'fRsliders.red', 'fRsliders.green' , 'fRsliders.blue' ## ## 'fRsliders' and 'fRpreview' are to be on the top of the GUI, ## on the left and right, respectively. ## 'fRbottom' is to be on the bottom of the GUI. ## ## 1b) Pack ALL frames. ## ## 2) Define & pack all widgets in the frames -- basically going through ## frames & their interiors in top-to-bottom and/or left-to-right order: ## ## - 'fRsliders' (to contain 3 sliderbars) ## ## - 'fRpreview' (to contain only its background color; to display ## the color specified by the sliderbar settings) ## ## - 'fRbottom' (to contain several buttons and label & text widgets ## to display the current % [0 to 100] and hex [ 00 ## to FF ] RGB values of the color.) ## ## 3) Define BINDINGS: none currently ## ## 4) Define PROCS: ## - 'color_update' - for '-command' options on 3 RGB scales ## - 'toggle_side' - for ToggleSide button ## - 'put_vars' - for UseIt button ## - 'popup_msg_var_scroll' - for Help button ## ## 5) Additional GUI INITIALIZATION: none, except for setting ## the HELPtext var for the Help button. ## ##+####################################################################### ## DEVELOPED WITH: originally with (Tcl 7.4)-(Tk 4.0) on SGI/Irix (Unix) ## circa 1999 and lately (circa 2011) with Tcl-Tk 8.5 on ## Ubuntu 9.10 (2009 october, 'Karmic Koala). ## ## wish> puts "$tcl_version $tk_version" ## showed ## 7.4 4.0 ## then ## 8.5 8.5 ##+######################################################################## ## FE system Copyright 2006+ by Blaise Montandon ##+######################################################################## ## MAINTENANCE HISTORY: ## This Tk script is based on a sample Tk script found at ## http://www.sci.usq.edu.au/~devoil/66309/tut2.html in 1999. ##------------------------------------------------------------------------ ## Created by: Blaise Montandon 2008mar31 Started version for the FE ## system, on Linux, Mandriva 2007. ## ... ## ... ## Changed by: Blaise Montandon 2012aug Converted the 2011oct05 version that ## is/was used the FE subsystems, ## to be 'stand-alone'. I.e. the code ## from Tk 'include' files that are ## incorporated into the script code ## via 'source' statements, was ## hard-coded into this script --- ## to make a 'stand-alone' script ## to donate to http://wiki.tcl.tk. ## Changed by: Blaise Montandon 2012nov03 Added an alternate, shorter name ## for this script, in comments above. ##+############################################################################ ##+################################# ## SET THE TOP WINDOW NAME. ##+################################# wm title . \ "Colors in Decimal & PerCent & Hex - version for wiki.tcl.tk" wm iconname . "ColorSelector" # catch { wm title . "$env(FE_WIN_TITLE)" } # catch { wm iconname . "$env(FE_ICON_TITLE)" } ##+################################### ## SET THE TOP WINDOW POSITION. ##+################################### wm geometry . +50+50 # catch {eval wm geometry . "$env(FE_COLORSEL_GEOM)" } ##+####################################################################### ## SET COLOR SCHEME (palette) FOR THE WINDOW. ##+####################################################################### ## Gray palette set r255 210 set g255 210 set b255 210 set COLOR_pal [format "#%02X%02X%02X" $r255 $g255 $b255] tk_setPalette $COLOR_pal ##+####################################################################### ## SET FONT VARS to use in the 'font create' statements below. ##+####################################################################### set FONTsize 14 set FONT_SMALLsize 12 ## For variable width: set FONT_varwidth \ " -family {comic sans ms} -size -$FONTsize -weight bold -slant roman " set FONT_SMALL_varwidth \ " -family {comic sans ms} -size -$FONT_SMALLsize -weight normal -slant roman " ## For fixed width: set FONT_fixedwidth \ " -family {dejavu sans mono} -size -$FONTsize -weight bold -slant roman " set FONT_SMALL_fixedwidth \ " -family {dejavu sans mono} -size -$FONT_SMALLsize -weight normal -slant roman " ##+##################################################################### ## DEFINE (temporary) 'font create' NAMES to be used ## in '-font' widget specs below. ##+##################################################################### eval font create fontTEMP_button $FONT_varwidth eval font create fontTEMP_label $FONT_varwidth # eval font create fontTEMP_entry $FONT_fixedwidth # eval font create fontTEMP_listbox $FONT_fixedwidth # eval font create fontTEMP_msg $FONT_fixedwidth eval font create fontTEMP_text $FONT_fixedwidth # eval font create fontTEMP_SMALL_button $FONT_SMALL_varwidth # eval font create fontTEMP_SMALL_label $FONT_SMALL_varwidth # eval font create fontTEMP_SMALL_entry $FONT_SMALL_fixedwidth # eval font create fontTEMP_SMALL_listbox $FONT_SMALL_fixedwidth # eval font create fontTEMP_SMALL_msg $FONT_SMALL_fixedwidth # eval font create fontTEMP_SMALL_text $FONT_SMALL_fixedwidth ##+####################################################################### ## SET GEOM VARS FOR THE VARIOUS WIDGET DEFINITIONS. ## (e.g. padx,pady for buttons) ##+####################################################################### ## For BUTTON widgets: set fePADY_button 0 set fePADX_button 0 set feBDwidth_button 2 ## For LABEL widgets: set feBDwidth_label 2 ## For ENTRY, LISTBOX widgets: # set feBDwidth_entry 2 # set feBDwidth_listbox 2 ## For TEXT, MESSAGE widgets: set feBDwidth_text 2 # set feBDwidth_msg 2 ##+######################################################################## ##+######################################################################## ## ## GET INPUT PARM VALUES -- ## i.e. set R255init G255init B255init from ## ## 1) arguments passed to this script ## OR ## 2) environment vars R255, G255, B255. ## ##+######################################################################## ##+######################################################################## ## Example argc/argv processing: ## ## if {$argc == 0} { ## set VARtext "$env(CONFIRM_TEXT)" ## } else { ## set VARtext [lindex $argv 0] ## } ##+######################################################################## if {$argc == 3} { set R255init [lindex $argv 0] set G255init [lindex $argv 1] set B255init [lindex $argv 2] } else { # set R255init 40 set R255init 0 catch { set R255init "$env(R255)" } # set G255init 80 set G255init 156 catch { set G255init "$env(G255)" } # set B255init 120 set B255init 255 catch { set B255init "$env(B255)" } } ##+################################################ ## SET THE WINDOW SIZE. ## (We 'fix' the size rather than setting a minsize ## and allowing the window to expand.) ##+################################################ ## 'minsize' not used now. See 'wm resizable . 0 0' below. # wm minsize . 550 200 # catch {eval wm minsize . "$env(FE_COLORSEL_MINSIZE)" } ## Alternative to minsize (make win not resizable): wm resizable . 0 0 ##+#################################################################### ##+#################################################################### ## DEFINE *ALL* THE FRAMES: ## TOP-LEVEL FRAMES: ## - 'fRsliders' - to contain 3 sliderbars. ## - 'fRpreview' - to contain only its background; to display ## the color specified by the sliderbar settings. ## - 'fRbottom' - to contain several buttons (UseIt,Cancel,etc), ## as well as 2 label & 2 text widgets to ## display the current per-cent and ## hex RGB-values of the color. ## ## 'fRsliders' & 'fRpreview' are packed on left & right. ## ## SUB-FRAMES: ## - 'fRsliders.fRred' (to contain 1 label, 1 sliderbar) ## - 'fRsliders.fRgreen' (to contain 1 label, 1 sliderbar) ## - 'fRsliders.fRblue' (to contain 1 label, 1 sliderbar) ##+#################################################################### ##+#################################################################### ## FOR TESTING of expansion of frames (esp. during window expansion): # set feRELIEF_frame raised # set feBDwidth_frame 2 set feRELIEF_frame flat set feBDwidth_frame 0 frame .fRsliders -relief $feRELIEF_frame -borderwidth $feBDwidth_frame frame .fRpreview -relief raised -borderwidth 4 \ -height 140 -width 140 frame .fRbottom -relief $feRELIEF_frame -borderwidth $feBDwidth_frame frame .fRsliders.fRred \ -relief $feRELIEF_frame \ -borderwidth $feBDwidth_frame frame .fRsliders.fRgreen \ -relief $feRELIEF_frame \ -borderwidth $feBDwidth_frame frame .fRsliders.fRblue \ -relief $feRELIEF_frame \ -borderwidth $feBDwidth_frame ##+######################################################## ## PACK *ALL* the FRAMES. ##+######################################################## pack .fRbottom \ -side bottom \ -anchor w \ -fill x \ -expand 1 ##+########################################## ## NOTE: Need to pack the 'bottom' frame ## before the 'sliders' & 'preview' ## frames -- otherwise the 'bottom' ## frame comes out in the lower-right ## of the window, instead of below ## 'sliders' & 'preview'. ## ## Alternatively, we could define an additional ## frame to contain the 'sliders' & 'preview' ## frames. ##+########################################## set LR_side "left" ##+########################################## ## NOTE: The variable 'LR_side' will ## be used to help toggle the position ## of 'preview' to left or right. ##+########################################## pack .fRsliders \ .fRpreview \ -side $LR_side \ -anchor w \ -fill both \ -expand 1 pack .fRsliders.fRred \ .fRsliders.fRgreen \ .fRsliders.fRblue \ -side top \ -anchor w \ -fill x \ -expand 1 ##+################################################################ ##+################################################################ ## START DEFINING & PACKING WIDGETS WITHIN THEIR FRAMES. ##+################################################################ ##+################################################################ ##+######################################################## ## IN THE 'sliders' frame -- DEFINE 3 LABELS and ## 3 SLIDERBAR WIDGETS. THEN PACK THEM. ##+######################################################## ## RED label .fRsliders.fRred.label \ -text "Red" \ -width 8 \ -font fontTEMP_label scale .fRsliders.fRred.scale \ -orient horizontal \ -from 0 -to 255 \ -digits 0 \ -length 350 \ -command {color_update} .fRsliders.fRred.scale set $R255init ## GREEN label .fRsliders.fRgreen.label \ -text "Green" \ -width 8 \ -font fontTEMP_label scale .fRsliders.fRgreen.scale \ -orient horizontal \ -from 0 -to 255 \ -digits 0 \ -length 350 \ -command color_update .fRsliders.fRgreen.scale set $G255init ## BLUE label .fRsliders.fRblue.label \ -text "Blue" \ -width 8 \ -font fontTEMP_label scale .fRsliders.fRblue.scale \ -orient horizontal \ -from 0 -to 255 \ -digits 0 \ -length 350 \ -command {color_update} .fRsliders.fRblue.scale set $B255init ##+################################################# ## PACK 3 LABELS & 3 SCALES IN 'fRsliders' FRAME. ##+################################################# pack .fRsliders.fRred.label \ -side left \ -anchor w \ -fill none \ -expand 0 pack .fRsliders.fRred.scale \ -side left \ -anchor w \ -fill x \ -expand 1 pack .fRsliders.fRgreen.label \ -side left \ -anchor w \ -fill none \ -expand 0 pack .fRsliders.fRgreen.scale \ -side left \ -anchor w \ -fill x \ -expand 1 pack .fRsliders.fRblue.label \ -side left \ -anchor w \ -fill none \ -expand 0 pack .fRsliders.fRblue.scale \ -side left \ -anchor w \ -fill x \ -expand 1 ##+######################################################## ## IN THE 'bottom' frame -- DEFINE several BUTTONS --- ## 1 'UseIt' BUTTON, 1 'Cancel' BUTTON, ## 1 'Toggle-Side' BUTTON, 1 'Help' BUTTON, and ## 1 TEXT WIDGET (rather than a label or message widget, ## so that it is possible to paste the hex value ## to another window) with a label widget. THEN PACK THEM. ##+######################################################## button .fRbottom.butReturn \ -text "UseIt" \ -font fontTEMP_button \ -padx $fePADX_button \ -pady $fePADY_button \ -relief raised \ -bd $feBDwidth_button \ -command {put_vars} # -text "OK" button .fRbottom.butCancel \ -text "Cancel" \ -font fontTEMP_button \ -padx $fePADX_button \ -pady $fePADY_button \ -relief raised \ -bd $feBDwidth_button \ -command {exit} button .fRbottom.butTogside \ -text "ToggleSide" \ -font fontTEMP_button \ -padx $fePADX_button \ -pady $fePADY_button \ -relief raised \ -bd $feBDwidth_button \ -command {toggle_side} button .fRbottom.butHelp \ -text "Help" \ -font fontTEMP_button \ -padx $fePADX_button \ -pady $fePADY_button \ -relief raised \ -bd $feBDwidth_button \ -command {popup_msg_var_scroll "$HELPtext"} label .fRbottom.labhex \ -text "RGB-in-Hex:" \ -width 11 \ -font fontTEMP_label text .fRbottom.txthex \ -relief raised \ -borderwidth $feBDwidth_text \ -height 1 \ -width 8 \ -wrap none \ -font fontTEMP_text label .fRbottom.labpcnt \ -text "RGB-%s:" \ -width 8 \ -font fontTEMP_label text .fRbottom.txtpcnt \ -relief raised \ -borderwidth $feBDwidth_text \ -height 1 \ -width 11 \ -wrap none \ -font fontTEMP_text ## Pack the widgets in frame '.fRbottom'. pack .fRbottom.butReturn \ .fRbottom.butCancel \ .fRbottom.butTogside \ .fRbottom.butHelp \ -side left \ -anchor center \ -fill none \ -expand 0 pack .fRbottom.txthex \ .fRbottom.labhex \ .fRbottom.txtpcnt \ .fRbottom.labpcnt \ -side right \ -anchor center \ -fill none \ -expand 0 ##+####################################### ## END OF MAIN SECTION TO SETUP THE GUI. ## FRAMES AND WIDGETS ARE DEFINED. ##+####################################### ##+##################################################################### ##+##################################################################### ## DEFINE PROCEDURES: ## - 'color_update' ## - 'toggle_side' ## - 'put_vars' ## - 'popup_msg_var_scroll' ##+##################################################################### ##+##################################################################### ##+##################################################################### ## 'color_update' PROCEDURE ##+##################################################################### ## ## PURPOSE: To set ## 1) the background color of the preview window ## 2) display the hex value of the r-g-b values ## as any slider is changed. ## ## CALLED BY: 3 scale widgets: ## - .fRsliders.fRred.scale ## - .fRsliders.fRgreen.scale ## - .fRsliders.fRblue.scale ## ##+##################################################################### proc color_update {x} { global r255 g255 b255 set r255 [.fRsliders.fRred.scale get] set g255 [.fRsliders.fRgreen.scale get] set b255 [.fRsliders.fRblue.scale get] set color [format "#%02X%02X%02X" $r255 $g255 $b255] .fRpreview config -bg $color .fRbottom.txthex delete 1.0 end .fRbottom.txthex insert end $color ## Show the RGB values in percents. set red_pcnt [expr {$r255 * 100 / 255}] set green_pcnt [expr {$g255 * 100 / 255}] set blue_pcnt [expr {$b255 * 100 / 255}] .fRbottom.txtpcnt delete 1.0 end .fRbottom.txtpcnt insert end "$red_pcnt $green_pcnt $blue_pcnt" } ## END of proc 'color_update' ##+##################################################################### ## 'toggle_side' PROCEDURE ##+##################################################################### ## ## PURPOSE: To switch the sides of the 'sliders' & 'preview' frames ## ## CALLED BY: .fRbottom.togside button ## ##+##################################################################### proc toggle_side { } { global LR_side if { "$LR_side" == "left" } { set LR_side "right" } else { set LR_side "left" } pack forget .fRsliders .fRpreview pack .fRsliders \ .fRpreview \ -side $LR_side \ -anchor w \ -fill both \ -expand 1 } ## END of proc 'toggle_side' ##+##################################################################### ## PROCEDURE -- put_vars (Put R255, G255, B255 environment var ## setting string to standard output.) ## ## Called by: button .fRbottom.butReturn ##+##################################################################### proc put_vars { } { global r255 g255 b255 set COLORhex [format "%02X%02X%02X" $r255 $g255 $b255] #OLD puts "R255=\"$r255\" ; G255=\"$g255\" ; B255=\"$b255\"" puts "$r255 $g255 $b255 $COLORhex" exit } ## END of proc 'puts_vars' ##+######################################################################## ## PROC 'popup_msg_var_scroll' ##+######################################################################## ## PURPOSE: Report help or error conditions to the user. ## CALLED BY: 'help' button ##+######################################################################## ## To have more control over the formatting of the message (esp. ## words per line), we use this 'toplevel-text' method, ## rather than the 'tk_dialog' method -- like on page 574 of the book ## by Hattie Schroeder & Mike Doyel,'Interactive Web Applications ## with Tcl/Tk', Appendix A "ED, the Tcl Code Editor". ##+######################################################################## proc popup_msg_var_scroll { VARtext } { ## global fontTEMP_text #; Not needed. 'wish' makes this global. ## global env # bell # bell ################################################# ## Set VARwidth & VARheight from $VARtext. ################################################# ## To get VARheight, ## split at '\n' (newlines) and count 'lines'. ################################################# set VARlist [ split $VARtext "\n" ] ## For testing: # puts "VARlist: $VARlist" set VARheight [ llength $VARlist ] ## For testing: # puts "VARheight: $VARheight" ################################################# ## To get VARwidth, ## loop through the 'lines' getting length ## of each; save max. ################################################# set VARwidth 0 ############################################# ## LOOK AT EACH LINE IN THE LIST. ############################################# foreach line $VARlist { ############################################# ## Get the length of the line. ############################################# set LINEwidth [ string length $line ] if { $LINEwidth > $VARwidth } { set VARwidth $LINEwidth } } ## END OF foreach line $VARlist ## For testing: # puts "VARwidth: $VARwidth" ############################################################### ## NOTE: VARwidth works for a fixed-width font used for the ## text widget ... BUT the programmer may need to be ## careful that the contents of VARtext are all ## countable characters by the 'string length' command. ############################################################### ##################################### ## SETUP 'TOP LEVEL' HELP WINDOW. ##################################### catch {destroy .topmsg} toplevel .topmsg # wm geometry .topmsg 600x400+100+50 wm geometry .topmsg +100+50 wm title .topmsg "Note" # wm title .topmsg "Note to $env(USER)" wm iconname .topmsg "Note" ##################################### ## DEFINE & PACK TEXT WIDGET. ##################################### text .topmsg.text \ -wrap none \ -font fontTEMP_text \ -width $VARwidth \ -height $VARheight \ -bg "#f0f0f0" \ -relief raised \ -bd 2 \ -yscrollcommand ".topmsg.scrolly set" \ -xscrollcommand ".topmsg.scrollx set" scrollbar .topmsg.scrolly \ -orient vertical \ -command ".topmsg.text yview" scrollbar .topmsg.scrollx \ -orient horizontal \ -command ".topmsg.text xview" ## Pack the scrollbars BEFORE the text widget, ## so that the text does not monopolize the space. pack .topmsg.scrolly \ -side right \ -anchor center \ -fill y \ -expand 0 ## DO NOT USE '-expand 1' HERE on the Y-scrollbar. ## THAT ALLOWS Y-SCROLLBAR TO EXPAND AND PUTS ## BLANK SPACE BETWEEN Y-SCROLLBAR & THE TEXT AREA. pack .topmsg.scrollx \ -side bottom \ -anchor center \ -fill x \ -expand 0 ## DO NOT USE '-expand 1' HERE on the X-scrollbar. ## THAT KEEPS THE TEXT AREA FROM EXPANDING. pack .topmsg.text \ -side top \ -anchor center \ -fill both \ -expand 1 ##################################### ## DEFINE & PACK OK BUTTON WIDGET. ##################################### button .topmsg.butt \ -text "OK" \ -command "destroy .topmsg" pack .topmsg.butt \ -side bottom \ -anchor center \ -fill none \ -expand 0 ##################################### ## LOAD MSG INTO TEXT WIDGET. ##################################### ## .topmsg.text delete 1.0 end .topmsg.text insert end $VARtext .topmsg.text configure -state disabled } ## END OF PROC 'popup_msg_var_scroll' ##+############################################### ## END OF PROCS SECTION. ##+############################################### ## ADDITONAL GUI INITIALIZATION (if any) FOLLOWS. ##+############################################### set HELPtext \ " Here's a little HELP on setting colors that you know by name using appropriate RGB values. Most people know that: yellow = red + green ; bright-yellow = 255 255 0 (add some blue to brighten further) magenta = red + blue ; bright-magenta = 255 0 255 (add some green to brighten further) cyan = green + blue ; bright-cyan = 0 255 255 (add some red to brighten further) For some colors, like brown, it is not so obvious which RGB colors to use to create the color. Brown is basically lots of red, a medium amount of green, and even less blue. So a medium brightness brown is about 200 150 100. In particular, 'sandy brown' is 244 164 96. X color names and their RGB values are shown by the command 'showrgb'. Here are some color-names and RGB values for REDDISH colors, in alphabetic order by name: brown,sandy 244 164 96 coral1 255 114 86 firebrick 178 34 34 khaki,dark 189 183 107 lavenderblush3 205 193 197 magenta3 205 0 205 maroon1 255 52 179 orange,dark 255 127 0 orchid1 255 131 250 peach puff 255 218 185 pink,deep 255 20 147 pink3 205 145 158 plum 221 160 221 rose,misty,3 205 183 181 salmon1 255 140 105 sienna1 255 130 71 tan1 255 165 79 tomato 255 99 71 violet 238 130 238 wood,burly,3 205 170 125 Here are some names and RGB values for GREENISH colors, in alphabetic order by name: aquamarine2 118 238 198 chartreuse 127 255 0 cyan,light 224 255 255 green,lawn 124 252 0 green,lime 50 205 50 green,pale 152 251 152 green,sea,1 84 255 159 green,spring 0 255 127 honeydew 240 255 240 mint cream 245 255 250 olivedrab2 179 238 58 turquoise 64 224 208 Here are some names and RGB values for BLUISH colors, in alphabetic order by name: azure2 224 238 238 blue,cornflower 100 149 237 blue,dodger 30 144 255 blue,midnight 25 25 112 lavender 230 230 250 lightblue2 178 223 238 purple1 155 48 255 royalblue1 72 118 255 skyblue1 135 206 255 steelblue1 99 184 255 slateblue1 131 111 255 turquoise1 0 245 255 turquoise,pale 175 238 238 Of course, you can scale the RGB values down to get darker colors. And you can scale the RGB values up to get brighter colors. " ====== I hope that some Tcl-Tk 'newbies' can learn from this useful script, just as I learned a lot from its predecessor script --- thanks to some (unknown to me) computer science professor/student at an Australian University half-way around the world from me --- me sitting at an SGI/IRIX (Unix) workstation in the eastern United States back in the late 1990's. ---- [RLE] (2012-08-06): Were you aware of the [tk_chooseColor] script which ships with Tcl/Tk? ---- [uniquename] 2012aug14: RLE, I am formulating a reply. I plan to post it here within the next few days. In the mean time, here is a relatively short reply. There are a lot of factors involved, leading to making my own color selector, rather than using 'tk_chooseColor'. Briefly, I had forgotten about it --- I saw an image of the GUI about 7 years ago on a web page. In any case, the situation is similar to the search for the ideal font selector utility, which I discuss on my new [YAFSG - Yet Another Font Selector GUI] page. Everyone has their idea of an ideal selector, and very few have the same ideal. In the course of looking for info on 'tk_chooseColor', I found some info that suggests a reasonable, but not definite, answer to the question "Which came first --- tk_chooseColor or the script I found at USQ?" I found an email from Ousterhout, dated in 1996, announcing the availability of 'tk_chooseColor'. I found the USQ script a few years later, in 1999. So 'tk_chooseColor' may be the egg, and the USQ script may be the chicken. Also, I have a reasonable, but not definite, answer to the question "What may have motivated creation of the USQ script?" I believe that a professor (or student) at USQ may have felt, like I, that 'tk_chooseColor' could use a little simplification --- or maybe the simplification made a good exercise for a computer science class. ---- [uniquename] 2012aug17: I found the following image of the tk_chooseColor GUI at the tkdocs.com site --- showing the GUI for 3 different 'platforms' --- Mac OS X and MS Windows and Linux. [tk_chooseColor_MacOSX_MSwin_Linux_784x319.png] I was surprised to see how different the GUI looks on the three platforms. I had always assumed that when a Tk chooser utility (like a file chooser utility) is ported to the different platforms, that the GUI would have the same features on each platform. In any case, this image shows what I mean by 'obfuscation' in color selector GUI's. With most GUI's like these, when I bring them up, I cannot use them immediately. It takes me several minutes (or more) to figure out which features are going to be most useful to me --- and how to use them. There is a lot of 'obfuscation' in the Mac and MS color chooser GUI's --- lots of distracting/time-consuming features. At first glance, the Linux color chooser looks 'unobfuscated'. But I tried it out on one of my Linux computers by opening a terminal window, typing 'wish', and then typing 'tk_chooseColor'. I found it works a lot like the color chooser that I presented above (although I have a lot more capability to change fonts and colors to match other GUI's in my software --- using font and color variables and font and color changing utilities of my software systems.) But then I noticed a distraction --- the color gradients. To me, it would be 'natural' if the color gradients above the red, green, and blue 'scale' widgets were red, green, and blue --- in particular, if they went from ====== - black (0,0,0) to red (255,0,0) - black (0,0,0) to green (0,255,0) - black (0,0,0) to blue (0,0,255) ====== It took me at least 30 seconds (maybe more than a minute) to figure out why the color gradients are as they are --- and why they seem to be made up of tiny rectangular patches. I finally realized that the colors on each color-bar are an indication of what color would show up in the color swatch if the slider for that particular bar were moved to line up with that particular color shade. And, I guess that the gradients are approximated with small rectangles of solid color because it is faster to draw about 16 colored rectangles than to draw in about 256 colored lines graduating through the colors that would appear on the color swatch. I think these color choosers would be a good way to measure the IQ of a person. You can tell that my IQ is probably less than 130, because it took me about a minute to figure out what the color gradients on the 3 graduated-color bars mean. A Mensa member or a person with an IQ above 150 probably would have figured it out in less than 15 seconds. In summary, I think the 3 color choosers above are good for testing people's IQ --- but I don't think they are good as color choosers. ---- [RLE] (2012-08-17): The answer to your first implied question (why do the chooser GUI's look different across platforms) is because Tk uses the native system color chooser if there is a native system chooser. So the Mac and Windows choosers are the native ones provided by MacOS and Windows respectively. X11 on Unix provides no such native widget, so Unix Tk includes a Tk script which generates a color chooser from Tk widgets. The Tk Unix chooser is the one that is most similar to your code above in this page. I also understand what you mean by "unobfuscated color chooser" now. At first I thought you were referring to the code that implemented the chooser, but you are referring to the complexity of the UI presented by the chooser, not to the code implementing it. ---- [uniquename] - 2012sep06 RLE, thanks for explaining why the Mac and MS Windows 'tk_chooseColor' GUI's are so different from the implementation on Linux. And thanks for bringing up 'tk_chooseColor' in the first place. It has caused me to think of what I could add to my color chooser to help the user choose colors. I have pointed out that I find the color gradients above the red, green, and blue 'scale' widgets on the Linux version of 'tk_chooseColor' to be more confusing than helpful. But there is another reason (besides wasting time) that I find it unhelpful --- I am partially red-green blind. Colors like light-green and light-pink look almost gray or white to me. And some shades of green look more like tan or brown --- or I would be hard-pressed to say what color they are. And because of my condition, I am led to think of how a totally color-blind person might react to the color gradients on the GUI. Such persons would probably find the gradients almost totally useless. They would just look like shades of gray --- on all 3 gradient bars. But a color-blind person might find some textual info helpful --- kind of like the info seen by running the 'showrgb' command on Linux. That output gives the user color names and the RGB values (0-255) that go with the names. Thus a color-blind person could know where to locate the 3 sliderbars of the 'scale' widgets to get the color 'brown', say. In fact, one of the first uses of my color chooser was in my 'feAppMenus' and 'feHandyTools' systems --- to choose a color for the toolchests that would go pretty well with the brownish-orangish screen background of Ubuntu 9.10 (2009 October release, 'Karmic Koala'). I had no idea what proportions of RGB to use to get brown. By running 'showrgb', I was able to determine I could get a pretty good color by using a high value for Red, a medium value for Green, and a low value for Blue. The point I am getting to is that I should add a 'TogHelp' button to my color chooser --- next to the 'TogSide' button. That button will show/hide a scrolling-text-widget that shows some helpful verbiage --- based on 'showrgb' output --- that can help users --- especially vision-challenged users --- help them compose some of the 'hard to concoct' colors. Most people know that you get yellow from mixing red and green, with essentially no blue (except to brighten the yellow). Similarly, most people know how to get magenta (red-blue) and cyan (green-blue). But for colors like brown, chartreuse, puce, etc., they could probably use some verbal help. So I will probably update the code posted above with an implementation of a 'TogHelp' button --- sometime within the next year. ___ [uniquename] 2012oct28 '''UPDATE''' I added the 'Help' button. The code that was above has been replaced. The new code includes the following changes: * Help text was added, along with a proc that shows the text in a popup window with scrollbars. * Comments were re-organized and improved --- and it was noted in the comments that this is a 'stand-alone' script that was converted from a script that used 'source' statements to incorporate 'common' code from some Tk 'include' files. * Indenting was improved to a more consistent format, and some white-space at the start of many widget-definition and widget-packing lines was removed. * Braces were added to 'expr' statements. * The font setting section was compacted somewhat. * The initial part of the code was re-organized somewhat to follow the 'canonical' format that I use in most of the other Tk scripts that I have posted here. That format is described on the page titled [A Canonical Structure for Tk Code --- and variations]. ---- [dzach] - 2012-10-22 There is this color blindness simulator called "Color Oracle", http://colororacle.org . I find it quite useful when deciding what colors to use in presentations etc. ---- '''[slebetman] - 2012-10-23 05:54:05''' Actually, for your use case the Mac style color wheel is more useful. Provided you understand color theory. You can be color blind and it would still be useful as it can be used to answer so many questions that the other two color pickers can't. First, basic color wheel: as you mentioned, everyone should know the primary and secondary colors: red, yellow, blue + green, orange, purple. Most learn this in elementary school. It actually still works in the RGB space but we just need to modify it a bit. The Mac style color wheel actually works with reflective (red,yellow,blue) and transmissive (reg,green,blue) colors simultaneously. We just need to modify our elementary school knowledge a bit. We start with printed colors. So we rename red as magenta, rename blue as cyan and let yellow be itself. Why do this? It turns out that red is not really a primary reflective color since we can get red by mixing magenta with yellow. Cyan is blue. It's sort of sky blue. It's just a fancy name for a specific kind of blue. It just turns out that you can derive lots of other kinds of blue from cyan by mixing in red, yellow and black. So that's the very basic. It still looks like our elementary school color wheel, we've just renamed things around a bit. Now we start mixing. In elementary school you learn that red+blue=purple. Well, actually, magenta+cyan=something bluish. So let's call it blue for convenience: magenta+cyan=blue. As mentioned before, magenta+yellow=red. And finally the traditional yellow+cyan=green. Now we get the Mac style color wheel. Notice something? We started with printed colors CMY and when we mixed them to get secondary colors we ended up with RGB! So, CMY and RGB are really one and the same color wheel. Just rotated 60 degrees. One of the interesting aspect of this color wheel is that it also shows you how to get the color you want by subtracting it's opposite. Look at the wheel. You'll notice that yellow is the opposite of blue. The technical term is complimentary colors. If you take any color and slowly subtract yellow from it you'll notice that the resulting color becomes more and more bluish. The opposite is true, subtract blue from a color and the resulting color is yellowish. You can use this knowledge to manipulate yellows in RGB space since you can only play with red, green and blue sliders. The same can be applied for all the other combinations - remove magenta and you end up with something greenish. Remove red and you end up with something cyanish. If you have a deep enough understanding of this you can even directly design colors in the six digit hex format. For example #cccc00 is obviously yellow due to the lack of blue. Of course, with the wheel GUI you can simply click on the correct coordinates. Now brown is a special case since real-world brown disagrees with on-screen brown. In the real-world you get brown by mixing red,yellow and blue.. sorry, magenta,yellow and cyan. But it doesn't work on-screen since doing that you'd get various shades of grey or white. You see, organic pigments in the real world are tinged slightly yellowish due to either chemical reaction or impurities. So when you try to mix CMY in the real world to create grey you'd get brown instead. This gives us a clue of where brownish colors lies in the color wheel. It is in the middle near the whites but slightly off towards the reds and yellows. Browns are essentially just desaturated kind of yellows or orange. All other fancy names of colors are just fancy names of blues or reds or yellows or greens or purples (which btw is blue+magenta) and should be obvious where they'd belong in the color wheel. Brown is the only non-obvious color. Anyway, this is slightly off-topic but useful if you find yourself trying to figure out colors. Also, this is a very simplified version of color theory and is not 100% accurate. It's just the best practical understanding of color theory I've found to date. <> GUI