ref: 75db9e5e065040075706b9a6c102b04d1b43d130
parent: aaeae6a3803aebe2a3bbc0783527b1b28aded69f
author: glenda <glenda@krsna>
date: Sat Aug 16 20:56:28 EDT 2025
ctl-interface
--- a/fc.c
+++ b/fc.c
@@ -5,6 +5,7 @@
#include <keyboard.h>
#include <bio.h>
#include <ctype.h>
+#define CTLFILE "/tmp/fc.ctl"
enum {
MAXBOXES = 300,
@@ -104,11 +105,11 @@
int needredraw;
int gridsnap;
int gridsize;
- int emoji_pos; /* Current x position */
- int emoji_frame; /* Animation frame */
+ int emoji_pos;
+ int emoji_frame;
int emoji_dir; /* Direction: 1=right, -1=left */
- char *emoji_frames[4]; /* ASCII emoji frames */
- int emoji_enabled; /* Toggle emoji display */
+ char *emoji_frames[4];
+ int emoji_enabled;
} sheet;
typedef struct BoxType BoxType;
@@ -181,6 +182,13 @@
int condition;
};
+typedef struct CommandHandler CommandHandler;
+struct CommandHandler {
+ char *name;
+ int minargs;
+ void (*execute)(char **args, int nargs);
+};
+
Image *colors[6];
Image *boxbg;
Image *boxselected;
@@ -214,6 +222,11 @@
void cmd_start_label(void);
void cmd_toggle_grid(void);
void cmd_delete_box(void);
+void cmd_cycle_emoji(void);
+void ctl_addbox(char**, int);
+void ctl_load(char**, int);
+void ctl_save(char**, int);
+void ctl_quit(char**, int);
void draw_background(void);
void draw_grid_lines(void);
void draw_all_boxes(void);
@@ -221,7 +234,6 @@
void init_emoji(void);
void draw_emoji_banner(void);
void cmd_toggle_emoji(void);
-void cmd_cycle_emoji(void);
int cistrcmp(char *s1, char *s2);
int tokenize_formula(char *formula, Token *tokens, int maxtokens);
int cellref_lookup(char *ref);
@@ -315,6 +327,14 @@
{nil, 0}
};
+CommandHandler cmd_handlers[] = {
+ {"addbox", 2, ctl_addbox},
+ {"load", 1, ctl_load},
+ {"save", 1, ctl_save},
+ {"quit", 0, ctl_quit},
+ {nil, 0, nil}
+};
+
char *happy_faces[] = {
"^_^",
"^o^",
@@ -2016,8 +2036,100 @@
USED(m);
}
+void
+ctl_addbox(char **args, int nargs)
+{
+ Point p = Pt(atoi(args[0]), atoi(args[1]));
+ int idx = addbox(p);
+
+ if(idx >= 0 && nargs > 2) {
+ strncpy(sheet.boxes[idx].formula, args[2], MAXFORMULA-1);
+ sheet.boxes[idx].formula[MAXFORMULA-1] = '\0';
+
+ BoxType *bt = &boxtypes[sheet.boxes[idx].type];
+ if(bt->parse) bt->parse(&sheet.boxes[idx]);
+ if(bt->eval) bt->eval(&sheet.boxes[idx]);
+
+ recalc_all();
+ }
+
+ if(idx >= 0 && nargs > 3) {
+ strncpy(sheet.boxes[idx].label, args[3], 31);
+ sheet.boxes[idx].label[31] = '\0';
+ }
+
+ sheet.needredraw = 1;
+}
void
+ctl_load(char **args, int nargs)
+{
+ if(nargs >= 1) {
+ load(args[0]);
+ recalc_all();
+ sheet.needredraw = 1;
+ }
+}
+
+void
+ctl_save(char **args, int nargs)
+{
+ if(nargs >= 1) {
+ save(args[0]);
+ }
+}
+
+void
+ctl_quit(char **args, int nargs)
+{
+ USED(args); USED(nargs);
+ cmd_quit();
+}
+
+void
+check_ctl_file(void)
+{
+ int fd, nt;
+
+ fd = open(CTLFILE, OREAD);
+ if(fd < 0) {
+ fprint(2, "cannot open control file\n");
+ return;
+ }
+
+ Biobuf bin;
+ Binit(&bin, fd, OREAD);
+ char *line;
+
+ while((line = Brdline(&bin, '\n'))) {
+ line[Blinelen(&bin)-1] = '\0';
+
+ char *tokens[10];
+ nt = tokenize(line, tokens, nelem(tokens));
+ if(nt == 0) continue;
+
+ CommandHandler *h;
+ for(h = cmd_handlers; h->name; h++) {
+ if(strcmp(tokens[0], h->name) == 0) {
+ if(nt-1 < h->minargs) {
+ fprint(2, "%s: needs %d arguments\n",
+ h->name, h->minargs);
+ } else {
+ h->execute(&tokens[1], nt-1);
+ }
+ break;
+ }
+ }
+ }
+
+ Bterm(&bin);
+ close(fd);
+
+ fd = create(CTLFILE, OWRITE, 0644);
+ if(fd >= 0) close(fd);
+}
+
+void
eresized(int new)
{
if(new && getwindow(display, Refnone) < 0)
@@ -2043,6 +2155,9 @@
einit(Emouse | Ekeyboard);
eresized(0);
+ int ctlfd = create(CTLFILE, OWRITE, 0644);
+ if(ctlfd >= 0) close(ctlfd);
+
memset(&sheet, 0, sizeof(sheet));
sheet.selected = -1;
sheet.editing = -1;
@@ -2053,7 +2168,8 @@
sheet.gridsnap = 1;
init_emoji();
redraw();
-
+
+
for(;;){
switch(event(&e)){
case Emouse:
@@ -2066,7 +2182,10 @@
}
ticks++;
- if(ticks % 30 == 0) { /* Adjust for speed */
+ if(ticks % 200 == 0) {
+ check_ctl_file();
+ }
+ if(ticks % 30 == 0) { /* Adjust for emoji speed */
sheet.needredraw = 1;
}
--
⑨