jcs
/subtext
/amendments
/45
util: Make vwarn and friends use a custom dialog without needing a Res
This way we can use panic() and things in new tiny projects without
having to build a resource file first
jcs made amendment 45 over 2 years ago
--- util.c Mon Dec 20 21:35:17 2021
+++ util.c Tue Jan 4 13:56:08 2022
@@ -22,18 +22,30 @@
#include "util.h"
/* ALRT resources */
-#define ERROR_ALERT_ID 129
#define ASK_ALERT_ID 130
-#define ERROR_STRING_SIZE 1024
+#define ERROR_STRING_SIZE 1024
+/* basic DITL with an ok button (1), text area (2), and icon (3) */
+#define ALERT_DITL_ICON 3
+static char alert_ditl[] = {
+ 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46,
+ 0x00, 0xE6, 0x00, 0x5A, 0x01, 0x20, 0x04, 0x02,
+ 0x4F, 0x4B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A,
+ 0x00, 0x32, 0x00, 0x40, 0x01, 0x21, 0x08, 0x02,
+ 0x5E, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A,
+ 0x00, 0x0A, 0x00, 0x2A, 0x00, 0x2A, 0xA0, 0x02,
+ 0x00, 0x02
+};
+static Handle alert_ditl_h;
+
enum {
STOP_ALERT,
CAUTION_ALERT,
NOTE_ALERT
};
-Handle err_str;
+Handle err_str = NULL;
static TEHandle track_control_te = NULL;
void vwarn(short alert_func, const char *format, va_list ap);
@@ -177,35 +189,67 @@ err_init(void)
SysBeep(20);
ExitToShell();
}
+
+ alert_ditl_h = xNewHandle(sizeof(alert_ditl));
+ HLock(alert_ditl_h);
+ memcpy(*alert_ditl_h, alert_ditl, sizeof(alert_ditl));
+ HUnlock(alert_ditl_h);
}
void
vwarn(short alert_func, const char *format, va_list ap)
{
- size_t len;
- short quit = 0;
- WindowPtr win;
+ Rect bounds, irect;
+ short quit = 0, height, width, hit;
+ WindowPtr win, dialog;
+ OSType itype;
+ Handle ihandle;
GetPort(&win);
+ if (err_str == NULL)
+ err_init();
HLock(err_str);
- len = vsprintf(*err_str, format, ap);
- if (len >= ERROR_STRING_SIZE) {
- sprintf(*err_str, "raise_error string overflow!");
- quit = 1;
- }
+ vsnprintf(*err_str, ERROR_STRING_SIZE, format, ap);
+ width = 300;
+ height = 100;
+ bounds.left = (screenBits.bounds.right - width) / 2;
+ bounds.right = bounds.left + width;
+ bounds.top = GetMBarHeight() +
+ ((screenBits.bounds.bottom - height) / 2.5);
+ bounds.bottom = bounds.top + height;
+
ParamText(CtoPstr(*err_str), "\p", "\p", "\p");
+
+ dialog = NewDialog(nil, &bounds, "\p", false, dBoxProc,
+ (WindowPtr)-1L, false, 0, alert_ditl_h);
+
+#if 0
+ /* XXX: why doesn't changing this work? */
+ GetDItem(dialog, ALERT_DITL_ICON, &itype, &ihandle, &irect);
switch (alert_func) {
case CAUTION_ALERT:
- CautionAlert(ERROR_ALERT_ID, nil);
+ ihandle = GetIcon(cautionIcon);
break;
case NOTE_ALERT:
- NoteAlert(ERROR_ALERT_ID, nil);
+ ihandle = GetIcon(noteIcon);
break;
default:
- StopAlert(ERROR_ALERT_ID, nil);
+ ihandle = GetIcon(stopIcon);
}
+ ihandle = GetIcon(cautionIcon);
+ SetDItem(dialog, ALERT_DITL_ICON, itype, ihandle, &irect);
+#endif
+
+ ShowWindow(dialog);
+ for (;;) {
+ ModalDialog(0, &hit);
+ if (hit == ok)
+ break;
+ }
+ DisposDialog(dialog);
+
HUnlock(err_str);
SetPort(win);