1
0
Fork 0
mirror of https://github.com/opentx/opentx.git synced 2025-07-24 00:35:18 +03:00

MenuModel split - 3rd part

This commit is contained in:
bsongis 2014-12-14 18:44:49 +01:00
parent 849bf8fab3
commit 32c9dc95d6
9 changed files with 528 additions and 483 deletions

View file

@ -72,6 +72,7 @@ void menuModelExposAll(uint8_t event);
void menuModelMixAll(uint8_t event);
void menuModelLimits(uint8_t event);
void menuModelCurvesAll(uint8_t event);
void menuModelCurveOne(uint8_t event);
void menuModelGVars(uint8_t event);
void menuModelLogicalSwitches(uint8_t event);
void menuModelCustomFunctions(uint8_t event);
@ -80,6 +81,12 @@ void menuModelTelemetry(uint8_t event);
void menuModelTemplates(uint8_t event);
void menuModelExpoOne(uint8_t event);
extern uint8_t s_curveChan;
#if defined(PCBTARANIS)
void editCurveRef(coord_t x, coord_t y, CurveRef & curve, uint8_t event, uint8_t attr);
#endif
const MenuFuncP_PROGMEM menuTabModel[] PROGMEM = {
menuModelSelect,
menuModelSetup,
@ -2434,420 +2441,6 @@ void DrawFunction(FnFuncP fn, uint8_t offset=0)
}
}
#if defined(CURVES)
static uint8_t s_curveChan;
int16_t curveFn(int16_t x)
{
return applyCustomCurve(x, s_curveChan);
}
struct point_t {
coord_t x;
coord_t y;
};
point_t getPoint(uint8_t i)
{
point_t result = {0, 0};
#if defined(PCBTARANIS)
CurveInfo &crv = g_model.curves[s_curveChan];
int8_t *points = curveAddress(s_curveChan);
bool custom = (crv.type == CURVE_TYPE_CUSTOM);
uint8_t count = 5+crv.points;
#else
CurveInfo crv = curveInfo(s_curveChan);
int8_t *points = crv.crv;
bool custom = crv.custom;
uint8_t count = crv.points;
#endif
if (i < count) {
#if defined(PCBTARANIS)
result.x = X0-1-WCHART+i*WCHART*2/(count-1);
#else
result.x = X0-1-WCHART+i*WCHART/(count/2);
#endif
result.y = (LCD_H-1) - (100 + points[i]) * (LCD_H-1) / 200;
if (custom && i>0 && i<count-1)
result.x = X0-1-WCHART + (100 + (100 + points[count+i-1]) * (2*WCHART)) / 200;
}
return result;
}
void DrawCurve(uint8_t offset=0)
{
DrawFunction(curveFn, offset);
uint8_t i = 0;
do {
point_t point = getPoint(i);
i++;
if (point.x == 0) break;
lcd_filled_rect(point.x-offset, point.y-1, 3, 3, SOLID, FORCE); // do markup square
} while(1);
}
#endif
#if defined(CURVES)
#if defined(PCBTARANIS)
extern int8_t * curveEnd[MAX_CURVES];
bool moveCurve(uint8_t index, int8_t shift)
{
if (curveEnd[MAX_CURVES-1] + shift > g_model.points + sizeof(g_model.points)) {
AUDIO_WARNING2();
return false;
}
int8_t *nextCrv = curveAddress(index+1);
memmove(nextCrv+shift, nextCrv, 5*(MAX_CURVES-index-1)+curveEnd[MAX_CURVES-1]-curveEnd[index]);
if (shift < 0) memclear(&g_model.points[NUM_POINTS-1] + shift, -shift);
while (index<MAX_CURVES) {
curveEnd[index++] += shift;
}
eeDirty(EE_MODEL);
return true;
}
#else
bool moveCurve(uint8_t index, int8_t shift, int8_t custom=0)
{
if (g_model.curves[MAX_CURVES-1] + shift > NUM_POINTS-5*MAX_CURVES) {
AUDIO_WARNING2();
return false;
}
int8_t *crv = curveAddress(index);
if (shift < 0) {
for (uint8_t i=0; i<custom; i++)
crv[i] = crv[2*i];
}
int8_t *nextCrv = curveAddress(index+1);
memmove(nextCrv+shift, nextCrv, 5*(MAX_CURVES-index-1)+g_model.curves[MAX_CURVES-1]-g_model.curves[index]);
if (shift < 0) memclear(&g_model.points[NUM_POINTS-1] + shift, -shift);
while (index<MAX_CURVES)
g_model.curves[index++] += shift;
for (uint8_t i=0; i<custom-2; i++)
crv[custom+i] = -100 + ((200 * (i+1) + custom/2) / (custom-1)) ;
eeDirty(EE_MODEL);
return true;
}
#endif
#if defined(PCBTARANIS)
void displayPresetChoice(uint8_t event)
{
displayWarning(event);
lcd_outdezAtt(WARNING_LINE_X+FW*7, WARNING_LINE_Y, 45*s_warning_input_value/4, LEFT|INVERS);
lcd_putcAtt(lcdLastPos, WARNING_LINE_Y, '@', INVERS);
if (s_warning_result) {
s_warning_result = 0;
CurveInfo & crv = g_model.curves[s_curveChan];
int8_t * points = curveAddress(s_curveChan);
for (uint8_t i=0; i<5+crv.points; i++)
points[i] = (i-((5+crv.points)/2)) * s_warning_input_value * 50 / (4+crv.points);
if (crv.type == CURVE_TYPE_CUSTOM) {
for (int i=0; i<3+crv.points; i++)
points[crv.points+i] = -100 + ((i+1)*200) / (4+crv.points);
}
}
}
void onCurveOneMenu(const char *result)
{
if (result == STR_CURVE_PRESET) {
POPUP_INPUT(STR_PRESET, displayPresetChoice, 0, -4, 4);
}
else if (result == STR_MIRROR) {
CurveInfo & 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];
int8_t * points = curveAddress(s_curveChan);
for (int i=0; i<5+crv.points; i++)
points[i] = 0;
if (crv.type == CURVE_TYPE_CUSTOM) {
for (int i=0; i<3+crv.points; i++)
points[crv.points+i] = -100 + ((i+1)*200) / (4+crv.points);
}
}
}
void menuModelCurveOne(uint8_t event)
{
static uint8_t pointsOfs = 0;
CurveInfo & crv = g_model.curves[s_curveChan];
int8_t * points = curveAddress(s_curveChan);
lcd_puts(9*FW, 0, TR_PT "\003X\006Y");
lcd_filled_rect(0, 0, LCD_W, FH, SOLID, FILL_WHITE|GREY_DEFAULT);
SIMPLE_SUBMENU(STR_MENUCURVE, 4 + 5+crv.points + (crv.type==CURVE_TYPE_CUSTOM ? 5+crv.points-2 : 0));
lcd_outdezAtt(PSIZE(TR_MENUCURVE)*FW+1, 0, s_curveChan+1, INVERS|LEFT);
lcd_putsLeft(FH+1, STR_NAME);
editName(INDENT_WIDTH, 2*FH+1, g_model.curveNames[s_curveChan], sizeof(g_model.curveNames[s_curveChan]), event, m_posVert==0);
uint8_t attr = (m_posVert==1 ? (s_editMode>0 ? INVERS|BLINK : INVERS) : 0);
lcd_putsLeft(3*FH+1, STR_TYPE);
lcd_putsiAtt(INDENT_WIDTH, 4*FH+1, STR_CURVE_TYPES, crv.type, attr);
if (attr) {
uint8_t newType = checkIncDecModelZero(event, crv.type, CURVE_TYPE_LAST);
if (newType != crv.type) {
for (int i=1; i<4+crv.points; i++)
points[i] = calcRESXto100(applyCustomCurve(calc100toRESX(-100 + i*200/(4+crv.points)), s_curveChan));
moveCurve(s_curveChan, checkIncDec_Ret > 0 ? 3+crv.points : -3-crv.points);
if (newType == CURVE_TYPE_CUSTOM) {
for (int i=0; i<3+crv.points; i++)
points[5+crv.points+i] = -100 + ((i+1)*200) / (4+crv.points);
}
crv.type = newType;
}
}
attr = (m_posVert==2 ? (s_editMode>0 ? INVERS|BLINK : INVERS) : 0);
lcd_putsLeft(5*FH+1, STR_COUNT);
lcd_outdezAtt(INDENT_WIDTH, 6*FH+1, 5+crv.points, LEFT|attr);
lcd_putsAtt(lcdLastPos, 6*FH+1, STR_PTS, attr);
if (attr) {
int8_t count = checkIncDecModel(event, crv.points, -3, 12); // 2pts - 17pts
if (checkIncDec_Ret) {
int8_t newPoints[MAX_POINTS];
newPoints[0] = points[0];
newPoints[4+count] = points[4+crv.points];
for (int i=1; i<4+count; i++)
newPoints[i] = calcRESXto100(applyCustomCurve(calc100toRESX(-100 + (i*200) / (4+count)), s_curveChan));
moveCurve(s_curveChan, checkIncDec_Ret*(crv.type==CURVE_TYPE_CUSTOM?2:1));
for (int i=0; i<5+count; i++) {
points[i] = newPoints[i];
if (crv.type == CURVE_TYPE_CUSTOM && i!=0 && i!=4+count)
points[5+count+i-1] = -100 + (i*200) / (4+count);
}
crv.points = count;
}
}
lcd_putsLeft(7*FH+1, STR_SMOOTH);
menu_lcd_onoff(7*FW, 7*FH+1, crv.smooth, m_posVert==3 ? INVERS : 0);
if (m_posVert==3) crv.smooth = checkIncDecModel(event, crv.smooth, 0, 1);
switch(event) {
case EVT_ENTRY:
pointsOfs = 0;
SET_SCROLLBAR_X(0);
break;
case EVT_KEY_LONG(KEY_ENTER):
if (m_posVert > 1) {
killEvents(event);
MENU_ADD_ITEM(STR_CURVE_PRESET);
MENU_ADD_ITEM(STR_MIRROR);
MENU_ADD_ITEM(STR_CLEAR);
menuHandler = onCurveOneMenu;
}
break;
case EVT_KEY_LONG(KEY_MENU):
pushMenu(menuChannelsView);
killEvents(event);
}
DrawCurve(FW);
uint8_t posY = FH+1;
attr = (s_editMode > 0 ? INVERS|BLINK : INVERS);
for (uint8_t i=0; i<5+crv.points; i++) {
point_t point = getPoint(i);
uint8_t selectionMode = 0;
if (crv.type==CURVE_TYPE_CUSTOM) {
if (m_posVert==4+2*i || (i==5+crv.points-1 && m_posVert==4+5+crv.points+5+crv.points-2-1))
selectionMode = 2;
else if (i>0 && m_posVert==3+2*i)
selectionMode = 1;
}
else if (m_posVert == 4+i) {
selectionMode = 2;
}
if (i>=pointsOfs && i<pointsOfs+7) {
int8_t x = -100 + 200*i/(5+crv.points-1);
if (crv.type==CURVE_TYPE_CUSTOM && i>0 && i<5+crv.points-1) x = points[5+crv.points+i-1];
lcd_outdezAtt(6+8*FW, posY, i+1, LEFT);
lcd_outdezAtt(3+12*FW, posY, x, LEFT|(selectionMode==1?attr:0));
lcd_outdezAtt(3+16*FW, posY, points[i], LEFT|(selectionMode==2?attr:0));
posY += FH;
}
if (selectionMode > 0) {
// do selection square
lcd_filled_rect(point.x-FW-1, point.y-2, 5, 5, SOLID, FORCE);
lcd_filled_rect(point.x-FW, point.y-1, 3, 3, SOLID);
if (s_editMode > 0) {
if (selectionMode == 1)
CHECK_INCDEC_MODELVAR(event, points[5+crv.points+i-1], i==1 ? -100 : points[5+crv.points+i-2], i==5+crv.points-2 ? 100 : points[5+crv.points+i]); // edit X
else if (selectionMode == 2)
CHECK_INCDEC_MODELVAR(event, points[i], -100, 100);
}
if (i < pointsOfs)
pointsOfs = i;
else if (i > pointsOfs+6)
pointsOfs = i-6;
}
}
}
#else
void menuModelCurveOne(uint8_t event)
{
TITLE(STR_MENUCURVE);
lcd_outdezAtt(PSIZE(TR_MENUCURVE)*FW+1, 0, s_curveChan+1, INVERS|LEFT);
DISPLAY_PROGRESS_BAR(20*FW+1);
CurveInfo crv = curveInfo(s_curveChan);
switch(event) {
case EVT_ENTRY:
s_editMode = 1;
break;
CASE_EVT_ROTARY_BREAK
case EVT_KEY_BREAK(KEY_ENTER):
if (s_editMode <= 0)
m_posHorz = 0;
if (s_editMode == 1 && crv.custom)
s_editMode = 2;
else
s_editMode = 1;
break;
case EVT_KEY_LONG(KEY_ENTER):
if (s_editMode <= 0) {
if (int8_t(++m_posHorz) > 4)
m_posHorz = -4;
for (uint8_t i=0; i<crv.points; i++)
crv.crv[i] = (i-(crv.points/2)) * int8_t(m_posHorz) * 50 / (crv.points-1);
eeDirty(EE_MODEL);
killEvents(event);
}
break;
case EVT_KEY_BREAK(KEY_EXIT):
if (s_editMode > 0) {
if (--s_editMode == 0)
m_posHorz = 0;
}
else {
popMenu();
}
break;
/* CASE_EVT_ROTARY_LEFT */
case EVT_KEY_REPT(KEY_LEFT):
case EVT_KEY_FIRST(KEY_LEFT):
if (s_editMode==1 && m_posHorz>0) m_posHorz--;
if (s_editMode <= 0) {
if (crv.custom) {
moveCurve(s_curveChan, -crv.points+2);
}
else if (crv.points > MIN_POINTS) {
moveCurve(s_curveChan, -1, (crv.points+1)/2);
}
else {
AUDIO_WARNING2();
}
return;
}
break;
/* CASE_EVT_ROTARY_RIGHT */
case EVT_KEY_REPT(KEY_RIGHT):
case EVT_KEY_FIRST(KEY_RIGHT):
if (s_editMode==1 && m_posHorz<(crv.points-1)) m_posHorz++;
if (s_editMode <= 0) {
if (!crv.custom) {
moveCurve(s_curveChan, crv.points-2, crv.points);
}
else if (crv.points < MAX_POINTS) {
if (moveCurve(s_curveChan, 1)) {
for (int8_t i=crv.points+crv.points-2; i>=0; i--) {
if (i%2)
crv.crv[i] = (crv.crv[i/2] + crv.crv[1+i/2]) / 2;
else
crv.crv[i] = crv.crv[i/2];
}
}
}
else {
AUDIO_WARNING2();
}
}
break;
}
lcd_putsLeft(7*FH, STR_TYPE);
uint8_t attr = (s_editMode <= 0 ? INVERS : 0);
lcd_outdezAtt(5*FW-2, 7*FH, crv.points, LEFT|attr);
lcd_putsAtt(lcdLastPos, 7*FH, crv.custom ? PSTR("pt'") : PSTR("pt"), attr);
DrawCurve();
if (s_editMode>0) {
uint8_t i = m_posHorz;
point_t point = getPoint(i);
if (s_editMode==1 || !BLINK_ON_PHASE) {
// do selection square
lcd_filled_rect(point.x-1, point.y-2, 5, 5, SOLID, FORCE);
lcd_filled_rect(point.x, point.y-1, 3, 3, SOLID);
}
int8_t x = -100 + 200*i/(crv.points-1);
if (crv.custom && i>0 && i<crv.points-1) x = crv.crv[crv.points+i-1];
lcd_puts(7, 2*FH, PSTR("x=")); lcd_outdezAtt(7+2*FW, 2*FH, x, LEFT);
lcd_puts(7, 3*FH, PSTR("y=")); lcd_outdezAtt(7+2*FW, 3*FH, crv.crv[i], LEFT);
lcd_rect(3, 1*FH+4, 7*FW-2, 3*FH-2);
if (p1valdiff || event==EVT_KEY_FIRST(KEY_DOWN) || event==EVT_KEY_FIRST(KEY_UP) || event==EVT_KEY_REPT(KEY_DOWN) || event==EVT_KEY_REPT(KEY_UP))
CHECK_INCDEC_MODELVAR(event, crv.crv[i], -100, 100); // edit Y on up/down
if (i>0 && i<crv.points-1 && s_editMode==2 && (event==EVT_KEY_FIRST(KEY_LEFT) || event==EVT_KEY_FIRST(KEY_RIGHT) || event==EVT_KEY_REPT(KEY_LEFT) || event==EVT_KEY_REPT(KEY_RIGHT)))
CHECK_INCDEC_MODELVAR(event, crv.crv[crv.points+i-1], i==1 ? -99 : crv.crv[crv.points+i-2]+1, i==crv.points-2 ? 99 : crv.crv[crv.points+i]-1); // edit X on left/right
}
}
#endif
#endif
#if defined(PCBTARANIS) && defined(CURVES)
void editCurveRef(coord_t x, coord_t y, CurveRef & curve, uint8_t event, uint8_t attr)
{
lcd_putsiAtt(x, y, "\004DiffExpoFuncCstm", curve.type, m_posHorz==0 ? attr : 0);
if (attr && m_posHorz==0) {
CHECK_INCDEC_MODELVAR_ZERO(event, curve.type, CURVE_REF_CUSTOM);
if (checkIncDec_Ret) curve.value = 0;
}
switch (curve.type) {
case CURVE_REF_DIFF:
case CURVE_REF_EXPO:
curve.value = GVAR_MENU_ITEM(x+5*FW, y, curve.value, -100, 100, m_posHorz==1 ? LEFT|attr : LEFT, 0, event);
break;
case CURVE_REF_FUNC:
lcd_putsiAtt(x+5*FW, y, STR_VCURVEFUNC, curve.value, m_posHorz==1 ? attr : 0);
if (attr && m_posHorz==1) CHECK_INCDEC_MODELVAR_ZERO(event, curve.value, CURVE_BASE-1);
break;
case CURVE_REF_CUSTOM:
putsCurve(x+5*FW+2, y, curve.value, m_posHorz==1 ? attr : 0);
if (attr && m_posHorz==1) {
if (event==EVT_KEY_LONG(KEY_ENTER) && curve.value!=0) {
s_curveChan = (curve.value<0 ? -curve.value-1 : curve.value-1);
pushMenu(menuModelCurveOne);
}
else {
CHECK_INCDEC_MODELVAR(event, curve.value, -MAX_CURVES, MAX_CURVES);
}
}
break;
}
}
#endif
uint8_t getExpoMixCount(uint8_t expo)
{
@ -3995,75 +3588,6 @@ void menuModelMixAll(uint8_t event)
return menuModelExpoMix(0, event);
}
#if defined(CURVES)
#if defined(GVARS)
#define CURVE_SELECTED() (sub >= 0 && sub < MAX_CURVES)
#define GVAR_SELECTED() (sub >= MAX_CURVES)
#else
#define CURVE_SELECTED() (sub >= 0)
#endif
void menuModelCurvesAll(uint8_t event)
{
#if defined(GVARS) && defined(PCBSTD)
SIMPLE_MENU(STR_MENUCURVES, menuTabModel, e_CurvesAll, 1+MAX_CURVES+MAX_GVARS);
#else
SIMPLE_MENU(STR_MENUCURVES, menuTabModel, e_CurvesAll, 1+MAX_CURVES);
#endif
int8_t sub = m_posVert - 1;
switch (event) {
#if defined(ROTARY_ENCODER_NAVIGATION)
case EVT_ROTARY_BREAK:
#endif
#if defined(PCBTARANIS)
case EVT_KEY_BREAK(KEY_ENTER):
#else
case EVT_KEY_FIRST(KEY_RIGHT):
case EVT_KEY_FIRST(KEY_ENTER):
#endif
if (CURVE_SELECTED() && !READ_ONLY()) {
s_curveChan = sub;
pushMenu(menuModelCurveOne);
}
break;
}
for (uint8_t i=0; i<LCD_LINES-1; i++) {
coord_t y = MENU_TITLE_HEIGHT + 1 + i*FH;
uint8_t k = i + s_pgOfs;
uint8_t attr = (sub == k ? INVERS : 0);
#if defined(GVARS) && defined(PCBSTD)
if (k >= MAX_CURVES) {
putsStrIdx(0, y, STR_GV, k-MAX_CURVES+1);
if (GVAR_SELECTED()) {
if (attr && s_editMode>0) attr |= BLINK;
lcd_outdezAtt(10*FW, y, GVAR_VALUE(k-MAX_CURVES, -1), attr);
if (attr) g_model.gvars[k-MAX_CURVES] = checkIncDec(event, g_model.gvars[k-MAX_CURVES], -1000, 1000, EE_MODEL);
}
}
else
#endif
{
putsStrIdx(0, y, STR_CV, k+1, attr);
#if defined(PCBTARANIS)
editName(4*FW, y, g_model.curveNames[k], sizeof(g_model.curveNames[k]), 0, 0);
CurveInfo & crv = g_model.curves[k];
lcd_outdezAtt(11*FW, y, 5+crv.points, LEFT);
lcd_putsAtt(lcdLastPos, y, STR_PTS, 0);
#endif
}
}
if (CURVE_SELECTED()) {
s_curveChan = sub;
DrawCurve(23);
}
}
#endif
#if LCD_W >= 212 && defined(GVARS) && defined(FLIGHT_MODES)
void onGVARSMenu(const char *result)