diff --git a/projects/oorexx/apps.rex b/projects/oorexx/apps.rex new file mode 100755 index 0000000..7f644ce --- /dev/null +++ b/projects/oorexx/apps.rex @@ -0,0 +1,244 @@ +#!/usr/bin/env rexx +/* apps.rex - Menu-driven application launcher using Object Rexx with ncurses */ +signal on halt name ProgramHalt +.environment['STOPNOW'] = 0 + +stdwin = .window~new /* Initialize the standard screen - first call must have zero arguments */ +do forever + if .environment['STOPNOW'] = 1 then do + stdwin~endwin /* Clean up before exiting */ + address system 'clear' + Say "Exiting Apps Menu." + exit 0 + end + call menu stdwin +end + +exit +/**************/ + +::routine tmemo + dt = .DateTime~new + yyyy = dt~year + mm = right('0'||dt~month, 2) + dd = right('0'||dt~day, 2) + hh = right('0'||dt~hours, 2) + min = right('0'||dt~minutes, 2) + ss = right('0'||dt~seconds, 2) + timestamp = 'memo-'||yyyy||'.'||mm||'.'||dd||'-'||hh||'.'||min||'.'||ss + + /* Use environment variable for HOME directly */ + home = SysGetpwnam("gmgauthier", "d") + filename = home || '/Documents/memos/' || timestamp || '.md' + address system 'touch' filename + address system 'tilde' filename + return + +/* Output panel similar to dialog --msgbox */ +::routine output_panel + use arg win, title, message + win~raw + win~noecho + + message_lines = .array~new + do while message \== '' + parse var message line '0a'x message + message_lines~append(line) + end + if message_lines~items = 0 then message_lines~append(message) + + max_width = 0 + do i = 1 to message_lines~items + if message_lines[i]~length > max_width then max_width = message_lines[i]~length + end + + box_height = message_lines~items + 4 + box_width = max_width + 4 + + /* Center the box on screen */ + max_y = win~lines + max_x = win~cols + start_y = (max_y - box_height) % 2 + start_x = (max_x - box_width) % 2 + + /* Create a subwindow - subsequent .window~new calls need height, width, y, x */ + subwin = .window~new(box_height, box_width, start_y, start_x) + subwin~box + + /* Display title */ + subwin~attron(win~A_BOLD) + subwin~mvaddstr(0, (box_width - title~length) % 2, title) + subwin~attroff(win~A_BOLD) + + /* Display message */ + do i = 1 to message_lines~items + subwin~mvaddstr(i+1, 2, message_lines[i]) + end + + subwin~mvaddstr(box_height - 2, (box_width - 15) % 2, "Press any key") + subwin~refresh + key = win~getch + win~refresh + return + +/* Function to find position of an item in an array */ +::routine findInArray + use arg array, item + do i = 1 to array~items + if array[i] = item then return i + end + return 0 /* Not found */ + +/* Menu function using ncurses */ +::routine menu + use arg winm + + /* Get the HOME environment variable directly */ + home = SysGetpwnam("gmgauthier", "d") + + winm~clear /* Clear the screen */ + winm~refresh /* Update the screen */ + winm~cbreak + winm~noecho + winm~keypad(1) /* Enable function keys and arrow keys */ + winm~start_color + winm~init_pair(1, winm~COLOR_WHITE, winm~COLOR_BLUE) + winm~init_pair(2, winm~COLOR_BLACK, winm~COLOR_WHITE) + + /* Get screen dimensions */ + max_y = winm~lines + max_x = winm~cols + + /* Create menu window - using proper 4 arguments for subwindow */ + menu_height = 19 + menu_width = 40 + start_y = (max_y - menu_height) % 2 + start_x = (max_x - menu_width) % 2 + + menuwin = .window~new(menu_height, menu_width, start_y, start_x) + menuwin~bkgd(winm~color_pair(1)) /* Set the entire background */ + menuwin~box(0,0) /* Standard box characters */ + + /* Create title */ + menuwin~attron(winm~A_BOLD) + title = "TUI Command Center" + menuwin~mvaddstr(2, (menu_width - title~length) % 2, title) + menuwin~attroff(winm~A_BOLD) + + /* Menu items */ + menu_items = .array~of(" w. WordPerfect 8", - + " x. Lotus 1-2-3", - + " e. Mutt Email", - + " c. Calcurse Calendar", - + " a. Abook Contacts", - + " n. Tilde Notepad", - + " t. Tudu Tasks", - + " l. Terminal Calculator", - + " f. MC File Manager", - + " i. Weechat IRC Client", - + " p. Castero Podcasts", - + " m. VLC Music Player") + + menu_keys = .array~of("w", "x", "e", "c", "a", "n", "t", "l", "f", "i", "p", "m") + + /* Display menu items */ + selected = 1 + call DrawMenu menuwin, menu_items, selected, winm + menuwin~mvaddstr(menu_height - 2, 3, "Q to exit") + menuwin~refresh + + /* Menu interaction loop */ + key = "" + do forever + menuwin~refresh + key = winm~getch + + select + when key = winm~KEY_UP then do + if selected > 1 then selected = selected - 1 + call DrawMenu menuwin, menu_items, selected, winm + end + when key = winm~KEY_DOWN then do + if selected < menu_items~items then selected = selected + 1 + call DrawMenu menuwin, menu_items, selected, winm + end + when key = D2C(10) | key = D2C(13) then do /* Enter key - numeric codes only */ + menuwin~refresh + call ProcessSelection menu_keys[selected], home + return + end + when key = D2C(81) | key = D2C(113) | key = "q" | key = C2D("q") then do + menuwin~endwin + .environment['STOPNOW'] = 1 + RETURN + end + otherwise do + if datatype(key) = 'CHAR' then do + key = lower(key) + pos = findInArray(menu_keys, key) + if pos > 0 then do + menuwin~mvaddstr(menu_height - 1, 20, "Letter selection: "||key) + menuwin~refresh + call SysWait 0.5 + winm~endwin + call ProcessSelection key, home + return + end + end + end + end + end + RETURN + +/* wait a specified number of seconds */ +::routine SysWait + use arg seconds + address system 'sleep' seconds + return + +/* process menu selections */ +::routine ProcessSelection + use arg key_char, home + select + when key_char = 'w' then address system 'wp' + when key_char = 'x' then address system '123' + when key_char = 'e' then address system 'neomutt -F' home'/.config/mutt/muttrc' + when key_char = 'c' then address system 'calcurse -c' home'/.local/share/calcurse/calendar -C' home'/.config/calcurse' + when key_char = 'a' then address system 'abook --datafile' home'/.local/share/abook/addressbook' + when key_char = 'n' then call tmemo + when key_char = 't' then address system 'tudu -f' home'/.local/share/tudu/tasks.xml -c' home'/.config/tudu/config' + when key_char = 'l' then address system 'tcalc' + when key_char = 'f' then address system 'mc' + when key_char = 'i' then address system 'weechat' + when key_char = 'p' then address system 'castero' + when key_char = 'm' then address system 'vlc -Z -L -I ncurses --no-video --recursive expand' home'/Music' + otherwise nop + end + return + +/* draw menu with selected item highlighted */ +::routine DrawMenu + use arg win, items, selected, mainwin + + do i = 1 to items~items + if i = selected then do + win~attron(mainwin~COLOR_PAIR(2)) + win~attron(mainwin~A_BOLD) + win~mvaddstr(i+3, 2, items[i]) + win~attroff(mainwin~COLOR_PAIR(2)) + win~attroff(mainwin~A_BOLD) + end + else do + win~mvaddstr(i+3, 2, items[i]) + end + end + return + +/* Handle program termination */ +::ROUTINE ProgramHalt + signal off halt + exit 0 + + +::requires "ncurses.cls" +::requires "rxunixsys" LIBRARY \ No newline at end of file