Dialog

Creating text-based or graphical user interfaces does not require a full-featured toolkit, like GTK or Tk, in every case. Instead, command-line utilities may already be sufficient to display program output, or ask for user input. The dialog tool, originally written by Savio Lam in 1993 and later reimplemented by Thomas E. Dickey, is based on ncurses and supports 29 widget types (fig. 1). The project provides a C library as well. Both are available for most Unix-like environments, among them Linux, BSD, macOS, and Cygwin. Additional wrapper libraries are available for Python, Perl, and Ruby. The dialog program is usually executed from command-line or shell script:

$ dialog <common options> <widget> <widget options>

The following command displays a dialog window to ask for a response:

$ dialog --yesno "Do you want to continue?" 6 32

The user’s choice is returned as the program exit status.

Hamurabi in Fortran
Fig. 1: Port of Hamurabi to Fortran, using dialog for input and output

There are alternatives to the text-based dialog:

bsddialog
Reimplementation of dialog and its C library.
whiptail
A dialog replacement using Newt instead of ncurses.

Other programs display graphical dialog windows:

kdialog
A Qt-based dialog tool, targeting KDE. Only partially compatible to dialog.
tpmg
A dialog tool much like Zenity or kdialog, written in core Tcl/Tk.
Xdialog
Creates dialog windows in GTK 1/2. Supports the most common widgets of dialog.
yad
Yet Another Dialog: displays dialog boxes in GTK 3 from command-line or shell script.
Zenity
GTK-based dialog tool for GNOME and Xfce that was first released in 2003.

There have been many more short-lived implementations of the dialog concept, such as dldialog, gdialog, lxdialog, or wxdialog.

dialog

A package of dialog is available for probably every Unix-like environment. On FreeBSD, the program is even part of the base system and does not have to be installed:

$ dialog --version
Version: 1.3-20180621

However, an enhanced version is available as cdialog from the ports system:

# pkg install devel/cdialog
# cdialog --version
Version: 1.3-20220728

On Linux, macOS, and Cygwin, packages are available under the name dialog. If no package is provided, we may simply compile the program from source:

$ fetch https://invisible-island.net/datafiles/release/dialog.tar.gz
$ tar xfvz dialog.tar.gz
$ cd dialog-1.3-20220728/
$ ./configure
$ make
$ ./dialog --version
Version: 1.3-20220728

The name of the unpacked directory depends on the actual source version.

In Fortran, we can invoke dialog through the intrinsic command-line execution routine. Since Fortran 2008, the exit status of the program is returned in optional argument exitstat. The status signals the choice the user has made. Additional arguments may be used to change style and behaviour.

! diafor.f90
program main
    implicit none
    integer, parameter :: DIALOG_YES = 0
    integer, parameter :: DIALOG_NO  = 1
    integer, parameter :: DIALOG_ESC = 255

    integer :: stat

    call execute_command_line('dialog --yesno "Do you want to continue?" 6 40', exitstat=stat)

    select case (stat)
        case (DIALOG_YES)
            print '("User pressed Yes.")'
        case (DIALOG_NO)
            print '("User pressed No.")'
        case (DIALOG_ESC)
            print '("User pressed Escape.")'
    end select
end program main

The program has no dependencies other than dialog:

$ gfortran -o diafor diafor.f90
$ ./diafor
Dialog called from Fortran
Fig. 2: A radio list dialog created from Fortran

Xdialog

The Xdialog command-line program display graphical dialog windows using GTK 2. On FreeBSD, install the package with:

$ pkg install x11/xdialog
$ Xdialog -v
2.3.1

If Xdialog is compiled directly from source, GTK 2 has to be selected explicitly:

$ fetch http://xdialog.free.fr/Xdialog-2.3.1.tar.bz2
$ tar xfvz Xdialog-2.3.1.tar.bz2
$ cd Xdialog-2.3.1/
$ ./configure --with-gtk2 --disable-nls
$ make
$ ./src/Xdialog -v
2.3.1

We can then create a graphical dialog box from command-line:

$ Xdialog --yesno "Do you want to continue?" 6 40

The Xdialog utility is not fully compatible to all of the dialog widgets.

Xdialog called from Fortran
Fig. 3: The radio list dialog displayed with Xdialog in a GTK 2 window

fortran-dialog

The fortran-dialog library provides wrapper routines around the dialog command-line utility, to display text-based widgets from Fortran, similar to pythondialog for Python. To build the library, simply clone the source code repository and execute the included Makefile:

$ git clone https://github.com/interkosmos/fortran-dialog
$ cd fortran-dialog/
$ make

Or, instead, use the Fortran Package Manager:

$ fpm build --profile release

The library can be added as a dependency to the fpm.toml build manifest of your project:

[dependencies]
fortran-dialog = { git = "https://github.com/interkosmos/fortran-dialog.git" }

The following example program creates a simple radio list dialog (fig. 2). The selected item is read with dialog_read(). Additionally, we could capture the exit status when calling dialog_close() through optional argument exit_stat.

! example.f90
program main
    use :: dialog
    implicit none
    character(len=8)  :: selected
    type(dialog_type) :: dialog
    type(list_type)   :: list(5)

    list(1) = list_type('2018', 'Fortran 2018', 'on')
    list(2) = list_type('2008', 'Fortran 2008')
    list(3) = list_type('2003', 'Fortran 2003')
    list(4) = list_type('95',   'Fortran 95')
    list(5) = list_type('90',   'Fortran 90')

    call dialog_backend('dialog')
    call dialog_radiolist(dialog, 'Select a language standard:', 12, 40, 5, list, &
                          no_tags=.true., title='Fortran Standard')
    call dialog_read(dialog, selected)
    call dialog_close(dialog)

    print '("Selected standard: ", a)', trim(selected)
end program main

The status of the list item selected by default has to be set to on. Compile, link, and run the program with:

$ gfortran -o example example.f90 libfortran-dialog.a
$ ./example

The radio list item selected by the user is printed to terminal afterwards. The same widget can be displayed in a graphical window, if the backend is set to the path of the Xdialog binary beforehand (fig. 3):

call dialog_backend('Xdialog')

Fortran Libraries

References