feat: message box dynamic sizing, documentation page updates
This commit is contained in:
1 parent
8c9ba7d0be
commit
a6342be15a
6 files changed
+101
-25
No files matched your search
@@ -210,6 +210,48 @@ bool is_space(char ch) {
|
||||
return ch == ' ' || ch == '\t' || ch == '\r';
|
||||
}
|
||||
|
||||
int clamp_int(int value, int min_value, int max_value) {
|
||||
if (value < min_value) return min_value;
|
||||
if (value > max_value) return max_value;
|
||||
return value;
|
||||
}
|
||||
|
||||
int button_row_width(const MessageBoxState* st) {
|
||||
if (!st || st->button_count <= 0) return 0;
|
||||
int total_w = st->button_count * messagebox::BUTTON_W;
|
||||
if (st->button_count > 1)
|
||||
total_w += (st->button_count - 1) * messagebox::BUTTON_GAP;
|
||||
return total_w;
|
||||
}
|
||||
|
||||
int widest_explicit_message_line(const MessageBoxState* st, int max_px) {
|
||||
if (!st || !st->text[0]) return 0;
|
||||
|
||||
char line[messagebox::MAX_LINE_LEN] = {};
|
||||
int line_len = 0;
|
||||
int widest = 0;
|
||||
|
||||
for (const char* p = st->text; ; p++) {
|
||||
char ch = *p;
|
||||
bool at_end = ch == '\0';
|
||||
if (at_end || ch == '\n') {
|
||||
line[line_len] = '\0';
|
||||
int width = text_width(line);
|
||||
if (width > widest) widest = width;
|
||||
line_len = 0;
|
||||
line[0] = '\0';
|
||||
if (at_end) break;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (line_len >= messagebox::MAX_LINE_LEN - 1)
|
||||
return max_px;
|
||||
line[line_len++] = ch;
|
||||
}
|
||||
|
||||
return widest > max_px ? max_px : widest;
|
||||
}
|
||||
|
||||
void wrap_message(MessageBoxState* st, int max_px) {
|
||||
if (!st) return;
|
||||
if (max_px < 40) max_px = 40;
|
||||
@@ -267,11 +309,12 @@ MessageBoxLayout message_layout(const MessageBoxState* st) {
|
||||
lo.button_count = st ? st->button_count : 0;
|
||||
lo.footer_rect = {0, g_app.win.height - messagebox::FOOTER_H, g_app.win.width, messagebox::FOOTER_H};
|
||||
|
||||
lo.text_rect = {20, 24, g_app.win.width - 40, lo.footer_rect.y - 32};
|
||||
lo.text_rect = {messagebox::TEXT_X, messagebox::TEXT_Y,
|
||||
g_app.win.width - messagebox::TEXT_X * 2,
|
||||
lo.footer_rect.y - messagebox::TEXT_Y - messagebox::TEXT_BOTTOM_GAP};
|
||||
|
||||
int total_w = lo.button_count * messagebox::BUTTON_W;
|
||||
if (lo.button_count > 1) total_w += (lo.button_count - 1) * messagebox::BUTTON_GAP;
|
||||
int x = g_app.win.width - 16 - total_w;
|
||||
int total_w = button_row_width(st);
|
||||
int x = g_app.win.width - messagebox::BUTTON_RIGHT_PAD - total_w;
|
||||
int y = lo.footer_rect.y + (messagebox::FOOTER_H - messagebox::BUTTON_H) / 2;
|
||||
for (int i = 0; i < lo.button_count && i < messagebox::MAX_BUTTONS; i++) {
|
||||
lo.buttons[i] = {x, y, messagebox::BUTTON_W, messagebox::BUTTON_H};
|
||||
@@ -387,7 +430,34 @@ void init(const char* message, uint8_t buttons, uint8_t default_choice) {
|
||||
configure_buttons(st);
|
||||
if (!has_choice(st, st->default_choice))
|
||||
st->default_choice = default_choice_for(st->buttons);
|
||||
wrap_message(st, MESSAGE_INIT_W - 40);
|
||||
wrap_message(st, messagebox::MESSAGE_MIN_W - messagebox::TEXT_X * 2);
|
||||
}
|
||||
|
||||
void preferred_size(const char* title, int* out_w, int* out_h) {
|
||||
MessageBoxState* st = &g_message;
|
||||
|
||||
int max_text_w = messagebox::MESSAGE_MAX_W - messagebox::TEXT_X * 2;
|
||||
int desired_text_w = widest_explicit_message_line(st, max_text_w);
|
||||
if (title && title[0]) {
|
||||
int title_w = text_width(title) + 120;
|
||||
if (title_w > desired_text_w) desired_text_w = title_w;
|
||||
}
|
||||
|
||||
int desired_w = desired_text_w + messagebox::TEXT_X * 2;
|
||||
int buttons_w = button_row_width(st) + messagebox::BUTTON_RIGHT_PAD * 2;
|
||||
if (buttons_w > desired_w) desired_w = buttons_w;
|
||||
desired_w = clamp_int(desired_w, messagebox::MESSAGE_MIN_W, messagebox::MESSAGE_MAX_W);
|
||||
|
||||
wrap_message(st, desired_w - messagebox::TEXT_X * 2);
|
||||
|
||||
int line_h = system_font_height() + 5;
|
||||
int text_h = st->line_count > 0 ? st->line_count * line_h : line_h;
|
||||
int desired_h = messagebox::TEXT_Y + text_h + messagebox::TEXT_BOTTOM_GAP +
|
||||
messagebox::FOOTER_H;
|
||||
desired_h = clamp_int(desired_h, messagebox::MESSAGE_MIN_H, messagebox::MESSAGE_MAX_H);
|
||||
|
||||
if (out_w) *out_w = desired_w;
|
||||
if (out_h) *out_h = desired_h;
|
||||
}
|
||||
|
||||
void draw() {
|
||||
|
||||
Reference in new issue
Block a user