Trainer UI (#7423)

Trainer UI
This commit is contained in:
3djc
2020-03-06 15:47:34 +01:00
committed by GitHub
parent 766211a6f3
commit 2fb3d977a9
29 changed files with 175 additions and 66 deletions
+1 -1
View File
@@ -1039,7 +1039,7 @@ void menuModelSetup(event_t event)
lcdDrawTextAlignedLeft(y, INDENT TR_MODE);
lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN, y, STR_VTRAINERMODES, g_model.trainerData.mode, attr);
if (attr) {
g_model.trainerData.mode = checkIncDec(event, g_model.trainerData.mode, 0, TRAINER_MODE_MAX(), EE_MODEL, isTrainerModeAvailable);
g_model.trainerData.mode = checkIncDec(event, g_model.trainerData.mode, 0, TRAINER_MODE_MAX, EE_MODEL, isTrainerModeAvailable);
#if defined(BLUETOOTH)
if (checkIncDec_Ret) {
bluetooth.state = BLUETOOTH_STATE_OFF;
+1 -1
View File
@@ -916,7 +916,7 @@ void menuModelSetup(event_t event)
lcdDrawTextAlignedLeft(y, INDENT TR_MODE);
lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN, y, STR_VTRAINERMODES, g_model.trainerData.mode, attr);
if (attr) {
g_model.trainerData.mode = checkIncDec(event, g_model.trainerData.mode, 0, TRAINER_MODE_MAX(), EE_MODEL, isTrainerModeAvailable);
g_model.trainerData.mode = checkIncDec(event, g_model.trainerData.mode, 0, TRAINER_MODE_MAX, EE_MODEL, isTrainerModeAvailable);
#if defined(BLUETOOTH)
if (checkIncDec_Ret) {
bluetooth.state = BLUETOOTH_STATE_OFF;
+88 -1
View File
@@ -449,6 +449,88 @@ class ReceiverButton: public TextButton {
uint8_t receiverIdx;
};
class TrainerModuleWindow : public FormGroup {
public:
TrainerModuleWindow(FormWindow * parent, const rect_t & rect) :
FormGroup(parent, rect, FORWARD_SCROLL | FORM_FORWARD_FOCUS)
{
update();
}
void update()
{
FormGridLayout grid;
clear();
new StaticText(this, grid.getLabelSlot(true), STR_MODE);
moduleChoice = new Choice(this, grid.getFieldSlot(), STR_VTRAINERMODES, 0, TRAINER_MODE_MAX, GET_DEFAULT(g_model.trainerData.mode), [=](int32_t newValue) {
g_model.trainerData.mode = newValue;
update();
SET_DIRTY();
moduleChoice->setFocus();
});
moduleChoice->setAvailableHandler(isTrainerModeAvailable);
grid.nextLine();
if (g_model.trainerData.mode > TRAINER_MODE_OFF) {
new StaticText(this, grid.getLabelSlot(true), STR_CHANNELRANGE);
channelStart = new NumberEdit(this, grid.getFieldSlot(2, 0), 1,
MAX_OUTPUT_CHANNELS - 8 + g_model.trainerData.channelsCount + 1,
GET_DEFAULT(1 + g_model.trainerData.channelsStart));
channelEnd = new NumberEdit(this, grid.getFieldSlot(2, 1),
g_model.trainerData.channelsStart + 1,
min<int8_t>(MAX_TRAINER_CHANNELS, g_model.trainerData.channelsStart + MAX_TRAINER_CHANNELS_M8),
GET_DEFAULT(g_model.trainerData.channelsStart + 8 + g_model.trainerData.channelsCount));
channelStart->setPrefix(STR_CH);
channelEnd->setPrefix(STR_CH);
channelStart->setSetValueHandler([=](int32_t newValue) {
g_model.trainerData.channelsStart = newValue - 1;
SET_DIRTY();
channelEnd->setMin(g_model.trainerData.channelsStart + 1);
channelEnd->setMax(min<int8_t>(MAX_TRAINER_CHANNELS, g_model.trainerData.channelsStart + MAX_TRAINER_CHANNELS_M8));
channelEnd->invalidate();
});
channelEnd->setSetValueHandler([=](int32_t newValue) {
g_model.trainerData.channelsCount = newValue - g_model.trainerData.channelsStart - 8;
SET_DIRTY();
channelStart->setMax(MAX_TRAINER_CHANNELS - 8 + g_model.trainerData.channelsCount + 1);
});
grid.nextLine();
}
if (g_model.trainerData.mode == TRAINER_MODE_SLAVE) {
// PPM frame
new StaticText(this, grid.getLabelSlot(true), STR_PPMFRAME);
// PPM frame length
auto edit = new NumberEdit(this, grid.getFieldSlot(3, 0), 125, 35 * 5 + 225,
GET_DEFAULT(g_model.trainerData.frameLength * 5 + 225),
SET_VALUE(g_model.trainerData.frameLength, (newValue - 225) / 5),
PREC1);
edit->setStep(5);
edit->setSuffix(STR_MS);
// PPM frame delay
edit = new NumberEdit(this, grid.getFieldSlot(3, 1), 100, 800,
GET_DEFAULT(g_model.trainerData.delay * 50 + 300),
SET_VALUE(g_model.trainerData.delay, (newValue - 300) / 50));
edit->setStep(50);
edit->setSuffix("us");
// PPM Polarity
new Choice(this, grid.getFieldSlot(3, 2), STR_PPM_POL, 0, 1, GET_SET_DEFAULT(g_model.trainerData.pulsePol ));
grid.nextLine();
}
getParent()->moveWindowsTop(top(), adjustHeight());
getParent()->invalidate(); // TODO should be automatically done
}
protected:
Choice * moduleChoice = nullptr;
NumberEdit * channelStart = nullptr;
NumberEdit * channelEnd = nullptr;
};
class ModuleWindow : public FormGroup {
public:
ModuleWindow(FormWindow * parent, const rect_t &rect, uint8_t moduleIdx) :
@@ -1067,7 +1149,12 @@ void ModelSetupPage::build(FormWindow * window)
grid.addWindow(new ModuleWindow(window, {0, grid.getWindowHeight(), LCD_W, 0}, EXTERNAL_MODULE));
}
grid.nextLine();
// Trainer
{
new Subtitle(window, grid.getLineSlot(), STR_TRAINER);
grid.nextLine();
grid.addWindow(new TrainerModuleWindow(window, {0, grid.getWindowHeight(), LCD_W, 0}));
}
window->setInnerHeight(grid.getWindowHeight());
}
+39 -30
View File
@@ -734,40 +734,49 @@ bool isTelemetryProtocolAvailable(int protocol)
bool isTrainerModeAvailable(int mode)
{
#if defined(PCBTARANIS)
if (IS_EXTERNAL_MODULE_ENABLED() && (mode == TRAINER_MODE_MASTER_SBUS_EXTERNAL_MODULE || mode == TRAINER_MODE_MASTER_CPPM_EXTERNAL_MODULE))
return false;
switch(mode) {
#if defined(HARDWARE_TRAINER_EXTERNAL_MODULE)
case TRAINER_MODE_MASTER_SBUS_EXTERNAL_MODULE:
case TRAINER_MODE_MASTER_CPPM_EXTERNAL_MODULE:
return !IS_EXTERNAL_MODULE_ENABLED();
#endif
#if defined(PCBX9E)
if (g_eeGeneral.bluetoothMode && mode == TRAINER_MODE_MASTER_SBUS_EXTERNAL_MODULE) {
// bluetooth uses the same USART than SBUS
return false;
case TRAINER_MODE_MASTER_SBUS_EXTERNAL_MODULE:
// bluetooth uses the same USART than SBUS
return !g_eeGeneral.bluetoothMode;
#endif
#if defined(HARDWARE_TRAINER_AUX_SERIAL)
case TRAINER_MODE_MASTER_BATTERY_COMPARTMENT:
return g_eeGeneral.auxSerialMode == UART_MODE_SBUS_TRAINER;
#endif
#if defined(HARDWARE_TRAINER_BLUETOOTH)
case TRAINER_MODE_MASTER_BLUETOOTH:
case TRAINER_MODE_SLAVE_BLUETOOTH:
return g_eeGeneral.bluetoothMode == BLUETOOTH_TRAINER;
#endif
#if defined(HARDWARE_TRAINER_JACK)
case TRAINER_MODE_MASTER_TRAINER_JACK:
case TRAINER_MODE_SLAVE:
return true;
#endif
#if defined(HARDWARE_TRAINER_MULTI)
case TRAINER_MODE_MULTI:
return true;
#endif
#if !defined(TRAINER_DETECT_GPIO)
case TRAINER_MODE_OFF:
return true;
#endif
default:
return false;
}
#endif
#if defined(PCBTARANIS) && !defined(TRAINER_BATTERY_COMPARTMENT)
if (mode == TRAINER_MODE_MASTER_BATTERY_COMPARTMENT)
return false;
#elif defined(PCBTARANIS)
if (mode == TRAINER_MODE_MASTER_BATTERY_COMPARTMENT)
return g_eeGeneral.auxSerialMode == UART_MODE_SBUS_TRAINER;
#endif
#if defined(PCBX9E)
if (mode == TRAINER_MODE_MASTER_BLUETOOTH || mode == TRAINER_MODE_SLAVE_BLUETOOTH)
return false;
#elif defined(BLUETOOTH)
if (g_eeGeneral.bluetoothMode != BLUETOOTH_TRAINER && (mode == TRAINER_MODE_MASTER_BLUETOOTH || mode == TRAINER_MODE_SLAVE_BLUETOOTH))
return false;
#endif
#if defined(PCBXLITE) && !defined(PCBXLITES)
if (mode == TRAINER_MODE_MASTER_TRAINER_JACK || mode == TRAINER_MODE_SLAVE)
return false;
#endif
return true;
}
bool modelHasNotes()