From 0fc21c9c08bc904a1ad6cd319c014f94e5d67fae Mon Sep 17 00:00:00 2001 From: Greg Gauthier Date: Mon, 14 Apr 2025 22:31:50 +0100 Subject: [PATCH] add a cursor carat, and keys to control it --- src/empdisplay3.a68 | 154 ++++++++++++++++++++++++++++++++++++++++++++ src/empdisplay4.a68 | 146 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 300 insertions(+) create mode 100644 src/empdisplay3.a68 create mode 100644 src/empdisplay4.a68 diff --git a/src/empdisplay3.a68 b/src/empdisplay3.a68 new file mode 100644 index 0000000..333f434 --- /dev/null +++ b/src/empdisplay3.a68 @@ -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 \ No newline at end of file diff --git a/src/empdisplay4.a68 b/src/empdisplay4.a68 new file mode 100644 index 0000000..5607185 --- /dev/null +++ b/src/empdisplay4.a68 @@ -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 \ No newline at end of file