#!/usr/bin/wish -f ## ## SCRIPT: draw_colorGradientOval_tween2colors_fromSelectedPoint.tk ## ##+########################################################################### ## PURPOSE: This Tk script allows the user to generate a set of colored ## ovals on a rectangular canvas --- with all the ovals centered ## at a user-selected point --- with the colors gradiating ## from one color at the selected-point to a 2nd color at ## the 'outer' oval. ## ## After choosing the colors, the user can then click on ## a Draw button (or use certain button1-release events) ## to cause this script to draw, on a Tk canvas, a sequence of ## ovals --- with the ovals gradiating in color from one chosen ## color to the other. ## ## The canvas can be re-sized by re-sizing the window. ## A window re-size causes the ovals to be redrawn using ## the current parameters --- colors and 'center point'. ## ## The resulting color-gradient image can be used as a background for ## - Tk GUI buttons ## - icons ## - logo backgrounds ## - title areas in web pages ## - borders of (or backgrounds of entire) web pages ## - 'desktop' backgrounds ## - backgrounds for Tk GUI 'toolchests' ## - your choice ## ##+########################################################################### ## GUI DESIGN: ## ## The GUI includes the following widgets: ## ## 1) Of course, the GUI has a Tk CANVAS widget on which to draw the ## sequence of color-changing ovals. ## ## 2) Some BUTTONS such as 'Exit', 'Help', and at least 2 'Color' ## buttons to bring up a separate color-selector GUI. ## ##+####################################################################### ## 'CANONICAL' STRUCTURE OF THIS CODE: ## ## 0) Set general window parms (win-name, win-position, win-color-scheme, ## fonts, widget-geom-parms, win-size-control, text-array-for-labels-etc). ## 1a) Define ALL frames (and sub-frames). ## 1b) Pack ALL the frames and sub-frames. ## 2) Define & pack all widgets in the frames, frame by frame. ## ## 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 more of ## the procs), if needed. ## ##+################################# ## Some detail of the code structure of this particular script: ## ## 1a) Define ALL frames: ## ## Top-level : ## ## '.fRbuttons' - to contain 'Exit', 'Help', 'Color1', 'Color2' buttons ## ## '.fRcanvas' - to contain the canvas widget. ## ## Sub-frames: none ## ## 1b) Pack ALL frames. ## ## 2) Define & pack all widgets in the frames -- basically going through ## frames & their interiors in left-to-right, top-to-bottom order: ## ## 3) Define bindings: ## - Double-Button1-release on the canvas, to do a re-draw ## ## 4) Define procs: ## ## 'ReDraw' - to (re)draw the sequence of ovals on the canvas ## for the current parameters --- 2 user-selected colors, ## a user-selected 'center point', and the current ## canvas dimensions. ## ## 'set_color1' ## 'set_color2' ## 'set_background_color' ## ## 'popup_msg_var_scroll' - to show messages to the user, such as ## the HELPtext for this utility ## ## 5) Additional GUI initialization: ReDraw for inital settings of ## the colors and the 'center point' ## and the current canvas dimensions. ## ##+####################################################################### ## DEVELOPED WITH: Tcl-Tk 8.5 on Ubuntu 9.10 (2009-october, 'Karmic Koala') ## ## $ wish ## % puts "$tcl_version $tk_version" ## ## showed ## 8.5 8.5 ## but this script should work in most previous 8.x versions, and ## probably even in some 7.x versions (if font settings are changed to ## old-style). ##+####################################################################### ## MAINTENANCE HISTORY: ## Started by: Blaise Montandon 2013aug12 Started development, on Ubuntu 9.10. ## Changed by: Blaise Montandon 2013aug13 Added the 'update_colors_label' ## proc to color the color buttons. ##+######################################################################## ##+####################################################################### ## Set WINDOW TITLES and POSITION. ##+####################################################################### wm title . "Draw Color-Gradient Ovals - from a user-selected 'center point'" wm iconname . "ColorOvals" wm geometry . +15+30 ##+###################################################### ## Set the COLOR SCHEME for the window and its widgets --- ## such as entry field background color. ##+###################################################### tk_setPalette "#e0e0e0" ## Initialize gradient color1. if {1} { ## White set COLOR1r 255 set COLOR1g 255 set COLOR1b 255 } if {0} { ## Magenta set COLOR1r 255 set COLOR1g 0 set COLOR1b 255 } set COLOR1hex [format "#%02X%02X%02X" $COLOR1r $COLOR1g $COLOR1b] ## Initialize gradient color2. if {0} { ## Yellow set COLOR2r 255 set COLOR2g 255 set COLOR2b 0 } if {1} { ## Blue set COLOR2r 0 set COLOR2g 0 set COLOR2b 255 } set COLOR2hex [format "#%02X%02X%02X" $COLOR2r $COLOR2g $COLOR2b] ## Initialize the background color for the canvas. if {0} { ## Dark gray set COLORBKGDr 60 set COLORBKGDg 60 set COLORBKGDb 60 } if {1} { ## Black set COLORBKGDr 0 set COLORBKGDg 0 set COLORBKGDb 0 } set COLORBKGDhex \ [format "#%02X%02X%02X" $COLORBKGDr $COLORBKGDg $COLORBKGDb] # set entryBKGD "#f0f0f0" # set listboxBKGD "#f0f0f0" # set radiobuttBKGD "#f0f0f0" set scaleBKGD "#f0f0f0" ##+######################################################## ## Set (temp) FONT NAMES. ## ## Use a VARIABLE-WIDTH font for text on label and ## button widgets. ## ## Use a FIXED-WIDTH font for text in a listbox list and for ## the text in the entry field or a text widget. ##+######################################################## font create fontTEMP_varwidth \ -family {comic sans ms} \ -size -14 \ -weight bold \ -slant roman font create fontTEMP_SMALL_varwidth \ -family {comic sans ms} \ -size -10 \ -weight bold \ -slant roman ## Some other possible (similar) variable width fonts: ## Arial ## Bitstream Vera Sans ## DejaVu Sans ## Droid Sans ## FreeSans ## Liberation Sans ## Nimbus Sans L ## Trebuchet MS ## Verdana font create fontTEMP_fixedwidth \ -family {liberation mono} \ -size -14 \ -weight bold \ -slant roman font create fontTEMP_SMALL_fixedwidth \ -family {liberation mono} \ -size -10 \ -weight bold \ -slant roman ## Some other possible fixed width fonts (esp. on Linux): ## Andale Mono ## Bitstream Vera Sans Mono ## Courier 10 Pitch ## DejaVu Sans Mono ## Droid Sans Mono ## FreeMono ## Nimbus Mono L ## TlwgMono ##+########################################################### ## SET GEOM VARS FOR THE VARIOUS WIDGET DEFINITIONS. ## (e.g. width and height of canvas, and padding for Buttons) ##+########################################################### set initCanWidthPx 300 set initCanHeightPx 300 set minCanWidthPx 24 set minCanHeightPx 24 # set BDwidthPx_canvas 2 set BDwidthPx_canvas 0 ## BUTTON widget geom settings: set PADXpx_button 0 set PADYpx_button 0 set BDwidthPx_button 2 ## LABEL widget geom settings: set PADXpx_label 0 set PADYpx_label 0 set BDwidthPx_label 2 ## SCALE geom parameters: set BDwidthPx_scale 2 set initScaleLengthPx 300 set scaleWidthPx 10 ## RADIOBUTTON geom parameters: # set PADXpx_radbutt 0 # set PADYpx_radbutt 0 # set BDwidthPx_radbutt 2 ## CHECKBUTTON geom parameters: # set PADXpx_chkbutt 0 # set PADYpx_chkbutt 0 # set BDwidthPx_chkbutt 2 ## ENTRY widget geom settings: # set BDwidthPx_entry 2 # set initEntryWidthChars 50 ## LISTBOX geom settings: # set BDwidthPx_listbox 2 # set initListboxWidthChars 50 # set initListboxHeightChars 8 ##+###################################################### ## Set a MIN-SIZE of the window (roughly). ## ## Set approx MIN WIDTH according to widgets across the ## '.fRbuttons' frame. ## ## Set approx MIN HEIGHT according to the height of the ## vertical 'stack' of frames. ##+###################################################### set minWinWidthPx [font measure fontTEMP_varwidth \ "Exit Help Color1 Color2 BkgdColor"] ## Add some pixels to account for right-left-size of window-manager ## decoration (about 6 pixels) and frame/widget borders for ## at least 4 buttons (4x4 pixels/widget). set minWinWidthPx [expr {20 + $minWinWidthPx}] ## Get the approx MIN HEIGHT based on ## 2 chars high for the '.fRbuttons' frame ## 24 pixels high for the '.fRcanvas' frame ## ## and add about 20 pixels for top-bottom window decoration -- ## and about 2x4 pixels for frame/widget borders of the 2 frames. set charHeightPx [font metrics fontTEMP_fixedwidth -linespace] set minWinHeightPx [expr {28 + ( 2 * $charHeightPx )} ] ## FOR TESTING: # puts "minWinWidthPx = $minWinWidthPx" # puts "minWinHeightPx = $minWinHeightPx" wm minsize . $minWinWidthPx $minWinHeightPx ## We allow the window to be resizable and we pack the canvas with ## '-fill both' so that the canvas can be enlarged by enlarging the ## window. ## If you want to make the window un-resizable, ## you can use the following statement. # wm resizable . 0 0 ##+#################################################################### ## Set a TEXT-ARRAY to hold text for buttons & labels on the GUI. ## NOTE: This can aid INTERNATIONALIZATION. This array can ## be set according to a nation/region parameter. ##+#################################################################### ## if { "$VARlocale" == "en"} set aRtext(buttonEXIT) "Exit" set aRtext(buttonHELP) "Help" set aRtext(buttonDRAW) "Draw" set aRtext(buttonCOLOR1) "CentrColr" set aRtext(buttonCOLOR2) "OutrColr" set aRtext(buttonCOLORBKGD) "BkgdColr" set aRtext(labelRATIO) "x-to-y Aspect Ratio of Ovals (0.8 to 2.0):" ## END OF if { "$VARlocale" == "en"} ##+################################################################ ## DEFINE *ALL* THE FRAMES: ## ## Top-level : '.fRbuttons' '.fRcanvas' ## ## Sub-frames: none ##+################################################################ ## FOR TESTING: (resizing of frames as window is resized) # set RELIEF_frame raised # set BDwidth_frame 2 set RELIEF_frame flat set BDwidth_frame 0 frame .fRbuttons -relief $RELIEF_frame -bd $BDwidth_frame frame .fRcanvas -relief raised -bd 2 ##+############################## ## PACK the FRAMES. ##+############################## pack .fRbuttons \ -side top \ -anchor nw \ -fill x \ -expand 0 pack .fRcanvas \ -side top \ -anchor nw \ -fill both \ -expand 1 ##+####################################################### ## The frames are defined and packed. ##+####################################################### ## DEFINE and PACK WIDGETS, frame by frame. ##+####################################################### ##+####################################################### ## In '.fRbuttons' FRAME - ## DEFINE-and-PACK BUTTON widgets ## --- Exit,Help,Color1,Color2,ColorBkgd --- ## and a LABEL and SCALE widget (for aspect ratio of ovals). ##+####################################################### button .fRbuttons.buttEXIT \ -text "$aRtext(buttonEXIT)" \ -font fontTEMP_varwidth \ -padx $PADXpx_button \ -pady $PADYpx_button \ -relief raised \ -bd $BDwidthPx_button \ -command {exit} button .fRbuttons.buttHELP \ -text "$aRtext(buttonHELP)" \ -font fontTEMP_varwidth \ -padx $PADXpx_button \ -pady $PADYpx_button \ -relief raised \ -bd $BDwidthPx_button \ -command {popup_msgVarWithScroll .topHelp $HELPtext} button .fRbuttons.buttDRAW \ -text "$aRtext(buttonDRAW)" \ -font fontTEMP_varwidth \ -padx $PADXpx_button \ -pady $PADYpx_button \ -relief raised \ -bd $BDwidthPx_button \ -command {ReDraw 0} button .fRbuttons.buttCOLOR1 \ -text "$aRtext(buttonCOLOR1)" \ -font fontTEMP_SMALL_varwidth \ -padx $PADXpx_button \ -pady $PADYpx_button \ -relief raised \ -bd $BDwidthPx_button \ -command {set_color1} button .fRbuttons.buttCOLOR2 \ -text "$aRtext(buttonCOLOR2)" \ -font fontTEMP_SMALL_varwidth \ -padx $PADXpx_button \ -pady $PADYpx_button \ -relief raised \ -bd $BDwidthPx_button \ -command {set_color2} button .fRbuttons.buttCOLORBKGD \ -text "$aRtext(buttonCOLORBKGD)" \ -font fontTEMP_SMALL_varwidth \ -padx $PADXpx_button \ -pady $PADYpx_button \ -relief raised \ -bd $BDwidthPx_button \ -command {set_background_color} label .fRbuttons.labelRATIO \ -text "$aRtext(labelRATIO)" \ -font fontTEMP_SMALL_varwidth \ -justify left \ -anchor w \ -relief flat \ -bd $BDwidthPx_label ## Set this widget var in the GUI initialization section ## at the bottom of this script. # set aspectRATIOxTOy 2.0 scale .fRbuttons.scaleRATIO \ -from 0.8 -to 2.0 \ -resolution 0.1 \ -length 120 \ -font fontTEMP_SMALL_varwidth \ -variable aspectRATIOxTOy \ -showvalue true \ -orient horizontal \ -bd $BDwidthPx_scale \ -width 10 ## Pack the '.fRbuttons' widgets. pack .fRbuttons.buttEXIT \ .fRbuttons.buttHELP \ .fRbuttons.buttCOLOR1 \ .fRbuttons.buttCOLOR2 \ .fRbuttons.buttCOLORBKGD \ .fRbuttons.buttDRAW \ .fRbuttons.labelRATIO \ .fRbuttons.scaleRATIO \ -side left \ -anchor w \ -fill none \ -expand 0 ##+######################################################## ## In the '.fRcanvas' FRAME - ## DEFINE-and-PACK CANVAS WIDGET. ##+######################################################## ## We set highlightthickness & borderwidth of the canvas to ## zero, as suggested on page 558, Chapter 37, 'The Canvas ## Widget', in the 4th edition of the book 'Practical ## Programming in Tcl and Tk'. ##+###################################################### canvas .fRcanvas.can \ -width $initCanWidthPx \ -height $initCanHeightPx \ -relief flat \ -highlightthickness 0 \ -borderwidth 0 pack .fRcanvas.can \ -side top \ -anchor nw \ -fill both \ -expand 1 ##+################################################## ## END OF DEFINITION of the GUI widgets. ##+################################################## ## Start of BINDINGS, PROCS, Added-GUI-INIT sections. ##+################################################## ##+####################################################################### ##+####################################################################### ## BINDINGS SECTION: ## - For button1-release on the canvas, to redraw the ovals ## for a new 'center point'. ##+####################################################################### bind .fRcanvas.can { reset_center_point %x %y ; ReDraw 0 } # bind .fRbuttons.scaleRATIO { ReDraw 0 } ##+################################################################## ##+################################################################## ## DEFINE PROCS SECTION: ## ## 'reset_center_point' - sets global variables centerXpx,centerYpx ## according the point just clicked. ## ## 'ReDraw' - to draw the sequence of curves on the canvas from the ## currently-specified colors and the current 'center point' ## and the current aspectRATIOxTOy and the current canvas ## dimensions. ## ## 'set_color1' - called by gradient-color1 button '-command' ## ## 'set_color2' - called by gradient-color2 button '-command' ## ## 'set_background_color' - called by background color button '-command' ## ## 'update_color_labels' - called by the 3 color procs to update ## colors and text on the 3 color buttons ## ## 'popup_msg_var_scroll' - used to show messages to the user, such as ## the HELPtext for this utility ## ##+################################################################# ##+###################################################################### ## proc 'reset_center_point': ## ## PURPOSE: Sets variables centerXpx,centerYpx ## according the point just clicked. ## ## CALLED BY: pressing the Draw button and, maybe, some button1-release ## bindings on radiobuttons --- and within the 2 color procs. ##+###################################################################### proc reset_center_point {x y} { global centerXpx centerYpx set centerXpx $x set centerYpx $y } ## END OF proc 'reset_center_point' ##+###################################################################### ## proc 'ReDraw': ## ## PURPOSE: To draw the sequence of ovals on the canvas --- ## with 'create oval' commands --- ## from given colors and the current 'center point' ## and the current aspectRATIOxTOy value and the current canvas ## dimensions. ## ## CALLED BY: pressing the Draw button and, maybe, some button1-release ## bindings on the canvas --- and perhaps on the aspectRATIOxTOy ## scale --- and perhaps within the color1 & color2 procs. ##+###################################################################### ## NOTE: The 'x' argument is to avoid an error when the scale '-command' ## passes a scale value as an argument to the command. This is in ## case we try using the '-command' option of scale widgets to ## do the redraws 'dynamically' as a sliderbar is moved. ##+##################################################################### proc ReDraw {x} { global centerXpx centerYpx aspectRATIOxTOy \ COLOR1r COLOR1g COLOR1b COLOR1hex \ COLOR2r COLOR2g COLOR2b COLOR2hex \ COLORBKGDr COLORBKGDg COLORBKGDb COLORBKGDhex wm title . "*BUSY* ... Performing redraw at center: $centerXpx $centerYpx" ## Clear the canvas. .fRcanvas.can delete all ## Set the current time, for determining execution ## time for building the photo image, below. set t0 [clock milliseconds] ## Get the current canvas size. set curCanWidthPx [winfo width .fRcanvas.can] set curCanHeightPx [winfo height .fRcanvas.can] ## Set a limit for the number of ovals to draw. set MAX_Xpx $centerXpx set delta [expr {$curCanWidthPx - $centerXpx}] if {$delta > $MAX_Xpx} {set MAX_Xpx $delta} set MAX_Xpx [expr {int($MAX_Xpx / $aspectRATIOxTOy)}] set MAX_Ypx $centerYpx set delta [expr {$curCanHeightPx - $centerYpx}] if {$delta > $MAX_Ypx} {set MAX_Ypx $delta} set MAX_Ypx [expr {int($MAX_Ypx * $aspectRATIOxTOy)}] set MAXovals $MAX_Xpx if {$MAX_Ypx > $MAXovals} {set MAXovals $MAX_Ypx} ## FOR TESTING: # puts "ReDraw > MAXovals: $MAXovals" # puts "curCanWidthPx : $curCanWidthPx" # puts "curCanHeightPx: $curCanHeightPx" ## Set the RGB ranges for the 2 selected colors. set rRange [expr {$COLOR2r - double($COLOR1r)}] set gRange [expr {$COLOR2g - double($COLOR1g)}] set bRange [expr {$COLOR2b - double($COLOR1b)}] ## Set some RGB ratios to use for color interpolation. set MAXovals [expr {double($MAXovals)}] set rRatio [expr {$rRange / $MAXovals}] set gRatio [expr {$gRange / $MAXovals}] set bRatio [expr {$bRange / $MAXovals}] ## Let us make sure $aspectRATIOxTOy is float, not integer. # set aspectRATIOxTOy [expr {double($aspectRATIOxTOy)}] ## Start the oval-drawing loop. for {set i 0} {$i < $MAXovals} {incr i} { ## Interpolate to get a color for this oval. set R255 [expr int( $COLOR1r + ($rRatio * $i) )] set G255 [expr int( $COLOR1g + ($gRatio * $i) )] set B255 [expr int( $COLOR1b + ($bRatio * $i) )] set tempCOLORhex [format "#%02X%02X%02X" $R255 $G255 $B255] ## Set the corners of the box to contain the oval. set ULXpx [expr {int($centerXpx - ($i * $aspectRATIOxTOy))}] set ULYpx [expr {int($centerYpx - ($i / $aspectRATIOxTOy))}] set LRXpx [expr {int($centerXpx + ($i * $aspectRATIOxTOy))}] set LRYpx [expr {int($centerYpx + ($i / $aspectRATIOxTOy))}] .fRcanvas.can create oval \ $ULXpx $ULYpx $LRXpx $LRYpx \ -outline $tempCOLORhex -width 3 # -width 2 # -width 1 ## FOR TESTING: (To see each oval being drawn.) # update } ## END OF oval-drawing loop ## Change the title of the window to show execution time. wm title . "DONE. [expr [clock milliseconds]-$t0] milliseconds elapsed." } ## END OF PROC 'ReDraw' ##+##################################################################### ## proc 'set_color1' ##+##################################################################### ## PURPOSE: ## This procedure is invoked to get an RGB triplet ## via 3 RGB slider bars on the FE Color Selector GUI. ## ## Uses that RGB value to set a 'fill' color. ## ## Arguments: none ## ## CALLED BY: .fRbuttons.buttCOLOR1 button ##+##################################################################### proc set_color1 {} { global COLOR1r COLOR1g COLOR1b COLOR1hex # global feDIR_tkguis ## FOR TESTING: # puts "COLOR1r: $COLOR1r" # puts "COLOR1g: $COLOR1g" # puts "COLOR1b: $COLOR1b" set TEMPrgb [ exec \ ./sho_colorvals_via_sliders3rgb.tk \ $COLOR1r $COLOR1g $COLOR1b] # $feDIR_tkguis/sho_colorvals_via_sliders3rgb.tk \ ## FOR TESTING: # puts "TEMPrgb: $TEMPrgb" if { "$TEMPrgb" == "" } { return } scan $TEMPrgb "%s %s %s %s" r255 g255 b255 hexRGB set COLOR1hex "#$hexRGB" set COLOR1r $r255 set COLOR1g $g255 set COLOR1b $b255 ## Update the colors on the color buttons. update_colors_label ## Redraw the geometry in the new interior color. ReDraw 0 } ## END OF proc 'set_color1' ##+##################################################################### ## proc 'set_color2' ##+##################################################################### ## PURPOSE: ## This procedure is invoked to get an RGB triplet ## via 3 RGB slider bars on the FE Color Selector GUI. ## ## Uses that RGB value to set an 'outline' color. ## ## Arguments: none ## ## CALLED BY: .fRbuttons.buttCOLOR2 button ##+##################################################################### proc set_color2 {} { global COLOR2r COLOR2g COLOR2b COLOR2hex # global feDIR_tkguis ## FOR TESTING: # puts "COLOR2r: $COLOR2r" # puts "COLOR2g: $COLOR2g" # puts "COLOR2b: $COLOR2b" set TEMPrgb [ exec \ ./sho_colorvals_via_sliders3rgb.tk \ $COLOR2r $COLOR2g $COLOR2b] # $feDIR_tkguis/sho_colorvals_via_sliders3rgb.tk \ ## FOR TESTING: # puts "TEMPrgb: $TEMPrgb" if { "$TEMPrgb" == "" } { return } scan $TEMPrgb "%s %s %s %s" r255 g255 b255 hexRGB set COLOR2hex "#$hexRGB" set COLOR2r $r255 set COLOR2g $g255 set COLOR2b $b255 ## Update the colors on the color buttons. update_colors_label ## Redraw the geometry in the new outline color. ReDraw 0 } ## END OF proc 'set_color2' ##+##################################################################### ## proc 'set_background_color' ##+##################################################################### ## PURPOSE: ## This procedure is invoked to get an RGB triplet ## via 3 RGB slider bars on the FE Color Selector GUI. ## ## Uses that RGB value to set the color of the canvas --- ## on which all the ovals lie. ## ## Arguments: none ## ## CALLED BY: .fRbuttons.buttCOLORBKGD button ##+##################################################################### proc set_background_color {} { global COLORBKGDr COLORBKGDg COLORBKGDb COLORBKGDhex # global feDIR_tkguis ## FOR TESTING: # puts "COLORBKGDr: $COLORBKGDr" # puts "COLORBKGDg: $COLORBKGDb" # puts "COLORBKGDb: $COLORBKGDb" set TEMPrgb [ exec \ ./sho_colorvals_via_sliders3rgb.tk \ $COLORBKGDr $COLORBKGDg $COLORBKGDb] # $feDIR_tkguis/sho_colorvals_via_sliders3rgb.tk \ ## FOR TESTING: # puts "TEMPrgb: $TEMPrgb" if { "$TEMPrgb" == "" } { return } scan $TEMPrgb "%s %s %s %s" r255 g255 b255 hexRGB set COLORBKGDhex "#$hexRGB" set COLORBKGDr $r255 set COLORBKGDg $g255 set COLORBKGDb $b255 ## Update the colors on the color buttons. update_colors_label ## Set the color of the canvas. .fRcanvas.can config -bg $COLORBKGDhex } ## END OF proc 'set_background_color' ##+##################################################################### ## proc 'update_colors_label' ##+##################################################################### ## PURPOSE: ## This procedure is invoked to update the text in a COLORS ## label widget, to show hex values of current color1, color2, ## and background-color settings. ## ## This proc also sets the background color of each of those 3 buttons ## to its current color --- and sets foreground color to a ## suitable black or white color, so that the label text is readable. ## ## Arguments: global color vars ## ## CALLED BY: 3 colors procs: ## 'set_object_color1' ## 'set_object_color2' ## 'set_background_color' ## and the additional-GUI-initialization section at ## the bottom of this script. ##+##################################################################### proc update_colors_label {} { global aRtext COLOR1hex COLOR2hex COLORBKGDhex \ COLOR1r COLOR1g COLOR1b \ COLOR2r COLOR2g COLOR2b \ COLORBKGDr COLORBKGDg COLORBKGDb ## Set background color on the COLOR1 button, and ## put the background color in the text on the button, and ## set the foreground color of the button. .fRbuttons.buttCOLOR1 configure -bg $COLOR1hex .fRbuttons.buttCOLOR1 configure -text "$aRtext(buttonCOLOR1) $COLOR1hex" set sumCOLOR1 [expr {$COLOR1r + $COLOR1g + $COLOR1b}] if {$sumCOLOR1 > 300} { .fRbuttons.buttCOLOR1 configure -fg #000000 } else { .fRbuttons.buttCOLOR1 configure -fg #f0f0f0 } ## Set background color on the COLOR2 button, and ## put the background color in the text on the button, and ## set the foreground color of the button. .fRbuttons.buttCOLOR2 configure -bg $COLOR2hex .fRbuttons.buttCOLOR2 configure -text "$aRtext(buttonCOLOR2) $COLOR2hex" set sumCOLOR2 [expr {$COLOR2r + $COLOR2g + $COLOR2b}] if {$sumCOLOR2 > 300} { .fRbuttons.buttCOLOR2 configure -fg #000000 } else { .fRbuttons.buttCOLOR2 configure -fg #f0f0f0 } ## Set background color on the COLORBKGD button, and ## put the background color in the text on the button, and ## set the foreground color of the button. .fRbuttons.buttCOLORBKGD configure -bg $COLORBKGDhex .fRbuttons.buttCOLORBKGD configure -text "$aRtext(buttonCOLORBKGD) $COLORBKGDhex" set sumCOLORBKGD [expr {$COLORBKGDr + $COLORBKGDg + $COLORBKGDb}] if {$sumCOLORBKGD > 300} { .fRbuttons.buttCOLORBKGD configure -fg #000000 } else { .fRbuttons.buttCOLORBKGD configure -fg #f0f0f0 } } ## END OF proc 'update_colors_label' ##+############################################################# ## proc redraw_if_canvas_resized ## ## CALLED BY: a binding at the bottom of this script ##+############################################################# proc redraw_if_canvas_resized {} { global PREVcanWidthPx PREVcanHeightPx set CURcanWidthPx [winfo width .fRcanvas.can] set CURcanHeightPx [winfo height .fRcanvas.can] if { $CURcanWidthPx != $PREVcanWidthPx || $CURcanHeightPx != $PREVcanHeightPx} { ReDraw 0 set PREVcanWidthPx $CURcanWidthPx set PREVcanHeightPx $CURcanHeightPx } } ## END OF proc 'redraw_if_canvas_resized' ##+######################################################################## ## PROC 'popup_msgVarWithScroll' ##+######################################################################## ## PURPOSE: Report help or error conditions to the user. ## ## We do not use focus,grab,tkwait in this proc, ## because we use it to show help when the GUI is idle, ## and we may want the user to be able to keep the Help ## window open while doing some other things with the GUI ## such as putting a filename in the filename entry field ## or clicking on a radiobutton. ## ## For a similar proc with focus-grab-tkwait added, ## see the proc 'popup_msgVarWithScroll_wait' in a ## 3DterrainGeneratorExaminer Tk script. ## ## REFERENCE: page 602 of 'Practical Programming in Tcl and Tk', ## 4th edition, by Welch, Jones, Hobbs. ## ## ARGUMENTS: A toplevel frame name (such as .fRhelp or .fRerrmsg) ## and a variable holding text (many lines, if needed). ## ## 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_msgVarWithScroll { toplevName VARtext } { ## global fontTEMP_varwidth #; 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 $toplevName} toplevel $toplevName # wm geometry $toplevName 600x400+100+50 wm geometry $toplevName +100+50 wm title $toplevName "Note" # wm title $toplevName "Note to $env(USER)" wm iconname $toplevName "Note" ##################################### ## In the frame '$toplevName' - ## DEFINE THE TEXT WIDGET and ## its two scrollbars --- and ## DEFINE an OK BUTTON widget. ##################################### text $toplevName.text \ -wrap none \ -font fontTEMP_varwidth \ -width $VARwidth \ -height $VARheight \ -bg "#f0f0f0" \ -relief raised \ -bd 2 \ -yscrollcommand "$toplevName.scrolly set" \ -xscrollcommand "$toplevName.scrollx set" scrollbar $toplevName.scrolly \ -orient vertical \ -command "$toplevName.text yview" scrollbar $toplevName.scrollx \ -orient horizontal \ -command "$toplevName.text xview" button $toplevName.butt \ -text "OK" \ -font fontTEMP_varwidth \ -command "destroy $toplevName" ############################################### ## PACK *ALL* the widgets in frame '$toplevName'. ############################################### ## Pack the bottom button BEFORE the ## bottom x-scrollbar widget, pack $toplevName.butt \ -side bottom \ -anchor center \ -fill none \ -expand 0 ## Pack the scrollbars BEFORE the text widget, ## so that the text does not monopolize the space. pack $toplevName.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 $toplevName.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 $toplevName.text \ -side top \ -anchor center \ -fill both \ -expand 1 ##################################### ## LOAD MSG INTO TEXT WIDGET. ##################################### ## $toplevName.text delete 1.0 end $toplevName.text insert end $VARtext $toplevName.text configure -state disabled } ## END OF PROC 'popup_msgVarWithScroll' ##+######################## ## END of PROC definitions. ##+######################## ## Set HELPtext variable. ##+######################## set HELPtext "\ ********** HELP for the Color-Gradient-Ovals Utility ***************** This Tk script QUICKLY generates a sequence of colored ovals on a rectangular canvas --- with all the ovals centered at a user-selected point --- and with the colors gradiating from one color at the selected 'center point' to a 2nd color at the 'outer' oval. Simply click on the canvas to establish a new 'center point'. The sequence of ovals are intended to yield a nicely color shaded image, with a highlight in any portion of the image. Some possible applications are listed below. A 'scale' widget on the GUI can be used to set the 'aspect ratio' to be used to redraw the ovals. After setting a new aspect ratio, the user can click on the 'Draw' button to cause a redraw. An aspect ratio of 1.0 causes the ovals to be circular. After choosing a color via either the 'CenterColor' or the 'OuterColor' button (OR after a button1-release event on the canvas, to change the 'center point'), this script will automatically do a redraw. The canvas can be re-sized by re-sizing the window. The 'Draw' button can be used after a window re-size, to cause a re-draw that fills the new canvas size. EXTENT OF THE OVALS and DRAW TIMES: The ovals are drawn until they just about fill the canvas, but one or more corners of the canvas is typically left at the background color, which is defaulted to black. You can use the 'BackgroundColor' button to set the background to the same color as the 'OuterColor' button. This will generally fill in the entire canvas nicely with 'smooth' coloring. (One reason for not drawing enough ovals to fill all the corners is to assure that we are not drawing more ovals than necessary. Another reason is to help indicate whether the ovals are being drawn with the aspect ratio that was specified.) The typical draw time for these shaded-oval images in a window of maximum size on a netbook computer (about 1024x600 pixels), with an Intel Atom N450 CPU, is about 2/10 of a second. Since the highest end Intel CPU's are about 10 times faster than that, the images may be drawn in far less than 0.1 of a second on a high-end desktop or laptop computer. USES FOR THE IMAGES: The resulting color-gradient image can be used for - Tk GUI button backgrounds - icon backgrounds - logo backgrounds - title areas in web pages - borders of (or tiled backgrounds of entire) web pages - 'desktop' backgrounds, tiled if need be - backgrounds for Tk GUI 'toolchests' - your choice Text or images or drawings could be superimposed on the color-gradient image by using one of this author's other Tk GUI utilities, such as http://wiki.tcl.tk/37228 - A GUI for making 'Title Blocks' ... with text, fonts, colors, images http://wiki.tcl.tk/37351 - wheeeDiagram --- some bells and whistles http://wiki.tcl.tk/37120 - A 'Sketch On' GUI ... for drawing on an image or colored background CAPTURING THE GENERATED IMAGE: A screen/window capture utility (like 'gnome-screenshot' on Linux) can be used to capture the GUI image in a PNG or GIF file, say. If necessary, an image editor (like 'mtpaint' on Linux) can be used to crop the window capture image. The image could also be down-sized --- say to make a 'bullet' image file or an icon image file. METHOD OF DRAWING: This script uses Tk drawing commands (on the Tk canvas) of the form: .canvas create oval x1 y1 x2 y2 -outline -width 3 The 'hexCOLOR' is interpolated from the 'CenterColor' and the 'OuterColor'. The width of 3 pixels is used to avoid occasional pixels not being covered by the ovals, resulting in pixels of the background color showing through the sequence of ovals that have been drawn on the canvas. You can try other widths of 1 and 2 to see the effect. If you like that option, you could add another widget to the GUI to allow for setting the width of the ovals. " ##+################################################################ ## Additional GUI INITIALIZATION: ##+################################################################ set aspectRATIOxTOy 2.0 ## We need this statement because ReDraw (below) does not ## (re)set the background/canvas color. .fRcanvas.can config -bg $COLORBKGDhex ## Initialize/update the colors on the color buttons. update_colors_label ## Need 'update' here to set the size of the canvas, ## because 'ReDraw' uses 'winfo' to get the width and ## height of the canvas. update ##+########################################################## ## When this script drops into the Tk event-handling loop, ## the 'bind . "redraw_if_canvas_resized"' ## command below causes redraws whenever the canvas is resized. ## ## (Unfortunately, the binding seems to cause more ## re-draws than we really need. We just want a re-draw when ## the mouse-button is released after re-sizing the window, ## NOT repeatedly while the window border is being moved. ## ## EVEN MORE unfortunately, the binding seems to ## cause the 'scale' widget to go wild and auto-advance, ## accompanied by a barrage of re-draws.) ## ## We initialize the PREVcanWidthPx and PREVcanHeightPx ## vars that are used in the 'redraw_if_canvas_resized' proc. ## Those canvas dimensions were intended to be used to try to ## make sure that when a event occurs, a redraw is ## at least restricted to those events that actually result ## in a change in the size of the canvas. ##+########################################################## set PREVcanWidthPx [winfo width .fRcanvas.can] set PREVcanHeightPx [winfo height .fRcanvas.can] ## Initialize the 'center point' of the ovals. ## (We could start off-center.) set centerXpx [expr {int($PREVcanWidthPx / 2)}] set centerYpx [expr {int($PREVcanHeightPx / 2)}] ReDraw 0 ## DEACTIVATED. Seems to cause the 'scale' to auto-advance ## and cause tons of redraws. # bind . "redraw_if_canvas_resized"