Apr 09

In this article I explore the gtkdialog Window object, its attributes and actions. In passing. other gtkdialog objects will be used without much elaboration, that elaboration intended to follow in subsequent articles.

This is the next article in a series of articles on gtkdialog, “gtkdialog Exploration – articles and examples”, which can be found at https://blogs.czapski.id.au/2017/04/gtkdialog-exploration.

It appears that gtkdialog, based as it seems to be on the GTK object model, leverages the GTK object hierarchy. Consider the reference for the Window object at http://01micko.com/reference/window.html.

The very first link points to a GtkWindow – http://developer.gnome.org/gtk2/2.24/GtkWindow.html.

In the GTK object hierarchy, https://developer.gnome.org/gtk2/2.24/GtkWindow.html#GtkWindow.object-hierarchy, the Window object is several levels below the GObject, the topmost object.

As briefly discussed in the previous article the GtkWindow, and consequently the gtkdialog Window, object inherit, as I understand it, from the objects higher up in the hierarchy. This will come into play when we explore attributes that can be set for a Window, and actions that can be configured for a Window.

Pre-Requisites

This article assumes that the Virtual Box Machine Image created in accordance with the instructions in the blog article to be found at https://blogs.czapski.id.au/2016/10/configure-virtual-box-virtual-machine-and-install-centos-6-8-base-image is available but it is expected that pretty much any Linux environment will do just as well so long as it supports yad and gtkdialog. For convenience I posted the export of the VirtualBox image which would have been built if the reader followed all the articles in the series “Build a Linux-based Infrastructure Solution Demonstration Series” to date, that is to the 8th of March 2017. The link to the main article is https://blogs.czapski.id.au/2017/04/virtualbox-image-with-content-as-built-so-far.

It also assumes that yad and gtkdialog are installed, as discussed in the article “Install yad and gtkdialog” (https://blogs.czapski.id.au/2017/04/gtkdialog-for-rapid-prototyping-of-linux-applications-install-gtkialog-and-yad)

Window Object Attributes

The gtkdialog Window object is the outermost visible object in the hierarchy of gtkdialog objects.

We explored the window object to an extent in the previous article, while setting the context and discussing comments and similar matters. Let’s now explore the Window object attributes more.

Reference documentation for the gtkdialog Window object, http://01micko.com/reference/window.html, provides a table of attributes specific to this gtkdialog object and makes a reference to ancestor class properties.

Attributes that can be configured for the window widget are defined in the widget’s reference page see https://developer.gnome.org/gtk2/2.24/GtkWindow.html#GtkWindow.object-hierarchy, section Properties – https://developer.gnome.org/gtk2/2.24/GtkWindow.html#GtkWindow.properties

Some of them are useful and some of them are not, as far as I am concerned or can empirically determine. Changing values of some of them do not have visible consequences.

Not all attributes/properties are recognised and acted upon by  gtkdialog. Some of the properties are inherited from the parent objects, like GtkContainer and GtkWidget. For example, border-width, which defines the amount of space between the window frame and the window content, is inherited from the GtkContainer.

Similarly, sensitive property is inherited from the GtkWidget and when set to true effectively disables everything inside the window, except for the window decorations like minimise, maximise and close. An “interesting” side effect of this is that setting sensitive to false and decorated to false will take away the means of closing the window except by killing the process which created the window 🙂

Properties like window-position take one of the pre-defined enumeration values.

For window-position see https://developer.gnome.org/gtk2/2.24/gtk2-Standard-Enumerations.html#GtkWindowPosition or http://gtk.php.net/manual/en/html/gtk/gtk.enum.windowposition.html (which is not directly related to gtkdialog as I use it but seems a good enough source of enumerations which GTK defines and supports.

By the way, tooltip-markup causes warnings to be emitted to the console, which, apart from being ugly, appear benign.

See the reference page: file:///home/demo/gtkdialog-0.8.3/doc/reference/window.html

To work out what attributes are actually supported, in this case by the window widget, we need to do some exploration. Discussion below goes into this to an extent and I provided most of the useful attributes that can be set, both from GtkWindow itself and inherited from GtkContainer and GtkWidget.

Let me reproduce the table and expand it to include inherited attributes which empirical observation leads me to believe have a visual impact on the window object.

The table below summarised Window attributes/properties and indicates which work with the gtkdialog and which do not as far as I can tell. “Do not” may well be a function of me not seeing any visible difference with the property set to different values. Some ancestor attributes/properties which are not really useable from gtkdialog are omitted.

Name Description Value Default From Since OK?
image-name Image filename

I could not figure out what this does for a Window object.

gtkdialog 0.8.1
block-function-signals Block signal emissions from functions

I am not quite sure what this does for a Window object. See reference for where this comes from. Perhaps you will get it. http://www.murga-linux.com/puppy/viewtopic.php?p=544704#544704

true or false false gtkdialog 0.7.21
file-monitor Emit signal when input file(s) change

If a file is specified as the value of the window’s <input file>xxxx</input> directive, and this property is set to true, and the content of the file changes then the signal of type “file-changed” will be emitted. If an <action signal=”file-changed”>xxx</action> or its variant is defined then the action will be executed.

true or false false gtkdialog 0.8.1 Y
auto-refresh Auto refresh when input file(s) change.

If a file is specified as the value of the window’s <input file>xxxx</input> directive, and this property is set to true, and the content of the file changes then the window’s title bar text will automatically display the content of the file (or some reasonable leading part of it). If this property is false then the input file change will not be reflected in the title bar.

true or false false gtkdialog 0.8.1 Y
 
accept-focus Whether the window should receive the input focus. The title bar is greyed out on false but objects inside the window are still active, for example, buttons are clickable on and do their thing, but keystrokes are not delivered to the window. true or false true GtkWindow Y
allow-grow If TRUE, users can expand the window beyond its minimum size. true or false true GtkWindow Y
allow-shrink If TRUE, the window has no minimum size. Setting this to TRUE seems pretty useless and perhaps unfriendly. true or false true GtkWindow Y
decorated Whether the window should be decorated by the window manager, that is whether it should have the title bar and the various buttons typically present there. true or false true GtkWindow Y
default-height The default height of the window, used when initially showing the window. Must be >= -1.

The value of this attribute overrides the height-request value if one is specified.

integer -1 GtkWindow Y
default-width The default width of the window, used when initially showing the window. Must be >= -1.

The value of this attribute overrides the width-request value if one is specified.

integer -1 GtkWindow Y
deletable Whether the window frame should have a close button. true or false true GtkWindow Y
icon-name The icon-name property specifies the name of the themed icon to use as the window icon. File path GtkWindow Y
mnemonics-visible Whether mnemonics are currently visible in this window. If buttons are defined and have “use-underline” attribute set to true and a mnemonic indicated with the “_” before the character in the label, or are “standard” buttons like OK or cancel, the indicated or default letter in the label will be underlined when the window is drawn if this property is set to true. true or false false GtkWindow Y
resizable If TRUE, users can resize the window. true or false true GtkWindow Y
skip-pager-hint TRUE if the window should not be shown in the pager. true or false false GtkWindow ?
skip-taskbar-hint TRUE if the window should not be shown in the task bar true or false false GtkWindow Y
title The title of the window. Overwritten by the <label>…</label> directive if one is specified string GtkWindow Y
type-hint These are hints for the window manager that indicate what type of function the window has. The window manager can use this when determining decoration and behaviour of the window. See enumerations – link below. Does not seem useful in the gtkdialog context. integer 0 GtkWindow Y
window-position The initial position of the window

GTK_WIN_POS_NONE=0

GTK_WIN_POS_CENTER=1

GTK_WIN_POS_MOUSE=2

Integer [0..2] 0 GtkWindow Y
 
border-width The amount of whitespace between the window frame and the content of the window Integer 5 GtkContainer Y
 
can-default Whether the widget can be the default widget.

This does not seem to have any effect when applied to a Window object

true or false false GtkWidget ?
can-focus Whether the widget can accept the input focus.

This does not seem to have any effect when applied to a Window object

true or false false GtkWidget ?
has-default Whether the widget is the default widget.

This does not seem to have any effect when applied to a Window object

true or false false GtkWidget ?
has-focus Whether the widget has the input focus.

This does not seem to have any effect when applied to a Window object

true or false false GtkWidget ?
has-tooltip Whether this widget has a tooltip.
Disables tooltip display if tooltip is defined for the Window
true or false false GtkWidget Y
height-request Override for height request of the widget, or -1 if natural height should be used.

Has not effect of default-height is specified.

>=0 -1 GtkWidget Y
is-focus Whether the widget is the focus widget within the toplevel.

Does not seem to have any effect when applied to the Window object

true or false false GtkWidget ?
name The name of the widget.

Nothing visible happens when this attribute is provided with a value.

string NULL GtkWidget ?
receives-default If TRUE, the widget will receive the default action when it is focused.

I don’t know what that is supposed to accomplish. Nothing visible happens regardless of the property value.

true or false false GtkWidget ?
sensitive Whether the widget responds to input.

FALSE disables all components contained in the window.

true or false TRUE GtkWidget Y
style GtkStyle GtkWidget ???
tooltip-markup The contents of the tooltip for this widget.

Simple markup can be used to call out parts of tooltip text in.

See http://www.murga-linux.com/puppy/viewtopic.php?t=40418 for a markup explorer tool.

Ineffective if tooltip-disabled is TRUE.

string NULL GtkWidget Y
tooltip-text The contents of the tooltip for this widget.

Ineffective if tooltip-disabled is TRUE.

string NULL GtkWidget Y
visible Whether the widget is visible.

It is somewhat self-defeating to make a window invisible on creation unless it is a “subsidiary” window and can be made visible form some other piece of logic.

true or false true GtkWidget Y
width-request Override for width request of the widget, or -1 if natural width should be used.

Has not effect if default-width is specified.

>=0 -1 GtkWidget Y

The following example includes just about every attribute that can be defined for a Window object. Experiment with the various settings to see what you can see.

scriptName=ex09
touch /tmp/${scriptName}.sh
chmod ug+x /tmp/${scriptName}.sh

cat <<-'EOSCRIPT' > /tmp/${scriptName}.sh
#!/bin/bash

GTKDIALOG=gtkdialog

fnEchoDateTime() {
echo "$(date)"
}
export -f fnEchoDateTime

GTK_WIN_POS_NONE=0
GTK_WIN_POS_CENTER=1
GTK_WIN_POS_MOUSE=2


MAIN_DIALOG_FILE=${0}.gtkd
cat <<-EOUIDFEINITION > ${MAIN_DIALOG_FILE}
<window 
    decorated="true" this="shows the title bar and its nprmal decorations"
    allow-grow="true" this="can resize to be bigger"
    allow-shrink="true" this="can resize to be smaller - including making it practically invisible"
    xx-default-height="200" remove="xx- to enable the attribute and see how that affects height-request"
    xx-default-width="400" remove="xx- to enable the attribute and see how that affects width-request"
    resizable="true" xx-resizable="overrides default-height and default-width if set to false"  this="works"
    deletable="true" xx-deletable="this keep (default) or remove the close button" this="works"
    icon-name="gtk-apply" this="works - shows designated icon at the left of the title bar"
    modal="false" this="does not seem to be doing anything different on true and on false"
    skip-pager-hint="true" this="does not seem to be doing anything different on tru and on false"
    skip-taskbar-hint="false" this="seems to be preventing the window being listed in the window selector when true"
    title="My First Window" this="is selfexplanatory and works"
    window-position="${GTK_WIN_POS_CENTER}"
    border-width="5" xx-border-width="is an inherited GtkContainer property - see object hierarchy at https://developer.gnome.org/gtk2/2.24/GtkWindow.html#GtkWindow.object-hierarchy"
    sensitive="true" xx-sensitive="is an inherited GtkWidget property that disables everything inside the window - see obect hierarchy"
    tooltip-markup="<span size='small'>This is a <b>window tooltip</b></span>"
    icon="gimp" this="does not do anything visible"
    mnemonics-visible="false" this="if buttons have underline for menemonics or are standard buttons mnemonics are initially underlined"
    accept-focus="true" this="if false makes window not focusaable (title bar is gray) - buttons are still clickable"
    window-position="${GTK_WIN_POS_CENTER}"
    auto-refresh="false" goes="with <input file>somefile</input>"
    border-width="5"
    can-default="false"
    can-focus="false"
    can-default="false"
    has-focus="false"
    has-tooltip="true"
    height-request="150" does="not have any effect if default-height is specified"
    width-request="400" does="not have any effect if default-width is specified"
    is-focus="true"
    name="myWindow"
    receives-focus="false"
    sensitive="true"
    xx-tooltip-text="This is a <b>window tooltip</b>"
    visible="true"
>
    <vbox>
        <frame   Description  >
            <text label="This is an example window."></text>
        </frame>
        <hbox>
            <button use-underline="true" tooltip-text="Refresh window variable - update date in window title">
                <label> _Refresh </label>
                <input file icon="gtk-refresh"></input>
                <width>16</width>
                <action function="refresh">vWindow</action>
            </button>
            <button ok></button>
            <button cancel></button>
        </hbox>
    </vbox>

    <label>Window Label</label>
    <variable>vWindow</variable>
    <input>fnEchoDateTime</input>
$(:<<'COMMENT'
    <input file>/tmp/aa.txt</input>
COMMENT
)
    
    <action this-is-window="escape" signal="key-press-event" condition="command_is_true( [[ \$KEY_RAW = 0x9 ]] && echo true )">EXIT:exit</action> 

</window>
EOUIDFEINITION

case ${1} in
    -d | --dump) cat ${MAIN_DIALOG_FILE} ;;
    *) gtkdialog --center --file=${MAIN_DIALOG_FILE} ;;
esac

rm -f ${MAIN_DIALOG_FILE}
EOSCRIPT

/tmp/${scriptName}.sh

See https://github.com/GNOME/gtk/blob/master/gdk/gdktypes.h for enumerations.

Window Object Directives

Note that the window defines a bunch of window specific child objects, which the reference calls directives – label, variable, input, etc..  These must be specified after all the other window child objects else gtkdialog will throw a hissy fit.

The label directive provides window title if title attribute is not set. If it is set the label directive is ignored. Consider:

scriptName=ex10
touch /tmp/${scriptName}.sh
chmod ug+x /tmp/${scriptName}.sh

cat <<-'EOSCRIPT' > /tmp/${scriptName}.sh
#!/bin/bash

GTKDIALOG=gtkdialog

fnEchoDateTime() {
echo "$(date)"
}
export -f fnEchoDateTime

GTK_WIN_POS_NONE=0
GTK_WIN_POS_CENTER=1
GTK_WIN_POS_MOUSE=2

MAIN_DIALOG_FILE=${0}.gtkd
cat <<-EOUIDFEINITION > ${MAIN_DIALOG_FILE}
<window 
    title="My First Window"
    window-position="${GTK_WIN_POS_CENTER}"
    default-width="400"
>
    <vbox>
        <frame   Description  >
            <text label="This is an example window."></text>
        </frame>
        <hbox>
            <button use-underline="true" tooltip-text="Refresh window variable - update date in window title">
                <label> _Refresh </label>
                <input file icon="gtk-refresh"></input>
                <width>16</width>
                <action function="refresh">vWindow</action>
            </button>
            <button ok></button>
            <button cancel></button>
        </hbox>
    </vbox>

    <label>Window Label</label>
    <variable>vWindow</variable>
$(:<<'COMMENT'
    <input>fnEchoDateTime</input>
    <input file>/tmp/aa.txt</input>
COMMENT
)
    <action this-is-window="escape" signal="key-press-event" condition="command_is_true( [[ \$KEY_RAW = 0x9 ]] && echo true )">EXIT:exit</action> 

</window>
EOUIDFEINITION

case ${1} in
    -d | --dump) cat ${MAIN_DIALOG_FILE} ;;
    *) gtkdialog --center --file=${MAIN_DIALOG_FILE} ;;
esac

rm -f ${MAIN_DIALOG_FILE}
EOSCRIPT

/tmp/${scriptName}.sh

Consider a variant where the title attribute to the Window object is not provided.

scriptName=ex11
touch /tmp/${scriptName}.sh
chmod ug+x /tmp/${scriptName}.sh

cat <<-'EOSCRIPT' > /tmp/${scriptName}.sh
#!/bin/bash

GTKDIALOG=gtkdialog

fnEchoDateTime() {
echo "$(date)"
}
export -f fnEchoDateTime

GTK_WIN_POS_NONE=0
GTK_WIN_POS_CENTER=1
GTK_WIN_POS_MOUSE=2

MAIN_DIALOG_FILE=${0}.gtkd
cat <<-EOUIDFEINITION > ${MAIN_DIALOG_FILE}
<window 
    window-position="${GTK_WIN_POS_CENTER}"
    default-width="400"
>
    <vbox>
        <frame   Description  >
            <text label="This is an example window."></text>
        </frame>
        <hbox>
            <button use-underline="true" tooltip-text="Refresh window variable - update date in window title">
                <label> _Refresh </label>
                <input file icon="gtk-refresh"></input>
                <width>16</width>
                <action function="refresh">vWindow</action>
            </button>
            <button ok></button>
            <button cancel></button>
        </hbox>
    </vbox>

    <label>Window Label</label>
    <variable>vWindow</variable>
$(:<<'COMMENT'
    <input>fnEchoDateTime</input>
    <input file>/tmp/aa.txt</input>
COMMENT
)
    <action this-is-window="escape" signal="key-press-event" condition="command_is_true( [[ \$KEY_RAW = 0x9 ]] && echo true )">EXIT:exit</action> 

</window>
EOUIDFEINITION

case ${1} in
    -d | --dump) cat ${MAIN_DIALOG_FILE} ;;
    *) gtkdialog --center --file=${MAIN_DIALOG_FILE} ;;
esac

rm -f ${MAIN_DIALOG_FILE}
EOSCRIPT

/tmp/${scriptName}.sh

The sensitive directive does the same thing as the sensitive attribute to the window tag – enables or disables window content. Consider:

scriptName=ex12
touch /tmp/${scriptName}.sh
chmod ug+x /tmp/${scriptName}.sh

cat <<-'EOSCRIPT' > /tmp/${scriptName}.sh
#!/bin/bash

GTKDIALOG=gtkdialog

fnEchoDateTime() {
echo "$(date)"
}
export -f fnEchoDateTime

GTK_WIN_POS_NONE=0
GTK_WIN_POS_CENTER=1
GTK_WIN_POS_MOUSE=2

MAIN_DIALOG_FILE=${0}.gtkd
cat <<-EOUIDFEINITION > ${MAIN_DIALOG_FILE}
<window 
    window-position="${GTK_WIN_POS_CENTER}"
    default-width="400"
>
    <vbox>
        <frame   Description  >
            <text label="This is an example window."></text>
        </frame>
        <hbox>
            <button use-underline="true" tooltip-text="Refresh window variable - update date in window title">
                <label> _Refresh </label>
                <input file icon="gtk-refresh"></input>
                <width>16</width>
                <action function="refresh">vWindow</action>
            </button>
            <button ok></button>
            <button cancel></button>
        </hbox>
    </vbox>

    <label>Window Label</label>
    <sensitive>false</sensitive>
    <variable>vWindow</variable>
$(:<<'COMMENT'
    <input>fnEchoDateTime</input>
    <input file>/tmp/aa.txt</input>
COMMENT
)
    <action this-is-window="escape" signal="key-press-event" condition="command_is_true( [[ \$KEY_RAW = 0x9 ]] && echo true )">EXIT:exit</action> 

</window>
EOUIDFEINITION

case ${1} in
    -d | --dump) cat ${MAIN_DIALOG_FILE} ;;
    *) gtkdialog --center --file=${MAIN_DIALOG_FILE} ;;
esac

rm -f ${MAIN_DIALOG_FILE}
EOSCRIPT

/tmp/${scriptName}.sh

The variable directive names the variable which can be used elsewhere to reference the window and act upon it, for example disable or enable, activate or deactivate, show or hide, refresh or clear, or set title. The example below provides a variable name vWindow to allow the button’s action directive to trigger the refresh action on the window. When the refresh action signal is processed the function fnEchoDateTime will be executed and its output will be provided to the Window object which will use it to set the window title. Consider the following example. Click the Refresh button a few times with at least 1 second between clicks and see what happens to the window title.

scriptName=ex13
touch /tmp/${scriptName}.sh
chmod ug+x /tmp/${scriptName}.sh

cat <<-'EOSCRIPT' > /tmp/${scriptName}.sh
#!/bin/bash

GTKDIALOG=gtkdialog

fnEchoDateTime() {
echo "$(date)"
}
export -f fnEchoDateTime

GTK_WIN_POS_NONE=0
GTK_WIN_POS_CENTER=1
GTK_WIN_POS_MOUSE=2

MAIN_DIALOG_FILE=${0}.gtkd
cat <<-EOUIDFEINITION > ${MAIN_DIALOG_FILE}
<window 
    title="My First Window"
    window-position="${GTK_WIN_POS_CENTER}"
    default-width="400"
>
    <vbox>
        <frame   Description  >
            <text label="This is an example window."></text>
        </frame>
        <hbox>
            <button use-underline="true" tooltip-text="Refresh window variable - update date in window title">
                <label> _Refresh </label>
                <input file icon="gtk-refresh"></input>
                <width>16</width>
             <action function="refresh">vWindow</action>
            </button>
            <button ok></button>
            <button cancel></button>
        </hbox>
    </vbox>

    <variable>vWindow</variable>
    <input>fnEchoDateTime</input>

    <action this-is-window="escape" signal="key-press-event" condition="command_is_true( [[ \$KEY_RAW = 0x9 ]] && echo true )">EXIT:exit</action> 

</window>
EOUIDFEINITION

case ${1} in
    -d | --dump) cat ${MAIN_DIALOG_FILE} ;;
    *) gtkdialog --center --file=${MAIN_DIALOG_FILE} ;;
esac

rm -f ${MAIN_DIALOG_FILE}
EOSCRIPT

/tmp/${scriptName}.sh

The input directive can invoke logic which can return a string to which the window title will be set when triggered by refresh of the variable named as the window variable. See example above. This function, as all such functions invoked by the gtkdialog, is expected to write to the stdout whatever text is supposed to be the input to the object – in this case the window title.

The output file directive will cause the “value” of this object to be written to the named file if the save action is triggered. In the case of the window object the title will be written to the file. Consider:

scriptName=ex14
touch /tmp/${scriptName}.sh
chmod ug+x /tmp/${scriptName}.sh

cat <<-'EOSCRIPT' > /tmp/${scriptName}.sh
#!/bin/bash

GTKDIALOG=gtkdialog

fnEchoDateTime() {
echo "$(date)"
}
export -f fnEchoDateTime

GTK_WIN_POS_NONE=0
GTK_WIN_POS_CENTER=1
GTK_WIN_POS_MOUSE=2

MAIN_DIALOG_FILE=${0}.gtkd
cat <<-EOUIDFEINITION > ${MAIN_DIALOG_FILE}
<window 
    title="My First Window"
    window-position="${GTK_WIN_POS_CENTER}"
    default-width="400"
>
    <vbox>
        <frame   Description  >
            <text label="This is an example window."></text>
        </frame>
        <hbox>
            <button use-underline="true" tooltip-text="Save window data">
                <label> _Save </label>
                <input file icon="gtk-save"></input>
                <width>16</width>
              <action function="save">vWindow</action>
            </button>
            <button use-underline="true" tooltip-text="Refresh window variable - update date in window title">
                <label> _Refresh </label>
                <input file icon="gtk-refresh"></input>
                <width>16</width>
                <action function="refresh">vWindow</action>
            </button>
            <button ok></button>
            <button cancel></button>
        </hbox>
    </vbox>

    <variable>vWindow</variable>
    <input>fnEchoDateTime</input>

    <output file>/tmp/gtkd.out</output>

    <action signal="key-press-event" condition="command_is_true( [[ \$KEY_RAW = 0x9 ]] && echo true )">EXIT:exit</action> 

</window>
EOUIDFEINITION

case ${1} in
    -d | --dump) cat ${MAIN_DIALOG_FILE} ;;
    *) gtkdialog --center --file=${MAIN_DIALOG_FILE} ;;
esac

rm -f ${MAIN_DIALOG_FILE}
EOSCRIPT

/tmp/${scriptName}.sh

The action directive provides a mechanism for invoking logic when certain kinds of events affecting the window object occur. The example above used the ‘<action function="save">…</action>‘ markup to add an action to a button object, to be invoked when the button is pressed. Another example would be invoking the close window logic when ESC key is pressed. In the example above, the key-press-event signal is intercepted in the action directive and if the raw key code was (0x9), the Escape key, the gtkdialog calls the exit logic and the window is closed.

Exploring the action directive

Let’s consider the following signals, defined in the Window object reference:

Name Description Content Since
action signal=”type” Execute command on signal Shell command
action signal=”type” Perform function on signal function:parameter
action signal=”type” condition=”type” Execute command on signal conditionally Shell command 0.8.3
action signal=”type” condition=”type” Perform function on signal conditionally function:parameter 0.8.3

In ex13, above, we used the “action function” and “action signal”, to save the window title to a file and to exit the application respectively. Note that the reference does not include the “action function” variant but it is supported and works, as the example illustrates.

Explore the reference for the Window object, http://01micko.com/reference/window.html, to see the signals and the functions defined in that document.

The “action condition” construct is perhaps worth exploring as it is explained what the “_is_true”/
_is_false” is supposed to return. To cut to the chase, the command or the function is supposed to return the literal text “true” or “false”. The example below extends the example above by making the save action conditional on the file not already existing. This is contrived but makes the point.

Consider:

scriptName=ex15
touch /tmp/${scriptName}.sh
chmod ug+x /tmp/${scriptName}.sh

cat <<-'EOSCRIPT' > /tmp/${scriptName}.sh
#!/bin/bash

GTKDIALOG=gtkdialog

fnEchoDateTime() {
    echo "$(date)"
}
export -f fnEchoDateTime

fnAlreadySaved() {
    vFileName="${1}"
    [[ -f ${vFileName} ]] && { echo "true" ; yad --title="File ${vFileName} exists" --text="File ${vFileName} exists - not saving" --center --image="gtk-dialog-error" --window-icon="gtk-dialog-error" --width=500 --height=100 --button="gtk-ok:0"; } || echo "false"
}
export -f fnAlreadySaved


GTK_WIN_POS_NONE=0
GTK_WIN_POS_CENTER=1
GTK_WIN_POS_MOUSE=2

MAIN_DIALOG_FILE=${0}.gtkd
cat <<-EOUIDFEINITION > ${MAIN_DIALOG_FILE}
<window 
    title="My First Window"
    window-position="${GTK_WIN_POS_CENTER}"
    default-width="400"
>
    <vbox>
        <frame   Description  >
            <text label="This is an example window."></text>
        </frame>
        <hbox>
            <button use-underline="true" tooltip-text="Save window data">
                <label> _Save </label>
                <input file icon="gtk-save"></input>
                <width>16</width>
                <action function="save" condition="command_is_false(fnAlreadySaved /tmp/gtkd.out)">vWindow</action>
            </button>
            <button use-underline="true" tooltip-text="Refresh window variable - update date in window title">
                <label> _Refresh </label>
                <input file icon="gtk-refresh"></input>
                <width>16</width>
                <action function="refresh">vWindow</action>
            </button>
            <button ok></button>
            <button cancel></button>
        </hbox>
    </vbox>

    <variable>vWindow</variable>
    <input>fnEchoDateTime</input>

    <output file>/tmp/gtkd.out</output>

    <action signal="key-press-event" condition="command_is_true( [[ \$KEY_RAW = 0x9 ]] && echo true )">EXIT:exit</action> 

</window>
EOUIDFEINITION

case ${1} in
    -d | --dump) cat ${MAIN_DIALOG_FILE} ;;
    *) gtkdialog --center --file=${MAIN_DIALOG_FILE} ;;
esac

rm -f ${MAIN_DIALOG_FILE}
EOSCRIPT

touch /tmp/gtkd.out; rm /tmp/gtkd.out; /tmp/${scriptName}.sh

Exploring “action signal” directive

Let’s explore the “action signal” directive to see what sort of signals the Window object receives.

From the reference:

There is no default signal for this widget.

The “file-changed” signal is emitted if file-monitor is true and the input file being monitored has changed.

The following signals are connected-up for all widgets:

button-press-event
button-release-event
configure-event
enter-notify-event
leave-notify-event
focus-in-event
focus-out-event
hide
show
realize
key-press-event
key-release-event
map-event
unmap-event

From examples, additional events:

delete-event
destroy-event

Consider the following example, which is based on the /home/demo/gtkdialog-0.8.3/examples/miscellaneous/signals example.

scriptName=ex16
touch /tmp/${scriptName}.sh
chmod ug+x /tmp/${scriptName}.sh

cat <<-'EOSCRIPT' > /tmp/${scriptName}.sh
#!/bin/bash

GTKDIALOG=gtkdialog

MAIN_DIALOG_FILE=${0}.gtkd
cat <<-EOUIDFEINITION > ${MAIN_DIALOG_FILE}
<window title="Signals" icon-name="gtk-dialog-warning">
    <vbox>
        <frame Widgets>
            <text>
                <label>Label</label>
                <action signal="button-press-event">echo Label: button-press-event</action>
                <action signal="button-release-event">echo Label: button-release-event</action>
                <action signal="configure-event">echo Label: configure-event</action>
                <action signal="enter-notify-event">echo Label: enter-notify-event</action>
                <action signal="leave-notify-event">echo Label: leave-notify-event</action>
                <action signal="focus-in-event">echo Label: focus-in-event</action>
                <action signal="focus-out-event">echo Label: focus-out-event</action>
                <action signal="key-press-event">echo Label: key-press-event</action>
                <action signal="key-release-event">echo Label: key-release-event</action>
                <action signal="hide">echo Label: hide</action>
                <action signal="show">echo Label: show</action>
                <action signal="realize">echo Label: realize</action>
                <action signal="map-event">echo Label: map-event</action>
                <action signal="unmap-event">echo Label: unmap-event</action>
            </text>
            <entry>
                <default>Entry</default>
                <action signal="button-press-event">echo Entry: button-press_event</action>
                <action signal="button-release-event">echo Entry: button-release-event</action>
                <action signal="configure-event">echo Entry: configure-event</action>
                <action signal="enter-notify-event">echo Entry: enter-notify-event</action>
                <action signal="leave-notify-event">echo Entry: leave-notify-event</action>
                <action signal="focus-in-event">echo Entry: focus-in-event</action>
                <action signal="focus-out-event">echo Entry: focus-out-event</action>
                <action signal="key-press-event">echo Entry: key-press-event</action>
                <action signal="key-release-event">echo Entry: key-release-event</action>
                <action signal="hide">echo Entry: hide</action>
                <action signal="show">echo Entry: show</action>
                <action signal="realize">echo Entry: realize</action>
                <action signal="map-event">echo Entry: map-event</action>
                <action signal="unmap-event">echo Entry: unmap-event</action>
            </entry>
        </frame>
        <hbox>
            <button ok>
                <action signal="button-press-event">echo Button: button-press_event</action>
                <action signal="button-release-event">echo Button: button-release-event</action>
                <action signal="configure-event">echo Button: configure-event</action>
                <action signal="enter-notify-event">echo Button: enter-notify-event</action>
                <action signal="leave-notify-event">echo Button: leave-notify-event</action>
                <action signal="focus-in-event">echo Button: focus-in-event</action>
                <action signal="focus-out-event">echo Button: focus-out-event</action>
                <action signal="key-press-event">echo Button: key-press-event</action>
                <action signal="key-release-event">echo Button: key-release-event</action>
                <action signal="hide">echo Button: hide</action>
                <action signal="show">echo Button: show</action>
                <action signal="realize">echo Button: realize</action>
                <action signal="map-event">echo Button: map-event</action>
                <action signal="unmap-event">echo Button: unmap-event</action>
            </button>
        </hbox>
    </vbox>
    <action signal="button-press-event">echo Window: button-press_event</action>
    <action signal="button-release-event">echo Window: button-release-event</action>
    <action signal="configure-event">echo Window: configure-event</action>
    <action signal="delete-event">echo Window: delete-event</action>
    <action signal="destroy-event">echo Window: destroy-event</action>
    <action signal="enter-notify-event">echo Window: enter-notify-event</action>
    <action signal="leave-notify-event">echo Window: leave-notify-event</action>
    <action signal="focus-in-event">echo Window: focus-in-event</action>
    <action signal="focus-out-event">echo Window: focus-out-event</action>
    <action signal="key-press-event">echo Window: key-press-event</action>
    <action signal="key-release-event">echo Window: key-release-event</action>
    <action signal="hide">echo Window: hide</action>
    <action signal="show">echo Window: show</action>
    <action signal="realize">echo Window: realize</action>
    <action signal="map-event">echo Window: map-event</action>
    <action signal="unmap-event">echo Window: unmap-event</action>
</window>
EOUIDFEINITION

case ${1} in
    -d | --dump) cat ${MAIN_DIALOG_FILE} ;;
    *) gtkdialog --center --file=${MAIN_DIALOG_FILE} ;;
esac

rm -f ${MAIN_DIALOG_FILE}
EOSCRIPT

/tmp/${scriptName}.sh

Each if the events gives rise to an opportunity to hook in logic to be executed when the event is triggered.

In examples ex15, the following stanza illustrates the handling of the key-press-event in such a way that the exit function is called conditionally if the key which was pressed was the Escape key (0x9).

<action signal="key-press-event" condition="command_is_true( [[ \$KEY_RAW = 0x9 ]] && echo true )">EXIT:exit</action>

Exploring “action function” directive

From the reference (http://01micko.com/reference/window.html):

The following functions can be performed upon this widget by any widget capable of emitting signals:

Type Description Parameter Since
enable Sensitise widget Variable name
disable Desensitise widget Variable name
show Show widget Variable name 0.8.1
hide Hide widget Variable name 0.8.1
refresh Reload input data[1] Variable name 0.8.1
save Save widget data Variable name 0.8.1
clear Remove all widget data Variable name 0.8.1

We used the “save” function in example ex15. Now we will consider disable, enable, hide and show functions.

Let’s consider the following example:

scriptName=ex17
touch /tmp/${scriptName}.sh
chmod ug+x /tmp/${scriptName}.sh

cat <<-'EOSCRIPT' > /tmp/${scriptName}.sh
#!/bin/bash

GTKDIALOG=gtkdialog

fnEchoDateTime() {
    echo "$(date)"
}
export -f fnEchoDateTime

GTK_WIN_POS_NONE=0
GTK_WIN_POS_CENTER=1
GTK_WIN_POS_MOUSE=2

MAIN_DIALOG_FILE=${0}.gtkd
cat <<-EOUIDFEINITION > ${MAIN_DIALOG_FILE}
<window 
    title="My First Window"
    window-position="${GTK_WIN_POS_CENTER}"
    default-width="400"
>
    <vbox>
        <frame   Description  >
            <text>
                <label>"This is an example window."</label>
                <variable>vText</variable>
            </text>
        </frame>
        <hbox>
            <button use-underline="true" tooltip-text="Hide Text">
                <label> _Hide </label>
                <variable>vBtnHide</variable>
                <action function="hide" condition="visible_is_true(vText)">vText</action>
                <action function="hide" condition="visible_is_true(vBtnHide)">vBtnHide</action>
                <action function="show" condition="visible_is_false(vBtnShow)">vBtnShow</action>
            </button>
            <button visible="false" use-underline="true" tooltip-text="Show Text">
                <label> _Show </label>
                <variable>vBtnShow</variable>
                <action function="show" condition="visible_is_false(vText)">vText</action>
                <action function="show" condition="visible_is_false(vBtnHide)">vBtnHide</action>
                <action function="hide" condition="visible_is_true(vBtnShow)">vBtnShow</action>
            </button>

            <button use-underline="true" tooltip-text="Disable Text">
                <label> _Disable </label>
                <variable>vBtnDisable</variable>
                <action function="disable" condition="sensitive_is_true(vText)">vText</action>
                <action function="hide" condition="visible_is_true(vBtnDisable)">vBtnDisable</action>
                <action function="show" condition="visible_is_false(vBtnEnable)">vBtnEnable</action>
            </button>
            <button visible="false" use-underline="true" tooltip-text="Enable Text">
                <label> _Enable </label>
                <variable>vBtnEnable</variable>
                <action function="enable" condition="sensitive_is_false(vText)">vText</action>
                <action function="show" condition="visible_is_false(vBtnDisable)">vBtnDisable</action>
                <action function="hide" condition="visible_is_true(vBtnEnable)">vBtnEnable</action>
            </button>

            <button use-underline="true" tooltip-text="update date in window title">
                <label> _Refresh </label>
                <input file icon="gtk-refresh"></input>
                <width>16</width>
                <action function="refresh">vWindow</action>
            </button>
            <button ok></button>
            <button cancel></button>
        </hbox>
    </vbox>

    <variable>vWindow</variable>
    <input>fnEchoDateTime</input>

    <output file>/tmp/gtkd.out</output>

    <action signal="key-press-event" condition="command_is_true( [[ \$KEY_RAW = 0x9 ]] && echo true )">EXIT:exit</action> 

</window>
EOUIDFEINITION

case ${1} in
    -d | --dump) cat ${MAIN_DIALOG_FILE} ;;
    *) gtkdialog --center --file=${MAIN_DIALOG_FILE} ;;
esac

rm -f ${MAIN_DIALOG_FILE}
EOSCRIPT

/tmp/${scriptName}.sh

In the script above we are not hiding/showing and enabling/disabling the window, as we might, because as soon as we hide the window it will disappear and as soon as we disable it we will not be able to do anything to it except close it using the close “button” in the title bar. We are, instead, jumping ahead a bit, hiding and showing the text object and enabling and disabling the text object. This example also demonstrates how a “toggle” button can be implemented, in this case by alternately hiding and showing two different buttons (hide and show, disable/enable). The end-user impression will be that a single button changes the label and the button function on click (hide/how, disable/enable).

To see how to hide/show and disable/enable the window object consider the following, not particularly useful in practice, example:

scriptName=ex18
touch /tmp/${scriptName}.sh
chmod ug+x /tmp/${scriptName}.sh

cat <<-'EOSCRIPT' > /tmp/${scriptName}.sh
#!/bin/bash

GTKDIALOG=gtkdialog

fnEchoDateTime() {
    echo "$(date)"
}
export -f fnEchoDateTime

GTK_WIN_POS_NONE=0
GTK_WIN_POS_CENTER=1
GTK_WIN_POS_MOUSE=2

MAIN_DIALOG_FILE=${0}.gtkd
cat <<-EOUIDFEINITION > ${MAIN_DIALOG_FILE}
<window 
    title="My First Window"
    window-position="${GTK_WIN_POS_CENTER}"
    default-width="400"
>
    <vbox>
        <frame   Description  >
            <text>
                <label>"Click Hide or Disable and wait up to 5 seconds for the timer to trigger the reversal of the action."</label>
                <variable>vText</variable>
            </text>
        </frame>
        <hbox>
            <timer sensitive="false" milliseconds="true" interval="5000" visible="false" disabled="true">
                <variable>tmr0</variable>
                <action>show:vWindow</action>
            </timer>
            <timer sensitive="false" milliseconds="true" interval="5000" visible="false" disabled="true">
                <variable>tmr1</variable>
                <action>enable:vWindow</action>
            </timer>
            <button use-underline="true" tooltip-text="Hide Window">
                <label> _Hide </label>
                <action function="hide" condition="visible_is_true(vWindow)">vWindow</action>
                <action function="enable" condition="sensitive_is_false(tmr0)">tmr0</action>
            </button>
            <button use-underline="true" tooltip-text="Disable Window">
                <label> _Disable </label>
                <action function="disable" condition="sensitive_is_true(vWindow)">vWindow</action>
                <action function="enable" condition="sensitive_is_false(tmr1)">tmr1</action>
            </button>
            <button use-underline="true" tooltip-text="update date in window title">
                <label> _Refresh </label>
                <input file icon="gtk-refresh"></input>
                <width>16</width>
                <action function="refresh">vWindow</action>
            </button>
            <button ok></button>
            <button cancel></button>
        </hbox>
    </vbox>

    <variable>vWindow</variable>
    <input>fnEchoDateTime</input>

    <output file>/tmp/gtkd.out</output>

    <action signal="key-press-event" condition="command_is_true( [[ \$KEY_RAW = 0x9 ]] && echo true )">EXIT:exit</action> 

</window>
EOUIDFEINITION

case ${1} in
    -d | --dump) cat ${MAIN_DIALOG_FILE} ;;
    *) gtkdialog --center --file=${MAIN_DIALOG_FILE} ;;
esac

rm -f ${MAIN_DIALOG_FILE}
EOSCRIPT

/tmp/${scriptName}.sh

In the script above we are jumping ahead a bit and using timers to trigger events that will show the hidden window and enable the disabled content after an interval.

Perhaps provision of a bit of context is in order at this point for no other reason than to make the basic action processing explicit.

Consider the two actions defined for the Hide button.

<action function="hide" condition="visible_is_true(vWindow)">vWindow</action>

<action function="enable" condition="sensitive_is_false(tmr0)">tmr0</action>

The first action will hide the window. The condition “visible_is_true(vWindow)” is superfluous in this case because the button will only be visible if the window is visible but it is there as an example of a conditional action.

The second action will enable a timer which will trigger its own action to reverse the effect of the button press on the Window object after an interval of up to 5 seconds.

Unless told otherwise, of which in a later article, the button press will cause the two actions to be executed one after the other. There are some circumstances in which execution of an action in the action list will prevent actions defined after it being executed but these are rare circumstances, which will be discussed in a subsequent article. One can have several actions which a button press will trigger. Other active objects can have actions as well, as can be seen with the timer objects and will be also seen in subsequent articles in which other objects are discussed and used.

For the time being one can assume that all actions defined for an object, like a window or a button, will get evaluated sequentially and will be executed if appropriate (like for example if the condition is met).

The style attribute does nothing visible. It is quite likely that I don’t know how to define a style. There is an alternative way to “style” objects which works in some instances and can be used as appropriate.

Consider the following example:

scriptName=ex19
touch /tmp/${scriptName}.sh
chmod ug+x /tmp/${scriptName}.sh

cat <<-'EOSCRIPT' > /tmp/${scriptName}.sh
#!/bin/bash

GTKDIALOG=gtkdialog

fnEchoDateTime() {
echo "$(date)"
}
export -f fnEchoDateTime

echo '
style "bgWhite" { bg[NORMAL] = "#FFFFFF" }
style "fgWhite" { fg[NORMAL] = "#FFFFFF" }
style "bgBlack" { bg[NORMAL] = "#000000" }
style "bgRed" { bg[NORMAL] = "#FF0000" }
style "fgRed" { fg[NORMAL] = "#FF0000" }
style "bgGreen" { bg[NORMAL] = "#FFFF00" }
style "fgGreen" { fg[NORMAL] = "#FFFF00" }
style "bgBlue" { bg[NORMAL] = "#0000FF" }
style "fgBlue" { fg[NORMAL] = "#0000FF" }

widget "MyWindowBg" style "bgBlack"
widget "MyWindowBg.GtkVBox.GtkHBox.MyButtonBg" style "bgGreen"

widget "MyWindowBg.GtkVBox.myEVB" style "bgBlue"

widget_class "*<GtkFrame>.GtkLabel" style "fgWhite"
widget_class "*<GtkFrame>.*.GtkLabel" style "fgGreen"
widget_class "*<GtkButton>.*.GtkLabel" style "fgRed"

' > /tmp/gtkrc_mono 
export GTK2_RC_FILES=/tmp/gtkrc_mono

GTK_WIN_POS_NONE=0
GTK_WIN_POS_CENTER=1
GTK_WIN_POS_MOUSE=2

MAIN_DIALOG_FILE=${0}.gtkd
cat <<-EOUIDFEINITION > ${MAIN_DIALOG_FILE}
<window 
    title="My First Window"
    window-position="${GTK_WIN_POS_CENTER}"
    default-width="400"
    name="MyWindowBg"
>
    <vbox>
        <eventbox name="myEVB" above-child="false" visible-window="true">
        <frame   Description  >
            <text><label>This is an example window.</label></text>
        </frame>
        </eventbox>
        <hbox>
            <button name="MyButtonBg" use-underline="true" tooltip-text="Refresh window variable - update date in window title">
                <label> _Refresh </label>
                <input file icon="gtk-refresh"></input>
                <width>16</width>
                <action function="refresh">vWindow</action>
            </button>
            <button ok></button>
            <button cancel></button>
        </hbox>
    </vbox>

    <variable>vWindow</variable>
    <input>fnEchoDateTime</input>
    <action this-is-window="escape" signal="key-press-event" condition="command_is_true( [[ \$KEY_RAW = 0x9 ]] && echo true )">EXIT:exit</action> 
</window>
EOUIDFEINITION

case ${1} in
    -d | --dump) cat ${MAIN_DIALOG_FILE} ;;
    *) gtkdialog --center --file=${MAIN_DIALOG_FILE} ;;
esac

rm -f ${MAIN_DIALOG_FILE}
EOSCRIPT

/tmp/${scriptName}.sh

Here we define and use GTK styles to change foreground and/or background colours of the various objects.

Here is how the application window looks.

This is just a brief teaser. How to apply styles to objects, what works and what does not, etc., may be covered in a future article.

Exploring Window examples

In /home/demo/gtkdialog-0.8.3/examples/window there are 3 examples. Review the window GUI definitions and run the examples

/bin/sh /home/demo/gtkdialog-0.8.3/examples/window/window --dump

/bin/sh /home/demo/gtkdialog-0.8.3/examples/window/window

/bin/sh /home/demo/gtkdialog-0.8.3/examples/window/window_attributes --dump

/bin/sh /home/demo/gtkdialog-0.8.3/examples/window/window_attributes

/bin/sh /home/demo/gtkdialog-0.8.3/examples/window/window_signals --dump

/bin/sh /home/demo/gtkdialog-0.8.3/examples/window/window_signals

Leave a Reply

preload preload preload