FE 'tkGooies' System

'IMAGE animations'
group

A Tcl-Tk GUI
'Visualizer'
using radial-lines ---
an Animation 'app'

(to be 'driven' by
varying input, such as
CPU usage,
network usage,
audio, or a random
number generator)

(FE = Freedom Environment)

FE 'tkGooie' interface for a
'VISUALIZER' app
---
based on 'dancing'
radial lines
---
to be driven by
variable input
such as
CPU-usage or audio

FE Home Page > FE Downloads Page >

FE 'tkGooies' Description Page >

FE 'tkGooies' 'IMAGEanimations' Page >

This
'tkVisualizer (using Radial Lines)'
tkGooie Page

INTRODUCTION to
Tcl-Tk Code for a GUI named
'tkVisualizer_RadialLines'
---
an Animation 'app'

For at least a year now (circa 2015), I have been planning to make a Tk GUI that performs an image animation like various audio (music) visualizers --- either 'stand alone' or embeddable --- or like the visualizers that one sees embedded in some media (audio or video) players.

I was motivated to do this by seeing images generated by the Gnome 'Totem' movie/audio player (renamed to 'Gnome Videos', circa 2015) --- on my Linux desktop and 'netbook' ('laptop') computers.

My goal is to (some future day) make this 'radial-lines' Tk visualizer be 'driven' by sampling audio input(s) on a computer --- or by sampling other varying data such as CPU usage or network usage --- or, initially, by generating varying data by using a random number generator (the Tcl 'rand' function).

Eventually, I hope to make other, higher-quality Tk visualizers --- using different image generation algorithms.

    A first release, in April 2016, of this radial-lines visualizer uses a random number generator.

    However, someday I plan to return to this code and enhance it to allow for sampling CPU usage and/or network-interface (ethernet) usage and/or audio input or output data.

---

Some features (widgets) that I wanted to have on the GUI:

  • animation 'Start' and 'Stop' radiobuttons

  • a color-button, by which to set the canvas background color

  • an entry field (and 'Browse...' button) by which to fetch (optionally) an image file to use as a background

  • a speed control 'scale' widget, by which to specify a wait-time (in milliseconds) between drawing each line segment

  • four radiobuttons by which to select the 'driver' --- CPU usage, or network usage or audio or a random number generator

  • a 'scale' widget by which to precisely set the width and height of a square image area in the middle of a scrollable canvas

  • a 'Clear' button and a 'Help' button and an 'Exit' button


Basic Goals of the 'Radial Lines' Image Generation Algorithm:

My purpose for this Tk GUI script is/was to generate an animation composed of radial lines (vari-colored lines of various lengths and widths) drawn on a Tk 'canvas' widget.

The radial lines are to be drawn emanating from a point in the center of a rectangular Tk 'canvas' widget.

The radial lines are to be drawn one at a time --- but very quickly.

Initially, the Tcl 'rand' command is to be employed to generate some randomness in various aspects of each of the radial line segments, such as

  • line-segment direction
    (an angle between 0 and two-pi radians)

  • two line-segment end-points
    (and hence a random line-segment length)

  • line-segment width

  • line-segment color.

Eventually, when I provide for sampling CPU or network or audio data, some of these 'aspects' may be driven by the sampled data --- in particular, the line-segment end-points (and lengths) may be driven by the magnitude of the sampled data --- while the line directions, widths, and colors may still be driven by calls to the 'rand' function.


Assembling the pieces   (The GUI)

Now it was a matter of putting the pieces together.

I took 'code-pieces' from some of my other Tk scripts that 'draw' in an image area on a Tk canvas.

I ended up with the following GUI as an initial display.

Note that I have provided a color button on the GUI so that the user can control the background color of the image area.

There are 'Start' and 'Stop' radiobuttons --- initialized to 'Stop'.

I also provided a couple of 'scale' widgets by which to control:

  • the speed at which the line-segments are drawn (actually, the 'wait time' between drawing each line segment)

  • the width and height of the image square (in pixels)

In addition, the user is provided a Tk 'entry' widget (and a 'Browse...' button) by which to, optionally, choose an image background for the animation.

There are four 'driver' radiobuttons --- but only the 'Random' radiobutton was implemented initially.

I intend to implement the 'CPU', 'Network', and 'Audio' radiobuttons at a future time.

---

If you take the hint in the message line of the initial GUI and simply click on the 'Start' radiobutton, the default settings are used and animation images like the following 'stopped-image' are generated.

For this animation, the 'wait time' was 10 milliseconds. The line drawing proceeds very quickly.

But, if you want 'full speed ahead', you can set the 'wait time' to zero.

---

Here is an image that shows the use of an image file to put a background image on the canvas.

Changing Animation Parameters
(on the fly)

It turned out, happily, that many of the animation controls on this GUI will work even DURING the animation.

For example, you can change the canvas background color during the course of an animation.

The animation pauses as a separate color-selector GUI appears.

After selecting a color, the animation continues.

Other 'on the fly' changes you can make:

  • You can click on the 'Clear' button at any time during the animation.

    The canvas will clear and line-segments will continue being drawn in the image area.

  • You can change the 'wait time' --- to speed up or slow down the animation --- while the animation is running.

---

Scrollable Canvas
(and big image area)

Note that the canvas in the GUI has vertical and horizontal scrollbars --- and you can set a large image area size with the image-size scale widget --- even bigger than the monitor screen.

If you think the max-pixels of the image-size scale widget is not big enough for you (say you have a '4K' monitor and you want to fill that screen to the max), you can edit the Tk script and change the '-to' parameter on the 'scale' widget for the image size.

---

Implementing the Color Button

The color button calls on an 'external' color-selector-GUI script to set the canvas background color.

You can make that color-selector script by cutting-and-pasting the code from the page that offers a non-obfuscated color selector GUI on this site.

You can see the code at the bottom of the Tk script to see how the name and location of the color selector script is set.


DESCRIPTION OF THE CODE

Below, I provide the Tk script code for this 'tkVisualizer_RadialLines' 'app'.

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).

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

  2) Define & pack all widgets in the frames, frame by frame.
              Within each frame, define ALL the widgets.
              Then pack the widgets.

  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 Tk coding structure is discussed in more detail on the page A Canonical Structure for Tk Code --- and variations.

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


Experimenting with the GUI

As in all my scripts that use the 'pack' geometry manager (which is all of my 100-plus Tk scripts, so far), I provide the four main 'pack' parameters --- '-side', '-anchor', '-fill', and '-expand' --- on all the 'pack' commands for the frames and widgets.

I think I have found a 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' widget will expand/contract appropriately when an image size 'scale' widget value is changed --- and button and label and scale widgets stay fixed in size and relative-location as the window size is changed.

If anyone wants to change the way the GUI configures itself as the main window size is changed, they can experiment with the '-side', '-anchor', '-fill', and '-expand' parameters on the 'pack' commands for the various widgets --- to get the widget behavior that they want.

---

Additional GUI experimentation:

You could 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.

Furthermore, there are variables used to set geometry parameters of widgets --- parameters such as border-widths and padding.

And you could change the '-relief' values for frames and widgets. Feel free to experiment with those 'appearance' parameters as well.


Some features of the code

There are plenty of comments in the code to describe what most of the code-sections are doing.

The most complex code is in the 'animate' proc.

See the comments in that proc to see how it is implemented.

See the top of the 'PROCS' section for a list of the procs used in this Tk script.

See comments in the procs for details on the purpose of each proc and for details on the methods by which each proc was implemented.

Here is a quick overview of the procs --- to give an idea of the 'guts' of this utility:



  - 'get_img_filename'      - fetches the filename of an image (GIF/PNG) file.
                              Called by the 'Browse...' button.

  - 'add_image'             - puts an image from the image-filename in the
                              filename-entry-field onto the canvas.
                              Called by bindings on the filename entry widget.

  - 'animate'               - to draw 'radial colored lines' on the canvas.
                              Called by a button1-release binding on the
                              'Start' radiobutton.

  - 'set_background_color'  - sets the background (canvas) color.
                              Called by the 'BkgdColor' button.

  - 'set_background_button_color'  - updates the background & foreground colors
                                     on the canvas-background color button.
                                     Called by the 'set_background_color' proc
                                     and in the 'Additional GUI Initialization'
                                     section at the bottom of the script.

  - 'clear'                 - removes all objects from the canvas (lines and img).
                              Called by the 'Clear' button.

  - 'advise_user'           - called by some procs, and called in the
                              'Additional GUI Initialization' section at
                              the bottom of the script.

  - 'popup_msg_var_scroll'  - to show help in the HELPtext variable.
                              Called by the 'Help' button.
                              This proc can show other msgs as needed.


One thing that I discovered in testing a previously-created GUI is a 'trick' to make the GUI (in particular the 'canvas' area) resize nicely after a change to the image-size via the image-size scale widget.

It turned out that the resizing would not occur after the tester (me) would resize the window by tugging on an edge or corner of the window.

But the resizing would occur nicely before that 'manual intervention' with the window manager.

It turned out that a Tk 'wm' (window manager) command --- namely

wm geometry . {}

can be used to restore the nice auto-resizing of the canvas area around the image area.

By some searches on wiki.tcl.tk (with terms like 'wm resize'), I found this 'trick' used on the page http://wiki.tcl.tk/10720 (weeEdit) --- in the '-command' of a 'Resize window' button.

In this code, the 'wm geometry . {}' statment was being used to resize a 'text' widget, not a 'canvas' widget.

A search on the string

wm geometry . {}

at wiki.tcl.tk revealed that this 'wm statement' was mentioned in a section titled 'word Wrap Via Tk Text Widget' --- on the page http://wiki.tcl.tk/44 (Additional string functions) --- with the comment 'Make sure the toplevel shrinks or expands to fit'.

Thanks to 'D.McC' (David McClamrock) for publicizing this seldom-mentioned technique.

I have never seen this 'toplevel shrink/expand' technique --- using 'wm geometry . {}' --- mentioned in the Tcl-Tk books that I have used the most --- the Eric Foster-Johnson books and the Brent Welch books.

But I did find mention of this capability in the original 1994 edition of the John Ousterhout Tcl-Tk book --- on page 237 --- where it says:

    "If you would like to restore a window to its natural size, you can invoke 'wm geometry' with an empty geometry string:

    wm geometry . {}

    "This causes Tk to forget any size specified by the user or by 'wm geometry' so the window returns to its natural size."

Apparently 'wm geometry . {}' can be used to cause Tk to signal the window manager and/or the 'wish' interpreter to resize the toplevel window according to the widget sizes within the window --- for example, after a user has clicked on a 'button' that causes the Tk-GUI to be re-configured.


Comments in the Code

It is my hope that the copious comments in the code might help Tcl-Tk coding 'newbies' get started in making GUI's like this. Without the comments --- especially in the 'animate' proc --- the code might look even more cryptic than it already is.

Without the comments, potential young Tcler's might be tempted to return to their iPhones and iPads and iPods --- to look for videos of the latest high-profile gun death(s) --- or various low-profile gun deaths not being covered by the national news outlets --- because people were merely maimed (not killed) --- or because not enough people (or not enough 'people of value') were killed.

    (Homicides rule --- in the news. Hideous maiming and a lifetime of pain do not make the national --- or even local --- news.

    Quantity of homicides also rules. And location matters.

    Shootings in 'bad neighborhoods' may make the local newspapers, but most do not make it to national TV and video.)


The Tk Script CODE

Here is a link to CODE for the Tk script
'tkVisualizer_RadialLines.tk'.

With your web browser, you can 'right-click' on this link --- and in the menu that pops up, select an item like 'Save Link Target As ...' --- to save this file to your local computer.

Then you can rename the file to remove the '.txt' suffix. Make sure that you have execute permission set on the file --- in order to execute the script.

---

Here is the 500x500 pixel background GIF image that I used for testing.

If you need an image for an initial test of the background image feature of this 'app', you can right-click on this image and save the file to your computer --- say, in the same directory in which you put the Tk script.

Some possible FUTURE ENHANCEMENTS

There are quite a few enhancements that could be considered for this script, such as:

  • 1) Implement the 'CPU', 'Network', and 'Audio' radiobuttons :

    You can see in the 'animate' proc where the code sets a 'DRIVERnum' variable depending on these radiobutton settings. (I might change the variable name to 'DRIVERtype'.)

    • If 'CPU' is selected, a 'get_from_cpu.sh' shell script is called.

    • If 'Network' is selected, a 'get_from_network.sh' shell script is called.

    • If 'Audio' is selected, a 'get_from_audio.sh' shell script is called.

    Those 3 shell scripts are not available yet. When/if I implement those options, I intend to post the scripts on this page, under the Tk code above.

    The shell script for the 'Network' option can be similar to the shell script used in the 'SYSTEMtools' 'tkGooies':

    The shell script for the 'CPU' option can be similar to the shell script used in the 'SYSTEMtools' 'tkGooies':

  • 2) A show/hide options checkbutton :

    To hide a lot of the options widgets, I may add a show/hide checkbutton at the top of the GUI, so that at least two of the lines of option widgets in the GUI can be hidden.

    Alternatively, one could add a 'fullscreen' option --- to show only the image area, until, say, the 'Esc' (escape) button is clicked.

  • 3) Different Positioning of the Radial Lines :

    You can see in the images above that the radial lines seem to be 'exploding' from the center-point of the image area.

    Instead of allowing the end-point pairs to be anywhere along a direction angle, we could establish a circle within the square image area and always set the pair of end-points to be the same distance on either side of that fixed circle.

    The effect would be an 'exploding donut', rather than an explosion emanating from a center point.

    A wide variety of other variations on the 'radial line' theme could be devised.

  • 4) Add line-count and time-elapsed display :

    I am rather curious about how fast the lines can be drawn --- especially when the 'wait-time' is set to zero.

    To support getting a constantly updated lines-per-second value displayed on the GUI :

    In this GUI, after each line segment is drawn, a message line could be updated with

    • the elapsed time of the animation
      (in milliseconds or seconds)

    • the number of the segment just drawn

    • the cumulative lines-per-second
      calculated from these 2 values

  • 5) Write-Ani-GIF :

    It may be good to offer an option to write an animated-GIF file (or movie file) from a sequence of images generated from this animation.

    It would certainly be more convenient than having to do a bunch of image captures and manually contruct an animated-GIF (or movie) file from a sequence of still-image captures.

    I have implemented a Write-Ani-GIF option in several 'tkGooies' in the 'IMAGEtools' group, such as:

    I can use code from one or more of those Tk scripts to make it relatively easy to implement a Write-Ani-GIF option --- although I might have to do some sort of Postscript to GIF conversion.

      (But a background image would not be shown in the Postscript files.)

    An alternative would be to use 'create image' rather than 'create line'.

    That is, create a Tk 'photo' image structure on the canvas and draw the lines in that image structure with 'put pixel' commands --- rather than use 'create line'.

    That way, the Write-Ani-GIF option could be implemented without using intermediary Postscript files --- and a background image would be captured along with the radial lines.

---

The bottom line here is that there are almost always non-trivial enhancements that could be made to a Tk GUI 'app' like this.

One advantage of this Tk script is that it is 'open' code --- available to anyone for enhancement.

So if you would like to apply your own 'visualization-flavor' to this script, you are welcome to take this code and enhance it.


IN CONCLUSION

As I have said on several other code-donation pages on this freedomenv.com site and on the Tclers' wiki at wiki.tcl.tk ...

There's a lot to like about a utility that is 'free freedom' --- that is, no-cost and open-source so that you can modify/enhance/fix it without having to wait for someone else to do it for you (which may be never).

A BIG THANK YOU to Ousterhout for starting Tcl-Tk, and a BIG THANK YOU to the Tcl-Tk developers and maintainers who have kept the simply MAH-velous 'wish' interpreter going.

Bottom of this page presenting
Tcl-Tk Code of a GUI for
'tkVisualizer_RadialLines' - an Animation
---
a utility or 'app' in the FE 'tkGooies' system,
in the 'IMAGEanimations' group.

To return to a previously visited web page location, click on the Back button of your web browser a sufficient number of times. OR, use the History-list option of your web browser.
OR ...

< Go to Top of Page, above. >

Page history:

This FE web page was created 2016 Apr 18.

Page was changed 2019 Mar 01.
(Added css and javascript to try to handle text-size for smartphones, esp. in portrait orientation.)

Page was changed 2019 Jun 15.
(Specified image widths in percents to size the images according to width of the browser window.)


NOTE:
This code may someday be posted in a page on the Tcler's Wiki --- wiki.tcl-lang.org --- formerly wiki.tcl.tk. If I do that, I may put a link to the page here.