From ae548b9814e82319aec7d49925cbdc9256c9db62 Mon Sep 17 00:00:00 2001 From: Bertrand Songis Date: Sat, 5 Oct 2019 19:01:57 +0200 Subject: [PATCH] New UI continued --- radio/src/curves.cpp | 39 +++- radio/src/curves.h | 49 ++++ radio/src/datastructs.h | 14 +- radio/src/gui/128x64/model_curve_edit.cpp | 8 +- radio/src/gui/212x64/model_curve_edit.cpp | 8 +- radio/src/gui/colorlcd/curve.h | 10 +- radio/src/gui/colorlcd/curveedit.cpp | 23 +- radio/src/gui/colorlcd/curveedit.h | 9 +- radio/src/gui/colorlcd/model_curves.cpp | 213 ++++++++++++------ radio/src/gui/colorlcd/model_inputs.cpp | 4 +- .../gui/colorlcd/model_logical_switches.cpp | 22 +- radio/src/gui/colorlcd/model_mixes.cpp | 4 +- radio/src/gui/colorlcd/model_outputs.cpp | 4 +- radio/src/gui/colorlcd/model_telemetry.cpp | 2 +- radio/src/gui/colorlcd/special_functions.cpp | 4 +- radio/src/gui/common/stdlcd/model_curves.cpp | 2 +- radio/src/lua/api_model.cpp | 60 ++--- radio/src/opentx.h | 26 +-- .../conversions/conversions_216_218.cpp | 6 +- .../conversions/conversions_218_219.cpp | 2 +- .../src/storage/conversions/datastructs_218.h | 4 +- radio/src/storage/datacopy.cpp | 4 +- radio/src/storage/storage_common.cpp | 2 +- radio/src/targets/horus/libopenui_config.h | 3 + radio/src/targets/nv14/libopenui_config.h | 3 + radio/src/thirdparty/libopenui | 2 +- 26 files changed, 331 insertions(+), 196 deletions(-) create mode 100644 radio/src/curves.h diff --git a/radio/src/curves.cpp b/radio/src/curves.cpp index 865a5ed5b..5d4643888 100644 --- a/radio/src/curves.cpp +++ b/radio/src/curves.cpp @@ -21,8 +21,8 @@ #include "opentx.h" uint8_t s_curveChan; - int8_t * curveEnd[MAX_CURVES]; + void loadCurves() { bool showWarning= false; @@ -94,8 +94,35 @@ void resetCustomCurveX(int8_t * points, int noPoints) } } +void curveReset(uint8_t index) +{ + CurveHeader * curve = &g_model.curves[index]; + int8_t * points = curveAddress(index); + + memclear(points, 5 + curve->points); + + if (curve->type == CURVE_TYPE_CUSTOM) + resetCustomCurveX(points, 5 + curve->points); + + memclear(curve, sizeof(CurveHeader)); +} + +void curveMirror(uint8_t index) +{ + CurveHeader & curve = g_model.curves[index]; + int8_t * points = curveAddress(index); + + for (int i = 0; i < 5 + curve.points; i++) + points[i] = -points[i]; +} + +bool isCurveUsed(uint8_t index) +{ + return !is_memclear(&g_model.curves[index], sizeof(CurveHeader)) || !is_memclear(curveAddress(index), 5); +} + #define CUSTOM_POINT_X(points, count, idx) ((idx)==0 ? -100 : (((idx)==(count)-1) ? 100 : points[(count)+(idx)-1])) -int32_t compute_tangent(CurveInfo * crv, int8_t * points, int i) +int32_t compute_tangent(CurveHeader * crv, int8_t * points, int i) { int32_t m=0; uint8_t num_points = crv->points + 5; @@ -166,7 +193,7 @@ int32_t compute_tangent(CurveInfo * crv, int8_t * points, int i) */ int16_t hermite_spline(int16_t x, uint8_t idx) { - CurveInfo &crv = g_model.curves[idx]; + CurveHeader &crv = g_model.curves[idx]; int8_t *points = curveAddress(idx); uint8_t count = crv.points+5; bool custom = (crv.type == CURVE_TYPE_CUSTOM); @@ -211,7 +238,7 @@ int16_t hermite_spline(int16_t x, uint8_t idx) int intpol(int x, uint8_t idx) // -100, -75, -50, -25, 0 ,25 ,50, 75, 100 { - CurveInfo & crv = g_model.curves[idx]; + CurveHeader & crv = g_model.curves[idx]; int8_t * points = curveAddress(idx); uint8_t count = crv.points+5; bool custom = (crv.type == CURVE_TYPE_CUSTOM); @@ -307,7 +334,7 @@ int applyCustomCurve(int x, uint8_t idx) if (idx >= MAX_CURVES) return 0; - CurveInfo & crv = g_model.curves[idx]; + CurveHeader & crv = g_model.curves[idx]; if (crv.smooth) return hermite_spline(x, idx); else @@ -322,7 +349,7 @@ point_t getPoint(uint8_t index) point_t getPoint(uint8_t curveIndex, uint8_t index) { point_t result = {0, 0}; - CurveInfo & crv = g_model.curves[curveIndex]; + CurveHeader & crv = g_model.curves[curveIndex]; int8_t * points = curveAddress(curveIndex); bool custom = (crv.type == CURVE_TYPE_CUSTOM); uint8_t count = 5 + crv.points; diff --git a/radio/src/curves.h b/radio/src/curves.h new file mode 100644 index 000000000..e3d80ad24 --- /dev/null +++ b/radio/src/curves.h @@ -0,0 +1,49 @@ +/* + * Copyright (C) OpenTX + * + * Based on code named + * th9x - http://code.google.com/p/th9x + * er9x - http://code.google.com/p/er9x + * gruvin9x - http://code.google.com/p/gruvin9x + * + * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * 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. + */ + +#ifndef _CURVES_H_ +#define _CURVES_H_ + +enum BaseCurves { + CURVE_NONE, + CURVE_X_GT0, + CURVE_X_LT0, + CURVE_ABS_X, + CURVE_F_GT0, + CURVE_F_LT0, + CURVE_ABS_F, + CURVE_BASE +}; + +void curveReset(uint8_t index); +void curveMirror(uint8_t index); +bool isCurveUsed(uint8_t index); +void loadCurves(); +int8_t * curveAddress(uint8_t idx); +bool moveCurve(uint8_t index, int8_t shift); +int8_t getCurveX(int noPoints, int point); +void resetCustomCurveX(int8_t * points, int noPoints); +point_t getPoint(uint8_t i); +point_t getPoint(uint8_t curveIndex, uint8_t index); +int applyCustomCurve(int x, uint8_t idx); +int applyCurve(int x, CurveRef & curve); +int applyCurrentCurve(int x); + +#endif diff --git a/radio/src/datastructs.h b/radio/src/datastructs.h index c5c3458b5..7796ab5fd 100644 --- a/radio/src/datastructs.h +++ b/radio/src/datastructs.h @@ -190,7 +190,7 @@ PACK(struct FlightModeData { * Curve structure */ -PACK(struct CurveData { +PACK(struct CurveHeader { uint8_t type:1; uint8_t smooth:1; int8_t points:6; // describes number of points - 5 @@ -580,7 +580,7 @@ PACK(struct ModelData { LimitData limitData[MAX_OUTPUT_CHANNELS]; ExpoData expoData[MAX_EXPOS]; - CurveData curves[MAX_CURVES]; + CurveHeader curves[MAX_CURVES]; int8_t points[MAX_CURVE_POINTS]; LogicalSwitchData logicalSw[MAX_LOGICAL_SWITCHES]; @@ -849,7 +849,7 @@ static inline void check_struct() CHKSIZE(FrSkyLineData, 4); CHKTYPE(union TelemetryScreenData, 24); CHKSIZE(ModelHeader, 12); - CHKSIZE(CurveData, 4); + CHKSIZE(CurveHeader, 4); #elif defined(PCBTARANIS) CHKSIZE(MixData, 20); CHKSIZE(ExpoData, 17); @@ -863,7 +863,7 @@ static inline void check_struct() CHKSIZE(FrSkyLineData, 6); CHKTYPE(union TelemetryScreenData, 24); CHKSIZE(ModelHeader, 24); - CHKSIZE(CurveData, 4); + CHKSIZE(CurveHeader, 4); #elif defined(PCBHORUS) CHKSIZE(MixData, 20); CHKSIZE(ExpoData, 17); @@ -873,7 +873,7 @@ static inline void check_struct() CHKSIZE(TimerData, 16); CHKSIZE(SwashRingData, 8); CHKSIZE(ModelHeader, 31); - CHKSIZE(CurveData, 4); + CHKSIZE(CurveHeader, 4); CHKSIZE(CustomScreenData, 610); CHKSIZE(Topbar::PersistentData, 216); #elif defined(PCBNV14) @@ -889,7 +889,7 @@ static inline void check_struct() CHKSIZE(FrSkyBarData, 5); CHKSIZE(FrSkyLineData, 2); CHKSIZE(ModelHeader, 12); - CHKTYPE(CurveData, 4); + CHKTYPE(CurveHeader, 4); #else // Common for all variants CHKSIZE(LimitData, 5); @@ -897,7 +897,7 @@ static inline void check_struct() CHKSIZE(FrSkyBarData, 3); CHKSIZE(FrSkyLineData, 2); CHKSIZE(ModelHeader, 11); - CHKTYPE(CurveData, 1); + CHKTYPE(CurveHeader, 1); CHKSIZE(MixData, 9); CHKSIZE(ExpoData, 4); diff --git a/radio/src/gui/128x64/model_curve_edit.cpp b/radio/src/gui/128x64/model_curve_edit.cpp index 188f4c868..d3f7d4b85 100644 --- a/radio/src/gui/128x64/model_curve_edit.cpp +++ b/radio/src/gui/128x64/model_curve_edit.cpp @@ -50,7 +50,7 @@ void runPopupCurvePreset(event_t event) if (warningResult) { warningResult = 0; - CurveInfo & crv = g_model.curves[s_curveChan]; + CurveHeader & crv = g_model.curves[s_curveChan]; int8_t * points = curveAddress(s_curveChan); int k = 25 * reusableBuffer.curveEdit.preset; int dx = 2000 / (5+crv.points-1); @@ -71,13 +71,13 @@ void onCurveOneMenu(const char * result) POPUP_INPUT(STR_PRESET, runPopupCurvePreset); } else if (result == STR_MIRROR) { - CurveInfo & crv = g_model.curves[s_curveChan]; + CurveHeader & crv = g_model.curves[s_curveChan]; int8_t * points = curveAddress(s_curveChan); for (int i=0; i<5+crv.points; i++) points[i] = -points[i]; } else if (result == STR_CLEAR) { - CurveInfo & crv = g_model.curves[s_curveChan]; + CurveHeader & crv = g_model.curves[s_curveChan]; int8_t * points = curveAddress(s_curveChan); for (int i=0; i<5+crv.points; i++) points[i] = 0; @@ -89,7 +89,7 @@ void onCurveOneMenu(const char * result) void menuModelCurveOne(event_t event) { - CurveData & crv = g_model.curves[s_curveChan]; + CurveHeader & crv = g_model.curves[s_curveChan]; int8_t * points = curveAddress(s_curveChan); drawStringWithIndex(PSIZE(TR_MENUCURVES)*FW+FW, 0, STR_CV, s_curveChan+1); diff --git a/radio/src/gui/212x64/model_curve_edit.cpp b/radio/src/gui/212x64/model_curve_edit.cpp index 3d3b083a8..0b76153ab 100644 --- a/radio/src/gui/212x64/model_curve_edit.cpp +++ b/radio/src/gui/212x64/model_curve_edit.cpp @@ -52,7 +52,7 @@ void runPopupCurvePreset(event_t event) if (warningResult) { warningResult = 0; - CurveInfo & crv = g_model.curves[s_curveChan]; + CurveHeader & crv = g_model.curves[s_curveChan]; int8_t * points = curveAddress(s_curveChan); int k = 25 * reusableBuffer.curveEdit.preset; int dx = 2000 / (5+crv.points-1); @@ -73,13 +73,13 @@ void onCurveOneMenu(const char * result) POPUP_INPUT(STR_PRESET, runPopupCurvePreset); } else if (result == STR_MIRROR) { - CurveInfo & crv = g_model.curves[s_curveChan]; + CurveHeader & crv = g_model.curves[s_curveChan]; int8_t * points = curveAddress(s_curveChan); for (int i=0; i<5+crv.points; i++) points[i] = -points[i]; } else if (result == STR_CLEAR) { - CurveInfo & crv = g_model.curves[s_curveChan]; + CurveHeader & crv = g_model.curves[s_curveChan]; int8_t * points = curveAddress(s_curveChan); for (int i=0; i<5+crv.points; i++) points[i] = 0; @@ -92,7 +92,7 @@ void onCurveOneMenu(const char * result) void menuModelCurveOne(event_t event) { static uint8_t pointsOfs = 0; - CurveData & crv = g_model.curves[s_curveChan]; + CurveHeader & crv = g_model.curves[s_curveChan]; int8_t * points = curveAddress(s_curveChan); drawStringWithIndex(PSIZE(TR_MENUCURVES)*FW+FW, 0, "CV", s_curveChan+1); diff --git a/radio/src/gui/colorlcd/curve.h b/radio/src/gui/colorlcd/curve.h index 393d684a3..73397f420 100644 --- a/radio/src/gui/colorlcd/curve.h +++ b/radio/src/gui/colorlcd/curve.h @@ -22,17 +22,19 @@ #ifndef _CURVE_H_ #define _CURVE_H_ -#include "form.h" +#include "window.h" struct CurvePoint { point_t coords; LcdFlags flags; }; -class Curve: public FormField { +class Curve: public Window { + friend class CurveEdit; + public: Curve(Window * parent, const rect_t & rect, std::function function, std::function position=nullptr): - FormField(parent, rect, OPAQUE), + Window(parent, rect, OPAQUE), function(std::move(function)), position(std::move(position)) { @@ -52,7 +54,7 @@ class Curve: public FormField { invalidate(); } - FormField::checkEvents(); + Window::checkEvents(); } void addPoint(const point_t & point, LcdFlags flags); diff --git a/radio/src/gui/colorlcd/curveedit.cpp b/radio/src/gui/colorlcd/curveedit.cpp index 6eac55c0c..494adf7f1 100644 --- a/radio/src/gui/colorlcd/curveedit.cpp +++ b/radio/src/gui/colorlcd/curveedit.cpp @@ -23,7 +23,8 @@ #include "opentx.h" // TODO for applyCustomCurve CurveEdit::CurveEdit(Window * parent, const rect_t & rect, uint8_t index) : - Curve(parent, rect, [=](int x) -> int { + FormField(parent, rect), + preview(this, {0, 0, width(), height()}, [=](int x) -> int { return applyCustomCurve(x, index); }), index(index), @@ -34,16 +35,16 @@ CurveEdit::CurveEdit(Window * parent, const rect_t & rect, uint8_t index) : void CurveEdit::update() { - clearPoints(); - CurveInfo & curve = g_model.curves[index]; + preview.clearPoints(); + CurveHeader & curve = g_model.curves[index]; for (uint8_t i = 0; i < 5 + curve.points; i++) { if (hasFocus() && current == i) { - position = [=] () -> int { + preview.position = [=] () -> int { return getPoint(index, i).x; }; } else { - addPoint(getPoint(index, i), DEFAULT_COLOR); + preview.addPoint(getPoint(index, i), DEFAULT_COLOR); } } invalidate(); @@ -58,11 +59,11 @@ bool CurveEdit::onTouchEnd(coord_t x, coord_t y) CurveKeyboard::show(this, isCustomCurve()); - CurveInfo & curve = g_model.curves[index]; + CurveHeader & curve = g_model.curves[index]; for (int i=0; i<5 + curve.points; i++) { if (i != current) { point_t point = getPoint(index, i); - if (abs(getPointX(point.x) - x) <= 10 && abs(getPointY(point.y) - y) <= 10) { + if (abs(preview.getPointX(point.x) - x) <= 10 && abs(preview.getPointY(point.y) - y) <= 10) { current = i; update(); break; @@ -81,7 +82,7 @@ void CurveEdit::onFocusLost() void CurveEdit::next() { - if (current++ == points.size()) { + if (current++ == preview.points.size()) { current = 0; } update(); @@ -90,7 +91,7 @@ void CurveEdit::next() void CurveEdit::previous() { if (current-- == 0) { - current = points.size(); + current = preview.points.size(); } update(); } @@ -113,7 +114,7 @@ void CurveEdit::down() void CurveEdit::right() { - CurveInfo & curve = g_model.curves[index]; + CurveHeader & curve = g_model.curves[index]; if (curve.type == CURVE_TYPE_CUSTOM && current != 0 && current != curve.points + 5 - 1) { int8_t * points = curveAddress(index); int8_t * point = &points[5 + curve.points + current - 1]; @@ -126,7 +127,7 @@ void CurveEdit::right() void CurveEdit::left() { - CurveInfo & curve = g_model.curves[index]; + CurveHeader & curve = g_model.curves[index]; if (curve.type == CURVE_TYPE_CUSTOM && current != 0 && current != curve.points + 5 - 1) { int8_t * points = curveAddress(index); int8_t * point = &points[5 + curve.points + current - 1]; diff --git a/radio/src/gui/colorlcd/curveedit.h b/radio/src/gui/colorlcd/curveedit.h index 2f05d9aa2..867208f10 100644 --- a/radio/src/gui/colorlcd/curveedit.h +++ b/radio/src/gui/colorlcd/curveedit.h @@ -21,17 +21,13 @@ #ifndef _CURVEEDIT_H_ #define _CURVEEDIT_H_ +#include "form.h" #include "curve.h" -class CurveEdit: public Curve { +class CurveEdit: public FormField { public: CurveEdit(Window * parent, const rect_t & rect, uint8_t index); - void checkEvents() override - { - Curve::checkEvents(); - } - void update(); void onEvent(event_t event) override; @@ -43,6 +39,7 @@ class CurveEdit: public Curve { #endif protected: + Curve preview; uint8_t index; uint8_t current; void next(); diff --git a/radio/src/gui/colorlcd/model_curves.cpp b/radio/src/gui/colorlcd/model_curves.cpp index 6682d4507..13938195b 100644 --- a/radio/src/gui/colorlcd/model_curves.cpp +++ b/radio/src/gui/colorlcd/model_curves.cpp @@ -24,18 +24,6 @@ #define SET_DIRTY() storageDirty(EE_MODEL) -bool isCurveFilled(uint8_t index) -{ - CurveInfo &curve = g_model.curves[index]; - int8_t * points = curveAddress(index); - for (int i = 0; i < 5 + curve.points; i++) { - if (points[i] != 0) { - return true; - } - } - return false; -} - class CurveEditWindow : public Page { public: explicit CurveEditWindow(uint8_t index): @@ -52,12 +40,91 @@ class CurveEditWindow : public Page { void buildHeader(Window * window) { - new StaticText(window, {70, 4, LCD_W - 100, 20}, STR_MENUCURVE, MENU_TITLE_COLOR); + new StaticText(window, {PAGE_TITLE_LEFT, PAGE_TITLE_TOP, LCD_W - PAGE_TITLE_LEFT, PAGE_LINE_HEIGHT}, STR_MENUCURVE, MENU_TITLE_COLOR); char s[16]; strAppendStringWithIndex(s, STR_CV, index + 1); - new StaticText(window, {70, 28, LCD_W - 100, 20}, s, MENU_TITLE_COLOR); + new StaticText(window, {PAGE_TITLE_LEFT, PAGE_TITLE_TOP + PAGE_LINE_HEIGHT, LCD_W - PAGE_TITLE_LEFT, PAGE_LINE_HEIGHT}, s, MENU_TITLE_COLOR); } +#if LCD_W > LCD_H + void buildBody(Window * window) + { + coord_t curveWidth = window->height() - 2 * PAGE_PADDING; + + CurveHeader & curve = g_model.curves[index]; + int8_t * points = curveAddress(index); + + // Curve editor + curveEdit = new CurveEdit(window, { LCD_W - curveWidth - PAGE_PADDING, PAGE_PADDING, curveWidth, curveWidth}, index); + + FormGridLayout grid; + grid.setLabelWidth(PAGE_PADDING); + grid.setMarginRight(curveWidth + 2 * PAGE_PADDING); + grid.spacer(PAGE_PADDING); + + // Name + new StaticText(window, grid.getFieldSlot(), STR_NAME); + grid.nextLine(); + new TextEdit(window, grid.getFieldSlot(), curve.name, sizeof(curve.name)); + grid.nextLine(); + + // Type + new StaticText(window, grid.getFieldSlot(), STR_TYPE); + grid.nextLine(); + new Choice(window, grid.getFieldSlot(2, 0), STR_CURVE_TYPES, 0, 1, GET_DEFAULT(g_model.curves[index].type), + [=](int32_t newValue) { + CurveHeader &curve = g_model.curves[index]; + if (newValue != curve.type) { + for (int i = 1; i < 4 + curve.points; i++) { + points[i] = calcRESXto100(applyCustomCurve(calc100toRESX(-100 + i * 200 / (4 + curve.points)), index)); + } + if (moveCurve(index, newValue == CURVE_TYPE_CUSTOM ? 3 + curve.points : -3 - curve.points)) { + if (newValue == CURVE_TYPE_CUSTOM) { + resetCustomCurveX(points, 5 + curve.points); + } + curve.type = newValue; + } + SET_DIRTY(); + curveEdit->update(); + } + }); + + // Points count + auto edit = new NumberEdit(window, grid.getFieldSlot(2, 1), 2, 17, GET_DEFAULT(g_model.curves[index].points + 5), + [=](int32_t newValue) { + newValue -= 5; + CurveHeader &curve = g_model.curves[index]; + int newPoints[MAX_POINTS_PER_CURVE]; + newPoints[0] = points[0]; + newPoints[4 + newValue] = points[4 + curve.points]; + for (int i = 1; i < 4 + newValue; i++) + newPoints[i] = calcRESXto100(applyCustomCurve(-RESX + (i * 2 * RESX) / (4 + newValue), index)); + if (moveCurve(index, (newValue - curve.points) * (curve.type == CURVE_TYPE_CUSTOM ? 2 : 1))) { + for (int i = 0; i < 5 + newValue; i++) { + points[i] = newPoints[i]; + if (curve.type == CURVE_TYPE_CUSTOM && i != 0 && i != 4 + newValue) + points[5 + newValue + i - 1] = -100 + (i * 200) / (4 + newValue); + } + curve.points = newValue; + SET_DIRTY(); + curveEdit->update(); + } + }); + edit->setSuffix(STR_PTS); + grid.nextLine(); + + // Smooth + new StaticText(window, grid.getFieldSlot(), STR_SMOOTH); + grid.nextLine(); + new CheckBox(window, grid.getFieldSlot(), GET_DEFAULT(g_model.curves[index].smooth), + [=](int32_t newValue) { + g_model.curves[index].smooth = newValue; + SET_DIRTY(); + curveEdit->update(); + }); + grid.nextLine(); + } +#else void buildBody(Window * window) { FormGridLayout grid; @@ -66,7 +133,7 @@ class CurveEditWindow : public Page { grid.setLabelWidth(100); grid.spacer(20); - CurveInfo & curve = g_model.curves[index]; + CurveHeader & curve = g_model.curves[index]; int8_t * points = curveAddress(index); // Curve editor @@ -82,7 +149,7 @@ class CurveEditWindow : public Page { new StaticText(window, grid.getLabelSlot(), STR_TYPE); new Choice(window, grid.getFieldSlot(2, 0), STR_CURVE_TYPES, 0, 1, GET_DEFAULT(g_model.curves[index].type), [=](int32_t newValue) { - CurveInfo &curve = g_model.curves[index]; + CurveHeader &curve = g_model.curves[index]; if (newValue != curve.type) { for (int i = 1; i < 4 + curve.points; i++) { points[i] = calcRESXto100(applyCustomCurve(calc100toRESX(-100 + i * 200 / (4 + curve.points)), index)); @@ -102,7 +169,7 @@ class CurveEditWindow : public Page { auto edit = new NumberEdit(window, grid.getFieldSlot(2, 1), 2, 17, GET_DEFAULT(g_model.curves[index].points + 5), [=](int32_t newValue) { newValue -= 5; - CurveInfo &curve = g_model.curves[index]; + CurveHeader &curve = g_model.curves[index]; int newPoints[MAX_POINTS_PER_CURVE]; newPoints[0] = points[0]; newPoints[4 + newValue] = points[4 + curve.points]; @@ -131,8 +198,8 @@ class CurveEditWindow : public Page { curveEdit->update(); }); grid.nextLine(); - } +#endif }; class CurveButton : public Button { @@ -141,7 +208,7 @@ class CurveButton : public Button { Button(parent, rect), index(index) { - if (isCurveFilled(index)) { + if (isCurveUsed(index)) { setHeight(130); new Curve(this, {5, 5, 120, 120}, [=](int x) -> int { @@ -156,12 +223,12 @@ class CurveButton : public Button { dc->drawSolidRect(0, 0, rect.w, rect.h, 2, hasFocus() ? CHECKBOX_COLOR : DISABLE_COLOR); // curve characteristics - if (isCurveFilled(index)) { - CurveInfo &curve = g_model.curves[index]; + if (isCurveUsed(index)) { + CurveHeader &curve = g_model.curves[index]; dc->drawNumber(130, 5, 5 + curve.points, LEFT, 0, nullptr, STR_PTS); dc->drawTextAtIndex(130, 25, STR_CURVE_TYPES, curve.type); if (curve.smooth) - dc->drawText(130, 45, "Smooth"); + dc->drawText(130, 45, STR_SMOOTH); } } @@ -197,66 +264,68 @@ void ModelCurvesPage::build(FormWindow * window, int8_t focusIndex) grid.setLabelWidth(66); for (uint8_t index = 0; index < MAX_CURVES; index++) { - CurveInfo &curve = g_model.curves[index]; + CurveHeader &curve = g_model.curves[index]; int8_t * points = curveAddress(index); - // Curve label - new StaticText(window, grid.getLabelSlot(), getCurveString(1 + index), BUTTON_BACKGROUND | CENTERED); + if (isCurveUsed(index)) { + // Curve label + new StaticText(window, grid.getLabelSlot(), getCurveString(1 + index), BUTTON_BACKGROUND | CENTERED); - // Curve drawing - Button * button = new CurveButton(window, grid.getFieldSlot(), index); - button->setPressHandler([=]() -> uint8_t { - Menu * menu = new Menu(); - menu->addLine(STR_EDIT, [=]() { - editCurve(window, index); - }); - menu->addLine(STR_CURVE_PRESET, [=]() { - Menu * menu = new Menu(); - for (int angle = -45; angle <= 45; angle += 15) { - char label[16]; - strAppend(strAppendSigned(label, angle), "@"); - menu->addLine(label, [=]() { - int dx = 2000 / (5 + curve.points - 1); - for (uint8_t i = 0; i < 5 + curve.points; i++) { - int x = -1000 + i * dx; - points[i] = div_and_round(angle * x, 450); - } - if (curve.type == CURVE_TYPE_CUSTOM) { - resetCustomCurveX(points, 5 + curve.points); - } - storageDirty(EE_MODEL); - rebuild(window, index); + // Curve drawing + Button * button = new CurveButton(window, grid.getFieldSlot(), index); + button->setPressHandler([=]() -> uint8_t { + Menu * menu = new Menu(); + menu->addLine(STR_EDIT, [=]() { + editCurve(window, index); }); - } + menu->addLine(STR_CURVE_PRESET, [=]() { + Menu * menu = new Menu(); + for (int angle = -45; angle <= 45; angle += 15) { + char label[16]; + strAppend(strAppendSigned(label, angle), "@"); + menu->addLine(label, [=]() { + int dx = 2000 / (5 + curve.points - 1); + for (uint8_t i = 0; i < 5 + curve.points; i++) { + int x = -1000 + i * dx; + points[i] = div_and_round(angle * x, 450); + } + if (curve.type == CURVE_TYPE_CUSTOM) { + resetCustomCurveX(points, 5 + curve.points); + } + storageDirty(EE_MODEL); + rebuild(window, index); + }); + } + }); + menu->addLine(STR_MIRROR, [=]() { + curveMirror(index); + storageDirty(EE_MODEL); + button->invalidate(); + }); + menu->addLine(STR_CLEAR, [=]() { + curveReset(index); + storageDirty(EE_MODEL); + rebuild(window, index); + }); + return 0; }); - if (isCurveFilled(index)) { - menu->addLine(STR_MIRROR, [=]() { - for (int i = 0; i < 5 + curve.points; i++) - points[i] = -points[i]; - storageDirty(EE_MODEL); - button->invalidate(); - }); - menu->addLine(STR_CLEAR, [=]() { - for (int i = 0; i < 5 + curve.points; i++) - points[i] = 0; - if (curve.type == CURVE_TYPE_CUSTOM) - resetCustomCurveX(points, 5 + curve.points); - storageDirty(EE_MODEL); - rebuild(window, index); - }); + + if (focusIndex == index) { + button->setFocus(); } - return 0; - }); - if (focusIndex == index) { - button->setFocus(); + grid.spacer(button->height() + 5); + } + else { + auto button = new TextButton(window, grid.getLabelSlot(), getCurveString(1 + index)); + button->setPressHandler([=]() { + editCurve(window, index); + return 0; + }); + grid.spacer(button->height() + 5); } - - grid.spacer(button->height() + 5); } - grid.nextLine(); - window->setLastField(); window->setInnerHeight(grid.getWindowHeight()); } diff --git a/radio/src/gui/colorlcd/model_inputs.cpp b/radio/src/gui/colorlcd/model_inputs.cpp index d83b2cac1..493c54f3a 100644 --- a/radio/src/gui/colorlcd/model_inputs.cpp +++ b/radio/src/gui/colorlcd/model_inputs.cpp @@ -119,8 +119,8 @@ class InputEditWindow: public Page { Choice * curveTypeChoice = nullptr; void buildHeader(Window * window) { - new StaticText(window, { 50, 0, 100, 20 }, STR_MENUINPUTS, MENU_TITLE_COLOR); - new StaticText(window, { 50, FH+2, 100, 20 }, getSourceString(MIXSRC_FIRST_INPUT + input), MENU_TITLE_COLOR); + new StaticText(window, {PAGE_TITLE_LEFT, PAGE_TITLE_TOP, LCD_W - PAGE_TITLE_LEFT, PAGE_LINE_HEIGHT}, STR_MENUINPUTS, MENU_TITLE_COLOR); + new StaticText(window, {PAGE_TITLE_LEFT, PAGE_TITLE_TOP + PAGE_LINE_HEIGHT, LCD_W - PAGE_TITLE_LEFT, PAGE_LINE_HEIGHT}, getSourceString(MIXSRC_FIRST_INPUT + input), MENU_TITLE_COLOR); } void updateCurves() { diff --git a/radio/src/gui/colorlcd/model_logical_switches.cpp b/radio/src/gui/colorlcd/model_logical_switches.cpp index 8081a46b1..5f6235f2f 100644 --- a/radio/src/gui/colorlcd/model_logical_switches.cpp +++ b/radio/src/gui/colorlcd/model_logical_switches.cpp @@ -58,6 +58,8 @@ class LogicalSwitchEditWindow: public Page { headerSwitchName->setFlags(isActive() ? BOLD|WARNING_COLOR : MENU_TITLE_COLOR); active = !active; } + + Page::checkEvents(); } protected: @@ -183,8 +185,8 @@ class LogicalSwitchEditWindow: public Page { } void buildHeader(Window * window) { - new StaticText(window, { 70, 4, LCD_W - 100, 20 }, STR_MENULOGICALSWITCHES, MENU_TITLE_COLOR); - headerSwitchName = new StaticText(window, { 70, 28, LCD_W - 100, 20 }, getSwitchPositionName(SWSRC_SW1+ls), MENU_TITLE_COLOR); + new StaticText(window, {PAGE_TITLE_LEFT, PAGE_TITLE_TOP, LCD_W - PAGE_TITLE_LEFT, PAGE_LINE_HEIGHT}, STR_MENULOGICALSWITCHES, MENU_TITLE_COLOR); + headerSwitchName = new StaticText(window, {PAGE_TITLE_LEFT, PAGE_TITLE_TOP + PAGE_LINE_HEIGHT, LCD_W - PAGE_TITLE_LEFT, PAGE_LINE_HEIGHT}, getSwitchPositionName(SWSRC_SW1+ls), MENU_TITLE_COLOR); } void buildBody(Window * window) { @@ -256,7 +258,7 @@ class LogicalSwitchButton : public Button { Button::checkEvents(); } - virtual void paint(BitmapBuffer * dc) override + void paint(BitmapBuffer * dc) override { LogicalSwitchData * ls = lswAddress(lsIndex); uint8_t lsFamily = lswFamily(ls->func); @@ -341,15 +343,19 @@ void ModelLogicalSwitchesPage::build(FormWindow * window, int8_t focusIndex) for (uint8_t i=0; ifunc == LS_FUNC_NONE) { - auto label = new TextButton(window, grid.getLabelSlot(), getSwitchPositionName(SWSRC_SW1+i)); - grid.spacer(label->height() + 5); + auto button = new TextButton(window, grid.getLabelSlot(), getSwitchPositionName(SWSRC_SW1+i)); + button->setPressHandler([=]() { + editLogicalSwitch(window, i); + return 0; + }); + grid.spacer(button->height() + 5); } else { new StaticText(window, grid.getLabelSlot(), getSwitchPositionName(SWSRC_SW1 + i), BUTTON_BACKGROUND | CENTERED); Button * button = new LogicalSwitchButton(window, grid.getFieldSlot(), i, - [=]() -> uint8_t { - Menu *menu = new Menu(); - LogicalSwitchData *ls = lswAddress(i); + [=]() { + Menu * menu = new Menu(); + LogicalSwitchData * ls = lswAddress(i); menu->addLine(STR_EDIT, [=]() { editLogicalSwitch(window, i); }); diff --git a/radio/src/gui/colorlcd/model_mixes.cpp b/radio/src/gui/colorlcd/model_mixes.cpp index 481b6e3ae..cfefa9436 100644 --- a/radio/src/gui/colorlcd/model_mixes.cpp +++ b/radio/src/gui/colorlcd/model_mixes.cpp @@ -72,8 +72,8 @@ class MixEditWindow : public Page { void buildHeader(Window * window) { - new StaticText(window, {70, 4, 100, 20}, STR_MIXER, MENU_TITLE_COLOR); - new StaticText(window, {70, 28, 100, 20}, getSourceString(MIXSRC_CH1 + channel), MENU_TITLE_COLOR); + new StaticText(window, {PAGE_TITLE_LEFT, PAGE_TITLE_TOP, LCD_W - PAGE_TITLE_LEFT, PAGE_LINE_HEIGHT}, STR_MIXER, MENU_TITLE_COLOR); + new StaticText(window, {PAGE_TITLE_LEFT, PAGE_TITLE_TOP + PAGE_LINE_HEIGHT, LCD_W - PAGE_TITLE_LEFT, PAGE_LINE_HEIGHT}, getSourceString(MIXSRC_CH1 + channel), MENU_TITLE_COLOR); } void updateCurves() diff --git a/radio/src/gui/colorlcd/model_outputs.cpp b/radio/src/gui/colorlcd/model_outputs.cpp index 385dd9c9d..9521d0e09 100644 --- a/radio/src/gui/colorlcd/model_outputs.cpp +++ b/radio/src/gui/colorlcd/model_outputs.cpp @@ -39,8 +39,8 @@ class OutputEditWindow : public Page { void buildHeader(Window * window) { - new StaticText(window, {70, 4, 100, 20}, STR_MENULIMITS, MENU_TITLE_COLOR); - new StaticText(window, {70, 28, 100, 20}, getSourceString(MIXSRC_CH1 + channel), MENU_TITLE_COLOR); + new StaticText(window, {PAGE_TITLE_LEFT, PAGE_TITLE_TOP, LCD_W - PAGE_TITLE_LEFT, PAGE_LINE_HEIGHT}, STR_MENULIMITS, MENU_TITLE_COLOR); + new StaticText(window, {PAGE_TITLE_LEFT, PAGE_TITLE_TOP + PAGE_LINE_HEIGHT, LCD_W - PAGE_TITLE_LEFT, PAGE_LINE_HEIGHT}, getSourceString(MIXSRC_CH1 + channel), MENU_TITLE_COLOR); } void buildBody(Window * window) diff --git a/radio/src/gui/colorlcd/model_telemetry.cpp b/radio/src/gui/colorlcd/model_telemetry.cpp index 0d618fa31..ee92df68c 100644 --- a/radio/src/gui/colorlcd/model_telemetry.cpp +++ b/radio/src/gui/colorlcd/model_telemetry.cpp @@ -125,7 +125,7 @@ class SensorEditWindow : public Page { void buildHeader(Window * window) { - new StaticText(window, {70, 4, 200, 20}, STR_SENSOR + std::to_string(index + 1), MENU_TITLE_COLOR); + new StaticText(window, {PAGE_TITLE_LEFT, PAGE_TITLE_TOP, LCD_W - PAGE_TITLE_LEFT, PAGE_LINE_HEIGHT}, STR_SENSOR + std::to_string(index + 1), MENU_TITLE_COLOR); // dynamic display of sensor value ? //new StaticText(window, {70, 28, 100, 20}, "SF" + std::to_string(index), MENU_TITLE_COLOR); } diff --git a/radio/src/gui/colorlcd/special_functions.cpp b/radio/src/gui/colorlcd/special_functions.cpp index ed594feeb..26b643293 100644 --- a/radio/src/gui/colorlcd/special_functions.cpp +++ b/radio/src/gui/colorlcd/special_functions.cpp @@ -58,8 +58,8 @@ class SpecialFunctionEditPage : public Page { void buildHeader(Window * window) { - new StaticText(window, { 60, 2, 200, 20 }, functions == g_model.customFn ? STR_MENUCUSTOMFUNC : STR_MENUSPECIALFUNCS, MENU_TITLE_COLOR); - headerSF = new StaticText(window, { 60, 22, 100, 20 }, (functions == g_model.customFn ? "SF" : "GF" ) + std::to_string(index), MENU_TITLE_COLOR); + new StaticText(window, { PAGE_TITLE_LEFT, PAGE_TITLE_TOP, LCD_W - PAGE_TITLE_LEFT, 20 }, functions == g_model.customFn ? STR_MENUCUSTOMFUNC : STR_MENUSPECIALFUNCS, MENU_TITLE_COLOR); + headerSF = new StaticText(window, { PAGE_TITLE_LEFT, PAGE_TITLE_TOP + PAGE_LINE_HEIGHT, LCD_W - PAGE_TITLE_LEFT, 20 }, (functions == g_model.customFn ? "SF" : "GF" ) + std::to_string(index), MENU_TITLE_COLOR); } void updateSpecialFunctionOneWindow(FormField * previousField, FormField * nextField) diff --git a/radio/src/gui/common/stdlcd/model_curves.cpp b/radio/src/gui/common/stdlcd/model_curves.cpp index b650a96ab..dee4ecdf2 100644 --- a/radio/src/gui/common/stdlcd/model_curves.cpp +++ b/radio/src/gui/common/stdlcd/model_curves.cpp @@ -83,7 +83,7 @@ void menuModelCurvesAll(event_t event) #endif { drawStringWithIndex(0, y, STR_CV, k+1, attr); - CurveData & crv = g_model.curves[k]; + CurveHeader & crv = g_model.curves[k]; editName(4*FW, y, crv.name, sizeof(crv.name), 0, 0); #if LCD_W >= 212 lcdDrawNumber(11*FW, y, 5+crv.points, LEFT); diff --git a/radio/src/lua/api_model.cpp b/radio/src/lua/api_model.cpp index 990d477d4..f3e5c36d1 100644 --- a/radio/src/lua/api_model.cpp +++ b/radio/src/lua/api_model.cpp @@ -829,33 +829,33 @@ static int luaModelGetCurve(lua_State *L) { unsigned int idx = luaL_checkunsigned(L, 1); if (idx < MAX_CURVES) { - CurveData & curveData = g_model.curves[idx]; + CurveHeader & CurveHeader = g_model.curves[idx]; lua_newtable(L); - lua_pushtablezstring(L, "name", curveData.name); - lua_pushtableinteger(L, "type", curveData.type); - lua_pushtableboolean(L, "smooth", curveData.smooth); - lua_pushtableinteger(L, "points", curveData.points + 5); + lua_pushtablezstring(L, "name", CurveHeader.name); + lua_pushtableinteger(L, "type", CurveHeader.type); + lua_pushtableboolean(L, "smooth", CurveHeader.smooth); + lua_pushtableinteger(L, "points", CurveHeader.points + 5); lua_pushstring(L, "y"); lua_newtable(L); int8_t * point = curveAddress(idx); - for (int i=0; i < curveData.points + 5; i++) { + for (int i=0; i < CurveHeader.points + 5; i++) { lua_pushinteger(L, i); lua_pushinteger(L, *point++); lua_settable(L, -3); } lua_settable(L, -3); - if (curveData.type == CURVE_TYPE_CUSTOM) { + if (CurveHeader.type == CURVE_TYPE_CUSTOM) { lua_pushstring(L, "x"); lua_newtable(L); lua_pushinteger(L, 0); lua_pushinteger(L, -100); lua_settable(L, -3); - for (int i=0; i < curveData.points + 3; i++) { + for (int i=0; i < CurveHeader.points + 3; i++) { lua_pushinteger(L, i+1); lua_pushinteger(L, *point++); lua_settable(L, -3); } - lua_pushinteger(L, curveData.points + 4); + lua_pushinteger(L, CurveHeader.points + 4); lua_pushinteger(L, 100); lua_settable(L, -3); lua_settable(L, -3); @@ -922,9 +922,9 @@ static int luaModelSetCurve(lua_State *L) memset(yPoints, -127, sizeof(yPoints)); - CurveData &destCurveData = g_model.curves[curveIdx]; - CurveData newCurveData; - memclear(&newCurveData, sizeof(CurveData)); + CurveHeader &destCurveHeader = g_model.curves[curveIdx]; + CurveHeader newCurveHeader; + memclear(&newCurveHeader, sizeof(CurveHeader)); luaL_checktype(L, -1, LUA_TTABLE); for (lua_pushnil(L); lua_next(L, -2); lua_pop(L, 1)) { @@ -932,18 +932,18 @@ static int luaModelSetCurve(lua_State *L) const char *key = luaL_checkstring(L, -2); if (!strcmp(key, "name")) { const char *name = luaL_checkstring(L, -1); - str2zchar(newCurveData.name, name, sizeof(newCurveData.name)); + str2zchar(newCurveHeader.name, name, sizeof(newCurveHeader.name)); } else if (!strcmp(key, "type")) { - newCurveData.type = luaL_checkinteger(L, -1); + newCurveHeader.type = luaL_checkinteger(L, -1); } else if (!strcmp(key, "smooth")) { // Earlier version of this api expected a 0/1 integer instead of a boolean // Still accept a 0/1 here if (lua_isboolean(L,-1)) - newCurveData.smooth = lua_toboolean(L, -1); + newCurveHeader.smooth = lua_toboolean(L, -1); else - newCurveData.smooth = luaL_checkinteger(L, -1); + newCurveHeader.smooth = luaL_checkinteger(L, -1); } else if (!strcmp(key, "x") || !strcmp(key, "y")) { luaL_checktype(L, -1, LUA_TTABLE); @@ -972,14 +972,14 @@ static int luaModelSetCurve(lua_State *L) do { numPoints++; } while (yPoints[numPoints]!=-127 && numPoints < MAX_POINTS_PER_CURVE); - newCurveData.points = numPoints - 5; + newCurveHeader.points = numPoints - 5; if (numPoints < MIN_POINTS_PER_CURVE || numPoints > MAX_POINTS_PER_CURVE) { lua_pushinteger(L, 1); return 1; } - if (newCurveData.type == CURVE_TYPE_CUSTOM) { + if (newCurveHeader.type == CURVE_TYPE_CUSTOM) { // The rest of the points are checked by the monotonic condition for (unsigned int i=numPoints; i < sizeof(xPoints);i++) @@ -992,7 +992,7 @@ static int luaModelSetCurve(lua_State *L) } // Check first and last point - if (xPoints[0] != -100 || xPoints[newCurveData.points + 4] != 100) { + if (xPoints[0] != -100 || xPoints[newCurveHeader.points + 4] != 100) { lua_pushinteger(L, 5); return 1; } @@ -1007,7 +1007,7 @@ static int luaModelSetCurve(lua_State *L) } // Check that ypoints have the right number of points set - for (int i=0; i < 5 + newCurveData.points;i++) + for (int i=0; i < 5 + newCurveHeader.points;i++) { if (yPoints[i] == -127) { @@ -1018,19 +1018,19 @@ static int luaModelSetCurve(lua_State *L) // Calculate size of curve we replace int oldCurveMemSize; - if (destCurveData.type == CURVE_TYPE_STANDARD) { - oldCurveMemSize = 5 + destCurveData.points; + if (destCurveHeader.type == CURVE_TYPE_STANDARD) { + oldCurveMemSize = 5 + destCurveHeader.points; } else { - oldCurveMemSize = 8 + 2 * destCurveData.points; + oldCurveMemSize = 8 + 2 * destCurveHeader.points; } // Calculate own size int newCurveMemSize; - if (newCurveData.type == CURVE_TYPE_STANDARD) - newCurveMemSize = 5 + newCurveData.points; + if (newCurveHeader.type == CURVE_TYPE_STANDARD) + newCurveMemSize = 5 + newCurveHeader.points; else - newCurveMemSize = 8 + 2 * newCurveData.points; + newCurveMemSize = 8 + 2 * newCurveHeader.points; int shift = newCurveMemSize - oldCurveMemSize; @@ -1042,15 +1042,15 @@ static int luaModelSetCurve(lua_State *L) } // Curve fits into mem, fill new curve - destCurveData = newCurveData; + destCurveHeader = newCurveHeader; int8_t *point = curveAddress(curveIdx); - for (int i = 0; i < destCurveData.points + 5; i++) { + for (int i = 0; i < destCurveHeader.points + 5; i++) { *point++ = yPoints[i]; } - if (destCurveData.type == CURVE_TYPE_CUSTOM) { - for (int i = 1; i < destCurveData.points + 4; i++) { + if (destCurveHeader.type == CURVE_TYPE_CUSTOM) { + for (int i = 1; i < destCurveHeader.points + 4; i++) { *point++ = xPoints[i]; } } diff --git a/radio/src/opentx.h b/radio/src/opentx.h index bd5b32c5d..7614473a2 100644 --- a/radio/src/opentx.h +++ b/radio/src/opentx.h @@ -256,6 +256,7 @@ #endif #include "myeeprom.h" +#include "curves.h" inline void memclear(void * p, size_t size) { @@ -802,31 +803,8 @@ inline void getGVarIncDecRange(int16_t & valMin, int16_t & valMax) } #endif -// Curves -enum BaseCurves { - CURVE_NONE, - CURVE_X_GT0, - CURVE_X_LT0, - CURVE_ABS_X, - CURVE_F_GT0, - CURVE_F_LT0, - CURVE_ABS_F, - CURVE_BASE -}; -int8_t * curveAddress(uint8_t idx); -point_t getPoint(uint8_t i); -point_t getPoint(uint8_t curveIndex, uint8_t index); -typedef CurveData CurveInfo; -void loadCurves(); -#define LOAD_MODEL_CURVES() loadCurves() -int intpol(int x, uint8_t idx); -int applyCurve(int x, CurveRef & curve); -int applyCustomCurve(int x, uint8_t idx); -int applyCurrentCurve(int x); -int8_t getCurveX(int noPoints, int point); -void resetCustomCurveX(int8_t * points, int noPoints); -bool moveCurve(uint8_t index, int8_t shift); // TODO bool? + void clearInputs(); void defaultInputs(); diff --git a/radio/src/storage/conversions/conversions_216_218.cpp b/radio/src/storage/conversions/conversions_216_218.cpp index 7f2689104..041b88fb5 100644 --- a/radio/src/storage/conversions/conversions_216_218.cpp +++ b/radio/src/storage/conversions/conversions_216_218.cpp @@ -200,7 +200,7 @@ PACK(typedef struct { uint8_t smooth:1; uint8_t spare:4; int8_t points; -}) CurveData_v216; +}) CurveHeader_v216; #if defined(PCBTARANIS) PACK(typedef struct { @@ -586,7 +586,7 @@ PACK(typedef struct { LimitData_v216 limitData[MAX_OUTPUT_CHANNELS_218]; ExpoData_v216 expoData[MAX_EXPOS_218]; - CurveData_v216 curves[MAX_CURVES_218]; + CurveHeader_v216 curves[MAX_CURVES_218]; int8_t points[MAX_CURVE_POINTS_218]; LogicalSwitchData_v216 logicalSw[32]; @@ -632,7 +632,7 @@ PACK(typedef struct { LimitData limitData[MAX_OUTPUT_CHANNELS_218]; ExpoData_v217 expoData[MAX_EXPOS_218]; - CurveData_v216 curves[MAX_CURVES_218]; + CurveHeader_v216 curves[MAX_CURVES_218]; int8_t points[MAX_CURVE_POINTS_218]; LogicalSwitchData_v217 logicalSw[MAX_LOGICAL_SWITCHES_218]; diff --git a/radio/src/storage/conversions/conversions_218_219.cpp b/radio/src/storage/conversions/conversions_218_219.cpp index 0f2c6de9c..8e020443c 100644 --- a/radio/src/storage/conversions/conversions_218_219.cpp +++ b/radio/src/storage/conversions/conversions_218_219.cpp @@ -164,7 +164,7 @@ void convertModelData_218_to_219(ModelData &model) } for (uint8_t i=0; i -void copyCurveData(A * dest, B * src) +void copyCurveHeader(A * dest, B * src) { dest->type = src->type; dest->smooth = src->smooth; @@ -259,7 +259,7 @@ void copyModelData(A * dest, B * src) copyExpoData(&dest->expoData[i], &src->expoData[i]); } for (int i=0; i<32; i++) { - copyCurveData(&dest->curves[i], &src->curves[i]); + copyCurveHeader(&dest->curves[i], &src->curves[i]); } memcpy(dest->points, src->points, sizeof(dest->points)); for (int i=0; i<64; i++) { diff --git a/radio/src/storage/storage_common.cpp b/radio/src/storage/storage_common.cpp index 86f5995c6..1efd5c65d 100644 --- a/radio/src/storage/storage_common.cpp +++ b/radio/src/storage/storage_common.cpp @@ -157,7 +157,7 @@ void postModelLoad(bool alarms) } } - LOAD_MODEL_CURVES(); + loadCurves(); resumeMixerCalculations(); if (pulsesStarted()) { diff --git a/radio/src/targets/horus/libopenui_config.h b/radio/src/targets/horus/libopenui_config.h index 402784f03..edb87637d 100644 --- a/radio/src/targets/horus/libopenui_config.h +++ b/radio/src/targets/horus/libopenui_config.h @@ -88,6 +88,9 @@ constexpr uint32_t ALERT_MESSAGE_TOP = ALERT_TITLE_TOP + 90; constexpr uint32_t ALERT_MESSAGE_LEFT = ALERT_TITLE_LEFT; constexpr uint32_t ALERT_ACTION_TOP = 240; +constexpr uint32_t PAGE_TITLE_TOP = 2; +constexpr uint32_t PAGE_TITLE_LEFT = 50; + // TODO common code, not in target enum LcdColorIndex { diff --git a/radio/src/targets/nv14/libopenui_config.h b/radio/src/targets/nv14/libopenui_config.h index d53189a08..bac963283 100644 --- a/radio/src/targets/nv14/libopenui_config.h +++ b/radio/src/targets/nv14/libopenui_config.h @@ -87,6 +87,9 @@ constexpr uint32_t ALERT_MESSAGE_LEFT = ALERT_TITLE_LEFT; constexpr uint32_t ALERT_ACTION_TOP = 240; constexpr uint32_t ALERT_BUTTON_TOP = 300; +constexpr uint32_t PAGE_TITLE_TOP = 4; +constexpr uint32_t PAGE_TITLE_LEFT = 70; + enum LcdColorIndex { DEFAULT_COLOR_INDEX, diff --git a/radio/src/thirdparty/libopenui b/radio/src/thirdparty/libopenui index 9807aaec0..50eb0980b 160000 --- a/radio/src/thirdparty/libopenui +++ b/radio/src/thirdparty/libopenui @@ -1 +1 @@ -Subproject commit 9807aaec0d8b85c786ce032abb00652c77e457cd +Subproject commit 50eb0980b37ffef097ef4fe6c8a27e1f694c2e55