/* * Kangaroo Punch MultiPlayer Game Server Mark II * Copyright (C) 2020-2021 Scott Duensing * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * */ #include "textbox.h" static void textboxFocusEvent(WidgetT *widget, uint8_t focused); static void textboxMouseEvent(WidgetT *widget, MouseT *mouse, uint16_t x, uint16_t y, uint8_t event); static void textboxPaint(WidgetT *widget); void textboxDel(WidgetT **widget) { TextboxT *t = (TextboxT *)*widget; if (t->title) free(t->title); if (t->value) free(t->value); free(t); t = NULL; } static void textboxFocusEvent(WidgetT *widget, uint8_t focused) { } char *textboxGetValue(TextboxT *textbox) { return textbox->value; } WidgetT *textboxInit(WidgetT *widget, uint16_t x, uint16_t y, uint16_t w, char *title) { TextboxT *t = (TextboxT *)widget; t->base.magic = MAGIC_TEXTBOX; t->base.x = x; t->base.y = y; t->base.w = w; t->base.h = fontHeightGet(_guiFont) + 4 + (_guiMetric[METRIC_TEXTBOX_VERTICAL_PADDING] * 2); t->base.delMethod = textboxDel; t->base.focusMethod = textboxFocusEvent; t->base.paintMethod = textboxPaint; t->base.mouseEventMethod = textboxMouseEvent; t->title = NULL; t->maxLength = 256; t->value = (char *)malloc(t->maxLength); t->caret = 0; if (!t->value) return NULL; t->value[0] = 0; // Visible is set in textboxSetTitle textboxSetTitle(t, title); return widget; } static void textboxMouseEvent(WidgetT *widget, MouseT *mouse, uint16_t x, uint16_t y, uint8_t event) { TextboxT *t = (TextboxT *)widget; (void)x; (void)y; (void)mouse; //***TODO*** Allow dragging text cursor with mouse. } TextboxT *textboxNew(uint16_t x, uint16_t y, uint16_t w, char *title) { TextboxT *textbox = (TextboxT *)malloc(sizeof(TextboxT)); WidgetT *widget = NULL; if (!textbox) return NULL; widget = widgetInit((WidgetT *)textbox); if (!widget) { free(textbox); return NULL; } if (!textbox) return NULL; widget = widgetInit((WidgetT *)textbox); if (!widget) { free(textbox); return NULL; } textbox = (TextboxT *)textboxInit((WidgetT *)textbox, x, y, w, title); return textbox; } static void textboxPaint(WidgetT *widget) { TextboxT *t = (TextboxT *)widget; uint16_t labelWidth = (strlen(t->title) * fontWidthGet(_guiFont)) + _guiMetric[METRIC_TEXTBOX_PADDING]; uint16_t valueWidth = (t->visible * fontWidthGet(_guiFont)) + (_guiMetric[METRIC_TEXTBOX_HORIZONTAL_PADDING] * 2); char *draw = NULL; if (GUI_GET_FLAG(widget, WIDGET_FLAG_DIRTY)) { vbeSurfaceSet(t->base.surface); // Draw title. fontRender(_guiFont, t->title, _guiColor[COLOR_TEXTBOX_TEXT], _guiColor[COLOR_WINDOW_BACKGROUND], t->base.x, t->base.y + 1 + _guiMetric[METRIC_TEXTBOX_VERTICAL_PADDING]); // Draw outline of textbox. guiDrawHighlightFrame( t->base.x + labelWidth, t->base.y, t->base.x + labelWidth + valueWidth + 2, t->base.y + t->base.h, _guiColor[COLOR_TEXTBOX_SHADOW], _guiColor[COLOR_TEXTBOX_HIGHLIGHT]); guiDrawRectangle( t->base.x + labelWidth + 1, t->base.y + 1, t->base.x + labelWidth + valueWidth + 1, t->base.y + t->base.h - 1, _guiColor[COLOR_WINDOW_BACKGROUND]); // Draw background. guiDrawRectangleFilled(t->base.x + labelWidth + 2, t->base.y + 2, t->base.x + labelWidth + valueWidth, t->base.y + t->base.h - 2, _guiColor[COLOR_TEXTBOX_BACKGROUND]); // Draw value. ***TODO*** This needs much more! draw = strdup(t->value); if (strlen(t->value) > t->visible) draw[t->visible] = 0; fontRender(_guiFont, draw, _guiColor[COLOR_TEXTBOX_TEXT], _guiColor[COLOR_TEXTBOX_BACKGROUND], t->base.x + labelWidth + 2 + _guiMetric[METRIC_TEXTBOX_HORIZONTAL_PADDING], t->base.y + 2 + _guiMetric[METRIC_TEXTBOX_VERTICAL_PADDING]); free(draw); GUI_CLEAR_FLAG(widget, WIDGET_FLAG_DIRTY); } } void textboxSetValue(TextboxT *textbox, char *value) { // Copy it & truncate if needed. strncpy(textbox->value, value, textbox->maxLength - 1); GUI_SET_FLAG((WidgetT *)textbox, WIDGET_FLAG_DIRTY); } void textboxSetMaxLength(TextboxT *textbox, uint16_t length) { char *temp = strdup(textbox->value); free(textbox->value); textbox->maxLength = length + 1; textbox->value = (char *)malloc(textbox->maxLength); textboxSetValue(textbox, temp); free(temp); } void textboxSetTitle(TextboxT *textbox, char *title) { if (textbox->title) free(textbox->title); textbox->title = strdup(title); // Figure out how many characters we have room to display. textbox->visible = (textbox->base.w - ((strlen(title) * fontWidthGet(_guiFont)) + _guiMetric[METRIC_TEXTBOX_PADDING] + 4 + (_guiMetric[METRIC_TEXTBOX_HORIZONTAL_PADDING] * 2))) / fontWidthGet(_guiFont); GUI_SET_FLAG((WidgetT *)textbox, WIDGET_FLAG_DIRTY); }