Giter Club home page Giter Club logo

fortran-dialog's Introduction

fortran-dialog

A work-in-progress wrapper module around dialog to create text user interfaces in Fortran 2008, similar to pythondialog for Python.

Packages of dialog(1) are available for most Unix-like operating systems. On FreeBSD, an older version of dialog is already part of the base system. Install the package devel/cdialog for an enhanced port:

# pkg install devel/cdialog

Add an alias to your global profile, or set the backend to cdialog before calling any dialog routines from Fortran:

call dialog_backend('cdialog')

The basic widgets are compatible to Xdialog as well. Just set the backend to Xdialog.

Coverage

Widget Supported
buildlist
calendar
checklist
dselect
editbox
form
fselect
gauge
infobox
inputbox
inputmenu
menu
mixedform
mixedgauge
msgbox
pause
passwordbox
passwordform
prgbox
programbox
progressbox
radiolist
rangebox
tailbox
tailboxbg
textbox
timebox
treeview
yesno

Build Instructions

Download the fortran-dialog repository, and execute the Makefile:

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

If you prefer the Fortran Package Manager, run:

$ fpm build --profile=release

You can add fortran-dialog as a dependency to your fpm.toml:

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

Example

The following example just shows a message box in terminal:

! example.f90
program main
    use :: dialog

    call dialog_msgbox('This is the message box widget.', 10, 30)
end program main

Link the example against libfortran-dialog.a:

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

To create a graphical message box with Xdialog(1), write instead:

! example.f90
program main
    use :: dialog

    call dialog_backend('Xdialog')
    call dialog_msgbox('This is the message box widget.', 10, 30)
end program main

Further Examples

More examples can be found in examples/:

  • hamurabi is a port of the simulation game Hamurabi.
  • showcase demonstrates all supported widget types.
  • wumpus is a port of the game Hunt the Wumpus.

Build the programs with make:

$ make examples

Widgets

This section lists code snippets in Fortran for the supported dialog(1) widgets. See the official website for screen shots.

buildlist

character(len=32) :: selected
type(dialog_type) :: dialog
type(list_type)   :: list(3)

list(1) = list_type('item1', 'List Item 1', 'on')
list(2) = list_type('item2', 'List Item 2')
list(3) = list_type('item3', 'List Item 3')

call dialog_buildlist(dialog, 'Select items:', 16, 40, 5, list, &
                      title='Build List')
call dialog_read(dialog, selected)
call dialog_close(dialog)

print '("Selected items: ", a)', trim(selected)

calendar

character(len=12) :: date
type(dialog_type) :: dialog

call dialog_calendar(dialog, 'Enter date:', 3, 42, day=1, month=1, year=2025, &
                     title='Calendar')
call dialog_read(dialog, date)
call dialog_close(dialog)

print '("Date: ", a)', date

checklist

character(len=32) :: selected
type(dialog_type) :: dialog
type(list_type)   :: list(3)

list(1) = list_type('item1', 'List Item 1', 'on')
list(2) = list_type('item2', 'List Item 2')
list(3) = list_type('item3', 'List Item 3')

call dialog_checklist(dialog, 'Select items:', 16, 40, 5, list, &
                      title='Check List')
call dialog_read(dialog, selected)
call dialog_close(dialog)

print '("Selected items: ", a)', trim(selected)

dselect

character(len=512) :: path
type(dialog_type)  :: dialog

call dialog_dselect(dialog, '/', 18, 72, title='Select Directory')
call dialog_read(dialog, path)
call dialog_close(dialog)

print '("Directory: ", a)', trim(path)

editbox

character(len=512) :: line
logical            :: eof
type(dialog_type)  :: dialog

call dialog_editbox(dialog, './examples/wumpus.f90', 18, 72, title='Edit Box')

do
    call dialog_read(dialog, line, eof)
    if (eof) exit
    print '(a)', trim(line)
end do

call dialog_close(dialog)

form

character(len=32) :: user, shell, group
type(dialog_type) :: dialog
type(form_type)   :: form(3)

form(1) = form_type('User:',  1, 1, 'user',    1, 10, 10, 0)
form(2) = form_type('Shell:', 2, 1, '/bin/sh', 2, 10, 10, 0)
form(3) = form_type('Group:', 3, 1, 'wheel',   3, 10, 10, 0)

call dialog_form(dialog, 'Set user data:', 16, 40, 5, form, &
                 ok_label='Submit', title='Form')
call dialog_read(dialog, user)
call dialog_read(dialog, shell)
call dialog_read(dialog, group)
call dialog_close(dialog)

print '("User:  ", a)', trim(user)
print '("Shell: ", a)', trim(shell)
print '("Group: ", a)', trim(group)

fselect

character(len=512) :: path
type(dialog_type)  :: dialog

call dialog_fselect(dialog, '/', 18, 72, title='Select File')
call dialog_read(dialog, path)
call dialog_close(dialog)

print '("File: ", a)', trim(path)

gauge

character, parameter :: NL = new_line('a')

character(len=3)  :: a
integer           :: i
type(dialog_type) :: dialog

call dialog_gauge(dialog, 'Progress:', 12, 32, 0, title='Gauge')

do i = 1, 100
    select case (i)
        case (:20)
            call dialog_write(dialog, 'Validating ...' // NL)
        case (21:40)
            call dialog_write(dialog, 'Updating ...' // NL)
        case (41:60)
            call dialog_write(dialog, 'Doing more work ...' // NL)
        case (61:80)
            call dialog_write(dialog, 'Just a few seconds ...' // NL)
        case (81:)
            call dialog_write(dialog, 'Almost done ...' // NL)
    end select

    write (a, '(i0)') i
    call dialog_write(dialog, 'XXX' // NL // a // NL)
end do

call dialog_close(dialog)

infobox

call dialog_infobox(new_line('a') // 'This is the info box widget.', &
                    8, 36, title='Information', sleep=2)

inputbox

character(len=32) :: input
type(dialog_type) :: dialog

call dialog_inputbox(dialog, 'Enter your name:', 7, 32, 'Alice', title='Name')
call dialog_read(dialog, input)
call dialog_close(dialog)

print '("Input: ", a)', trim(input)

inputmenu

character(len=32) :: renamed
logical           :: eof
type(dialog_type) :: dialog
type(menu_type)   :: menu(3)

menu(1) = menu_type('item1', 'Item 1')
menu(2) = menu_type('item2', 'Item 2')
menu(3) = menu_type('item3', 'Item 3')

call dialog_inputmenu(dialog, 'Input:', 16, 40, size(menu), menu, &
                      no_tags=.true., title='Input Menu')

do
    call dialog_read(dialog, renamed, eof)
    if (eof) exit
    print '(a)', trim(renamed)
end do

call dialog_close(dialog)

menu

character(len=32) :: selected
type(dialog_type) :: dialog
type(menu_type)   :: menu(3)

menu(1) = menu_type('item1', 'Item 1')
menu(2) = menu_type('item2', 'Item 2')
menu(3) = menu_type('item3', 'Item 3')

call dialog_menu(dialog, 'Select an item:', 16, 40, size(menu), menu, &
                 no_tags=.true., title='Menu Demo')
call dialog_read(dialog, selected)
call dialog_close(dialog)

print '("Selected item: ", a)', trim(selected)

mixedform

character(len=32) :: user, shell, group
type(dialog_type) :: dialog
type(form_type)   :: form(3)

form(1) = form_type('User:',  1, 1, 'user',    1, 10, 10, 0, 2)
form(2) = form_type('Shell:', 2, 1, '/bin/sh', 2, 10, 10, 0, 0)
form(3) = form_type('Group:', 3, 1, 'wheel',   3, 10, 10, 0, 0)

call dialog_mixedform(dialog, 'Set user data:', 16, 40, 5, form, &
                      ok_label='Submit', title='Mixed Form')
call dialog_read(dialog, user)
call dialog_read(dialog, shell)
call dialog_read(dialog, group)
call dialog_close(dialog)

print '("User:  ", a)', trim(user)
print '("Shell: ", a)', trim(shell)
print '("Group: ", a)', trim(group)

mixedgauge

character(len=4) :: a
integer          :: i
type(gauge_type) :: gauge(10)

gauge(1) = gauge_type('Process one',   '0')
gauge(2) = gauge_type('Process two',   '1')
gauge(3) = gauge_type('Process three', '2')
gauge(4) = gauge_type('Process four',  '3')
gauge(5) = gauge_type('',              '8')
gauge(6) = gauge_type('Process five',  '5')
gauge(7) = gauge_type('Process six',   '6')
gauge(8) = gauge_type('Process seven', '7')
gauge(9) = gauge_type('Process eight', '4')

do i = 0, 100, 20
    write (a, '("-", i0)') i
    gauge(10) = gauge_type('Process nine', a)
    call dialog_mixedgauge('Progress:', 20, 64, 33, gauge, title='Mixed Gauge')
    call sleep(1)
end do

msgbox

call dialog_msgbox('This is the message box widget.', 8, 36, &
                   backtitle='msgbox', title='Message')

passwordbox

character(len=32) :: password
type(dialog_type) :: dialog

call dialog_passwordbox(dialog, 'Enter password:', 7, 32, &
                        insecure=.true., title='Password')
call dialog_read(dialog, password)
call dialog_close(dialog)

print '("Password: ", a)', trim(password)

passwordform

character(len=32) :: uuid, password
type(dialog_type) :: dialog
type(form_type)   :: form(2)

form(1) = form_type('UUID:',     1, 1, '12345',  1, 10, 10, 0)
form(2) = form_type('Password:', 2, 1, 'secret', 2, 10, 10, 0)

call dialog_passwordform(dialog, 'Set values:', 12, 40, 3, form, insecure=.true., &
                         ok_label='Submit', title='Password Form')
call dialog_read(dialog, uuid)
call dialog_read(dialog, password)
call dialog_close(dialog)

print '("UUID:     ", a)', trim(uuid)
print '("Password: ", a)', trim(password)

pause

integer :: stat

call dialog_pause('System reboots in 30 seconds.', 8, 36, 30, &
                  title='Pause', exit_stat=stat)

select case (stat)
    case (DIALOG_YES)
        print '("You pressed OK.")'
    case (DIALOG_NO)
        print '("You pressed Cancel.")'
    case default
        print '("You pressed Escape.")'
end select

prgbox

call dialog_prgbox('Uptime:', 'uptime', 8, 64, title='Prg Box')

programbox

character, parameter :: NL = new_line('a')

call dialog_programbox(dialog, 'Output:', 12, 32, title='Program Box')
call dialog_write(dialog, 'zzz ...' // NL)
call dialog_write(dialog, 'zzz ...' // NL)
call dialog_write(dialog, 'zzz ...' // NL)
call dialog_close(dialog)

progressbox

character, parameter :: NL = new_line('a')

call dialog_progressbox(dialog, 'Output:', 12, 32, title='Progress Box')
call dialog_write(dialog, 'zzz ...' // NL)
call dialog_write(dialog, 'zzz ...' // NL)
call dialog_write(dialog, 'zzz ...' // NL)
call dialog_close(dialog)

radiolist

character(len=32) :: selected
type(dialog_type) :: dialog
type(list_type)   :: list(3)

list(1) = list_type('item1', 'List Item 1', 'on')
list(2) = list_type('item2', 'List Item 2')
list(3) = list_type('item3', 'List Item 3')

call dialog_radiolist(dialog, 'Select items:', 16, 40, 5, list, &
                      title='Radio List')
call dialog_read(dialog, selected)
call dialog_close(dialog)

print '("Selected item: ", a)', trim(selected)

rangebox

character(len=3)  :: range
type(dialog_type) :: dialog

call dialog_rangebox(dialog, 'Select range with PGUP/PGDOWN:', 7, 32, min_value=0, &
                     max_value=42, default_value=21, title='Range Box')
call dialog_read(dialog, range)
call dialog_close(dialog)

print '("Selected range: ", a)', range

tailbox

call dialog_tailbox('/var/log/messages', 18, 72, title='Tail Box')

textbox

call dialog_textbox('./examples/wumpus.f90', 18, 72, title='Text Box')

timebox

character(len=8)  :: time
type(dialog_type) :: dialog

call dialog_inputbox(dialog, 'Enter time:', 7, 32, hour=12, minute=0, second=0, &
                     title='Time')
call dialog_read(dialog, time)
call dialog_close(dialog)

print '("Time: ", a)', time

treeview

character(len=32) :: selected
type(dialog_type) :: dialog
type(tree_type)   :: tree(4)

tree(1) = tree_type('tag1', 'one',   'off', 0)
tree(2) = tree_type('tag2', 'two',   'off', 1)
tree(3) = tree_type('tag3', 'three', 'on',  2)
tree(4) = tree_type('tag4', 'four',  'off', 1)

call dialog_treeview(dialog, 'Select item:', 0, 0, 0, tree, title='Tree View')
call dialog_read(dialog, selected)
call dialog_close(dialog)

print '("Selected: ", a)', trim(selected)

yesno

integer :: answer

answer = dialog_yesno('Please press Yes or No!', 6, 30, title='Example')

select case (answer)
    case (DIALOG_YES)
        print '("You pressed Yes.")'
    case (DIALOG_NO)
        print '("You pressed No.")'
    case default
        print '("You pressed Escape.")'
end select

Themes

You can create a new dialog(1) theme via:

$ dialog --create-rc ~/.dialogrc

Alter the settings to your liking. In /usr/local/share/examples/dialog/, you find several pre-defined themes:

  • debian.rc
  • slackware.rc
  • sourcemage.rc
  • suse.rc
  • whiptail.rc

Copy one of the widget styles to ~/.dialogrc.

Compatiblity

  • Single quotes should be avoided, as they have to be escaped as "'\''" in any text passed to dialog(1) from Fortran.
  • Only the wrapper function dialog_yesno() and subroutines with optional dummy argument exit_stat return the exit status of dialog(1). The routine dialog_close() returns an optional exit status.
  • Dialog proceeding (--and-widget) is not supported.

Licence

ISC

fortran-dialog's People

Contributors

interkosmos avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

fortran-dialog's Issues

run examples with fpm

nice project.

not sure if this is intentional, but to be able to run the examples with fpm I had to rename the folder from examples to example. minor suggestion to rename it to example so that one can do fpm run --example wumpus

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.