add a cursor carat, and keys to control it

This commit is contained in:
Greg Gauthier 2025-04-14 22:31:50 +01:00
parent 931f384af2
commit 0fc21c9c08
2 changed files with 300 additions and 0 deletions

154
src/empdisplay3.a68 Normal file
View File

@ -0,0 +1,154 @@
PROC main = INT: BEGIN
# Postgres Setup #
FILE db;
STRING result;
STRING conninfo = "dbname=testdb user=gmgauthier password=thx1138gg host=localhost port=5432";
INT status = pq connect db(db, conninfo, result);
IF status /= 0 THEN print(("Connect failed: ", result, newline)); stop FI;
print(("We've initialized the database connection", newline));
# Query Employees #
INT qstatus = pq exec(db, "SELECT employee, employee_id, start_date, salary FROM employees ORDER BY employee_id");
IF qstatus /= 0 THEN
print(("Query failed: ", qstatus, newline));
INT fin1 = pq finish(db);
print((fin1, newline));
stop
FI;
print(("We've loaded the data from the database", newline));
# ncurses Setup #
print(("We're starting curses...", newline));
curses start; # VOID, no return to check #
INT lines = curses lines; INT cols = curses columns; # Check screen init #
IF lines = 0 OR cols = 0 THEN
curses end;
print(("ncurses failed to initialize: lines=", lines, " cols=", cols, newline));
INT fin1 = pq finish(db);
print((fin1, newline)); # suppresses the warning #
stop
FI;
# Clear screen to avoid artifacts #
curses clear;
# Border and Title (y=2, x=10, width=40, height=15) #
PROC draw char = (INT y, x, CHAR c) VOID: (
curses move(y, x); curses putchar(c)
);
PROC draw str = (INT y, x, STRING s) VOID: (
FOR i FROM 1 TO UPB s DO
draw char(y, x + i - 1, s[i])
OD
);
# Top/Bottom Border #
FOR x FROM 10 TO 49 DO
draw char(2, x, "-"); draw char(16, x, "-")
OD;
# Sides #
FOR y FROM 3 TO 15 DO
draw char(y, 10, "|"); draw char(y, 49, "|")
OD;
# Corners #
draw char(2, 10, "+"); draw char(2, 49, "+");
draw char(16, 10, "+"); draw char(16, 49, "+");
# Title (y=3) #
draw str(3, 12, "Employee Data");
# Headers (y=5) #
draw str(5, 12, "Name ID Start Salary");
# Data (y=7, 9, 11, 13, 15) with Row Separators #
INT roz = pq ntuples(db);
[roz, 4]STRING data; # Store all data to debug #
# First Pass: Draw Row Separators #
draw char(6, 10, "|"); # Header separator #
FOR x FROM 11 TO 48 DO
draw char(6, x, "-")
OD;
draw char(6, 49, "|");
FOR i FROM 1 TO roz DO
INT y = 7 + 2 * (i - 1); # Data at y=7, 9, 11, 13, 15 #
IF i < roz THEN # Separator after each row except the last #
draw char(y + 1, 10, "|");
FOR x FROM 11 TO 48 DO
draw char(y + 1, x, "-")
OD;
draw char(y + 1, 49, "|")
FI
OD;
# Second Pass: Fetch and Draw Data #
FOR i FROM 1 TO roz DO
INT y = 7 + 2 * (i - 1);
IF pq get value(db, i, 1) = 0 THEN # employee, 1-based row #
data[i, 1] := result;
draw str(y, 12, result)
FI;
IF pq get value(db, i, 2) = 0 THEN # employee_id #
data[i, 2] := result;
draw str(y, 19, result)
FI;
IF pq get value(db, i, 3) = 0 THEN # start_date #
data[i, 3] := result;
draw str(y, 23, result)
FI;
IF pq get value(db, i, 4) = 0 THEN # salary #
data[i, 4] := result;
draw str(y, 30, result)
FI
OD;
# Refresh and Wait for 'q' to Quit #
curses refresh;
draw str(18, 10, "Press 'q' to quit");
curses refresh;
# After drawing the table... #
INT cursor_row := 1; # Start at first row #
draw char(7, 10, ">"); # Initial highlight #
DO
CHAR ch := curses getchar;
IF ch = "q" THEN
stop
FI;
# Placeholder for arrow keys—need to check if a68g supports KEY_UP/DOWN #
IF ch = "u" THEN # Using 'u' for up, 'd' for down as a test #
IF cursor_row > 1 THEN
draw char(7 + 2 * (cursor_row - 1), 10, "|"); # Clear old marker #
cursor_row -:= 1;
draw char(7 + 2 * (cursor_row - 1), 10, ">"); # New marker #
curses refresh
FI
ELIF ch = "d" THEN
IF cursor_row < roz THEN
draw char(7 + 2 * (cursor_row - 1), 10, "|"); # Clear old marker #
cursor_row +:= 1;
draw char(7 + 2 * (cursor_row - 1), 10, ">"); # New marker #
curses refresh
FI
FI
OD;
curses end;
print(("We've terminated curses", newline));
# Debug: Print all data after curses #
FOR i FROM 1 TO roz DO
print(("Row ", i, ": ", data[i, 1], " | ", data[i, 2], " | ", data[i, 3], " | ", data[i, 4], newline))
OD;
# Cleanup #
INT fin2 = pq finish(db);
print(("We've reached program cleanup", newline));
fin2 # success, return pq finish status #
END;
main

146
src/empdisplay4.a68 Normal file
View File

@ -0,0 +1,146 @@
PROC main = INT: BEGIN
# Postgres Setup #
FILE db;
STRING result;
STRING conninfo = "dbname=testdb user=gmgauthier password=thx1138gg host=localhost port=5432";
INT status = pq connect db(db, conninfo, result);
IF status /= 0 THEN print(("Connect failed: ", result, newline)); stop FI;
print(("We've initialized the database connection", newline));
# Query Employees #
INT qstatus = pq exec(db, "SELECT employee, employee_id, start_date, salary FROM employees ORDER BY employee_id");
IF qstatus /= 0 THEN
print(("Query failed: ", qstatus, newline));
INT fin1 = pq finish(db);
print((fin1, newline));
stop
FI;
print(("We've loaded the data from the database", newline));
# ncurses Setup #
print(("We're starting curses...", newline));
curses start; # VOID, no return to check #
INT lines = curses lines; INT cols = curses columns; # Check screen init #
IF lines = 0 OR cols = 0 THEN
curses end;
print(("ncurses failed to initialize: lines=", lines, " cols=", cols, newline));
INT fin1 = pq finish(db);
print((fin1, newline)); # suppresses the warning #
stop
FI;
curses clear;
# Border and Title (y=2, x=10, width=40, height=15) #
PROC draw char = (INT y, x, CHAR c) VOID: (
curses move(y, x); curses putchar(c)
);
PROC draw str = (INT y, x, STRING s) VOID: (
FOR i FROM 1 TO UPB s DO
draw char(y, x + i - 1, s[i])
OD
);
# Top/Bottom Border #
FOR x FROM 10 TO 49 DO
draw char(2, x, "-"); draw char(16, x, "-")
OD;
# Sides #
FOR y FROM 3 TO 15 DO
draw char(y, 10, "|"); draw char(y, 49, "|")
OD;
# Corners #
draw char(2, 10, "+"); draw char(2, 49, "+");
draw char(16, 10, "+"); draw char(16, 49, "+");
# Title (y=3) #
draw str(3, 12, "Employee Data");
# Headers (y=5) #
draw str(5, 12, "Name ID Start Salary");
# Data (y=7, 9, 11, 13, 15) with Row Separators #
INT roz = pq ntuples(db);
[roz, 4]STRING data; # Store data #
# First Pass: Draw Row Separators #
draw char(6, 10, "|"); # Header separator #
FOR x FROM 11 TO 48 DO
draw char(6, x, "-")
OD;
draw char(6, 49, "|");
FOR i FROM 1 TO roz DO
INT y = 7 + 2 * (i - 1); # Data at y=7, 9, 11, 13, 15 #
IF i < roz THEN # Separator after each row except the last #
draw char(y + 1, 10, "|");
FOR x FROM 11 TO 48 DO
draw char(y + 1, x, "-")
OD;
draw char(y + 1, 49, "|")
FI
OD;
# Second Pass: Fetch and Draw Data #
FOR i FROM 1 TO roz DO
INT y = 7 + 2 * (i - 1);
IF pq get value(db, i, 1) = 0 THEN # employee, 1-based row #
data[i, 1] := result;
draw str(y, 12, result)
FI;
IF pq get value(db, i, 2) = 0 THEN # employee_id #
data[i, 2] := result;
draw str(y, 19, result)
FI;
IF pq get value(db, i, 3) = 0 THEN # start_date #
data[i, 3] := result;
draw str(y, 23, result)
FI;
IF pq get value(db, i, 4) = 0 THEN # salary #
data[i, 4] := result;
draw str(y, 30, result)
FI
OD;
# Refresh and Wait for 'q' to Quit #
curses refresh;
draw str(18, 10, "Press 'u' for up, 'd' for down, or 'q' to quit");
curses refresh;
# Cursor Interaction #
INT cursor_row := 1; # Start at first row #
draw char(7, 10, ">"); # Initial highlight #
curses refresh; # Ensure initial marker is visible #
BOOL running := TRUE;
WHILE running DO
CHAR ch := curses getchar;
IF ch = "q" THEN
running := FALSE
ELIF ch = "u" THEN # Up #
IF cursor_row > 1 THEN
draw char(7 + 2 * (cursor_row - 1), 10, "|"); # Clear old marker #
cursor_row -:= 1;
draw char(7 + 2 * (cursor_row - 1), 10, ">"); # New marker #
curses refresh
FI
ELIF ch = "d" THEN # Down #
IF cursor_row < roz THEN
draw char(7 + 2 * (cursor_row - 1), 10, "|"); # Clear old marker #
cursor_row +:= 1;
draw char(7 + 2 * (cursor_row - 1), 10, ">"); # New marker #
curses refresh
FI
FI
OD;
curses end;
print(("We've terminated curses", newline));
# Cleanup #
INT fin2 = pq finish(db);
print(("We've reached program cleanup", newline));
fin2 # success, return pq finish status #
END;
main