diff options
Diffstat (limited to 'src/user/popups')
-rw-r--r-- | src/user/popups/info.c | 99 | ||||
-rw-r--r-- | src/user/popups/popup.c | 45 |
2 files changed, 144 insertions, 0 deletions
diff --git a/src/user/popups/info.c b/src/user/popups/info.c new file mode 100644 index 0000000..81a09e9 --- /dev/null +++ b/src/user/popups/info.c @@ -0,0 +1,99 @@ +#include <popups/popup.h> + +#include <libfont/fonts.h> + +#include <knob/format.h> +#include <knob/heap.h> + +#include <stdint.h> +#include <stdarg.h> + +#define BORDER_SIZE 2 +//includes border +#define PADDING 8 +#define FONT "berry" + +#define BORDER_COLOR 0x10 +#define BG_COLOR 0x07 +#define FG_COlOR 0x10 + +static const struct font_info *info_font = 0; + +static const struct key_packet info_quits[] = { + { .key_id = KEY_ESCAPE, .modifiers = NO_MODS }, + { .key_id = 0 } +}; + +void info_popup(struct popup *into, const char *msg, uint8_t fg, uint8_t bg) { + if (!info_font) + info_font = get_font(FONT); + + uint32_t w = 0, h = 1, lw = 0; + for (const char *i = msg; *i; ++i) + if (*i == '\n') { + ++h; + if (lw > w) + w = lw; + lw = 0; + } + else + ++lw; + if (lw > w) + w = lw; + + into->has_quit = false; + into->quit_binds = (struct key_packet *)info_quits; + into->free_quit_binds = false; + + const uint32_t pitch = info_font->space_width * w + 2 * PADDING; + const uint32_t height = info_font->space_height * h + 2 * PADDING; + + uint8_t *const pixbuf = get_block(pitch * height); + + for (uint32_t i = 0; i < pitch * BORDER_SIZE; ++i) + pixbuf[i] = BORDER_COLOR; + for (uint32_t y = BORDER_SIZE; y < height - BORDER_SIZE; ++y) { + for (uint32_t x = 0; x < BORDER_SIZE; ++x) + pixbuf[y * pitch + x] = BORDER_COLOR; + for (uint32_t x = pitch - BORDER_SIZE; x < pitch; ++x) + pixbuf[y * pitch + x] = BORDER_COLOR; + } + for (uint32_t i = 0; i < pitch * BORDER_SIZE; ++i) + pixbuf[(height - BORDER_SIZE) * pitch + i] = BORDER_COLOR; + + for (uint32_t y = BORDER_SIZE; y < height - BORDER_SIZE; ++y) + for (uint32_t x = BORDER_SIZE; x < pitch - BORDER_SIZE; ++x) + pixbuf[y * pitch + x] = BG_COLOR; + + uint32_t my = 0; + uint32_t mx = 0; + --msg; + while (*++msg) { + if (*msg == '\n') { + ++my; + mx = 0; + } + else { + //syslogf("calling put_char(0x%x, '%c', pixbuf + %u, %u, 0x%2x, 0x%2x)", info_font, *msg, + // (my * info_font->space_height + PADDING) * pitch + mx * info_font->space_width + PADDING, + // pitch, BG_COLOR, FG_COlOR); + put_char(info_font, *msg, pixbuf + (my * info_font->space_height + PADDING) * pitch + mx++ * info_font->space_width + PADDING, pitch, BG_COLOR, FG_COlOR); + } + } + + into->pixbuf = pixbuf; + into->handle = _new_window(pitch, height, pixbuf); +} + +void info_popupf_v(struct popup *into, const char *text, uint8_t fg, uint8_t bg, va_list args) { + char *const msg = format_v(text, args); + info_popup(into, msg, fg, bg); + free_block(msg); +} + +void info_popupf(struct popup *into, const char *text, uint8_t fg, uint8_t bg, ...) { + va_list args; + va_start(args, bg); + info_popupf_v(into, text, fg, bg, args); + va_end(args); +}
\ No newline at end of file diff --git a/src/user/popups/popup.c b/src/user/popups/popup.c new file mode 100644 index 0000000..d214f81 --- /dev/null +++ b/src/user/popups/popup.c @@ -0,0 +1,45 @@ +#include <popups/popup.h> + +#include <knob/format.h> +#include <knob/heap.h> + +#include <pland/syscall.h> + +void handle_actions(struct popup *p) { + if (p->has_quit) + return; + struct window_action a; + while (1) { + _get_win_action(p->handle, &a); + if (a.action_type == NOT_READY) + return; + if ((a.action_type == KEY_DOWN)) { + //syslogf("got key 0x%2x, 0x%3x", a.as_key.key_id, a.as_key.modifiers); + for (const struct key_packet *kp = p->quit_binds; kp->key_id; ++kp) { + //syslogf("checking against 0x%2x, 0x%3x", kp->key_id, kp->modifiers); + if ((a.as_key.key_id == kp->key_id) && (a.as_key.modifiers == kp->modifiers)) { + p->has_quit = true; + p->quit_as = a.as_key; + return; + } + } + } + } +} + +void delete_popup(struct popup *p) { + _delete_window(p->handle); + free_block(p->pixbuf); + if (p->free_quit_binds) + free_block(p->quit_binds); +} + +void make_modal(struct popup *p) { + handle_actions(p); + while (!p->has_quit) { + _wait_for_action(); + _yield_task(); + handle_actions(p); + } + delete_popup(p); +}
\ No newline at end of file |