jcs
/subtext
/amendments
/73
main+console: Import new focusable code from wallops
jcs made amendment 73 over 2 years ago
--- console.c Thu Jan 27 13:41:36 2022
+++ console.c Mon Feb 14 15:16:20 2022
@@ -94,9 +94,9 @@ console_init(void)
focusable->key_down = console_key_down;
focusable->close = console_close;
console->focusable = focusable;
-
- SetPort(console->win);
- show_focusable(focusable);
+ add_focusable(focusable);
+ TextFont(monaco);
+ TextSize(9);
console->session = session_create("console", "console",
&console_node_funcs);
@@ -106,9 +106,6 @@ console_init(void)
console->session->tspeed = 19200;
strlcpy(console->session->autologin_username, "sysop",
sizeof(console->session->autologin_username));
-
- TextFont(monaco);
- TextSize(9);
return console;
}
--- main.c Sat Jan 29 18:46:06 2022
+++ main.c Mon Feb 14 15:12:40 2022
@@ -30,11 +30,11 @@
MenuHandle file_menu;
short quitting = 0;
struct db *db = NULL;
-struct focusable *cur_focusable = NULL;
-struct focusable *last_focusable = NULL;
+struct focusable **focusables = NULL;
+short nfocusables = 0;
-short handle_menu(long menu_id);
-void update_menu(void);
+bool handle_menu(long menu_id);
+void handle_exit(void);
int
main(void)
@@ -45,10 +45,12 @@ main(void)
WindowPtr event_win;
GrafPtr old_port;
AppFile finder_file;
+ struct focusable *found_focusable;
short event_in, n, finder_action, finder_count;
- char key, iters;
+ char key;
uthread_init();
+ _atexit(handle_exit);
InitGraf(&thePort);
InitFonts();
@@ -69,7 +71,6 @@ main(void)
if (!(file_menu = GetMHandle(FILE_MENU_ID)))
panic("no file menu");
InsertMenu(GetMenu(VIEWS_SUBMENU_ID), -1);
- update_menu();
DrawMenuBar();
/* see if we were started by double-clicking a .bbs file */
@@ -92,30 +93,45 @@ main(void)
if (db->config.telnet_port)
telnet_init();
- iters = 0;
while (!quitting) {
if (db->config.telnet_port)
telnet_idle();
-
+
uthread_coordinate();
SystemTask();
if (!GetNextEvent(everyEvent, &event))
continue;
-
+
+ if (event.what != nullEvent) {
+ event_in = FindWindow(event.where, &event_win);
+ found_focusable = NULL;
+ for (n = 0; n < nfocusables; n++) {
+ if (focusables[n]->win == event_win) {
+ found_focusable = focusables[n];
+ break;
+ }
+ }
+ }
+
switch (event.what) {
+ case nullEvent:
+ for (n = 0; n < nfocusables; n++) {
+ if (focusables[n]->idle)
+ focusables[n]->idle(focusables[n], &event);
+ }
+ break;
case keyDown:
case autoKey:
key = event.message & charCodeMask;
if ((event.modifiers & cmdKey) != 0 &&
- handle_menu(MenuKey(key)) == 1)
+ handle_menu(MenuKey(key)) == true)
break;
- if (cur_focusable && cur_focusable->key_down)
- cur_focusable->key_down(cur_focusable, &event);
+ if (nfocusables && focusables[0]->visible &&
+ focusables[0]->key_down)
+ focusables[0]->key_down(focusables[0], &event);
break;
- case mouseDown:
- event_in = FindWindow(event.where, &event_win);
-
+ case mouseDown:
switch (event_in) {
case inMenuBar:
handle_menu(MenuSelect(event.where));
@@ -127,24 +143,17 @@ main(void)
DragWindow(event_win, event.where, &screenBits.bounds);
break;
case inGoAway:
- if (TrackGoAway(event_win, event.where) && cur_focusable &&
- cur_focusable->close)
- cur_focusable->close(cur_focusable, &event);
+ if (TrackGoAway(event_win, event.where) &&
+ found_focusable && found_focusable->close)
+ found_focusable->close(found_focusable, &event);
break;
case inContent:
if (event_win != FrontWindow()) {
- SelectWindow(event_win);
- if (last_focusable &&
- last_focusable->win == event_win) {
- struct focusable *fcur;
- fcur = cur_focusable;
- cur_focusable = last_focusable;
- last_focusable = fcur;
- }
+ if (found_focusable)
+ show_focusable(found_focusable);
}
- if (cur_focusable && cur_focusable->win == event_win &&
- cur_focusable->mouse_down)
- cur_focusable->mouse_down(cur_focusable, &event);
+ if (found_focusable && found_focusable->mouse_down)
+ found_focusable->mouse_down(found_focusable, &event);
break;
}
break;
@@ -158,8 +167,8 @@ main(void)
BeginUpdate(event_win);
}
- if (cur_focusable && cur_focusable->update)
- cur_focusable->update(cur_focusable, &event);
+ if (found_focusable && found_focusable->update)
+ found_focusable->update(found_focusable, &event);
if (event.what == updateEvt) {
EndUpdate(event_win);
@@ -172,56 +181,58 @@ main(void)
switch (event.message & (1 << 0)) {
case 0:
/* suspend */
- if (cur_focusable && cur_focusable->suspend)
- cur_focusable->suspend(cur_focusable, &event);
+ for (n = 0; n < nfocusables; n++) {
+ if (focusables[n]->suspend)
+ focusables[n]->suspend(focusables[n], &event);
+ }
break;
case 1:
/* resume */
- if (cur_focusable && cur_focusable->resume)
- cur_focusable->resume(cur_focusable, &event);
+ for (n = 0; n < nfocusables; n++) {
+ if (focusables[n]->resume)
+ focusables[n]->resume(focusables[n], &event);
+ }
break;
}
}
break;
}
}
-
- db_close(db);
return 0;
}
-short
+void
+handle_exit(void)
+{
+ short n;
+
+ for (n = 0; n < nfocusables; n++) {
+ if (focusables[n]->atexit)
+ focusables[n]->atexit(focusables[n]);
+ }
+
+ telnet_atexit();
+ db_close(db);
+}
+
+bool
handle_menu(long menu_id)
{
- short ret = 0;
+ bool ret = false;
+ bool quit = false;
+ size_t n;
switch (HiWord(menu_id)) {
case APPLE_MENU_ID:
switch (LoWord(menu_id)) {
case APPLE_MENU_ABOUT_ID: {
- VersRecHndl vers;
char vers_s[255];
- char short_vers[255] = { 0 };
- short vlen;
- if ((vers = (VersRecHndl)GetResource('vers', 1))) {
- /*
- * vers "long version string" is a pascal string after the
- * short version pascal string
- */
- HLock(vers);
- vlen = (*vers)->shortVersion[0];
- memcpy(short_vers, (*vers)->shortVersion + vlen + 1,
- sizeof((*vers)->shortVersion) - vlen - 1);
- PtoCstr(short_vers);
- sprintf(vers_s, "%s %s", PROGRAM_NAME, short_vers);
- ReleaseResource(vers);
- note("%s", vers_s);
- } else
- warnx("Can't find version number!");
+ sprintf(vers_s, "%s %s", PROGRAM_NAME, get_version(true));
+ note("%s", vers_s);
- ret = 1;
+ ret = true;
break;
}
}
@@ -229,13 +240,24 @@ handle_menu(long menu_id)
case FILE_MENU_ID:
switch (LoWord(menu_id)) {
case FILE_MENU_QUIT_ID:
- quitting = 1;
- ret = 1;
+ ret = true;
+ quit = true;
+ for (n = 0; n < nfocusables; n++) {
+ if (focusables[n] && focusables[n]->quit &&
+ !focusables[n]->quit(focusables[n])) {
+ quit = false;
+ break;
+ }
+ }
+ if (quit)
+ ExitToShell();
break;
}
break;
case EDIT_MENU_ID:
- /* let each focusable handle this */
+ if (nfocusables && focusables[0]->visible && focusables[0]->menu)
+ ret = focusables[0]->menu(focusables[0], HiWord(menu_id),
+ LoWord(menu_id));
break;
case BBS_MENU_ID:
switch (LoWord(menu_id)) {
@@ -269,29 +291,86 @@ handle_menu(long menu_id)
}
void
-update_menu(void)
+add_focusable(struct focusable *focusable)
{
+ nfocusables++;
+ focusables = xreallocarray(focusables, sizeof(Ptr), nfocusables);
+
+ if (nfocusables > 1)
+ memmove(focusables + sizeof(Ptr), focusables,
+ sizeof(Ptr) * (nfocusables - 1));
+
+ focusables[0] = focusable;
+
+ show_focusable(focusable);
}
void
show_focusable(struct focusable *focusable)
{
- if (cur_focusable)
- last_focusable = cur_focusable;
- cur_focusable = focusable;
+ struct focusable *last, *tmp;
+ short n;
+ if (nfocusables > 1 && focusables[0] != focusable) {
+ last = focusables[0];
+ focusables[0] = focusable;
+ for (n = 1; n < nfocusables; n++) {
+ tmp = focusables[n];
+ focusables[n] = last;
+ last = tmp;
+ if (last == focusable)
+ break;
+ }
+ }
+
+ focusable->visible = true;
ShowWindow(focusable->win);
+ SelectWindow(focusable->win);
+ SetPort(focusable->win);
}
void
close_focusable(struct focusable *focusable)
{
- if (cur_focusable == focusable) {
- cur_focusable = NULL;
- if (last_focusable)
- cur_focusable = last_focusable;
- } else if (last_focusable == focusable)
- last_focusable = NULL;
+ short n;
- CloseWindow(focusable->win);
+ if (focusable->visible)
+ CloseWindow(focusable->win);
+
+ for (n = 0; n < nfocusables; n++) {
+ if (focusables[n] == focusable) {
+ for (; n < nfocusables - 1; n++)
+ focusables[n] = focusables[n + 1];
+ break;
+ }
+ }
+
+ nfocusables--;
+ if (nfocusables)
+ focusables = xreallocarray(focusables, sizeof(Ptr), nfocusables);
+ else {
+ free(focusables);
+ focusables = NULL;
+ }
+
+ if (nfocusables && focusables[0]->visible)
+ SelectWindow(focusables[0]->win);
+}
+
+void
+hide_focusable(struct focusable *focusable)
+{
+ short n;
+
+ HideWindow(focusable->win);
+ focusable->visible = false;
+
+ for (n = 0; n < nfocusables; n++) {
+ if (focusables[n] == focusable) {
+ for (; n < nfocusables - 1; n++)
+ focusables[n] = focusables[n + 1];
+ break;
+ }
+ }
+ focusables[nfocusables - 1] = focusable;
}
--- session.c Sat Jan 29 18:38:39 2022
+++ session.c Sat Jan 29 23:32:56 2022
@@ -119,7 +119,7 @@ session_run(struct uthread *uthread, void *arg)
session_flush(s);
while (!done && !s->ending) {
- session_output_string(s, "Main Menu> ");
+ session_printf(s, "{{B}}Main Menu>{{/}} ");
session_flush(s);
get_another_char:
--- subtext.h Sun Jan 23 13:43:00 2022
+++ subtext.h Thu Feb 10 15:56:15 2022
@@ -17,6 +17,8 @@
#ifndef __SUBTEXT_H__
#define __SUBTEXT_H__
+#include "util.h"
+
#define PROGRAM_NAME "Subtext"
#define MBAR_ID 128
@@ -63,18 +65,25 @@ extern MenuHandle file_menu;
struct focusable {
WindowPtr win;
+ bool visible;
void *cookie;
+ short (*wait_type)(struct focusable *focusable);
+ void (*idle)(struct focusable *focusable, EventRecord *event);
void (*update)(struct focusable *focusable, EventRecord *event);
void (*key_down)(struct focusable *focusable, EventRecord *event);
void (*mouse_down)(struct focusable *focusable, EventRecord *event);
+ bool (*menu)(struct focusable *focusable, short menu, short item);
void (*close)(struct focusable *focusable, EventRecord *event);
void (*suspend)(struct focusable *focusable, EventRecord *event);
void (*resume)(struct focusable *focusable, EventRecord *event);
+ bool (*quit)(struct focusable *focusable);
+ void (*atexit)(struct focusable *focusable);
};
-extern struct focusable *cur_focusable;
-extern struct focusable *last_focusable;
-
+extern struct focusable **focusables;
+extern short nfocusables;
+void add_focusable(struct focusable *focusable);
void show_focusable(struct focusable *focusable);
void close_focusable(struct focusable *focusable);
+void hide_focusable(struct focusable *focusable);
#endif /* __SUBTEXT_H__ */