/* * EEZ Modular Firmware * Copyright (C) 2015-present, Envox d.o.o. * * 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 #include #include #include #include namespace eez { namespace gui { enum { DISPLAY_OPTION_ALL = 0, DISPLAY_OPTION_INTEGER = 1, DISPLAY_OPTION_FRACTION = 2, DISPLAY_OPTION_FRACTION_AND_UNIT = 3, DISPLAY_OPTION_UNIT = 4, DISPLAY_OPTION_INTEGER_AND_FRACTION = 5 }; int findStartOfFraction(char *text) { int i; for (i = 0; text[i] && (text[i] == '<' || text[i] == ' ' || text[i] == '-' || (text[i] >= '0' && text[i] <= '9')); i++); return i; } int findStartOfUnit(char *text, int i) { for (i = 0; text[i] && (text[i] == '<' || text[i] == ' ' || text[i] == '-' || (text[i] >= '0' && text[i] <= '9') || text[i] == '.'); i++); return i; } bool DisplayDataWidgetState::updateState() { WIDGET_STATE_START(DisplayDataWidget); const Style *style = getStyle(g_hooks.overrideStyle(widgetCursor, widget->style)); WIDGET_STATE(flags.active, g_isActiveWidget); WIDGET_STATE(flags.focused, isFocusWidget(widgetCursor)); WIDGET_STATE(flags.blinking, g_isBlinkTime && isBlinking(widgetCursor, widget->data)); bool refreshData = true; auto newData = get(widgetCursor, widget->data); auto currentTime = millis(); if (hasPreviousState && data != newData) { uint32_t refreshRate = getTextRefreshRate(widgetCursor, widget->data); if (refreshRate != 0 && currentTime - dataRefreshLastTime < refreshRate) { refreshData = false; } } if (refreshData) { WIDGET_STATE(data, newData); dataRefreshLastTime = currentTime; } WIDGET_STATE(color, flags.focused ? style->focusColor : getColor(widgetCursor, widget->data, style)); WIDGET_STATE(backgroundColor, flags.focused ? style->focusBackgroundColor : getBackgroundColor(widgetCursor, widget->data, style)); WIDGET_STATE(activeColor, flags.focused ? style->focusBackgroundColor : getActiveColor(widgetCursor, widget->data, style)); WIDGET_STATE(activeBackgroundColor, flags.focused ? style->focusColor : getActiveBackgroundColor(widgetCursor, widget->data, style)); bool cursorVisible = millis() % (2 * CONF_GUI_TEXT_CURSOR_BLINK_TIME_MS) < CONF_GUI_TEXT_CURSOR_BLINK_TIME_MS; WIDGET_STATE(cursorPosition, cursorVisible ? getTextCursorPosition(widgetCursor, widget->data) : -1); WIDGET_STATE(xScroll, getXScroll(widgetCursor)); WIDGET_STATE_END() } void DisplayDataWidgetState::render() { const WidgetCursor &widgetCursor = g_widgetCursor; auto widget = (const DisplayDataWidget *)widgetCursor.widget; const Style *style = getStyle(g_hooks.overrideStyle(widgetCursor, widget->style)); char text[64]; data.toText(text, sizeof(text)); char *start = text; int length = -1; if (widget->displayOption != DISPLAY_OPTION_ALL) { if (data.getType() == VALUE_TYPE_FLOAT) { if (widget->displayOption == DISPLAY_OPTION_INTEGER) { int i = findStartOfFraction(text); text[i] = 0; } else if (widget->displayOption == DISPLAY_OPTION_FRACTION) { int i = findStartOfFraction(text); start = text + i; } else if (widget->displayOption == DISPLAY_OPTION_FRACTION_AND_UNIT) { int i = findStartOfFraction(text); int k = findStartOfUnit(text, i); if (i < k) { start = text + i; text[k] = 0; } else { stringCopy(text, sizeof(text), ".0"); } } else if (widget->displayOption == DISPLAY_OPTION_UNIT) { int i = findStartOfUnit(text, 0); start = text + i; } else if (widget->displayOption == DISPLAY_OPTION_INTEGER_AND_FRACTION) { int i = findStartOfUnit(text, 0); text[i] = 0; } // trim left while (*start && *start == ' ') { start++; } // trim right length = strlen(start); if (length > 0 && start[length - 1] == ' ') { length--; } } else { if ( widget->displayOption != DISPLAY_OPTION_INTEGER && widget->displayOption != DISPLAY_OPTION_INTEGER_AND_FRACTION ) { *text = 0; } } } drawText( start, length, widgetCursor.x, widgetCursor.y, widgetCursor.w, widgetCursor.h, style, flags.active, flags.blinking, false, &color, &backgroundColor, &activeColor, &activeBackgroundColor, data.getType() == VALUE_TYPE_FLOAT #if OPTION_KEYPAD || widget->data == DATA_ID_KEYPAD_EDIT_UNIT #endif , // useSmallerFontIfDoesNotFit cursorPosition, xScroll ); } int DISPLAY_DATA_getCharIndexAtPosition(int xPos, const WidgetCursor &widgetCursor) { auto widget = (const DisplayDataWidget *)widgetCursor.widget; const Style *style = getStyle(g_hooks.overrideStyle(widgetCursor, widget->style)); char text[64]; Value data = get(widgetCursor, widget->data); data.toText(text, sizeof(text)); char *start = text; if (widget->displayOption == DISPLAY_OPTION_INTEGER) { int i = findStartOfFraction(text); text[i] = 0; } else if (widget->displayOption == DISPLAY_OPTION_FRACTION) { int i = findStartOfFraction(text); start = text + i; } else if (widget->displayOption == DISPLAY_OPTION_FRACTION_AND_UNIT) { int i = findStartOfFraction(text); int k = findStartOfUnit(text, i); if (i < k) { start = text + i; text[k] = 0; } else { stringCopy(text, sizeof(text), ".0"); } } else if (widget->displayOption == DISPLAY_OPTION_UNIT) { int i = findStartOfUnit(text, 0); start = text + i; } else if (widget->displayOption == DISPLAY_OPTION_INTEGER_AND_FRACTION) { int i = findStartOfUnit(text, 0); text[i] = 0; } // trim left while (*start && *start == ' ') { start++; } // trim right int length = strlen(start); while (length > 0 && start[length - 1] == ' ') { length--; } int xScroll = getXScroll(widgetCursor); return getCharIndexAtPosition(xPos, start, length, widgetCursor.x - xScroll, widgetCursor.y, widgetCursor.w, widgetCursor.h, style); } int DISPLAY_DATA_getCursorXPosition(int cursorPosition, const WidgetCursor &widgetCursor) { auto widget = (const DisplayDataWidget *)widgetCursor.widget; const Style *style = getStyle(g_hooks.overrideStyle(widgetCursor, widget->style)); char text[64]; Value data = get(widgetCursor, widget->data); data.toText(text, sizeof(text)); char *start = text; if (widget->displayOption == DISPLAY_OPTION_INTEGER) { int i = findStartOfFraction(text); text[i] = 0; } else if (widget->displayOption == DISPLAY_OPTION_FRACTION) { int i = findStartOfFraction(text); start = text + i; } else if (widget->displayOption == DISPLAY_OPTION_FRACTION_AND_UNIT) { int i = findStartOfFraction(text); int k = findStartOfUnit(text, i); if (i < k) { start = text + i; text[k] = 0; } else { stringCopy(text, sizeof(text), ".0"); } } else if (widget->displayOption == DISPLAY_OPTION_UNIT) { int i = findStartOfUnit(text, 0); start = text + i; } else if (widget->displayOption == DISPLAY_OPTION_INTEGER_AND_FRACTION) { int i = findStartOfUnit(text, 0); text[i] = 0; } // trim left while (*start && *start == ' ') { start++; } // trim right int length = strlen(start); while (length > 0 && start[length - 1] == ' ') { length--; } return getCursorXPosition(cursorPosition, start, length, widgetCursor.x, widgetCursor.y, widgetCursor.w, widgetCursor.h, style); } } // namespace gui } // namespace eez