kpmpgsmkii/client/src/gui/textbox.c

171 lines
5.3 KiB
C

/*
* 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 <https://www.gnu.org/licenses/>.
*
*/
#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);
}