Updated 2014-06-07 21:35:24 by uniquename

uniquename - 2012nov05

I am interested in making nice images for 'toolchest' and 'drawer' backgrounds (and other GUI embellishments), as I have indicated at Experiments in making embellished GUI's and at A color-gradient-button-maker GUI.

In Experiments in making embellished GUI's, I experimented with making 'toolchest' GUI's --- toolchests with 'app-drawers' --- using several different methods, based on

  • one Tk 'button' per drawer
  • a Tk 'canvas' rectangle for each drawer
  • a single Tk 'canvas', partitioned into drawers

These experiments address my desire to be able to make really appealing 'app-menus'.

The next step is to have the 'drawers' in the 'app-menus' bring up apps or utilities --- and many of those utilities may ulitmately be Tk scripts that present GUI's made up of Tk widgets, such as labels, buttons, checkbuttons, radiobuttons, scales, canvases, and scrolling text widgets.

To make such widget-filled Tk GUI's really stunning, it would help if we could make use of the '-image' option of many of the Tk widgets --- with the '-compound center' option, for the 1st four widget types mentioned above --- so that we can have text on top of a nice background --- rather than text on a simple colored background.

It has taken quite a bit of experimenting with various Tk options to be able to come up with a promising 'first pass' at making a Tk GUI with 'theme' options.

Here is an image of a 'first pass' at such a GUI --- a self-theming GUI. The radiobuttons and checkbutton on this GUI are used to call on different themes (combinations of images and colors).

Following are three images showing the appearance of the GUI (for some selected button/label and background images) --- for orange, green, and gray 'themes'.

The following image shows that if you click on the 'Images on GUI' checkbutton, the images disappear from the label and button widgets. This shows the more typical non-image-enhanced Tk GUI.

By the way, if you 'grab' the slider on the 'scale' widget, the fonts in all the widgets 'dynamically' change size as you move the slider. (It worked even better than I thought it would.)

___________________________________________________________

I present the code for the 'demo_tkGUI_themes_using_imagesANDcolors.tk' GUI-script below --- for version 1. (Some improvements are to come. See the 'Enhancement' notes near the bottom of this page.)

The comments at the top of the script point out that this is a GUI to demonstrate the ability to provide 'themes' for a Tk GUI, in a quite flexible, almost-anything-is-possible way --- using a combination of images and colors.

I follow my usual 'canonical' structure for Tk code, for this Tk script:
  0) Set general window & widget parms (win-name, win-position,
     win-color-scheme, fonts, widget-geometry-parms, win-size-control,
     text-array-for-labels-etc).

  1a) Define ALL frames (and sub-frames, if any).
  1b) Pack   ALL framesand sub-frames.

  2) Define & pack all widgets in the frames, frame by frame.

  3) Define keyboard 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.

This structure is discussed in more detail on the page A Canonical Structure for Tk Code --- and variations.

This structure makes it easy for me to find code sections --- while generating and testing a Tk script, and when looking for code snippets to include in Tk scripts (code re-use).

One new thing that I have added is the text-array-for-labels-etc item in section 0. This can make it easier for people to internationalize my scripts. I may be using a text-array like this in most of my scripts in the future.

_________________________________________________________________

As in all my scripts that use the 'pack' geometry manager (which is all of my 100-plus scripts, so far), I provide the four main pack parameters --- '-side', '-anchor', '-fill', '-expand' --- on all of the 'pack' commands for the frames and widgets. So Tcler's can experiment with these parameters if they want to change the behavior of the GUI when window size is changed.

I think I have found a pretty good setting of the '-side', '-anchor', '-fill', and '-expand' parameters on the 'pack' commands for the various widgets of this GUI. In particular ...

The 'canvas' and 'text' widgets expand/contract when the window size is changed --- while button and label widgets stay fixed in size and relative-location as the window size is changed.

However, I see one improvement I may make: I may try using a 'fill-y' technique of some sort on the label to the left of the 'scale' widget --- to make the label, that is, its underlying image, expand in the y-direction --- in order to cover some of the plain-color area with a shaded image that matches the 'theme'.

You might want to change the fonts used for the various GUI widgets. For example, you could change '-weight' from 'bold' to 'normal' --- or '-slant' from 'roman' to 'italic'. Or change font families.

In fact, you may NEED to change the font families, because the families I used may not be available on your computer --- and the default font that the 'wish' interpreter chooses may not be very pleasing.

I use variables to set geometry parameters of widgets --- parameters such as border-widths and padding. And I have included the '-relief' parameter on the definitions of frames and widgets. Feel free to experiment with those 'appearance' parameters as well.

_________________________________________________________________

That said, here's the code --- with plenty of comments to describe what most of the code-sections are doing.

The logic of the script gets rather 'interesting' as this is a GUI that is intended to change its own appearance. I have provided plenty of comments to help readers understand the structure and intent of various code sections. In particular, the comments are to help ME understand what I did, when I look at this in the future to get code-ideas for making enhanced Tk GUI's.

A major part of the code that is involved in setting a 'theme', according to the radiobuttons setting, is in the proc 'change_theme'.

It is my hope that the copious comments in the code will help Tcl-Tk coding 'newbies' get started in making GUI's like this. Without the comments, the code might look quite unfriendly.

Without the comments, potential young Tcler's might be tempted to return to their iPhones and iPads and iPods --- to watch BFHV (Bulgaria's Funniest Home Videos).

 Code for the Tk script 'demo_tkGUI_themes_using_imagesANDcolors.tk' :

#!/usr/bin/wish -f
##
## Tk SCRIPT NAME:   demo_tkGUI_themes_using_imagesANDcolors.tk
##
##+#######################################################################
## PURPOSE:  This TkGUI script provides a demo GUI that uses about 7 of the
##           commonly used Tk widgets. This is a GUI to demonstrate the ability
##           to provide 'themes' for a Tk GUI, in a quite flexible way (almost
##           anything is possible), using a combination of images and colors.
##
##           This GUI is 'self-theming' in the sense that radiobuttons
##           and a checkbutton on the GUI can be used to reconfigure
##           the GUI with different themes (combinations of 'photo'
##           images and colors).
##
##           For about 4 types of widgets (labels and 3 types of buttons),
##           the images are backgrounds for text on the widget. The text
##           is shown on top of an image via the '-compound center' option.
##
##           The widgets shown are label, button, checkbutton, radiobuttons,
##           scale, canvas, and text --- 7 widgets out of a family of
##           about 18 Tk widgets:
##
##                      button, canvas, checkbutton, entry, frame,
##                      label, labelframe, listbox, menu, menubutton,
##                      message, panedwindow, radiobutton, scale,
##                      scrollbar, spinbox, text, toplevel.
##
##           I have chosen the widgets that I use the most. I also use
##           frame, entry, and listbox widgets frequently, but they do
##           not have an '-image' option. And I seldom use an '-image'
##           option with the text widget.
##
##           Images of two types are read in:
##              - long, rectangular button shapes
##            or 
##              - large (tall and wide) rectangular background shapes.
##           The images are supplied via a GIF or PNG file.
##
##           The image is 'clipped' on each button widget (or 'copied'
##           to make a new image of the right size, for label, radiobutton,
##           and checkbutton widgets), usually according to the width
##           of the text on the widget.
##
##           The image is applied to most widgets with an '-image' option
##           and in most cases with the '-compound center' option.
##
##           The '-compound' option locates the image relative to the text
##           on the widget. Options are
##                     left,right,top,bottom,center,none.
##
##           Only 'center' and 'none' are used in this script.
##
##           (Unfortunately, there seems to be no way to locate the text
##            on the widget in a similar fashion, i.e. via compass points.
##            So one has to make do with having text centered on the
##            image. There is no option to adjust the text to the left side
##            of the underlying image, for example.)
##
##+###########
## GUI DESIGN:
##
##    The GUI includes a couple of LABEL and BUTTON widgets with different
##    lengths of text in them.
##
##    It includes a CHECKBOX widget and at least 2 RADIOBUTTON widgets.
##
##    In addition, there is a SCALE widget and a CANVAS widget.
##    A TEXT widget may also be included.
##
##    Two 'image create' commands load two GIF files into two image
##    'structures' --- for 'button' images and 'background' images ---
##    to be used on the widgets.
##
##+########################################################################
## 'CANONICAL' STRUCTURE OF THIS CODE:
##
##  0) Set general window parms (win-name,win-position,color-scheme,fonts,
##     widget-geom-parameters,win-size-control,text-array-for-labels-etc).
##  1a) Define ALL frames (and sub-frames, if any).
##  1b) Pack   ALL frames and sub-frames.
##  2) Define & pack all widgets in the frames --- going 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 two procs
##     from section 4), if needed.
##
##+#################################
## Some detail on the code structure of this particular Tk script:
##
##  1a) Define ALL frames:
## 
##   Top-level : 
##       - 'fRbuttons_label' for buttons: Exit,Help
##       - 'fRlabel_scale'   for a scale for font-size
##       - 'fRradiobuttons'  for about 4 radiobuttons for color-themes
##       - 'fRcheckbuttons'  for at least one checkbutton --- to turn
##                           images off/on, for example
##       - 'fRcanvas'        for a canvas widget with a background image
##       - 'fRtext'          for a text widget with a background image
##
##  1b) Pack ALL frames.
##
##  2) Define & pack all widgets in the frames -- basically going through
##     frames & their interiors in  left-to-right and/or top-to-bottom order.
##     Only after ALL the widgets for a frame are defined, pack them.
##
##  3) Define bindings:
##       button1-release for the radiobuttons and checkbutton
##
##  4) Define procs:
##      - 'images_on_off'  - for the images off/on checkbutton
##      - 'change_theme'   - for the color-themes radiobuttons
##      - 'reset_fontsize' - for the scale widget
##      - 'popup_msg_var_scroll' - for a Help button
##
##  5) Additional GUI initialization:  set the initial values for the
##       widget variables --- for scale, checkbutton, radiobuttons ---
##       and call 'change_theme' to initialize images in the GUI.
##
##+#######################################################################
## DEVELOPED WITH: Tcl-Tk 8.5 on Ubuntu 9.10 (2009oct version, 'Karmic Koala').
##   wish> puts "$tcl_version $tk_version"
##   8.5 8.5
##+########################################################################
## FE system Copyright 2006+ by Blaise Montandon
##+########################################################################
## MAINTENANCE HISTORY:
## Started by: Blaise Montandon 2012nov04 Started development, on Ubuntu 9.10.
##                                        To develop theme-ing techniques
##                                        for use in Freedom Environment (FE)
##                                        subsystems, such as 'feHandyTools'
##                                        'feHappyScripts','feFileMan',
##                                        and 'tkGooies'.
##                                        See www.freedomenv.com
## Changed by: Blaise Montandon 2012
##+#######################################################################

##+#######################################################################
## SET THE TOP WINDOW NAME.
##+#######################################################################

wm title    . "Demo - Tk Themes --- using images (under text) and colors"
wm iconname . "tkThemesDemo"


##+#######################################################################
##  SET THE TOP WINDOW POSITION.
##+#######################################################################

wm geometry . +10+20


##+#######################################################################
## SET COLOR SCHEME (palette) FOR THE WINDOW.
## (We do that in the GUI INITIALIZATION section at the bottom of
##  this script, where a choice is made of 'color-theme'.)
##+#######################################################################
## and
##+#######################################################################
## SET BACKGROUND COLOR vars FOR WIDGETS, such as
## RADIOBUTTON & CHECKBUTTON widgets.
## Also a faint (initial) foreground color for LABEL widgets ---
## and strong (initial) foreground color for LABEL & BUTTON widgets ---
## which can be reset to blend with image/theme color.
##+#######################################################################

set hexSelectColor_radbutt "#cfcfcf"
set hexSelectColor_chkbutt "#cfcfcf"

set FGimgIDlabelFAINT "#6f6f6f"
set FGimgIDlabel  "#000000"
set FGimgIDbutton "#000000"


##+#########################################################################
## CREATE IMAGE 'STRUCTURES' for widget backgrounds ---
## 3 types --- button, label, and background.
##
## The actual GIF/PNG files used for these image-ID's are set in the
## GUI INITIALIZATION section at the bottom of this script,
## via a call to the 'change_theme' proc.
##+########################################################################

image create photo imgIDbutton

## In order to get the proper width image on 'label' widgets,
## we cannot simply use the '-width' option to 'clip' the
## image, like we can with the 'button' widget.  We need to
## do an image 'copy' to create an appropriate sized image
## for each label widget.

# image create photo imgIDlabel

## Similarly, we need to do an image 'copy' to create an
## appropriate sized image for the radiobutton and
## checkbutton widgets. So we will do 'image create photo'
## at the definition of each widget.

image create photo imgIDbkgnd 


##+#######################################################################
## SET FONT VARS for use in the 'font create' statements below.
##+#######################################################################

set guiFONTsize 14
set guiFONT_SMALLsize 12

## For variable width:

set FONT_varwidth \
   " -family {comic sans ms} -size -$guiFONTsize -weight bold -slant roman "

set FONT_SMALL_varwidth \
   " -family {comic sans ms} -size -$guiFONT_SMALLsize -weight normal -slant roman "


## For fixed width:

set FONT_fixedwidth \
   " -family {dejavu sans mono} -size -$guiFONTsize -weight bold -slant roman "

set FONT_SMALL_fixedwidth \
   " -family {dejavu sans mono} -size -$guiFONT_SMALLsize -weight normal -slant roman "


##+#####################################################################
## DEFINE (temporary) FONT NAMES using 'font create'.
## The font names are to be used in '-font' widget specs below.
##+#####################################################################

eval font create fontTEMP_varwidth   $FONT_varwidth
eval font create fontTEMP_fixedwidth $FONT_fixedwidth


eval font create fontTEMP_button  $FONT_varwidth
eval font create fontTEMP_label   $FONT_varwidth

eval font create fontTEMP_text    $FONT_fixedwidth

## Add these widgets to the demo someday?
# 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_SMALL_button  $FONT_SMALL_varwidth
eval font create fontTEMP_SMALL_label   $FONT_SMALL_varwidth

eval font create fontTEMP_SMALL_text    $FONT_SMALL_fixedwidth

## Someday?
# 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


##+#######################################################################
## SET GEOM VARS FOR THE VARIOUS WIDGET DEFINITIONS.
## (e.g. padx,pady for Buttons)
##+#######################################################################

## For BUTTON widgets:
   
set PADY_button 0
set PADX_button 0
set BDwidth_button 2


## For LABEL widgets:

set PADY_label 0
set PADX_label 0
set BDwidth_label 2


## For TEXT widgets:

set BDwidth_text 2


##+#######################################################################
##  SET the top window MIN-SIZE (roughly).
##
## For width: allow for several buttons in the '.fRbuttons' frame:
##               about 2 buttons (Exit,Help), but not
##               an ending info-label. We will allow the user to
##               make this window fairly narrow, but keep the
##               Exit and Help buttons showing.
##
## For height: allow 1 char high for each of the 6 frames:
##       - 'fRbuttons_label' for buttons: Exit,Help - and an info-label
##       - 'fRlabel_scale'   for a scale for font-size, with label
##       - 'fRradiobuttons'  for several radiobuttons for color-theme
##       - 'fRcheckbuttons'  for a checkbutton, to turn images off/on
##       - 'fRcanvas'        for a canvas widget
##       - 'fRtext'          for a text widget
##+#######################################################################

set minWinWidthPx [font measure fontTEMP_varwidth \
   "Exit  Help"]

## Add some pixels to account for right-left-side window decoration
## (about 8 pixels), about 2 widgets x 3 pixels/widget for borders/padding
## for 2 widgets --- 2 buttons.

set minWinWidthPx [expr {14 + $minWinWidthPx}]


## MIN HEIGHT --- allow for about 6 chars high in the 6 stacked frames:

set charHeightPx [font metrics fontTEMP_fixedwidth -linespace]
set minWinHeightPx [expr { 6 * $charHeightPx}]

## Add about 28 pixels for top-bottom window decoration, and
## about 6 frames x 4 pixels/frame for the widgets' borders/padding.

set minWinHeightPx [expr {$minWinHeightPx + 52}]

## 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 an 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(labelINFO)     "Use checkbutton below to turn images off/on."
set aRtext(labelFONTSIZE) "FontSize (pixels):"
set aRtext(labelTHEME)    "Color Theme:"
set aRtext(radbuttBLUE)   "Blue"
set aRtext(radbuttORANGE) "Orange"
set aRtext(radbuttGREEN)  "Green"
set aRtext(radbuttGRAY)   "Gray"

set aRtext(labelIMAGES0or1) "Images on GUI:"
set aRtext(chkbuttIMAGES0or1) ""

## Use the following statement instead of the 2 statements above,
## if we put text in the checkbutton, instead of using a label widget.

# set aRtext(chkbuttIMAGES0or1) "Images on GUI"

## END OF  if { "$VARlocale" == "en"}


##+####################################################################
##+####################################################################
## DEFINE *ALL* THE FRAMES:
##
##   Top-level :
##
##       - 'fRbuttons_label' for buttons: Exit,Help and an info-label
##       - 'fRlabel_scale'   for a scale for font-size
##       - 'fRradiobuttons'  for several radiobuttons for color-themes
##       - 'fRcheckbuttons'  for a checkbutton to turn images off/on
##       - 'fRcanvas'        for a canvas widget
##       - 'fRtext'          for a text widget
##
##+####################################################################
##+####################################################################

## FOR TESTING of expansion of frames (esp. during window expansion):
# set RELIEF_frame raised
# set BDwidth_frame 2

  set RELIEF_frame flat
  set BDwidth_frame 0


frame .fRbuttons_label -relief $RELIEF_frame  -borderwidth $BDwidth_frame

frame .fRlabel_scale   -relief $RELIEF_frame  -borderwidth $BDwidth_frame

frame .fRradiobuttons  -relief $RELIEF_frame  -borderwidth $BDwidth_frame
frame .fRcheckbuttons  -relief $RELIEF_frame  -borderwidth $BDwidth_frame

frame .fRcanvas  -relief $RELIEF_frame  -borderwidth $BDwidth_frame
frame .fRtext    -relief $RELIEF_frame  -borderwidth $BDwidth_frame


##+########################################################
## PACK *ALL* the FRAMES.
##+########################################################

pack .fRbuttons_label \
   -side top \
   -anchor nw \
   -fill none \
   -expand 0

pack .fRlabel_scale \
   -side top \
   -anchor nw \
   -fill none \
   -expand 0

pack .fRradiobuttons \
   -side top \
   -anchor nw \
   -fill none \
   -expand 0

pack .fRcheckbuttons \
   -side top \
   -anchor nw \
   -fill none \
   -expand 0

pack .fRcanvas \
   -side top \
   -anchor nw \
   -fill both \
   -expand 1

pack .fRtext \
   -side top \
   -anchor nw \
   -fill both \
   -expand 1


##+################################################################
##+################################################################
## START DEFINING & PACKING WIDGETS WITHIN THEIR FRAMES. 
##+################################################################
##+################################################################

##+##########################################################
## IN THE '.fRbuttons_label' FRAME --
## DEFINE several BUTTONS
## --- Exit, Help --- and 1 LABEL widget.
##+##########################################################

set widthPXbuttEXIT [font measure fontTEMP_button " $aRtext(buttonEXIT) "]

button .fRbuttons_label.buttEXIT \
   -text "$aRtext(buttonEXIT)" \
   -font fontTEMP_button \
   -padx $PADX_button \
   -pady $PADY_button \
   -relief raised \
   -bd $BDwidth_button \
   -image imgIDbutton \
   -fg $FGimgIDbutton \
   -compound center \
   -width $widthPXbuttEXIT \
   -command {exit}


set widthPXbuttHELP [font measure fontTEMP_button " $aRtext(buttonHELP) "]

button .fRbuttons_label.buttHELP \
   -text "$aRtext(buttonHELP)" \
   -font fontTEMP_button \
   -padx $PADX_button \
   -pady $PADY_button \
   -relief raised \
   -bd $BDwidth_button \
   -image imgIDbutton \
   -fg $FGimgIDbutton \
   -compound center \
   -width $widthPXbuttHELP \
   -command {popup_msg_var_scroll "$HELPtext"}


image create photo imgIDlabelINFO

## We will build the image in proc 'change_theme', which is called
## in the GUI INITIALIZATION section at the bottom of this script.

label .fRbuttons_label.labelINFO \
   -text "$aRtext(labelINFO)" \
   -font fontTEMP_label \
   -padx $PADX_label \
   -pady $PADY_label \
   -justify left \
   -anchor w \
   -relief raised \
   -bd $BDwidth_label \
   -width 0 \
   -image imgIDlabelINFO \
   -fg $FGimgIDlabelFAINT \
   -compound center

#   -fg $FGimgIDlabel \


##+####################################################
## Pack ALL the widgets in the 'fRbuttons_label' frame.
##+####################################################

pack .fRbuttons_label.buttEXIT \
     .fRbuttons_label.buttHELP \
   -side left \
   -anchor w \
   -fill none \
   -expand 0

pack .fRbuttons_label.labelINFO \
   -side left \
   -anchor w \
   -fill none \
   -expand 0


##+########################################################
## IN THE '.fRlabel_scale' FRAME --
## DEFINE 1 SCALE widget (for specifying font-size),
## with 1 LABEL widget on the left of the scale.
##+########################################################

image create photo imgIDlabelFONTSIZE

## We will build the image in proc 'change_theme', which is called
## in the GUI INITIALIZATION section at the bottom of this script.

label .fRlabel_scale.labelFONTSIZE \
   -text "$aRtext(labelFONTSIZE)" \
   -font fontTEMP_label \
   -padx $PADX_label \
   -pady $PADY_label \
   -justify left \
   -anchor w \
   -relief  flat \
   -bd $BDwidth_label \
   -width 0 \
   -image imgIDlabelFONTSIZE \
   -fg $FGimgIDlabel \
   -compound center


## We will set 'fontSIZE' (the scale variable) in the
## GUI-init section at the bottom of this script.
##
# set fontSIZE 14

scale .fRlabel_scale.scaleFONTSIZE \
   -orient horizontal \
   -resolution 1 \
   -from 8 -to 16 \
   -digits 0 \
   -length 350 \
   -repeatdelay 1000 \
   -font fontTEMP_label \
   -variable fontSIZE \
   -fg "#ffffff" \
   -troughcolor "#f0f0f0" \
   -command "reset_fontsize"

## The background color ('-bg') for the scale will be
## set in the call to 'change_theme'.


## Pack ALL the widgets in frame 'fRlabel_scale'.

pack .fRlabel_scale.labelFONTSIZE \
   -side left \
   -anchor w \
   -fill none \
   -expand 0

pack .fRlabel_scale.scaleFONTSIZE \
   -side left \
   -anchor w \
   -fill x \
   -expand 0

## WARNING: DO NOT USE '-expand 1'. It makes the scale action 'jumpy'.


##+########################################################
## IN THE 'fRradiobuttons' FRAME --
## DEFINE 1 LABEL widget
## and several RADIOBUTTONS (for 'color-theme').
##+########################################################

image create photo imgIDlabelTHEME

## We will build the image in proc 'change_theme', which is called
## in the GUI INITIALIZATION section at the bottom of this script.

label .fRradiobuttons.labelTHEME \
   -text "$aRtext(labelTHEME)" \
   -font fontTEMP_label \
   -padx $PADX_label \
   -pady $PADY_label \
   -justify left \
   -anchor w \
   -relief  flat \
   -bd $BDwidth_label \
   -width 0 \
   -image imgIDlabelTHEME \
   -fg $FGimgIDlabel \
   -compound center


## VARtheme is the var for the 'color-theme' radiobuttons.
## It will be set in the GUI-init section at the bottom of
## this script.


image create photo imgIDradbuttBLUE

## We will build the image in proc 'change_theme', which is called
## in the GUI INITIALIZATION section at the bottom of this script.

radiobutton  .fRradiobuttons.radbuttBLUE \
   -text "$aRtext(radbuttBLUE)" \
   -font fontTEMP_button \
   -anchor w \
   -padx $PADX_button \
   -pady $PADY_button \
   -variable VARtheme \
   -value "blue" \
   -selectcolor $hexSelectColor_radbutt \
   -relief raised \
   -bd 2 \
   -image imgIDradbuttBLUE \
   -fg $FGimgIDbutton \
   -width 0 \
   -compound center


image create photo imgIDradbuttORANGE

## We will build the image in proc 'change_theme', which is called
## in the GUI INITIALIZATION section at the bottom of this script.

radiobutton .fRradiobuttons.radbuttORANGE \
   -text "$aRtext(radbuttORANGE)" \
   -font fontTEMP_button \
   -anchor w \
   -padx $PADX_button \
   -pady $PADY_button \
   -variable VARtheme \
   -value "orange" \
   -selectcolor $hexSelectColor_radbutt \
   -relief raised \
   -bd 2 \
   -image imgIDradbuttORANGE \
   -fg $FGimgIDbutton \
   -width 0 \
   -compound center


image create photo imgIDradbuttGREEN

## We will build the image in proc 'change_theme', which is called
## in the GUI INITIALIZATION section at the bottom of this script.

radiobutton  .fRradiobuttons.radbuttGREEN \
   -text "$aRtext(radbuttGREEN)" \
   -font fontTEMP_button \
   -anchor w \
   -padx $PADX_button \
   -pady $PADY_button \
   -variable VARtheme \
   -value "green" \
   -selectcolor $hexSelectColor_radbutt \
   -relief raised \
   -bd 2 \
   -image imgIDradbuttGREEN \
   -fg $FGimgIDbutton \
   -width 0 \
   -compound center


image create photo imgIDradbuttGRAY

## We will build the image in proc 'change_theme', which is called
## in the GUI INITIALIZATION section at the bottom of this script.

radiobutton .fRradiobuttons.radbuttGRAY \
   -text "$aRtext(radbuttGRAY)" \
   -font fontTEMP_button \
   -anchor w \
   -padx $PADX_button \
   -pady $PADY_button \
   -variable VARtheme \
   -value "gray" \
   -selectcolor $hexSelectColor_radbutt \
   -relief raised \
   -bd 2 \
   -image imgIDradbuttGRAY \
   -fg $FGimgIDbutton \
   -width 0 \
   -compound center


## PACK ALL the widgets in frame 'fRradiobuttons'.

pack  .fRradiobuttons.labelTHEME \
      .fRradiobuttons.radbuttBLUE \
      .fRradiobuttons.radbuttORANGE \
      .fRradiobuttons.radbuttGREEN \
      .fRradiobuttons.radbuttGRAY \
   -side left \
   -anchor w \
   -fill none \
   -expand 0 


##+########################################################
## IN THE 'fRcheckbuttons' FRAME --
## DEFINE 1 LABEL & 1 CHECKBUTTON widget
## (to turn images on the GUI on or off).
##+########################################################

image create photo imgIDlabelIMAGES0or1

## We will build the image in proc 'change_theme', which is called
## in the GUI INITIALIZATION section at the bottom of this script.

label .fRcheckbuttons.labelIMAGES0or1 \
   -text "$aRtext(labelIMAGES0or1)" \
   -font fontTEMP_label \
   -padx $PADX_label \
   -pady $PADY_label \
   -justify left \
   -anchor w \
   -relief  flat \
   -bd $BDwidth_label \
   -image imgIDlabelIMAGES0or1 \
   -width 0 \
   -fg $FGimgIDlabel \
   -compound center


## The checkbutton var 'VARimgs0or1' will be set in the
## GUI-init section at the bottom of this script.
## set VARimgs0or1 1


## Activate this statement, if we put text in the checkbutton,
## instead of using the label widget above.

# image create photo imgIDchkbuttIMAGES0or1

## If we use the image:
## We will build the image in proc 'change_theme', which is called
## in the GUI INITIALIZATION section at the bottom of this script.

checkbutton .fRcheckbuttons.chkbuttIMAGES0or1 \
   -text "$aRtext(chkbuttIMAGES0or1)" \
   -font  fontTEMP_button \
   -padx $PADX_button \
   -pady $PADY_button \
   -variable VARimgs0or1 \
   -selectcolor $hexSelectColor_chkbutt \
   -relief raised \
   -bd 2

## Activate this if we put text in the checkbutton,
## instead of using a label widget.

#   -image imgIDchkbuttIMAGES0or1 \
#   -fg $FGimgIDbutton \
#   -compound center \
#   -width 0


## PACK ALL the widgets in frame 'fRcheckbuttons'.

pack .fRcheckbuttons.labelIMAGES0or1 \
     .fRcheckbuttons.chkbuttIMAGES0or1 \
   -side left \
   -anchor w \
   -fill none \
   -expand 0


##+########################################################
## IN THE 'fRcanvas' frame --
## DEFINE 1 CANVAS widget, with x,y scrollbars.
##+########################################################
##  NOTE: We can trim the image by using the '-width' and
## '-height' options (in pixels) when creating the canvas.

## We could set the initial canvas size according to
## percents (say 30% & 20%) of the screen width and height.

canvas .fRcanvas.canvas \
   -width 300 \
   -height 100 \
   -relief raised \
   -borderwidth 2 \
   -yscrollcommand ".fRcanvas.scrbary set" \
   -xscrollcommand ".fRcanvas.scrbarx set" \

scrollbar .fRcanvas.scrbary \
   -orient vertical -command ".fRcanvas.canvas yview"

scrollbar .fRcanvas.scrbarx \
   -orient horizontal -command ".fRcanvas.canvas xview"

## Put an image on the canvas.

.fRcanvas.canvas create image 0 0  \
   -image imgIDbkgnd \
   -anchor nw \
   -tag CANVASTAGimg 

## Put some text on the canvas.

.fRcanvas.canvas create text 0 0  \
   -text "This is a canvas widget." \
   -font fontTEMP_fixedwidth \
   -anchor nw \
   -tag CANVASTAGtext


## Pack ALL the widgets in the 'fRcanvas' frame.

pack .fRcanvas.scrbary \
   -side right \
   -anchor e \
   -fill y \
   -expand 0

pack .fRcanvas.scrbarx \
   -side bottom \
   -anchor sw \
   -fill x \
   -expand 0

pack .fRcanvas.canvas \
   -side left \
   -anchor nw \
   -fill both \
   -expand 1


##+###########################################################
## IN THE '.fRtext' frame --
## DEFINE 1 TEXT areas --- with x,y scrollbars.
##+###########################################################
## NOTE1: The '-width' and '-height' options are in CHARS,
##        NOT pixels and the like.
## NOTE2: We can trim the image by using the '-width' and
## '-height' options (in chars) when creating the text widget.

text .fRtext.txtDEMO \
   -relief raised \
   -borderwidth 2 \
   -height 9 \
   -width  18 \
   -wrap none \
   -font fontTEMP_text \
   -fg "#000000" \
   -yscrollcommand ".fRtext.scrbary set" \
   -xscrollcommand ".fRtext.scrbarx set"

scrollbar .fRtext.scrbary \
   -command ".fRtext.txtDEMO yview"

scrollbar .fRtext.scrbarx \
   -orient horizontal \
   -command ".fRtext.txtDEMO xview"

## Put some text on the text area.

# .fRtext.txtDEMO delete 1.0 end
# .fRtext.txtDEMO insert end "This is a text widget."

.fRtext.txtDEMO insert 1.0 "This is a text widget.
"

## Put an image on the text area.

.fRtext.txtDEMO image create end \
  -image imgIDbkgnd \
  -align top

## Note to myself: Tried to make a tag here.
## Error in startup script: unknown option "-tag"
##  -tag TEXTTAGimg


##+###################################################
## Pack ALL the text widgets in the '.fRtext' frame.
##+###################################################

pack .fRtext.scrbary \
   -side right \
   -anchor center \
   -fill y \
   -expand 0

pack .fRtext.scrbarx \
   -side bottom \
   -anchor center \
   -fill x \
   -expand 0

pack .fRtext.txtDEMO \
   -side top \
   -anchor nw \
   -fill both \
   -expand 1

##+#################################################
## Keep the user from changing the demo text,
## in case they type in the widget.
##+#################################################

.fRtext.txtDEMO configure -state disabled


##+#####################################################################
## END OF SECTIONS TO SETUP THE GUI.
## ALL FRAMES and WIDGETS are DEFINED.
##+#####################################################################

##+#####################################################################
##+#####################################################################
## DEFINE BINDINGS:
##   -  <ButtonRelease-1> events for the radiobuttons & checkbutton.
##+#####################################################################

bind .fRradiobuttons.radbuttBLUE   <ButtonRelease-1>  "change_theme"
bind .fRradiobuttons.radbuttORANGE <ButtonRelease-1>  "change_theme"
bind .fRradiobuttons.radbuttGREEN  <ButtonRelease-1>  "change_theme"
bind .fRradiobuttons.radbuttGRAY   <ButtonRelease-1>  "change_theme"

bind  .fRcheckbuttons.chkbuttIMAGES0or1 <ButtonRelease-1>  "images_on_off"

## Could use this binding, instead of '-command' on the scale widget.
# bind .fRlabel_scale.scaleSIZE  <ButtonRelease-1>  "reset_fontsize 0"


##+#####################################################################
##+#####################################################################
## DEFINE PROCEDURES:
##      - 'images_on_off'  - for the images off/on checkbutton
##      - 'change_theme'   - for the color-themes radiobuttons
##      - 'reset_fontsize' - for the scale widget
##      - 'popup_msg_var_scroll' - for a Help button
##+#####################################################################
##+#####################################################################

##+#####################################################################
## proc 'images_on_off'
##+#####################################################################
## PURPOSE: Changes the '-image'and '-compound' options on the
##          label and button widgets.
##
## Arguments: via global vars
##
## CALLED BY: button1-release binding on the images-on/off checkbutton
##+#####################################################################
## Note: We start with embellishment (images) ON.
## We set that checkbutton variable in the GUI initialization
## section at the bottom of this script.
##     set VARimgs0or1 1

proc images_on_off {} {

   global VARimgs0or1 widthPXbuttEXIT widthPXbuttHELP

   if {"$VARimgs0or1" == "0"} {

      .fRbuttons_label.buttEXIT      configure -image "" -compound none -width 0
      .fRbuttons_label.buttHELP      configure -image "" -compound none -width 0
      .fRbuttons_label.labelINFO     configure -image "" -compound none -width 0

      .fRlabel_scale.labelFONTSIZE   configure -image "" -compound none

      .fRradiobuttons.labelTHEME     configure -image "" -compound none -width 0
      .fRradiobuttons.radbuttBLUE    configure -image "" -compound none -width 0
      .fRradiobuttons.radbuttORANGE  configure -image "" -compound none -width 0
      .fRradiobuttons.radbuttGREEN   configure -image "" -compound none -width 0
      .fRradiobuttons.radbuttGRAY    configure -image "" -compound none -width 0

      .fRcheckbuttons.labelIMAGES0or1    configure -image "" -compound none -width 0

      ## Activate if we put text in the checkbutton, instead of using a label widget.
      # .fRcheckbuttons.chkbuttIMAGES0or1  configure -image "" -compound none -width 0

      ## Using 'delete all' is a rather indiscriminate way to remove
      ## the images from the canvas and text area. In case there are
      ## other objects on these widgets, we have to
      ## use a more specific technique.

      .fRcanvas.canvas          delete -tag CANVASTAGimg         
      # .fRtext.txtDEMO           delete -tag TEXTTAGimg

   } else {

      .fRbuttons_label.buttEXIT      configure -image imgIDbutton    -compound center -width $widthPXbuttEXIT
      .fRbuttons_label.buttHELP      configure -image imgIDbutton    -compound center -width $widthPXbuttHELP
      .fRbuttons_label.labelINFO     configure -image imgIDlabelINFO -compound center

      .fRlabel_scale.labelFONTSIZE   configure -image imgIDlabelFONTSIZE -compound center

      .fRradiobuttons.labelTHEME     configure -image imgIDlabelTHEME    -compound center
      .fRradiobuttons.radbuttBLUE    configure -image imgIDradbuttBLUE   -compound center
      .fRradiobuttons.radbuttORANGE  configure -image imgIDradbuttORANGE -compound center
      .fRradiobuttons.radbuttGREEN   configure -image imgIDradbuttGREEN  -compound center
      .fRradiobuttons.radbuttGRAY    configure -image imgIDradbuttGRAY   -compound center

      .fRcheckbuttons.labelIMAGES0or1    configure -image imgIDlabelIMAGES0or1   -compound center

      ## Activate if we put text in the checkbutton, instead of using a label widget.
      # .fRcheckbuttons.chkbuttIMAGES0or1  configure -image imgIDchkbuttIMAGES0or1 -compound center

      ## Put the bkgnd img back on the canvas and text area.

      .fRcanvas.canvas create image 0 0 \
         -image imgIDbkgnd \
         -anchor nw -tag CANVASTAGimg

      .fRcanvas.canvas raise CANVASTAGtext

      # .fRtext.txtDEMO image create 1.0 \
      #    -image imgIDbkgnd

   }
   ## END OF  if {$VARimgs0or1 == 1}

}
## END OF PROC  'images_on_off'


##+########################################################################
## PROC 'change_theme'
##+########################################################################
## PURPOSE: Change the color and images on the GUI.
##
## Arguments for input:  global vars VARtheme, aRtext
## Arguments for output: global vars heightPXimgIDbutton, heightPXimgIDlabel
##
## CALLED BY: button1-release on color-theme radiobuttons
##+########################################################################

proc change_theme {} {

   global VARtheme aRtext heightPXimgIDbutton heightPXimgIDlabel

   ## Set an theme (color and images) according to
   ## the value of the radiobuttons var, VARtheme.
   ## There are 'blue' 'orange' 'green' 'gray' sections below.

   if {"$VARtheme" == "blue"} {

      ## Set the variable for the color-theme radiobuttons.

      set VARtheme "blue"

      ## Set the RGB values for the 'format' and 'tk_setPalette'
      ## statements below.

      ## Bright blue.
      # set R255pal 160
      # set G255pal 200
      # set B255pal 255

      ## Darker blue.
      # set R255pal 186
      # set G255pal 222
      # set B255pal 241

      ## Still darker blue.
      set R255pal 145
      set G255pal 180
      set B255pal 200

      ## Set images for button, label, background.
      ## Note: We allow for the image on labels and buttons being different.

      image create photo imgIDbutton \
         -file "./buttonBkgnd_sheeny_lightBlue_424x28.gif"

      image create photo imgIDlabel \
         -file "./buttonBkgnd_sheeny_lightBlue_424x28.gif"

      ## Set foreground color for the buttons.
      set FGimgIDbutton "#000000"

      ## Set foreground color for the labels.
      set FGimgIDlabel "#000000"
      set FGimgIDlabelFAINT "#6f6f6f"

      ## Some button/label options:
      ##   buttonBkgnd_glass_blue_A_424x32.gif
      ##   buttonBkgnd_glassy_aqua_496x28.gif
      ##   buttonBkgnd_shaded_paleblue_504x26.gif
      ##   buttonBkgnd_sheeny_blue_432x28.gif
      ##   buttonBkgnd_sheeny_lightBlue_424x28.gif


      image create photo imgIDbkgnd \
      -file "./bigBkgnd_blueWaterAndBeach_1280x744.gif"

      ## Some background options:
      ##   bigBkgnd_RainDrops_onWaterSurface_1280x565.gif
      ##   bigBkgnd_blueWaterAndBeach_1280x744.gif
      ##   bigBkgnd_sunlight_thru_blue_1143x300.gif

   }
   ## END OF 'blue' theme.


   if {"$VARtheme" == "orange"} {

      ## Set the variable for the color-theme radiobuttons.

      set VARtheme "orange"

      ## Set the RGB values for the 'format' and 'tk_setPalette'
      ## statements below.

      ## Orange.
      set R255pal 255
      set G255pal 200
      set B255pal 0

      ## Set images for button, label, background.
      ## Note: We allow for the image on labels and buttons being different.

      image create photo imgIDbutton \
         -file "./buttonBkgnd_glossy_orange_512x28.gif"

      image create photo imgIDlabel \
         -file "./buttonBkgnd_glossy_orange_512x28.gif"

      ## Set foreground color for the buttons.
      set FGimgIDbutton "#000000"

      ## Set foreground color for the labels.
      set FGimgIDlabel "#000000"
      set FGimgIDlabelFAINT "#6f6f6f"

      ## Some button/label options:
      ##   buttonBkgnd_glossy_orange_512x28.gif
      ##   buttonBkgnd_shaded_orange_744x28.gif

      image create photo imgIDbkgnd \
         -file "./bigBkgnd_antelope_canyon_sandstone_760x757.gif"

      ## Some background options:
      ##   bigBkgnd_antelope_canyon_sandstone_760x757.gif

   }
   ## END OF 'orange' theme.


   if {"$VARtheme" == "green"} {

      ## Set the variable for the color-theme radiobuttons.

      set VARtheme "green"

      ## Set the RGB values for the 'format' and 'tk_setPalette'
      ## statements below.

      ## Green.
      set R255pal 100
      set G255pal 200
      set B255pal 0

      ## Set images for button, label, background.
      ## Note: We allow for the image on labels and buttons being different.

      image create photo imgIDbutton \
         -file "./buttonBkgnd_sheeny_green_416x28.gif"

      image create photo imgIDlabel \
         -file "./buttonBkgnd_sheeny_green_416x28.gif"

      ## Set foreground color for the buttons.
      set FGimgIDbutton "#000000"

      ## Set foreground color for the labels.
      set FGimgIDlabel "#000000"
      set FGimgIDlabelFAINT "#6f6f6f"

      ## Some button/label image options:
      ##   buttonBkgnd_sheeny_green_416x28.gif


      image create photo imgIDbkgnd \
         -file "./bigBkgnd_reliefMap_eastTexas_568x664.gif"

      ## Some background image options:
      ##   bigBkgnd_lightRays_green_766x300.gif
      ##   bigBkgnd_reliefMap_eastTexas_568x664.gif
      ##   bigBkgnd_water_drops_green_1280x1024.gif

   }
   ## END OF 'green' theme.


   if {"$VARtheme" == "gray"} {

      ## Set the variable for the color-theme radiobuttons.

      set VARtheme "gray"

      ## Set the RGB values for the 'format' and 'tk_setPalette'
      ## statements below.

      ## Gray.
      set R255pal 210
      set G255pal 210
      set B255pal 210

      ## Set images for button, label, background.
      ## Note: We allow for the image on labels and buttons being different.

      image create photo imgIDbutton \
         -file "./buttonBkgnd_gradient_gray_592x28.gif"

      image create photo imgIDlabel \
         -file "./buttonBkgnd_gradient_gray_592x28.gif"

      ## Set foreground color for the buttons.
      set FGimgIDbutton "#000000"

      ## Set foreground color for the labels.
      set FGimgIDlabel "#000000"
      set FGimgIDlabelFAINT "#6f6f6f"

      ## Some button/label image options:
      ##   buttonBkgnd_gradient_gray_592x28.gif

      image create photo imgIDbkgnd \
         -file "./bigBkgnd_lightRays_gray_766x300.gif"

      ## Some background image options:
      ##   bigBkgnd_lightRays_gray_766x300.gif

   }
   ## END OF 'gray' theme.

   ## Set the palette color from the RGB palette values chosen.
   set hexCOLORpal [format "#%02X%02X%02X" $R255pal $G255pal $B255pal]
   tk_setPalette $hexCOLORpal

   ## Put height of the chosen button image in a var.

   set heightPXimgIDbutton [image height imgIDbutton]

   ## Put height of the chosen label image in a var.

   set heightPXimgIDlabel [image height imgIDlabel]


   ## Create the image for the 'labelINFO' widget, sized properly.

   set tempWidthPx [font measure fontTEMP_label " $aRtext(labelINFO) "]
   # image create photo imgIDlabelINFO
   imgIDlabelINFO copy imgIDlabel -from 0 0 $tempWidthPx $heightPXimgIDlabel

   ## Set the foreground (text) color for the 'labelINFO' widget.

   .fRbuttons_label.labelINFO configure -fg $FGimgIDlabelFAINT


   ## Create the image for the 'labelIMAGES0or1' widget, sized properly.

   set tempWidthPx [font measure fontTEMP_varwidth " $aRtext(labelIMAGES0or1) "]
   # image create photo imgIDlabelIMAGES0or1
   imgIDlabelIMAGES0or1 copy imgIDlabel -from 0 0 $tempWidthPx $heightPXimgIDlabel


   ## Create the image for the 'labelFONTSIZE' widget, sized properly.

   set tempWidthPx [font measure fontTEMP_label " $aRtext(labelFONTSIZE) "]
   # image create photo imgIDlabelFONTSIZE
   imgIDlabelFONTSIZE copy imgIDlabel -from 0 0 $tempWidthPx $heightPXimgIDlabel

   ## Reset the background color for the 'scaleFONTSIZE' widget.

   .fRlabel_scale.scaleFONTSIZE  configure -bg $hexCOLORpal


   ## Create the image for the 'labelTHEME' widget, sized properly.

   set tempWidthPx [font measure fontTEMP_varwidth " $aRtext(labelTHEME) "]
   # image create photo imgIDlabelTHEME
   imgIDlabelTHEME copy imgIDlabel -from 0 0 $tempWidthPx $heightPXimgIDlabel


   ## Create the image for the 'radbuttBLUE' widget, sized properly.

   set tempWidthPx [font measure fontTEMP_varwidth " $aRtext(radbuttBLUE) "]
   # image create photo imgIDradbuttBLUE
   imgIDradbuttBLUE copy imgIDbutton -from 0 0 $tempWidthPx $heightPXimgIDbutton

   ## Create the image for the 'radbuttORANGE' widget, sized properly.

   set tempWidthPx [font measure fontTEMP_varwidth " $aRtext(radbuttORANGE) "]
   # image create photo imgIDradbuttORANGE
   imgIDradbuttORANGE copy imgIDbutton -from 0 0 $tempWidthPx $heightPXimgIDbutton

   ## Create the image for the 'radbuttGREEN' widget, sized properly.

   set tempWidthPx [font measure fontTEMP_varwidth " $aRtext(radbuttGREEN) "]
   # image create photo imgIDradbuttGREEN
   imgIDradbuttGREEN copy imgIDbutton -from 0 0 $tempWidthPx $heightPXimgIDbutton

   ## Create the image for the 'radbuttGRAY' widget, sized properly.

   set tempWidthPx [font measure fontTEMP_varwidth " $aRtext(radbuttGRAY) "]
   # image create photo imgIDradbuttGRAY
   imgIDradbuttGRAY copy imgIDbutton -from 0 0 $tempWidthPx $heightPXimgIDbutton


   ## Create the image for the 'labelIMAGES0or1' widget, sized properly.

   set tempWidthPx [font measure fontTEMP_varwidth " $aRtext(labelIMAGES0or1) "]
   # image create photo imgIDlabelIMAGES0or1
   imgIDlabelIMAGES0or1 copy imgIDlabel -from 0 0 $tempWidthPx $heightPXimgIDlabel


   ## Create the image for the 'chkbuttIMAGES0or1' widget, sized properly.
   ## Activate if we put text in the checkbutton, instead of using a label widget.

   # set tempWidthPx [font measure fontTEMP_varwidth "$aRtext(chkbuttIMAGES0or1)"]
   # # image create photo imgIDchkbuttIMAGES0or1
   # imgIDchkbuttIMAGES0or1 copy imgIDbutton -from 0 0 $tempWidthPx $heightPXimgIDbutton

}
## END OF PROC  'change_theme'


##+########################################################################
## PROC 'reset_fontsize'
##+########################################################################
## PURPOSE: Change the size of fonts on the GUI.
## CALLED BY: '-command' option of the scale widget
##+########################################################################

proc reset_fontsize { fontsizePx } {

   global VARfontsize

   font configure fontTEMP_varwidth   -size [expr {-$fontsizePx}]
   font configure fontTEMP_fixedwidth -size [expr {-$fontsizePx}]

   font configure fontTEMP_button     -size [expr {-$fontsizePx}]
   font configure fontTEMP_label      -size [expr {-$fontsizePx}]
   font configure fontTEMP_text       -size [expr {-$fontsizePx}]

}
## END OF PROC  'reset_fontsize'


##+########################################################################
## 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_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 .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_varwidth \
      -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'


set HELPtext "\
\ \ \ \ \ ** HELP for this Tk 'Theme-ing' demo **

  This TkGUI script provides a demo GUI that uses about 7 of the
  commonly used Tk widgets. This is a GUI to demonstrate the ability
  to provide 'themes' for a GUI, even on Linux, using a combination
  of images and colors.

  This demo GUI is 'self-theming' in the sense that radiobuttons
  and checkbuttons on the GUI can be used to reconfigure
  the GUI with different themes (combinations of 'photo'
  images and colors).

  For about 4 types of widgets (label, button, radiobutton,
  checkbutton), the images are backgrounds for text
  on the widget. The text is shown on top of an image
  via the '-compound center' option.

  The widgets shown are label, button, checkbutton, radiobuttons,
  scale, canvas, and text --- 7 widgets out of a family of
  about 18 Tk widgets:

         button, canvas, checkbutton, entry, frame,
         label, labelframe, listbox, menu, menubutton,
         message, panedwindow, radiobutton, scale,
         scrollbar, spinbox, text, toplevel.

 I have chosen widgets that I use the most. I also use
 'frame', 'entry', and 'listbox' widgets frequently, but they
 do not have an '-image' option. So I do not include an
 'entry' or 'listbox' widget on this demo GUI. For the sake of
 blending those kinds of widgets into a 'theme', I may add
 those two widgets in a future version of this demo.

 Although I have never used an '-image' option with the 'text'
 widget and cannot forsee doing so in the future, I include an
 image-on-a-text-widget here --- to demo putting an image on
 a text widget, in case others find that something they may
 want to do.

 The images used in this demo are either
    - a long, rectangular button or label shape
 OR
    - a large, 'fat' background shape.
 The images are 'clipped' to fit the various sized widgets.
 The images are supplied via a GIF or PNG file.

 The image is 'clipped' on each 'button' widget (or 'copied'
 to make a new image of the right size, for 'label', 'radiobutton',
 and 'checkbutton' widgets), usually according to the width
 of the text on the widget.

     (The '-width' option of the 'button' widget seems to
      support clipping the image supplied in the '-image'
      option. But that does not seem to be the case for
      'label', 'radiobutton',  and 'checkbutton' widgets.
      I had to use an image-copy technique to clip the 
      images for those widgets.)

 The image is applied to most widgets with an '-image' option
 and in most cases with the '-compound center' option.
 Exceptions are the scale, canvas, and text widgets.

 The '-compound' option locates the image relative to the text
 on the widget. Options are
           left,right,top,bottom,center,none.

 In this demo script, we only use 'center' and 'none'.

    Unfortunately, there seems to be no way to locate the text
    on the image in a similar fashion, i.e. via compass points.
    So one has to make do with having text centered on the
    image. There is no option to adjust the text to the left side
    of the underlying image, for example. For that kind of
    flexibility, the only option currently available
    (as of Tk/wish 8.6) appears to be to use the canvas widget.
"


##+######################################################
## Additional GUI INITIALIZATION:
## (for most of the APPLICATION-SPECIFIC initialization;
##  i.e. for widget VARIABLES --- NOT widget APPEARANCE
##  PARAMETERS like button padding or '-relief' settings.)
##+######################################################

## Set the variable for the scale widget.

set fontSIZE 14


## Set the variable for the checkbutton widget.
##
## We start with images ON. (See the '-image' option
## in the widget definition statements above.)

set VARimgs0or1 1


## Set an initial theme (color and images) by setting
## the variable of the radiobuttons, $VARtheme, and
## calling the 'change_theme' proc.

set VARtheme "blue"
change_theme


Cropping Button Images (button vs. its cousins --- label, radiobutton, checkbutton)

To provide the image background for the label widgets and 3 types of button widgets, I use long buttons (more than 400 pixels wide and about 24 to 28 pixels high) --- and crop the 'base' images to a length suitable to hold the text on the widgets.

We use the '-image' and '-compound' options to put text-on-image on these 4 types of widgets. Unfortunately, only the '-compound center' option is available to put an image under the text. This option does not allow us to position the text on the image in any other location than the center. This proves to create some problems, which will be described in a follow-up to this page.

I found a rather surprising difference in the 'cropping' capability of the 'button' widget in comparison to its cousins --- the 'label', 'radiobutton', and 'checkbutton' widgets.

I could provide the long 400-plus-pixel image filename in the '-image' option of 'button' and simply crop the image by using the '-width' parameter of button.

However, for the label-radiobutton-checkbutton widgets, the '-width' parameter would not perform the 'crop'. I had to use 'image create' to create new 'image structures', for each widget, to which I could apply a '-width' parameter --- to get an image to use in the '-image' option of the label-radiobutton-checkbutton widgets.

I suppose that the Tk developers did not notice this difference because they have probably used the '-compound center' (text-ON-image) option in a very small number of 'use-cases'.

Anyway, I am pleased to report that I was able to find a work-around.

__________________

Enhancements to improve the look

There are two things that stand out to me as areas where the GUI 'look' could be improved:

  • there seems to be no way to put an image-background behind the 'scale' widget (a TIP item for Tk 9.0?)
  • for the 'indicator-circle' on radiobuttons and the 'indicator-square' on checkbuttons ---- it would be nice if we could get the image under the text to extend under the 'indicators'

___

In regard to the lack of an image behind the 'scale' widget:

There is a possible work-around. One could make a scale-like widget from a frame widget containing a label widget and 2 button widgets (like Suchenwirth's 'spinner' widget that he published on the spinbox page, or like my 'miniscale' widget that I published on the A color-gradient-button-maker GUI with 6 'miniscale' widgets page). Then one could use the -image' option of the 'label' and 'button' widgets.

It's not ideal --- but at least, for those who find the 'scale-without-an-image-background' ugly, there is an opportunity to reduce the ugliness.

___

In regard to the lack of an image behind the 'indicators' on the radiobutton and checkbutton widgets:

At one point early in the development and testing of this script, I had a combination of parameters that made the 'radiobutton-circles' and the 'checkbutton-square' appear ON the image, rather than beside the image.

In that pure accident, there was no text showing --- so I do not know if I can get both the 'indicator circle/square' on the image and the text on the image, at the same time.

But in 'spare moments', I will see if I can get the 'circles'/'squares' on the images --- along with the text.

Since I accidentally had an image behind the 'indicators' in one version of the code (now lost-through-editing), I will try to resolve that issue. If I can discover a resolution, I will put a link here to a page that shows the code and discusses what 'trickery' was involved in getting both 'indicator' and text on an image background.

___

P.S. - On the image files used for the demo:

If anyone would like, I could post the 8 images (GIF files) that I used to make the blue, orange, green, and gray test themes. They're not the prettiest (I am no artist, and I am visually color-challenged) --- and I just quickly picked from some images that I had 'lying around'. But it might be more convenient for people wanting to try out this demo --- if they had the images rather than having to make their own.

I would have posted the images but I do a lot of image posting here, and I do not want to use up 'my quota' ... :-). Besides it takes about half an hour to upload the 8 images --- especially when the 'Captcha' images (in the gauntlet we have to run) are hard to decipher.