Files
edgetx-gx12/radio/src/gui/common/stdlcd/model_usbjoystick.cpp
T

245 lines
8.2 KiB
C++

/*
* Copyright (C) EdgeTX
*
* Based on code named
* opentx - https://github.com/opentx/opentx
* 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.
*/
#include "edgetx.h"
#include "usb_joystick.h"
#define _STR_MAX(x) "/" #x
#define STR_MAX(x) _STR_MAX(x)
#if LCD_W >= 212
#define MODE_POS 5*FW
#define SUBMODE_POS MODE_POS+2*FW
#define USBJ_ONE_2ND_COLUMN (12*FW)
#define BTNMODE_POS SUBMODE_POS+5*FW
#define BTNNUM_POS BTNMODE_POS+12*FW
#else
#define MODE_POS 5*FW
#define SUBMODE_POS MODE_POS+2*FW
#define USBJ_ONE_2ND_COLUMN (12*FW)
#define BTNMODE_POS SUBMODE_POS+5*FW
#define BTNNUM_POS LCD_W
#endif
enum USBJFields {
USBJ_FIELD_MODE,
USBJ_FIELD_INVERSION,
USBJ_FIELD_SUBMODE,
USBJ_FIELD_BTNPOS,
USBJ_FIELD_BTNNUM,
USBJ_FIELD_MAX
};
void menuModelUSBJoystickOne(event_t event)
{
if (EVT_KEY_OPEN_CHAN_VIEW(event)) {
pushMenu(menuChannelsView);
}
USBJoystickChData * cch = usbJChAddress(s_currIdx);
putsChn(12*FW, 0, s_currIdx+1, 0);
lcdDrawNumber(20*FW, 0, channelOutputs[s_currIdx], RIGHT);
SUBMENU(STR_USBJOYSTICK_LABEL, USBJ_FIELD_MAX, {
0,
(cch->mode != USBJOYS_CH_NONE) ? (uint8_t)0 : (uint8_t)HIDDEN_ROW,
(cch->mode != USBJOYS_CH_NONE) ? (uint8_t)0 : (uint8_t)HIDDEN_ROW,
(cch->mode == USBJOYS_CH_BUTTON) ?
(((cch->param == USBJOYS_BTN_MODE_SW_EMU) || (cch->param == USBJOYS_BTN_MODE_DELTA)) ? (uint8_t)READONLY_ROW : (uint8_t)0)
: (uint8_t)HIDDEN_ROW,
(cch->mode == USBJOYS_CH_BUTTON) ? (uint8_t)0 : (uint8_t)HIDDEN_ROW });
int8_t sub = menuVerticalPosition;
char str[20];
for (uint8_t i=0; i<(NUM_BODY_LINES-1); i++) {
coord_t y = MENU_HEADER_HEIGHT + 1 + i*FH;
uint8_t k = i + menuVerticalOffset;
for (int j=0; j<=k; ++j) {
if (j<(int)DIM(mstate_tab) && mstate_tab[j] == HIDDEN_ROW) {
++k;
}
}
LcdFlags attr = (sub==k ? (s_editMode>0 ? BLINK|INVERS : INVERS) : 0);
switch (k) {
case USBJ_FIELD_MODE:
cch->mode = editChoice(USBJ_ONE_2ND_COLUMN, y, STR_USBJOYSTICK_CH_MODE, STR_VUSBJOYSTICK_CH_MODE, cch->mode, 0, USBJOYS_CH_LAST, attr, event);
break;
case USBJ_FIELD_INVERSION:
lcdDrawTextAlignedLeft(y, STR_USBJOYSTICK_CH_INVERSION);
drawCheckBox(USBJ_ONE_2ND_COLUMN, y, cch->inversion, attr);
if (attr) cch->inversion = checkIncDecModel(event, cch->inversion, 0, 1);
break;
case USBJ_FIELD_SUBMODE:
if (cch->mode == USBJOYS_CH_BUTTON) {
if (cch->param > USBJOYS_BTN_MODE_LAST) cch->param = 0;
cch->param = editChoice(USBJ_ONE_2ND_COLUMN, y, STR_USBJOYSTICK_CH_BTNMODE, STR_VUSBJOYSTICK_CH_BTNMODE, cch->param, 0, USBJOYS_BTN_MODE_LAST, attr, event);
if (cch->param == USBJOYS_BTN_MODE_SW_EMU) cch->switch_npos = 0;
else if (cch->param == USBJOYS_BTN_MODE_DELTA) cch->switch_npos = 1;
}
else if (cch->mode == USBJOYS_CH_AXIS) {
cch->param = editChoice(USBJ_ONE_2ND_COLUMN, y, STR_USBJOYSTICK_CH_AXIS, STR_VUSBJOYSTICK_CH_AXIS, cch->param, 0, USBJOYS_AXIS_LAST, attr, event);
}
else if (cch->mode == USBJOYS_CH_SIM) {
if (cch->param > USBJOYS_SIM_LAST) cch->param = 0;
cch->param = editChoice(USBJ_ONE_2ND_COLUMN, y, STR_USBJOYSTICK_CH_SIM, STR_VUSBJOYSTICK_CH_SIM, cch->param, 0, USBJOYS_SIM_LAST, attr, event);
}
break;
case USBJ_FIELD_BTNPOS:
if (cch->param == USBJOYS_BTN_MODE_SW_EMU) {
lcdDrawTextAlignedLeft(y, STR_USBJOYSTICK_CH_SWPOS);
lcdDrawText(USBJ_ONE_2ND_COLUMN, y, STR_VUSBJOYSTICK_CH_SWPOS[0], attr);
}
else if (cch->param == USBJOYS_BTN_MODE_DELTA) {
lcdDrawTextAlignedLeft(y, STR_USBJOYSTICK_CH_SWPOS);
lcdDrawText(USBJ_ONE_2ND_COLUMN, y, STR_VUSBJOYSTICK_CH_SWPOS[1], attr);
}
else {
cch->switch_npos = editChoice(USBJ_ONE_2ND_COLUMN, y, STR_USBJOYSTICK_CH_SWPOS, STR_VUSBJOYSTICK_CH_SWPOS, cch->switch_npos, 0, 7, attr, event);
}
break;
case USBJ_FIELD_BTNNUM:
lcdDrawTextAlignedLeft(y, STR_USBJOYSTICK_CH_BTNNUM);
uint8_t last = cch->lastBtnNumNoCLip();
uint8_t limited = 0;
if(last >= USBJ_BUTTON_SIZE) {
limited = 1;
last = USBJ_BUTTON_SIZE-1;
}
if (last > cch->btn_num)
snprintf(str, 20, "%u..%u%c", cch->btn_num, last, limited ? '!' : ' ');
else
snprintf(str, 20, "%u%c", cch->btn_num, limited ? '!' : ' ');
lcdDrawText(USBJ_ONE_2ND_COLUMN, y, str, attr);
if (attr) {
CHECK_INCDEC_MODELVAR(event, cch->btn_num, 0, USBJ_BUTTON_SIZE);
}
break;
}
}
if (cch->mode == USBJOYS_CH_BUTTON) {
if (isUSBBtnNumCollision(s_currIdx)) {
lcdDrawText(LCD_W/2, LCD_H-FH, STR_USBJOYSTICK_BTN_COLLISION, INVERS | CENTERED);
}
}
else if (cch->mode == USBJOYS_CH_AXIS) {
if (isUSBAxisCollision(s_currIdx)) {
lcdDrawText(LCD_W/2, LCD_H-FH, STR_USBJOYSTICK_AXIS_COLLISION, INVERS | CENTERED);
}
}
else if (cch->mode == USBJOYS_CH_SIM) {
if (isUSBSimCollision(s_currIdx)) {
lcdDrawText(LCD_W/2, LCD_H-FH, STR_USBJOYSTICK_AXIS_COLLISION, INVERS | CENTERED);
}
}
}
void onUSBJoystickMenu(const char *result)
{
int8_t sub = menuVerticalPosition;
USBJoystickChData * cs = usbJChAddress(sub);
if (result == STR_EDIT) {
s_currIdx = sub;
pushMenu(menuModelUSBJoystickOne);
}
else if (result == STR_CLEAR) {
memset(cs, 0, sizeof(USBJoystickChData));
storageDirty(EE_MODEL);
}
}
void menuModelUSBJoystick(event_t event)
{
check_submenu_simple(event, USBJ_MAX_JOYSTICK_CHANNELS);
title(STR_USBJOYSTICK_LABEL);
if (s_editMode > 0) s_editMode = 0;
int8_t sub = menuVerticalPosition;
coord_t y = 0;
uint8_t k = 0;
if (event == EVT_KEY_BREAK(KEY_ENTER)) {
USBJoystickChData * cch = usbJChAddress(sub);
s_currIdx = sub;
if (sub >= 0)
POPUP_MENU_ADD_ITEM(STR_EDIT);
if (cch->mode != USBJOYS_CH_NONE)
POPUP_MENU_ADD_ITEM(STR_CLEAR);
if (popupMenuItemsCount == 1) {
popupMenuItemsCount = 0;
s_currIdx = sub;
pushMenu(menuModelUSBJoystickOne);
}
else {
POPUP_MENU_START(onUSBJoystickMenu);
}
}
char str[20];
for (uint8_t i=0; i<NUM_BODY_LINES; i++) {
y = MENU_HEADER_HEIGHT + 1 + i*FH;
k = i + menuVerticalOffset;
LcdFlags attr = (sub==k) ? INVERS : 0;
USBJoystickChData * cch = usbJChAddress(k);
putsChn(0, y, k+1, attr);
lcdDrawChar(4*FW, y, cch->inversion ? '{' : ' ', 0);
lcdDrawTextAtIndex(MODE_POS, y, STR_VUSBJOYSTICK_CH_MODE_S, cch->mode, 0);
if (cch->mode == USBJOYS_CH_BUTTON) {
lcdDrawTextAtIndex(SUBMODE_POS, y, STR_VUSBJOYSTICK_CH_SWPOS, cch->switch_npos, 0);
lcdDrawTextAtIndex(BTNMODE_POS, y, STR_VUSBJOYSTICK_CH_BTNMODE_S, cch->param, 0);
uint8_t last = cch->lastBtnNum();
if (last > cch->btn_num)
sprintf(str, "%u..%u", cch->btn_num, last);
else
sprintf(str, "%u", cch->btn_num);
LcdFlags warn = 0;
if (isUSBBtnNumCollision(k)) warn = INVERS;
lcdDrawText(BTNNUM_POS, y, str, RIGHT|warn);
}
else if (cch->mode == USBJOYS_CH_AXIS) {
LcdFlags warn = 0;
if (isUSBAxisCollision(k)) warn = INVERS;
lcdDrawTextAtIndex(SUBMODE_POS, y, STR_VUSBJOYSTICK_CH_AXIS, cch->param, warn);
}
else if (cch->mode == USBJOYS_CH_SIM) {
LcdFlags warn = 0;
if (isUSBSimCollision(k)) warn = INVERS;
lcdDrawTextAtIndex(SUBMODE_POS, y, STR_VUSBJOYSTICK_CH_SIM, cch->param, warn);
}
}
}