mirror of
https://github.com/opentx/opentx.git
synced 2025-07-14 11:59:50 +03:00
ModelEdit window splitted (one file per tab). Templates/Wizard still have to be re-introduced, but in a menu instead of a Model tab
This commit is contained in:
parent
39a4b8e39d
commit
b802bc5db2
68 changed files with 14773 additions and 32446 deletions
|
@ -109,6 +109,8 @@ add_custom_command(
|
||||||
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/firmwares/ersky9x/ersky9xsimulator.cpp
|
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/firmwares/ersky9x/ersky9xsimulator.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
|
add_subdirectory(modeledit)
|
||||||
|
|
||||||
SET( companion9x_SRCS
|
SET( companion9x_SRCS
|
||||||
eeprominterface.cpp
|
eeprominterface.cpp
|
||||||
hexinterface.cpp
|
hexinterface.cpp
|
||||||
|
@ -137,15 +139,11 @@ SET( companion9x_SRCS
|
||||||
firmwares/ersky9x/ersky9xeeprom.cpp
|
firmwares/ersky9x/ersky9xeeprom.cpp
|
||||||
firmwares/ersky9x/ersky9xinterface.cpp
|
firmwares/ersky9x/ersky9xinterface.cpp
|
||||||
${ERSKY9X_CHECKOUT_DIRECTORY}/ersky9xsimulator.cpp
|
${ERSKY9X_CHECKOUT_DIRECTORY}/ersky9xsimulator.cpp
|
||||||
node.cpp
|
|
||||||
edge.cpp
|
|
||||||
helpers.cpp
|
helpers.cpp
|
||||||
mdichild.cpp
|
mdichild.cpp
|
||||||
generaledit.cpp
|
generaledit.cpp
|
||||||
modeledit.cpp
|
|
||||||
modelslist.cpp
|
modelslist.cpp
|
||||||
mountlist.cpp
|
mountlist.cpp
|
||||||
mixerslist.cpp
|
|
||||||
avroutputdialog.cpp
|
avroutputdialog.cpp
|
||||||
preferencesdialog.cpp
|
preferencesdialog.cpp
|
||||||
burnconfigdialog.cpp
|
burnconfigdialog.cpp
|
||||||
|
@ -155,8 +153,6 @@ SET( companion9x_SRCS
|
||||||
burndialog.cpp
|
burndialog.cpp
|
||||||
printdialog.cpp
|
printdialog.cpp
|
||||||
fusesdialog.cpp
|
fusesdialog.cpp
|
||||||
expodialog.cpp
|
|
||||||
mixerdialog.cpp
|
|
||||||
logsdialog.cpp
|
logsdialog.cpp
|
||||||
downloaddialog.cpp
|
downloaddialog.cpp
|
||||||
simulatordialog.cpp
|
simulatordialog.cpp
|
||||||
|
@ -175,9 +171,7 @@ SET( companion9x_MOC_HDRS
|
||||||
comparedialog.h
|
comparedialog.h
|
||||||
printdialog.h
|
printdialog.h
|
||||||
fusesdialog.h
|
fusesdialog.h
|
||||||
mixerdialog.h
|
|
||||||
logsdialog.h
|
logsdialog.h
|
||||||
expodialog.h
|
|
||||||
contributorsdialog.h
|
contributorsdialog.h
|
||||||
customizesplashdialog.h
|
customizesplashdialog.h
|
||||||
splashlibrary.h
|
splashlibrary.h
|
||||||
|
@ -191,9 +185,7 @@ SET( companion9x_MOC_HDRS
|
||||||
xmenuwidget.h
|
xmenuwidget.h
|
||||||
xsimulatordialog.h
|
xsimulatordialog.h
|
||||||
generaledit.h
|
generaledit.h
|
||||||
modeledit.h
|
|
||||||
modelslist.h
|
modelslist.h
|
||||||
mixerslist.h
|
|
||||||
mdichild.h
|
mdichild.h
|
||||||
mainwindow.h
|
mainwindow.h
|
||||||
myslider.h
|
myslider.h
|
||||||
|
@ -206,16 +198,13 @@ SET( companion9x_UIS
|
||||||
avroutputdialog.ui
|
avroutputdialog.ui
|
||||||
comparedialog.ui
|
comparedialog.ui
|
||||||
fusesdialog.ui
|
fusesdialog.ui
|
||||||
expodialog.ui
|
|
||||||
logsdialog.ui
|
logsdialog.ui
|
||||||
mixerdialog.ui
|
|
||||||
preferencesdialog.ui
|
preferencesdialog.ui
|
||||||
simulatordialog.ui
|
simulatordialog.ui
|
||||||
xsimulatordialog.ui
|
xsimulatordialog.ui
|
||||||
burnconfigdialog.ui
|
burnconfigdialog.ui
|
||||||
downloaddialog.ui
|
downloaddialog.ui
|
||||||
generaledit.ui
|
generaledit.ui
|
||||||
modeledit.ui
|
|
||||||
printdialog.ui
|
printdialog.ui
|
||||||
contributorsdialog.ui
|
contributorsdialog.ui
|
||||||
customizesplashdialog.ui
|
customizesplashdialog.ui
|
||||||
|
@ -314,7 +303,7 @@ ELSE( )
|
||||||
ADD_EXECUTABLE( ${PROJECT_NAME} WIN32 ${companion9x_SRCS} ${companion9x_QM} )
|
ADD_EXECUTABLE( ${PROJECT_NAME} WIN32 ${companion9x_SRCS} ${companion9x_QM} )
|
||||||
ENDIF( )
|
ENDIF( )
|
||||||
|
|
||||||
TARGET_LINK_LIBRARIES( ${PROJECT_NAME} ${QT_LIBRARIES} ${QT_QTMAIN_LIBRARY} ${XERCESC_LIBRARY} ${PTHREAD_LIBRARY} ${SDL_LIBRARY} ${PHONON_LIBS} )
|
TARGET_LINK_LIBRARIES( ${PROJECT_NAME} modeledit ${QT_LIBRARIES} ${QT_QTMAIN_LIBRARY} ${XERCESC_LIBRARY} ${PTHREAD_LIBRARY} ${SDL_LIBRARY} ${PHONON_LIBS} )
|
||||||
|
|
||||||
IF(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
|
IF(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
|
||||||
INSTALL( TARGETS ${PROJECT_NAME} DESTINATION ${CMAKE_INSTALL_PREFIX}/bin )
|
INSTALL( TARGETS ${PROJECT_NAME} DESTINATION ${CMAKE_INSTALL_PREFIX}/bin )
|
||||||
|
|
|
@ -21,7 +21,7 @@ public:
|
||||||
}
|
}
|
||||||
bool general_settings;
|
bool general_settings;
|
||||||
uint8_t models_count;
|
uint8_t models_count;
|
||||||
uint8_t models[C9XMAX_MODELS];
|
uint8_t models[C9X_MAX_MODELS];
|
||||||
};
|
};
|
||||||
|
|
||||||
compareDialog::compareDialog(QWidget *parent, GeneralSettings *gg) :
|
compareDialog::compareDialog(QWidget *parent, GeneralSettings *gg) :
|
||||||
|
@ -342,7 +342,7 @@ void compareDialog::printPhases()
|
||||||
gvars=1;
|
gvars=1;
|
||||||
}
|
}
|
||||||
if (gvars==1) {
|
if (gvars==1) {
|
||||||
gvarnum=GetEepromInterface()->getCapability(GvarsNum);
|
gvarnum=GetEepromInterface()->getCapability(Gvars);
|
||||||
}
|
}
|
||||||
if ((gvars==1 && GetEepromInterface()->getCapability(GvarsFlightPhases)) || GetEepromInterface()->getCapability(RotaryEncoders)) {
|
if ((gvars==1 && GetEepromInterface()->getCapability(GvarsFlightPhases)) || GetEepromInterface()->getCapability(RotaryEncoders)) {
|
||||||
str.append("<br><table border=1 cellspacing=0 cellpadding=1 width=\"100%\">");
|
str.append("<br><table border=1 cellspacing=0 cellpadding=1 width=\"100%\">");
|
||||||
|
@ -564,7 +564,7 @@ void compareDialog::printGvars()
|
||||||
int gvarnum=0;
|
int gvarnum=0;
|
||||||
if ((GetCurrentFirmwareVariant() & GVARS_VARIANT ) || (!GetEepromInterface()->getCapability(HasVariants) && GetEepromInterface()->getCapability(Gvars))) {
|
if ((GetCurrentFirmwareVariant() & GVARS_VARIANT ) || (!GetEepromInterface()->getCapability(HasVariants) && GetEepromInterface()->getCapability(Gvars))) {
|
||||||
gvars=1;
|
gvars=1;
|
||||||
gvarnum=GetEepromInterface()->getCapability(GvarsNum);
|
gvarnum=GetEepromInterface()->getCapability(Gvars);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!GetEepromInterface()->getCapability(GvarsFlightPhases) && (gvars==1 && GetEepromInterface()->getCapability(Gvars))) {
|
if (!GetEepromInterface()->getCapability(GvarsFlightPhases) && (gvars==1 && GetEepromInterface()->getCapability(Gvars))) {
|
||||||
|
|
|
@ -534,6 +534,18 @@ ModelData::ModelData()
|
||||||
clear();
|
clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ModelData::clearInputs()
|
||||||
|
{
|
||||||
|
for (int i=0; i<C9X_MAX_EXPOS; i++)
|
||||||
|
expoData[i].clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ModelData::clearMixes()
|
||||||
|
{
|
||||||
|
for (int i=0; i<C9X_MAX_MIXERS; i++)
|
||||||
|
mixData[i].clear();
|
||||||
|
}
|
||||||
|
|
||||||
void ModelData::clear()
|
void ModelData::clear()
|
||||||
{
|
{
|
||||||
memset(this, 0, sizeof(ModelData));
|
memset(this, 0, sizeof(ModelData));
|
||||||
|
@ -553,10 +565,8 @@ void ModelData::clear()
|
||||||
}
|
}
|
||||||
for (int i=0; i<C9X_MAX_PHASES; i++)
|
for (int i=0; i<C9X_MAX_PHASES; i++)
|
||||||
phaseData[i].clear();
|
phaseData[i].clear();
|
||||||
for (int i=0; i<C9X_MAX_EXPOS; i++)
|
clearInputs();
|
||||||
expoData[i].clear();
|
clearMixes();
|
||||||
for (int i=0; i<C9X_MAX_MIXERS; i++)
|
|
||||||
mixData[i].clear();
|
|
||||||
for(int i=0; i<4; i++){
|
for(int i=0; i<4; i++){
|
||||||
mixData[i].destCh = i+1;
|
mixData[i].destCh = i+1;
|
||||||
mixData[i].srcRaw = RawSource(SOURCE_TYPE_STICK, i);
|
mixData[i].srcRaw = RawSource(SOURCE_TYPE_STICK, i);
|
||||||
|
|
|
@ -59,13 +59,14 @@ const uint8_t modn12x3[4][4]= {
|
||||||
{4, 2, 3, 1},
|
{4, 2, 3, 1},
|
||||||
{4, 3, 2, 1} };
|
{4, 3, 2, 1} };
|
||||||
|
|
||||||
#define C9XMAX_MODELS 60
|
#define C9X_MAX_MODELS 60
|
||||||
#define C9X_MAX_PHASES 9
|
#define C9X_MAX_PHASES 9
|
||||||
#define C9X_MAX_MIXERS 64
|
#define C9X_MAX_MIXERS 64
|
||||||
#define C9X_MAX_EXPOS 32
|
#define C9X_MAX_EXPOS 32
|
||||||
#define C9X_MAX_CURVES 16
|
#define C9X_MAX_CURVES 16
|
||||||
#define MAX_POINTS 17
|
#define C9X_MAX_POINTS 17
|
||||||
#define C9X_MAX_GVARS 9
|
#define C9X_MAX_GVARS 9
|
||||||
|
#define C9X_MAX_ENCODERS 2
|
||||||
#define NUM_SAFETY_CHNOUT 16
|
#define NUM_SAFETY_CHNOUT 16
|
||||||
#define C9X_NUM_CHNOUT 32 // number of real output channels
|
#define C9X_NUM_CHNOUT 32 // number of real output channels
|
||||||
#define C9X_NUM_CSW 32 // number of custom switches
|
#define C9X_NUM_CSW 32 // number of custom switches
|
||||||
|
@ -107,6 +108,18 @@ const uint8_t chout_ar[] = { //First number is 0..23 -> template setup, Second
|
||||||
3,1,2,4 , 3,1,4,2 , 3,2,1,4 , 3,2,4,1 , 3,4,1,2 , 3,4,2,1,
|
3,1,2,4 , 3,1,4,2 , 3,2,1,4 , 3,2,4,1 , 3,4,1,2 , 3,4,2,1,
|
||||||
4,1,2,3 , 4,1,3,2 , 4,2,1,3 , 4,2,3,1 , 4,3,1,2 , 4,3,2,1 }; // TODO delete it?
|
4,1,2,3 , 4,1,3,2 , 4,2,1,3 , 4,2,3,1 , 4,3,1,2 , 4,3,2,1 }; // TODO delete it?
|
||||||
|
|
||||||
|
// Beep center bits
|
||||||
|
#define BC_BIT_RUD (0x01)
|
||||||
|
#define BC_BIT_ELE (0x02)
|
||||||
|
#define BC_BIT_THR (0x04)
|
||||||
|
#define BC_BIT_AIL (0x08)
|
||||||
|
#define BC_BIT_P1 (0x10)
|
||||||
|
#define BC_BIT_P2 (0x20)
|
||||||
|
#define BC_BIT_P3 (0x40)
|
||||||
|
#define BC_BIT_P4 (0x80)
|
||||||
|
#define BC_BIT_REA (0x80)
|
||||||
|
#define BC_BIT_REB (0x100)
|
||||||
|
|
||||||
// TODO remove this enum!
|
// TODO remove this enum!
|
||||||
enum EnumKeys {
|
enum EnumKeys {
|
||||||
KEY_MENU,
|
KEY_MENU,
|
||||||
|
@ -477,7 +490,7 @@ class CurveData {
|
||||||
CurveData() { clear(5); }
|
CurveData() { clear(5); }
|
||||||
bool custom; // 0=end, 1=pos, 2=neg, 3=both
|
bool custom; // 0=end, 1=pos, 2=neg, 3=both
|
||||||
uint8_t count;
|
uint8_t count;
|
||||||
CurvePoint points[MAX_POINTS];
|
CurvePoint points[C9X_MAX_POINTS];
|
||||||
char name[6+1];
|
char name[6+1];
|
||||||
void clear(int count) { memset(this, 0, sizeof(CurveData)); this->count = count; }
|
void clear(int count) { memset(this, 0, sizeof(CurveData)); this->count = count; }
|
||||||
};
|
};
|
||||||
|
@ -828,6 +841,9 @@ class ModelData {
|
||||||
|
|
||||||
ModelData removeGlobalVars();
|
ModelData removeGlobalVars();
|
||||||
|
|
||||||
|
void clearMixes();
|
||||||
|
void clearInputs();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void removeGlobalVar(int & var);
|
void removeGlobalVar(int & var);
|
||||||
};
|
};
|
||||||
|
@ -835,13 +851,14 @@ class ModelData {
|
||||||
class RadioData {
|
class RadioData {
|
||||||
public:
|
public:
|
||||||
GeneralSettings generalSettings;
|
GeneralSettings generalSettings;
|
||||||
ModelData models[C9XMAX_MODELS];
|
ModelData models[C9X_MAX_MODELS];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// TODO rename FlightPhase to FlightMode
|
||||||
enum Capability {
|
enum Capability {
|
||||||
OwnerName,
|
OwnerName,
|
||||||
FlightPhases,
|
FlightPhases,
|
||||||
FlightPhasesAreNamed,
|
FlightModesName,
|
||||||
FlightPhasesHaveFades,
|
FlightPhasesHaveFades,
|
||||||
SimulatorType,
|
SimulatorType,
|
||||||
Mixes,
|
Mixes,
|
||||||
|
@ -867,6 +884,7 @@ enum Capability {
|
||||||
CustomSwitchesExt,
|
CustomSwitchesExt,
|
||||||
RotaryEncoders,
|
RotaryEncoders,
|
||||||
Outputs,
|
Outputs,
|
||||||
|
ChannelsName,
|
||||||
ExtraChannels,
|
ExtraChannels,
|
||||||
ExtraInputs,
|
ExtraInputs,
|
||||||
ExtraTrims,
|
ExtraTrims,
|
||||||
|
@ -931,7 +949,7 @@ enum Capability {
|
||||||
GvarsHaveSources,
|
GvarsHaveSources,
|
||||||
GvarsAsSources,
|
GvarsAsSources,
|
||||||
GvarsAsWeight,
|
GvarsAsWeight,
|
||||||
GvarsNum,
|
GvarsName,
|
||||||
GvarsOfsNum,
|
GvarsOfsNum,
|
||||||
NoTelemetryProtocol,
|
NoTelemetryProtocol,
|
||||||
TelemetryCSFields,
|
TelemetryCSFields,
|
||||||
|
|
|
@ -286,8 +286,6 @@ int Er9xInterface::getCapability(const Capability capability)
|
||||||
return 12;
|
return 12;
|
||||||
case CustomAndSwitches:
|
case CustomAndSwitches:
|
||||||
return 5;
|
return 5;
|
||||||
case GvarsNum:
|
|
||||||
return 7;
|
|
||||||
case GvarsOfsNum:
|
case GvarsOfsNum:
|
||||||
return 5;
|
return 5;
|
||||||
case CSFunc:
|
case CSFunc:
|
||||||
|
@ -332,7 +330,9 @@ int Er9xInterface::getCapability(const Capability capability)
|
||||||
case DiffMixers:
|
case DiffMixers:
|
||||||
case HasNegCurves:
|
case HasNegCurves:
|
||||||
case HasFixOffset:
|
case HasFixOffset:
|
||||||
|
return 1;
|
||||||
case Gvars:
|
case Gvars:
|
||||||
|
return 7;
|
||||||
case GvarsHaveSources:
|
case GvarsHaveSources:
|
||||||
case GvarsAsSources:
|
case GvarsAsSources:
|
||||||
case GvarsAsWeight:
|
case GvarsAsWeight:
|
||||||
|
|
|
@ -306,7 +306,7 @@ int Ersky9xInterface::getCapability(const Capability capability)
|
||||||
return 2;
|
return 2;
|
||||||
case Pots:
|
case Pots:
|
||||||
return 3;
|
return 3;
|
||||||
case GvarsNum:
|
case Gvars:
|
||||||
return 7;
|
return 7;
|
||||||
case GvarsOfsNum:
|
case GvarsOfsNum:
|
||||||
return 5;
|
return 5;
|
||||||
|
@ -350,7 +350,6 @@ int Ersky9xInterface::getCapability(const Capability capability)
|
||||||
return 125;
|
return 125;
|
||||||
case MaxVolume:
|
case MaxVolume:
|
||||||
return 23;
|
return 23;
|
||||||
case Gvars:
|
|
||||||
case GvarsHaveSources:
|
case GvarsHaveSources:
|
||||||
case GvarsAsSources:
|
case GvarsAsSources:
|
||||||
case GvarsAsWeight:
|
case GvarsAsWeight:
|
||||||
|
|
|
@ -562,9 +562,13 @@ int Open9xInterface::getCapability(const Capability capability)
|
||||||
return 6;
|
return 6;
|
||||||
else
|
else
|
||||||
return 5;
|
return 5;
|
||||||
case FlightPhasesAreNamed:
|
|
||||||
case FlightPhasesHaveFades:
|
case FlightPhasesHaveFades:
|
||||||
|
return 1;
|
||||||
case Gvars:
|
case Gvars:
|
||||||
|
return 5;
|
||||||
|
case FlightModesName:
|
||||||
|
case GvarsName:
|
||||||
|
return (IS_TARANIS(board) ? 10 : 6);
|
||||||
case GvarsInCS:
|
case GvarsInCS:
|
||||||
case GvarsAsWeight:
|
case GvarsAsWeight:
|
||||||
case ExpoIsCurve:
|
case ExpoIsCurve:
|
||||||
|
@ -692,8 +696,8 @@ int Open9xInterface::getCapability(const Capability capability)
|
||||||
return (IS_ARM(board) ? (IS_TARANIS(board) ? 8 : 6) : false);
|
return (IS_ARM(board) ? (IS_TARANIS(board) ? 8 : 6) : false);
|
||||||
case HasExpoNames:
|
case HasExpoNames:
|
||||||
return (IS_ARM(board) ? (IS_TARANIS(board) ? 8 : 6) : false);
|
return (IS_ARM(board) ? (IS_TARANIS(board) ? 8 : 6) : false);
|
||||||
case HasChNames:
|
case ChannelsName:
|
||||||
return (IS_TARANIS(board) ? 1 : 0);
|
return (IS_TARANIS(board) ? 6 : 0);
|
||||||
case HasCvNames:
|
case HasCvNames:
|
||||||
return (IS_TARANIS(board) ? 1 : 0);
|
return (IS_TARANIS(board) ? 1 : 0);
|
||||||
case NoTimerDirs:
|
case NoTimerDirs:
|
||||||
|
@ -777,7 +781,6 @@ int Open9xInterface::getCapability(const Capability capability)
|
||||||
return (IS_ARM(board) ? 250 : 15);
|
return (IS_ARM(board) ? 250 : 15);
|
||||||
case CSFunc:
|
case CSFunc:
|
||||||
return 18;
|
return 18;
|
||||||
case GvarsNum:
|
|
||||||
case GvarsOfsNum:
|
case GvarsOfsNum:
|
||||||
return 5;
|
return 5;
|
||||||
case HasSDLogs:
|
case HasSDLogs:
|
||||||
|
|
|
@ -560,15 +560,12 @@ void populateTrimUseCB(QComboBox *b, unsigned int phase)
|
||||||
void populateGvarUseCB(QComboBox *b, unsigned int phase)
|
void populateGvarUseCB(QComboBox *b, unsigned int phase)
|
||||||
{
|
{
|
||||||
b->addItem(QObject::tr("Own value"));
|
b->addItem(QObject::tr("Own value"));
|
||||||
unsigned int num_phases = GetEepromInterface()->getCapability(FlightPhases);
|
for (int i=0; i<GetEepromInterface()->getCapability(FlightPhases); i++) {
|
||||||
if (num_phases>0) {
|
if (i != (int)phase) {
|
||||||
for (unsigned int i = 0; i < num_phases; i++) {
|
|
||||||
if (i != phase) {
|
|
||||||
b->addItem(QObject::tr("Flight mode %1 value").arg(i));
|
b->addItem(QObject::tr("Flight mode %1 value").arg(i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void populateTimerSwitchCB(QComboBox *b, int value, int extrafields)
|
void populateTimerSwitchCB(QComboBox *b, int value, int extrafields)
|
||||||
{
|
{
|
||||||
|
@ -983,7 +980,7 @@ void populateSourceCB(QComboBox *b, const RawSource &source, unsigned int flags)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flags & POPULATE_GVARS) {
|
if (flags & POPULATE_GVARS) {
|
||||||
for (int i=0; i<GetEepromInterface()->getCapability(GvarsNum); i++) {
|
for (int i=0; i<GetEepromInterface()->getCapability(Gvars); i++) {
|
||||||
item = RawSource(SOURCE_TYPE_GVAR, i);
|
item = RawSource(SOURCE_TYPE_GVAR, i);
|
||||||
b->addItem(item.toString(), item.toValue());
|
b->addItem(item.toString(), item.toValue());
|
||||||
if (item == source) b->setCurrentIndex(b->count()-1);
|
if (item == source) b->setCurrentIndex(b->count()-1);
|
||||||
|
|
|
@ -6,10 +6,10 @@
|
||||||
|
|
||||||
#define TMR_NUM_OPTION (TMR_VAROFS+2*9+2*GetEepromInterface()->getCapability(CustomSwitches)-1)
|
#define TMR_NUM_OPTION (TMR_VAROFS+2*9+2*GetEepromInterface()->getCapability(CustomSwitches)-1)
|
||||||
|
|
||||||
//convert from mode 1 to mode g_eeGeneral.stickMode
|
//convert from mode 1 to mode generalSettings.stickMode
|
||||||
//NOTICE! => 1..4 -> 1..4
|
//NOTICE! => 1..4 -> 1..4
|
||||||
#define CONVERT_MODE(x) (((x)<=4) ? modn12x3[g_eeGeneral.stickMode][((x)-1)] : (x))
|
#define CONVERT_MODE(x) (((x)<=4) ? modn12x3[generalSettings.stickMode][((x)-1)] : (x))
|
||||||
#define CHANNEL_ORDER(x) (chout_ar[g_eeGeneral.templateSetup*4 + (x)-1])
|
#define CHANNEL_ORDER(x) (chout_ar[generalSettings.templateSetup*4 + (x)-1])
|
||||||
|
|
||||||
#define CURVE_BASE 7
|
#define CURVE_BASE 7
|
||||||
#define CH(x) (SRC_CH1+(x)-1-(SRC_SWC-SRC_3POS))
|
#define CH(x) (SRC_CH1+(x)-1-(SRC_SWC-SRC_3POS))
|
||||||
|
|
|
@ -44,7 +44,7 @@
|
||||||
#include "xmlinterface.h"
|
#include "xmlinterface.h"
|
||||||
#include "hexinterface.h"
|
#include "hexinterface.h"
|
||||||
#include "mainwindow.h"
|
#include "mainwindow.h"
|
||||||
#include "modeledit.h"
|
#include "modeledit/modeledit.h"
|
||||||
#include "generaledit.h"
|
#include "generaledit.h"
|
||||||
#include "avroutputdialog.h"
|
#include "avroutputdialog.h"
|
||||||
#include "burnconfigdialog.h"
|
#include "burnconfigdialog.h"
|
||||||
|
@ -192,9 +192,9 @@ void MdiChild::OpenEditWindow(bool wizard=false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ModelEdit *t = new ModelEdit(radioData, (row - 1), wizard, this);
|
ModelEdit *t = new ModelEdit(radioData, (row - 1), wizard, this);
|
||||||
if (isNew && !wizard) t->applyBaseTemplate();
|
// TODO if (isNew && !wizard) t->applyBaseTemplate();
|
||||||
t->setWindowTitle(tr("Editing model %1: ").arg(row) + model.name);
|
t->setWindowTitle(tr("Editing model %1: ").arg(row) + model.name);
|
||||||
connect(t, SIGNAL(modelValuesChanged()), this, SLOT(setModified()));
|
connect(t, SIGNAL(modified()), this, SLOT(setModified()));
|
||||||
//t->exec();
|
//t->exec();
|
||||||
t->show();
|
t->show();
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@ modelConfigDialog::modelConfigDialog(RadioData &radioData, uint64_t * result, QW
|
||||||
ui(new Ui::modelConfigDialog),
|
ui(new Ui::modelConfigDialog),
|
||||||
radioData(radioData),
|
radioData(radioData),
|
||||||
result(result),
|
result(result),
|
||||||
g_eeGeneral(radioData.generalSettings)
|
generalSettings(radioData.generalSettings)
|
||||||
{
|
{
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
rxLock=false;
|
rxLock=false;
|
||||||
|
|
|
@ -23,7 +23,7 @@ private:
|
||||||
int ModelType;
|
int ModelType;
|
||||||
RadioData &radioData;
|
RadioData &radioData;
|
||||||
uint64_t * result;
|
uint64_t * result;
|
||||||
GeneralSettings g_eeGeneral;
|
GeneralSettings generalSettings;
|
||||||
QStringList ruddercolor;
|
QStringList ruddercolor;
|
||||||
QStringList aileroncolor;
|
QStringList aileroncolor;
|
||||||
QStringList elevatorcolor;
|
QStringList elevatorcolor;
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,393 +0,0 @@
|
||||||
#ifndef MODELEDIT_H
|
|
||||||
#define MODELEDIT_H
|
|
||||||
|
|
||||||
#include <QDialog>
|
|
||||||
#include <QtGui>
|
|
||||||
#include <QPen>
|
|
||||||
#include "eeprominterface.h"
|
|
||||||
#include "mixerslist.h"
|
|
||||||
#ifdef PHONON
|
|
||||||
#include <phonon/audiooutput.h>
|
|
||||||
#include <phonon/mediaobject.h>
|
|
||||||
#include <phonon/mediasource.h>
|
|
||||||
#endif
|
|
||||||
namespace Ui {
|
|
||||||
class ModelEdit;
|
|
||||||
}
|
|
||||||
|
|
||||||
class ModelEdit : public QDialog
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit ModelEdit(RadioData &radioData, uint8_t id , bool openWizard =false, bool inNew =false, QWidget *parent = 0);
|
|
||||||
~ModelEdit();
|
|
||||||
|
|
||||||
void applyBaseTemplate();
|
|
||||||
bool redrawCurve;
|
|
||||||
void drawCurve();
|
|
||||||
bool drawing;
|
|
||||||
bool mixInserted;
|
|
||||||
bool expoInserted;
|
|
||||||
bool openWizard;
|
|
||||||
bool isNew;
|
|
||||||
private:
|
|
||||||
Ui::ModelEdit *ui;
|
|
||||||
|
|
||||||
QSpinBox* spny[17];
|
|
||||||
QSpinBox* spnx[17];
|
|
||||||
QSpinBox* gvarsSB[9][5];
|
|
||||||
QSpinBox* reSB[9][2];
|
|
||||||
QGroupBox* barsGB[3];
|
|
||||||
QGroupBox* numsGB[3];
|
|
||||||
QComboBox* barsCB[12];
|
|
||||||
QDoubleSpinBox* minSB[12];
|
|
||||||
QDoubleSpinBox* maxSB[12];
|
|
||||||
QComboBox* csf[36];
|
|
||||||
QComboBox* csw[C9X_NUM_CSW];
|
|
||||||
MixersList *ExposlistWidget;
|
|
||||||
|
|
||||||
MixersList *MixerlistWidget;
|
|
||||||
|
|
||||||
RadioData &radioData;
|
|
||||||
int id_model;
|
|
||||||
ModelData g_model;
|
|
||||||
GeneralSettings g_eeGeneral;
|
|
||||||
bool protocolEditLock;
|
|
||||||
bool protocol2EditLock;
|
|
||||||
bool trainerEditLock;
|
|
||||||
bool switchEditLock;
|
|
||||||
bool heliEditLock;
|
|
||||||
bool limitEditLock;
|
|
||||||
bool phasesLock;
|
|
||||||
bool telemetryLock;
|
|
||||||
bool curvesLock;
|
|
||||||
bool phononLock;
|
|
||||||
bool fsLock;
|
|
||||||
bool modelImageLock;
|
|
||||||
bool plot_curve[16];
|
|
||||||
int selectedSwitch;
|
|
||||||
int selectedFunction;
|
|
||||||
QDoubleSpinBox * cswitchValue[C9X_NUM_CSW];
|
|
||||||
QDoubleSpinBox * cswitchOffset[C9X_NUM_CSW];
|
|
||||||
QComboBox * cswitchAnd[C9X_NUM_CSW];
|
|
||||||
QDoubleSpinBox * cswitchDuration[C9X_NUM_CSW];
|
|
||||||
QDoubleSpinBox * cswitchDelay[C9X_NUM_CSW];
|
|
||||||
QComboBox * cswitchSource1[C9X_NUM_CSW];
|
|
||||||
QComboBox * cswitchSource2[C9X_NUM_CSW];
|
|
||||||
QLabel * fswLabel[C9X_MAX_CUSTOM_FUNCTIONS];
|
|
||||||
QComboBox * fswtchSwtch[C9X_MAX_CUSTOM_FUNCTIONS];
|
|
||||||
QComboBox * fswtchFunc[C9X_MAX_CUSTOM_FUNCTIONS];
|
|
||||||
QCheckBox * fswtchParamGV[C9X_MAX_CUSTOM_FUNCTIONS];
|
|
||||||
QDoubleSpinBox * fswtchParam[C9X_MAX_CUSTOM_FUNCTIONS];
|
|
||||||
QPushButton * playBT[C9X_MAX_CUSTOM_FUNCTIONS];
|
|
||||||
QComboBox * fswtchParamT[C9X_MAX_CUSTOM_FUNCTIONS];
|
|
||||||
QComboBox * fswtchParamArmT[C9X_MAX_CUSTOM_FUNCTIONS];
|
|
||||||
QCheckBox * fswtchEnable[C9X_MAX_CUSTOM_FUNCTIONS];
|
|
||||||
QComboBox * fswtchRepeat[C9X_MAX_CUSTOM_FUNCTIONS];
|
|
||||||
QComboBox * fswtchGVmode[C9X_MAX_CUSTOM_FUNCTIONS];
|
|
||||||
|
|
||||||
QSpinBox * safetySwitchValue[C9X_NUM_CHNOUT];
|
|
||||||
QComboBox * safetySwitchSwtch[C9X_NUM_CHNOUT];
|
|
||||||
QSlider * phasesTrimSliders[9][4];
|
|
||||||
QSpinBox * phasesTrimValues[9][4];
|
|
||||||
|
|
||||||
void setupExposListWidget();
|
|
||||||
void setupMixerListWidget();
|
|
||||||
float getBarStep(int barId);
|
|
||||||
void telBarUpdate();
|
|
||||||
|
|
||||||
void updateSettings();
|
|
||||||
void tabModelEditSetup();
|
|
||||||
void tabPhases();
|
|
||||||
void tabExpos();
|
|
||||||
void tabMixes();
|
|
||||||
void tabHeli();
|
|
||||||
void tabLimits();
|
|
||||||
void tabCurves();
|
|
||||||
void tabCustomSwitches();
|
|
||||||
void tabSafetySwitches();
|
|
||||||
void tabCustomFunctions();
|
|
||||||
void tabTelemetry();
|
|
||||||
void tabTemplates();
|
|
||||||
void updateCurvesTab();
|
|
||||||
void setSwitchWidgetVisibility(int i);
|
|
||||||
void setLimitMinMax();
|
|
||||||
void updateSelectedSwitch();
|
|
||||||
void updateSwitchesTab();
|
|
||||||
void updateHeliTab();
|
|
||||||
void updateA1Fields();
|
|
||||||
void updateA2Fields();
|
|
||||||
|
|
||||||
void launchSimulation();
|
|
||||||
void resizeEvent(QResizeEvent *event = 0);
|
|
||||||
|
|
||||||
|
|
||||||
int currentCurve;
|
|
||||||
void setCurrentCurve(int curveId);
|
|
||||||
|
|
||||||
QSpinBox *getNodeSB(int i);
|
|
||||||
QSpinBox *getNodeSBX(int i);
|
|
||||||
|
|
||||||
int getExpoIndex(unsigned int dch);
|
|
||||||
bool gm_insertExpo(int idx);
|
|
||||||
void gm_deleteExpo(int index);
|
|
||||||
void gm_openExpo(int index);
|
|
||||||
int gm_moveExpo(int idx, bool dir);
|
|
||||||
void exposDeleteList(QList<int> list);
|
|
||||||
QList<int> createExpoListFromSelected();
|
|
||||||
void setSelectedByExpoList(QList<int> list);
|
|
||||||
|
|
||||||
int getMixerIndex(unsigned int dch);
|
|
||||||
bool gm_insertMix(int idx);
|
|
||||||
void gm_deleteMix(int index);
|
|
||||||
void gm_openMix(int index);
|
|
||||||
int gm_moveMix(int idx, bool dir);
|
|
||||||
void mixersDeleteList(QList<int> list);
|
|
||||||
QList<int> createMixListFromSelected();
|
|
||||||
void setSelectedByMixList(QList<int> list);
|
|
||||||
|
|
||||||
void applyTemplate(uint8_t idx);
|
|
||||||
void applyNumericTemplate(uint64_t tpl);
|
|
||||||
MixData* setDest(uint8_t dch);
|
|
||||||
void setCurve(uint8_t c, int8_t ar[]);
|
|
||||||
void setSwitch(unsigned int idx, unsigned int func, int v1, int v2);
|
|
||||||
void on_phaseSwitch_currentIndexChanged(unsigned int phase, int index);
|
|
||||||
void on_phaseFadeIn_valueChanged(unsigned int phase, int value);
|
|
||||||
void on_phaseFadeOut_valueChanged(unsigned int phase, int value);
|
|
||||||
void on_phaseTrim_valueChanged(unsigned int phase, unsigned int stick, int value);
|
|
||||||
void on_phaseTrimUse_currentIndexChanged(unsigned int phase, unsigned int stick, int index, QSpinBox *trim, QSlider *slider);
|
|
||||||
void displayOnePhaseOneTrim(unsigned int phase_idx, unsigned int trim_idx, QComboBox *trimUse, QSpinBox *trimVal, QSlider *trimSlider);
|
|
||||||
void displayOnePhase(unsigned int phase_idx, QLineEdit *name, QComboBox *sw, QDoubleSpinBox *fadeIn, QDoubleSpinBox *fadeOut, QComboBox *trim1Use, QSpinBox *trim1, QLabel *trim1Label, QSlider *trim1Slider, QComboBox *trim2Use, QSpinBox *trim2, QLabel *trim2Label, QSlider *trim2Slider, QComboBox *trim3Use, QSpinBox *trim3, QLabel *trim3Label, QSlider *trim3Slider, QComboBox *trim4Use, QSpinBox *trim4, QLabel *trim4Label, QSlider *trim4Slider, QLabel *gv1Label, QComboBox *gv1Use,QSpinBox *gv1Value, QLabel *gv2Label, QComboBox *gv2Use,QSpinBox *gv2Value, QLabel *gv3Label, QComboBox *gv3Use,QSpinBox *gv3Value, QLabel *gv4Label, QComboBox *gv4Use,QSpinBox *gv4Value, QLabel *gv5Label, QComboBox *gv5Use,QSpinBox *gv5Value, QLabel *re1Label, QComboBox *re1Use,QSpinBox *re1Value, QLabel *re2Label, QComboBox *re2Use,QSpinBox *re2Value,bool doConnect);
|
|
||||||
|
|
||||||
void incSubtrim(uint8_t idx, int16_t inc);
|
|
||||||
#ifdef PHONON
|
|
||||||
Phonon::MediaObject *clickObject;
|
|
||||||
Phonon::AudioOutput *clickOutput;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
signals:
|
|
||||||
void modelValuesChanged();
|
|
||||||
|
|
||||||
private slots:
|
|
||||||
void clearExpos(bool ask=true);
|
|
||||||
void clearMixes(bool ask=true);
|
|
||||||
void clearCurves(bool ask=true);
|
|
||||||
void on_modelVoice_SB_editingFinished();
|
|
||||||
void on_T2ThrTrgChkB_toggled(bool checked);
|
|
||||||
void on_ttraceCB_currentIndexChanged(int index);
|
|
||||||
void on_instantTrim_CB_currentIndexChanged(int index);
|
|
||||||
void on_extendedLimitsChkB_toggled(bool checked);
|
|
||||||
void on_extendedTrimsChkB_toggled(bool checked);
|
|
||||||
void on_thrwarnChkB_toggled(bool checked);
|
|
||||||
void on_thrrevChkB_toggled(bool checked);
|
|
||||||
void on_timer1Perm_toggled(bool checked);
|
|
||||||
void on_timer2Perm_toggled(bool checked);
|
|
||||||
void on_timer1Minute_toggled(bool checked);
|
|
||||||
void on_timer2Minute_toggled(bool checked);
|
|
||||||
void on_timer1CountDownBeep_toggled(bool checked);
|
|
||||||
void on_timer2CountDownBeep_toggled(bool checked);
|
|
||||||
void fssldEdited();
|
|
||||||
void fssbEdited();
|
|
||||||
void fssldValueChanged();
|
|
||||||
void fssbValueChanged();
|
|
||||||
void resetCurve();
|
|
||||||
void editCurve();
|
|
||||||
void playMusic();
|
|
||||||
#ifdef PHONON
|
|
||||||
void mediaPlayer_state(Phonon::State newState, Phonon::State oldState);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void plotCurve(bool checked);
|
|
||||||
//phases slots
|
|
||||||
void phaseName_editingFinished();
|
|
||||||
void phaseSwitch_currentIndexChanged();
|
|
||||||
void phaseFadeIn_editingFinished();
|
|
||||||
void phaseFadeOut_editingFinished();
|
|
||||||
void phaseTrimUse_currentIndexChanged();
|
|
||||||
void phaseTrim_valueChanged();
|
|
||||||
void phaseTrimSlider_valueChanged();
|
|
||||||
void GVName_editingFinished();
|
|
||||||
void GVSource_currentIndexChanged();
|
|
||||||
void phaseGVValue_editingFinished();
|
|
||||||
void phaseGVUse_currentIndexChanged();
|
|
||||||
void phaseREValue_editingFinished();
|
|
||||||
void phaseREUse_currentIndexChanged();
|
|
||||||
|
|
||||||
void mimeMixerDropped(int index, const QMimeData *data, Qt::DropAction action);
|
|
||||||
void pasteMixerMimeData(const QMimeData * mimeData, int destIdx);
|
|
||||||
|
|
||||||
void mimeExpoDropped(int index, const QMimeData *data, Qt::DropAction action);
|
|
||||||
void pasteExpoMimeData(const QMimeData * mimeData, int destIdx);
|
|
||||||
|
|
||||||
void on_pushButton_clicked();
|
|
||||||
|
|
||||||
void exposDelete(bool ask=true);
|
|
||||||
void exposCut();
|
|
||||||
void exposCopy();
|
|
||||||
void exposPaste();
|
|
||||||
void exposDuplicate();
|
|
||||||
void expoOpen(QListWidgetItem *item = NULL);
|
|
||||||
void expoAdd();
|
|
||||||
|
|
||||||
void cswDelete();
|
|
||||||
void cswCopy();
|
|
||||||
void cswPaste();
|
|
||||||
void cswCut();
|
|
||||||
|
|
||||||
void fswDelete();
|
|
||||||
void fswCopy();
|
|
||||||
void fswPaste();
|
|
||||||
void fswCut();
|
|
||||||
|
|
||||||
void moveExpoUp();
|
|
||||||
void moveExpoDown();
|
|
||||||
|
|
||||||
void mixersDelete(bool ask=true);
|
|
||||||
void mixersCut();
|
|
||||||
void mixersCopy();
|
|
||||||
void mixersPaste();
|
|
||||||
void mixersDuplicate();
|
|
||||||
void mixerOpen();
|
|
||||||
void mixerAdd();
|
|
||||||
void moveMixUp();
|
|
||||||
void moveMixDown();
|
|
||||||
|
|
||||||
void expolistWidget_customContextMenuRequested(QPoint pos);
|
|
||||||
void expolistWidget_doubleClicked(QModelIndex index);
|
|
||||||
void expolistWidget_KeyPress(QKeyEvent *event);
|
|
||||||
|
|
||||||
|
|
||||||
void mixerlistWidget_customContextMenuRequested(QPoint pos);
|
|
||||||
void mixerlistWidget_doubleClicked(QModelIndex index);
|
|
||||||
void mixerlistWidget_KeyPress(QKeyEvent *event);
|
|
||||||
|
|
||||||
void csw_customContextMenuRequested(QPoint pos);
|
|
||||||
void fsw_customContextMenuRequested(QPoint pos);
|
|
||||||
|
|
||||||
|
|
||||||
void curvePointEdited();
|
|
||||||
void on_ca_ctype_CB_currentIndexChanged();
|
|
||||||
void on_ca_apply_PB_clicked();
|
|
||||||
|
|
||||||
void on_cname_LE_editingFinished();
|
|
||||||
void limitOffsetEdited();
|
|
||||||
void limitSymEdited();
|
|
||||||
void limitEdited();
|
|
||||||
void limitNameEdited();
|
|
||||||
void limitInvEdited();
|
|
||||||
void ppmcenterEdited();
|
|
||||||
void customSwitchesEdited();
|
|
||||||
void safetySwitchesEdited();
|
|
||||||
void customFunctionEdited();
|
|
||||||
void refreshCustomFunction(int index, bool modified=false);
|
|
||||||
void startupSwitchEdited();
|
|
||||||
void exposEdited();
|
|
||||||
void mixesEdited();
|
|
||||||
void heliEdited();
|
|
||||||
|
|
||||||
void on_bcRUDChkB_toggled(bool checked);
|
|
||||||
void on_bcELEChkB_toggled(bool checked);
|
|
||||||
void on_bcTHRChkB_toggled(bool checked);
|
|
||||||
void on_bcAILChkB_toggled(bool checked);
|
|
||||||
void on_bcP1ChkB_toggled(bool checked);
|
|
||||||
void on_bcP2ChkB_toggled(bool checked);
|
|
||||||
void on_bcP3ChkB_toggled(bool checked);
|
|
||||||
void on_bcP4ChkB_toggled(bool checked);
|
|
||||||
void on_bcREaChkB_toggled(bool checked);
|
|
||||||
void on_bcREbChkB_toggled(bool checked);
|
|
||||||
|
|
||||||
void on_thrExpoChkB_toggled(bool checked);
|
|
||||||
void on_thrTrimChkB_toggled(bool checked);
|
|
||||||
void on_a1UnitCB_currentIndexChanged(int index);
|
|
||||||
void on_a2UnitCB_currentIndexChanged(int index);
|
|
||||||
void on_a1RatioSB_editingFinished();
|
|
||||||
void on_a1RatioSB_valueChanged();
|
|
||||||
void on_a1CalibSB_editingFinished();
|
|
||||||
void on_a11LevelCB_currentIndexChanged(int index);
|
|
||||||
void on_a11GreaterCB_currentIndexChanged(int index);
|
|
||||||
void on_a11ValueSB_editingFinished();
|
|
||||||
void on_a12LevelCB_currentIndexChanged(int index);
|
|
||||||
void on_a12GreaterCB_currentIndexChanged(int index);
|
|
||||||
void on_a12ValueSB_editingFinished();
|
|
||||||
void on_a2RatioSB_editingFinished();
|
|
||||||
void on_a2RatioSB_valueChanged();
|
|
||||||
void on_a2CalibSB_editingFinished();
|
|
||||||
void on_a21LevelCB_currentIndexChanged(int index);
|
|
||||||
void on_a21GreaterCB_currentIndexChanged(int index);
|
|
||||||
void on_a21ValueSB_editingFinished();
|
|
||||||
void on_a22LevelCB_currentIndexChanged(int index);
|
|
||||||
void on_a22GreaterCB_currentIndexChanged(int index);
|
|
||||||
void on_a22ValueSB_editingFinished();
|
|
||||||
void on_frskyProtoCB_currentIndexChanged(int index);
|
|
||||||
void on_frskyUnitsCB_currentIndexChanged(int index);
|
|
||||||
void on_frskyBladesCB_currentIndexChanged(int index);
|
|
||||||
void on_frskyCurrentCB_currentIndexChanged(int index);
|
|
||||||
void on_frskyVoltCB_currentIndexChanged(int index);
|
|
||||||
void on_AltitudeToolbar_ChkB_toggled(bool checked);
|
|
||||||
void on_rssiAlarm1CB_currentIndexChanged(int index);
|
|
||||||
void on_rssiAlarm2CB_currentIndexChanged(int index);
|
|
||||||
void on_rssiAlarm1SB_editingFinished();
|
|
||||||
void on_rssiAlarm2SB_editingFinished();
|
|
||||||
void on_AltitudeGPS_ChkB_toggled(bool checked);
|
|
||||||
void on_showNames_Ckb_toggled(bool checked);
|
|
||||||
void on_varioSourceCB_currentIndexChanged(int index);
|
|
||||||
void on_varioLimitMin_DSB_editingFinished();
|
|
||||||
void on_varioLimitMax_DSB_editingFinished();
|
|
||||||
void on_varioLimitCenterMin_DSB_editingFinished();
|
|
||||||
void on_varioLimitMinOff_ChkB_toggled(bool checked);
|
|
||||||
void on_varioLimitCenterMax_DSB_editingFinished();
|
|
||||||
void telBarCBcurrentIndexChanged(int index);
|
|
||||||
void ScreenTypeCBcurrentIndexChanged(int index);
|
|
||||||
void telMaxSBeditingFinished();
|
|
||||||
void telMinSBeditingFinished();
|
|
||||||
void customFieldEdited();
|
|
||||||
void on_ppmDelaySB_editingFinished();
|
|
||||||
void on_ppmDelaySB_2_editingFinished();
|
|
||||||
void on_ppmDelaySB_3_editingFinished();
|
|
||||||
void on_numChannelsSB_editingFinished();
|
|
||||||
void on_numChannelsSB_2_editingFinished();
|
|
||||||
void on_numChannelsSB_3_editingFinished();
|
|
||||||
void on_numChannelsStart_editingFinished();
|
|
||||||
void on_numChannelsStart_2_editingFinished();
|
|
||||||
void on_numChannelsStart_3_editingFinished();
|
|
||||||
// void void ModelEdit::on_numChannelsStart_3_editingFinished();
|
|
||||||
void on_protocolCB_currentIndexChanged(int index);
|
|
||||||
void on_protocolCB_2_currentIndexChanged(int index);
|
|
||||||
void on_protocolCB_3_currentIndexChanged(int index);
|
|
||||||
void on_pulsePolCB_currentIndexChanged(int index);
|
|
||||||
void on_pulsePolCB_2_currentIndexChanged(int index);
|
|
||||||
void on_pulsePolCB_3_currentIndexChanged(int index);
|
|
||||||
void on_ppmFrameLengthDSB_editingFinished();
|
|
||||||
void on_ppmFrameLengthDSB_2_editingFinished();
|
|
||||||
void on_ppmFrameLengthDSB_3_editingFinished();
|
|
||||||
void on_DSM_Type_currentIndexChanged(int index);
|
|
||||||
void on_DSM_Type_2_currentIndexChanged(int index);
|
|
||||||
void on_pxxRxNum_editingFinished();
|
|
||||||
void on_pxxRxNum_2_editingFinished();
|
|
||||||
void on_fsm1CB_currentIndexChanged(int index);
|
|
||||||
void on_fsm2CB_currentIndexChanged(int index);
|
|
||||||
|
|
||||||
// TODO void on_trimSWCB_currentIndexChanged(int index);
|
|
||||||
void on_trimIncCB_currentIndexChanged(int index);
|
|
||||||
void on_timer1DirCB_currentIndexChanged(int index);
|
|
||||||
void on_timer1ModeCB_currentIndexChanged(int index);
|
|
||||||
void on_timer1ValTE_editingFinished();
|
|
||||||
void on_timer1ModeBCB_currentIndexChanged(int index);
|
|
||||||
void on_timer2DirCB_currentIndexChanged(int index);
|
|
||||||
void on_timer2ModeCB_currentIndexChanged(int index);
|
|
||||||
void on_timer2ValTE_editingFinished();
|
|
||||||
void on_timer2ModeBCB_currentIndexChanged(int index);
|
|
||||||
void on_modelNameLE_editingFinished();
|
|
||||||
void on_modelImage_CB_currentIndexChanged(int index);
|
|
||||||
void on_phases_currentChanged(int index);
|
|
||||||
void on_tabWidget_currentChanged(int index);
|
|
||||||
void on_templateList_doubleClicked(QModelIndex index);
|
|
||||||
void ControlCurveSignal(bool flag);
|
|
||||||
void shrink();
|
|
||||||
void wizard();
|
|
||||||
void closeEvent(QCloseEvent *event);
|
|
||||||
void on_curvetype_CB_currentIndexChanged(int index);
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // MODELEDIT_H
|
|
File diff suppressed because it is too large
Load diff
54
companion/src/modeledit/CMakeLists.txt
Normal file
54
companion/src/modeledit/CMakeLists.txt
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
include_directories(${CMAKE_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR})
|
||||||
|
|
||||||
|
set(modeledit_NAMES
|
||||||
|
modeledit
|
||||||
|
setup
|
||||||
|
heli
|
||||||
|
curves
|
||||||
|
telemetry
|
||||||
|
expodialog
|
||||||
|
mixerdialog
|
||||||
|
)
|
||||||
|
|
||||||
|
set(modeledit_SRCS
|
||||||
|
modelpanel.cpp
|
||||||
|
flightmodes.cpp
|
||||||
|
inputs.cpp
|
||||||
|
mixes.cpp
|
||||||
|
channels.cpp
|
||||||
|
customswitches.cpp
|
||||||
|
customfunctions.cpp
|
||||||
|
# templates.cpp
|
||||||
|
mixerslist.cpp
|
||||||
|
node.cpp
|
||||||
|
edge.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
set(modeledit_HDRS
|
||||||
|
modelpanel.h
|
||||||
|
flightmodes.h
|
||||||
|
inputs.h
|
||||||
|
mixes.h
|
||||||
|
channels.h
|
||||||
|
customswitches.h
|
||||||
|
customfunctions.h
|
||||||
|
# templates.h
|
||||||
|
mixerslist.h
|
||||||
|
node.h
|
||||||
|
)
|
||||||
|
|
||||||
|
set(modeledit_UIS
|
||||||
|
flightmode.ui
|
||||||
|
telemetry_analog.ui
|
||||||
|
)
|
||||||
|
|
||||||
|
foreach(name ${modeledit_NAMES})
|
||||||
|
set(modeledit_SRCS ${modeledit_SRCS} ${name}.cpp)
|
||||||
|
set(modeledit_HDRS ${modeledit_HDRS} ${name}.h)
|
||||||
|
set(modeledit_UIS ${modeledit_UIS} ${name}.ui)
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
qt4_wrap_ui(modeledit_SRCS ${modeledit_UIS})
|
||||||
|
qt4_wrap_cpp(modeledit_SRCS ${modeledit_HDRS})
|
||||||
|
|
||||||
|
add_library(modeledit ${modeledit_SRCS})
|
179
companion/src/modeledit/channels.cpp
Normal file
179
companion/src/modeledit/channels.cpp
Normal file
|
@ -0,0 +1,179 @@
|
||||||
|
#include "channels.h"
|
||||||
|
#include <QLabel>
|
||||||
|
#include <QLineEdit>
|
||||||
|
#include <QSpinBox>
|
||||||
|
#include <QComboBox>
|
||||||
|
#include <QCheckBox>
|
||||||
|
#include <QDoubleSpinBox>
|
||||||
|
|
||||||
|
Channels::Channels(QWidget * parent, ModelData & model):
|
||||||
|
ModelPanel(parent, model)
|
||||||
|
{
|
||||||
|
QGridLayout * gridLayout = new QGridLayout(this);
|
||||||
|
|
||||||
|
int col = 1;
|
||||||
|
if (GetEepromInterface()->getCapability(ChannelsName))
|
||||||
|
addLabel(gridLayout, tr("Name"), col++);
|
||||||
|
addLabel(gridLayout, tr("Offset"), col++);
|
||||||
|
addLabel(gridLayout, tr("Min"), col++);
|
||||||
|
addLabel(gridLayout, tr("Max"), col++);
|
||||||
|
addLabel(gridLayout, tr("Invert"), col++);
|
||||||
|
if (GetEepromInterface()->getCapability(PPMCenter))
|
||||||
|
addLabel(gridLayout, tr("Center"), col++);
|
||||||
|
if (GetEepromInterface()->getCapability(SYMLimits))
|
||||||
|
addLabel(gridLayout, tr("Sym"), col++);
|
||||||
|
|
||||||
|
for (int i=0; i<GetEepromInterface()->getCapability(Outputs); i++) {
|
||||||
|
col = 0;
|
||||||
|
|
||||||
|
// Channel label
|
||||||
|
QLabel *label = new QLabel(this);
|
||||||
|
label->setText(tr("Channel %1").arg(i+1));
|
||||||
|
gridLayout->addWidget(label, i+1, col++, 1, 1);
|
||||||
|
|
||||||
|
// Channel name
|
||||||
|
int nameLen = GetEepromInterface()->getCapability(ChannelsName);
|
||||||
|
if (nameLen > 0) {
|
||||||
|
QLineEdit * name = new QLineEdit(this);
|
||||||
|
name->setProperty("index", i);
|
||||||
|
name->setMaxLength(nameLen);
|
||||||
|
QRegExp rx(CHAR_FOR_NAMES_REGEX);
|
||||||
|
name->setValidator(new QRegExpValidator(rx, this));
|
||||||
|
name->setText(model.limitData[i].name);
|
||||||
|
connect(name, SIGNAL(editingFinished()), this, SLOT(nameEdited()));
|
||||||
|
gridLayout->addWidget(name, i+1, col++, 1, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Channel offset
|
||||||
|
QDoubleSpinBox * offset = new QDoubleSpinBox(this);
|
||||||
|
offset->setProperty("index", i);
|
||||||
|
offset->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter);
|
||||||
|
offset->setAccelerated(true);
|
||||||
|
offset->setDecimals(1);
|
||||||
|
offset->setMinimum(-100);
|
||||||
|
offset->setSingleStep(0.1);
|
||||||
|
offset->setValue(float(model.limitData[i].offset) / 10);
|
||||||
|
connect(offset, SIGNAL(editingFinished()), this, SLOT(offsetEdited()));
|
||||||
|
gridLayout->addWidget(offset, i+1, col++, 1, 1);
|
||||||
|
|
||||||
|
// Channel min
|
||||||
|
QSpinBox * minSB = new QSpinBox(this);
|
||||||
|
minSB->setProperty("index", i);
|
||||||
|
minSB->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter);
|
||||||
|
minSB->setAccelerated(true);
|
||||||
|
minSB->setMinimum(model.extendedLimits ? -125 : -100);
|
||||||
|
minSB->setMaximum(0);
|
||||||
|
minSB->setValue(model.limitData[i].min);
|
||||||
|
connect(minSB, SIGNAL(editingFinished()), this, SLOT(minEdited()));
|
||||||
|
gridLayout->addWidget(minSB, i+1, col++, 1, 1);
|
||||||
|
|
||||||
|
// Channel max
|
||||||
|
QSpinBox * maxSB = new QSpinBox(this);
|
||||||
|
maxSB->setProperty("index", i);
|
||||||
|
maxSB->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter);
|
||||||
|
maxSB->setAccelerated(true);
|
||||||
|
maxSB->setMinimum(0);
|
||||||
|
maxSB->setMaximum(model.extendedLimits ? 125 : 100);
|
||||||
|
maxSB->setValue(model.limitData[i].max);
|
||||||
|
connect(maxSB, SIGNAL(editingFinished()), this, SLOT(maxEdited()));
|
||||||
|
gridLayout->addWidget(maxSB, i+1, col++, 1, 1);
|
||||||
|
|
||||||
|
// Channel inversion
|
||||||
|
QComboBox * invCB = new QComboBox(this);
|
||||||
|
invCB->insertItems(0, QStringList() << tr("---") << tr("INV"));
|
||||||
|
invCB->setProperty("index", i);
|
||||||
|
invCB->setCurrentIndex((model.limitData[i].revert) ? 1 : 0);
|
||||||
|
connect(invCB, SIGNAL(currentIndexChanged(int)), this, SLOT(invEdited()));
|
||||||
|
gridLayout->addWidget(invCB, i+1, col++, 1, 1);
|
||||||
|
|
||||||
|
// PPM center
|
||||||
|
if (GetEepromInterface()->getCapability(PPMCenter)) {
|
||||||
|
QSpinBox * center = new QSpinBox(this);
|
||||||
|
center->setProperty("index", i);
|
||||||
|
center->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter);
|
||||||
|
center->setMinimum(1375);
|
||||||
|
center->setMaximum(1625);
|
||||||
|
center->setValue(1500);
|
||||||
|
center->setValue(model.limitData[i].ppmCenter + 1500);
|
||||||
|
connect(center, SIGNAL(editingFinished()), this, SLOT(ppmcenterEdited()));
|
||||||
|
gridLayout->addWidget(center, i+1, col++, 1, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Symetrical limits
|
||||||
|
if (GetEepromInterface()->getCapability(SYMLimits)) {
|
||||||
|
QCheckBox * symlimits = new QCheckBox(this);
|
||||||
|
symlimits->setProperty("index", i);
|
||||||
|
symlimits->setChecked(model.limitData[i].symetrical);
|
||||||
|
connect(symlimits, SIGNAL(toggled(bool)), this, SLOT(symlimitsEdited()));
|
||||||
|
gridLayout->addWidget(symlimits, i+1, col++, 1, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||||
|
// setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
|
||||||
|
}
|
||||||
|
|
||||||
|
Channels::~Channels()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void Channels::symlimitsEdited()
|
||||||
|
{
|
||||||
|
QCheckBox * ckb = qobject_cast<QCheckBox*>(sender());
|
||||||
|
int index = ckb->property("index").toInt();
|
||||||
|
model.limitData[index].symetrical = (ckb->checkState() ? 1 : 0);
|
||||||
|
emit modified();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Channels::nameEdited()
|
||||||
|
{
|
||||||
|
if (!lock) {
|
||||||
|
lock = true;
|
||||||
|
QLineEdit *le = qobject_cast<QLineEdit*>(sender());
|
||||||
|
int index = le->property("index").toInt();
|
||||||
|
strcpy(model.limitData[index].name, le->text().toAscii());
|
||||||
|
lock = false;
|
||||||
|
emit modified();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Channels::offsetEdited()
|
||||||
|
{
|
||||||
|
QDoubleSpinBox *dsb = qobject_cast<QDoubleSpinBox*>(sender());
|
||||||
|
int index = dsb->property("index").toInt();
|
||||||
|
model.limitData[index].offset = round(dsb->value()*10);
|
||||||
|
emit modified();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Channels::minEdited()
|
||||||
|
{
|
||||||
|
QSpinBox *sb = qobject_cast<QSpinBox*>(sender());
|
||||||
|
int index = sb->property("index").toInt();
|
||||||
|
model.limitData[index].min = sb->value();
|
||||||
|
emit modified();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Channels::maxEdited()
|
||||||
|
{
|
||||||
|
QSpinBox *sb = qobject_cast<QSpinBox*>(sender());
|
||||||
|
int index = sb->property("index").toInt();
|
||||||
|
model.limitData[index].max = sb->value();
|
||||||
|
emit modified();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Channels::invEdited()
|
||||||
|
{
|
||||||
|
QComboBox *cb = qobject_cast<QComboBox*>(sender());
|
||||||
|
int index = cb->property("index").toInt();
|
||||||
|
model.limitData[index].revert = cb->currentIndex();
|
||||||
|
emit modified();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Channels::ppmcenterEdited()
|
||||||
|
{
|
||||||
|
QSpinBox *sb = qobject_cast<QSpinBox*>(sender());
|
||||||
|
int index = sb->property("index").toInt();
|
||||||
|
model.limitData[index].ppmCenter = sb->value() - 1500;
|
||||||
|
emit modified();
|
||||||
|
}
|
||||||
|
|
25
companion/src/modeledit/channels.h
Normal file
25
companion/src/modeledit/channels.h
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
#ifndef CHANNELS_H
|
||||||
|
#define CHANNELS_H
|
||||||
|
|
||||||
|
#include "modelpanel.h"
|
||||||
|
|
||||||
|
class Channels : public ModelPanel
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
Channels(QWidget *parent, ModelData & model);
|
||||||
|
~Channels();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void symlimitsEdited();
|
||||||
|
void nameEdited();
|
||||||
|
void offsetEdited();
|
||||||
|
void minEdited();
|
||||||
|
void maxEdited();
|
||||||
|
void invEdited();
|
||||||
|
void ppmcenterEdited();
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // CHANNELS_H
|
217
companion/src/modeledit/curvedialog.ui
Normal file
217
companion/src/modeledit/curvedialog.ui
Normal file
|
@ -0,0 +1,217 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>Dialog</class>
|
||||||
|
<widget class="QDialog" name="Dialog">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>400</width>
|
||||||
|
<height>300</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Dialog</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<item>
|
||||||
|
<layout class="QGridLayout" name="gridLayout_2">
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QLabel" name="ca_ctype_label_2">
|
||||||
|
<property name="text">
|
||||||
|
<string>Curve type</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="1">
|
||||||
|
<widget class="QSpinBox" name="ca_coeff_SB_2">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="minimum">
|
||||||
|
<number>-100</number>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<number>100</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QLabel" name="ca_coeff_label_2">
|
||||||
|
<property name="text">
|
||||||
|
<string>Coefficient</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="5" column="1">
|
||||||
|
<widget class="QComboBox" name="ca_side_CB_2">
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Both</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>x>0</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>x<0</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="0">
|
||||||
|
<widget class="QLabel" name="ca_ymid_label_2">
|
||||||
|
<property name="text">
|
||||||
|
<string>Y at X=0</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="4" column="1">
|
||||||
|
<widget class="QSpinBox" name="ca_ymax_SB_2">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="minimum">
|
||||||
|
<number>-100</number>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<number>100</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="1">
|
||||||
|
<widget class="QSpinBox" name="ca_ymid_SB_2">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="minimum">
|
||||||
|
<number>-100</number>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<number>100</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="5" column="0">
|
||||||
|
<widget class="QLabel" name="ca_side_label_2">
|
||||||
|
<property name="text">
|
||||||
|
<string>Side</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="0">
|
||||||
|
<widget class="QLabel" name="ca_ymin_label_2">
|
||||||
|
<property name="text">
|
||||||
|
<string>Y at X=-100</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="1">
|
||||||
|
<widget class="QSpinBox" name="ca_ymin_SB_2">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="minimum">
|
||||||
|
<number>-100</number>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<number>100</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="4" column="0">
|
||||||
|
<widget class="QLabel" name="ca_ymax_label_2">
|
||||||
|
<property name="text">
|
||||||
|
<string>Y at X=100</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="1">
|
||||||
|
<widget class="QComboBox" name="ca_ctype_CB_2">
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Linear</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Single Expo</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Symmetrical f(x)=-f(-x)</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Symmetrical f(x)=f(-x)</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QDialogButtonBox" name="buttonBox">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="standardButtons">
|
||||||
|
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources/>
|
||||||
|
<connections>
|
||||||
|
<connection>
|
||||||
|
<sender>buttonBox</sender>
|
||||||
|
<signal>accepted()</signal>
|
||||||
|
<receiver>Dialog</receiver>
|
||||||
|
<slot>accept()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>248</x>
|
||||||
|
<y>254</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>157</x>
|
||||||
|
<y>274</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>buttonBox</sender>
|
||||||
|
<signal>rejected()</signal>
|
||||||
|
<receiver>Dialog</receiver>
|
||||||
|
<slot>reject()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>316</x>
|
||||||
|
<y>260</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>286</x>
|
||||||
|
<y>274</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
</connections>
|
||||||
|
</ui>
|
722
companion/src/modeledit/curves.cpp
Normal file
722
companion/src/modeledit/curves.cpp
Normal file
|
@ -0,0 +1,722 @@
|
||||||
|
#include "curves.h"
|
||||||
|
#include "ui_curves.h"
|
||||||
|
#include "node.h"
|
||||||
|
#include "edge.h"
|
||||||
|
#include <QSpinBox>
|
||||||
|
#include <QCheckBox>
|
||||||
|
#include <QPushButton>
|
||||||
|
#include <QMessageBox>
|
||||||
|
|
||||||
|
// TODO Capability CustomCurves to be removed
|
||||||
|
|
||||||
|
#define GFX_MARGIN 16
|
||||||
|
|
||||||
|
static const QColor colors[C9X_MAX_CURVES] = {
|
||||||
|
QColor(0,0,127),
|
||||||
|
QColor(0,127,0),
|
||||||
|
QColor(127,0,0),
|
||||||
|
QColor(0,127,127),
|
||||||
|
QColor(127,0,127),
|
||||||
|
QColor(127,127,0),
|
||||||
|
QColor(127,127,127),
|
||||||
|
QColor(0,0,255),
|
||||||
|
QColor(0,127,255),
|
||||||
|
QColor(127,0,255),
|
||||||
|
QColor(0,255,0),
|
||||||
|
QColor(0,255,127),
|
||||||
|
QColor(127,255,0),
|
||||||
|
QColor(255,0,0),
|
||||||
|
QColor(255,0,127),
|
||||||
|
QColor(255,127,0),
|
||||||
|
};
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
#ifdef __APPLE__
|
||||||
|
ui->curveEdit_1->setStyleSheet("color: #00007f;");
|
||||||
|
ui->curveEdit_2->setStyleSheet("color: #007f00;");
|
||||||
|
ui->curveEdit_3->setStyleSheet("color: #7f0000;");
|
||||||
|
ui->curveEdit_4->setStyleSheet("color: #007f7f;");
|
||||||
|
ui->curveEdit_5->setStyleSheet("color: #7f007f;");
|
||||||
|
ui->curveEdit_6->setStyleSheet("color: #7f7f00;");
|
||||||
|
ui->curveEdit_7->setStyleSheet("color: #7f7f7f;");
|
||||||
|
ui->curveEdit_8->setStyleSheet("color: #0000ff;");
|
||||||
|
ui->curveEdit_9->setStyleSheet("color: #007fff;");
|
||||||
|
ui->curveEdit_10->setStyleSheet("color: #7f00ff;");
|
||||||
|
ui->curveEdit_11->setStyleSheet("color: #00ff00;");
|
||||||
|
ui->curveEdit_12->setStyleSheet("color: #00ff7f;");
|
||||||
|
ui->curveEdit_13->setStyleSheet("color: #7fff00;");
|
||||||
|
ui->curveEdit_14->setStyleSheet("color: #ff0000;");
|
||||||
|
ui->curveEdit_15->setStyleSheet("color: #ff007f;");
|
||||||
|
ui->curveEdit_16->setStyleSheet("color: #ff7f00;");
|
||||||
|
#else
|
||||||
|
ui->curveEdit_1->setStyleSheet("background-color: #00007f; color: white;");
|
||||||
|
ui->curveEdit_2->setStyleSheet("background-color: #007f00; color: white;");
|
||||||
|
ui->curveEdit_3->setStyleSheet("background-color: #7f0000; color: white;");
|
||||||
|
ui->curveEdit_4->setStyleSheet("background-color: #007f7f; color: white;");
|
||||||
|
ui->curveEdit_5->setStyleSheet("background-color: #7f007f; color: white;");
|
||||||
|
ui->curveEdit_6->setStyleSheet("background-color: #7f7f00; color: white;");
|
||||||
|
ui->curveEdit_7->setStyleSheet("background-color: #7f7f7f; color: white;");
|
||||||
|
ui->curveEdit_8->setStyleSheet("background-color: #0000ff; color: white;");
|
||||||
|
ui->curveEdit_9->setStyleSheet("background-color: #007fff; color: white;");
|
||||||
|
ui->curveEdit_10->setStyleSheet("background-color: #7f00ff; color: white;");
|
||||||
|
ui->curveEdit_11->setStyleSheet("background-color: #00ff00; color: white;");
|
||||||
|
ui->curveEdit_12->setStyleSheet("background-color: #00ff7f; color: white;");
|
||||||
|
ui->curveEdit_13->setStyleSheet("background-color: #7fff00; color: white;");
|
||||||
|
ui->curveEdit_14->setStyleSheet("background-color: #ff0000; color: white;");
|
||||||
|
ui->curveEdit_15->setStyleSheet("background-color: #ff007f; color: white;");
|
||||||
|
ui->curveEdit_16->setStyleSheet("background-color: #ff7f00; color: white;");
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
Curves::Curves(QWidget * parent, ModelData & model):
|
||||||
|
ModelPanel(parent, model),
|
||||||
|
ui(new Ui::Curves),
|
||||||
|
currentCurve(0)
|
||||||
|
{
|
||||||
|
ui->setupUi(this);
|
||||||
|
|
||||||
|
if (!GetEepromInterface()->getCapability(HasCvNames)) {
|
||||||
|
ui->cname_LE->hide();
|
||||||
|
ui->cname_label->hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
QGraphicsScene *scene = new QGraphicsScene(ui->curvePreview);
|
||||||
|
scene->setItemIndexMethod(QGraphicsScene::NoIndex);
|
||||||
|
ui->curvePreview->setScene(scene);
|
||||||
|
|
||||||
|
QIcon clearIcon;
|
||||||
|
clearIcon.addFile(":/images/clear.png", QSize(), QIcon::Normal, QIcon::Off);
|
||||||
|
|
||||||
|
for (int i=0; i<GetEepromInterface()->getCapability(NumCurves); i++) {
|
||||||
|
visibleCurves[i] = false;
|
||||||
|
// The reset curve button
|
||||||
|
QPushButton * reset = new QPushButton(this);
|
||||||
|
reset->setProperty("index", i);
|
||||||
|
reset->setMinimumSize(QSize(0, 0));
|
||||||
|
reset->setIcon(clearIcon);
|
||||||
|
reset->setIconSize(QSize(14, 14));
|
||||||
|
connect(reset, SIGNAL(clicked()), this, SLOT(resetCurve()));
|
||||||
|
ui->curvesLayout->addWidget(reset, i, 0, 1, 1);
|
||||||
|
|
||||||
|
// The edit curve button
|
||||||
|
QPushButton * edit = new QPushButton(this);
|
||||||
|
edit->setProperty("index", i);
|
||||||
|
QPalette palette;
|
||||||
|
palette.setBrush(QPalette::Active, QPalette::Button, QBrush(colors[i]));
|
||||||
|
palette.setBrush(QPalette::Active, QPalette::ButtonText, QBrush(Qt::white));
|
||||||
|
edit->setPalette(palette);
|
||||||
|
edit->setText(tr("Curve %1").arg(i+1));
|
||||||
|
connect(edit, SIGNAL(clicked()), this, SLOT(editCurve()));
|
||||||
|
ui->curvesLayout->addWidget(edit, i, 1, 1, 1);
|
||||||
|
|
||||||
|
// The curve plot checkbox
|
||||||
|
QCheckBox * plot = new QCheckBox(this);
|
||||||
|
plot->setProperty("index", i);
|
||||||
|
plot->setPalette(palette);
|
||||||
|
connect(plot, SIGNAL(toggled(bool)), this, SLOT(plotCurve(bool)));
|
||||||
|
ui->curvesLayout->addWidget(plot, i, 2, 1, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
visibleCurves[0] = true;
|
||||||
|
|
||||||
|
for (int i=0; i<C9X_MAX_POINTS; i++) {
|
||||||
|
spny[i] = new QSpinBox(this);
|
||||||
|
spny[i]->setProperty("index", i);
|
||||||
|
spny[i]->setMinimum(-100);
|
||||||
|
spny[i]->setMaximum(+100);
|
||||||
|
spny[i]->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter);
|
||||||
|
spny[i]->setAccelerated(true);
|
||||||
|
connect(spny[i], SIGNAL(valueChanged(int)), this, SLOT(onPointEdited()));
|
||||||
|
ui->pointsLayout->addWidget(spny[i], i, 0, 1, 1);
|
||||||
|
|
||||||
|
spnx[i] = new QSpinBox(this);
|
||||||
|
spnx[i]->setProperty("index", i);
|
||||||
|
spnx[i]->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter);
|
||||||
|
spnx[i]->setAccelerated(true);
|
||||||
|
connect(spnx[i], SIGNAL(valueChanged(int)), this, SLOT(onPointEdited()));
|
||||||
|
ui->pointsLayout->addWidget(spnx[i], i, 1, 1, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Curves::~Curves()
|
||||||
|
{
|
||||||
|
delete ui;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Curves::editCurve()
|
||||||
|
{
|
||||||
|
QPushButton *button = (QPushButton *)sender();
|
||||||
|
int index = button->property("index").toInt();
|
||||||
|
setCurrentCurve(index);
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Curves::resetCurve()
|
||||||
|
{
|
||||||
|
QPushButton *button = (QPushButton *)sender();
|
||||||
|
int index = button->property("index").toInt();
|
||||||
|
int res = QMessageBox::question(this, "companion9x", tr("Are you sure you want to reset curve %1 ?").arg(index+1), QMessageBox::Yes | QMessageBox::No);
|
||||||
|
if (res == QMessageBox::Yes) {
|
||||||
|
model.curves[index].clear(5);
|
||||||
|
update();
|
||||||
|
emit modified();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Curves::plotCurve(bool checked)
|
||||||
|
{
|
||||||
|
QCheckBox *chk = (QCheckBox *)sender();
|
||||||
|
int index = chk->property("index").toInt();
|
||||||
|
visibleCurves[index] = checked;
|
||||||
|
updateCurve();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Curves::update()
|
||||||
|
{
|
||||||
|
lock = true;
|
||||||
|
|
||||||
|
if (GetEepromInterface()->getCapability(HasCvNames)) {
|
||||||
|
ui->cname_LE->setText(model.curves[currentCurve].name);
|
||||||
|
}
|
||||||
|
|
||||||
|
int count = model.curves[currentCurve].count;
|
||||||
|
for (int i=0; i<count; i++) {
|
||||||
|
spny[i]->show();
|
||||||
|
spny[i]->setValue(model.curves[currentCurve].points[i].y);
|
||||||
|
if (model.curves[currentCurve].custom) {
|
||||||
|
spnx[i]->show();
|
||||||
|
if (i==0 || i==model.curves[currentCurve].count-1) {
|
||||||
|
spnx[i]->setDisabled(true);
|
||||||
|
spnx[i]->setMaximum(+100);
|
||||||
|
spnx[i]->setMinimum(-100);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
spnx[i]->setMaximum(model.curves[currentCurve].points[i+1].x);
|
||||||
|
spnx[i]->setMinimum(model.curves[currentCurve].points[i-1].x);
|
||||||
|
}
|
||||||
|
spnx[i]->setValue(model.curves[currentCurve].points[i].x);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
spnx[i]->hide();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (int i=count; i<C9X_MAX_POINTS; i++) {
|
||||||
|
spny[i]->hide();
|
||||||
|
spnx[i]->hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
updateCurveType();
|
||||||
|
updateCurve();
|
||||||
|
|
||||||
|
lock = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Curves::setCurrentCurve(int index)
|
||||||
|
{
|
||||||
|
currentCurve = index;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Curves::updateCurveType()
|
||||||
|
{
|
||||||
|
int index = model.curves[currentCurve].custom;
|
||||||
|
if (model.curves[currentCurve].count==5)
|
||||||
|
index += 2;
|
||||||
|
else if (model.curves[currentCurve].count==9)
|
||||||
|
index += 4;
|
||||||
|
else if (model.curves[currentCurve].count==17)
|
||||||
|
index += 6;
|
||||||
|
ui->curvetype_CB->setCurrentIndex(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Curves::updateCurve()
|
||||||
|
{
|
||||||
|
Node * nodel = 0;
|
||||||
|
Node * nodex = 0;
|
||||||
|
QColor color;
|
||||||
|
|
||||||
|
QGraphicsScene *scene = ui->curvePreview->scene();
|
||||||
|
scene->clear();
|
||||||
|
|
||||||
|
qreal width = scene->sceneRect().width();
|
||||||
|
qreal height = scene->sceneRect().height();
|
||||||
|
|
||||||
|
qreal centerX = scene->sceneRect().left() + width/2; //center X
|
||||||
|
qreal centerY = scene->sceneRect().top() + height/2; //center Y
|
||||||
|
|
||||||
|
QGraphicsSimpleTextItem *ti = scene->addSimpleText(tr("Editing curve %1").arg(currentCurve+1));
|
||||||
|
ti->setPos(3, 3);
|
||||||
|
|
||||||
|
scene->addLine(centerX, GFX_MARGIN, centerX, height+GFX_MARGIN);
|
||||||
|
scene->addLine(GFX_MARGIN, centerY, width+GFX_MARGIN, centerY);
|
||||||
|
|
||||||
|
QPen pen;
|
||||||
|
pen.setWidth(2);
|
||||||
|
pen.setStyle(Qt::SolidLine);
|
||||||
|
|
||||||
|
int numcurves = GetEepromInterface()->getCapability(NumCurves);
|
||||||
|
for (int k=0; k<numcurves; k++) {
|
||||||
|
pen.setColor(colors[k]);
|
||||||
|
if (currentCurve!=k && visibleCurves[k]) {
|
||||||
|
int numpoints = model.curves[k].count;
|
||||||
|
for (int i=0; i<numpoints-1; i++) {
|
||||||
|
if (model.curves[k].custom)
|
||||||
|
scene->addLine(centerX + (qreal)model.curves[k].points[i].x*width/200,centerY - (qreal)model.curves[k].points[i].y*height/200,centerX + (qreal)model.curves[k].points[i+1].x*width/200,centerY - (qreal)model.curves[k].points[i+1].y*height/200,pen);
|
||||||
|
else
|
||||||
|
scene->addLine(GFX_MARGIN + i*width/(numpoints-1),centerY - (qreal)model.curves[k].points[i].y*height/200,GFX_MARGIN + (i+1)*width/(numpoints-1),centerY - (qreal)model.curves[k].points[i+1].y*height/200,pen);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int numpoints = model.curves[currentCurve].count;
|
||||||
|
for (int i=0; i<numpoints; i++) {
|
||||||
|
nodel = nodex;
|
||||||
|
nodex = new Node();
|
||||||
|
nodex->setProperty("index", i);
|
||||||
|
nodex->setColor(colors[currentCurve]);
|
||||||
|
if (model.curves[currentCurve].custom) {
|
||||||
|
if (i>0 && i<numpoints-1) {
|
||||||
|
nodex->setFixedX(false);
|
||||||
|
nodex->setMinX(model.curves[currentCurve].points[i-1].x);
|
||||||
|
nodex->setMaxX(model.curves[currentCurve].points[i+1].x);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
nodex->setFixedX(true);
|
||||||
|
}
|
||||||
|
nodex->setPos(centerX + (qreal)model.curves[currentCurve].points[i].x*width/200,centerY - (qreal)model.curves[currentCurve].points[i].y*height/200);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
nodex->setFixedX(true);
|
||||||
|
nodex->setPos(GFX_MARGIN + i*width/(numpoints-1), centerY - (qreal)model.curves[currentCurve].points[i].y*height/200);
|
||||||
|
}
|
||||||
|
connect(nodex, SIGNAL(moved(int, int)), this, SLOT(onNodeMoved(int, int)));
|
||||||
|
connect(nodex, SIGNAL(focus()), this, SLOT(onNodeFocus()));
|
||||||
|
connect(nodex, SIGNAL(unfocus()), this, SLOT(onNodeUnfocus()));
|
||||||
|
scene->addItem(nodex);
|
||||||
|
if (i>0) scene->addItem(new Edge(nodel, nodex));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Curves::onPointEdited()
|
||||||
|
{
|
||||||
|
if (!lock) {
|
||||||
|
lock = true;
|
||||||
|
int index = sender()->property("index").toInt();
|
||||||
|
model.curves[currentCurve].points[index].x = spnx[index]->value();
|
||||||
|
model.curves[currentCurve].points[index].y = spny[index]->value();
|
||||||
|
updateCurve();
|
||||||
|
emit modified();
|
||||||
|
lock = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Curves::onNodeMoved(int x, int y)
|
||||||
|
{
|
||||||
|
if (!lock) {
|
||||||
|
lock = true;
|
||||||
|
int index = sender()->property("index").toInt();
|
||||||
|
model.curves[currentCurve].points[index].x = x;
|
||||||
|
model.curves[currentCurve].points[index].y = y;
|
||||||
|
spnx[index]->setValue(x);
|
||||||
|
spny[index]->setValue(y);
|
||||||
|
emit modified();
|
||||||
|
lock = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Curves::onNodeFocus()
|
||||||
|
{
|
||||||
|
int index = sender()->property("index").toInt();
|
||||||
|
spny[index]->setFocus();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Curves::onNodeUnfocus()
|
||||||
|
{
|
||||||
|
int index = sender()->property("index").toInt();
|
||||||
|
spny[index]->clearFocus();
|
||||||
|
updateCurve();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Curves::on_curvetype_CB_currentIndexChanged(int index)
|
||||||
|
{
|
||||||
|
static const int numpoint[] = {3,3,5,5,9,9,17,17};
|
||||||
|
static const bool custom[] = {false,true,false,true,false,true,false,true};
|
||||||
|
|
||||||
|
if (!lock) {
|
||||||
|
lock = true;
|
||||||
|
|
||||||
|
int numcurves = GetEepromInterface()->getCapability(NumCurves);
|
||||||
|
// int currpoints = model.curves[currentCurve].count;
|
||||||
|
// bool currcustom = model.curves[currentCurve].custom;
|
||||||
|
|
||||||
|
int totalpoints=0;
|
||||||
|
for (int i=0; i<numcurves; i++) {
|
||||||
|
if (i!=currentCurve) {
|
||||||
|
totalpoints += model.curves[i].count;
|
||||||
|
if (model.curves[i].custom) {
|
||||||
|
totalpoints += model.curves[i].count-2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
totalpoints += numpoint[index];
|
||||||
|
if (custom[index]) {
|
||||||
|
totalpoints += numpoint[index]-2;
|
||||||
|
}
|
||||||
|
|
||||||
|
int fwpoints = GetEepromInterface()->getCapability(NumCurvePoints);
|
||||||
|
if (fwpoints!=0) {
|
||||||
|
if (fwpoints < totalpoints) {
|
||||||
|
QMessageBox::warning(this, "companion9x", tr("Not enough free points in EEPROM to store the curve."));
|
||||||
|
updateCurveType();
|
||||||
|
lock = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
model.curves[currentCurve].count = numpoint[index];
|
||||||
|
model.curves[currentCurve].custom = custom[index];
|
||||||
|
|
||||||
|
// TODO something better!
|
||||||
|
for (int i=0; i<C9X_MAX_POINTS; i++) {
|
||||||
|
model.curves[currentCurve].points[i].x = (i >= model.curves[currentCurve].count-1 ? +100 : -100 + (200*i)/(numpoint[index]-1));
|
||||||
|
model.curves[currentCurve].points[i].y = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
update();
|
||||||
|
emit modified();
|
||||||
|
lock = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Curves::on_cname_LE_editingFinished()
|
||||||
|
{
|
||||||
|
memset(model.curves[currentCurve].name, 0, sizeof(model.curves[currentCurve].name));
|
||||||
|
strcpy(model.curves[currentCurve].name, ui->cname_LE->text().toAscii());
|
||||||
|
emit modified();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Curves::resizeEvent(QResizeEvent *event)
|
||||||
|
{
|
||||||
|
QRect qr = ui->curvePreview->contentsRect();
|
||||||
|
ui->curvePreview->scene()->setSceneRect(GFX_MARGIN, GFX_MARGIN, qr.width()-GFX_MARGIN*2, qr.height()-GFX_MARGIN*2);
|
||||||
|
updateCurve();
|
||||||
|
|
||||||
|
ModelPanel::resizeEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
void ModelEdit::on_ca_ctype_CB_currentIndexChanged()
|
||||||
|
{
|
||||||
|
int index=ui->ca_ctype_CB->currentIndex();
|
||||||
|
switch (index) {
|
||||||
|
case 0:
|
||||||
|
ui->ca_coeff_SB->hide();
|
||||||
|
ui->ca_coeff_label->hide();
|
||||||
|
ui->ca_ymid_SB->hide();
|
||||||
|
ui->ca_ymid_label->hide();
|
||||||
|
ui->ca_ymin_SB->show();
|
||||||
|
ui->ca_ymin_label->show();
|
||||||
|
ui->ca_ymin_SB->setValue(-100);
|
||||||
|
ui->ca_ymax_SB->setValue(100);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
ui->ca_coeff_SB->show();
|
||||||
|
ui->ca_coeff_label->show();
|
||||||
|
ui->ca_ymid_SB->hide();
|
||||||
|
ui->ca_ymid_label->hide();
|
||||||
|
ui->ca_ymin_SB->show();
|
||||||
|
ui->ca_ymin_label->show();
|
||||||
|
ui->ca_ymin_SB->setValue(-100);
|
||||||
|
ui->ca_ymax_SB->setValue(100);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
ui->ca_coeff_SB->show();
|
||||||
|
ui->ca_coeff_label->show();
|
||||||
|
ui->ca_ymid_SB->hide();
|
||||||
|
ui->ca_ymid_label->hide();
|
||||||
|
ui->ca_ymin_SB->hide();
|
||||||
|
ui->ca_ymin_label->hide();
|
||||||
|
ui->ca_ymax_SB->setValue(100);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
ui->ca_coeff_SB->show();
|
||||||
|
ui->ca_coeff_label->show();
|
||||||
|
ui->ca_ymid_SB->show();
|
||||||
|
ui->ca_ymid_label->show();
|
||||||
|
ui->ca_ymin_SB->hide();
|
||||||
|
ui->ca_ymin_label->hide();
|
||||||
|
ui->ca_ymid_SB->setValue(0);
|
||||||
|
ui->ca_ymax_SB->setValue(100);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ModelEdit::on_ca_apply_PB_clicked()
|
||||||
|
{
|
||||||
|
int index=ui->ca_ctype_CB->currentIndex();
|
||||||
|
float x;
|
||||||
|
int y;
|
||||||
|
int invert=0;
|
||||||
|
float a;
|
||||||
|
if (index==0) {
|
||||||
|
a=(ui->ca_ymax_SB->value()-ui->ca_ymin_SB->value())/200.0;
|
||||||
|
int numpoints=model.curves[currentCurve].count;
|
||||||
|
for (int i=0; i<numpoints; i++) {
|
||||||
|
if (model.curves[currentCurve].custom) {
|
||||||
|
x=(model.curves[currentCurve].points[i].x+100);
|
||||||
|
} else {
|
||||||
|
x=(200.0/(numpoints-1))*i;
|
||||||
|
}
|
||||||
|
y=ui->ca_ymin_SB->value()+a*x;
|
||||||
|
switch (ui->ca_side_CB->currentIndex()) {
|
||||||
|
case 0:
|
||||||
|
model.curves[currentCurve].points[i].y=y;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
if (x>=100) {
|
||||||
|
model.curves[currentCurve].points[i].y=y;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
if (x<100) {
|
||||||
|
model.curves[currentCurve].points[i].y=y;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (index==1) {
|
||||||
|
int numpoints=model.curves[currentCurve].count;
|
||||||
|
for (int i=0; i<numpoints; i++) {
|
||||||
|
if (model.curves[currentCurve].custom) {
|
||||||
|
x=((model.curves[currentCurve].points[i].x)+100)/2.0;
|
||||||
|
} else {
|
||||||
|
x=(100.0/(numpoints-1))*i;
|
||||||
|
}
|
||||||
|
a=ui->ca_coeff_SB->value();
|
||||||
|
if (a>=0) {
|
||||||
|
y=round(c9xexpou(x,a)*(ui->ca_ymax_SB->value()-ui->ca_ymin_SB->value())/100.0+ui->ca_ymin_SB->value());
|
||||||
|
} else {
|
||||||
|
a=-a;
|
||||||
|
x=100-x;
|
||||||
|
y=round((100.0-c9xexpou(x,a))*(ui->ca_ymax_SB->value()-ui->ca_ymin_SB->value())/100.0+ui->ca_ymin_SB->value());
|
||||||
|
}
|
||||||
|
switch (ui->ca_side_CB->currentIndex()) {
|
||||||
|
case 0:
|
||||||
|
model.curves[currentCurve].points[i].y=y;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
if (x>=50) {
|
||||||
|
model.curves[currentCurve].points[i].y=y;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
if (x<50) {
|
||||||
|
model.curves[currentCurve].points[i].y=y;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (index==2) {
|
||||||
|
int numpoints=model.curves[currentCurve].count;
|
||||||
|
for (int i=0; i<numpoints; i++) {
|
||||||
|
if (model.curves[currentCurve].custom) {
|
||||||
|
x=(model.curves[currentCurve].points[i].x);
|
||||||
|
} else {
|
||||||
|
x=-100.0+(200.0/(numpoints-1))*i;
|
||||||
|
}
|
||||||
|
a=ui->ca_coeff_SB->value();
|
||||||
|
if (x<0) {
|
||||||
|
x=-x;
|
||||||
|
invert=1;
|
||||||
|
} else {
|
||||||
|
invert=0;
|
||||||
|
}
|
||||||
|
if (a>=0) {
|
||||||
|
y=round(c9xexpou(x,a)*(ui->ca_ymax_SB->value()/100.0));
|
||||||
|
} else {
|
||||||
|
a=-a;
|
||||||
|
x=100-x;
|
||||||
|
y=round((100.0-c9xexpou(x,a))*(ui->ca_ymax_SB->value()/100.0));
|
||||||
|
}
|
||||||
|
switch (ui->ca_side_CB->currentIndex()) {
|
||||||
|
case 0:
|
||||||
|
if (invert==1) {
|
||||||
|
model.curves[currentCurve].points[i].y=-y;
|
||||||
|
} else {
|
||||||
|
model.curves[currentCurve].points[i].y=y;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
if (invert==0) {
|
||||||
|
model.curves[currentCurve].points[i].y=y;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
if (invert==1) {
|
||||||
|
model.curves[currentCurve].points[i].y=-y;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (index==3) {
|
||||||
|
int numpoints=model.curves[currentCurve].count;
|
||||||
|
for (int i=0; i<numpoints; i++) {
|
||||||
|
if (model.curves[currentCurve].custom) {
|
||||||
|
x=(model.curves[currentCurve].points[i].x);
|
||||||
|
} else {
|
||||||
|
x=-100.0+(200.0/(numpoints-1))*i;
|
||||||
|
}
|
||||||
|
int pos=(x>=0);
|
||||||
|
a=ui->ca_coeff_SB->value();
|
||||||
|
if (x<0) {
|
||||||
|
x=-x;
|
||||||
|
}
|
||||||
|
if (a>=0) {
|
||||||
|
y=round(c9xexpou(x,a)*((ui->ca_ymax_SB->value()-ui->ca_ymid_SB->value())/100.0)+ui->ca_ymid_SB->value());
|
||||||
|
} else {
|
||||||
|
a=-a;
|
||||||
|
x=100-x;
|
||||||
|
y=round((100.0-c9xexpou(x,a))*((ui->ca_ymax_SB->value()-ui->ca_ymid_SB->value())/100.0)+ui->ca_ymid_SB->value());
|
||||||
|
}
|
||||||
|
switch (ui->ca_side_CB->currentIndex()) {
|
||||||
|
case 0:
|
||||||
|
model.curves[currentCurve].points[i].y=y;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
if (pos) {
|
||||||
|
model.curves[currentCurve].points[i].y=y;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
if (!pos) {
|
||||||
|
model.curves[currentCurve].points[i].y=y;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
updateSettings();
|
||||||
|
setCurrentCurve(currentCurve);
|
||||||
|
drawCurve();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ModelEdit::clearCurves(bool ask)
|
||||||
|
{
|
||||||
|
if(ask) {
|
||||||
|
int res = QMessageBox::question(this,tr("Clear Curves?"),tr("Really clear all the curves?"),QMessageBox::Yes | QMessageBox::No);
|
||||||
|
if(res!=QMessageBox::Yes) return;
|
||||||
|
}
|
||||||
|
curvesLock=true;
|
||||||
|
if (!GetEepromInterface()->getCapability(CustomCurves)){
|
||||||
|
ui->curvetype_CB->setDisabled(true);
|
||||||
|
int count=0;
|
||||||
|
for (int j=0; j< GetEepromInterface()->getCapability(NumCurves3); j++) {
|
||||||
|
model.curves[count].count=3;
|
||||||
|
model.curves[count].custom=false;
|
||||||
|
memset(model.curves[j].name,0,sizeof(model.curves[j].name));
|
||||||
|
for (int i=0; i<17; i++) {
|
||||||
|
model.curves[count].points[i].x=0;
|
||||||
|
model.curves[count].points[i].y=0;
|
||||||
|
}
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
for (int j=0; j< GetEepromInterface()->getCapability(NumCurves5); j++) {
|
||||||
|
model.curves[count].count=5;
|
||||||
|
model.curves[count].custom=false;
|
||||||
|
memset(model.curves[j].name,0,sizeof(model.curves[j].name));
|
||||||
|
for (int i=0; i<17; i++) {
|
||||||
|
model.curves[count].points[i].x=0;
|
||||||
|
model.curves[count].points[i].y=0;
|
||||||
|
}
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
for (int j=0; j< GetEepromInterface()->getCapability(NumCurves9); j++) {
|
||||||
|
model.curves[count].count=9;
|
||||||
|
model.curves[count].custom=false;
|
||||||
|
memset(model.curves[j].name,0,sizeof(model.curves[j].name));
|
||||||
|
for (int i=0; i<17; i++) {
|
||||||
|
model.curves[count].points[i].x=0;
|
||||||
|
model.curves[count].points[i].y=0;
|
||||||
|
}
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
for (int j=count; j<16; j++) {
|
||||||
|
model.curves[j].count=5;
|
||||||
|
model.curves[j].custom=false;
|
||||||
|
memset(model.curves[j].name,0,sizeof(model.curves[j].name));
|
||||||
|
for (int i=0; i<17; i++) {
|
||||||
|
model.curves[j].points[i].x=0;
|
||||||
|
model.curves[j].points[i].y=0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (int j=0; j<16; j++) {
|
||||||
|
model.curves[j].count=5;
|
||||||
|
model.curves[j].custom=false;
|
||||||
|
memset(model.curves[j].name,0,sizeof(model.curves[j].name));
|
||||||
|
for (int i=0; i<17; i++) {
|
||||||
|
model.curves[j].points[i].x=0;
|
||||||
|
model.curves[j].points[i].y=0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (int i=0; i<17; i++) {
|
||||||
|
spnx[i]->setMinimum(-100);
|
||||||
|
spnx[i]->setMaximum(100);
|
||||||
|
spnx[i]->setValue(0);
|
||||||
|
spny[i]->setValue(0);
|
||||||
|
}
|
||||||
|
currentCurve=0;
|
||||||
|
curvesLock=false;
|
||||||
|
if (GetEepromInterface()->getCapability(NumCurves3)>0) {
|
||||||
|
ui->curvetype_CB->setCurrentIndex(0);
|
||||||
|
} else {
|
||||||
|
ui->curvetype_CB->setCurrentIndex(2);
|
||||||
|
}
|
||||||
|
ui->cname_LE->clear();
|
||||||
|
updateSettings();
|
||||||
|
drawCurve();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ModelEdit::setCurve(uint8_t c, int8_t ar[])
|
||||||
|
{
|
||||||
|
int len=sizeof(ar)/sizeof(int8_t);
|
||||||
|
if (GetEepromInterface()->getCapability(CustomCurves)) {
|
||||||
|
if (GetEepromInterface()->getCapability(NumCurves)>c) {
|
||||||
|
if (len<9) {
|
||||||
|
model.curves[c].count=5;
|
||||||
|
model.curves[c].custom=false;
|
||||||
|
for (int i=0; i< 5; i++) {
|
||||||
|
model.curves[c].points[i].y=ar[i];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
model.curves[c].count=5;
|
||||||
|
model.curves[c].custom=false;
|
||||||
|
for (int i=0; i< 5; i++) {
|
||||||
|
model.curves[c].points[i].y=ar[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (len<9) {
|
||||||
|
model.curves[c].count=5;
|
||||||
|
model.curves[c].custom=false;
|
||||||
|
for (int i=0; i< 5; i++) {
|
||||||
|
model.curves[c].points[i].y=ar[i];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
model.curves[c+8].count=5;
|
||||||
|
model.curves[c+8].custom=false;
|
||||||
|
for (int i=0; i< 5; i++) {
|
||||||
|
model.curves[c+8].points[i].y=ar[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ModelEdit::ControlCurveSignal(bool flag)
|
||||||
|
{
|
||||||
|
foreach(QSpinBox *sb, findChildren<QSpinBox *>(QRegExp("curvePt[0-9]+"))) {
|
||||||
|
sb->blockSignals(flag);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
47
companion/src/modeledit/curves.h
Normal file
47
companion/src/modeledit/curves.h
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
#ifndef CURVES_H
|
||||||
|
#define CURVES_H
|
||||||
|
|
||||||
|
#include "modelpanel.h"
|
||||||
|
#include <QSpinBox>
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
class Curves;
|
||||||
|
}
|
||||||
|
|
||||||
|
class Curves : public ModelPanel
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
Curves(QWidget *parent, ModelData & model);
|
||||||
|
virtual ~Curves();
|
||||||
|
|
||||||
|
virtual void update();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void resetCurve();
|
||||||
|
void editCurve();
|
||||||
|
void plotCurve(bool checked);
|
||||||
|
void on_cname_LE_editingFinished();
|
||||||
|
void on_curvetype_CB_currentIndexChanged(int index);
|
||||||
|
void onPointEdited();
|
||||||
|
void onNodeMoved(int x, int y);
|
||||||
|
void onNodeFocus();
|
||||||
|
void onNodeUnfocus();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void resizeEvent(QResizeEvent *event);
|
||||||
|
|
||||||
|
private:
|
||||||
|
Ui::Curves *ui;
|
||||||
|
int currentCurve;
|
||||||
|
bool visibleCurves[C9X_MAX_CURVES];
|
||||||
|
QSpinBox * spnx[C9X_MAX_POINTS];
|
||||||
|
QSpinBox * spny[C9X_MAX_POINTS];
|
||||||
|
void setCurrentCurve(int index);
|
||||||
|
void updateCurve();
|
||||||
|
void updateCurveType();
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // CURVES_H
|
167
companion/src/modeledit/curves.ui
Normal file
167
companion/src/modeledit/curves.ui
Normal file
|
@ -0,0 +1,167 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>Curves</class>
|
||||||
|
<widget class="QWidget" name="Curves">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>638</width>
|
||||||
|
<height>587</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Form</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<item>
|
||||||
|
<layout class="QGridLayout" name="gridLayout_80" columnstretch="0,0,0,0,0">
|
||||||
|
<item row="0" column="0" rowspan="3">
|
||||||
|
<layout class="QGridLayout" name="curvesLayout"/>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="1" rowspan="3">
|
||||||
|
<layout class="QGridLayout" name="gridLayout_8" rowstretch="0,0,0" columnstretch="1,1">
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QLabel" name="curvetype_label">
|
||||||
|
<property name="text">
|
||||||
|
<string>Curve type</string>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="1">
|
||||||
|
<widget class="QComboBox" name="curvetype_CB">
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>3 points</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>3 points custom</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>5 points</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>5 points custom</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>9 points</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>9 points custom</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>17 points</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>17 points custom</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="0">
|
||||||
|
<widget class="QLabel" name="cname_label">
|
||||||
|
<property name="text">
|
||||||
|
<string>Curve name</string>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="1">
|
||||||
|
<widget class="QLineEdit" name="cname_LE">
|
||||||
|
<property name="maxLength">
|
||||||
|
<number>6</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="0" colspan="2">
|
||||||
|
<widget class="QGraphicsView" name="curvePreview">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>400</width>
|
||||||
|
<height>400</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignCenter</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="2" rowspan="3" colspan="2">
|
||||||
|
<layout class="QGridLayout" name="pointsLayout">
|
||||||
|
<property name="horizontalSpacing">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="verticalSpacing">
|
||||||
|
<number>2</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item row="4" column="0" colspan="5">
|
||||||
|
<spacer name="verticalSpacer_6">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeType">
|
||||||
|
<enum>QSizePolicy::MinimumExpanding</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="4" rowspan="3">
|
||||||
|
<spacer name="horizontalSpacer">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources/>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
473
companion/src/modeledit/customfunctions.cpp
Normal file
473
companion/src/modeledit/customfunctions.cpp
Normal file
|
@ -0,0 +1,473 @@
|
||||||
|
#include "customfunctions.h"
|
||||||
|
#include <QLabel>
|
||||||
|
#include <QLineEdit>
|
||||||
|
#include <QSpinBox>
|
||||||
|
#include <QComboBox>
|
||||||
|
#include <QCheckBox>
|
||||||
|
#include <QDoubleSpinBox>
|
||||||
|
#include "helpers.h"
|
||||||
|
|
||||||
|
CustomFunctionsPanel::CustomFunctionsPanel(QWidget * parent, ModelData & model, GeneralSettings & generalSettings):
|
||||||
|
ModelPanel(parent, model),
|
||||||
|
generalSettings(generalSettings),
|
||||||
|
phononLock(false)
|
||||||
|
{
|
||||||
|
QGridLayout * gridLayout = new QGridLayout(this);
|
||||||
|
|
||||||
|
int col = 1;
|
||||||
|
addLabel(gridLayout, tr("Switch"), col++);
|
||||||
|
addLabel(gridLayout, tr("Function"), col++);
|
||||||
|
addLabel(gridLayout, tr("Parameters"), col++);
|
||||||
|
addLabel(gridLayout, tr("Enable"), col++);
|
||||||
|
|
||||||
|
lock = true;
|
||||||
|
int num_fsw = GetEepromInterface()->getCapability(CustomFunctions);
|
||||||
|
|
||||||
|
QStringList paramarmList;
|
||||||
|
if (!GetEepromInterface()->getCapability(VoicesAsNumbers)) {
|
||||||
|
for (int i=0; i<num_fsw; i++) {
|
||||||
|
if (model.funcSw[i].func==FuncPlayPrompt || model.funcSw[i].func==FuncBackgroundMusic) {
|
||||||
|
QString temp = model.funcSw[i].paramarm;
|
||||||
|
if (!temp.isEmpty()) {
|
||||||
|
if (!paramarmList.contains(temp)) {
|
||||||
|
paramarmList.append(temp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QSettings settings("companion9x", "companion9x");
|
||||||
|
QString path = settings.value("sdPath", ".").toString();
|
||||||
|
path.append("/SOUNDS/");
|
||||||
|
QString lang = generalSettings.ttsLanguage;
|
||||||
|
if (lang.isEmpty())
|
||||||
|
lang="en";
|
||||||
|
path.append(lang);
|
||||||
|
QDir qd(path);
|
||||||
|
int vml= GetEepromInterface()->getCapability(VoicesMaxLength)+4;
|
||||||
|
if (qd.exists()) {
|
||||||
|
QStringList filters;
|
||||||
|
filters << "*.wav" << "*.WAV";
|
||||||
|
foreach ( QString file, qd.entryList(filters, QDir::Files) ) {
|
||||||
|
QFileInfo fi(file);
|
||||||
|
QString temp=fi.completeBaseName();
|
||||||
|
if (!paramarmList.contains(temp) && temp.length()<=vml) {
|
||||||
|
paramarmList.append(temp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i=0; i<num_fsw; i++) {
|
||||||
|
AssignFunc func = model.funcSw[i].func;
|
||||||
|
|
||||||
|
// The label
|
||||||
|
QLabel * label = new QLabel(this);
|
||||||
|
label->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||||
|
label->setMouseTracking(true);
|
||||||
|
label->setProperty("index", i);
|
||||||
|
label->setText(tr("CF%1").arg(i+1));
|
||||||
|
gridLayout->addWidget(label, i+1, 0);
|
||||||
|
connect(label, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(fsw_customContextMenuRequested(QPoint)));
|
||||||
|
|
||||||
|
// The switch
|
||||||
|
fswtchSwtch[i] = new QComboBox(this);
|
||||||
|
fswtchSwtch[i]->setProperty("index", i);
|
||||||
|
connect(fswtchSwtch[i], SIGNAL(currentIndexChanged(int)), this, SLOT(customFunctionEdited()));
|
||||||
|
gridLayout->addWidget(fswtchSwtch[i], i+1, 1);
|
||||||
|
populateSwitchCB(fswtchSwtch[i], model.funcSw[i].swtch, POPULATE_MSWITCHES|POPULATE_ONOFF);
|
||||||
|
|
||||||
|
// The function
|
||||||
|
fswtchFunc[i] = new QComboBox(this);
|
||||||
|
fswtchFunc[i]->setProperty("index", i);
|
||||||
|
connect(fswtchFunc[i], SIGNAL(currentIndexChanged(int)), this, SLOT(customFunctionEdited()));
|
||||||
|
gridLayout->addWidget(fswtchFunc[i], i+1, 2);
|
||||||
|
populateFuncCB(fswtchFunc[i], model.funcSw[i].func);
|
||||||
|
|
||||||
|
QHBoxLayout *paramLayout = new QHBoxLayout();
|
||||||
|
gridLayout->addLayout(paramLayout, i+1, 3);
|
||||||
|
|
||||||
|
fswtchGVmode[i] = new QComboBox(this);
|
||||||
|
fswtchGVmode[i]->setProperty("index", i);
|
||||||
|
connect(fswtchGVmode[i], SIGNAL(currentIndexChanged(int)), this, SLOT(customFunctionEdited()));
|
||||||
|
paramLayout->addWidget(fswtchGVmode[i]);
|
||||||
|
populateGVmodeCB(fswtchGVmode[i], model.funcSw[i].adjustMode);
|
||||||
|
|
||||||
|
fswtchParamGV[i] = new QCheckBox(this);
|
||||||
|
fswtchParamGV[i]->setProperty("index", i);
|
||||||
|
fswtchParamGV[i]->setText("GV");
|
||||||
|
fswtchParamGV[i]->setSizePolicy(QSizePolicy::Minimum,QSizePolicy::Minimum);
|
||||||
|
connect(fswtchParamGV[i], SIGNAL(stateChanged(int)), this, SLOT(customFunctionEdited()));
|
||||||
|
paramLayout->addWidget(fswtchParamGV[i]);
|
||||||
|
|
||||||
|
fswtchParam[i] = new QDoubleSpinBox(this);
|
||||||
|
fswtchParam[i]->setProperty("index", i);
|
||||||
|
fswtchParam[i]->setAccelerated(true);
|
||||||
|
fswtchParam[i]->setDecimals(0);
|
||||||
|
connect(fswtchParam[i], SIGNAL(editingFinished()), this, SLOT(customFunctionEdited()));
|
||||||
|
paramLayout->addWidget(fswtchParam[i]);
|
||||||
|
|
||||||
|
fswtchParamT[i] = new QComboBox(this);
|
||||||
|
fswtchParamT[i]->setProperty("index", i);
|
||||||
|
paramLayout->addWidget(fswtchParamT[i]);
|
||||||
|
populateFuncParamCB(fswtchParamT[i], func, model.funcSw[i].param, model.funcSw[i].adjustMode);
|
||||||
|
connect(fswtchParamT[i], SIGNAL(currentIndexChanged(int)), this, SLOT(customFunctionEdited()));
|
||||||
|
|
||||||
|
fswtchParamArmT[i] = new QComboBox(this);
|
||||||
|
fswtchParamArmT[i]->setProperty("index", i);
|
||||||
|
populateFuncParamArmTCB(fswtchParamArmT[i],&model, model.funcSw[i].paramarm, paramarmList);
|
||||||
|
fswtchParamArmT[i]->setEditable(true);
|
||||||
|
paramLayout->addWidget(fswtchParamArmT[i]);
|
||||||
|
|
||||||
|
connect(fswtchParamArmT[i], SIGNAL(currentIndexChanged(int)), this, SLOT(customFunctionEdited()));
|
||||||
|
connect(fswtchParamArmT[i], SIGNAL(editTextChanged ( const QString)), this, SLOT(customFunctionEdited()));
|
||||||
|
|
||||||
|
#ifdef PHONON
|
||||||
|
playBT[i] = new QPushButton(this);
|
||||||
|
playBT[i]->setObjectName(QString("play_%1").arg(i));
|
||||||
|
playBT[i]->setIcon(QIcon(":/images/play.png"));
|
||||||
|
paramLayout->addWidget(playBT[i]);
|
||||||
|
connect(playBT[i], SIGNAL(pressed()), this, SLOT(playMusic()));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
QHBoxLayout *repeatLayout = new QHBoxLayout();
|
||||||
|
gridLayout->addLayout(repeatLayout, i+1, 4);
|
||||||
|
|
||||||
|
fswtchRepeat[i] = new QComboBox(this);
|
||||||
|
fswtchRepeat[i]->setProperty("index", i);
|
||||||
|
connect(fswtchRepeat[i], SIGNAL(currentIndexChanged(int)), this, SLOT(customFunctionEdited()));
|
||||||
|
repeatLayout->addWidget(fswtchRepeat[i], i+1);
|
||||||
|
populateRepeatCB(fswtchRepeat[i], model.funcSw[i].repeatParam);
|
||||||
|
|
||||||
|
fswtchEnable[i] = new QCheckBox(this);
|
||||||
|
fswtchEnable[i]->setProperty("index", i);
|
||||||
|
fswtchEnable[i]->setText(tr("ON"));
|
||||||
|
repeatLayout->addWidget(fswtchEnable[i], i+1);
|
||||||
|
fswtchEnable[i]->setChecked(model.funcSw[i].enabled);
|
||||||
|
connect(fswtchEnable[i], SIGNAL(stateChanged(int)), this, SLOT(customFunctionEdited()));
|
||||||
|
}
|
||||||
|
|
||||||
|
lock = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
CustomFunctionsPanel::~CustomFunctionsPanel()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef PHONON
|
||||||
|
|
||||||
|
void CustomFunctionsPanel::mediaPlayer_state(Phonon::State newState, Phonon::State oldState)
|
||||||
|
{
|
||||||
|
if (phononLock)
|
||||||
|
return;
|
||||||
|
phononLock=true;
|
||||||
|
if ((newState==Phonon::StoppedState || newState==Phonon::PausedState) && oldState==Phonon::PlayingState) {
|
||||||
|
clickObject->stop();
|
||||||
|
clickObject->clearQueue();
|
||||||
|
clickObject->clear();
|
||||||
|
for (int i=0; i<GetEepromInterface()->getCapability(CustomFunctions); i++) {
|
||||||
|
playBT[i]->setObjectName(QString("play_%1").arg(i));
|
||||||
|
playBT[i]->setIcon(QIcon(":/images/play.png"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (newState==Phonon::ErrorState) {
|
||||||
|
clickObject->stop();
|
||||||
|
clickObject->clearQueue();
|
||||||
|
clickObject->clear();
|
||||||
|
for (int i=0; i<GetEepromInterface()->getCapability(CustomFunctions); i++) {
|
||||||
|
playBT[i]->setObjectName(QString("play_%1").arg(i));
|
||||||
|
playBT[i]->setIcon(QIcon(":/images/play.png"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
phononLock=false;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void CustomFunctionsPanel::playMusic()
|
||||||
|
{
|
||||||
|
QPushButton *playButton = qobject_cast<QPushButton*>(sender());
|
||||||
|
int index=playButton->objectName().mid(5,2).toInt();
|
||||||
|
QString function=playButton->objectName().left(4);
|
||||||
|
QSettings settings("companion9x", "companion9x");
|
||||||
|
QString path=settings.value("sdPath", ".").toString();
|
||||||
|
QDir qd(path);
|
||||||
|
QString track;
|
||||||
|
if (qd.exists()) {
|
||||||
|
if (GetEepromInterface()->getCapability(VoicesAsNumbers)) {
|
||||||
|
track=path+QString("/%1.wav").arg(int(fswtchParam[index]->value()),4,10,(const QChar)'0');
|
||||||
|
} else {
|
||||||
|
path.append("/SOUNDS/");
|
||||||
|
QString lang = generalSettings.ttsLanguage;
|
||||||
|
if (lang.isEmpty())
|
||||||
|
lang="en";
|
||||||
|
path.append(lang);
|
||||||
|
if (fswtchParamArmT[index]->currentText()!="----") {
|
||||||
|
track=path+"/"+fswtchParamArmT[index]->currentText()+".wav";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
QFile file(track);
|
||||||
|
if (!file.exists()) {
|
||||||
|
QMessageBox::critical(this, tr("Error"), tr("Unable to find sound file %1!").arg(track));
|
||||||
|
track.clear();
|
||||||
|
}
|
||||||
|
#ifdef PHONON
|
||||||
|
if (function=="play" && !track.isEmpty()) {
|
||||||
|
clickObject->clear();
|
||||||
|
clickObject->setCurrentSource(Phonon::MediaSource(track));
|
||||||
|
clickObject->play();
|
||||||
|
playBT[index]->setObjectName(QString("stop_%1").arg(index));
|
||||||
|
playBT[index]->setIcon(QIcon(":/images/stop.png"));
|
||||||
|
} else {
|
||||||
|
clickObject->stop();
|
||||||
|
clickObject->clear();
|
||||||
|
playBT[index]->setObjectName(QString("play_%1").arg(index));
|
||||||
|
playBT[index]->setIcon(QIcon(":/images/play.png"));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#define CUSTOM_FUNCTION_NUMERIC_PARAM (1<<0)
|
||||||
|
#define CUSTOM_FUNCTION_SOURCE_PARAM (1<<1)
|
||||||
|
#define CUSTOM_FUNCTION_FILE_PARAM (1<<2)
|
||||||
|
#define CUSTOM_FUNCTION_GV_MODE (1<<3)
|
||||||
|
#define CUSTOM_FUNCTION_GV_TOOGLE (1<<4)
|
||||||
|
#define CUSTOM_FUNCTION_ENABLE (1<<5)
|
||||||
|
#define CUSTOM_FUNCTION_REPEAT (1<<6)
|
||||||
|
#define CUSTOM_FUNCTION_PLAY (1<<7)
|
||||||
|
|
||||||
|
void CustomFunctionsPanel::customFunctionEdited()
|
||||||
|
{
|
||||||
|
if (!lock) {
|
||||||
|
lock = true;
|
||||||
|
|
||||||
|
int index = sender()->property("index").toInt();
|
||||||
|
refreshCustomFunction(index, true);
|
||||||
|
|
||||||
|
emit modified();
|
||||||
|
lock = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CustomFunctionsPanel::refreshCustomFunction(int i, bool modified)
|
||||||
|
{
|
||||||
|
unsigned int widgetsMask = 0;
|
||||||
|
if (modified) {
|
||||||
|
model.funcSw[i].swtch = RawSwitch(fswtchSwtch[i]->itemData(fswtchSwtch[i]->currentIndex()).toInt());
|
||||||
|
model.funcSw[i].func = (AssignFunc)fswtchFunc[i]->currentIndex();
|
||||||
|
model.funcSw[i].enabled =fswtchEnable[i]->isChecked();
|
||||||
|
model.funcSw[i].repeatParam = (AssignFunc)fswtchRepeat[i]->currentIndex();
|
||||||
|
model.funcSw[i].adjustMode = (AssignFunc)fswtchGVmode[i]->currentIndex();
|
||||||
|
}
|
||||||
|
|
||||||
|
int index = fswtchFunc[i]->currentIndex();
|
||||||
|
|
||||||
|
if (index>=FuncSafetyCh1 && index<=FuncSafetyCh16) {
|
||||||
|
fswtchParam[i]->setDecimals(0);
|
||||||
|
fswtchParam[i]->setSingleStep(1);
|
||||||
|
fswtchParam[i]->setMinimum(-125);
|
||||||
|
fswtchParam[i]->setMaximum(125);
|
||||||
|
if (modified) {
|
||||||
|
model.funcSw[i].param = fswtchParam[i]->value();
|
||||||
|
}
|
||||||
|
fswtchParam[i]->setValue(model.funcSw[i].param);
|
||||||
|
widgetsMask |= CUSTOM_FUNCTION_NUMERIC_PARAM + CUSTOM_FUNCTION_ENABLE;
|
||||||
|
} else if (index==FuncLogs) {
|
||||||
|
fswtchParam[i]->setDecimals(1);
|
||||||
|
fswtchParam[i]->setMinimum(0);
|
||||||
|
fswtchParam[i]->setMaximum(25.5);
|
||||||
|
fswtchParam[i]->setSingleStep(0.1);
|
||||||
|
if (modified) model.funcSw[i].param = fswtchParam[i]->value()*10.0;
|
||||||
|
fswtchParam[i]->setValue(model.funcSw[i].param/10.0);
|
||||||
|
widgetsMask |= CUSTOM_FUNCTION_NUMERIC_PARAM + CUSTOM_FUNCTION_ENABLE;
|
||||||
|
} else if (index>=FuncAdjustGV1 && index<=FuncAdjustGV5) {
|
||||||
|
if (modified) model.funcSw[i].adjustMode = fswtchGVmode[i]->currentIndex();
|
||||||
|
widgetsMask |= CUSTOM_FUNCTION_GV_MODE + CUSTOM_FUNCTION_ENABLE;
|
||||||
|
if (model.funcSw[i].adjustMode==0) {
|
||||||
|
if (modified) model.funcSw[i].param = fswtchParam[i]->value();
|
||||||
|
fswtchParam[i]->setDecimals(0);
|
||||||
|
fswtchParam[i]->setSingleStep(1);
|
||||||
|
fswtchParam[i]->setMinimum(-125);
|
||||||
|
fswtchParam[i]->setMaximum(125);
|
||||||
|
fswtchParam[i]->setValue(model.funcSw[i].param);
|
||||||
|
widgetsMask |= CUSTOM_FUNCTION_NUMERIC_PARAM;
|
||||||
|
} else {
|
||||||
|
if (modified) model.funcSw[i].param = fswtchParamT[i]->itemData(fswtchParamT[i]->currentIndex()).toInt();
|
||||||
|
populateFuncParamCB(fswtchParamT[i], index, model.funcSw[i].param, model.funcSw[i].adjustMode);
|
||||||
|
widgetsMask |= CUSTOM_FUNCTION_SOURCE_PARAM;
|
||||||
|
}
|
||||||
|
} else if (index==FuncReset) {
|
||||||
|
if (modified) model.funcSw[i].param = (uint8_t)fswtchParamT[i]->currentIndex();
|
||||||
|
populateFuncParamCB(fswtchParamT[i], index, model.funcSw[i].param);
|
||||||
|
widgetsMask |= CUSTOM_FUNCTION_SOURCE_PARAM;
|
||||||
|
} else if (index==FuncVolume) {
|
||||||
|
if (modified) model.funcSw[i].param = fswtchParamT[i]->itemData(fswtchParamT[i]->currentIndex()).toInt();
|
||||||
|
populateFuncParamCB(fswtchParamT[i], index, model.funcSw[i].param);
|
||||||
|
widgetsMask |= CUSTOM_FUNCTION_SOURCE_PARAM + CUSTOM_FUNCTION_ENABLE;
|
||||||
|
} else if (index==FuncPlaySound || index==FuncPlayHaptic || index==FuncPlayValue || index==FuncPlayPrompt || index==FuncPlayBoth || index==FuncBackgroundMusic) {
|
||||||
|
if (modified) model.funcSw[i].repeatParam = fswtchRepeat[i]->itemData(fswtchRepeat[i]->currentIndex()).toInt();
|
||||||
|
if (index != FuncBackgroundMusic) {
|
||||||
|
if (GetEepromInterface()->getCapability(HasFuncRepeat)) {
|
||||||
|
widgetsMask |= CUSTOM_FUNCTION_REPEAT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (index==FuncPlayValue) {
|
||||||
|
if (modified) model.funcSw[i].param = fswtchParamT[i]->itemData(fswtchParamT[i]->currentIndex()).toInt();
|
||||||
|
populateFuncParamCB(fswtchParamT[i], index, model.funcSw[i].param);
|
||||||
|
widgetsMask |= CUSTOM_FUNCTION_SOURCE_PARAM + CUSTOM_FUNCTION_REPEAT;
|
||||||
|
} else if (index==FuncPlayPrompt || index==FuncPlayBoth) {
|
||||||
|
if (GetEepromInterface()->getCapability(VoicesAsNumbers)) {
|
||||||
|
fswtchParam[i]->setDecimals(0);
|
||||||
|
fswtchParam[i]->setSingleStep(1);
|
||||||
|
fswtchParam[i]->setMinimum(0);
|
||||||
|
if (index==FuncPlayPrompt) {
|
||||||
|
widgetsMask |= CUSTOM_FUNCTION_NUMERIC_PARAM + CUSTOM_FUNCTION_REPEAT + CUSTOM_FUNCTION_GV_TOOGLE;
|
||||||
|
} else {
|
||||||
|
widgetsMask |= CUSTOM_FUNCTION_NUMERIC_PARAM + CUSTOM_FUNCTION_REPEAT;
|
||||||
|
fswtchParamGV[i]->setChecked(false);
|
||||||
|
}
|
||||||
|
fswtchParam[i]->setMaximum(index==FuncPlayBoth ? 254 : 255);
|
||||||
|
if (modified) {
|
||||||
|
if (fswtchParamGV[i]->isChecked()) {
|
||||||
|
fswtchParam[i]->setMinimum(1);
|
||||||
|
model.funcSw[i].param = std::min(fswtchParam[i]->value(),5.0)+(fswtchParamGV[i]->isChecked() ? 250 : 0);
|
||||||
|
} else {
|
||||||
|
model.funcSw[i].param = fswtchParam[i]->value();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (model.funcSw[i].param>250 && (index!=FuncPlayBoth)) {
|
||||||
|
fswtchParamGV[i]->setChecked(true);
|
||||||
|
fswtchParam[i]->setValue(model.funcSw[i].param-250);
|
||||||
|
fswtchParam[i]->setMaximum(5);
|
||||||
|
} else {
|
||||||
|
fswtchParamGV[i]->setChecked(false);
|
||||||
|
fswtchParam[i]->setValue(model.funcSw[i].param);
|
||||||
|
}
|
||||||
|
if (model.funcSw[i].param < 251)
|
||||||
|
widgetsMask |= CUSTOM_FUNCTION_PLAY;
|
||||||
|
} else {
|
||||||
|
widgetsMask |= CUSTOM_FUNCTION_FILE_PARAM;
|
||||||
|
if (modified) {
|
||||||
|
memset(model.funcSw[i].paramarm, 0, sizeof(model.funcSw[i].paramarm));
|
||||||
|
int vml=GetEepromInterface()->getCapability(VoicesMaxLength);
|
||||||
|
if (fswtchParamArmT[i]->currentText() != "----") {
|
||||||
|
widgetsMask |= CUSTOM_FUNCTION_PLAY;
|
||||||
|
for (int j=0; j<std::min(fswtchParamArmT[i]->currentText().length(),vml); j++) {
|
||||||
|
model.funcSw[i].paramarm[j] = fswtchParamArmT[i]->currentText().toAscii().at(j);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (index==FuncBackgroundMusic) {
|
||||||
|
widgetsMask |= CUSTOM_FUNCTION_FILE_PARAM;
|
||||||
|
if (modified) {
|
||||||
|
memset(model.funcSw[i].paramarm, 0, sizeof(model.funcSw[i].paramarm));
|
||||||
|
int vml=GetEepromInterface()->getCapability(VoicesMaxLength);
|
||||||
|
if (fswtchParamArmT[i]->currentText() != "----") {
|
||||||
|
widgetsMask |= CUSTOM_FUNCTION_PLAY;
|
||||||
|
for (int j=0; j<std::min(fswtchParamArmT[i]->currentText().length(),vml); j++) {
|
||||||
|
model.funcSw[i].paramarm[j] = fswtchParamArmT[i]->currentText().toAscii().at(j);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (index==FuncPlaySound) {
|
||||||
|
if (modified) model.funcSw[i].param = (uint8_t)fswtchParamT[i]->currentIndex();
|
||||||
|
populateFuncParamCB(fswtchParamT[i], index, model.funcSw[i].param);
|
||||||
|
widgetsMask |= CUSTOM_FUNCTION_SOURCE_PARAM;
|
||||||
|
} else if (index==FuncPlayHaptic) {
|
||||||
|
if (modified) model.funcSw[i].param = (uint8_t)fswtchParamT[i]->currentIndex();
|
||||||
|
populateFuncParamCB(fswtchParamT[i], index, model.funcSw[i].param);
|
||||||
|
widgetsMask |= CUSTOM_FUNCTION_SOURCE_PARAM;
|
||||||
|
}
|
||||||
|
} else if (model.funcSw[i].swtch.type!=SWITCH_TYPE_NONE) {
|
||||||
|
if (modified) model.funcSw[i].param = fswtchParam[i]->value();
|
||||||
|
fswtchParam[i]->setDecimals(0);
|
||||||
|
fswtchParam[i]->setSingleStep(1);
|
||||||
|
fswtchParam[i]->setValue(model.funcSw[i].param);
|
||||||
|
if (index<=FuncInstantTrim) {
|
||||||
|
widgetsMask |= CUSTOM_FUNCTION_ENABLE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fswtchParam[i]->setVisible(widgetsMask & CUSTOM_FUNCTION_NUMERIC_PARAM);
|
||||||
|
fswtchParamGV[i]->setVisible(widgetsMask & CUSTOM_FUNCTION_GV_TOOGLE);
|
||||||
|
fswtchParamT[i]->setVisible(widgetsMask & CUSTOM_FUNCTION_SOURCE_PARAM);
|
||||||
|
fswtchParamArmT[i]->setVisible(widgetsMask & CUSTOM_FUNCTION_FILE_PARAM);
|
||||||
|
fswtchEnable[i]->setVisible(widgetsMask & CUSTOM_FUNCTION_ENABLE);
|
||||||
|
if (!(widgetsMask & CUSTOM_FUNCTION_ENABLE)) fswtchEnable[i]->setChecked(false);
|
||||||
|
fswtchRepeat[i]->setVisible(widgetsMask & CUSTOM_FUNCTION_REPEAT);
|
||||||
|
fswtchGVmode[i]->setVisible(widgetsMask & CUSTOM_FUNCTION_GV_MODE);
|
||||||
|
#ifdef PHONON
|
||||||
|
playBT[i]->setVisible(widgetsMask & CUSTOM_FUNCTION_PLAY);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void CustomFunctionsPanel::update()
|
||||||
|
{
|
||||||
|
for (int i=0; i<GetEepromInterface()->getCapability(CustomFunctions); i++) {
|
||||||
|
refreshCustomFunction(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CustomFunctionsPanel::fswPaste()
|
||||||
|
{
|
||||||
|
const QClipboard *clipboard = QApplication::clipboard();
|
||||||
|
const QMimeData *mimeData = clipboard->mimeData();
|
||||||
|
if (mimeData->hasFormat("application/x-companion9x-fsw")) {
|
||||||
|
QByteArray fswData = mimeData->data("application/x-companion9x-fsw");
|
||||||
|
|
||||||
|
FuncSwData *fsw = &model.funcSw[selectedFunction];
|
||||||
|
memcpy(fsw, fswData.mid(0, sizeof(FuncSwData)).constData(), sizeof(FuncSwData));
|
||||||
|
// TODO update switch and func
|
||||||
|
populateSwitchCB(fswtchSwtch[selectedFunction], model.funcSw[selectedFunction].swtch, POPULATE_MSWITCHES|POPULATE_ONOFF);
|
||||||
|
populateFuncCB(fswtchFunc[selectedFunction], model.funcSw[selectedFunction].func);
|
||||||
|
refreshCustomFunction(selectedFunction);
|
||||||
|
emit modified();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CustomFunctionsPanel::fswDelete()
|
||||||
|
{
|
||||||
|
model.funcSw[selectedFunction].clear();
|
||||||
|
// TODO update switch and func
|
||||||
|
populateSwitchCB(fswtchSwtch[selectedFunction], model.funcSw[selectedFunction].swtch, POPULATE_MSWITCHES|POPULATE_ONOFF);
|
||||||
|
populateFuncCB(fswtchFunc[selectedFunction], model.funcSw[selectedFunction].func);
|
||||||
|
refreshCustomFunction(selectedFunction);
|
||||||
|
emit modified();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CustomFunctionsPanel::fswCopy()
|
||||||
|
{
|
||||||
|
QByteArray fswData;
|
||||||
|
fswData.append((char*)&model.funcSw[selectedFunction],sizeof(FuncSwData));
|
||||||
|
QMimeData *mimeData = new QMimeData;
|
||||||
|
mimeData->setData("application/x-companion9x-fsw", fswData);
|
||||||
|
QApplication::clipboard()->setMimeData(mimeData,QClipboard::Clipboard);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CustomFunctionsPanel::fswCut()
|
||||||
|
{
|
||||||
|
fswCopy();
|
||||||
|
fswDelete();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CustomFunctionsPanel::fsw_customContextMenuRequested(QPoint pos)
|
||||||
|
{
|
||||||
|
QLabel *label = (QLabel *)sender();
|
||||||
|
selectedFunction = label->property("index").toInt();
|
||||||
|
|
||||||
|
QPoint globalPos = label->mapToGlobal(pos);
|
||||||
|
|
||||||
|
const QClipboard *clipboard = QApplication::clipboard();
|
||||||
|
const QMimeData *mimeData = clipboard->mimeData();
|
||||||
|
bool hasData = mimeData->hasFormat("application/x-companion9x-fsw");
|
||||||
|
|
||||||
|
QMenu contextMenu;
|
||||||
|
contextMenu.addAction(QIcon(":/images/clear.png"), tr("&Delete"),this,SLOT(fswDelete()),tr("Delete"));
|
||||||
|
contextMenu.addAction(QIcon(":/images/copy.png"), tr("&Copy"),this,SLOT(fswCopy()),tr("Ctrl+C"));
|
||||||
|
contextMenu.addAction(QIcon(":/images/cut.png"), tr("&Cut"),this,SLOT(fswCut()),tr("Ctrl+X"));
|
||||||
|
contextMenu.addAction(QIcon(":/images/paste.png"), tr("&Paste"),this,SLOT(fswPaste()),tr("Ctrl+V"))->setEnabled(hasData);
|
||||||
|
|
||||||
|
contextMenu.exec(globalPos);
|
||||||
|
}
|
61
companion/src/modeledit/customfunctions.h
Normal file
61
companion/src/modeledit/customfunctions.h
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
#ifndef CUSTOMFUNCTIONS_H
|
||||||
|
#define CUSTOMFUNCTIONS_H
|
||||||
|
|
||||||
|
#include "modelpanel.h"
|
||||||
|
#include <QLabel>
|
||||||
|
#include <QCheckBox>
|
||||||
|
#include <QComboBox>
|
||||||
|
#include <QDoubleSpinBox>
|
||||||
|
#include <QPushButton>
|
||||||
|
#ifdef PHONON
|
||||||
|
#include <phonon/audiooutput.h>
|
||||||
|
#include <phonon/mediaobject.h>
|
||||||
|
#include <phonon/mediasource.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
class CustomFunctionsPanel : public ModelPanel
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
CustomFunctionsPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings);
|
||||||
|
~CustomFunctionsPanel();
|
||||||
|
|
||||||
|
virtual void update();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void customFunctionEdited();
|
||||||
|
void fsw_customContextMenuRequested(QPoint pos);
|
||||||
|
void refreshCustomFunction(int index, bool modified=false);
|
||||||
|
void playMusic();
|
||||||
|
#ifdef PHONON
|
||||||
|
void mediaPlayer_state(Phonon::State newState, Phonon::State oldState);
|
||||||
|
#endif
|
||||||
|
void fswDelete();
|
||||||
|
void fswCopy();
|
||||||
|
void fswPaste();
|
||||||
|
void fswCut();
|
||||||
|
|
||||||
|
private:
|
||||||
|
GeneralSettings & generalSettings;
|
||||||
|
bool phononLock;
|
||||||
|
QComboBox * fswtchSwtch[C9X_MAX_CUSTOM_FUNCTIONS];
|
||||||
|
QComboBox * fswtchFunc[C9X_MAX_CUSTOM_FUNCTIONS];
|
||||||
|
QCheckBox * fswtchParamGV[C9X_MAX_CUSTOM_FUNCTIONS];
|
||||||
|
QDoubleSpinBox * fswtchParam[C9X_MAX_CUSTOM_FUNCTIONS];
|
||||||
|
QPushButton * playBT[C9X_MAX_CUSTOM_FUNCTIONS];
|
||||||
|
QComboBox * fswtchParamT[C9X_MAX_CUSTOM_FUNCTIONS];
|
||||||
|
QComboBox * fswtchParamArmT[C9X_MAX_CUSTOM_FUNCTIONS];
|
||||||
|
QCheckBox * fswtchEnable[C9X_MAX_CUSTOM_FUNCTIONS];
|
||||||
|
QComboBox * fswtchRepeat[C9X_MAX_CUSTOM_FUNCTIONS];
|
||||||
|
QComboBox * fswtchGVmode[C9X_MAX_CUSTOM_FUNCTIONS];
|
||||||
|
#ifdef PHONON
|
||||||
|
Phonon::MediaObject *clickObject;
|
||||||
|
Phonon::AudioOutput *clickOutput;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int selectedFunction;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // CUSTOMFUNCTIONS_H
|
399
companion/src/modeledit/customswitches.cpp
Normal file
399
companion/src/modeledit/customswitches.cpp
Normal file
|
@ -0,0 +1,399 @@
|
||||||
|
#include "customswitches.h"
|
||||||
|
#include <QLabel>
|
||||||
|
#include <QLineEdit>
|
||||||
|
#include <QSpinBox>
|
||||||
|
#include <QComboBox>
|
||||||
|
#include <QCheckBox>
|
||||||
|
#include <QDoubleSpinBox>
|
||||||
|
#include "helpers.h"
|
||||||
|
|
||||||
|
CustomSwitchesPanel::CustomSwitchesPanel(QWidget * parent, ModelData & model):
|
||||||
|
ModelPanel(parent, model),
|
||||||
|
selectedSwitch(0)
|
||||||
|
{
|
||||||
|
QGridLayout * gridLayout = new QGridLayout(this);
|
||||||
|
|
||||||
|
int col = 1;
|
||||||
|
addLabel(gridLayout, tr("Function"), col++);
|
||||||
|
addLabel(gridLayout, tr("V1"), col++);
|
||||||
|
addLabel(gridLayout, tr("V2"), col++);
|
||||||
|
addLabel(gridLayout, tr("AND"), col++);
|
||||||
|
if (GetEepromInterface()->getCapability(CustomSwitchesExt)) {
|
||||||
|
addLabel(gridLayout, tr("Duration"), col++);
|
||||||
|
addLabel(gridLayout, tr("Delay"), col++);
|
||||||
|
}
|
||||||
|
|
||||||
|
lock = true;
|
||||||
|
for (int i=0; i<GetEepromInterface()->getCapability(CustomSwitches); i++) {
|
||||||
|
// The label
|
||||||
|
QLabel * label = new QLabel(this);
|
||||||
|
label->setProperty("index", i);
|
||||||
|
if (i < 9)
|
||||||
|
label->setText(tr("CS%1").arg(i+1));
|
||||||
|
else
|
||||||
|
label->setText(tr("CS%1").arg(QChar('A'+i-9)));
|
||||||
|
label->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||||
|
label->setMouseTracking(true);
|
||||||
|
connect(label, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(csw_customContextMenuRequested(QPoint)));
|
||||||
|
gridLayout->addWidget(label, i+1, 0);
|
||||||
|
|
||||||
|
// The function
|
||||||
|
csw[i] = new QComboBox(this);
|
||||||
|
csw[i]->setProperty("index", i);
|
||||||
|
connect(csw[i], SIGNAL(currentIndexChanged(int)), this, SLOT(edited()));
|
||||||
|
gridLayout->addWidget(csw[i], i+1, 1);
|
||||||
|
|
||||||
|
// V1
|
||||||
|
cswitchSource1[i] = new QComboBox(this);
|
||||||
|
cswitchSource1[i]->setProperty("index",i);
|
||||||
|
connect(cswitchSource1[i], SIGNAL(currentIndexChanged(int)), this, SLOT(edited()));
|
||||||
|
gridLayout->addWidget(cswitchSource1[i], i+1, 2);
|
||||||
|
cswitchSource1[i]->setVisible(false);
|
||||||
|
cswitchValue[i] = new QDoubleSpinBox(this);
|
||||||
|
cswitchValue[i]->setMaximum(125);
|
||||||
|
cswitchValue[i]->setMinimum(-125);
|
||||||
|
cswitchValue[i]->setAccelerated(true);
|
||||||
|
cswitchValue[i]->setDecimals(0);
|
||||||
|
cswitchValue[i]->setProperty("index", i);
|
||||||
|
connect(cswitchValue[i], SIGNAL(editingFinished()), this, SLOT(edited()));
|
||||||
|
gridLayout->addWidget(cswitchValue[i], i+1, 2);
|
||||||
|
cswitchValue[i]->setVisible(false);
|
||||||
|
|
||||||
|
// V2
|
||||||
|
cswitchSource2[i] = new QComboBox(this);
|
||||||
|
cswitchSource2[i]->setProperty("index", i);
|
||||||
|
connect(cswitchSource2[i], SIGNAL(currentIndexChanged(int)), this, SLOT(edited()));
|
||||||
|
gridLayout->addWidget(cswitchSource2[i], i+1, 3);
|
||||||
|
cswitchSource2[i]->setVisible(false);
|
||||||
|
cswitchOffset[i] = new QDoubleSpinBox(this);
|
||||||
|
cswitchOffset[i]->setProperty("index",i);
|
||||||
|
cswitchOffset[i]->setMaximum(125);
|
||||||
|
cswitchOffset[i]->setMinimum(-125);
|
||||||
|
cswitchOffset[i]->setAccelerated(true);
|
||||||
|
cswitchOffset[i]->setDecimals(0);
|
||||||
|
connect(cswitchOffset[i], SIGNAL(editingFinished()), this, SLOT(edited()));
|
||||||
|
gridLayout->addWidget(cswitchOffset[i], i+1, 3);
|
||||||
|
cswitchOffset[i]->setVisible(false);
|
||||||
|
|
||||||
|
// AND
|
||||||
|
cswitchAnd[i] = new QComboBox(this);
|
||||||
|
cswitchAnd[i]->setProperty("index", i);
|
||||||
|
connect(cswitchAnd[i], SIGNAL(currentIndexChanged(int)), this, SLOT(edited()));
|
||||||
|
gridLayout->addWidget(cswitchAnd[i], i+1, 4);
|
||||||
|
cswitchAnd[i]->setVisible(false);
|
||||||
|
|
||||||
|
if (GetEepromInterface()->getCapability(CustomSwitchesExt)) {
|
||||||
|
// Duration
|
||||||
|
cswitchDuration[i] = new QDoubleSpinBox(this);
|
||||||
|
cswitchDuration[i]->setProperty("index", i);
|
||||||
|
cswitchDuration[i]->setSingleStep(0.5);
|
||||||
|
cswitchDuration[i]->setMaximum(50);
|
||||||
|
cswitchDuration[i]->setMinimum(0);
|
||||||
|
cswitchDuration[i]->setAccelerated(true);
|
||||||
|
cswitchDuration[i]->setDecimals(1);
|
||||||
|
connect(cswitchDuration[i],SIGNAL(editingFinished()), this, SLOT(edited()));
|
||||||
|
gridLayout->addWidget(cswitchDuration[i], i+1, 5);
|
||||||
|
cswitchDuration[i]->setVisible(false);
|
||||||
|
|
||||||
|
// Delay
|
||||||
|
cswitchDelay[i] = new QDoubleSpinBox(this);
|
||||||
|
cswitchDelay[i]->setProperty("index", i);
|
||||||
|
cswitchDelay[i]->setSingleStep(0.5);
|
||||||
|
cswitchDelay[i]->setMaximum(50);
|
||||||
|
cswitchDelay[i]->setMinimum(0);
|
||||||
|
cswitchDelay[i]->setAccelerated(true);
|
||||||
|
cswitchDelay[i]->setDecimals(1);
|
||||||
|
connect(cswitchDelay[i], SIGNAL(editingFinished()), this, SLOT(edited()));
|
||||||
|
gridLayout->addWidget(cswitchDelay[i], i+1, 6);
|
||||||
|
cswitchDelay[i]->setVisible(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
lock = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
CustomSwitchesPanel::~CustomSwitchesPanel()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void CustomSwitchesPanel::edited()
|
||||||
|
{
|
||||||
|
if (!lock) {
|
||||||
|
lock = true;
|
||||||
|
int i = sender()->property("index").toInt();
|
||||||
|
bool chAr;
|
||||||
|
float value, step;
|
||||||
|
int newval;
|
||||||
|
chAr = (getCSFunctionFamily(model.customSw[i].func) != getCSFunctionFamily(csw[i]->itemData(csw[i]->currentIndex()).toInt()));
|
||||||
|
model.customSw[i].func = csw[i]->itemData(csw[i]->currentIndex()).toInt();
|
||||||
|
if(chAr) {
|
||||||
|
if (getCSFunctionFamily(model.customSw[i].func)==CS_FAMILY_TIMERS) {
|
||||||
|
model.customSw[i].val1 = -119;
|
||||||
|
model.customSw[i].val2 = -119;
|
||||||
|
} else {
|
||||||
|
model.customSw[i].val1 = 0;
|
||||||
|
model.customSw[i].val2 = 0;
|
||||||
|
}
|
||||||
|
model.customSw[i].andsw = 0;
|
||||||
|
setSwitchWidgetVisibility(i);
|
||||||
|
}
|
||||||
|
if (GetEepromInterface()->getCapability(CustomSwitchesExt)) {
|
||||||
|
model.customSw[i].duration= (uint8_t)round(cswitchDuration[i]->value()*2);
|
||||||
|
model.customSw[i].delay= (uint8_t)round(cswitchDelay[i]->value()*2);
|
||||||
|
}
|
||||||
|
RawSource source;
|
||||||
|
switch (getCSFunctionFamily(model.customSw[i].func))
|
||||||
|
{
|
||||||
|
case (CS_FAMILY_VOFS):
|
||||||
|
if (model.customSw[i].val1 != cswitchSource1[i]->itemData(cswitchSource1[i]->currentIndex()).toInt()) {
|
||||||
|
source=RawSource(model.customSw[i].val1);
|
||||||
|
model.customSw[i].val1 = cswitchSource1[i]->itemData(cswitchSource1[i]->currentIndex()).toInt();
|
||||||
|
RawSource newSource = RawSource(model.customSw[i].val1);
|
||||||
|
if (newSource.type == SOURCE_TYPE_TELEMETRY) {
|
||||||
|
if (model.customSw[i].func>CS_FN_ELESS && model.customSw[i].func<CS_FN_VEQUAL) {
|
||||||
|
model.customSw[i].val2 = 0;
|
||||||
|
} else {
|
||||||
|
model.customSw[i].val2 = -128;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (model.customSw[i].func>CS_FN_ELESS && model.customSw[i].func<CS_FN_VEQUAL) {
|
||||||
|
model.customSw[i].val2 = (cswitchOffset[i]->value()/source.getStep(model));
|
||||||
|
} else {
|
||||||
|
model.customSw[i].val2 = ((cswitchOffset[i]->value()-source.getOffset(model))/source.getStep(model))-source.getRawOffset(model);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setSwitchWidgetVisibility(i);
|
||||||
|
} else {
|
||||||
|
source=RawSource(model.customSw[i].val1);
|
||||||
|
if (model.customSw[i].func>CS_FN_ELESS && model.customSw[i].func<CS_FN_VEQUAL) {
|
||||||
|
model.customSw[i].val2 = (cswitchOffset[i]->value()/source.getStep(model));
|
||||||
|
cswitchOffset[i]->setValue(model.customSw[i].val2*source.getStep(model));
|
||||||
|
} else {
|
||||||
|
model.customSw[i].val2 = ((cswitchOffset[i]->value()-source.getOffset(model))/source.getStep(model))-source.getRawOffset(model);
|
||||||
|
cswitchOffset[i]->setValue((model.customSw[i].val2 +source.getRawOffset(model))*source.getStep(model)+source.getOffset(model));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case (CS_FAMILY_TIMERS): {
|
||||||
|
value=cswitchOffset[i]->value();
|
||||||
|
newval=TimToVal(value);
|
||||||
|
if (newval>model.customSw[i].val2) {
|
||||||
|
if (value >=60) {
|
||||||
|
value=round(value);
|
||||||
|
step=1;
|
||||||
|
} else if (value>=2) {
|
||||||
|
value=(round(value*2.0)/2);
|
||||||
|
step=0.5;
|
||||||
|
} else {
|
||||||
|
step=0.1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (value <=2) {
|
||||||
|
step=0.1;
|
||||||
|
} else if (value<=60) {
|
||||||
|
value=(round(value*2.0)/2);
|
||||||
|
step=0.5;
|
||||||
|
} else {
|
||||||
|
value=round(value);
|
||||||
|
step=1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
model.customSw[i].val2=TimToVal(value);
|
||||||
|
value=ValToTim(model.customSw[i].val2);
|
||||||
|
cswitchOffset[i]->setValue(value);
|
||||||
|
cswitchOffset[i]->setSingleStep(step);
|
||||||
|
|
||||||
|
value=cswitchValue[i]->value();
|
||||||
|
newval=TimToVal(value);
|
||||||
|
if (newval>model.customSw[i].val1) {
|
||||||
|
if (value >=60) {
|
||||||
|
value=round(value);
|
||||||
|
step=1;
|
||||||
|
} else if (value>=2) {
|
||||||
|
value=(round(value*2.0)/2);
|
||||||
|
step=0.5;
|
||||||
|
} else {
|
||||||
|
step=0.1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (value <=2) {
|
||||||
|
step=0.1;
|
||||||
|
} else if (value<=60) {
|
||||||
|
value=(round(value*2.0)/2);
|
||||||
|
step=0.5;
|
||||||
|
} else {
|
||||||
|
value=round(value);
|
||||||
|
step=1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
model.customSw[i].val1=TimToVal(value);
|
||||||
|
value=ValToTim(model.customSw[i].val1);
|
||||||
|
cswitchValue[i]->setValue(value);
|
||||||
|
cswitchValue[i]->setSingleStep(step);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case (CS_FAMILY_VBOOL):
|
||||||
|
case (CS_FAMILY_VCOMP):
|
||||||
|
model.customSw[i].val1 = cswitchSource1[i]->itemData(cswitchSource1[i]->currentIndex()).toInt();
|
||||||
|
model.customSw[i].val2 = cswitchSource2[i]->itemData(cswitchSource2[i]->currentIndex()).toInt();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
model.customSw[i].andsw = cswitchAnd[i]->itemData(cswitchAnd[i]->currentIndex()).toInt();
|
||||||
|
emit modified();
|
||||||
|
lock = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CustomSwitchesPanel::setSwitchWidgetVisibility(int i)
|
||||||
|
{
|
||||||
|
RawSource source = RawSource(model.customSw[i].val1);
|
||||||
|
switch (getCSFunctionFamily(model.customSw[i].func))
|
||||||
|
{
|
||||||
|
case CS_FAMILY_VOFS:
|
||||||
|
cswitchSource1[i]->setVisible(true);
|
||||||
|
cswitchSource2[i]->setVisible(false);
|
||||||
|
cswitchValue[i]->setVisible(false);
|
||||||
|
cswitchOffset[i]->setVisible(true);
|
||||||
|
populateSourceCB(cswitchSource1[i], source, POPULATE_SOURCES | (GetEepromInterface()->getCapability(ExtraTrims) ? POPULATE_TRIMS : 0) | POPULATE_SWITCHES | POPULATE_TELEMETRY | (GetEepromInterface()->getCapability(GvarsInCS) ? POPULATE_GVARS : 0));
|
||||||
|
cswitchOffset[i]->setDecimals(source.getDecimals(model));
|
||||||
|
cswitchOffset[i]->setSingleStep(source.getStep(model));
|
||||||
|
if (model.customSw[i].func>CS_FN_ELESS && model.customSw[i].func<CS_FN_VEQUAL) {
|
||||||
|
cswitchOffset[i]->setMinimum(source.getStep(model)*-127);
|
||||||
|
cswitchOffset[i]->setMaximum(source.getStep(model)*127);
|
||||||
|
cswitchOffset[i]->setValue(source.getStep(model)*model.customSw[i].val2);
|
||||||
|
} else {
|
||||||
|
cswitchOffset[i]->setMinimum(source.getMin(model));
|
||||||
|
cswitchOffset[i]->setMaximum(source.getMax(model));
|
||||||
|
cswitchOffset[i]->setValue(source.getStep(model)*(model.customSw[i].val2+source.getRawOffset(model))+source.getOffset(model));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case CS_FAMILY_VBOOL:
|
||||||
|
cswitchSource1[i]->setVisible(true);
|
||||||
|
cswitchSource2[i]->setVisible(true);
|
||||||
|
cswitchValue[i]->setVisible(false);
|
||||||
|
cswitchOffset[i]->setVisible(false);
|
||||||
|
populateSwitchCB(cswitchSource1[i], RawSwitch(model.customSw[i].val1));
|
||||||
|
populateSwitchCB(cswitchSource2[i], RawSwitch(model.customSw[i].val2));
|
||||||
|
break;
|
||||||
|
case CS_FAMILY_VCOMP:
|
||||||
|
cswitchSource1[i]->setVisible(true);
|
||||||
|
cswitchSource2[i]->setVisible(true);
|
||||||
|
cswitchValue[i]->setVisible(false);
|
||||||
|
cswitchOffset[i]->setVisible(false);
|
||||||
|
populateSourceCB(cswitchSource1[i], RawSource(model.customSw[i].val1), POPULATE_SOURCES | (GetEepromInterface()->getCapability(ExtraTrims) ? POPULATE_TRIMS : 0) | POPULATE_SWITCHES | POPULATE_TELEMETRY | (GetEepromInterface()->getCapability(GvarsInCS) ? POPULATE_GVARS : 0));
|
||||||
|
populateSourceCB(cswitchSource2[i], RawSource(model.customSw[i].val2), POPULATE_SOURCES | (GetEepromInterface()->getCapability(ExtraTrims) ? POPULATE_TRIMS : 0) | POPULATE_SWITCHES | POPULATE_TELEMETRY | (GetEepromInterface()->getCapability(GvarsInCS) ? POPULATE_GVARS : 0));
|
||||||
|
break;
|
||||||
|
case CS_FAMILY_TIMERS:
|
||||||
|
cswitchSource1[i]->setVisible(false);
|
||||||
|
cswitchSource2[i]->setVisible(false);
|
||||||
|
cswitchValue[i]->setVisible(true);
|
||||||
|
cswitchOffset[i]->setVisible(true);
|
||||||
|
cswitchOffset[i]->setDecimals(1);
|
||||||
|
cswitchOffset[i]->setMinimum(0.1);
|
||||||
|
cswitchOffset[i]->setMaximum(175);
|
||||||
|
float value=ValToTim(model.customSw[i].val2);
|
||||||
|
cswitchOffset[i]->setSingleStep(0.1);
|
||||||
|
if (value>60) {
|
||||||
|
cswitchOffset[i]->setSingleStep(1);
|
||||||
|
} else if (value>2) {
|
||||||
|
cswitchOffset[i]->setSingleStep(0.5);
|
||||||
|
}
|
||||||
|
cswitchOffset[i]->setValue(value);
|
||||||
|
|
||||||
|
cswitchValue[i]->setDecimals(1);
|
||||||
|
cswitchValue[i]->setMinimum(0.1);
|
||||||
|
cswitchValue[i]->setMaximum(175);
|
||||||
|
value=ValToTim(model.customSw[i].val1);
|
||||||
|
cswitchValue[i]->setSingleStep(0.1);
|
||||||
|
if (value>60) {
|
||||||
|
cswitchValue[i]->setSingleStep(1);
|
||||||
|
} else if (value>2) {
|
||||||
|
cswitchValue[i]->setSingleStep(0.5);
|
||||||
|
}
|
||||||
|
cswitchValue[i]->setValue(value);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
cswitchAnd[i]->setVisible(true);
|
||||||
|
populateSwitchCB(cswitchAnd[i], RawSwitch(model.customSw[i].andsw), POPULATE_AND_SWITCHES);
|
||||||
|
if (GetEepromInterface()->getCapability(CustomSwitchesExt)) {
|
||||||
|
cswitchDuration[i]->setVisible(true);
|
||||||
|
cswitchDuration[i]->setValue(model.customSw[i].duration/2.0);
|
||||||
|
cswitchDelay[i]->setVisible(true);
|
||||||
|
cswitchDelay[i]->setValue(model.customSw[i].delay/2.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CustomSwitchesPanel::update()
|
||||||
|
{
|
||||||
|
lock = true;
|
||||||
|
for (int i=0; i<GetEepromInterface()->getCapability(CustomSwitches); i++) {
|
||||||
|
populateCSWCB(csw[i], model.customSw[i].func);
|
||||||
|
setSwitchWidgetVisibility(i);
|
||||||
|
}
|
||||||
|
lock = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CustomSwitchesPanel::cswPaste()
|
||||||
|
{
|
||||||
|
const QClipboard *clipboard = QApplication::clipboard();
|
||||||
|
const QMimeData *mimeData = clipboard->mimeData();
|
||||||
|
if (mimeData->hasFormat("application/x-companion9x-csw")) {
|
||||||
|
QByteArray cswData = mimeData->data("application/x-companion9x-csw");
|
||||||
|
|
||||||
|
CustomSwData *csw = &model.customSw[selectedSwitch];
|
||||||
|
memcpy(csw, cswData.mid(0, sizeof(CustomSwData)).constData(), sizeof(CustomSwData));
|
||||||
|
emit modified();
|
||||||
|
updateSelectedSwitch();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CustomSwitchesPanel::cswDelete()
|
||||||
|
{
|
||||||
|
model.customSw[selectedSwitch].clear();
|
||||||
|
emit modified();
|
||||||
|
updateSelectedSwitch();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CustomSwitchesPanel::cswCopy()
|
||||||
|
{
|
||||||
|
QByteArray cswData;
|
||||||
|
cswData.append((char*)&model.customSw[selectedSwitch],sizeof(CustomSwData));
|
||||||
|
QMimeData *mimeData = new QMimeData;
|
||||||
|
mimeData->setData("application/x-companion9x-csw", cswData);
|
||||||
|
QApplication::clipboard()->setMimeData(mimeData,QClipboard::Clipboard);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CustomSwitchesPanel::updateSelectedSwitch()
|
||||||
|
{
|
||||||
|
lock = true;
|
||||||
|
populateCSWCB(csw[selectedSwitch], model.customSw[selectedSwitch].func);
|
||||||
|
setSwitchWidgetVisibility(selectedSwitch);
|
||||||
|
lock = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CustomSwitchesPanel::cswCut()
|
||||||
|
{
|
||||||
|
cswCopy();
|
||||||
|
cswDelete();
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO make something generic here!
|
||||||
|
void CustomSwitchesPanel::csw_customContextMenuRequested(QPoint pos)
|
||||||
|
{
|
||||||
|
QLabel *label = (QLabel *)sender();
|
||||||
|
selectedSwitch = label->property("index").toInt();
|
||||||
|
|
||||||
|
QPoint globalPos = label->mapToGlobal(pos);
|
||||||
|
|
||||||
|
const QClipboard *clipboard = QApplication::clipboard();
|
||||||
|
const QMimeData *mimeData = clipboard->mimeData();
|
||||||
|
bool hasData = mimeData->hasFormat("application/x-companion9x-csw");
|
||||||
|
|
||||||
|
QMenu contextMenu;
|
||||||
|
contextMenu.addAction(QIcon(":/images/clear.png"), tr("&Delete"),this,SLOT(cswDelete()),tr("Delete"));
|
||||||
|
contextMenu.addAction(QIcon(":/images/copy.png"), tr("&Copy"),this,SLOT(cswCopy()),tr("Ctrl+C"));
|
||||||
|
contextMenu.addAction(QIcon(":/images/cut.png"), tr("&Cut"),this,SLOT(cswCut()),tr("Ctrl+X"));
|
||||||
|
contextMenu.addAction(QIcon(":/images/paste.png"), tr("&Paste"),this,SLOT(cswPaste()),tr("Ctrl+V"))->setEnabled(hasData);
|
||||||
|
|
||||||
|
contextMenu.exec(globalPos);
|
||||||
|
}
|
42
companion/src/modeledit/customswitches.h
Normal file
42
companion/src/modeledit/customswitches.h
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
#ifndef CUSTOMSWITCHES_H
|
||||||
|
#define CUSTOMSWITCHES_H
|
||||||
|
|
||||||
|
#include "modelpanel.h"
|
||||||
|
#include <QComboBox>
|
||||||
|
#include <QDoubleSpinBox>
|
||||||
|
|
||||||
|
class CustomSwitchesPanel : public ModelPanel
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
CustomSwitchesPanel(QWidget *parent, ModelData & model);
|
||||||
|
virtual ~CustomSwitchesPanel();
|
||||||
|
|
||||||
|
virtual void update();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void edited();
|
||||||
|
void csw_customContextMenuRequested(QPoint pos);
|
||||||
|
void cswDelete();
|
||||||
|
void cswCopy();
|
||||||
|
void cswPaste();
|
||||||
|
void cswCut();
|
||||||
|
|
||||||
|
private:
|
||||||
|
QComboBox * csw[C9X_NUM_CSW];
|
||||||
|
QDoubleSpinBox * cswitchValue[C9X_NUM_CSW];
|
||||||
|
QDoubleSpinBox * cswitchOffset[C9X_NUM_CSW];
|
||||||
|
QComboBox * cswitchAnd[C9X_NUM_CSW];
|
||||||
|
QDoubleSpinBox * cswitchDuration[C9X_NUM_CSW];
|
||||||
|
QDoubleSpinBox * cswitchDelay[C9X_NUM_CSW];
|
||||||
|
QComboBox * cswitchSource1[C9X_NUM_CSW];
|
||||||
|
QComboBox * cswitchSource2[C9X_NUM_CSW];
|
||||||
|
void setSwitchWidgetVisibility(int i);
|
||||||
|
int selectedSwitch;
|
||||||
|
|
||||||
|
void updateSelectedSwitch();
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // CUSTOMSWITCHES_H
|
449
companion/src/modeledit/flightmode.ui
Normal file
449
companion/src/modeledit/flightmode.ui
Normal file
|
@ -0,0 +1,449 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>FlightMode</class>
|
||||||
|
<widget class="QWidget" name="FlightMode">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>610</width>
|
||||||
|
<height>499</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Form</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<item>
|
||||||
|
<layout class="QGridLayout" name="paramsLayout">
|
||||||
|
<item row="0" column="2">
|
||||||
|
<widget class="QLabel" name="label_3">
|
||||||
|
<property name="text">
|
||||||
|
<string>Fade In</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="3">
|
||||||
|
<widget class="QDoubleSpinBox" name="fadeIn">
|
||||||
|
<property name="decimals">
|
||||||
|
<number>1</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="3">
|
||||||
|
<widget class="QDoubleSpinBox" name="fadeOut">
|
||||||
|
<property name="decimals">
|
||||||
|
<number>1</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="2">
|
||||||
|
<widget class="QLabel" name="label_4">
|
||||||
|
<property name="text">
|
||||||
|
<string>Fade Out</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="1">
|
||||||
|
<widget class="QLineEdit" name="name">
|
||||||
|
<property name="maxLength">
|
||||||
|
<number>6</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QLabel" name="label">
|
||||||
|
<property name="text">
|
||||||
|
<string>Name</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="4" rowspan="2">
|
||||||
|
<spacer name="spacer_5">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QLabel" name="label_2">
|
||||||
|
<property name="text">
|
||||||
|
<string>Switch</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="1">
|
||||||
|
<widget class="QComboBox" name="swtch"/>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QGridLayout" name="trimsLayout">
|
||||||
|
<item row="2" column="1">
|
||||||
|
<widget class="QSlider" name="trim1Slider">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="tickPosition">
|
||||||
|
<enum>QSlider::TicksBothSides</enum>
|
||||||
|
</property>
|
||||||
|
<property name="tickInterval">
|
||||||
|
<number>25</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QSlider" name="trim2Slider">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="tickPosition">
|
||||||
|
<enum>QSlider::TicksBothSides</enum>
|
||||||
|
</property>
|
||||||
|
<property name="tickInterval">
|
||||||
|
<number>25</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="3">
|
||||||
|
<widget class="QSlider" name="trim3Slider">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="invertedAppearance">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="invertedControls">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="tickPosition">
|
||||||
|
<enum>QSlider::TicksBothSides</enum>
|
||||||
|
</property>
|
||||||
|
<property name="tickInterval">
|
||||||
|
<number>25</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="2">
|
||||||
|
<widget class="QSlider" name="trim4Slider">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="tickPosition">
|
||||||
|
<enum>QSlider::TicksBothSides</enum>
|
||||||
|
</property>
|
||||||
|
<property name="tickInterval">
|
||||||
|
<number>25</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="1">
|
||||||
|
<widget class="QFrame" name="frame">
|
||||||
|
<property name="frameShape">
|
||||||
|
<enum>QFrame::StyledPanel</enum>
|
||||||
|
</property>
|
||||||
|
<property name="frameShadow">
|
||||||
|
<enum>QFrame::Raised</enum>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||||
|
<item>
|
||||||
|
<layout class="QGridLayout" name="leftTrims_3" columnstretch="0,1" columnminimumwidth="80,0">
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QLabel" name="trim1Label">
|
||||||
|
<property name="text">
|
||||||
|
<string>trim1</string>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="1">
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_5c_3">
|
||||||
|
<item>
|
||||||
|
<spacer name="verticalSpacer_3c_3">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>40</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QComboBox" name="trim2Use"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QSpinBox" name="trim2Value">
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignCenter</set>
|
||||||
|
</property>
|
||||||
|
<property name="accelerated">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="minimum">
|
||||||
|
<number>-896</number>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<number>896</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="verticalSpacer_4a_3">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>40</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="1">
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_6b_3">
|
||||||
|
<item>
|
||||||
|
<spacer name="verticalSpacer_5b_3">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>40</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QComboBox" name="trim1Use"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QSpinBox" name="trim1Value">
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignCenter</set>
|
||||||
|
</property>
|
||||||
|
<property name="accelerated">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="minimum">
|
||||||
|
<number>-896</number>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<number>896</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="verticalSpacer_6b_3">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>40</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QLabel" name="trim2Label">
|
||||||
|
<property name="text">
|
||||||
|
<string>trim2</string>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="2">
|
||||||
|
<widget class="QFrame" name="frame_2">
|
||||||
|
<property name="frameShape">
|
||||||
|
<enum>QFrame::StyledPanel</enum>
|
||||||
|
</property>
|
||||||
|
<property name="frameShadow">
|
||||||
|
<enum>QFrame::Raised</enum>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||||
|
<item>
|
||||||
|
<layout class="QGridLayout" name="righTrims_2" columnstretch="0,1" columnminimumwidth="80,0">
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QLabel" name="trim4Label">
|
||||||
|
<property name="text">
|
||||||
|
<string>trim4</string>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QLabel" name="trim3Label">
|
||||||
|
<property name="text">
|
||||||
|
<string>trim3</string>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="1">
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_7b_2">
|
||||||
|
<item>
|
||||||
|
<spacer name="verticalSpacer_7b_2">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>40</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QComboBox" name="trim3Use"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QSpinBox" name="trim3Value">
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignCenter</set>
|
||||||
|
</property>
|
||||||
|
<property name="accelerated">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="minimum">
|
||||||
|
<number>-896</number>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<number>896</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="verticalSpacer_8d_2">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>40</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="1">
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_8d_2">
|
||||||
|
<item>
|
||||||
|
<spacer name="verticalSpacer_9d_2">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>40</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QComboBox" name="trim4Use"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QSpinBox" name="trim4Value">
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignCenter</set>
|
||||||
|
</property>
|
||||||
|
<property name="accelerated">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="minimum">
|
||||||
|
<number>-896</number>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<number>896</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="verticalSpacer_10c_2">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>40</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="Line" name="line">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QGridLayout" name="gvNreLayout" columnstretch="1,1">
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QGroupBox" name="gvGB"/>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="1">
|
||||||
|
<widget class="QGroupBox" name="reGB"/>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources/>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
484
companion/src/modeledit/flightmodes.cpp
Normal file
484
companion/src/modeledit/flightmodes.cpp
Normal file
|
@ -0,0 +1,484 @@
|
||||||
|
#include "flightmodes.h"
|
||||||
|
#include "ui_flightmode.h"
|
||||||
|
#include "firmwares/opentx/open9xeeprom.h" // TODO shouldn't be there
|
||||||
|
#include "helpers.h"
|
||||||
|
#include <QComboBox>
|
||||||
|
#include <QGridLayout>
|
||||||
|
|
||||||
|
FlightMode::FlightMode(QWidget * parent, ModelData & model, int phaseIdx, GeneralSettings & generalSettings):
|
||||||
|
ModelPanel(parent, model),
|
||||||
|
ui(new Ui::FlightMode),
|
||||||
|
generalSettings(generalSettings),
|
||||||
|
phaseIdx(phaseIdx),
|
||||||
|
phase(model.phaseData[phaseIdx]),
|
||||||
|
reCount(GetEepromInterface()->getCapability(RotaryEncoders)),
|
||||||
|
gvCount(((!GetEepromInterface()->getCapability(HasVariants)) || (GetCurrentFirmwareVariant() & GVARS_VARIANT)) ?
|
||||||
|
GetEepromInterface()->getCapability(Gvars) : 0)
|
||||||
|
{
|
||||||
|
ui->setupUi(this);
|
||||||
|
|
||||||
|
// Phase name
|
||||||
|
QRegExp rx(CHAR_FOR_NAMES_REGEX);
|
||||||
|
if (GetEepromInterface()->getCapability(FlightPhases)) {
|
||||||
|
ui->name->setValidator(new QRegExpValidator(rx, this));
|
||||||
|
ui->name->setMaxLength(GetEepromInterface()->getCapability(FlightModesName));
|
||||||
|
connect(ui->name, SIGNAL(editingFinished()), this, SLOT(phaseName_editingFinished()));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ui->name->setDisabled(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Phase switch
|
||||||
|
if (phaseIdx > 0) {
|
||||||
|
populateSwitchCB(ui->swtch, phase.swtch);
|
||||||
|
connect(ui->swtch, SIGNAL(currentIndexChanged(int)), this, SLOT(phaseSwitch_currentIndexChanged(int)));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ui->swtch->hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
// FadeIn / FadeOut
|
||||||
|
if (GetEepromInterface()->getCapability(FlightPhasesHaveFades)) {
|
||||||
|
int scale = GetEepromInterface()->getCapability(SlowScale);
|
||||||
|
int range = GetEepromInterface()->getCapability(SlowRange);
|
||||||
|
ui->fadeIn->setMaximum(float(range)/scale);
|
||||||
|
ui->fadeIn->setSingleStep(1.0/scale);
|
||||||
|
ui->fadeIn->setDecimals((scale==1 ? 0 :1) );
|
||||||
|
connect(ui->fadeIn, SIGNAL(editingFinished()), this, SLOT(phaseFadeIn_editingFinished()));
|
||||||
|
ui->fadeOut->setMaximum(float(range)/scale);
|
||||||
|
ui->fadeOut->setSingleStep(1.0/scale);
|
||||||
|
ui->fadeOut->setDecimals((scale==1 ? 0 :1));
|
||||||
|
connect(ui->fadeOut, SIGNAL(editingFinished()), this, SLOT(phaseFadeOut_editingFinished()));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ui->fadeIn->setDisabled(true);
|
||||||
|
ui->fadeOut->setDisabled(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// The trims
|
||||||
|
QString labels[] = { tr("Rud"), tr("Ele"), tr("Thr"), tr("Ail") }; // TODO is elsewhere for sure
|
||||||
|
|
||||||
|
trimsLabel << ui->trim1Label << ui->trim2Label << ui->trim3Label << ui->trim4Label;
|
||||||
|
trimsUse << ui->trim1Use << ui->trim2Use << ui->trim3Use << ui->trim4Use;
|
||||||
|
trimsValue << ui->trim1Value << ui->trim2Value << ui->trim3Value << ui->trim4Value;
|
||||||
|
trimsSlider << ui->trim1Slider << ui->trim2Slider << ui->trim3Slider << ui->trim4Slider;
|
||||||
|
|
||||||
|
for (int i=0; i<4; i++) {
|
||||||
|
trimsLabel[i]->setText(labels[CONVERT_MODE(i+1)-1]);
|
||||||
|
|
||||||
|
if (phaseIdx > 0) {
|
||||||
|
trimsUse[i]->setProperty("index", i);
|
||||||
|
populateTrimUseCB(trimsUse[i], phaseIdx);
|
||||||
|
connect(trimsUse[i], SIGNAL(currentIndexChanged(int)), this, SLOT(phaseTrimUse_currentIndexChanged(int)));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
trimsUse[i]->hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
trimsValue[i]->setProperty("index", i);
|
||||||
|
connect(trimsValue[i], SIGNAL(valueChanged(int)), this, SLOT(phaseTrim_valueChanged()));
|
||||||
|
|
||||||
|
trimsSlider[i]->setProperty("index", i);
|
||||||
|
connect(trimsSlider[i], SIGNAL(valueChanged(int)), this, SLOT(phaseTrimSlider_valueChanged()));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Rotary encoders
|
||||||
|
if (reCount > 0) {
|
||||||
|
QGridLayout *reLayout = new QGridLayout(ui->reGB);
|
||||||
|
for (int i=0; i<reCount; i++) {
|
||||||
|
// RE label
|
||||||
|
QLabel *label = new QLabel(ui->reGB);
|
||||||
|
label->setText(tr("Rotary Encoder %1").arg(i+1));
|
||||||
|
reLayout->addWidget(label, i, 0, 1, 1);
|
||||||
|
if (phaseIdx > 0) {
|
||||||
|
// RE link to another RE
|
||||||
|
QComboBox *link = new QComboBox(ui->gvGB);
|
||||||
|
link->setProperty("index", i);
|
||||||
|
populateGvarUseCB(link, phaseIdx);
|
||||||
|
connect(link, SIGNAL(currentIndexChanged(int)), this, SLOT(phaseREUse_currentIndexChanged(int)));
|
||||||
|
if (phase.rotaryEncoders[i] > 1024) {
|
||||||
|
link->setCurrentIndex(phase.rotaryEncoders[i] - 1024);
|
||||||
|
}
|
||||||
|
reLayout->addWidget(link, i, 1, 1, 1);
|
||||||
|
}
|
||||||
|
// RE value
|
||||||
|
reValues[i] = new QSpinBox(ui->reGB);
|
||||||
|
reValues[i]->setProperty("index", i);
|
||||||
|
reValues[i]->setMinimum(-1024);
|
||||||
|
reValues[i]->setMaximum(1024);
|
||||||
|
connect(reValues[i], SIGNAL(editingFinished()), this, SLOT(phaseREValue_editingFinished()));
|
||||||
|
reLayout->addWidget(reValues[i], i, 2, 1, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ui->reGB->hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
// GVars
|
||||||
|
if (gvCount > 0) {
|
||||||
|
QGridLayout *gvLayout = new QGridLayout(ui->gvGB);
|
||||||
|
for (int i=0; i<gvCount; i++) {
|
||||||
|
int col = 0;
|
||||||
|
// GVar label
|
||||||
|
QLabel *label = new QLabel(ui->gvGB);
|
||||||
|
label->setText(tr("GVAR%1").arg(i+1));
|
||||||
|
gvLayout->addWidget(label, i, col++, 1, 1);
|
||||||
|
#if 0
|
||||||
|
// TODO remove this capability?
|
||||||
|
// GVar source (er9x/ersky9x)
|
||||||
|
if (GetEepromInterface()->getCapability(GvarsHaveSources)) {
|
||||||
|
QComboBox *source = new QComboBox(ui->gvGB);
|
||||||
|
source->setProperty("index", i);
|
||||||
|
populateGvSourceCB(source, model.gvsource[i]);
|
||||||
|
// connect(source, SIGNAL(currentIndexChanged(int)), this, SLOT(phaseGVSource_currentIndexChanged(int)));
|
||||||
|
gvLayout->addWidget(source, i, col++, 1, 1);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
// GVar name
|
||||||
|
int nameLen = GetEepromInterface()->getCapability(GvarsName);
|
||||||
|
if (nameLen > 0) {
|
||||||
|
gvNames[i] = new QLineEdit(ui->gvGB);
|
||||||
|
gvNames[i]->setProperty("index", i);
|
||||||
|
gvNames[i]->setMaxLength(nameLen);
|
||||||
|
connect(gvNames[i], SIGNAL(editingFinished()), this, SLOT(GVName_editingFinished()));
|
||||||
|
gvLayout->addWidget(gvNames[i], i, col++, 1, 1);
|
||||||
|
}
|
||||||
|
if (phaseIdx > 0) {
|
||||||
|
// GVar link to another GVar
|
||||||
|
QComboBox *link = new QComboBox(ui->gvGB);
|
||||||
|
link->setProperty("index", i);
|
||||||
|
populateGvarUseCB(link, phaseIdx);
|
||||||
|
if (phase.gvars[i] > 1024) {
|
||||||
|
link->setCurrentIndex(phase.gvars[i] - 1024);
|
||||||
|
}
|
||||||
|
connect(link, SIGNAL(currentIndexChanged(int)), this, SLOT(phaseGVUse_currentIndexChanged(int)));
|
||||||
|
gvLayout->addWidget(link, i, col++, 1, 1);
|
||||||
|
}
|
||||||
|
// GVar value
|
||||||
|
gvValues[i] = new QSpinBox(ui->gvGB);
|
||||||
|
gvValues[i]->setProperty("index", i);
|
||||||
|
connect(gvValues[i], SIGNAL(editingFinished()), this, SLOT(phaseGVValue_editingFinished()));
|
||||||
|
gvValues[i]->setMinimum(-1024);
|
||||||
|
gvValues[i]->setMaximum(1024);
|
||||||
|
gvLayout->addWidget(gvValues[i], i, col++, 1, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ui->gvGB->hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
FlightMode::~FlightMode()
|
||||||
|
{
|
||||||
|
delete ui;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FlightMode::update()
|
||||||
|
{
|
||||||
|
ui->name->setText(phase.name);
|
||||||
|
|
||||||
|
int scale = GetEepromInterface()->getCapability(SlowScale);
|
||||||
|
ui->fadeIn->setValue(float(phase.fadeIn)/scale);
|
||||||
|
ui->fadeOut->setValue(float(phase.fadeOut)/scale);
|
||||||
|
|
||||||
|
for (int i=0; i<4; i++) {
|
||||||
|
int trimsMax = GetEepromInterface()->getCapability(ExtendedTrims);
|
||||||
|
if (trimsMax == 0 || !model.extendedTrims) {
|
||||||
|
trimsMax = 125;
|
||||||
|
}
|
||||||
|
trimsSlider[i]->setRange(-trimsMax, +trimsMax);
|
||||||
|
trimsValue[i]->setRange(-trimsMax, +trimsMax);
|
||||||
|
int chn = CONVERT_MODE(i+1)-1;
|
||||||
|
if (chn == 2/*TODO constant*/ && generalSettings.throttleReversed)
|
||||||
|
trimsSlider[i]->setInvertedAppearance(true);
|
||||||
|
|
||||||
|
trimUpdate(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i=0; i<gvCount; i++) {
|
||||||
|
gvNames[i]->setText(model.gvars_names[i]);
|
||||||
|
if (phase.gvars[i] < 1024) {
|
||||||
|
gvValues[i]->setValue(phase.gvars[i]);
|
||||||
|
gvValues[i]->setDisabled(false);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
int idx = phase.gvars[i] - 1025;
|
||||||
|
if (idx >= i) idx++;
|
||||||
|
// TODO no!!!!
|
||||||
|
PhaseData *phasegvar = &model.phaseData[idx];
|
||||||
|
gvValues[i]->setValue(phasegvar->gvars[i]);
|
||||||
|
gvValues[i]->setDisabled(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i=0; i<reCount; i++) {
|
||||||
|
if (phase.rotaryEncoders[i] < 1024) {
|
||||||
|
reValues[i]->setValue(phase.rotaryEncoders[i]);
|
||||||
|
reValues[i]->setDisabled(false);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
int idx = phase.rotaryEncoders[i] - 1025;
|
||||||
|
if (idx >= i) idx++;
|
||||||
|
// TODO no!!!!
|
||||||
|
PhaseData *phasere = &model.phaseData[idx];
|
||||||
|
reValues[i]->setValue(phasere->rotaryEncoders[i]);
|
||||||
|
reValues[i]->setDisabled(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FlightMode::phaseName_editingFinished()
|
||||||
|
{
|
||||||
|
QLineEdit *lineEdit = qobject_cast<QLineEdit*>(sender());
|
||||||
|
strcpy(phase.name, lineEdit->text().toAscii());
|
||||||
|
emit modified();
|
||||||
|
emit nameModified();
|
||||||
|
}
|
||||||
|
|
||||||
|
void FlightMode::phaseSwitch_currentIndexChanged(int index)
|
||||||
|
{
|
||||||
|
QComboBox *comboBox = qobject_cast<QComboBox*>(sender());
|
||||||
|
phase.swtch = RawSwitch(comboBox->itemData(index).toInt());
|
||||||
|
emit modified();
|
||||||
|
}
|
||||||
|
|
||||||
|
void FlightMode::phaseFadeIn_editingFinished()
|
||||||
|
{
|
||||||
|
QDoubleSpinBox *spinBox = qobject_cast<QDoubleSpinBox*>(sender());
|
||||||
|
int scale = GetEepromInterface()->getCapability(SlowScale);
|
||||||
|
phase.fadeIn = round(spinBox->value()*scale);
|
||||||
|
emit modified();
|
||||||
|
}
|
||||||
|
|
||||||
|
void FlightMode::phaseFadeOut_editingFinished()
|
||||||
|
{
|
||||||
|
QDoubleSpinBox *spinBox = qobject_cast<QDoubleSpinBox*>(sender());
|
||||||
|
int scale = GetEepromInterface()->getCapability(SlowScale);
|
||||||
|
phase.fadeOut = round(spinBox->value()*scale);
|
||||||
|
emit modified();
|
||||||
|
}
|
||||||
|
|
||||||
|
void FlightMode::trimUpdate(unsigned int trim)
|
||||||
|
{
|
||||||
|
lock = true;
|
||||||
|
int chn = CONVERT_MODE(trim+1)-1;
|
||||||
|
int value = phase.trim[chn];
|
||||||
|
if (phaseIdx > 0 && phase.trimRef[chn] >= 0) {
|
||||||
|
trimsUse[trim]->setCurrentIndex(1 + phase.trimRef[chn] - (phase.trimRef[chn] >= phaseIdx ? 1 : 0));
|
||||||
|
value = model.phaseData[model.getTrimFlightPhase(chn, phaseIdx)].trim[chn];
|
||||||
|
trimsValue[trim]->setEnabled(false);
|
||||||
|
trimsSlider[trim]->setEnabled(false);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (phaseIdx > 0) trimsUse[trim]->setCurrentIndex(0);
|
||||||
|
trimsValue[trim]->setEnabled(true);
|
||||||
|
trimsSlider[trim]->setEnabled(true);
|
||||||
|
}
|
||||||
|
trimsSlider[trim]->setValue(value);
|
||||||
|
trimsValue[trim]->setValue(value);
|
||||||
|
lock = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FlightMode::phaseGVValue_editingFinished()
|
||||||
|
{
|
||||||
|
if (!lock) {
|
||||||
|
QSpinBox *spinBox = qobject_cast<QSpinBox*>(sender());
|
||||||
|
int gvar = spinBox->property("index").toInt();
|
||||||
|
phase.gvars[gvar] = spinBox->value();
|
||||||
|
emit modified();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FlightMode::GVName_editingFinished()
|
||||||
|
{
|
||||||
|
if (!lock) {
|
||||||
|
QLineEdit *lineedit = qobject_cast<QLineEdit*>(sender());
|
||||||
|
int gvar = lineedit->property("index").toInt();
|
||||||
|
memset(&model.gvars_names[gvar], 0, sizeof(model.gvars_names[gvar]));
|
||||||
|
strcpy(model.gvars_names[gvar], lineedit->text().toAscii());
|
||||||
|
emit modified();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FlightMode::GVSource_currentIndexChanged(int index)
|
||||||
|
{
|
||||||
|
QComboBox *comboBox = qobject_cast<QComboBox*>(sender());
|
||||||
|
int gvar = comboBox->property("index").toInt();
|
||||||
|
model.gvsource[gvar] = index;
|
||||||
|
emit modified();
|
||||||
|
}
|
||||||
|
|
||||||
|
void FlightMode::phaseGVUse_currentIndexChanged(int index)
|
||||||
|
{
|
||||||
|
if (!lock) {
|
||||||
|
lock = true;
|
||||||
|
QComboBox *comboBox = qobject_cast<QComboBox*>(sender());
|
||||||
|
int gvar = comboBox->property("index").toInt();
|
||||||
|
if (index == 0) {
|
||||||
|
int value = phase.gvars[gvar];
|
||||||
|
if (value>1024) {
|
||||||
|
value=0;
|
||||||
|
}
|
||||||
|
gvValues[gvar]->setValue(value);
|
||||||
|
gvValues[gvar]->setEnabled(true);
|
||||||
|
phase.gvars[gvar]=value;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
phase.gvars[gvar] = 1024+index;
|
||||||
|
// TOTO it's wrong!!!
|
||||||
|
int value = model.phaseData[index + (index>phaseIdx ? 0 :-1)].gvars[gvar];
|
||||||
|
gvValues[gvar]->setValue(value);
|
||||||
|
gvValues[gvar]->setDisabled(true);
|
||||||
|
}
|
||||||
|
emit modified();
|
||||||
|
lock = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FlightMode::phaseREValue_editingFinished()
|
||||||
|
{
|
||||||
|
if (!lock) {
|
||||||
|
QSpinBox *spinBox = qobject_cast<QSpinBox*>(sender());
|
||||||
|
int gvar = spinBox->property("index").toInt();
|
||||||
|
phase.rotaryEncoders[gvar] = spinBox->value();
|
||||||
|
emit modified();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FlightMode::phaseREUse_currentIndexChanged(int index)
|
||||||
|
{
|
||||||
|
if (!lock) {
|
||||||
|
lock = true;
|
||||||
|
QComboBox *comboBox = qobject_cast<QComboBox*>(sender());
|
||||||
|
int re = comboBox->property("index").toInt();
|
||||||
|
if (index == 0) {
|
||||||
|
// TODO no!!!
|
||||||
|
int value = phase.rotaryEncoders[re];
|
||||||
|
if (value > 1024) {
|
||||||
|
value = 0;
|
||||||
|
}
|
||||||
|
reValues[re]->setValue(value);
|
||||||
|
reValues[re]->setEnabled(true);
|
||||||
|
phase.rotaryEncoders[re] = value;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
phase.rotaryEncoders[re] = 1024 + index;
|
||||||
|
int value = model.phaseData[index + (index>phaseIdx ? 0 :-1)].rotaryEncoders[re];
|
||||||
|
reValues[re]->setValue(value);
|
||||||
|
reValues[re]->setDisabled(true) ;
|
||||||
|
}
|
||||||
|
lock = false;
|
||||||
|
emit modified();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FlightMode::phaseTrimUse_currentIndexChanged(int index)
|
||||||
|
{
|
||||||
|
if (!lock) {
|
||||||
|
QComboBox *comboBox = qobject_cast<QComboBox*>(sender());
|
||||||
|
int trim = comboBox->property("index").toInt();
|
||||||
|
int chn = CONVERT_MODE(trim+1)-1;
|
||||||
|
if (index == 0) {
|
||||||
|
phase.trim[chn] = model.phaseData[model.getTrimFlightPhase(chn, phaseIdx)].trim[chn];
|
||||||
|
phase.trimRef[chn] = -1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
phase.trim[chn] = 0;
|
||||||
|
phase.trimRef[chn] = index - 1 + (index > (int)phaseIdx ? 1 : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
trimUpdate(trim);
|
||||||
|
emit modified();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FlightMode::phaseTrim_valueChanged()
|
||||||
|
{
|
||||||
|
if (!lock) {
|
||||||
|
QSpinBox *spinBox = qobject_cast<QSpinBox*>(sender());
|
||||||
|
int trim = spinBox->property("index").toInt();
|
||||||
|
int chn = CONVERT_MODE(trim+1)-1;
|
||||||
|
int value = spinBox->value();
|
||||||
|
phase.trim[chn] = value;
|
||||||
|
lock = true;
|
||||||
|
trimsSlider[trim]->setValue(value);
|
||||||
|
lock = false;
|
||||||
|
emit modified();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FlightMode::phaseTrimSlider_valueChanged()
|
||||||
|
{
|
||||||
|
if (!lock) {
|
||||||
|
QSlider *slider = qobject_cast<QSlider*>(sender());
|
||||||
|
int trim = slider->property("index").toInt();
|
||||||
|
int chn = CONVERT_MODE(trim+1)-1;
|
||||||
|
int value = slider->value();
|
||||||
|
phase.trim[chn] = value;
|
||||||
|
lock = true;
|
||||||
|
trimsValue[trim]->setValue(value);
|
||||||
|
lock = false;
|
||||||
|
emit modified();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**********************************************************/
|
||||||
|
|
||||||
|
FlightModes::FlightModes(QWidget * parent, ModelData & model, GeneralSettings & generalSettings):
|
||||||
|
ModelPanel(parent, model),
|
||||||
|
modesCount(GetEepromInterface()->getCapability(FlightPhases))
|
||||||
|
{
|
||||||
|
QGridLayout * gridLayout = new QGridLayout(this);
|
||||||
|
tabWidget = new QTabWidget(this);
|
||||||
|
for (int i=0; i<modesCount; i++) {
|
||||||
|
FlightMode *tab = new FlightMode(tabWidget, model, i, generalSettings);
|
||||||
|
tab->setProperty("index", i);
|
||||||
|
panels << tab;
|
||||||
|
connect(tab, SIGNAL(modified()), this, SLOT(onPhaseModified()));
|
||||||
|
connect(tab, SIGNAL(nameModified()), this, SLOT(onPhaseNameChanged()));
|
||||||
|
tabWidget->addTab(tab, getTabName(i));
|
||||||
|
}
|
||||||
|
gridLayout->addWidget(tabWidget, 0, 0, 1, 1);
|
||||||
|
connect(tabWidget, SIGNAL(currentChanged(int)), this, SLOT(on_tabWidget_currentChanged(int)));
|
||||||
|
}
|
||||||
|
|
||||||
|
FlightModes::~FlightModes()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void FlightModes::onPhaseModified()
|
||||||
|
{
|
||||||
|
emit modified();
|
||||||
|
}
|
||||||
|
|
||||||
|
QString FlightModes::getTabName(int index)
|
||||||
|
{
|
||||||
|
QString result = tr("Flight Mode %1").arg(index);
|
||||||
|
const char *name = model.phaseData[index].name;
|
||||||
|
if (GetEepromInterface()->getCapability(FlightModesName) && strlen(name) > 0) {
|
||||||
|
result += tr(" (%1)").arg(name);
|
||||||
|
}
|
||||||
|
else if (index == 0) {
|
||||||
|
result += tr(" (default)");
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FlightModes::onPhaseNameChanged()
|
||||||
|
{
|
||||||
|
int index = sender()->property("index").toInt();
|
||||||
|
tabWidget->setTabText(index, getTabName(index));
|
||||||
|
}
|
||||||
|
|
||||||
|
void FlightModes::update()
|
||||||
|
{
|
||||||
|
on_tabWidget_currentChanged(tabWidget->currentIndex());
|
||||||
|
}
|
||||||
|
|
||||||
|
void FlightModes::on_tabWidget_currentChanged(int index)
|
||||||
|
{
|
||||||
|
panels[index]->update();
|
||||||
|
}
|
86
companion/src/modeledit/flightmodes.h
Normal file
86
companion/src/modeledit/flightmodes.h
Normal file
|
@ -0,0 +1,86 @@
|
||||||
|
#ifndef FLIGHTMODES_H
|
||||||
|
#define FLIGHTMODES_H
|
||||||
|
|
||||||
|
#include "modelpanel.h"
|
||||||
|
#include <QVector>
|
||||||
|
#include <QLabel>
|
||||||
|
#include <QTabWidget>
|
||||||
|
#include <QSpinBox>
|
||||||
|
#include <QComboBox>
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
class FlightMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
class FlightMode : public ModelPanel
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
FlightMode(QWidget *parent, ModelData &model, int modeIdx, GeneralSettings & generalSettings);
|
||||||
|
virtual ~FlightMode();
|
||||||
|
|
||||||
|
virtual void update();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void nameModified();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void phaseName_editingFinished();
|
||||||
|
void phaseSwitch_currentIndexChanged(int index);
|
||||||
|
void phaseFadeIn_editingFinished();
|
||||||
|
void phaseFadeOut_editingFinished();
|
||||||
|
void phaseTrimUse_currentIndexChanged(int index);
|
||||||
|
void phaseTrim_valueChanged();
|
||||||
|
void phaseTrimSlider_valueChanged();
|
||||||
|
void GVName_editingFinished();
|
||||||
|
void GVSource_currentIndexChanged(int index);
|
||||||
|
void phaseGVValue_editingFinished();
|
||||||
|
void phaseGVUse_currentIndexChanged(int index);
|
||||||
|
void phaseREValue_editingFinished();
|
||||||
|
void phaseREUse_currentIndexChanged(int index);
|
||||||
|
|
||||||
|
private:
|
||||||
|
Ui::FlightMode *ui;
|
||||||
|
GeneralSettings & generalSettings;
|
||||||
|
int phaseIdx;
|
||||||
|
PhaseData & phase;
|
||||||
|
int reCount;
|
||||||
|
int gvCount;
|
||||||
|
QVector<QLabel *> trimsLabel;
|
||||||
|
QLineEdit * gvNames[C9X_MAX_GVARS];
|
||||||
|
QSpinBox * gvValues[C9X_MAX_GVARS];
|
||||||
|
QSpinBox * reValues[C9X_MAX_ENCODERS];
|
||||||
|
QVector<QComboBox *> trimsUse;
|
||||||
|
QVector<QSpinBox *> trimsValue;
|
||||||
|
QVector<QSlider *> trimsSlider;
|
||||||
|
|
||||||
|
void trimUpdate(unsigned int trim);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
class FlightModes : public ModelPanel
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
FlightModes(QWidget *parent, ModelData & model, GeneralSettings & generalSettings);
|
||||||
|
virtual ~FlightModes();
|
||||||
|
|
||||||
|
virtual void update();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void onPhaseModified();
|
||||||
|
void onPhaseNameChanged();
|
||||||
|
void on_tabWidget_currentChanged(int index);
|
||||||
|
|
||||||
|
private:
|
||||||
|
int modesCount;
|
||||||
|
QTabWidget *tabWidget;
|
||||||
|
QString getTabName(int index);
|
||||||
|
QVector<FlightMode *> panels;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // FLIGHTMODES_H
|
||||||
|
|
49
companion/src/modeledit/heli.cpp
Normal file
49
companion/src/modeledit/heli.cpp
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
#include "heli.h"
|
||||||
|
#include "ui_heli.h"
|
||||||
|
#include "helpers.h"
|
||||||
|
|
||||||
|
HeliPanel::HeliPanel(QWidget *parent, ModelData & model):
|
||||||
|
ModelPanel(parent, model),
|
||||||
|
ui(new Ui::Heli)
|
||||||
|
{
|
||||||
|
ui->setupUi(this);
|
||||||
|
|
||||||
|
connect(ui->swashTypeCB, SIGNAL(currentIndexChanged(int)), this, SLOT(edited()));
|
||||||
|
connect(ui->swashCollectiveCB, SIGNAL(currentIndexChanged(int)), this, SLOT(edited()));
|
||||||
|
connect(ui->swashRingValSB, SIGNAL(editingFinished()), this, SLOT(edited()));
|
||||||
|
connect(ui->swashInvertELE, SIGNAL(stateChanged(int)), this, SLOT(edited()));
|
||||||
|
connect(ui->swashInvertAIL, SIGNAL(stateChanged(int)), this, SLOT(edited()));
|
||||||
|
connect(ui->swashInvertCOL, SIGNAL(stateChanged(int)), this, SLOT(edited()));
|
||||||
|
}
|
||||||
|
|
||||||
|
HeliPanel::~HeliPanel()
|
||||||
|
{
|
||||||
|
delete ui;
|
||||||
|
}
|
||||||
|
|
||||||
|
void HeliPanel::update()
|
||||||
|
{
|
||||||
|
lock = true;
|
||||||
|
|
||||||
|
ui->swashTypeCB->setCurrentIndex(model.swashRingData.type);
|
||||||
|
populateSourceCB(ui->swashCollectiveCB, model.swashRingData.collectiveSource, POPULATE_SOURCES | POPULATE_SWITCHES | POPULATE_TRIMS);
|
||||||
|
ui->swashRingValSB->setValue(model.swashRingData.value);
|
||||||
|
ui->swashInvertELE->setChecked(model.swashRingData.invertELE);
|
||||||
|
ui->swashInvertAIL->setChecked(model.swashRingData.invertAIL);
|
||||||
|
ui->swashInvertCOL->setChecked(model.swashRingData.invertCOL);
|
||||||
|
|
||||||
|
lock = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void HeliPanel::edited()
|
||||||
|
{
|
||||||
|
if (!lock) {
|
||||||
|
model.swashRingData.type = ui->swashTypeCB->currentIndex();
|
||||||
|
model.swashRingData.collectiveSource = ui->swashCollectiveCB->itemData(ui->swashCollectiveCB->currentIndex()).toInt();
|
||||||
|
model.swashRingData.value = ui->swashRingValSB->value();
|
||||||
|
model.swashRingData.invertELE = ui->swashInvertELE->isChecked();
|
||||||
|
model.swashRingData.invertAIL = ui->swashInvertAIL->isChecked();
|
||||||
|
model.swashRingData.invertCOL = ui->swashInvertCOL->isChecked();
|
||||||
|
emit modified();
|
||||||
|
}
|
||||||
|
}
|
26
companion/src/modeledit/heli.h
Normal file
26
companion/src/modeledit/heli.h
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
#ifndef HELI_H
|
||||||
|
#define HELI_H
|
||||||
|
|
||||||
|
#include "modelpanel.h"
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
class Heli;
|
||||||
|
}
|
||||||
|
|
||||||
|
class HeliPanel : public ModelPanel
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
HeliPanel(QWidget *parent, ModelData & model);
|
||||||
|
~HeliPanel();
|
||||||
|
void update();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void edited();
|
||||||
|
|
||||||
|
private:
|
||||||
|
Ui::Heli *ui;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // HELI_H
|
141
companion/src/modeledit/heli.ui
Normal file
141
companion/src/modeledit/heli.ui
Normal file
|
@ -0,0 +1,141 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>Heli</class>
|
||||||
|
<widget class="QWidget" name="Heli">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>795</width>
|
||||||
|
<height>307</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Form</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QGridLayout" name="gridLayout" columnstretch="0,1" columnminimumwidth="100,0">
|
||||||
|
<property name="horizontalSpacing">
|
||||||
|
<number>6</number>
|
||||||
|
</property>
|
||||||
|
<item row="3" column="1">
|
||||||
|
<layout class="QGridLayout" name="gridLayout_21">
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QCheckBox" name="swashInvertELE">
|
||||||
|
<property name="text">
|
||||||
|
<string>Invert Elevator</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="1">
|
||||||
|
<widget class="QCheckBox" name="swashInvertAIL">
|
||||||
|
<property name="text">
|
||||||
|
<string>Invert Aileron</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="2">
|
||||||
|
<widget class="QCheckBox" name="swashInvertCOL">
|
||||||
|
<property name="text">
|
||||||
|
<string>Invert Collective</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="0">
|
||||||
|
<widget class="QLabel" name="label_108">
|
||||||
|
<property name="text">
|
||||||
|
<string>Invert</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="1">
|
||||||
|
<widget class="QComboBox" name="swashTypeCB">
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Off</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>120</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>120X</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>140</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>90</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QLabel" name="label_106">
|
||||||
|
<property name="text">
|
||||||
|
<string>Collective</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="1">
|
||||||
|
<widget class="QComboBox" name="swashCollectiveCB"/>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QLabel" name="label_103">
|
||||||
|
<property name="text">
|
||||||
|
<string>Swash Type</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="1">
|
||||||
|
<widget class="QSpinBox" name="swashRingValSB">
|
||||||
|
<property name="suffix">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="minimum">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<number>100</number>
|
||||||
|
</property>
|
||||||
|
<property name="singleStep">
|
||||||
|
<number>1</number>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="0">
|
||||||
|
<widget class="QLabel" name="label_107">
|
||||||
|
<property name="text">
|
||||||
|
<string>Swash Ring</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="4" column="1">
|
||||||
|
<spacer name="verticalSpacer_21">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>40</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources/>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
486
companion/src/modeledit/inputs.cpp
Normal file
486
companion/src/modeledit/inputs.cpp
Normal file
|
@ -0,0 +1,486 @@
|
||||||
|
#include "inputs.h"
|
||||||
|
#include <QMessageBox>
|
||||||
|
#include "expodialog.h"
|
||||||
|
#include "helpers.h"
|
||||||
|
|
||||||
|
InputsPanel::InputsPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings):
|
||||||
|
ModelPanel(parent, model),
|
||||||
|
generalSettings(generalSettings),
|
||||||
|
expoInserted(false)
|
||||||
|
{
|
||||||
|
QGridLayout * exposLayout = new QGridLayout(this);
|
||||||
|
|
||||||
|
ExposlistWidget = new MixersList(this, true);
|
||||||
|
QPushButton * qbUp = new QPushButton(this);
|
||||||
|
QPushButton * qbDown = new QPushButton(this);
|
||||||
|
QPushButton * qbClear = new QPushButton(this);
|
||||||
|
|
||||||
|
qbUp->setText(tr("Move Up"));
|
||||||
|
qbUp->setIcon(QIcon(":/images/moveup.png"));
|
||||||
|
qbUp->setShortcut(QKeySequence(tr("Ctrl+Up")));
|
||||||
|
qbDown->setText(tr("Move Down"));
|
||||||
|
qbDown->setIcon(QIcon(":/images/movedown.png"));
|
||||||
|
qbDown->setShortcut(QKeySequence(tr("Ctrl+Down")));
|
||||||
|
qbClear->setText(tr("Clear Expo Settings"));
|
||||||
|
qbClear->setIcon(QIcon(":/images/clear.png"));
|
||||||
|
|
||||||
|
exposLayout->addWidget(ExposlistWidget,1,1,1,3);
|
||||||
|
exposLayout->addWidget(qbUp,2,1);
|
||||||
|
exposLayout->addWidget(qbClear,2,2);
|
||||||
|
exposLayout->addWidget(qbDown,2,3);
|
||||||
|
|
||||||
|
connect(ExposlistWidget, SIGNAL(customContextMenuRequested(QPoint)),this,SLOT(expolistWidget_customContextMenuRequested(QPoint)));
|
||||||
|
connect(ExposlistWidget, SIGNAL(doubleClicked(QModelIndex)),this,SLOT(expolistWidget_doubleClicked(QModelIndex)));
|
||||||
|
connect(ExposlistWidget, SIGNAL(mimeDropped(int,const QMimeData*,Qt::DropAction)),this,SLOT(mimeExpoDropped(int,const QMimeData*,Qt::DropAction)));
|
||||||
|
|
||||||
|
connect(qbUp, SIGNAL(pressed()),SLOT(moveExpoUp()));
|
||||||
|
connect(qbDown, SIGNAL(pressed()),SLOT(moveExpoDown()));
|
||||||
|
connect(qbClear, SIGNAL(pressed()),SLOT(clearExpos()));
|
||||||
|
|
||||||
|
connect(ExposlistWidget, SIGNAL(keyWasPressed(QKeyEvent*)), this, SLOT(expolistWidget_KeyPress(QKeyEvent*)));
|
||||||
|
}
|
||||||
|
|
||||||
|
InputsPanel::~InputsPanel()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void InputsPanel::update()
|
||||||
|
{
|
||||||
|
lock = true;
|
||||||
|
|
||||||
|
// curDest -> destination channel
|
||||||
|
// i -> mixer number
|
||||||
|
QByteArray qba;
|
||||||
|
ExposlistWidget->clear();
|
||||||
|
int curDest = -1;
|
||||||
|
|
||||||
|
for(int i=0; i<C9X_MAX_EXPOS; i++) {
|
||||||
|
ExpoData *md = &model.expoData[i];
|
||||||
|
|
||||||
|
if (md->mode==0) break;
|
||||||
|
QString str = "";
|
||||||
|
while(curDest<(int)md->chn-1) {
|
||||||
|
curDest++;
|
||||||
|
str = getStickStr(curDest);
|
||||||
|
qba.clear();
|
||||||
|
qba.append((quint8)-curDest-1);
|
||||||
|
QListWidgetItem *itm = new QListWidgetItem(str);
|
||||||
|
itm->setData(Qt::UserRole,qba);
|
||||||
|
ExposlistWidget->addItem(itm);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(curDest!=(int)md->chn) {
|
||||||
|
str = getStickStr(md->chn);
|
||||||
|
curDest = md->chn;
|
||||||
|
} else {
|
||||||
|
str = " ";
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (md->mode) {
|
||||||
|
case (1): str += " <-"; break;
|
||||||
|
case (2): str += " ->"; break;
|
||||||
|
default: str += " "; break;
|
||||||
|
};
|
||||||
|
|
||||||
|
str += tr("Weight") + getGVarString(md->weight).rightJustified(6, ' ');
|
||||||
|
if (!GetEepromInterface()->getCapability(ExpoIsCurve)) {
|
||||||
|
if (md->expo!=0)
|
||||||
|
str += " " + tr("Expo") + getGVarString(md->expo, true).rightJustified(7, ' ');
|
||||||
|
} else {
|
||||||
|
if (md->curveMode==0 && md->curveParam!=0)
|
||||||
|
str += " " + tr("Expo") + getGVarString(md->curveParam, true).rightJustified(7, ' ');
|
||||||
|
}
|
||||||
|
if (GetEepromInterface()->getCapability(FlightPhases)) {
|
||||||
|
if(md->phases) {
|
||||||
|
if (md->phases!=(unsigned int)(1<<GetEepromInterface()->getCapability(FlightPhases))-1) {
|
||||||
|
int mask=1;
|
||||||
|
int first=0;
|
||||||
|
for (int i=0; i<GetEepromInterface()->getCapability(FlightPhases);i++) {
|
||||||
|
if (!(md->phases & mask)) {
|
||||||
|
first++;
|
||||||
|
}
|
||||||
|
mask <<=1;
|
||||||
|
}
|
||||||
|
if (first>1) {
|
||||||
|
str += " " + tr("Flight modes") + QString("(");
|
||||||
|
} else {
|
||||||
|
str += " " + tr("Flight mode") + QString("(");
|
||||||
|
}
|
||||||
|
mask=1;
|
||||||
|
first=1;
|
||||||
|
for (int i=0; i<GetEepromInterface()->getCapability(FlightPhases);i++) {
|
||||||
|
if (!(md->phases & mask)) {
|
||||||
|
if (!first) {
|
||||||
|
str += QString(", ")+ QString("%1").arg(getPhaseName(i+1, model.phaseData[i].name));
|
||||||
|
} else {
|
||||||
|
str += QString("%1").arg(getPhaseName(i+1,model.phaseData[i].name));
|
||||||
|
first=0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mask <<=1;
|
||||||
|
}
|
||||||
|
str += QString(")");
|
||||||
|
} else {
|
||||||
|
str += tr("DISABLED")+QString(" !!!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (md->swtch.type != SWITCH_TYPE_NONE) str += " " + tr("Switch") + QString("(%1)").arg(md->swtch.toString());
|
||||||
|
if (md->curveMode)
|
||||||
|
if (md->curveParam) str += " " + tr("Curve") + QString("(%1)").arg(getCurveStr(md->curveParam));
|
||||||
|
if (GetEepromInterface()->getCapability(HasExpoNames)) {
|
||||||
|
QString ExpoName;
|
||||||
|
ExpoName.append(md->name);
|
||||||
|
if (!ExpoName.isEmpty()) {
|
||||||
|
str+=QString("(%1)").arg(ExpoName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
qba.clear();
|
||||||
|
qba.append((quint8)i);
|
||||||
|
qba.append((const char*)md, sizeof(ExpoData));
|
||||||
|
QListWidgetItem *itm = new QListWidgetItem(str);
|
||||||
|
itm->setData(Qt::UserRole,qba); // expo number
|
||||||
|
ExposlistWidget->addItem(itm); //(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
while(curDest<NUM_STICKS-1) {
|
||||||
|
curDest++;
|
||||||
|
QString str = getStickStr(curDest);
|
||||||
|
qba.clear();
|
||||||
|
qba.append((quint8)-curDest-1);
|
||||||
|
QListWidgetItem *itm = new QListWidgetItem(str);
|
||||||
|
itm->setData(Qt::UserRole,qba); // add new expo
|
||||||
|
ExposlistWidget->addItem(itm);
|
||||||
|
}
|
||||||
|
|
||||||
|
lock = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool InputsPanel::gm_insertExpo(int idx)
|
||||||
|
{
|
||||||
|
if (idx<0 || idx>=C9X_MAX_EXPOS || model.expoData[C9X_MAX_EXPOS-1].mode > 0) {
|
||||||
|
QMessageBox::information(this, "companion9x", tr("Not enough available expos!"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int chn = model.expoData[idx].chn;
|
||||||
|
memmove(&model.expoData[idx+1],&model.expoData[idx],
|
||||||
|
(C9X_MAX_EXPOS-(idx+1))*sizeof(ExpoData) );
|
||||||
|
memset(&model.expoData[idx],0,sizeof(ExpoData));
|
||||||
|
model.expoData[idx].chn = chn;
|
||||||
|
model.expoData[idx].weight = 100;
|
||||||
|
model.expoData[idx].mode = 3 /* TODO enum */;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void InputsPanel::gm_deleteExpo(int index)
|
||||||
|
{
|
||||||
|
memmove(&model.expoData[index],&model.expoData[index+1],
|
||||||
|
(C9X_MAX_EXPOS-(index+1))*sizeof(ExpoData));
|
||||||
|
memset(&model.expoData[C9X_MAX_EXPOS-1],0,sizeof(ExpoData));
|
||||||
|
}
|
||||||
|
|
||||||
|
void InputsPanel::gm_openExpo(int index)
|
||||||
|
{
|
||||||
|
if(index<0 || index>=C9X_MAX_EXPOS) return;
|
||||||
|
|
||||||
|
ExpoData mixd(model.expoData[index]);
|
||||||
|
emit modified();
|
||||||
|
update();
|
||||||
|
|
||||||
|
ExpoDialog *g = new ExpoDialog(this, &mixd, generalSettings.stickMode);
|
||||||
|
if(g->exec()) {
|
||||||
|
model.expoData[index] = mixd;
|
||||||
|
emit modified();
|
||||||
|
update();
|
||||||
|
} else {
|
||||||
|
if (expoInserted) {
|
||||||
|
gm_deleteExpo(index);
|
||||||
|
}
|
||||||
|
expoInserted=false;
|
||||||
|
emit modified();
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int InputsPanel::getExpoIndex(unsigned int dch)
|
||||||
|
{
|
||||||
|
unsigned int i = 0;
|
||||||
|
while (model.expoData[i].chn<=dch && model.expoData[i].mode && i<C9X_MAX_EXPOS) i++;
|
||||||
|
if(i==C9X_MAX_EXPOS) return -1;
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QList<int> InputsPanel::createExpoListFromSelected()
|
||||||
|
{
|
||||||
|
QList<int> list;
|
||||||
|
foreach(QListWidgetItem *item, ExposlistWidget->selectedItems()) {
|
||||||
|
int idx= item->data(Qt::UserRole).toByteArray().at(0);
|
||||||
|
if(idx>=0 && idx<C9X_MAX_EXPOS) list << idx;
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void InputsPanel::setSelectedByExpoList(QList<int> list)
|
||||||
|
{
|
||||||
|
for(int i=0; i<ExposlistWidget->count(); i++) {
|
||||||
|
int t = ExposlistWidget->item(i)->data(Qt::UserRole).toByteArray().at(0);
|
||||||
|
if(list.contains(t))
|
||||||
|
ExposlistWidget->item(i)->setSelected(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void InputsPanel::exposDelete(bool ask)
|
||||||
|
{
|
||||||
|
QMessageBox::StandardButton ret = QMessageBox::No;
|
||||||
|
|
||||||
|
if(ask)
|
||||||
|
ret = QMessageBox::warning(this, "companion9x",
|
||||||
|
tr("Delete Selected Expos?"),
|
||||||
|
QMessageBox::Yes | QMessageBox::No);
|
||||||
|
|
||||||
|
|
||||||
|
if ((ret == QMessageBox::Yes) || (!ask)) {
|
||||||
|
exposDeleteList(createExpoListFromSelected());
|
||||||
|
emit modified();
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void InputsPanel::exposCut()
|
||||||
|
{
|
||||||
|
exposCopy();
|
||||||
|
exposDelete(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void InputsPanel::exposCopy()
|
||||||
|
{
|
||||||
|
QList<int> list = createExpoListFromSelected();
|
||||||
|
|
||||||
|
QByteArray mxData;
|
||||||
|
foreach(int idx, list) {
|
||||||
|
mxData.append((char*)&model.expoData[idx],sizeof(ExpoData));
|
||||||
|
}
|
||||||
|
|
||||||
|
QMimeData *mimeData = new QMimeData;
|
||||||
|
mimeData->setData("application/x-companion9x-expo", mxData);
|
||||||
|
QApplication::clipboard()->setMimeData(mimeData,QClipboard::Clipboard);
|
||||||
|
}
|
||||||
|
|
||||||
|
void InputsPanel::mimeExpoDropped(int index, const QMimeData *data, Qt::DropAction /*action*/)
|
||||||
|
{
|
||||||
|
int idx = ExposlistWidget->item(index > 0 ? index-1 : 0)->data(Qt::UserRole).toByteArray().at(0);
|
||||||
|
pasteExpoMimeData(data, idx);
|
||||||
|
}
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <QtGui/qwidget.h>
|
||||||
|
void InputsPanel::pasteExpoMimeData(const QMimeData * mimeData, int destIdx)
|
||||||
|
{
|
||||||
|
if (mimeData->hasFormat("application/x-companion9x-expo")) {
|
||||||
|
int idx; // mixer index
|
||||||
|
int dch;
|
||||||
|
|
||||||
|
if (destIdx < 0) {
|
||||||
|
dch = -destIdx - 1;
|
||||||
|
idx = getExpoIndex(dch) - 1; //get expo index to insert
|
||||||
|
} else {
|
||||||
|
idx = destIdx;
|
||||||
|
dch = model.expoData[idx].chn;
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray mxData = mimeData->data("application/x-companion9x-expo");
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
while (i < mxData.size()) {
|
||||||
|
idx++;
|
||||||
|
if (!gm_insertExpo(idx))
|
||||||
|
break;
|
||||||
|
ExpoData *md = &model.expoData[idx];
|
||||||
|
memcpy(md, mxData.mid(i, sizeof(ExpoData)).constData(), sizeof(ExpoData));
|
||||||
|
md->chn = dch;
|
||||||
|
i += sizeof(ExpoData);
|
||||||
|
}
|
||||||
|
|
||||||
|
emit modified();
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void InputsPanel::exposPaste()
|
||||||
|
{
|
||||||
|
const QClipboard *clipboard = QApplication::clipboard();
|
||||||
|
const QMimeData *mimeData = clipboard->mimeData();
|
||||||
|
QListWidgetItem *item = ExposlistWidget->currentItem();
|
||||||
|
if (item)
|
||||||
|
pasteExpoMimeData(mimeData, item->data(Qt::UserRole).toByteArray().at(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
void InputsPanel::exposDuplicate()
|
||||||
|
{
|
||||||
|
exposCopy();
|
||||||
|
exposPaste();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void InputsPanel::expoOpen(QListWidgetItem *item)
|
||||||
|
{
|
||||||
|
if (!item)
|
||||||
|
item = ExposlistWidget->currentItem();
|
||||||
|
|
||||||
|
int idx = item->data(Qt::UserRole).toByteArray().at(0);
|
||||||
|
if (idx<0) {
|
||||||
|
int ch = -idx-1;
|
||||||
|
idx = getExpoIndex(ch); // get expo index to insert
|
||||||
|
if (!gm_insertExpo(idx))
|
||||||
|
return;
|
||||||
|
model.expoData[idx].chn = ch;
|
||||||
|
expoInserted=true;
|
||||||
|
} else {
|
||||||
|
expoInserted=false;
|
||||||
|
}
|
||||||
|
gm_openExpo(idx);
|
||||||
|
}
|
||||||
|
|
||||||
|
void InputsPanel::expoAdd()
|
||||||
|
{
|
||||||
|
int index = ExposlistWidget->currentItem()->data(Qt::UserRole).toByteArray().at(0);
|
||||||
|
|
||||||
|
if(index<0) { // if empty then return relevant index
|
||||||
|
expoOpen();
|
||||||
|
} else {
|
||||||
|
index++;
|
||||||
|
if (!gm_insertExpo(index))
|
||||||
|
return;
|
||||||
|
model.expoData[index].chn = model.expoData[index-1].chn;
|
||||||
|
}
|
||||||
|
gm_openExpo(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void InputsPanel::expolistWidget_customContextMenuRequested(QPoint pos)
|
||||||
|
{
|
||||||
|
QPoint globalPos = ExposlistWidget->mapToGlobal(pos);
|
||||||
|
|
||||||
|
const QClipboard *clipboard = QApplication::clipboard();
|
||||||
|
const QMimeData *mimeData = clipboard->mimeData();
|
||||||
|
bool hasData = mimeData->hasFormat("application/x-companion9x-expo");
|
||||||
|
|
||||||
|
QMenu contextMenu;
|
||||||
|
contextMenu.addAction(QIcon(":/images/add.png"), tr("&Add"),this,SLOT(expoAdd()),tr("Ctrl+A"));
|
||||||
|
contextMenu.addAction(QIcon(":/images/edit.png"), tr("&Edit"),this,SLOT(expoOpen()),tr("Enter"));
|
||||||
|
contextMenu.addSeparator();
|
||||||
|
contextMenu.addAction(QIcon(":/images/clear.png"), tr("&Delete"),this,SLOT(exposDelete()),tr("Delete"));
|
||||||
|
contextMenu.addAction(QIcon(":/images/copy.png"), tr("&Copy"),this,SLOT(exposCopy()),tr("Ctrl+C"));
|
||||||
|
contextMenu.addAction(QIcon(":/images/cut.png"), tr("&Cut"),this,SLOT(exposCut()),tr("Ctrl+X"));
|
||||||
|
contextMenu.addAction(QIcon(":/images/paste.png"), tr("&Paste"),this,SLOT(exposPaste()),tr("Ctrl+V"))->setEnabled(hasData);
|
||||||
|
contextMenu.addAction(QIcon(":/images/duplicate.png"), tr("Du&plicate"),this,SLOT(exposDuplicate()),tr("Ctrl+U"));
|
||||||
|
contextMenu.addSeparator();
|
||||||
|
contextMenu.addAction(QIcon(":/images/moveup.png"), tr("Move Up"),this,SLOT(moveExpoUp()),tr("Ctrl+Up"));
|
||||||
|
contextMenu.addAction(QIcon(":/images/movedown.png"), tr("Move Down"),this,SLOT(moveExpoDown()),tr("Ctrl+Down"));
|
||||||
|
|
||||||
|
contextMenu.exec(globalPos);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void InputsPanel::expolistWidget_KeyPress(QKeyEvent *event)
|
||||||
|
{
|
||||||
|
if(event->matches(QKeySequence::SelectAll)) expoAdd(); //Ctrl A
|
||||||
|
if(event->matches(QKeySequence::Delete)) exposDelete();
|
||||||
|
if(event->matches(QKeySequence::Copy)) exposCopy();
|
||||||
|
if(event->matches(QKeySequence::Cut)) exposCut();
|
||||||
|
if(event->matches(QKeySequence::Paste)) exposPaste();
|
||||||
|
if(event->matches(QKeySequence::Underline)) exposDuplicate();
|
||||||
|
|
||||||
|
if(event->key()==Qt::Key_Return || event->key()==Qt::Key_Enter) expoOpen();
|
||||||
|
if(event->matches(QKeySequence::MoveToNextLine))
|
||||||
|
ExposlistWidget->setCurrentRow(ExposlistWidget->currentRow()+1);
|
||||||
|
if(event->matches(QKeySequence::MoveToPreviousLine))
|
||||||
|
ExposlistWidget->setCurrentRow(ExposlistWidget->currentRow()-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int InputsPanel::gm_moveExpo(int idx, bool dir) //true=inc=down false=dec=up
|
||||||
|
{
|
||||||
|
if(idx>C9X_MAX_EXPOS || (idx==C9X_MAX_EXPOS && dir)) return idx;
|
||||||
|
|
||||||
|
int tdx = dir ? idx+1 : idx-1;
|
||||||
|
ExpoData temp;
|
||||||
|
temp.clear();
|
||||||
|
ExpoData &src=model.expoData[idx];
|
||||||
|
ExpoData &tgt=model.expoData[tdx];
|
||||||
|
if (!dir && tdx<0 && src.chn>0) {
|
||||||
|
src.chn--;
|
||||||
|
return idx;
|
||||||
|
} else if (!dir && tdx<0) {
|
||||||
|
return idx;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(memcmp(&src,&temp,sizeof(ExpoData))==0) return idx;
|
||||||
|
bool tgtempty=(memcmp(&tgt,&temp,sizeof(ExpoData))==0 ? 1:0);
|
||||||
|
if(tgt.chn!=src.chn || tgtempty) {
|
||||||
|
if ((dir) && (src.chn<(NUM_STICKS-1))) src.chn++;
|
||||||
|
if ((!dir) && (src.chn>0)) src.chn--;
|
||||||
|
return idx;
|
||||||
|
}
|
||||||
|
|
||||||
|
//flip between idx and tgt
|
||||||
|
memcpy(&temp,&src,sizeof(ExpoData));
|
||||||
|
memcpy(&src,&tgt,sizeof(ExpoData));
|
||||||
|
memcpy(&tgt,&temp,sizeof(ExpoData));
|
||||||
|
return tdx;
|
||||||
|
}
|
||||||
|
|
||||||
|
void InputsPanel::moveExpoUp()
|
||||||
|
{
|
||||||
|
QList<int> list = createExpoListFromSelected();
|
||||||
|
QList<int> highlightList;
|
||||||
|
foreach(int idx, list) {
|
||||||
|
highlightList << gm_moveExpo(idx, false);
|
||||||
|
}
|
||||||
|
emit modified();
|
||||||
|
update();
|
||||||
|
setSelectedByExpoList(highlightList);
|
||||||
|
}
|
||||||
|
|
||||||
|
void InputsPanel::moveExpoDown()
|
||||||
|
{
|
||||||
|
QList<int> list = createExpoListFromSelected();
|
||||||
|
QList<int> highlightList;
|
||||||
|
foreach(int idx, list) {
|
||||||
|
highlightList << gm_moveExpo(idx, true);
|
||||||
|
}
|
||||||
|
emit modified();
|
||||||
|
update();
|
||||||
|
setSelectedByExpoList(highlightList);
|
||||||
|
}
|
||||||
|
|
||||||
|
void InputsPanel::expolistWidget_doubleClicked(QModelIndex index)
|
||||||
|
{
|
||||||
|
expoOpen(ExposlistWidget->item(index.row()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void InputsPanel::exposDeleteList(QList<int> list)
|
||||||
|
{
|
||||||
|
qSort(list.begin(), list.end());
|
||||||
|
|
||||||
|
int iDec = 0;
|
||||||
|
foreach(int idx, list) {
|
||||||
|
gm_deleteExpo(idx-iDec);
|
||||||
|
iDec++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void InputsPanel::clearExpos()
|
||||||
|
{
|
||||||
|
if (QMessageBox::question(this, tr("Clear Expos?"), tr("Really clear all the expos?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
|
||||||
|
model.clearInputs();
|
||||||
|
emit modified();
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
}
|
50
companion/src/modeledit/inputs.h
Normal file
50
companion/src/modeledit/inputs.h
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
#ifndef INPUTS_H
|
||||||
|
#define INPUTS_H
|
||||||
|
|
||||||
|
#include "modelpanel.h"
|
||||||
|
#include "mixerslist.h"
|
||||||
|
|
||||||
|
class InputsPanel : public ModelPanel
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
InputsPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings);
|
||||||
|
virtual ~InputsPanel();
|
||||||
|
|
||||||
|
virtual void update();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void clearExpos();
|
||||||
|
void moveExpoUp();
|
||||||
|
void moveExpoDown();
|
||||||
|
void mimeExpoDropped(int index, const QMimeData *data, Qt::DropAction action);
|
||||||
|
void expolistWidget_customContextMenuRequested(QPoint pos);
|
||||||
|
void expolistWidget_doubleClicked(QModelIndex index);
|
||||||
|
void expolistWidget_KeyPress(QKeyEvent *event);
|
||||||
|
|
||||||
|
private:
|
||||||
|
GeneralSettings & generalSettings;
|
||||||
|
bool expoInserted;
|
||||||
|
MixersList *ExposlistWidget;
|
||||||
|
|
||||||
|
int getExpoIndex(unsigned int dch);
|
||||||
|
bool gm_insertExpo(int idx);
|
||||||
|
void gm_deleteExpo(int index);
|
||||||
|
void gm_openExpo(int index);
|
||||||
|
int gm_moveExpo(int idx, bool dir);
|
||||||
|
void exposDeleteList(QList<int> list);
|
||||||
|
QList<int> createExpoListFromSelected();
|
||||||
|
void setSelectedByExpoList(QList<int> list);
|
||||||
|
void exposDelete(bool ask=true);
|
||||||
|
void exposCut();
|
||||||
|
void exposCopy();
|
||||||
|
void exposPaste();
|
||||||
|
void exposDuplicate();
|
||||||
|
void expoOpen(QListWidgetItem *item = NULL);
|
||||||
|
void expoAdd();
|
||||||
|
void pasteExpoMimeData(const QMimeData * mimeData, int destIdx);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // INPUTS_H
|
548
companion/src/modeledit/mixes.cpp
Normal file
548
companion/src/modeledit/mixes.cpp
Normal file
|
@ -0,0 +1,548 @@
|
||||||
|
#include "mixes.h"
|
||||||
|
#include "helpers.h"
|
||||||
|
// #include <QMessageBox>
|
||||||
|
// #include "expodialog.h"
|
||||||
|
|
||||||
|
MixesPanel::MixesPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings):
|
||||||
|
ModelPanel(parent, model),
|
||||||
|
generalSettings(generalSettings),
|
||||||
|
mixInserted(false)
|
||||||
|
{
|
||||||
|
QGridLayout * mixesLayout = new QGridLayout(this);
|
||||||
|
|
||||||
|
MixerlistWidget = new MixersList(this, false); // TODO enum
|
||||||
|
QPushButton * qbUp = new QPushButton(this);
|
||||||
|
QPushButton * qbDown = new QPushButton(this);
|
||||||
|
QPushButton * qbClear = new QPushButton(this);
|
||||||
|
|
||||||
|
qbUp->setText(tr("Move Up"));
|
||||||
|
qbUp->setIcon(QIcon(":/images/moveup.png"));
|
||||||
|
qbUp->setShortcut(QKeySequence(tr("Ctrl+Up")));
|
||||||
|
qbDown->setText(tr("Move Down"));
|
||||||
|
qbDown->setIcon(QIcon(":/images/movedown.png"));
|
||||||
|
qbDown->setShortcut(QKeySequence(tr("Ctrl+Down")));
|
||||||
|
qbClear->setText(tr("Clear Mixes"));
|
||||||
|
qbClear->setIcon(QIcon(":/images/clear.png"));
|
||||||
|
|
||||||
|
mixesLayout->addWidget(MixerlistWidget,1,1,1,3);
|
||||||
|
mixesLayout->addWidget(qbUp,2,1);
|
||||||
|
mixesLayout->addWidget(qbClear,2,2);
|
||||||
|
mixesLayout->addWidget(qbDown,2,3);
|
||||||
|
|
||||||
|
connect(MixerlistWidget,SIGNAL(customContextMenuRequested(QPoint)),this,SLOT(mixerlistWidget_customContextMenuRequested(QPoint)));
|
||||||
|
connect(MixerlistWidget,SIGNAL(doubleClicked(QModelIndex)),this,SLOT(mixerlistWidget_doubleClicked(QModelIndex)));
|
||||||
|
connect(MixerlistWidget,SIGNAL(mimeDropped(int,const QMimeData*,Qt::DropAction)),this,SLOT(mimeMixerDropped(int,const QMimeData*,Qt::DropAction)));
|
||||||
|
|
||||||
|
connect(qbUp,SIGNAL(pressed()),SLOT(moveMixUp()));
|
||||||
|
connect(qbDown,SIGNAL(pressed()),SLOT(moveMixDown()));
|
||||||
|
connect(qbClear,SIGNAL(pressed()),SLOT(clearMixes()));
|
||||||
|
|
||||||
|
connect(MixerlistWidget,SIGNAL(keyWasPressed(QKeyEvent*)), this, SLOT(mixerlistWidget_KeyPress(QKeyEvent*)));
|
||||||
|
}
|
||||||
|
|
||||||
|
MixesPanel::~MixesPanel()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void MixesPanel::update()
|
||||||
|
{
|
||||||
|
// curDest -> destination channel4
|
||||||
|
// i -> mixer number
|
||||||
|
QByteArray qba;
|
||||||
|
MixerlistWidget->clear();
|
||||||
|
unsigned int curDest = 0;
|
||||||
|
int i;
|
||||||
|
unsigned int outputs = GetEepromInterface()->getCapability(Outputs);
|
||||||
|
int showNames = false; // TODO in a menu ui->showNames_Ckb->isChecked();
|
||||||
|
for(i=0; i<GetEepromInterface()->getCapability(Mixes); i++) {
|
||||||
|
MixData *md = &model.mixData[i];
|
||||||
|
if ((md->destCh==0) || (md->destCh>outputs+(unsigned int)GetEepromInterface()->getCapability(ExtraChannels))) continue;
|
||||||
|
QString str = "";
|
||||||
|
while(curDest<(md->destCh-1)) {
|
||||||
|
curDest++;
|
||||||
|
if (curDest > outputs) {
|
||||||
|
str = tr("X%1 ").arg(curDest-outputs);
|
||||||
|
} else {
|
||||||
|
str = tr("CH%1%2").arg(curDest/10).arg(curDest%10);
|
||||||
|
if (GetEepromInterface()->getCapability(HasChNames) && showNames) {
|
||||||
|
QString name=model.limitData[curDest-1].name;
|
||||||
|
if (!name.isEmpty()) {
|
||||||
|
name.append(" ");
|
||||||
|
str=name.left(6);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
qba.clear();
|
||||||
|
qba.append((quint8)-curDest);
|
||||||
|
QListWidgetItem *itm = new QListWidgetItem(str);
|
||||||
|
itm->setData(Qt::UserRole,qba);
|
||||||
|
MixerlistWidget->addItem(itm);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (md->destCh > outputs) {
|
||||||
|
str = tr("X%1 ").arg(md->destCh-outputs);
|
||||||
|
} else {
|
||||||
|
str = tr("CH%1%2").arg(md->destCh/10).arg(md->destCh%10);
|
||||||
|
str.append(" ");
|
||||||
|
if (GetEepromInterface()->getCapability(HasChNames) && showNames) {
|
||||||
|
QString name=model.limitData[md->destCh-1].name;
|
||||||
|
if (!name.isEmpty()) {
|
||||||
|
name.append(" ");
|
||||||
|
str=name.left(6);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (curDest != md->destCh) {
|
||||||
|
curDest = md->destCh;
|
||||||
|
} else {
|
||||||
|
str.fill(' ');
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(md->mltpx) {
|
||||||
|
case (1): str += " *"; break;
|
||||||
|
case (2): str += " R"; break;
|
||||||
|
default: str += " "; break;
|
||||||
|
};
|
||||||
|
|
||||||
|
str += " " + getGVarString(md->weight, true).rightJustified(6, ' ');
|
||||||
|
str += md->srcRaw.toString();
|
||||||
|
unsigned int fpCount = GetEepromInterface()->getCapability(FlightPhases);
|
||||||
|
if (GetEepromInterface()->getCapability(FlightPhases)) {
|
||||||
|
if(md->phases) {
|
||||||
|
if (md->phases!=(unsigned int)(1<<fpCount)-1) {
|
||||||
|
int mask=1;
|
||||||
|
int first=0;
|
||||||
|
for (unsigned int i=0; i<fpCount; i++) {
|
||||||
|
if (!(md->phases & mask)) {
|
||||||
|
first++;
|
||||||
|
}
|
||||||
|
mask <<=1;
|
||||||
|
}
|
||||||
|
if (first>1) {
|
||||||
|
str += " " + tr("Flight modes") + QString("(");
|
||||||
|
} else {
|
||||||
|
str += " " + tr("Flight mode") + QString("(");
|
||||||
|
}
|
||||||
|
mask=1;
|
||||||
|
first=1;
|
||||||
|
for (unsigned int i=0; i<fpCount; i++) {
|
||||||
|
if (!(md->phases & mask)) {
|
||||||
|
if (!first) {
|
||||||
|
str += QString(", ")+ QString("%1").arg(getPhaseName(i+1, model.phaseData[i].name));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
str += QString("%1").arg(getPhaseName(i+1,model.phaseData[i].name));
|
||||||
|
first=0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mask <<=1;
|
||||||
|
}
|
||||||
|
str += QString(")");
|
||||||
|
} else {
|
||||||
|
str += tr("DISABLED")+QString(" !!!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(md->swtch.type != SWITCH_TYPE_NONE) str += " " + tr("Switch") + QString("(%1)").arg(md->swtch.toString());
|
||||||
|
if(md->carryTrim>0) {
|
||||||
|
str += " " +tr("No Trim");
|
||||||
|
} else if (md->carryTrim<0) {
|
||||||
|
str += " " + RawSource(SOURCE_TYPE_TRIM, (-(md->carryTrim)-1)).toString();
|
||||||
|
}
|
||||||
|
if(md->noExpo) {
|
||||||
|
str += " " +tr("No DR/Expo");
|
||||||
|
}
|
||||||
|
if (GetEepromInterface()->getCapability(MixFmTrim) && md->enableFmTrim==1) {
|
||||||
|
if (md->sOffset) str += " " + tr("FMTrim") + QString("(%1%)").arg(md->sOffset);
|
||||||
|
} else {
|
||||||
|
if (md->sOffset) str += " " + tr("Offset") + getGVarString(md->sOffset);
|
||||||
|
}
|
||||||
|
if (md->differential) str += " " + tr("Diff") + getGVarString(md->differential);
|
||||||
|
if (md->curve) str += " " + tr("Curve") + QString("(%1)").arg(getCurveStr(md->curve));
|
||||||
|
int scale=GetEepromInterface()->getCapability(SlowScale);
|
||||||
|
if (scale==0)
|
||||||
|
scale=1;
|
||||||
|
if (md->delayDown || md->delayUp)
|
||||||
|
str += tr(" Delay(u%1:d%2)").arg((double)md->delayUp/scale).arg((double)md->delayDown/scale);
|
||||||
|
if (md->speedDown || md->speedUp)
|
||||||
|
str += tr(" Slow(u%1:d%2)").arg((double)md->speedUp/scale).arg((double)md->speedDown/scale);
|
||||||
|
if (md->mixWarn) str += tr(" Warn(%1)").arg(md->mixWarn);
|
||||||
|
if (GetEepromInterface()->getCapability(HasMixerNames)) {
|
||||||
|
QString MixerName;
|
||||||
|
MixerName.append(md->name);
|
||||||
|
if (!MixerName.isEmpty()) {
|
||||||
|
str+=QString("(%1)").arg(MixerName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
qba.clear();
|
||||||
|
qba.append((quint8)i);
|
||||||
|
qba.append((const char*)md, sizeof(MixData));
|
||||||
|
QListWidgetItem *itm = new QListWidgetItem(str);
|
||||||
|
itm->setData(Qt::UserRole,qba); // mix number
|
||||||
|
MixerlistWidget->addItem(itm);//(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
while(curDest<outputs+GetEepromInterface()->getCapability(ExtraChannels)) {
|
||||||
|
curDest++;
|
||||||
|
QString str;
|
||||||
|
|
||||||
|
if (curDest > outputs) {
|
||||||
|
str = tr("X%1 ").arg(curDest-outputs);
|
||||||
|
} else {
|
||||||
|
str = tr("CH%1%2").arg(curDest/10).arg(curDest%10);
|
||||||
|
if (GetEepromInterface()->getCapability(HasChNames) && showNames) {
|
||||||
|
QString name=model.limitData[curDest-1].name;
|
||||||
|
if (!name.isEmpty()) {
|
||||||
|
name.append(" ");
|
||||||
|
str=name.left(6);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
qba.clear();
|
||||||
|
qba.append((quint8)-curDest);
|
||||||
|
QListWidgetItem *itm = new QListWidgetItem(str);
|
||||||
|
itm->setData(Qt::UserRole,qba); // add new mixer
|
||||||
|
MixerlistWidget->addItem(itm);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool MixesPanel::gm_insertMix(int idx)
|
||||||
|
{
|
||||||
|
if (idx<0 || idx>=GetEepromInterface()->getCapability(Mixes) || model.mixData[GetEepromInterface()->getCapability(Mixes)-1].destCh > 0) {
|
||||||
|
QMessageBox::information(this, "companion9x", tr("Not enough available mixers!"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int i = model.mixData[idx].destCh;
|
||||||
|
memmove(&model.mixData[idx+1],&model.mixData[idx],
|
||||||
|
(GetEepromInterface()->getCapability(Mixes)-(idx+1))*sizeof(MixData) );
|
||||||
|
memset(&model.mixData[idx],0,sizeof(MixData));
|
||||||
|
model.mixData[idx].srcRaw = RawSource(SOURCE_TYPE_NONE);
|
||||||
|
model.mixData[idx].destCh = i;
|
||||||
|
model.mixData[idx].weight = 100;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MixesPanel::gm_deleteMix(int index)
|
||||||
|
{
|
||||||
|
memmove(&model.mixData[index],&model.mixData[index+1],
|
||||||
|
(GetEepromInterface()->getCapability(Mixes)-(index+1))*sizeof(MixData));
|
||||||
|
memset(&model.mixData[GetEepromInterface()->getCapability(Mixes)-1],0,sizeof(MixData));
|
||||||
|
}
|
||||||
|
|
||||||
|
void MixesPanel::gm_openMix(int index)
|
||||||
|
{
|
||||||
|
if(index<0 || index>=GetEepromInterface()->getCapability(Mixes)) return;
|
||||||
|
|
||||||
|
MixData mixd(model.mixData[index]);
|
||||||
|
emit modified();
|
||||||
|
update();
|
||||||
|
|
||||||
|
MixerDialog *g = new MixerDialog(this, &mixd, generalSettings.stickMode);
|
||||||
|
if(g->exec()) {
|
||||||
|
model.mixData[index] = mixd;
|
||||||
|
emit modified();
|
||||||
|
update();
|
||||||
|
} else {
|
||||||
|
if (mixInserted) {
|
||||||
|
gm_deleteMix(index);
|
||||||
|
}
|
||||||
|
mixInserted=false;
|
||||||
|
emit modified();
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int MixesPanel::getMixerIndex(unsigned int dch)
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
while ((model.mixData[i].destCh<=dch) && (model.mixData[i].destCh) && (i<GetEepromInterface()->getCapability(Mixes))) i++;
|
||||||
|
if(i==GetEepromInterface()->getCapability(Mixes)) return -1;
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MixesPanel::mixerlistWidget_doubleClicked(QModelIndex index)
|
||||||
|
{
|
||||||
|
int idx= MixerlistWidget->item(index.row())->data(Qt::UserRole).toByteArray().at(0);
|
||||||
|
if (idx<0) {
|
||||||
|
int i = -idx;
|
||||||
|
idx = getMixerIndex(i); //get mixer index to insert
|
||||||
|
if (!gm_insertMix(idx))
|
||||||
|
return;
|
||||||
|
model.mixData[idx].destCh = i;
|
||||||
|
mixInserted=true;
|
||||||
|
} else {
|
||||||
|
mixInserted=false;
|
||||||
|
}
|
||||||
|
gm_openMix(idx);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MixesPanel::mixersDeleteList(QList<int> list)
|
||||||
|
{
|
||||||
|
qSort(list.begin(), list.end());
|
||||||
|
|
||||||
|
int iDec = 0;
|
||||||
|
foreach(int idx, list) {
|
||||||
|
gm_deleteMix(idx-iDec);
|
||||||
|
iDec++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<int> MixesPanel::createMixListFromSelected()
|
||||||
|
{
|
||||||
|
QList<int> list;
|
||||||
|
foreach(QListWidgetItem *item, MixerlistWidget->selectedItems()) {
|
||||||
|
int idx= item->data(Qt::UserRole).toByteArray().at(0);
|
||||||
|
if(idx>=0 && idx<GetEepromInterface()->getCapability(Mixes)) list << idx;
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO duplicated code
|
||||||
|
void MixesPanel::setSelectedByMixList(QList<int> list)
|
||||||
|
{
|
||||||
|
for(int i=0; i<MixerlistWidget->count(); i++) {
|
||||||
|
int t = MixerlistWidget->item(i)->data(Qt::UserRole).toByteArray().at(0);
|
||||||
|
if(list.contains(t))
|
||||||
|
MixerlistWidget->item(i)->setSelected(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void MixesPanel::mixersDelete(bool ask)
|
||||||
|
{
|
||||||
|
QMessageBox::StandardButton ret = QMessageBox::No;
|
||||||
|
|
||||||
|
if(ask)
|
||||||
|
ret = QMessageBox::warning(this, "companion9x",
|
||||||
|
tr("Delete Selected Mixes?"),
|
||||||
|
QMessageBox::Yes | QMessageBox::No);
|
||||||
|
|
||||||
|
|
||||||
|
if ((ret == QMessageBox::Yes) || (!ask)) {
|
||||||
|
mixersDeleteList(createMixListFromSelected());
|
||||||
|
emit modified();
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MixesPanel::mixersCut()
|
||||||
|
{
|
||||||
|
mixersCopy();
|
||||||
|
mixersDelete(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MixesPanel::mixersCopy()
|
||||||
|
{
|
||||||
|
|
||||||
|
QList<int> list = createMixListFromSelected();
|
||||||
|
|
||||||
|
QByteArray mxData;
|
||||||
|
foreach(int idx, list) {
|
||||||
|
mxData.append((char*)&model.mixData[idx],sizeof(MixData));
|
||||||
|
}
|
||||||
|
|
||||||
|
QMimeData *mimeData = new QMimeData;
|
||||||
|
mimeData->setData("application/x-companion9x-mix", mxData);
|
||||||
|
QApplication::clipboard()->setMimeData(mimeData,QClipboard::Clipboard);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MixesPanel::pasteMixerMimeData(const QMimeData * mimeData, int destIdx)
|
||||||
|
{
|
||||||
|
if(mimeData->hasFormat("application/x-companion9x-mix")) {
|
||||||
|
int idx; // mixer index
|
||||||
|
int dch;
|
||||||
|
|
||||||
|
if(destIdx<0) {
|
||||||
|
dch = -destIdx;
|
||||||
|
idx = getMixerIndex(dch) - 1; //get mixer index to insert
|
||||||
|
} else {
|
||||||
|
idx = destIdx;
|
||||||
|
dch = model.mixData[idx].destCh;
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray mxData = mimeData->data("application/x-companion9x-mix");
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
while(i<mxData.size()) {
|
||||||
|
idx++;
|
||||||
|
if(idx==GetEepromInterface()->getCapability(Mixes)) break;
|
||||||
|
|
||||||
|
if (!gm_insertMix(idx))
|
||||||
|
break;
|
||||||
|
MixData *md = &model.mixData[idx];
|
||||||
|
memcpy(md,mxData.mid(i,sizeof(MixData)).constData(),sizeof(MixData));
|
||||||
|
md->destCh = dch;
|
||||||
|
i += sizeof(MixData);
|
||||||
|
}
|
||||||
|
|
||||||
|
emit modified();
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void MixesPanel::mixersPaste()
|
||||||
|
{
|
||||||
|
const QClipboard *clipboard = QApplication::clipboard();
|
||||||
|
const QMimeData *mimeData = clipboard->mimeData();
|
||||||
|
QListWidgetItem *item = MixerlistWidget->currentItem();
|
||||||
|
if (item)
|
||||||
|
pasteMixerMimeData(mimeData, item->data(Qt::UserRole).toByteArray().at(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
void MixesPanel::mixersDuplicate()
|
||||||
|
{
|
||||||
|
mixersCopy();
|
||||||
|
mixersPaste();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MixesPanel::mixerOpen()
|
||||||
|
{
|
||||||
|
int idx = MixerlistWidget->currentItem()->data(Qt::UserRole).toByteArray().at(0);
|
||||||
|
if(idx<0) {
|
||||||
|
int i = -idx;
|
||||||
|
idx = getMixerIndex(i); //get mixer index to insert
|
||||||
|
if (!gm_insertMix(idx))
|
||||||
|
return;
|
||||||
|
model.mixData[idx].destCh = i;
|
||||||
|
mixInserted=true;
|
||||||
|
} else {
|
||||||
|
mixInserted=false;
|
||||||
|
}
|
||||||
|
|
||||||
|
gm_openMix(idx);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MixesPanel::mixerAdd()
|
||||||
|
{
|
||||||
|
if (!MixerlistWidget->currentItem())
|
||||||
|
return;
|
||||||
|
int index = MixerlistWidget->currentItem()->data(Qt::UserRole).toByteArray().at(0);
|
||||||
|
|
||||||
|
if(index<0) { // if empty then return relavent index
|
||||||
|
int i = -index;
|
||||||
|
index = getMixerIndex(i); //get mixer index to insert
|
||||||
|
if (!gm_insertMix(index))
|
||||||
|
return;
|
||||||
|
model.mixData[index].destCh = i;
|
||||||
|
mixInserted=true;
|
||||||
|
} else {
|
||||||
|
index++;
|
||||||
|
if (!gm_insertMix(index))
|
||||||
|
return;
|
||||||
|
model.mixData[index].destCh = model.mixData[index-1].destCh;
|
||||||
|
mixInserted=true;
|
||||||
|
}
|
||||||
|
gm_openMix(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MixesPanel::mixerlistWidget_customContextMenuRequested(QPoint pos)
|
||||||
|
{
|
||||||
|
QPoint globalPos = MixerlistWidget->mapToGlobal(pos);
|
||||||
|
|
||||||
|
const QClipboard *clipboard = QApplication::clipboard();
|
||||||
|
const QMimeData *mimeData = clipboard->mimeData();
|
||||||
|
bool hasData = mimeData->hasFormat("application/x-companion9x-mix");
|
||||||
|
|
||||||
|
QMenu contextMenu;
|
||||||
|
contextMenu.addAction(QIcon(":/images/add.png"), tr("&Add"),this,SLOT(mixerAdd()),tr("Ctrl+A"));
|
||||||
|
contextMenu.addAction(QIcon(":/images/edit.png"), tr("&Edit"),this,SLOT(mixerOpen()),tr("Enter"));
|
||||||
|
contextMenu.addSeparator();
|
||||||
|
contextMenu.addAction(QIcon(":/images/clear.png"), tr("&Delete"),this,SLOT(mixersDelete()),tr("Delete"));
|
||||||
|
contextMenu.addAction(QIcon(":/images/copy.png"), tr("&Copy"),this,SLOT(mixersCopy()),tr("Ctrl+C"));
|
||||||
|
contextMenu.addAction(QIcon(":/images/cut.png"), tr("&Cut"),this,SLOT(mixersCut()),tr("Ctrl+X"));
|
||||||
|
contextMenu.addAction(QIcon(":/images/paste.png"), tr("&Paste"),this,SLOT(mixersPaste()),tr("Ctrl+V"))->setEnabled(hasData);
|
||||||
|
contextMenu.addAction(QIcon(":/images/duplicate.png"), tr("Du&plicate"),this,SLOT(mixersDuplicate()),tr("Ctrl+U"));
|
||||||
|
contextMenu.addSeparator();
|
||||||
|
contextMenu.addAction(QIcon(":/images/moveup.png"), tr("Move Up"),this,SLOT(moveMixUp()),tr("Ctrl+Up"));
|
||||||
|
contextMenu.addAction(QIcon(":/images/movedown.png"), tr("Move Down"),this,SLOT(moveMixDown()),tr("Ctrl+Down"));
|
||||||
|
|
||||||
|
contextMenu.exec(globalPos);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MixesPanel::mimeMixerDropped(int index, const QMimeData *data, Qt::DropAction /*action*/)
|
||||||
|
{
|
||||||
|
int idx= MixerlistWidget->item(index > 0 ? index-1 : 0)->data(Qt::UserRole).toByteArray().at(0);
|
||||||
|
pasteMixerMimeData(data, idx);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MixesPanel::mixesEdited()
|
||||||
|
{
|
||||||
|
emit modified();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MixesPanel::mixerlistWidget_KeyPress(QKeyEvent *event)
|
||||||
|
{
|
||||||
|
if(event->matches(QKeySequence::SelectAll)) mixerAdd(); //Ctrl A
|
||||||
|
if(event->matches(QKeySequence::Delete)) mixersDelete();
|
||||||
|
if(event->matches(QKeySequence::Copy)) mixersCopy();
|
||||||
|
if(event->matches(QKeySequence::Cut)) mixersCut();
|
||||||
|
if(event->matches(QKeySequence::Paste)) mixersPaste();
|
||||||
|
if(event->matches(QKeySequence::Underline)) mixersDuplicate();
|
||||||
|
|
||||||
|
if(event->key()==Qt::Key_Return || event->key()==Qt::Key_Enter) mixerOpen();
|
||||||
|
if(event->matches(QKeySequence::MoveToNextLine))
|
||||||
|
MixerlistWidget->setCurrentRow(MixerlistWidget->currentRow()+1);
|
||||||
|
if(event->matches(QKeySequence::MoveToPreviousLine))
|
||||||
|
MixerlistWidget->setCurrentRow(MixerlistWidget->currentRow()-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int MixesPanel::gm_moveMix(int idx, bool dir) //true=inc=down false=dec=up
|
||||||
|
{
|
||||||
|
if(idx>GetEepromInterface()->getCapability(Mixes) || (idx==0 && !dir) || (idx==GetEepromInterface()->getCapability(Mixes) && dir)) return idx;
|
||||||
|
|
||||||
|
int tdx = dir ? idx+1 : idx-1;
|
||||||
|
MixData &src=model.mixData[idx];
|
||||||
|
MixData &tgt=model.mixData[tdx];
|
||||||
|
|
||||||
|
unsigned int outputs = GetEepromInterface()->getCapability(Outputs);
|
||||||
|
if((src.destCh==0) || (src.destCh>outputs) || (tgt.destCh>outputs)) return idx;
|
||||||
|
|
||||||
|
if (tgt.destCh!=src.destCh) {
|
||||||
|
if ((dir) && (src.destCh<outputs)) src.destCh++;
|
||||||
|
if ((!dir) && (src.destCh>0)) src.destCh--;
|
||||||
|
return idx;
|
||||||
|
}
|
||||||
|
|
||||||
|
//flip between idx and tgt
|
||||||
|
MixData temp;
|
||||||
|
memcpy(&temp,&src,sizeof(MixData));
|
||||||
|
memcpy(&src,&tgt,sizeof(MixData));
|
||||||
|
memcpy(&tgt,&temp,sizeof(MixData));
|
||||||
|
return tdx;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MixesPanel::moveMixUp()
|
||||||
|
{
|
||||||
|
QList<int> list = createMixListFromSelected();
|
||||||
|
QList<int> highlightList;
|
||||||
|
foreach(int idx, list) {
|
||||||
|
highlightList << gm_moveMix(idx, false);
|
||||||
|
}
|
||||||
|
emit modified();
|
||||||
|
update();
|
||||||
|
setSelectedByMixList(highlightList);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MixesPanel::moveMixDown()
|
||||||
|
{
|
||||||
|
QList<int> list = createMixListFromSelected();
|
||||||
|
QList<int> highlightList;
|
||||||
|
foreach(int idx, list) {
|
||||||
|
highlightList << gm_moveMix(idx, true);
|
||||||
|
}
|
||||||
|
emit modified();
|
||||||
|
update();
|
||||||
|
setSelectedByMixList(highlightList);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MixesPanel::clearMixes()
|
||||||
|
{
|
||||||
|
if (QMessageBox::question(this, tr("Clear Mixes?"), tr("Really clear all the mixes?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
|
||||||
|
model.clearMixes();
|
||||||
|
emit modified();
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
}
|
56
companion/src/modeledit/mixes.h
Normal file
56
companion/src/modeledit/mixes.h
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
#ifndef MIXES_H
|
||||||
|
#define MIXES_H
|
||||||
|
|
||||||
|
#include "modelpanel.h"
|
||||||
|
#include "mixerslist.h"
|
||||||
|
#include "mixerdialog.h"
|
||||||
|
|
||||||
|
class MixesPanel : public ModelPanel
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
MixesPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings);
|
||||||
|
virtual ~MixesPanel();
|
||||||
|
|
||||||
|
virtual void update();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
// TODO all slots?
|
||||||
|
void clearMixes();
|
||||||
|
void mixersDelete(bool ask=true);
|
||||||
|
void mixersCut();
|
||||||
|
void mixersCopy();
|
||||||
|
void mixersPaste();
|
||||||
|
void mixersDuplicate();
|
||||||
|
void mixerOpen();
|
||||||
|
void mixerAdd();
|
||||||
|
void moveMixUp();
|
||||||
|
void moveMixDown();
|
||||||
|
|
||||||
|
void mixerlistWidget_customContextMenuRequested(QPoint pos);
|
||||||
|
void mixerlistWidget_doubleClicked(QModelIndex index);
|
||||||
|
void mixerlistWidget_KeyPress(QKeyEvent *event);
|
||||||
|
|
||||||
|
void mimeMixerDropped(int index, const QMimeData *data, Qt::DropAction action);
|
||||||
|
void pasteMixerMimeData(const QMimeData * mimeData, int destIdx);
|
||||||
|
|
||||||
|
void mixesEdited();
|
||||||
|
|
||||||
|
private:
|
||||||
|
GeneralSettings & generalSettings;
|
||||||
|
MixersList *MixerlistWidget;
|
||||||
|
bool mixInserted;
|
||||||
|
|
||||||
|
int getMixerIndex(unsigned int dch);
|
||||||
|
bool gm_insertMix(int idx);
|
||||||
|
void gm_deleteMix(int index);
|
||||||
|
void gm_openMix(int index);
|
||||||
|
int gm_moveMix(int idx, bool dir);
|
||||||
|
void mixersDeleteList(QList<int> list);
|
||||||
|
QList<int> createMixListFromSelected();
|
||||||
|
void setSelectedByMixList(QList<int> list);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // MIXES_H
|
130
companion/src/modeledit/modeledit.cpp
Normal file
130
companion/src/modeledit/modeledit.cpp
Normal file
|
@ -0,0 +1,130 @@
|
||||||
|
#include "modeledit.h"
|
||||||
|
#include "ui_modeledit.h"
|
||||||
|
#include "setup.h"
|
||||||
|
#include "heli.h"
|
||||||
|
#include "flightmodes.h"
|
||||||
|
#include "inputs.h"
|
||||||
|
#include "mixes.h"
|
||||||
|
#include "channels.h"
|
||||||
|
#include "curves.h"
|
||||||
|
#include "customswitches.h"
|
||||||
|
#include "customfunctions.h"
|
||||||
|
#include "telemetry.h"
|
||||||
|
#include <QScrollArea>
|
||||||
|
|
||||||
|
ModelEdit::ModelEdit(RadioData & radioData, int modelId, bool openWizard, bool isNew, QWidget *parent) :
|
||||||
|
QDialog(parent),
|
||||||
|
ui(new Ui::ModelEdit),
|
||||||
|
modelId(modelId),
|
||||||
|
model(radioData.models[modelId]),
|
||||||
|
generalSettings(generalSettings)
|
||||||
|
{
|
||||||
|
ui->setupUi(this);
|
||||||
|
addTab(new Setup(this, model), tr("Setup"));
|
||||||
|
addTab(new HeliPanel(this, model), tr("Heli"));
|
||||||
|
addTab(new FlightModes(this, model, radioData.generalSettings), tr("Flight Modes"));
|
||||||
|
addTab(new InputsPanel(this, model, radioData.generalSettings), tr("Inputs"));
|
||||||
|
addTab(new MixesPanel(this, model, radioData.generalSettings), tr("Mixes"));
|
||||||
|
addTab(new Channels(this, model), tr("Channels"));
|
||||||
|
addTab(new CustomSwitchesPanel(this, model), tr("Custom Switches"));
|
||||||
|
if (GetEepromInterface()->getCapability(CustomFunctions))
|
||||||
|
addTab(new CustomFunctionsPanel(this, model, radioData.generalSettings), tr("Assignable Functions"));
|
||||||
|
addTab(new Curves(this, model), tr("Curves"));
|
||||||
|
// TODO remove this capability if (!GetEepromInterface()->getCapability(FSSwitch))
|
||||||
|
if (GetEepromInterface()->getCapability(Telemetry) & TM_HASTELEMETRY)
|
||||||
|
addTab(new TelemetryPanel(this, model), tr("Telemetry"));
|
||||||
|
}
|
||||||
|
|
||||||
|
ModelEdit::~ModelEdit()
|
||||||
|
{
|
||||||
|
delete ui;
|
||||||
|
}
|
||||||
|
|
||||||
|
class VerticalScrollArea : public QScrollArea
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
VerticalScrollArea(QWidget * parent, ModelPanel * panel);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual bool eventFilter(QObject *o, QEvent *e);
|
||||||
|
|
||||||
|
private:
|
||||||
|
ModelPanel * panel;
|
||||||
|
QWidget * parent;
|
||||||
|
};
|
||||||
|
|
||||||
|
VerticalScrollArea::VerticalScrollArea(QWidget * parent, ModelPanel * panel):
|
||||||
|
QScrollArea(parent),
|
||||||
|
panel(panel),
|
||||||
|
parent(parent)
|
||||||
|
{
|
||||||
|
setWidgetResizable(true);
|
||||||
|
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||||
|
setWidget(panel);
|
||||||
|
panel->installEventFilter(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool VerticalScrollArea::eventFilter(QObject *o, QEvent *e)
|
||||||
|
{
|
||||||
|
if (o == panel && e->type() == QEvent::Resize) {
|
||||||
|
setMinimumWidth(panel->minimumSizeHint().width() + verticalScrollBar()->width());
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ModelEdit::addTab(ModelPanel *panel, QString text)
|
||||||
|
{
|
||||||
|
panels << panel;
|
||||||
|
QWidget * widget = new QWidget(ui->tabWidget);
|
||||||
|
QVBoxLayout *baseLayout = new QVBoxLayout(widget);
|
||||||
|
VerticalScrollArea * area = new VerticalScrollArea(widget, panel);
|
||||||
|
baseLayout->addWidget(area);
|
||||||
|
ui->tabWidget->addTab(widget, text);
|
||||||
|
connect(panel, SIGNAL(modified()), this, SLOT(onTabModified()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void ModelEdit::onTabModified()
|
||||||
|
{
|
||||||
|
emit modified();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ModelEdit::on_tabWidget_currentChanged(int index)
|
||||||
|
{
|
||||||
|
panels[index]->update();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ModelEdit::on_pushButton_clicked()
|
||||||
|
{
|
||||||
|
launchSimulation();
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO merge both
|
||||||
|
#include "simulatordialog.h"
|
||||||
|
#include "xsimulatordialog.h"
|
||||||
|
|
||||||
|
void ModelEdit::launchSimulation()
|
||||||
|
{
|
||||||
|
if (GetEepromInterface()->getSimulator()) {
|
||||||
|
RadioData *simuData = new RadioData();
|
||||||
|
simuData->generalSettings = generalSettings;
|
||||||
|
simuData->models[modelId] = model;
|
||||||
|
if (GetEepromInterface()->getCapability(SimulatorType)) {
|
||||||
|
xsimulatorDialog sd(this);
|
||||||
|
sd.loadParams(*simuData, modelId);
|
||||||
|
sd.exec();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
simulatorDialog sd(this);
|
||||||
|
sd.loadParams(*simuData, modelId);
|
||||||
|
sd.exec();
|
||||||
|
}
|
||||||
|
delete simuData;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
QMessageBox::warning(NULL,
|
||||||
|
QObject::tr("Warning"),
|
||||||
|
QObject::tr("Simulator for this firmware is not yet available"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
39
companion/src/modeledit/modeledit.h
Normal file
39
companion/src/modeledit/modeledit.h
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
#ifndef MODELEDIT_H
|
||||||
|
#define MODELEDIT_H
|
||||||
|
|
||||||
|
#include <QDialog>
|
||||||
|
#include "modelpanel.h"
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
class ModelEdit;
|
||||||
|
}
|
||||||
|
|
||||||
|
class ModelEdit : public QDialog
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit ModelEdit(RadioData & radioData, int modelId , bool openWizard =false, bool inNew =false, QWidget *parent = 0);
|
||||||
|
~ModelEdit();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void modified();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void onTabModified();
|
||||||
|
void on_pushButton_clicked();
|
||||||
|
void on_tabWidget_currentChanged(int index);
|
||||||
|
|
||||||
|
private:
|
||||||
|
Ui::ModelEdit *ui;
|
||||||
|
int modelId;
|
||||||
|
ModelData & model;
|
||||||
|
GeneralSettings & generalSettings;
|
||||||
|
QVector<ModelPanel *> panels;
|
||||||
|
|
||||||
|
void addTab(ModelPanel *panel, QString text);
|
||||||
|
void launchSimulation();
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // MODELEDIT_H
|
67
companion/src/modeledit/modeledit.ui
Normal file
67
companion/src/modeledit/modeledit.ui
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>ModelEdit</class>
|
||||||
|
<widget class="QDialog" name="ModelEdit">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>339</width>
|
||||||
|
<height>385</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Dialog</string>
|
||||||
|
</property>
|
||||||
|
<property name="windowIcon">
|
||||||
|
<iconset resource="../companion9x.qrc">
|
||||||
|
<normaloff>:/icon.png</normaloff>:/icon.png</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="sizeGripEnabled">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||||
|
<item>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<property name="sizeConstraint">
|
||||||
|
<enum>QLayout::SetMinimumSize</enum>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QTabWidget" name="tabWidget">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="tabPosition">
|
||||||
|
<enum>QTabWidget::North</enum>
|
||||||
|
</property>
|
||||||
|
<property name="currentIndex">
|
||||||
|
<number>-1</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="pushButton">
|
||||||
|
<property name="text">
|
||||||
|
<string>Simulate</string>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="../companion9x.qrc">
|
||||||
|
<normaloff>:/images/simulate.png</normaloff>:/images/simulate.png</iconset>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources>
|
||||||
|
<include location="../companion9x.qrc"/>
|
||||||
|
</resources>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
30
companion/src/modeledit/modelpanel.cpp
Normal file
30
companion/src/modeledit/modelpanel.cpp
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
#include "modelpanel.h"
|
||||||
|
#include <QLabel>
|
||||||
|
|
||||||
|
ModelPanel::ModelPanel(QWidget * parent, ModelData & model):
|
||||||
|
QWidget(parent),
|
||||||
|
model(model),
|
||||||
|
lock(false)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
ModelPanel::~ModelPanel()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void ModelPanel::update()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void ModelPanel::addLabel(QGridLayout * gridLayout, QString text, int col)
|
||||||
|
{
|
||||||
|
QLabel *label = new QLabel(this);
|
||||||
|
label->setFrameShape(QFrame::Panel);
|
||||||
|
label->setFrameShadow(QFrame::Raised);
|
||||||
|
label->setMidLineWidth(0);
|
||||||
|
label->setAlignment(Qt::AlignCenter);
|
||||||
|
label->setMargin(3);
|
||||||
|
label->setText(text);
|
||||||
|
gridLayout->addWidget(label, 0, col, 1, 1);
|
||||||
|
}
|
||||||
|
|
29
companion/src/modeledit/modelpanel.h
Normal file
29
companion/src/modeledit/modelpanel.h
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
#ifndef MODELPANEL_H
|
||||||
|
#define MODELPANEL_H
|
||||||
|
|
||||||
|
#include <QWidget>
|
||||||
|
#include <QGridLayout>
|
||||||
|
#include "eeprominterface.h"
|
||||||
|
|
||||||
|
class ModelPanel : public QWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
ModelPanel(QWidget *parent, ModelData & model);
|
||||||
|
virtual ~ModelPanel();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void modified();
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
virtual void update();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
ModelData & model;
|
||||||
|
bool lock;
|
||||||
|
void addLabel(QGridLayout * gridLayout, QString text, int col);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // CHANNELS_H
|
|
@ -46,26 +46,22 @@
|
||||||
|
|
||||||
#include "edge.h"
|
#include "edge.h"
|
||||||
#include "node.h"
|
#include "node.h"
|
||||||
#include "modeledit.h"
|
|
||||||
|
|
||||||
Node::Node(QSpinBox *sb,QSpinBox *sbx)
|
Node::Node():
|
||||||
|
minX(-100),
|
||||||
|
maxX(+100)
|
||||||
{
|
{
|
||||||
setFlag(ItemIsMovable);
|
setFlag(ItemIsMovable);
|
||||||
setFlag(ItemSendsGeometryChanges);
|
setFlag(ItemSendsGeometryChanges);
|
||||||
setCacheMode(DeviceCoordinateCache);
|
setCacheMode(DeviceCoordinateCache);
|
||||||
setZValue(-1);
|
setZValue(-1);
|
||||||
nodecolor = QColor(Qt::yellow);
|
nodecolor = QColor(Qt::yellow);
|
||||||
qsb = sb;
|
|
||||||
qsbx = sbx;
|
|
||||||
bPressed = false;
|
bPressed = false;
|
||||||
centerX = true;
|
centerX = true;
|
||||||
centerY = true;
|
centerY = true;
|
||||||
fixedX = false;
|
fixedX = false;
|
||||||
fixedY = false;
|
fixedY = false;
|
||||||
ballSize = DEFAULT_BALL_SIZE;
|
ballSize = DEFAULT_BALL_SIZE;
|
||||||
minX=-100;
|
|
||||||
maxX=100;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Node::addEdge(Edge *edge)
|
void Node::addEdge(Edge *edge)
|
||||||
|
@ -105,7 +101,7 @@ void Node::stepToCenter(qreal step)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Node::setColor(QColor color)
|
void Node::setColor(const QColor & color)
|
||||||
{
|
{
|
||||||
nodecolor=color;
|
nodecolor=color;
|
||||||
}
|
}
|
||||||
|
@ -190,24 +186,21 @@ QVariant Node::itemChange(GraphicsItemChange change, const QVariant &value)
|
||||||
if(fixedY) newPos.setY(y());//make sure x doesn't change
|
if(fixedY) newPos.setY(y());//make sure x doesn't change
|
||||||
newPos.setX(qMin(rect.right(), qMax(newPos.x(), rect.left())));// bound X
|
newPos.setX(qMin(rect.right(), qMax(newPos.x(), rect.left())));// bound X
|
||||||
newPos.setY(qMin(rect.bottom(), qMax(newPos.y(), rect.top())));// bound Y
|
newPos.setY(qMin(rect.bottom(), qMax(newPos.y(), rect.top())));// bound Y
|
||||||
if (qsb) {
|
|
||||||
ModelEdit* modeledit = qobject_cast<ModelEdit*>(qsb->parent()->parent()->parent()->parent()->parent()->parent()->parent());
|
|
||||||
modeledit->redrawCurve = false;
|
|
||||||
qsb->setValue(100+(rect.top()-y())*200/rect.height());
|
|
||||||
if (qsbx && !getFixedX()) {
|
|
||||||
int newX = -100 + ( (newPos.x()-rect.left()) * 200) / rect.width();
|
int newX = -100 + ( (newPos.x()-rect.left()) * 200) / rect.width();
|
||||||
|
int newY = 100+(rect.top()-y())*200/rect.height();
|
||||||
if (newX < minX) newX = minX;
|
if (newX < minX) newX = minX;
|
||||||
if (newX > maxX) newX = maxX;
|
if (newX > maxX) newX = maxX;
|
||||||
|
|
||||||
|
if (!getFixedX()) {
|
||||||
newPos.setX(((newX+100)*rect.width()/200+rect.left()));
|
newPos.setX(((newX+100)*rect.width()/200+rect.left()));
|
||||||
qsbx->setValue(newX);
|
|
||||||
}
|
|
||||||
modeledit->redrawCurve = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
emit moved(newX, newY);
|
||||||
return newPos;
|
return newPos;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ItemPositionHasChanged:
|
case ItemPositionHasChanged:
|
||||||
|
|
||||||
foreach (Edge *edge, edgeList)
|
foreach (Edge *edge, edgeList)
|
||||||
edge->adjust();
|
edge->adjust();
|
||||||
break;
|
break;
|
||||||
|
@ -222,8 +215,8 @@ void Node::mousePressEvent(QGraphicsSceneMouseEvent *event)
|
||||||
{
|
{
|
||||||
update();
|
update();
|
||||||
bPressed = true;
|
bPressed = true;
|
||||||
if(qsb) qsb->setFocus();
|
|
||||||
QGraphicsItem::mousePressEvent(event);
|
QGraphicsItem::mousePressEvent(event);
|
||||||
|
emit focus();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Node::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
|
void Node::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
|
||||||
|
@ -231,16 +224,10 @@ void Node::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
|
||||||
update();
|
update();
|
||||||
bPressed = false;
|
bPressed = false;
|
||||||
if (scene()) {
|
if (scene()) {
|
||||||
if(qsb) {
|
|
||||||
qsb->clearFocus();
|
|
||||||
ModelEdit* modeledit = qobject_cast<ModelEdit*>(qsb->parent()->parent()->parent()->parent()->parent()->parent()->parent());
|
|
||||||
QGraphicsItem::mouseReleaseEvent(event);
|
|
||||||
modeledit->drawCurve();
|
|
||||||
} else {
|
|
||||||
QGraphicsItem::mouseReleaseEvent(event);
|
QGraphicsItem::mouseReleaseEvent(event);
|
||||||
|
emit unfocus();
|
||||||
}
|
}
|
||||||
//need to tell SB that it needs to write the value
|
else {
|
||||||
} else {
|
|
||||||
QGraphicsItem::mouseReleaseEvent(event);
|
QGraphicsItem::mouseReleaseEvent(event);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -52,11 +52,12 @@ QT_BEGIN_NAMESPACE
|
||||||
class QGraphicsSceneMouseEvent;
|
class QGraphicsSceneMouseEvent;
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
class Node : public QGraphicsItem
|
class Node : public QGraphicsObject
|
||||||
{
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Node(QSpinBox *sb = 0, QSpinBox *sbx = 0);
|
Node();
|
||||||
|
|
||||||
void addEdge(Edge *edge);
|
void addEdge(Edge *edge);
|
||||||
QList<Edge *> edges() const;
|
QList<Edge *> edges() const;
|
||||||
|
@ -80,16 +81,19 @@ public:
|
||||||
bool getFixedY() {return fixedY;}
|
bool getFixedY() {return fixedY;}
|
||||||
void setMinX(int val) {minX = val;};
|
void setMinX(int val) {minX = val;};
|
||||||
void setMaxX(int val) {maxX = val;};
|
void setMaxX(int val) {maxX = val;};
|
||||||
void setColor(QColor color);
|
void setColor(const QColor & color);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void moved(int x, int y);
|
||||||
|
void focus();
|
||||||
|
void unfocus();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
QVariant itemChange(GraphicsItemChange change, const QVariant &value);
|
QVariant itemChange(GraphicsItemChange change, const QVariant &value);
|
||||||
|
|
||||||
void mousePressEvent(QGraphicsSceneMouseEvent *event);
|
void mousePressEvent(QGraphicsSceneMouseEvent *event);
|
||||||
void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
|
void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
bool bPressed;
|
bool bPressed;
|
||||||
bool centerX;
|
bool centerX;
|
||||||
bool centerY;
|
bool centerY;
|
||||||
|
@ -98,8 +102,6 @@ private:
|
||||||
int ballSize;
|
int ballSize;
|
||||||
int minX;
|
int minX;
|
||||||
int maxX;
|
int maxX;
|
||||||
QSpinBox *qsb;
|
|
||||||
QSpinBox *qsbx;
|
|
||||||
QList<Edge *> edgeList;
|
QList<Edge *> edgeList;
|
||||||
QPointF newPos;
|
QPointF newPos;
|
||||||
QColor nodecolor;
|
QColor nodecolor;
|
1492
companion/src/modeledit/setup.cpp
Normal file
1492
companion/src/modeledit/setup.cpp
Normal file
File diff suppressed because it is too large
Load diff
96
companion/src/modeledit/setup.h
Normal file
96
companion/src/modeledit/setup.h
Normal file
|
@ -0,0 +1,96 @@
|
||||||
|
#ifndef SETUP_H
|
||||||
|
#define SETUP_H
|
||||||
|
|
||||||
|
#include "modelpanel.h"
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
class Setup;
|
||||||
|
}
|
||||||
|
|
||||||
|
class Setup : public ModelPanel
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
Setup(QWidget *parent, ModelData & model);
|
||||||
|
virtual ~Setup();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void on_protocolCB_currentIndexChanged(int index);
|
||||||
|
void on_protocolCB_2_currentIndexChanged(int index);
|
||||||
|
void on_protocolCB_3_currentIndexChanged(int index);
|
||||||
|
void on_fsm1CB_currentIndexChanged(int index);
|
||||||
|
void on_fsm2CB_currentIndexChanged(int index);
|
||||||
|
void on_modelVoice_SB_editingFinished();
|
||||||
|
void on_T2ThrTrgChkB_toggled(bool checked);
|
||||||
|
void on_ttraceCB_currentIndexChanged(int index);
|
||||||
|
void on_instantTrim_CB_currentIndexChanged(int index);
|
||||||
|
void on_thrExpoChkB_toggled(bool checked);
|
||||||
|
void on_thrTrimChkB_toggled(bool checked);
|
||||||
|
void on_extendedLimitsChkB_toggled(bool checked);
|
||||||
|
void on_extendedTrimsChkB_toggled(bool checked);
|
||||||
|
void on_thrwarnChkB_toggled(bool checked);
|
||||||
|
void on_thrrevChkB_toggled(bool checked);
|
||||||
|
void on_timer1Perm_toggled(bool checked);
|
||||||
|
void on_timer2Perm_toggled(bool checked);
|
||||||
|
void on_timer1Minute_toggled(bool checked);
|
||||||
|
void on_timer2Minute_toggled(bool checked);
|
||||||
|
void on_timer1CountDownBeep_toggled(bool checked);
|
||||||
|
void on_timer2CountDownBeep_toggled(bool checked);
|
||||||
|
void fssldEdited();
|
||||||
|
void fssbEdited();
|
||||||
|
void fssldValueChanged();
|
||||||
|
void fssbValueChanged();
|
||||||
|
void on_ppmDelaySB_editingFinished();
|
||||||
|
void on_ppmDelaySB_2_editingFinished();
|
||||||
|
void on_ppmDelaySB_3_editingFinished();
|
||||||
|
void on_numChannelsSB_editingFinished();
|
||||||
|
void on_numChannelsSB_2_editingFinished();
|
||||||
|
void on_numChannelsSB_3_editingFinished();
|
||||||
|
void on_numChannelsStart_editingFinished();
|
||||||
|
void on_numChannelsStart_2_editingFinished();
|
||||||
|
void on_numChannelsStart_3_editingFinished();
|
||||||
|
// void void ModelEdit::on_numChannelsStart_3_editingFinished();
|
||||||
|
void on_pulsePolCB_currentIndexChanged(int index);
|
||||||
|
void on_pulsePolCB_2_currentIndexChanged(int index);
|
||||||
|
void on_pulsePolCB_3_currentIndexChanged(int index);
|
||||||
|
void on_ppmFrameLengthDSB_editingFinished();
|
||||||
|
void on_ppmFrameLengthDSB_2_editingFinished();
|
||||||
|
void on_ppmFrameLengthDSB_3_editingFinished();
|
||||||
|
void on_DSM_Type_currentIndexChanged(int index);
|
||||||
|
void on_DSM_Type_2_currentIndexChanged(int index);
|
||||||
|
void on_pxxRxNum_editingFinished();
|
||||||
|
void on_pxxRxNum_2_editingFinished();
|
||||||
|
|
||||||
|
// TODO void on_trimSWCB_currentIndexChanged(int index);
|
||||||
|
void on_trimIncCB_currentIndexChanged(int index);
|
||||||
|
void on_timer1DirCB_currentIndexChanged(int index);
|
||||||
|
void on_timer1ModeCB_currentIndexChanged(int index);
|
||||||
|
void on_timer1ValTE_editingFinished();
|
||||||
|
void on_timer1ModeBCB_currentIndexChanged(int index);
|
||||||
|
void on_timer2DirCB_currentIndexChanged(int index);
|
||||||
|
void on_timer2ModeCB_currentIndexChanged(int index);
|
||||||
|
void on_timer2ValTE_editingFinished();
|
||||||
|
void on_timer2ModeBCB_currentIndexChanged(int index);
|
||||||
|
void on_modelNameLE_editingFinished();
|
||||||
|
void on_modelImage_CB_currentIndexChanged(int index);
|
||||||
|
|
||||||
|
void on_bcRUDChkB_toggled(bool checked);
|
||||||
|
void on_bcELEChkB_toggled(bool checked);
|
||||||
|
void on_bcTHRChkB_toggled(bool checked);
|
||||||
|
void on_bcAILChkB_toggled(bool checked);
|
||||||
|
void on_bcP1ChkB_toggled(bool checked);
|
||||||
|
void on_bcP2ChkB_toggled(bool checked);
|
||||||
|
void on_bcP3ChkB_toggled(bool checked);
|
||||||
|
void on_bcP4ChkB_toggled(bool checked);
|
||||||
|
void on_bcREaChkB_toggled(bool checked);
|
||||||
|
void on_bcREbChkB_toggled(bool checked);
|
||||||
|
|
||||||
|
void startupSwitchEdited();
|
||||||
|
|
||||||
|
private:
|
||||||
|
Ui::Setup *ui;
|
||||||
|
void tabModelEditSetup();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // SETUP_H
|
3759
companion/src/modeledit/setup.ui
Normal file
3759
companion/src/modeledit/setup.ui
Normal file
File diff suppressed because it is too large
Load diff
939
companion/src/modeledit/telemetry.cpp
Normal file
939
companion/src/modeledit/telemetry.cpp
Normal file
|
@ -0,0 +1,939 @@
|
||||||
|
#include "telemetry.h"
|
||||||
|
#include "ui_telemetry.h"
|
||||||
|
#include "ui_telemetry_analog.h"
|
||||||
|
#include "helpers.h"
|
||||||
|
|
||||||
|
TelemetryAnalog::TelemetryAnalog(QWidget *parent, FrSkyChannelData & analog):
|
||||||
|
QWidget(parent),
|
||||||
|
ui(new Ui::TelemetryAnalog),
|
||||||
|
analog(analog),
|
||||||
|
lock(false)
|
||||||
|
{
|
||||||
|
ui->setupUi(this);
|
||||||
|
|
||||||
|
float ratio;
|
||||||
|
|
||||||
|
if (analog.type==0 || analog.type==1 || analog.type==2) {
|
||||||
|
ratio = (analog.ratio<<analog.multiplier)/10.0;
|
||||||
|
ui->RatioSB->setDecimals(1);
|
||||||
|
ui->RatioSB->setMaximum(25.5*GetEepromInterface()->getCapability(TelemetryMaxMultiplier));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ratio = analog.ratio<<analog.multiplier;
|
||||||
|
ui->RatioSB->setDecimals(0);
|
||||||
|
ui->RatioSB->setMaximum(255*GetEepromInterface()->getCapability(TelemetryMaxMultiplier));
|
||||||
|
}
|
||||||
|
ui->RatioSB->setValue(ratio);
|
||||||
|
|
||||||
|
update();
|
||||||
|
|
||||||
|
ui->UnitCB->setCurrentIndex(analog.type);
|
||||||
|
ui->alarm1LevelCB->setCurrentIndex(analog.alarms[0].level);
|
||||||
|
ui->alarm1GreaterCB->setCurrentIndex(analog.alarms[0].greater);
|
||||||
|
ui->alarm2LevelCB->setCurrentIndex(analog.alarms[1].level);
|
||||||
|
ui->alarm2GreaterCB->setCurrentIndex(analog.alarms[1].greater);
|
||||||
|
|
||||||
|
if (!(GetEepromInterface()->getCapability(Telemetry) & TM_HASOFFSET)) {
|
||||||
|
ui->CalibSB->hide();
|
||||||
|
ui->CalibLabel->hide();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ui->label_Max->setText(tr("Range"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TelemetryAnalog::update()
|
||||||
|
{
|
||||||
|
float ratio, alarm1value, alarm2value;
|
||||||
|
if (analog.ratio==0) {
|
||||||
|
ui->alarm1ValueSB->setMinimum(0);
|
||||||
|
ui->alarm1ValueSB->setMaximum(0);
|
||||||
|
ui->alarm2ValueSB->setMinimum(0);
|
||||||
|
ui->alarm2ValueSB->setMaximum(0);
|
||||||
|
ui->CalibSB->setMinimum(0);
|
||||||
|
ui->CalibSB->setMaximum(0);
|
||||||
|
ui->CalibSB->setValue(0);
|
||||||
|
ui->alarm1ValueSB->setValue(0);
|
||||||
|
ui->alarm2ValueSB->setValue(0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (analog.type==0 || analog.type==1 || analog.type==2) {
|
||||||
|
ratio=(analog.ratio<<analog.multiplier)/10.0;
|
||||||
|
ui->alarm1ValueSB->setDecimals(2);
|
||||||
|
ui->alarm1ValueSB->setSingleStep(ratio/255.0);
|
||||||
|
ui->alarm2ValueSB->setDecimals(2);
|
||||||
|
ui->alarm2ValueSB->setSingleStep(ratio/255.0);
|
||||||
|
ui->alarm1ValueSB->setMinimum((analog.ratio*1.0*analog.offset)/2550.0);
|
||||||
|
ui->alarm1ValueSB->setMaximum(ratio+(analog.ratio*1.0*analog.offset)/2550.0);
|
||||||
|
ui->alarm2ValueSB->setMinimum((analog.offset*1.0*analog.ratio)/2550.0);
|
||||||
|
ui->alarm2ValueSB->setMaximum(ratio+(analog.offset*1.0*analog.ratio)/2550.0);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ratio=analog.ratio<<analog.multiplier;
|
||||||
|
ui->alarm1ValueSB->setDecimals(2);
|
||||||
|
ui->alarm1ValueSB->setSingleStep(ratio/255.0);
|
||||||
|
ui->alarm2ValueSB->setDecimals(2);
|
||||||
|
ui->alarm2ValueSB->setSingleStep(ratio/255.0);
|
||||||
|
ui->alarm1ValueSB->setMinimum((analog.offset*1.0*analog.ratio)/255.0);
|
||||||
|
ui->alarm1ValueSB->setMaximum(ratio+(analog.offset*1.0*analog.ratio)/255.0);
|
||||||
|
ui->alarm2ValueSB->setMinimum((analog.offset*1.0*analog.ratio)/255.0);
|
||||||
|
ui->alarm2ValueSB->setMaximum(ratio+(analog.offset*1.0*analog.ratio)/255.0);
|
||||||
|
}
|
||||||
|
ui->CalibSB->setDecimals(2);
|
||||||
|
ui->CalibSB->setMaximum((ratio*127)/255.0);
|
||||||
|
ui->CalibSB->setMinimum((-ratio*128)/255.0);
|
||||||
|
ui->CalibSB->setSingleStep(ratio/255.0);
|
||||||
|
ui->CalibSB->setValue((analog.offset*ratio)/255);
|
||||||
|
alarm1value=ratio*(analog.alarms[0].value/255.0+analog.offset/255.0);
|
||||||
|
alarm2value=ratio*(analog.alarms[1].value/255.0+analog.offset/255.0);;
|
||||||
|
ui->alarm1ValueSB->setValue(alarm1value);
|
||||||
|
ui->alarm2ValueSB->setValue(alarm2value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TelemetryAnalog::on_UnitCB_currentIndexChanged(int index)
|
||||||
|
{
|
||||||
|
float ratio;
|
||||||
|
analog.type=index;
|
||||||
|
switch (index) {
|
||||||
|
case 0:
|
||||||
|
case 1:
|
||||||
|
case 2:
|
||||||
|
ui->RatioSB->setDecimals(1);
|
||||||
|
ui->RatioSB->setMaximum(25.5*GetEepromInterface()->getCapability(TelemetryMaxMultiplier));
|
||||||
|
ratio=(analog.ratio<<analog.multiplier)/10.0;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ui->RatioSB->setDecimals(0);
|
||||||
|
ui->RatioSB->setMaximum(255*GetEepromInterface()->getCapability(TelemetryMaxMultiplier));
|
||||||
|
ratio=(analog.ratio<<analog.multiplier);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
ui->RatioSB->setValue(ratio);
|
||||||
|
update();
|
||||||
|
emit modified();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TelemetryAnalog::on_RatioSB_valueChanged()
|
||||||
|
{
|
||||||
|
if (!lock) {
|
||||||
|
if (analog.type==0 || analog.type==1 || analog.type==2) {
|
||||||
|
analog.multiplier = findmult(ui->RatioSB->value(), 25.5);
|
||||||
|
float singlestep =(1<<analog.multiplier)/10.0;
|
||||||
|
lock=true;
|
||||||
|
ui->RatioSB->setSingleStep(singlestep);
|
||||||
|
ui->RatioSB->setValue(round(ui->RatioSB->value()/singlestep)*singlestep);
|
||||||
|
lock=false;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
analog.multiplier = findmult(ui->RatioSB->value(), 255);
|
||||||
|
float singlestep =(1<<analog.multiplier);
|
||||||
|
lock = true;
|
||||||
|
ui->RatioSB->setSingleStep(singlestep);
|
||||||
|
ui->RatioSB->setValue(round(ui->RatioSB->value()/singlestep)*singlestep);
|
||||||
|
lock = false;
|
||||||
|
}
|
||||||
|
emit modified();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TelemetryAnalog::on_RatioSB_editingFinished()
|
||||||
|
{
|
||||||
|
float ratio, calib, alarm1value,alarm2value;
|
||||||
|
if (lock) return;
|
||||||
|
if (analog.type==0 || analog.type==1 || analog.type==2) {
|
||||||
|
analog.multiplier = findmult(ui->RatioSB->value(), 25.5);
|
||||||
|
ui->CalibSB->setSingleStep((1<<analog.multiplier)/10.0);
|
||||||
|
ui->alarm1ValueSB->setSingleStep((1<<analog.multiplier)/10.0);
|
||||||
|
ui->alarm2ValueSB->setSingleStep((1<<analog.multiplier)/10.0);
|
||||||
|
analog.ratio = ((int)(round(ui->RatioSB->value()*10))/(1 <<analog.multiplier));
|
||||||
|
} else {
|
||||||
|
analog.multiplier = findmult(ui->RatioSB->value(), 255);
|
||||||
|
ui->CalibSB->setSingleStep(1<<analog.multiplier);
|
||||||
|
ui->alarm1ValueSB->setSingleStep(1<<analog.multiplier);
|
||||||
|
ui->alarm2ValueSB->setSingleStep(1<<analog.multiplier);
|
||||||
|
analog.ratio = (ui->RatioSB->value()/(1 << analog.multiplier));
|
||||||
|
}
|
||||||
|
ui->CalibSB->setMaximum((ui->RatioSB->value()*127)/255);
|
||||||
|
ui->CalibSB->setMinimum((ui->RatioSB->value()*-128)/255);
|
||||||
|
ui->alarm1ValueSB->setMaximum(ui->RatioSB->value());
|
||||||
|
ui->alarm2ValueSB->setMaximum(ui->RatioSB->value());
|
||||||
|
repaint();
|
||||||
|
ratio=analog.ratio * (1 << analog.multiplier);
|
||||||
|
calib=ui->CalibSB->value();
|
||||||
|
alarm1value=ui->alarm1ValueSB->value();
|
||||||
|
alarm2value=ui->alarm2ValueSB->value();
|
||||||
|
if (analog.type==0) {
|
||||||
|
calib*=10;
|
||||||
|
alarm1value*=10;
|
||||||
|
alarm2value*=10;
|
||||||
|
}
|
||||||
|
if (calib>0) {
|
||||||
|
if (calib>((ratio*127)/255)) {
|
||||||
|
analog.offset=127;
|
||||||
|
} else {
|
||||||
|
analog.offset=round(calib*255/ratio);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (calib<0) {
|
||||||
|
if (calib<((ratio*-128)/255)) {
|
||||||
|
analog.offset=-128;
|
||||||
|
} else {
|
||||||
|
analog.offset=round(calib*255/ratio);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
analog.alarms[0].value=round((alarm1value*255-analog.offset*(analog.ratio<<analog.multiplier))/(analog.ratio<<analog.multiplier));
|
||||||
|
analog.alarms[1].value=round((alarm2value*255-analog.offset*(analog.ratio<<analog.multiplier))/(analog.ratio<<analog.multiplier));
|
||||||
|
update();
|
||||||
|
// TODO ? telBarUpdate();
|
||||||
|
emit modified();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TelemetryAnalog::on_CalibSB_editingFinished()
|
||||||
|
{
|
||||||
|
float ratio,calib,alarm1value,alarm2value;
|
||||||
|
if (analog.type==0 || analog.type==1 || analog.type==2) {
|
||||||
|
ratio=(analog.ratio<<analog.multiplier)/10.0;
|
||||||
|
} else {
|
||||||
|
ratio=analog.ratio<<analog.multiplier;
|
||||||
|
}
|
||||||
|
if (ratio!=0) {
|
||||||
|
analog.offset = round((255*ui->CalibSB->value()/ratio));
|
||||||
|
calib=ratio*analog.offset/255.0;
|
||||||
|
alarm1value=ui->alarm1ValueSB->value();
|
||||||
|
alarm2value=ui->alarm2ValueSB->value();
|
||||||
|
if (alarm1value<calib) {
|
||||||
|
alarm1value=calib;
|
||||||
|
} else if (alarm1value>(ratio+calib)) {
|
||||||
|
alarm1value=ratio+calib;
|
||||||
|
}
|
||||||
|
if (alarm2value<calib) {
|
||||||
|
alarm2value=calib;
|
||||||
|
} else if (alarm2value>(ratio+calib)) {
|
||||||
|
alarm2value=ratio+calib;
|
||||||
|
}
|
||||||
|
analog.alarms[0].value=round(((alarm1value-calib)*255)/ratio);
|
||||||
|
analog.alarms[1].value=round(((alarm2value-calib)*255)/ratio);
|
||||||
|
} else {
|
||||||
|
analog.offset=0;
|
||||||
|
analog.alarms[0].value=0;
|
||||||
|
analog.alarms[1].value=0;
|
||||||
|
}
|
||||||
|
update();
|
||||||
|
// TODO ? telBarUpdate();
|
||||||
|
emit modified();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TelemetryAnalog::on_alarm1LevelCB_currentIndexChanged(int index)
|
||||||
|
{
|
||||||
|
analog.alarms[0].level = index;
|
||||||
|
emit modified();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void TelemetryAnalog::on_alarm1GreaterCB_currentIndexChanged(int index)
|
||||||
|
{
|
||||||
|
analog.alarms[0].greater = index;
|
||||||
|
emit modified();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TelemetryAnalog::on_alarm1ValueSB_editingFinished()
|
||||||
|
{
|
||||||
|
float ratio, calib, alarm1value;
|
||||||
|
ratio=analog.ratio<<analog.multiplier;
|
||||||
|
calib=analog.offset;
|
||||||
|
alarm1value=ui->alarm1ValueSB->value();
|
||||||
|
if (analog.type==0) {
|
||||||
|
ratio/=10;
|
||||||
|
}
|
||||||
|
if (alarm1value<((calib*ratio)/255)) {
|
||||||
|
analog.alarms[0].value=0;
|
||||||
|
} else if (alarm1value>(ratio+(calib*ratio)/255)) {
|
||||||
|
analog.alarms[0].value=255;
|
||||||
|
} else {
|
||||||
|
analog.alarms[0].value = round((alarm1value-((calib*ratio)/255))/ratio*255);
|
||||||
|
}
|
||||||
|
update();
|
||||||
|
emit modified();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TelemetryAnalog::on_alarm2LevelCB_currentIndexChanged(int index)
|
||||||
|
{
|
||||||
|
analog.alarms[1].level = index;
|
||||||
|
emit modified();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TelemetryAnalog::on_alarm2GreaterCB_currentIndexChanged(int index)
|
||||||
|
{
|
||||||
|
analog.alarms[1].greater = index;
|
||||||
|
emit modified();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TelemetryAnalog::on_alarm2ValueSB_editingFinished()
|
||||||
|
{
|
||||||
|
float ratio, calib, alarm2value;
|
||||||
|
ratio = analog.ratio<<analog.multiplier;
|
||||||
|
calib = analog.offset;
|
||||||
|
alarm2value = ui->alarm2ValueSB->value();
|
||||||
|
if (analog.type==0) {
|
||||||
|
ratio/=10;
|
||||||
|
}
|
||||||
|
if (alarm2value<((calib*ratio)/255)) {
|
||||||
|
analog.alarms[1].value=0;
|
||||||
|
} else if (alarm2value>(ratio+(calib*ratio)/255)) {
|
||||||
|
analog.alarms[1].value=255;
|
||||||
|
} else {
|
||||||
|
analog.alarms[1].value = round((alarm2value-((calib*ratio)/255))/ratio*255);
|
||||||
|
}
|
||||||
|
update();
|
||||||
|
emit modified();
|
||||||
|
}
|
||||||
|
|
||||||
|
TelemetryAnalog::~TelemetryAnalog()
|
||||||
|
{
|
||||||
|
delete ui;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************/
|
||||||
|
|
||||||
|
TelemetryPanel::TelemetryPanel(QWidget *parent, ModelData & model):
|
||||||
|
ModelPanel(parent, model),
|
||||||
|
ui(new Ui::Telemetry)
|
||||||
|
{
|
||||||
|
ui->setupUi(this);
|
||||||
|
|
||||||
|
analogs[0] = new TelemetryAnalog(this, model.frsky.channels[0]);
|
||||||
|
ui->A1Layout->addWidget(analogs[0]);
|
||||||
|
connect(analogs[0], SIGNAL(modified()), this, SLOT(onAnalogModified()));
|
||||||
|
analogs[1] = new TelemetryAnalog(this, model.frsky.channels[1]);
|
||||||
|
ui->A2Layout->addWidget(analogs[1]);
|
||||||
|
connect(analogs[1], SIGNAL(modified()), this, SLOT(onAnalogModified()));
|
||||||
|
|
||||||
|
QGroupBox* barsgb[3] = { ui->CS1Bars, ui->CS2Bars, ui->CS3Bars };
|
||||||
|
QGroupBox* numsgb[3] = { ui->CS1Nums, ui->CS2Nums, ui->CS3Nums };
|
||||||
|
|
||||||
|
QComboBox* barscb[12] = { ui->telBarCS1B1_CB, ui->telBarCS1B2_CB, ui->telBarCS1B3_CB, ui->telBarCS1B4_CB,
|
||||||
|
ui->telBarCS2B1_CB, ui->telBarCS2B2_CB, ui->telBarCS2B3_CB, ui->telBarCS2B4_CB,
|
||||||
|
ui->telBarCS3B1_CB, ui->telBarCS3B2_CB, ui->telBarCS3B3_CB, ui->telBarCS3B4_CB};
|
||||||
|
QDoubleSpinBox* minSB[12] = { ui->telMinCS1SB1, ui->telMinCS1SB2, ui->telMinCS1SB3, ui->telMinCS1SB4,
|
||||||
|
ui->telMinCS2SB1, ui->telMinCS2SB2, ui->telMinCS2SB3, ui->telMinCS2SB4,
|
||||||
|
ui->telMinCS3SB1, ui->telMinCS3SB2, ui->telMinCS3SB3, ui->telMinCS3SB4};
|
||||||
|
QDoubleSpinBox* maxSB[12] = { ui->telMaxCS1SB1, ui->telMaxCS1SB2, ui->telMaxCS1SB3, ui->telMaxCS1SB4,
|
||||||
|
ui->telMaxCS2SB1, ui->telMaxCS2SB2, ui->telMaxCS2SB3, ui->telMaxCS2SB4,
|
||||||
|
ui->telMaxCS3SB1, ui->telMaxCS3SB2, ui->telMaxCS3SB3, ui->telMaxCS3SB4};
|
||||||
|
QComboBox* tmp[36] = { ui->telemetryCS1F1_CB, ui->telemetryCS1F2_CB, ui->telemetryCS1F3_CB, ui->telemetryCS1F4_CB, ui->telemetryCS1F5_CB, ui->telemetryCS1F6_CB, ui->telemetryCS1F7_CB, ui->telemetryCS1F8_CB, ui->telemetryCS1F9_CB, ui->telemetryCS1F10_CB, ui->telemetryCS1F11_CB, ui->telemetryCS1F12_CB,
|
||||||
|
ui->telemetryCS2F1_CB, ui->telemetryCS2F2_CB, ui->telemetryCS2F3_CB, ui->telemetryCS2F4_CB, ui->telemetryCS2F5_CB, ui->telemetryCS2F6_CB, ui->telemetryCS2F7_CB, ui->telemetryCS2F8_CB, ui->telemetryCS2F9_CB, ui->telemetryCS2F10_CB, ui->telemetryCS2F11_CB, ui->telemetryCS2F12_CB,
|
||||||
|
ui->telemetryCS3F1_CB, ui->telemetryCS3F2_CB, ui->telemetryCS3F3_CB, ui->telemetryCS3F4_CB, ui->telemetryCS3F5_CB, ui->telemetryCS3F6_CB, ui->telemetryCS3F7_CB, ui->telemetryCS3F8_CB, ui->telemetryCS3F9_CB, ui->telemetryCS3F10_CB, ui->telemetryCS3F11_CB, ui->telemetryCS3F12_CB};
|
||||||
|
|
||||||
|
memcpy(barsGB, barsgb, sizeof(barsGB));
|
||||||
|
memcpy(numsGB, numsgb, sizeof(numsGB));
|
||||||
|
memcpy(barsCB, barscb, sizeof(barsCB));
|
||||||
|
memcpy(this->maxSB, maxSB, sizeof(this->maxSB));
|
||||||
|
memcpy(this->minSB, minSB, sizeof(this->minSB));
|
||||||
|
memcpy(csf, tmp, sizeof(csf));
|
||||||
|
|
||||||
|
setup();
|
||||||
|
}
|
||||||
|
|
||||||
|
TelemetryPanel::~TelemetryPanel()
|
||||||
|
{
|
||||||
|
delete ui;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TelemetryPanel::setup()
|
||||||
|
{
|
||||||
|
QSettings settings("companion9x", "companion9x");
|
||||||
|
QString firmware_id = settings.value("firmware", default_firmware_variant.id).toString();
|
||||||
|
|
||||||
|
lock=true;
|
||||||
|
ui->telemetryCSType1->setCurrentIndex(model.frsky.screens[0].type);
|
||||||
|
ui->telemetryCSType2->setCurrentIndex(model.frsky.screens[1].type);
|
||||||
|
ui->telemetryCSType3->setCurrentIndex(model.frsky.screens[2].type);
|
||||||
|
|
||||||
|
for (int i=0; i<3; i++) {
|
||||||
|
bool isNum = (model.frsky.screens[i].type==0);
|
||||||
|
barsGB[i]->setVisible(!isNum);
|
||||||
|
numsGB[i]->setVisible(isNum);
|
||||||
|
}
|
||||||
|
|
||||||
|
connect(ui->telemetryCSType1,SIGNAL(currentIndexChanged(int)),this,SLOT(ScreenTypeCBcurrentIndexChanged(int)));
|
||||||
|
connect(ui->telemetryCSType2,SIGNAL(currentIndexChanged(int)),this,SLOT(ScreenTypeCBcurrentIndexChanged(int)));
|
||||||
|
connect(ui->telemetryCSType3,SIGNAL(currentIndexChanged(int)),this,SLOT(ScreenTypeCBcurrentIndexChanged(int)));
|
||||||
|
|
||||||
|
//frsky Settings
|
||||||
|
if (!GetEepromInterface()->getCapability(TelemetryRSSIModel) ) {
|
||||||
|
ui->RSSIGB->hide();
|
||||||
|
}
|
||||||
|
ui->rssiAlarm1SB->setValue(model.frsky.rssiAlarms[0].value);
|
||||||
|
ui->rssiAlarm2SB->setValue(model.frsky.rssiAlarms[1].value);
|
||||||
|
ui->rssiAlarm1CB->setCurrentIndex(model.frsky.rssiAlarms[0].level);
|
||||||
|
ui->rssiAlarm2CB->setCurrentIndex(model.frsky.rssiAlarms[1].level);
|
||||||
|
|
||||||
|
if (!GetEepromInterface()->getCapability(HasAltitudeSel)) {
|
||||||
|
ui->AltitudeGPS_ChkB->hide();
|
||||||
|
} else {
|
||||||
|
ui->AltitudeGPS_ChkB->setChecked(model.frsky.FrSkyGpsAlt);
|
||||||
|
}
|
||||||
|
int varioCap=GetEepromInterface()->getCapability(HasVario);
|
||||||
|
// if (IS_TARANIS(GetEepromInterface()->getBoard())) {
|
||||||
|
if (false) {
|
||||||
|
ui->AltitudeToolbar_ChkB->setChecked(model.frsky.altitudeDisplayed);
|
||||||
|
} else {
|
||||||
|
ui->AltitudeToolbar_ChkB->hide();
|
||||||
|
}
|
||||||
|
if (!varioCap) {
|
||||||
|
ui->varioLimitMax_DSB->hide();
|
||||||
|
ui->varioLimitMinOff_ChkB->hide();
|
||||||
|
ui->varioLimitMin_DSB->hide();
|
||||||
|
ui->varioLimitCenterMin_DSB->hide();
|
||||||
|
ui->varioLimitCenterMax_DSB->hide();
|
||||||
|
ui->varioLimit_label->hide();
|
||||||
|
ui->VarioLabel_1->hide();
|
||||||
|
ui->VarioLabel_2->hide();
|
||||||
|
ui->VarioLabel_3->hide();
|
||||||
|
ui->VarioLabel_4->hide();
|
||||||
|
ui->varioSourceCB->hide();
|
||||||
|
ui->varioSource_label->hide();
|
||||||
|
} else {
|
||||||
|
if (!GetEepromInterface()->getCapability(HasVarioSink)) {
|
||||||
|
ui->varioLimitMinOff_ChkB->hide();
|
||||||
|
ui->varioLimitMin_DSB->hide();
|
||||||
|
ui->varioLimitCenterMin_DSB->hide();
|
||||||
|
ui->VarioLabel_1->hide();
|
||||||
|
ui->VarioLabel_2->hide();
|
||||||
|
}
|
||||||
|
ui->varioLimitMin_DSB->setValue(model.frsky.varioMin-10);
|
||||||
|
ui->varioLimitMax_DSB->setValue(model.frsky.varioMax+10);
|
||||||
|
ui->varioLimitCenterMax_DSB->setValue((model.frsky.varioCenterMax/10.0)+0.5);
|
||||||
|
ui->varioSourceCB->setCurrentIndex(model.frsky.varioSource);
|
||||||
|
if (model.frsky.varioCenterMin==-16) {
|
||||||
|
ui->varioLimitMinOff_ChkB->setChecked(true);
|
||||||
|
ui->varioLimitCenterMin_DSB->setValue(-2.0);
|
||||||
|
ui->varioLimitCenterMin_DSB->setDisabled(true);
|
||||||
|
} else {
|
||||||
|
ui->varioLimitMinOff_ChkB->setChecked(false);
|
||||||
|
ui->varioLimitCenterMin_DSB->setValue((model.frsky.varioCenterMin/10.0)-0.5);
|
||||||
|
}
|
||||||
|
int mask=1;
|
||||||
|
for (int i=0; i< ui->varioSourceCB->count(); i++) {
|
||||||
|
if (!(varioCap&mask)) {
|
||||||
|
QModelIndex index = ui->varioSourceCB->model()->index(i, 0);
|
||||||
|
QVariant v(0);
|
||||||
|
ui->varioSourceCB->model()->setData(index, v, Qt::UserRole - 1);
|
||||||
|
}
|
||||||
|
mask <<=1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(GetEepromInterface()->getCapability(HasAltitudeSel)||GetEepromInterface()->getCapability(HasVario))) {
|
||||||
|
ui->altimetryGB->hide();
|
||||||
|
}
|
||||||
|
if (GetEepromInterface()->getCapability(NoTelemetryProtocol)) {
|
||||||
|
model.frsky.usrProto=1;
|
||||||
|
ui->frskyProtoCB->setDisabled(true);
|
||||||
|
} else {
|
||||||
|
ui->frskyProtoCB->setEnabled(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (GetEepromInterface()->getCapability(TelemetryCSFields)==0) {
|
||||||
|
ui->groupBox_5->hide();
|
||||||
|
} else {
|
||||||
|
if (GetEepromInterface()->getCapability(TelemetryCSFields)==8) {
|
||||||
|
ui->tabCsView->removeTab(1);
|
||||||
|
ui->tabCsView->removeTab(2);
|
||||||
|
}
|
||||||
|
if (GetEepromInterface()->getCapability(TelemetryCSFields)==16) {
|
||||||
|
ui->tabCsView->removeTab(2);
|
||||||
|
}
|
||||||
|
int cols=GetEepromInterface()->getCapability(TelemetryColsCSFields);
|
||||||
|
if (cols==0) cols=2;
|
||||||
|
for (int screen=0; screen<(GetEepromInterface()->getCapability(TelemetryCSFields)/(4*cols)); screen++) {
|
||||||
|
for (int c=0; c<cols; c++) {
|
||||||
|
for (int r=0; r<4; r++) {
|
||||||
|
int index=screen*12+c*4+r;
|
||||||
|
if (model.frsky.screens[screen].type==0) {
|
||||||
|
populateCustomScreenFieldCB(csf[index], model.frsky.screens[screen].body.lines[r].source[c], (r<4), model.frsky.usrProto);
|
||||||
|
} else {
|
||||||
|
populateCustomScreenFieldCB(csf[index], 0, (r<4), model.frsky.usrProto);
|
||||||
|
}
|
||||||
|
connect(csf[index], SIGNAL(currentIndexChanged(int)), this, SLOT(customFieldEdited()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (int c=cols; c<3; c++) {
|
||||||
|
for (int r=0; r<4; r++) {
|
||||||
|
int index=screen*12+c*4+r;
|
||||||
|
csf[index]->hide();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!GetEepromInterface()->getCapability(TelemetryUnits)) {
|
||||||
|
ui->frskyUnitsCB->setDisabled(true);
|
||||||
|
int index=0;
|
||||||
|
if (firmware_id.contains("imperial")) {
|
||||||
|
index=1;
|
||||||
|
}
|
||||||
|
ui->frskyUnitsCB->setCurrentIndex(index);
|
||||||
|
}
|
||||||
|
if ((GetEepromInterface()->getCapability(Telemetry)&TM_HASWSHH)) {
|
||||||
|
ui->frskyProtoCB->addItem(tr("Winged Shadow How High"));
|
||||||
|
} else {
|
||||||
|
ui->frskyProtoCB->addItem(tr("Winged Shadow How High (not supported)"));
|
||||||
|
}
|
||||||
|
|
||||||
|
ui->frskyProtoCB->setCurrentIndex(model.frsky.usrProto);
|
||||||
|
ui->frskyUnitsCB->setCurrentIndex(model.frsky.imperial);
|
||||||
|
ui->frskyBladesCB->setCurrentIndex(model.frsky.blades);
|
||||||
|
ui->frskyCurrentCB->setCurrentIndex(model.frsky.currentSource);
|
||||||
|
ui->frskyVoltCB->setCurrentIndex(model.frsky.voltsSource);
|
||||||
|
|
||||||
|
for (int screen=0; screen<2;screen++) {
|
||||||
|
for (int rows=0; rows<4; rows++) {
|
||||||
|
for (int cols=0; cols<3; cols++) {
|
||||||
|
int index=screen*12+cols*4+rows;
|
||||||
|
populateCustomScreenFieldCB(csf[index], model.frsky.screens[screen].body.lines[rows].source[cols], (rows<4), model.frsky.usrProto);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int j=0; j<12; j++) {
|
||||||
|
int screen = j/4;
|
||||||
|
int field = j%4;
|
||||||
|
populateCustomScreenFieldCB(barsCB[j], model.frsky.screens[screen].body.bars[field].source, false, model.frsky.usrProto);
|
||||||
|
switch (model.frsky.screens[screen].body.bars[field].source-1) {
|
||||||
|
case TELEMETRY_SOURCE_TX_BATT:
|
||||||
|
case TELEMETRY_SOURCE_A1:
|
||||||
|
case TELEMETRY_SOURCE_A1_MIN:
|
||||||
|
case TELEMETRY_SOURCE_A2:
|
||||||
|
case TELEMETRY_SOURCE_A2_MIN:
|
||||||
|
case TELEMETRY_SOURCE_CELLS_SUM:
|
||||||
|
case TELEMETRY_SOURCE_VFAS:
|
||||||
|
case TELEMETRY_SOURCE_CURRENT_MAX:
|
||||||
|
case TELEMETRY_SOURCE_CURRENT:
|
||||||
|
minSB[j]->setDecimals(1);
|
||||||
|
maxSB[j]->setDecimals(1);
|
||||||
|
break;
|
||||||
|
case TELEMETRY_SOURCE_CELL:
|
||||||
|
minSB[j]->setDecimals(2);
|
||||||
|
maxSB[j]->setDecimals(2);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
minSB[j]->setDecimals(0);
|
||||||
|
maxSB[j]->setDecimals(0);
|
||||||
|
}
|
||||||
|
minSB[j]->setMinimum(getBarValue(model.frsky.screens[screen].body.bars[field].source, 0, &model.frsky));
|
||||||
|
minSB[j]->setMaximum(getBarValue(model.frsky.screens[screen].body.bars[field].source, 255, &model.frsky));
|
||||||
|
minSB[j]->setSingleStep(getBarStep(model.frsky.screens[screen].body.bars[field].source));
|
||||||
|
minSB[j]->setValue(getBarValue(model.frsky.screens[screen].body.bars[field].source, model.frsky.screens[screen].body.bars[field].barMin, &model.frsky));
|
||||||
|
maxSB[j]->setMinimum(getBarValue(model.frsky.screens[screen].body.bars[field].source, 0, &model.frsky));
|
||||||
|
maxSB[j]->setMaximum(getBarValue(model.frsky.screens[screen].body.bars[field].source, 255, &model.frsky));
|
||||||
|
maxSB[j]->setSingleStep(getBarStep(model.frsky.screens[screen].body.bars[field].source));
|
||||||
|
maxSB[j]->setValue(getBarValue(model.frsky.screens[screen].body.bars[field].source, (255-model.frsky.screens[screen].body.bars[field].barMax), &model.frsky));
|
||||||
|
|
||||||
|
if (model.frsky.screens[screen].body.bars[field].source==0 || model.frsky.screens[screen].type==0) {
|
||||||
|
minSB[j]->setDisabled(true);
|
||||||
|
maxSB[j]->setDisabled(true);
|
||||||
|
}
|
||||||
|
connect(barsCB[j],SIGNAL(currentIndexChanged(int)),this,SLOT(telBarCBcurrentIndexChanged(int)));
|
||||||
|
connect(maxSB[j],SIGNAL(editingFinished()),this,SLOT(telMaxSBeditingFinished()));
|
||||||
|
connect(minSB[j],SIGNAL(editingFinished()),this,SLOT(telMinSBeditingFinished()));
|
||||||
|
}
|
||||||
|
lock=false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TelemetryPanel::onAnalogModified()
|
||||||
|
{
|
||||||
|
emit modified();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TelemetryPanel::on_frskyUnitsCB_currentIndexChanged(int index)
|
||||||
|
{
|
||||||
|
model.frsky.imperial=index;
|
||||||
|
emit modified();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TelemetryPanel::on_frskyBladesCB_currentIndexChanged(int index)
|
||||||
|
{
|
||||||
|
model.frsky.blades=index;
|
||||||
|
emit modified();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TelemetryPanel::on_frskyCurrentCB_currentIndexChanged(int index)
|
||||||
|
{
|
||||||
|
model.frsky.currentSource=index;
|
||||||
|
emit modified();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TelemetryPanel::on_frskyVoltCB_currentIndexChanged(int index)
|
||||||
|
{
|
||||||
|
model.frsky.voltsSource=index;
|
||||||
|
emit modified();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TelemetryPanel::on_frskyProtoCB_currentIndexChanged(int index)
|
||||||
|
{
|
||||||
|
if (lock) return;
|
||||||
|
int bindex[12];
|
||||||
|
lock=true;
|
||||||
|
for (int i=0; i<12; i++) {
|
||||||
|
bindex[i]=barsCB[i]->currentIndex();
|
||||||
|
model.frsky.usrProto=index;
|
||||||
|
populateCustomScreenFieldCB(barsCB[i], bindex[i], false, model.frsky.usrProto);
|
||||||
|
}
|
||||||
|
if (!GetEepromInterface()->getCapability(TelemetryCSFields)) {
|
||||||
|
ui->groupBox_5->hide();
|
||||||
|
} else {
|
||||||
|
for (int screen=0; screen<2;screen++) {
|
||||||
|
for (int rows=0; rows<4; rows++) {
|
||||||
|
for (int cols=0; cols<3; cols++) {
|
||||||
|
int index=screen*12+cols*4+rows;
|
||||||
|
populateCustomScreenFieldCB(csf[index], model.frsky.screens[screen].body.lines[rows].source[cols], (rows<4), model.frsky.usrProto);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lock=false;
|
||||||
|
if (index==0) {
|
||||||
|
for (int i=0; i<12; i++) {
|
||||||
|
if (bindex[i]>2) {
|
||||||
|
barsCB[i]->setCurrentIndex(0);
|
||||||
|
} else {
|
||||||
|
barsCB[i]->setCurrentIndex(bindex[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (index==2) {
|
||||||
|
for (int i=0; i<12; i++) {
|
||||||
|
if (bindex[i]>3) {
|
||||||
|
barsCB[i]->setCurrentIndex(0);
|
||||||
|
} else {
|
||||||
|
barsCB[i]->setCurrentIndex(bindex[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (int i=0; i<12; i++) {
|
||||||
|
barsCB[i]->setCurrentIndex(bindex[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
emit modified();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TelemetryPanel::on_rssiAlarm1CB_currentIndexChanged(int index) {
|
||||||
|
if (lock) return;
|
||||||
|
model.frsky.rssiAlarms[0].level=index;
|
||||||
|
emit modified();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TelemetryPanel::on_rssiAlarm2CB_currentIndexChanged(int index) {
|
||||||
|
if (lock) return;
|
||||||
|
model.frsky.rssiAlarms[1].level=index;
|
||||||
|
emit modified();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TelemetryPanel::on_rssiAlarm1SB_editingFinished()
|
||||||
|
{
|
||||||
|
if (lock) return;
|
||||||
|
model.frsky.rssiAlarms[0].value=(ui->rssiAlarm1SB->value());
|
||||||
|
emit modified();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TelemetryPanel::on_rssiAlarm2SB_editingFinished()
|
||||||
|
{
|
||||||
|
if (lock) return;
|
||||||
|
model.frsky.rssiAlarms[1].value=(ui->rssiAlarm2SB->value());
|
||||||
|
emit modified();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TelemetryPanel::on_AltitudeGPS_ChkB_toggled(bool checked)
|
||||||
|
{
|
||||||
|
if (lock) return;
|
||||||
|
model.frsky.FrSkyGpsAlt = checked;
|
||||||
|
emit modified();
|
||||||
|
//AltitudeGPS_CB
|
||||||
|
}
|
||||||
|
|
||||||
|
void TelemetryPanel::on_AltitudeToolbar_ChkB_toggled(bool checked)
|
||||||
|
{
|
||||||
|
model.frsky.altitudeDisplayed = checked;
|
||||||
|
emit modified();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TelemetryPanel::on_varioSourceCB_currentIndexChanged(int index)
|
||||||
|
{
|
||||||
|
if (lock) return;
|
||||||
|
model.frsky.varioSource = index;
|
||||||
|
emit modified();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TelemetryPanel::on_varioLimitMin_DSB_editingFinished()
|
||||||
|
{
|
||||||
|
if (lock) return;
|
||||||
|
model.frsky.varioMin= round(ui->varioLimitMin_DSB->value()+10);
|
||||||
|
emit modified();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TelemetryPanel::on_varioLimitMax_DSB_editingFinished()
|
||||||
|
{
|
||||||
|
if (lock) return;
|
||||||
|
model.frsky.varioMax= round(ui->varioLimitMax_DSB->value()-10);
|
||||||
|
emit modified();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TelemetryPanel::on_varioLimitCenterMin_DSB_editingFinished()
|
||||||
|
{
|
||||||
|
if (lock) return;
|
||||||
|
if (ui->varioLimitCenterMin_DSB->value()>ui->varioLimitCenterMax_DSB->value()) {
|
||||||
|
ui->varioLimitCenterMax_DSB->setValue(ui->varioLimitCenterMin_DSB->value());
|
||||||
|
}
|
||||||
|
model.frsky.varioCenterMin= round((ui->varioLimitCenterMin_DSB->value()+0.5)*10);
|
||||||
|
emit modified();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TelemetryPanel::on_varioLimitMinOff_ChkB_toggled(bool checked)
|
||||||
|
{
|
||||||
|
if (lock) return;
|
||||||
|
model.frsky.varioCenterMin = -16;
|
||||||
|
if (!checked) {
|
||||||
|
lock=true;
|
||||||
|
ui->varioLimitCenterMin_DSB->setValue(-2.0);
|
||||||
|
ui->varioLimitCenterMin_DSB->setEnabled(true);
|
||||||
|
lock=false;
|
||||||
|
} else {
|
||||||
|
ui->varioLimitCenterMin_DSB->setValue(-2.0);
|
||||||
|
ui->varioLimitCenterMin_DSB->setDisabled(true);
|
||||||
|
}
|
||||||
|
emit modified();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TelemetryPanel::on_varioLimitCenterMax_DSB_editingFinished()
|
||||||
|
{
|
||||||
|
if (lock) return;
|
||||||
|
if (ui->varioLimitCenterMin_DSB->value()>ui->varioLimitCenterMax_DSB->value()) {
|
||||||
|
ui->varioLimitCenterMax_DSB->setValue(ui->varioLimitCenterMin_DSB->value());
|
||||||
|
}
|
||||||
|
model.frsky.varioCenterMax= round((ui->varioLimitCenterMax_DSB->value()-0.5)*10);
|
||||||
|
emit modified();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TelemetryPanel::telBarUpdate()
|
||||||
|
{
|
||||||
|
int index;
|
||||||
|
lock=true;
|
||||||
|
for (int i=0; i<12; i++) {
|
||||||
|
int screen=i/4;
|
||||||
|
index=barsCB[i]->currentIndex();
|
||||||
|
if (index==TELEMETRY_SOURCE_A1 || index==TELEMETRY_SOURCE_A1 || index==TELEMETRY_SOURCE_A1_MIN || index==TELEMETRY_SOURCE_A2_MIN) {
|
||||||
|
minSB[i]->setMinimum(getBarValue(index, 0, &model.frsky));
|
||||||
|
minSB[i]->setMaximum(getBarValue(index, 255, &model.frsky));
|
||||||
|
minSB[i]->setSingleStep(getBarStep(index));
|
||||||
|
maxSB[i]->setMinimum(getBarValue(index, 0, &model.frsky));
|
||||||
|
maxSB[i]->setMaximum(getBarValue(index, 255, &model.frsky));
|
||||||
|
maxSB[i]->setSingleStep(getBarStep(index));
|
||||||
|
minSB[i]->setValue(getBarValue(index, model.frsky.screens[screen].body.bars[i%4].barMin, &model.frsky));
|
||||||
|
maxSB[i]->setValue(getBarValue(index, 255-model.frsky.screens[screen].body.bars[i%4].barMax, &model.frsky));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lock=false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TelemetryPanel::ScreenTypeCBcurrentIndexChanged(int index)
|
||||||
|
{
|
||||||
|
if (lock) return;
|
||||||
|
|
||||||
|
QComboBox *comboBox = qobject_cast<QComboBox*>(sender());
|
||||||
|
int screen = comboBox->objectName().right(1).toInt() -1;
|
||||||
|
lock=true;
|
||||||
|
model.frsky.screens[screen].type=index;
|
||||||
|
|
||||||
|
for (int i=0; i<3; i++) {
|
||||||
|
bool isNum = (model.frsky.screens[i].type==0);
|
||||||
|
barsGB[i]->setVisible(!isNum);
|
||||||
|
numsGB[i]->setVisible(isNum);
|
||||||
|
}
|
||||||
|
|
||||||
|
lock=false;
|
||||||
|
emit modified();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TelemetryPanel::telBarCBcurrentIndexChanged(int index)
|
||||||
|
{
|
||||||
|
if (lock) return;
|
||||||
|
QComboBox *comboBox = qobject_cast<QComboBox*>(sender());
|
||||||
|
int screenId = comboBox->objectName().mid(8,1).toInt() - 1;
|
||||||
|
int barId = comboBox->objectName().mid(10,1).toInt() - 1;
|
||||||
|
int bar=barId+screenId*4;
|
||||||
|
model.frsky.screens[screenId].body.bars[barId].source=index;
|
||||||
|
lock=true;
|
||||||
|
if (index==0) {
|
||||||
|
model.frsky.screens[screenId].body.bars[barId].barMin=0;
|
||||||
|
model.frsky.screens[screenId].body.bars[barId].barMax=0;
|
||||||
|
minSB[bar]->setDisabled(true);
|
||||||
|
maxSB[bar]->setDisabled(true);
|
||||||
|
} else {
|
||||||
|
minSB[bar]->setEnabled(true);
|
||||||
|
maxSB[bar]->setEnabled(true);
|
||||||
|
}
|
||||||
|
switch (index-1) {
|
||||||
|
case TELEMETRY_SOURCE_TX_BATT:
|
||||||
|
case TELEMETRY_SOURCE_A1:
|
||||||
|
case TELEMETRY_SOURCE_A1_MIN:
|
||||||
|
case TELEMETRY_SOURCE_A2:
|
||||||
|
case TELEMETRY_SOURCE_A2_MIN:
|
||||||
|
case TELEMETRY_SOURCE_CELLS_SUM:
|
||||||
|
case TELEMETRY_SOURCE_VFAS:
|
||||||
|
case TELEMETRY_SOURCE_CURRENT_MAX:
|
||||||
|
case TELEMETRY_SOURCE_CURRENT:
|
||||||
|
minSB[bar]->setDecimals(1);
|
||||||
|
maxSB[bar]->setDecimals(1);
|
||||||
|
break;
|
||||||
|
case TELEMETRY_SOURCE_CELL:
|
||||||
|
minSB[bar]->setDecimals(2);
|
||||||
|
maxSB[bar]->setDecimals(2);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
minSB[bar]->setDecimals(0);
|
||||||
|
maxSB[bar]->setDecimals(0);
|
||||||
|
}
|
||||||
|
minSB[bar]->setMinimum(getBarValue(index, 0, &model.frsky));
|
||||||
|
minSB[bar]->setMaximum(getBarValue(index, 255, &model.frsky));
|
||||||
|
minSB[bar]->setSingleStep(getBarStep(index));
|
||||||
|
maxSB[bar]->setMinimum(getBarValue(index, 0, &model.frsky));
|
||||||
|
maxSB[bar]->setMaximum(getBarValue(index, 255, &model.frsky));
|
||||||
|
maxSB[bar]->setSingleStep(getBarStep(index));
|
||||||
|
minSB[bar]->setValue(getBarValue(index, model.frsky.screens[screenId].body.bars[barId].barMin, &model.frsky));
|
||||||
|
maxSB[bar]->setValue(getBarValue(index, 255-model.frsky.screens[screenId].body.bars[barId].barMax, &model.frsky));
|
||||||
|
lock=false;
|
||||||
|
emit modified();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TelemetryPanel::telMinSBeditingFinished()
|
||||||
|
{
|
||||||
|
if (lock) return;
|
||||||
|
QDoubleSpinBox *spinBox = qobject_cast<QDoubleSpinBox*>(sender());
|
||||||
|
int screenId = spinBox->objectName().mid(8,1).toInt() - 1;
|
||||||
|
int barId = spinBox->objectName().right(1).toInt() - 1;
|
||||||
|
int minId = barId+screenId*4;
|
||||||
|
lock=true;
|
||||||
|
if (model.frsky.screens[screenId].body.bars[barId].source==TELEMETRY_SOURCE_A1 || model.frsky.screens[screenId].body.bars[barId].source==TELEMETRY_SOURCE_A1_MIN) {
|
||||||
|
model.frsky.screens[screenId].body.bars[barId].barMin=round((minSB[minId]->value()-analogs[0]->ui->CalibSB->value())/getBarStep(model.frsky.screens[screenId].body.bars[barId].source));
|
||||||
|
} else if (model.frsky.screens[screenId].body.bars[minId].source==TELEMETRY_SOURCE_A2 || model.frsky.screens[screenId].body.bars[minId].source==TELEMETRY_SOURCE_A2_MIN) {
|
||||||
|
model.frsky.screens[screenId].body.bars[barId].barMin=round((minSB[minId]->value()-analogs[1]->ui->CalibSB->value())/getBarStep(model.frsky.screens[screenId].body.bars[barId].source));
|
||||||
|
} else {
|
||||||
|
model.frsky.screens[screenId].body.bars[barId].barMin=round((minSB[minId]->value()-getBarValue(model.frsky.screens[screenId].body.bars[barId].source, 0, &model.frsky))/getBarStep(model.frsky.screens[screenId].body.bars[barId].source));
|
||||||
|
}
|
||||||
|
spinBox->setValue(getBarValue(model.frsky.screens[screenId].body.bars[barId].source, model.frsky.screens[screenId].body.bars[barId].barMin, &model.frsky));
|
||||||
|
if (maxSB[minId]->value()<minSB[minId]->value()) {
|
||||||
|
model.frsky.screens[screenId].body.bars[minId].barMax=(255-model.frsky.screens[screenId].body.bars[barId].barMin+1);
|
||||||
|
maxSB[minId]->setValue(getBarValue(model.frsky.screens[screenId].body.bars[barId].source, 255-model.frsky.screens[screenId].body.bars[barId].barMax, &model.frsky));
|
||||||
|
}
|
||||||
|
maxSB[minId]->setMinimum(getBarValue(model.frsky.screens[screenId].body.bars[barId].source, (model.frsky.screens[screenId].body.bars[barId].barMin+1), &model.frsky));
|
||||||
|
lock=false;
|
||||||
|
emit modified();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TelemetryPanel::telMaxSBeditingFinished()
|
||||||
|
{
|
||||||
|
if (lock) return;
|
||||||
|
QDoubleSpinBox *spinBox = qobject_cast<QDoubleSpinBox*>(sender());
|
||||||
|
int screenId = spinBox->objectName().mid(8,1).toInt() - 1;
|
||||||
|
int barId = spinBox->objectName().right(1).toInt() - 1;
|
||||||
|
lock=true;
|
||||||
|
if (model.frsky.screens[screenId].body.bars[barId].source==5) {
|
||||||
|
model.frsky.screens[screenId].body.bars[barId].barMax = (255-round((spinBox->value()-analogs[0]->ui->CalibSB->value())/getBarStep(model.frsky.screens[screenId].body.bars[barId].source)));
|
||||||
|
} else if (model.frsky.screens[screenId].body.bars[barId].source==6) {
|
||||||
|
model.frsky.screens[screenId].body.bars[barId].barMax = (255-round((spinBox->value()-analogs[1]->ui->CalibSB->value())/getBarStep(model.frsky.screens[screenId].body.bars[barId].source)));
|
||||||
|
} else {
|
||||||
|
model.frsky.screens[screenId].body.bars[barId].barMax = (255-round((spinBox->value()-getBarValue(model.frsky.screens[screenId].body.bars[barId].source, 0, &model.frsky))/getBarStep(model.frsky.screens[screenId].body.bars[barId].source) ));
|
||||||
|
}
|
||||||
|
spinBox->setValue(getBarValue(model.frsky.screens[screenId].body.bars[barId].source, (255-model.frsky.screens[screenId].body.bars[barId].barMax), &model.frsky));
|
||||||
|
lock=false;
|
||||||
|
emit modified();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TelemetryPanel::customFieldEdited()
|
||||||
|
{
|
||||||
|
if (!lock) {
|
||||||
|
lock = true;
|
||||||
|
|
||||||
|
int cols=GetEepromInterface()->getCapability(TelemetryColsCSFields);
|
||||||
|
if (cols==0) cols=2;
|
||||||
|
|
||||||
|
for (int i=0; i<GetEepromInterface()->getCapability(TelemetryCSFields); i++) {
|
||||||
|
int screen=i/(4*cols);
|
||||||
|
int r=((i%(4*cols))%4);
|
||||||
|
int c=((i%(4*cols))/4);
|
||||||
|
if (model.frsky.screens[screen].type==0) {
|
||||||
|
model.frsky.screens[screen].body.lines[r].source[c]=csf[i]->currentIndex();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
emit modified();
|
||||||
|
|
||||||
|
lock = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
float TelemetryPanel::getBarStep(int barId)
|
||||||
|
{
|
||||||
|
switch (barId-1) {
|
||||||
|
case TELEMETRY_SOURCE_TX_BATT:
|
||||||
|
return 0.1;
|
||||||
|
break;
|
||||||
|
case TELEMETRY_SOURCE_TIMER1:
|
||||||
|
case TELEMETRY_SOURCE_TIMER2:
|
||||||
|
return 3;
|
||||||
|
break;
|
||||||
|
case TELEMETRY_SOURCE_A1:
|
||||||
|
case TELEMETRY_SOURCE_A1_MIN:
|
||||||
|
return (analogs[0]->ui->RatioSB->value()/255);
|
||||||
|
break;
|
||||||
|
case TELEMETRY_SOURCE_A2:
|
||||||
|
case TELEMETRY_SOURCE_A2_MIN:
|
||||||
|
return (analogs[1]->ui->RatioSB->value()/255);
|
||||||
|
break;
|
||||||
|
case TELEMETRY_SOURCE_ALT:
|
||||||
|
case TELEMETRY_SOURCE_GPS_ALT:
|
||||||
|
case TELEMETRY_SOURCE_ALT_MAX:
|
||||||
|
case TELEMETRY_SOURCE_ALT_MIN:
|
||||||
|
return 8;
|
||||||
|
break;
|
||||||
|
case TELEMETRY_SOURCE_RPM:
|
||||||
|
case TELEMETRY_SOURCE_RPM_MAX:
|
||||||
|
return 50;
|
||||||
|
break;
|
||||||
|
case TELEMETRY_SOURCE_CELLS_SUM:
|
||||||
|
case TELEMETRY_SOURCE_VFAS:
|
||||||
|
return 0.1;
|
||||||
|
break;
|
||||||
|
case TELEMETRY_SOURCE_CELL:
|
||||||
|
return 0.02;
|
||||||
|
break;
|
||||||
|
case TELEMETRY_SOURCE_HDG:
|
||||||
|
return 2;
|
||||||
|
break;
|
||||||
|
case TELEMETRY_SOURCE_DIST:
|
||||||
|
case TELEMETRY_SOURCE_DIST_MAX:
|
||||||
|
return 8;
|
||||||
|
break;
|
||||||
|
case TELEMETRY_SOURCE_CURRENT_MAX:
|
||||||
|
case TELEMETRY_SOURCE_CURRENT:
|
||||||
|
return 0.5;
|
||||||
|
break;
|
||||||
|
case TELEMETRY_SOURCE_POWER:
|
||||||
|
return 5;
|
||||||
|
break;
|
||||||
|
case TELEMETRY_SOURCE_CONSUMPTION:
|
||||||
|
return 20;
|
||||||
|
break;
|
||||||
|
case TELEMETRY_SOURCE_SPEED:
|
||||||
|
case TELEMETRY_SOURCE_SPEED_MAX:
|
||||||
|
if (model.frsky.imperial==1) {
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
return 1.852;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
98
companion/src/modeledit/telemetry.h
Normal file
98
companion/src/modeledit/telemetry.h
Normal file
|
@ -0,0 +1,98 @@
|
||||||
|
#ifndef TELEMETRY_H
|
||||||
|
#define TELEMETRY_H
|
||||||
|
|
||||||
|
#include "modelpanel.h"
|
||||||
|
#include <QGroupBox>
|
||||||
|
#include <QComboBox>
|
||||||
|
#include <QDoubleSpinBox>
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
class TelemetryAnalog;
|
||||||
|
class Telemetry;
|
||||||
|
}
|
||||||
|
|
||||||
|
class TelemetryAnalog : public QWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
friend class TelemetryPanel;
|
||||||
|
|
||||||
|
public:
|
||||||
|
TelemetryAnalog(QWidget *parent, FrSkyChannelData & analog);
|
||||||
|
virtual ~TelemetryAnalog();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void modified();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void on_UnitCB_currentIndexChanged(int index);
|
||||||
|
void on_RatioSB_editingFinished();
|
||||||
|
void on_RatioSB_valueChanged();
|
||||||
|
void on_CalibSB_editingFinished();
|
||||||
|
void on_alarm1LevelCB_currentIndexChanged(int index);
|
||||||
|
void on_alarm1GreaterCB_currentIndexChanged(int index);
|
||||||
|
void on_alarm1ValueSB_editingFinished();
|
||||||
|
void on_alarm2LevelCB_currentIndexChanged(int index);
|
||||||
|
void on_alarm2GreaterCB_currentIndexChanged(int index);
|
||||||
|
void on_alarm2ValueSB_editingFinished();
|
||||||
|
|
||||||
|
private:
|
||||||
|
Ui::TelemetryAnalog *ui;
|
||||||
|
FrSkyChannelData & analog;
|
||||||
|
bool lock;
|
||||||
|
|
||||||
|
void update();
|
||||||
|
};
|
||||||
|
|
||||||
|
class TelemetryPanel : public ModelPanel
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
TelemetryPanel(QWidget *parent, ModelData & model);
|
||||||
|
virtual ~TelemetryPanel();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void modified();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void onAnalogModified();
|
||||||
|
void on_frskyProtoCB_currentIndexChanged(int index);
|
||||||
|
void on_frskyUnitsCB_currentIndexChanged(int index);
|
||||||
|
void on_frskyBladesCB_currentIndexChanged(int index);
|
||||||
|
void on_frskyCurrentCB_currentIndexChanged(int index);
|
||||||
|
void on_frskyVoltCB_currentIndexChanged(int index);
|
||||||
|
void on_AltitudeToolbar_ChkB_toggled(bool checked);
|
||||||
|
void on_rssiAlarm1CB_currentIndexChanged(int index);
|
||||||
|
void on_rssiAlarm2CB_currentIndexChanged(int index);
|
||||||
|
void on_rssiAlarm1SB_editingFinished();
|
||||||
|
void on_rssiAlarm2SB_editingFinished();
|
||||||
|
void on_AltitudeGPS_ChkB_toggled(bool checked);
|
||||||
|
void on_varioSourceCB_currentIndexChanged(int index);
|
||||||
|
void on_varioLimitMin_DSB_editingFinished();
|
||||||
|
void on_varioLimitMax_DSB_editingFinished();
|
||||||
|
void on_varioLimitCenterMin_DSB_editingFinished();
|
||||||
|
void on_varioLimitMinOff_ChkB_toggled(bool checked);
|
||||||
|
void on_varioLimitCenterMax_DSB_editingFinished();
|
||||||
|
void telBarCBcurrentIndexChanged(int index);
|
||||||
|
void ScreenTypeCBcurrentIndexChanged(int index);
|
||||||
|
void telMaxSBeditingFinished();
|
||||||
|
void telMinSBeditingFinished();
|
||||||
|
void customFieldEdited();
|
||||||
|
|
||||||
|
private:
|
||||||
|
Ui::Telemetry *ui;
|
||||||
|
TelemetryAnalog * analogs[2];
|
||||||
|
QGroupBox* barsGB[3];
|
||||||
|
QGroupBox* numsGB[3];
|
||||||
|
QComboBox* barsCB[12];
|
||||||
|
QDoubleSpinBox* minSB[12];
|
||||||
|
QDoubleSpinBox* maxSB[12];
|
||||||
|
QComboBox* csf[36];
|
||||||
|
|
||||||
|
void setup();
|
||||||
|
float getBarStep(int barId);
|
||||||
|
void telBarUpdate();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // TELEMETRY_H
|
2013
companion/src/modeledit/telemetry.ui
Normal file
2013
companion/src/modeledit/telemetry.ui
Normal file
File diff suppressed because it is too large
Load diff
324
companion/src/modeledit/telemetry_analog.ui
Normal file
324
companion/src/modeledit/telemetry_analog.ui
Normal file
|
@ -0,0 +1,324 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>TelemetryAnalog</class>
|
||||||
|
<widget class="QWidget" name="TelemetryAnalog">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>291</width>
|
||||||
|
<height>118</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Form</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<item>
|
||||||
|
<layout class="QGridLayout" name="gridLayout_11" columnstretch="0,1,0,1" columnminimumwidth="0,0,90,0">
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QLabel" name="label_918">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Unit</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QLabel" name="label_Max">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Max Value</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="0">
|
||||||
|
<widget class="QLabel" name="label_919">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Alarm 1 </string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="1">
|
||||||
|
<widget class="QComboBox" name="alarm1LevelCB">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>----</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Yellow</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Orange</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Red</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="2">
|
||||||
|
<widget class="QComboBox" name="alarm1GreaterCB">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string><</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>></string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="0">
|
||||||
|
<widget class="QLabel" name="label_921">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Alarm 2</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="1">
|
||||||
|
<widget class="QComboBox" name="alarm2LevelCB">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>----</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Yellow</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Orange</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Red</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="2">
|
||||||
|
<widget class="QComboBox" name="alarm2GreaterCB">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string><</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>></string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="2">
|
||||||
|
<widget class="QLabel" name="CalibLabel">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Min Value</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="1">
|
||||||
|
<widget class="QDoubleSpinBox" name="RatioSB">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="decimals">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<double>255.000000000000000</double>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="3">
|
||||||
|
<widget class="QDoubleSpinBox" name="CalibSB">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="decimals">
|
||||||
|
<number>2</number>
|
||||||
|
</property>
|
||||||
|
<property name="minimum">
|
||||||
|
<double>-12.800000000000001</double>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<double>12.699999999999999</double>
|
||||||
|
</property>
|
||||||
|
<property name="singleStep">
|
||||||
|
<double>0.100000000000000</double>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="3">
|
||||||
|
<widget class="QDoubleSpinBox" name="alarm1ValueSB">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="decimals">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<double>255.000000000000000</double>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="3">
|
||||||
|
<widget class="QDoubleSpinBox" name="alarm2ValueSB">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="decimals">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<double>255.000000000000000</double>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="1" colspan="3">
|
||||||
|
<widget class="QComboBox" name="UnitCB">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Volts (V)</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Amps (A)</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Speed (m/s or ft/s)</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Raw (-)</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Speed (km/h or miles/h)</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Meters (m or ft)</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Temp (°)</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Fuel (%)</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>mAmps (mA)</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources/>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
852
companion/src/modeledit/templates.cpp
Normal file
852
companion/src/modeledit/templates.cpp
Normal file
|
@ -0,0 +1,852 @@
|
||||||
|
#include "templates.h"
|
||||||
|
#include <QListWidget>
|
||||||
|
#include <QMessageBox>
|
||||||
|
|
||||||
|
Templates::Templates(QWidget * parent, ModelData & model):
|
||||||
|
QWidget(parent),
|
||||||
|
model(model)
|
||||||
|
{
|
||||||
|
QGridLayout * gridLayout = new QGridLayout(this);
|
||||||
|
QListWidget * templateList = new QListWidget(this);
|
||||||
|
gridLayout->addWidget(templateList, 0, 0, 1, 1);
|
||||||
|
|
||||||
|
templateList->addItem(tr("Simple 4-CH"));
|
||||||
|
templateList->addItem(tr("T-Cut"));
|
||||||
|
templateList->addItem(tr("Sticky T-Cut"));
|
||||||
|
templateList->addItem(tr("V-Tail"));
|
||||||
|
templateList->addItem(tr("Elevon\\Delta"));
|
||||||
|
templateList->addItem(tr("Heli Setup"));
|
||||||
|
templateList->addItem(tr("Heli Setup with gyro gain control"));
|
||||||
|
templateList->addItem(tr("Gyro gain control"));
|
||||||
|
templateList->addItem(tr("Heli Setup (Futaba's channel assignment style)"));
|
||||||
|
templateList->addItem(tr("Heli Setup with gyro gain control (Futaba's channel assignment style)"));
|
||||||
|
templateList->addItem(tr("Gyro gain control (Futaba's channel assignment style)"));
|
||||||
|
templateList->addItem(tr("Servo Test"));
|
||||||
|
templateList->addItem(tr("MultiCopter"));
|
||||||
|
templateList->addItem(tr("Use Model Config Wizard"));
|
||||||
|
|
||||||
|
connect(templateList, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(doubleClicked(QModelIndex)));
|
||||||
|
}
|
||||||
|
|
||||||
|
Templates::~Templates()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void Templates::setSwitch(unsigned int idx, unsigned int func, int v1, int v2)
|
||||||
|
{
|
||||||
|
g_model.customSw[idx-1].func = func;
|
||||||
|
g_model.customSw[idx-1].val1 = v1;
|
||||||
|
g_model.customSw[idx-1].val2 = v2;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Templates::onDoubleClicked(QModelIndex index)
|
||||||
|
{
|
||||||
|
QString text = ui->templateList->item(index.row())->text();
|
||||||
|
if (index.row()==13) {
|
||||||
|
uint64_t result=0xffffffff;
|
||||||
|
modelConfigDialog *mcw = new modelConfigDialog(radioData, &result, this);
|
||||||
|
mcw->exec();
|
||||||
|
if (result!=0xffffffff) {
|
||||||
|
applyNumericTemplate(result);
|
||||||
|
updateSettings();
|
||||||
|
tabMixes();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
int res = QMessageBox::question(this,tr("Apply Template?"),tr("Apply template \"%1\"?").arg(text),QMessageBox::Yes | QMessageBox::No);
|
||||||
|
if(res!=QMessageBox::Yes) return;
|
||||||
|
applyTemplate(index.row());
|
||||||
|
updateSettings();
|
||||||
|
tabMixes();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Templates::applyNumericTemplate(uint64_t tpl)
|
||||||
|
{
|
||||||
|
clearCurves();
|
||||||
|
clearExpos(false);
|
||||||
|
clearMixes(false);
|
||||||
|
int8_t heli_ar1[] = {-100, -20, 30, 70, 90};
|
||||||
|
int8_t heli_ar2[] = {80, 70, 60, 70, 100};
|
||||||
|
int8_t heli_ar3[] = {100, 90, 80, 90, 100};
|
||||||
|
int8_t heli_ar4[] = {-30, -15, 0, 50, 100};
|
||||||
|
int8_t heli_ar5[] = {-100, -50, 0, 50, 100};
|
||||||
|
bool rx[10];
|
||||||
|
for (int i=0; i<10 ; i++) {
|
||||||
|
rx[i]=false;
|
||||||
|
}
|
||||||
|
int thrsw=GetEepromInterface()->getCapability(GetThrSwitch);
|
||||||
|
MixData *md = &model.mixData[0];
|
||||||
|
uint8_t spo2ch=(tpl & 0x0F);
|
||||||
|
tpl>>=4;
|
||||||
|
uint8_t spo1ch=(tpl & 0x0F);
|
||||||
|
tpl>>=4;
|
||||||
|
uint8_t fla2ch=(tpl & 0x0F);
|
||||||
|
tpl>>=4;
|
||||||
|
uint8_t fla1ch=(tpl & 0x0F);
|
||||||
|
tpl>>=4;
|
||||||
|
uint8_t rud2ch=(tpl & 0x0F);
|
||||||
|
tpl>>=4;
|
||||||
|
uint8_t ele2ch=(tpl & 0x0F);
|
||||||
|
tpl>>=4;
|
||||||
|
uint8_t ail2ch=(tpl & 0x0F);
|
||||||
|
tpl>>=4;
|
||||||
|
uint8_t chstyle=(tpl & 0x03);
|
||||||
|
tpl>>=2;
|
||||||
|
uint8_t gyro=(tpl & 0x03);
|
||||||
|
tpl>>=2;
|
||||||
|
uint8_t tailtype=(tpl & 0x03);
|
||||||
|
tpl>>=2;
|
||||||
|
uint8_t swashtype=(tpl & 0x07);
|
||||||
|
tpl>>=3;
|
||||||
|
uint8_t ruddertype=(tpl & 0x03);
|
||||||
|
tpl>>=2;
|
||||||
|
uint8_t spoilertype=(tpl & 0x3);
|
||||||
|
tpl>>=2;
|
||||||
|
uint8_t flaptype=(tpl & 0x03);
|
||||||
|
tpl>>=2;
|
||||||
|
uint8_t ailerontype=(tpl & 0x03);
|
||||||
|
tpl>>=2;
|
||||||
|
uint8_t enginetype=(tpl & 0x03);
|
||||||
|
tpl>>=2;
|
||||||
|
uint8_t modeltype=(tpl & 0x03);
|
||||||
|
|
||||||
|
#define ICC(x) icc[(x)-1]
|
||||||
|
uint8_t icc[4] = {0};
|
||||||
|
for(uint8_t i=1; i<=4; i++) //generate inverse array
|
||||||
|
for(uint8_t j=1; j<=4; j++) if(CC(i)==j) icc[j-1]=i;
|
||||||
|
|
||||||
|
int ailerons;
|
||||||
|
int flaps;
|
||||||
|
int throttle;
|
||||||
|
int spoilers;
|
||||||
|
int elevators;
|
||||||
|
int rudders;
|
||||||
|
int sign;
|
||||||
|
uint8_t rxch;
|
||||||
|
switch (modeltype) {
|
||||||
|
case 0:
|
||||||
|
ailerons=ailerontype;
|
||||||
|
flaps=flaptype;
|
||||||
|
throttle=1;
|
||||||
|
switch (tailtype) {
|
||||||
|
case 0:
|
||||||
|
case 1:
|
||||||
|
rudders=1;
|
||||||
|
elevators=1;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
rudders=1;
|
||||||
|
elevators=2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
rxch=ICC(STK_RUD);
|
||||||
|
md=setDest(rxch); md->srcRaw=RawSource(SOURCE_TYPE_STICK, 0); md->weight=100; md->swtch=RawSwitch();strncpy(md->name, tr("RUD").toAscii().data(),6);
|
||||||
|
if (tailtype==1) {
|
||||||
|
md=setDest(rxch); md->srcRaw=RawSource(SOURCE_TYPE_STICK, 1); md->weight=-100; md->swtch=RawSwitch();strncpy(md->name, tr("ELE").toAscii().data(),6);
|
||||||
|
}
|
||||||
|
rx[rxch-1]=true;
|
||||||
|
rxch=ICC(STK_ELE);
|
||||||
|
if (tailtype==1) {
|
||||||
|
md=setDest(rxch); md->srcRaw=RawSource(SOURCE_TYPE_STICK, 0); md->weight=100; md->swtch=RawSwitch();strncpy(md->name, tr("RUD").toAscii().data(),6);
|
||||||
|
}
|
||||||
|
md=setDest(rxch); md->srcRaw=RawSource(SOURCE_TYPE_STICK, 1); md->weight=100; md->swtch=RawSwitch();strncpy(md->name, tr("ELE").toAscii().data(),6);
|
||||||
|
rx[rxch-1]=true;
|
||||||
|
rxch=ICC(STK_THR);
|
||||||
|
md=setDest(rxch); md->srcRaw=RawSource(SOURCE_TYPE_STICK, 2); md->weight=100; md->swtch=RawSwitch();strncpy(md->name, tr("THR").toAscii().data(),6);
|
||||||
|
rx[rxch-1]=true;
|
||||||
|
if (ail2ch > 0) {
|
||||||
|
rx[ail2ch-1]=true;
|
||||||
|
}
|
||||||
|
if (ele2ch > 0) {
|
||||||
|
rx[ele2ch-1]=true;
|
||||||
|
}
|
||||||
|
if (fla1ch > 0) {
|
||||||
|
rx[fla1ch-1]=true;
|
||||||
|
}
|
||||||
|
if (fla2ch > 0) {
|
||||||
|
rx[fla2ch-1]=true;
|
||||||
|
}
|
||||||
|
if (ailerons>0) {
|
||||||
|
rxch=ICC(STK_AIL);
|
||||||
|
md=setDest(rxch); md->srcRaw=RawSource(SOURCE_TYPE_STICK, 3); md->weight=100; md->swtch=RawSwitch();strncpy(md->name, tr("AIL").toAscii().data(),6);
|
||||||
|
rx[rxch-1]=true;
|
||||||
|
}
|
||||||
|
if (ailerons>1) {
|
||||||
|
if (ail2ch==0) {
|
||||||
|
for (int j=0; j<10 ; j++) {
|
||||||
|
if (!rx[j]) {
|
||||||
|
md=setDest(j+1); md->srcRaw=RawSource(SOURCE_TYPE_STICK, 3); md->weight=100; md->swtch=RawSwitch();strncpy(md->name, tr("AIL2").toAscii().data(),6);
|
||||||
|
rx[j]=true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
md=setDest(ail2ch); md->srcRaw=RawSource(SOURCE_TYPE_STICK, 3); md->weight=100; md->swtch=RawSwitch();strncpy(md->name, tr("AIL2").toAscii().data(),6);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (elevators>1) {
|
||||||
|
if (ele2ch==0) {
|
||||||
|
for (int j=0; j<10 ; j++) {
|
||||||
|
if (!rx[j]) {
|
||||||
|
md=setDest(j+1); md->srcRaw=RawSource(SOURCE_TYPE_STICK, 1); md->weight=-100; md->swtch=RawSwitch();;strncpy(md->name, tr("ELE2").toAscii().data(),6);
|
||||||
|
rx[j]=true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
md=setDest(ele2ch); md->srcRaw=RawSource(SOURCE_TYPE_STICK, 1); md->weight=-100; md->swtch=RawSwitch();;strncpy(md->name, tr("ELE2").toAscii().data(),6);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (flaps>0) {
|
||||||
|
md=setDest(11); md->srcRaw=RawSource(SOURCE_TYPE_MAX); md->weight=-100; md->swtch=RawSwitch(SWITCH_TYPE_SWITCH,-DSW_AIL);strncpy(md->name, tr("FLAPS").toAscii().data(),6); md->speedUp=4; md->speedDown=4;
|
||||||
|
md=setDest(11); md->srcRaw=RawSource(SOURCE_TYPE_STICK, 5); md->weight=100; md->swtch=RawSwitch(SWITCH_TYPE_SWITCH,DSW_AIL);strncpy(md->name, tr("FLAPS").toAscii().data(),6); md->speedUp=4; md->speedDown=4;
|
||||||
|
}
|
||||||
|
sign=-1;
|
||||||
|
for (uint8_t i=0; i< flaps; i++) {
|
||||||
|
sign*=-1;
|
||||||
|
int index;
|
||||||
|
if (i==0) {
|
||||||
|
index=fla1ch;
|
||||||
|
} else {
|
||||||
|
index=fla2ch;
|
||||||
|
}
|
||||||
|
if (index==0) {
|
||||||
|
for (int j=0; j<10 ; j++) {
|
||||||
|
if (!rx[j]) {
|
||||||
|
md=setDest(j+1); md->srcRaw=RawSource(SOURCE_TYPE_CH, 10); md->weight=100*sign; md->sOffset=0; md->swtch=RawSwitch();strncpy(md->name, tr("FLAP%1").arg(i+1).toAscii().data(),6);
|
||||||
|
rx[j]=true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
md=setDest(index); md->srcRaw=RawSource(SOURCE_TYPE_CH, 10); md->weight=100*sign; md->sOffset=0; md->swtch=RawSwitch();strncpy(md->name, tr("FLAP%1").arg(i+1).toAscii().data(),6);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
setCurve(CURVE5(1),heli_ar1);
|
||||||
|
setCurve(CURVE5(2),heli_ar2);
|
||||||
|
setCurve(CURVE5(3),heli_ar3);
|
||||||
|
setCurve(CURVE5(4),heli_ar4);
|
||||||
|
setCurve(CURVE5(5),heli_ar5);
|
||||||
|
setCurve(CURVE5(6),heli_ar5);
|
||||||
|
switch (swashtype) {
|
||||||
|
case 0:
|
||||||
|
model.swashRingData.type = HELI_SWASH_TYPE_90;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
model.swashRingData.type = HELI_SWASH_TYPE_120;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
model.swashRingData.type = HELI_SWASH_TYPE_120X;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
model.swashRingData.type = HELI_SWASH_TYPE_140;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
model.swashRingData.type = HELI_SWASH_TYPE_NONE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
model.swashRingData.collectiveSource = RawSource(SOURCE_TYPE_CH, 10);
|
||||||
|
|
||||||
|
if (chstyle==0) {
|
||||||
|
if (swashtype!=4) {
|
||||||
|
md=setDest(1); md->srcRaw=RawSource(SOURCE_TYPE_CYC, 0); md->weight= 100; md->swtch=RawSwitch();strncpy(md->name, tr("ELE").toAscii().data(),6);
|
||||||
|
md=setDest(2); md->srcRaw=RawSource(SOURCE_TYPE_CYC, 1); md->weight= 100; md->swtch=RawSwitch();strncpy(md->name, tr("AIL").toAscii().data(),6);
|
||||||
|
md=setDest(3); md->srcRaw=RawSource(SOURCE_TYPE_CYC, 2); md->weight= 100; md->swtch=RawSwitch();strncpy(md->name, tr("PITCH").toAscii().data(),6);
|
||||||
|
} else {
|
||||||
|
md=setDest(1); md->srcRaw=RawSource(SOURCE_TYPE_STICK, 3); md->weight= 100; md->swtch=RawSwitch();strncpy(md->name, tr("ELE").toAscii().data(),6);
|
||||||
|
md=setDest(2); md->srcRaw=RawSource(SOURCE_TYPE_STICK, 1); md->weight= 100; md->swtch=RawSwitch();strncpy(md->name, tr("AIL").toAscii().data(),6);
|
||||||
|
md=setDest(3); md->srcRaw=RawSource(SOURCE_TYPE_CH, 10); md->weight= 100; md->swtch=RawSwitch();strncpy(md->name, tr("PITCH").toAscii().data(),6);
|
||||||
|
}
|
||||||
|
md=setDest(4); md->srcRaw=RawSource(SOURCE_TYPE_STICK, 0); md->weight=100; md->swtch=RawSwitch();strncpy(md->name, tr("RUD").toAscii().data(),6);
|
||||||
|
md=setDest(5); md->srcRaw=RawSource(SOURCE_TYPE_STICK, 2); md->weight= 100; md->swtch=RawSwitch(SWITCH_TYPE_SWITCH,DSW_ID0); md->curve=CV(1); md->carryTrim=TRIM_OFF;
|
||||||
|
md=setDest(5); md->srcRaw=RawSource(SOURCE_TYPE_STICK, 2); md->weight= 100; md->swtch=RawSwitch(SWITCH_TYPE_SWITCH,DSW_ID1); md->curve=CV(2); md->carryTrim=TRIM_OFF;
|
||||||
|
md=setDest(5); md->srcRaw=RawSource(SOURCE_TYPE_STICK, 2); md->weight= 100; md->swtch=RawSwitch(SWITCH_TYPE_SWITCH,DSW_ID2); md->curve=CV(3); md->carryTrim=TRIM_OFF;
|
||||||
|
md=setDest(5); md->srcRaw=RawSource(SOURCE_TYPE_MAX); md->weight=-100; md->swtch=RawSwitch(SWITCH_TYPE_SWITCH,thrsw); md->mltpx=MLTPX_REP;
|
||||||
|
switch (gyro) {
|
||||||
|
case 1:
|
||||||
|
md=setDest(6); md->srcRaw=RawSource(SOURCE_TYPE_MAX); md->weight=30; md->swtch=RawSwitch(SWITCH_TYPE_SWITCH,-DSW_GEA);strncpy(md->name, tr("GYRO").toAscii().data(),6);
|
||||||
|
md=setDest(6); md->srcRaw=RawSource(SOURCE_TYPE_MAX); md->weight=-30; md->swtch=RawSwitch(SWITCH_TYPE_SWITCH,DSW_GEA);strncpy(md->name, tr("GYRO").toAscii().data(),6);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
md=setDest(6); md->srcRaw=RawSource(SOURCE_TYPE_STICK, 5); md->weight= 50; md->swtch=RawSwitch(SWITCH_TYPE_SWITCH,-DSW_GEA); md->sOffset=100;strncpy(md->name, tr("GYRO").toAscii().data(),6);
|
||||||
|
md=setDest(6); md->srcRaw=RawSource(SOURCE_TYPE_STICK, 5); md->weight=-50; md->swtch=RawSwitch(SWITCH_TYPE_SWITCH,DSW_GEA); md->sOffset=100;strncpy(md->name, tr("GYRO").toAscii().data(),6);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (swashtype!=4) {
|
||||||
|
md=setDest(1); md->srcRaw=RawSource(SOURCE_TYPE_CYC, 1); md->weight= 100; md->swtch=RawSwitch();strncpy(md->name, tr("AIL").toAscii().data(),6);
|
||||||
|
md=setDest(2); md->srcRaw=RawSource(SOURCE_TYPE_CYC, 0); md->weight= 100; md->swtch=RawSwitch();strncpy(md->name, tr("ELE").toAscii().data(),6);
|
||||||
|
md=setDest(6); md->srcRaw=RawSource(SOURCE_TYPE_CYC, 2); md->weight= 100; md->swtch=RawSwitch();strncpy(md->name, tr("PITCH").toAscii().data(),6);
|
||||||
|
} else {
|
||||||
|
md=setDest(1); md->srcRaw=RawSource(SOURCE_TYPE_STICK, 3); md->weight= 100; md->swtch=RawSwitch();strncpy(md->name, tr("AIL").toAscii().data(),6);
|
||||||
|
md=setDest(2); md->srcRaw=RawSource(SOURCE_TYPE_STICK, 1); md->weight= 100; md->swtch=RawSwitch();strncpy(md->name, tr("ELE").toAscii().data(),6);
|
||||||
|
md=setDest(6); md->srcRaw=RawSource(SOURCE_TYPE_CH, 10); md->weight= 100; md->swtch=RawSwitch();strncpy(md->name, tr("PITCH").toAscii().data(),6);
|
||||||
|
}
|
||||||
|
md=setDest(4); md->srcRaw=RawSource(SOURCE_TYPE_STICK, 0); md->weight=100; md->swtch=RawSwitch();strncpy(md->name, tr("RUD").toAscii().data(),6);
|
||||||
|
md=setDest(3); md->srcRaw=RawSource(SOURCE_TYPE_STICK, 2); md->weight= 100; md->swtch=RawSwitch(SWITCH_TYPE_SWITCH,DSW_ID0); md->curve=CV(1); md->carryTrim=TRIM_OFF;
|
||||||
|
md=setDest(3); md->srcRaw=RawSource(SOURCE_TYPE_STICK, 2); md->weight= 100; md->swtch=RawSwitch(SWITCH_TYPE_SWITCH,DSW_ID1); md->curve=CV(2); md->carryTrim=TRIM_OFF;
|
||||||
|
md=setDest(3); md->srcRaw=RawSource(SOURCE_TYPE_STICK, 2); md->weight= 100; md->swtch=RawSwitch(SWITCH_TYPE_SWITCH,DSW_ID2); md->curve=CV(3); md->carryTrim=TRIM_OFF;
|
||||||
|
md=setDest(3); md->srcRaw=RawSource(SOURCE_TYPE_MAX); md->weight=-100; md->swtch=RawSwitch(SWITCH_TYPE_SWITCH,thrsw); md->mltpx=MLTPX_REP;
|
||||||
|
switch (gyro) {
|
||||||
|
case 1:
|
||||||
|
md=setDest(5); md->srcRaw=RawSource(SOURCE_TYPE_MAX); md->weight=30; md->swtch=RawSwitch(SWITCH_TYPE_SWITCH,-DSW_GEA);strncpy(md->name, tr("GYRO").toAscii().data(),6);
|
||||||
|
md=setDest(5); md->srcRaw=RawSource(SOURCE_TYPE_MAX); md->weight=-30; md->swtch=RawSwitch(SWITCH_TYPE_SWITCH,DSW_GEA);strncpy(md->name, tr("GYRO").toAscii().data(),6);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
md=setDest(5); md->srcRaw=RawSource(SOURCE_TYPE_STICK, 5); md->weight= 50; md->swtch=RawSwitch(SWITCH_TYPE_SWITCH,-DSW_GEA); md->sOffset=100;strncpy(md->name, tr("GYRO").toAscii().data(),6);
|
||||||
|
md=setDest(5); md->srcRaw=RawSource(SOURCE_TYPE_STICK, 5); md->weight=-50; md->swtch=RawSwitch(SWITCH_TYPE_SWITCH,DSW_GEA); md->sOffset=100;strncpy(md->name, tr("GYRO").toAscii().data(),6);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// collective
|
||||||
|
md=setDest(11); md->srcRaw=RawSource(SOURCE_TYPE_STICK, 2); md->weight=100; md->swtch=RawSwitch(SWITCH_TYPE_SWITCH,DSW_ID0); md->curve=CV(4); md->carryTrim=TRIM_OFF;
|
||||||
|
md=setDest(11); md->srcRaw=RawSource(SOURCE_TYPE_STICK, 2); md->weight=100; md->swtch=RawSwitch(SWITCH_TYPE_SWITCH,DSW_ID1); md->curve=CV(5); md->carryTrim=TRIM_OFF;
|
||||||
|
md=setDest(11); md->srcRaw=RawSource(SOURCE_TYPE_STICK, 2); md->weight=100; md->swtch=RawSwitch(SWITCH_TYPE_SWITCH,DSW_ID2); md->curve=CV(6); md->carryTrim=TRIM_OFF;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
ailerons=ailerontype;
|
||||||
|
flaps=flaptype;
|
||||||
|
spoilers=spoilertype;
|
||||||
|
throttle=enginetype;
|
||||||
|
switch (tailtype) {
|
||||||
|
case 0:
|
||||||
|
case 1:
|
||||||
|
rudders=1;
|
||||||
|
elevators=1;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
rudders=1;
|
||||||
|
elevators=2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (throttle==1) {
|
||||||
|
rxch=ICC(STK_THR);
|
||||||
|
md=setDest(rxch); md->srcRaw=RawSource(SOURCE_TYPE_STICK, 2); md->weight=100; md->swtch=RawSwitch();strncpy(md->name, tr("THR").toAscii().data(),6);
|
||||||
|
rx[rxch-1]=true;
|
||||||
|
}
|
||||||
|
rxch=ICC(STK_RUD);
|
||||||
|
md=setDest(rxch); md->srcRaw=RawSource(SOURCE_TYPE_STICK, 0); md->weight=100; md->swtch=RawSwitch();strncpy(md->name, tr("RUD").toAscii().data(),6);
|
||||||
|
if (tailtype==1) {
|
||||||
|
md=setDest(rxch); md->srcRaw=RawSource(SOURCE_TYPE_STICK, 1); md->weight=-100; md->swtch=RawSwitch();strncpy(md->name, tr("RUD").toAscii().data(),6);
|
||||||
|
}
|
||||||
|
rx[rxch-1]=true;
|
||||||
|
rxch=ICC(STK_ELE);
|
||||||
|
if (tailtype==1) {
|
||||||
|
md=setDest(rxch); md->srcRaw=RawSource(SOURCE_TYPE_STICK, 0); md->weight=-100; md->swtch=RawSwitch();strncpy(md->name, tr("ELE").toAscii().data(),6);
|
||||||
|
}
|
||||||
|
md=setDest(rxch); md->srcRaw=RawSource(SOURCE_TYPE_STICK, 1); md->weight=100; md->swtch=RawSwitch();strncpy(md->name, tr("ELE").toAscii().data(),6);
|
||||||
|
rx[rxch-1]=true;
|
||||||
|
if (ail2ch > 0) {
|
||||||
|
rx[ail2ch-1]=true;
|
||||||
|
}
|
||||||
|
if (ele2ch > 0) {
|
||||||
|
rx[ele2ch-1]=true;
|
||||||
|
}
|
||||||
|
if (fla1ch > 0) {
|
||||||
|
rx[fla1ch-1]=true;
|
||||||
|
}
|
||||||
|
if (fla2ch > 0) {
|
||||||
|
rx[fla2ch-1]=true;
|
||||||
|
}
|
||||||
|
if (spo1ch > 0) {
|
||||||
|
rx[spo1ch-1]=true;
|
||||||
|
}
|
||||||
|
if (spo2ch > 0) {
|
||||||
|
rx[spo2ch-1]=true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ailerons>0) {
|
||||||
|
rxch=ICC(STK_AIL);
|
||||||
|
md=setDest(rxch); md->srcRaw=RawSource(SOURCE_TYPE_STICK, 3); md->weight=100; md->swtch=RawSwitch();strncpy(md->name, tr("AIL").toAscii().data(),6);
|
||||||
|
rx[rxch-1]=true;
|
||||||
|
}
|
||||||
|
if (ailerons>1) {
|
||||||
|
if (ail2ch==0) {
|
||||||
|
for (int j=0; j<10 ; j++) {
|
||||||
|
if (!rx[j]) {
|
||||||
|
md=setDest(j+1); md->srcRaw=RawSource(SOURCE_TYPE_STICK, 3); md->weight=100; md->swtch=RawSwitch();strncpy(md->name, tr("AIL2").toAscii().data(),6);
|
||||||
|
rx[j]=true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
md=setDest(ail2ch); md->srcRaw=RawSource(SOURCE_TYPE_STICK, 3); md->weight=100; md->swtch=RawSwitch();strncpy(md->name, tr("AIL2").toAscii().data(),6);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (elevators>1) {
|
||||||
|
if (ele2ch==0) {
|
||||||
|
for (int j=0; j<10 ; j++) {
|
||||||
|
if (!rx[j]) {
|
||||||
|
md=setDest(j+1); md->srcRaw=RawSource(SOURCE_TYPE_STICK, 1); md->weight=-100; md->swtch=RawSwitch();strncpy(md->name, tr("ELE2").toAscii().data(),6);
|
||||||
|
rx[j]=true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
md=setDest(ele2ch); md->srcRaw=RawSource(SOURCE_TYPE_STICK, 1); md->weight=-100; md->swtch=RawSwitch();strncpy(md->name, tr("ELE2").toAscii().data(),6);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (flaps>0) {
|
||||||
|
md=setDest(11); md->srcRaw=RawSource(SOURCE_TYPE_MAX); md->weight=-100; md->swtch=RawSwitch(SWITCH_TYPE_SWITCH,-DSW_AIL);strncpy(md->name, tr("FLAPS").toAscii().data(),6);md->speedUp=4; md->speedDown=4;
|
||||||
|
md=setDest(11); md->srcRaw=RawSource(SOURCE_TYPE_STICK, 5); md->weight=100; md->swtch=RawSwitch(SWITCH_TYPE_SWITCH,DSW_AIL);strncpy(md->name, tr("FLAPS").toAscii().data(),6);md->speedUp=4; md->speedDown=4;
|
||||||
|
}
|
||||||
|
sign=-1;
|
||||||
|
for (uint8_t i=0; i< flaps; i++) {
|
||||||
|
sign*=-1;
|
||||||
|
int index;
|
||||||
|
if (i==0) {
|
||||||
|
index=fla1ch;
|
||||||
|
} else {
|
||||||
|
index=fla2ch;
|
||||||
|
}
|
||||||
|
if (index==0) {
|
||||||
|
for (int j=0; j<10 ; j++) {
|
||||||
|
if (!rx[j]) {
|
||||||
|
md=setDest(j+1); md->srcRaw=RawSource(SOURCE_TYPE_CH, 10); md->weight=100*sign; md->sOffset=0; md->swtch=RawSwitch();strncpy(md->name, tr("FLAP%1").arg(i+1).toAscii().data(),6);
|
||||||
|
rx[j]=true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
md=setDest(index); md->srcRaw=RawSource(SOURCE_TYPE_CH, 10); md->weight=100*sign; md->sOffset=0; md->swtch=RawSwitch();strncpy(md->name, tr("FLAP%1").arg(i+1).toAscii().data(),6);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (spoilers>0) {
|
||||||
|
md=setDest(12); md->srcRaw=RawSource(SOURCE_TYPE_MAX); md->weight=-100; md->swtch=RawSwitch(SWITCH_TYPE_SWITCH,-DSW_GEA);strncpy(md->name, tr("SPOIL").toAscii().data(),6); md->speedUp=4;;md->speedDown=4;
|
||||||
|
md=setDest(12); md->srcRaw=RawSource(SOURCE_TYPE_STICK, 5); md->weight=100; md->swtch=RawSwitch(SWITCH_TYPE_SWITCH,DSW_GEA);strncpy(md->name, tr("SPOIL").toAscii().data(),6);md->speedUp=4;md->speedDown=4;
|
||||||
|
}
|
||||||
|
sign=-1;
|
||||||
|
for (uint8_t i=0; i< spoilers; i++) {
|
||||||
|
sign*=-1;
|
||||||
|
int index;
|
||||||
|
if (i==0) {
|
||||||
|
index=spo1ch;
|
||||||
|
} else {
|
||||||
|
index=spo2ch;
|
||||||
|
}
|
||||||
|
if (index==0) {
|
||||||
|
for (int j=0; j<10 ; j++) {
|
||||||
|
if (!rx[j]) {
|
||||||
|
md=setDest(j+1); md->srcRaw=RawSource(SOURCE_TYPE_CH, 11); md->weight=100*sign; md->sOffset=0; md->swtch=RawSwitch();strncpy(md->name, tr("SPOIL%1").arg(i+1).toAscii().data(),6);
|
||||||
|
rx[j]=true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
md=setDest(index); md->srcRaw=RawSource(SOURCE_TYPE_CH, 11); md->weight=100*sign; md->sOffset=0; md->swtch=RawSwitch();strncpy(md->name, tr("SPOIL%1").arg(i+1).toAscii().data(),6);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
flaps=flaptype;
|
||||||
|
throttle=enginetype;
|
||||||
|
rudders=ruddertype;
|
||||||
|
if (throttle==1) {
|
||||||
|
rxch=ICC(STK_THR);
|
||||||
|
md=setDest(rxch); md->srcRaw=RawSource(SOURCE_TYPE_STICK, 2); md->weight=100; md->swtch=RawSwitch();strncpy(md->name, tr("THR").toAscii().data(),6);
|
||||||
|
rx[rxch-1]=true;
|
||||||
|
}
|
||||||
|
rxch=ICC(STK_ELE);
|
||||||
|
md=setDest(rxch); md->srcRaw=RawSource(SOURCE_TYPE_STICK, 1); md->weight=100; md->swtch=RawSwitch();strncpy(md->name, tr("ELE").toAscii().data(),6);
|
||||||
|
md=setDest(rxch); md->srcRaw=RawSource(SOURCE_TYPE_STICK, 3); md->weight=100; md->swtch=RawSwitch();strncpy(md->name, tr("ELE").toAscii().data(),6);
|
||||||
|
rx[rxch-1]=true;
|
||||||
|
rxch=ICC(STK_AIL);
|
||||||
|
md=setDest(rxch); md->srcRaw=RawSource(SOURCE_TYPE_STICK, 1); md->weight=-100; md->swtch=RawSwitch();strncpy(md->name, tr("AIL").toAscii().data(),6);
|
||||||
|
md=setDest(rxch); md->srcRaw=RawSource(SOURCE_TYPE_STICK, 3); md->weight=100; md->swtch=RawSwitch();strncpy(md->name, tr("AIL").toAscii().data(),6);
|
||||||
|
rx[rxch-1]=true;
|
||||||
|
if (rudders>0) {
|
||||||
|
rxch=ICC(STK_RUD);
|
||||||
|
md=setDest(rxch); md->srcRaw=RawSource(SOURCE_TYPE_STICK, 0); md->weight=100; md->swtch=RawSwitch();strncpy(md->name, tr("RUD").toAscii().data(),6);
|
||||||
|
rx[rxch-1]=true;
|
||||||
|
}
|
||||||
|
if (rud2ch > 0) {
|
||||||
|
rx[rud2ch-1]=true;
|
||||||
|
}
|
||||||
|
if (fla1ch > 0) {
|
||||||
|
rx[fla1ch-1]=true;
|
||||||
|
}
|
||||||
|
if (fla2ch > 0) {
|
||||||
|
rx[fla2ch-1]=true;
|
||||||
|
}
|
||||||
|
if (rudders>1) {
|
||||||
|
if (rud2ch==0) {
|
||||||
|
for (int j=0; j<10 ; j++) {
|
||||||
|
if (!rx[j]) {
|
||||||
|
md=setDest(j+1); md->srcRaw=RawSource(SOURCE_TYPE_STICK, 0); md->weight=-100; md->swtch=RawSwitch();strncpy(md->name, tr("RUD2").toAscii().data(),6);
|
||||||
|
rx[j]=true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
md=setDest(rud2ch); md->srcRaw=RawSource(SOURCE_TYPE_STICK, 0); md->weight=-100; md->swtch=RawSwitch();strncpy(md->name, tr("RUD2").toAscii().data(),6);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (flaps>0) {
|
||||||
|
md=setDest(11); md->srcRaw=RawSource(SOURCE_TYPE_MAX); md->weight=-100; md->swtch=RawSwitch(SWITCH_TYPE_SWITCH,-DSW_AIL);strncpy(md->name, tr("FLAPS").toAscii().data(),6); md->sOffset=0; md->speedUp=4;
|
||||||
|
md=setDest(11); md->srcRaw=RawSource(SOURCE_TYPE_STICK, 5); md->weight=100; md->swtch=RawSwitch(SWITCH_TYPE_SWITCH,DSW_AIL);strncpy(md->name, tr("FLAPS").toAscii().data(),6); md->sOffset=0; md->speedUp=4;
|
||||||
|
}
|
||||||
|
sign=-1;
|
||||||
|
for (uint8_t i=0; i< flaps; i++) {
|
||||||
|
sign*=-1;
|
||||||
|
int index;
|
||||||
|
if (i==0) {
|
||||||
|
index=fla1ch;
|
||||||
|
} else {
|
||||||
|
index=fla2ch;
|
||||||
|
}
|
||||||
|
if (index==0) {
|
||||||
|
for (int j=0; j<10 ; j++) {
|
||||||
|
if (!rx[j]) {
|
||||||
|
md=setDest(j+1); md->srcRaw=RawSource(SOURCE_TYPE_CH, 10); md->weight=100*sign; md->sOffset=0; md->speedUp=4; md->speedDown=4; md->swtch=RawSwitch();strncpy(md->name, tr("FLAP%1").arg(i+1).toAscii().data(),6);
|
||||||
|
rx[j]=true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
md=setDest(index); md->srcRaw=RawSource(SOURCE_TYPE_CH, 10); md->weight=100*sign; md->sOffset=0; md->speedUp=4; md->speedDown=4; md->swtch=RawSwitch();strncpy(md->name, tr("FLAP%1").arg(i+1).toAscii().data(),6);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
updateHeliTab();
|
||||||
|
updateCurvesTab();
|
||||||
|
if (modeltype==1 && swashtype!=4) {
|
||||||
|
ui->tabWidget->setCurrentIndex(1);
|
||||||
|
} else {
|
||||||
|
ui->tabWidget->setCurrentIndex(4);
|
||||||
|
}
|
||||||
|
resizeEvent();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Templates::applyTemplate(uint8_t idx)
|
||||||
|
{
|
||||||
|
int8_t heli_ar1[] = {-100, -20, 30, 70, 90};
|
||||||
|
int8_t heli_ar2[] = {80, 70, 60, 70, 100};
|
||||||
|
int8_t heli_ar3[] = {100, 90, 80, 90, 100};
|
||||||
|
int8_t heli_ar4[] = {-30, -15, 0, 50, 100};
|
||||||
|
int8_t heli_ar5[] = {-100, -50, 0, 50, 100};
|
||||||
|
|
||||||
|
int thrsw=GetEepromInterface()->getCapability(GetThrSwitch);
|
||||||
|
MixData *md = &model.mixData[0];
|
||||||
|
|
||||||
|
//CC(STK) -> vSTK
|
||||||
|
//ICC(vSTK) -> STK
|
||||||
|
#define ICC(x) icc[(x)-1]
|
||||||
|
uint8_t icc[4] = {0};
|
||||||
|
for(uint8_t i=1; i<=4; i++) //generate inverse array
|
||||||
|
for(uint8_t j=1; j<=4; j++) if(CC(i)==j) icc[j-1]=i;
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t j = 0;
|
||||||
|
|
||||||
|
//Simple 4-Ch
|
||||||
|
if(idx==j++) {
|
||||||
|
if (md->destCh)
|
||||||
|
clearMixes();
|
||||||
|
md=setDest(ICC(STK_RUD)); md->srcRaw=RawSource(SOURCE_TYPE_STICK, 0); md->weight=100; md->swtch=RawSwitch();
|
||||||
|
md=setDest(ICC(STK_ELE)); md->srcRaw=RawSource(SOURCE_TYPE_STICK, 1); md->weight=100; md->swtch=RawSwitch();
|
||||||
|
md=setDest(ICC(STK_THR)); md->srcRaw=RawSource(SOURCE_TYPE_STICK, 2); md->weight=100; md->swtch=RawSwitch();
|
||||||
|
md=setDest(ICC(STK_AIL)); md->srcRaw=RawSource(SOURCE_TYPE_STICK, 3); md->weight=100; md->swtch=RawSwitch();
|
||||||
|
}
|
||||||
|
|
||||||
|
//T-Cut
|
||||||
|
if(idx==j++) {
|
||||||
|
md=setDest(ICC(STK_THR)); md->srcRaw=RawSource(SOURCE_TYPE_MAX); md->weight=-100; md->swtch=RawSwitch(SWITCH_TYPE_SWITCH,thrsw); md->mltpx=MLTPX_REP;
|
||||||
|
}
|
||||||
|
|
||||||
|
//sticky t-cut
|
||||||
|
if(idx==j++) {
|
||||||
|
md=setDest(ICC(STK_THR)); md->srcRaw=RawSource(SOURCE_TYPE_MAX); md->weight=-100; md->swtch=RawSwitch(SWITCH_TYPE_VIRTUAL, 12); md->mltpx=MLTPX_REP;
|
||||||
|
md=setDest(14); md->srcRaw=RawSource(SOURCE_TYPE_CH, 13); md->weight= 100; md->swtch=RawSwitch();
|
||||||
|
md=setDest(14); md->srcRaw=RawSource(SOURCE_TYPE_MAX); md->weight=-100; md->swtch=RawSwitch(SWITCH_TYPE_VIRTUAL, 11); md->mltpx=MLTPX_REP;
|
||||||
|
md=setDest(14); md->srcRaw=RawSource(SOURCE_TYPE_MAX); md->weight= 100; md->swtch=RawSwitch(SWITCH_TYPE_SWITCH,thrsw); md->mltpx=MLTPX_REP;
|
||||||
|
setSwitch(0xB, CS_FN_VNEG, RawSource(SOURCE_TYPE_STICK, 2).toValue(), -99);
|
||||||
|
setSwitch(0xC, CS_FN_VPOS, RawSource(SOURCE_TYPE_CH, 13).toValue(), 0);
|
||||||
|
updateSwitchesTab();
|
||||||
|
}
|
||||||
|
|
||||||
|
//V-Tail
|
||||||
|
if(idx==j++) {
|
||||||
|
clearMixes();
|
||||||
|
md=setDest(ICC(STK_THR)); md->srcRaw=RawSource(SOURCE_TYPE_STICK, 2); md->weight=100; md->swtch=RawSwitch();
|
||||||
|
md=setDest(ICC(STK_AIL)); md->srcRaw=RawSource(SOURCE_TYPE_STICK, 3); md->weight=100; md->swtch=RawSwitch();
|
||||||
|
md=setDest(ICC(STK_RUD)); md->srcRaw=RawSource(SOURCE_TYPE_STICK, 0); md->weight= 100; md->swtch=RawSwitch();
|
||||||
|
md=setDest(ICC(STK_RUD)); md->srcRaw=RawSource(SOURCE_TYPE_STICK, 1); md->weight=-100; md->swtch=RawSwitch();
|
||||||
|
md=setDest(ICC(STK_ELE)); md->srcRaw=RawSource(SOURCE_TYPE_STICK, 0); md->weight= 100; md->swtch=RawSwitch();
|
||||||
|
md=setDest(ICC(STK_ELE)); md->srcRaw=RawSource(SOURCE_TYPE_STICK, 1); md->weight= 100; md->swtch=RawSwitch();
|
||||||
|
}
|
||||||
|
|
||||||
|
//Elevon\\Delta
|
||||||
|
if(idx==j++) {
|
||||||
|
clearMixes();
|
||||||
|
md=setDest(ICC(STK_THR)); md->srcRaw=RawSource(SOURCE_TYPE_STICK, 2); md->weight=100; md->swtch=RawSwitch();
|
||||||
|
md=setDest(ICC(STK_RUD)); md->srcRaw=RawSource(SOURCE_TYPE_STICK, 0); md->weight=100; md->swtch=RawSwitch();
|
||||||
|
md=setDest(ICC(STK_ELE)); md->srcRaw=RawSource(SOURCE_TYPE_STICK, 1); md->weight= 100; md->swtch=RawSwitch();
|
||||||
|
md=setDest(ICC(STK_ELE)); md->srcRaw=RawSource(SOURCE_TYPE_STICK, 3); md->weight= 100; md->swtch=RawSwitch();
|
||||||
|
md=setDest(ICC(STK_AIL)); md->srcRaw=RawSource(SOURCE_TYPE_STICK, 1); md->weight=-100; md->swtch=RawSwitch();
|
||||||
|
md=setDest(ICC(STK_AIL)); md->srcRaw=RawSource(SOURCE_TYPE_STICK, 3); md->weight=100; md->swtch=RawSwitch();
|
||||||
|
}
|
||||||
|
|
||||||
|
//Heli Setup
|
||||||
|
if(idx==j++) {
|
||||||
|
clearMixes(); //This time we want a clean slate
|
||||||
|
clearCurves();
|
||||||
|
|
||||||
|
// Set up Mixes
|
||||||
|
// 3 cyclic channels
|
||||||
|
md=setDest(1); md->srcRaw=RawSource(SOURCE_TYPE_CYC, 0); md->weight= 100; md->swtch=RawSwitch();
|
||||||
|
md=setDest(2); md->srcRaw=RawSource(SOURCE_TYPE_CYC, 1); md->weight= 100; md->swtch=RawSwitch();
|
||||||
|
md=setDest(3); md->srcRaw=RawSource(SOURCE_TYPE_CYC, 2); md->weight= 100; md->swtch=RawSwitch();
|
||||||
|
|
||||||
|
// rudder
|
||||||
|
md=setDest(4); md->srcRaw=RawSource(SOURCE_TYPE_STICK, 0); md->weight=100; md->swtch=RawSwitch();
|
||||||
|
|
||||||
|
// throttle
|
||||||
|
md=setDest(5); md->srcRaw=RawSource(SOURCE_TYPE_STICK, 2); md->weight= 100; md->swtch=RawSwitch(SWITCH_TYPE_SWITCH,DSW_ID0); md->curve=CV(1); md->carryTrim=TRIM_OFF;
|
||||||
|
md=setDest(5); md->srcRaw=RawSource(SOURCE_TYPE_STICK, 2); md->weight= 100; md->swtch=RawSwitch(SWITCH_TYPE_SWITCH,DSW_ID1); md->curve=CV(2); md->carryTrim=TRIM_OFF;
|
||||||
|
md=setDest(5); md->srcRaw=RawSource(SOURCE_TYPE_STICK, 2); md->weight= 100; md->swtch=RawSwitch(SWITCH_TYPE_SWITCH,DSW_ID2); md->curve=CV(3); md->carryTrim=TRIM_OFF;
|
||||||
|
md=setDest(5); md->srcRaw=RawSource(SOURCE_TYPE_MAX); md->weight=-100; md->swtch=RawSwitch(SWITCH_TYPE_SWITCH,thrsw); md->mltpx=MLTPX_REP;
|
||||||
|
|
||||||
|
// gyro gain
|
||||||
|
md=setDest(6); md->srcRaw=RawSource(SOURCE_TYPE_MAX); md->weight=30; md->swtch=RawSwitch(SWITCH_TYPE_SWITCH,-DSW_GEA);
|
||||||
|
md=setDest(6); md->srcRaw=RawSource(SOURCE_TYPE_MAX); md->weight=-30; md->swtch=RawSwitch(SWITCH_TYPE_SWITCH,DSW_GEA);
|
||||||
|
|
||||||
|
// collective
|
||||||
|
md=setDest(11); md->srcRaw=RawSource(SOURCE_TYPE_STICK, 2); md->weight=100; md->swtch=RawSwitch(SWITCH_TYPE_SWITCH,DSW_ID0); md->curve=CV(4); md->carryTrim=TRIM_OFF;
|
||||||
|
md=setDest(11); md->srcRaw=RawSource(SOURCE_TYPE_STICK, 2); md->weight=100; md->swtch=RawSwitch(SWITCH_TYPE_SWITCH,DSW_ID1); md->curve=CV(5); md->carryTrim=TRIM_OFF;
|
||||||
|
md=setDest(11); md->srcRaw=RawSource(SOURCE_TYPE_STICK, 2); md->weight=100; md->swtch=RawSwitch(SWITCH_TYPE_SWITCH,DSW_ID2); md->curve=CV(6); md->carryTrim=TRIM_OFF;
|
||||||
|
|
||||||
|
model.swashRingData.type = HELI_SWASH_TYPE_120;
|
||||||
|
model.swashRingData.collectiveSource = RawSource(SOURCE_TYPE_CH, 10);
|
||||||
|
|
||||||
|
// set up Curves
|
||||||
|
setCurve(CURVE5(1),heli_ar1);
|
||||||
|
setCurve(CURVE5(2),heli_ar2);
|
||||||
|
setCurve(CURVE5(3),heli_ar3);
|
||||||
|
setCurve(CURVE5(4),heli_ar4);
|
||||||
|
setCurve(CURVE5(5),heli_ar5);
|
||||||
|
setCurve(CURVE5(6),heli_ar5);
|
||||||
|
|
||||||
|
// make sure curves are redrawn
|
||||||
|
updateHeliTab();
|
||||||
|
updateCurvesTab();
|
||||||
|
resizeEvent();
|
||||||
|
}
|
||||||
|
|
||||||
|
//Heli Setup gyro gain control
|
||||||
|
if(idx==j++) {
|
||||||
|
clearMixes(); //This time we want a clean slate
|
||||||
|
clearCurves();
|
||||||
|
|
||||||
|
// Set up Mixes
|
||||||
|
// 3 cyclic channels
|
||||||
|
md=setDest(1); md->srcRaw=RawSource(SOURCE_TYPE_CYC, 0); md->weight= 100; md->swtch=RawSwitch();
|
||||||
|
md=setDest(2); md->srcRaw=RawSource(SOURCE_TYPE_CYC, 1); md->weight= 100; md->swtch=RawSwitch();
|
||||||
|
md=setDest(3); md->srcRaw=RawSource(SOURCE_TYPE_CYC, 2); md->weight= 100; md->swtch=RawSwitch();
|
||||||
|
|
||||||
|
// rudder
|
||||||
|
md=setDest(4); md->srcRaw=RawSource(SOURCE_TYPE_STICK, 0); md->weight=100; md->swtch=RawSwitch();
|
||||||
|
|
||||||
|
// throttle
|
||||||
|
md=setDest(5); md->srcRaw=RawSource(SOURCE_TYPE_STICK, 2); md->weight= 100; md->swtch=RawSwitch(SWITCH_TYPE_SWITCH,DSW_ID0); md->curve=CV(1); md->carryTrim=TRIM_OFF;
|
||||||
|
md=setDest(5); md->srcRaw=RawSource(SOURCE_TYPE_STICK, 2); md->weight= 100; md->swtch=RawSwitch(SWITCH_TYPE_SWITCH,DSW_ID1); md->curve=CV(2); md->carryTrim=TRIM_OFF;
|
||||||
|
md=setDest(5); md->srcRaw=RawSource(SOURCE_TYPE_STICK, 2); md->weight= 100; md->swtch=RawSwitch(SWITCH_TYPE_SWITCH,DSW_ID2); md->curve=CV(3); md->carryTrim=TRIM_OFF;
|
||||||
|
md=setDest(5); md->srcRaw=RawSource(SOURCE_TYPE_MAX); md->weight=-100; md->swtch=RawSwitch(SWITCH_TYPE_SWITCH,thrsw); md->mltpx=MLTPX_REP;
|
||||||
|
|
||||||
|
// gyro gain
|
||||||
|
md=setDest(6); md->srcRaw=RawSource(SOURCE_TYPE_STICK, 5); md->weight= 50; md->swtch=RawSwitch(SWITCH_TYPE_SWITCH,-DSW_GEA); md->sOffset=100;
|
||||||
|
md=setDest(6); md->srcRaw=RawSource(SOURCE_TYPE_STICK, 5); md->weight=-50; md->swtch=RawSwitch(SWITCH_TYPE_SWITCH,DSW_GEA); md->sOffset=100;
|
||||||
|
|
||||||
|
// collective
|
||||||
|
md=setDest(11); md->srcRaw=RawSource(SOURCE_TYPE_STICK, 2); md->weight=100; md->swtch=RawSwitch(SWITCH_TYPE_SWITCH,DSW_ID0); md->curve=CV(4); md->carryTrim=TRIM_OFF;
|
||||||
|
md=setDest(11); md->srcRaw=RawSource(SOURCE_TYPE_STICK, 2); md->weight=100; md->swtch=RawSwitch(SWITCH_TYPE_SWITCH,DSW_ID1); md->curve=CV(5); md->carryTrim=TRIM_OFF;
|
||||||
|
md=setDest(11); md->srcRaw=RawSource(SOURCE_TYPE_STICK, 2); md->weight=100; md->swtch=RawSwitch(SWITCH_TYPE_SWITCH,DSW_ID2); md->curve=CV(6); md->carryTrim=TRIM_OFF;
|
||||||
|
|
||||||
|
model.swashRingData.type = HELI_SWASH_TYPE_120;
|
||||||
|
model.swashRingData.collectiveSource = RawSource(SOURCE_TYPE_CH, 10);
|
||||||
|
|
||||||
|
// set up Curves
|
||||||
|
setCurve(CURVE5(1),heli_ar1);
|
||||||
|
setCurve(CURVE5(2),heli_ar2);
|
||||||
|
setCurve(CURVE5(3),heli_ar3);
|
||||||
|
setCurve(CURVE5(4),heli_ar4);
|
||||||
|
setCurve(CURVE5(5),heli_ar5);
|
||||||
|
setCurve(CURVE5(6),heli_ar5);
|
||||||
|
|
||||||
|
// make sure curves are redrawn
|
||||||
|
updateHeliTab();
|
||||||
|
updateCurvesTab();
|
||||||
|
resizeEvent();
|
||||||
|
}
|
||||||
|
|
||||||
|
// gyro gain control
|
||||||
|
if(idx==j++) {
|
||||||
|
int res = QMessageBox::question(this,tr("Clear Mixes?"),tr("Really clear existing mixes on CH6?"),QMessageBox::Yes | QMessageBox::No);
|
||||||
|
if(res!=QMessageBox::Yes) return;
|
||||||
|
// first clear mix on ch6
|
||||||
|
bool found=true;
|
||||||
|
while (found) {
|
||||||
|
found=false;
|
||||||
|
for (int i=0; i< GetEepromInterface()->getCapability(Mixes); i++) {
|
||||||
|
if (model.mixData[i].destCh==6) {
|
||||||
|
gm_deleteMix(i);
|
||||||
|
found=true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
md=setDest(6); md->srcRaw=RawSource(SOURCE_TYPE_STICK, 5); md->weight= 50; md->swtch=RawSwitch(SWITCH_TYPE_SWITCH,-DSW_GEA); md->sOffset=100;
|
||||||
|
md=setDest(6); md->srcRaw=RawSource(SOURCE_TYPE_STICK, 5); md->weight=-50; md->swtch=RawSwitch(SWITCH_TYPE_SWITCH,DSW_GEA); md->sOffset=100;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Heli Setup futaba style
|
||||||
|
if(idx==j++) {
|
||||||
|
clearMixes(); //This time we want a clean slate
|
||||||
|
clearCurves();
|
||||||
|
|
||||||
|
// Set up Mixes
|
||||||
|
// 3 cyclic channels
|
||||||
|
md=setDest(1); md->srcRaw=RawSource(SOURCE_TYPE_CYC, 1); md->weight= 100; md->swtch=RawSwitch();
|
||||||
|
md=setDest(2); md->srcRaw=RawSource(SOURCE_TYPE_CYC, 0); md->weight= 100; md->swtch=RawSwitch();
|
||||||
|
md=setDest(6); md->srcRaw=RawSource(SOURCE_TYPE_CYC, 2); md->weight= 100; md->swtch=RawSwitch();
|
||||||
|
|
||||||
|
// rudder
|
||||||
|
md=setDest(4); md->srcRaw=RawSource(SOURCE_TYPE_STICK, 0); md->weight=100; md->swtch=RawSwitch();
|
||||||
|
|
||||||
|
// throttle
|
||||||
|
md=setDest(3); md->srcRaw=RawSource(SOURCE_TYPE_STICK, 2); md->weight= 100; md->swtch=RawSwitch(SWITCH_TYPE_SWITCH,DSW_ID0); md->curve=CV(1); md->carryTrim=TRIM_OFF;
|
||||||
|
md=setDest(3); md->srcRaw=RawSource(SOURCE_TYPE_STICK, 2); md->weight= 100; md->swtch=RawSwitch(SWITCH_TYPE_SWITCH,DSW_ID1); md->curve=CV(2); md->carryTrim=TRIM_OFF;
|
||||||
|
md=setDest(3); md->srcRaw=RawSource(SOURCE_TYPE_STICK, 2); md->weight= 100; md->swtch=RawSwitch(SWITCH_TYPE_SWITCH,DSW_ID2); md->curve=CV(3); md->carryTrim=TRIM_OFF;
|
||||||
|
md=setDest(3); md->srcRaw=RawSource(SOURCE_TYPE_MAX); md->weight=-100; md->swtch=RawSwitch(SWITCH_TYPE_SWITCH,thrsw); md->mltpx=MLTPX_REP;
|
||||||
|
|
||||||
|
// gyro gain
|
||||||
|
md=setDest(5); md->srcRaw=RawSource(SOURCE_TYPE_MAX); md->weight=30; md->swtch=RawSwitch(SWITCH_TYPE_SWITCH,-DSW_GEA);
|
||||||
|
md=setDest(5); md->srcRaw=RawSource(SOURCE_TYPE_MAX); md->weight=-30; md->swtch=RawSwitch(SWITCH_TYPE_SWITCH,DSW_GEA);
|
||||||
|
|
||||||
|
// collective
|
||||||
|
md=setDest(11); md->srcRaw=RawSource(SOURCE_TYPE_STICK, 2); md->weight=100; md->swtch=RawSwitch(SWITCH_TYPE_SWITCH,DSW_ID0); md->curve=CV(4); md->carryTrim=TRIM_OFF;
|
||||||
|
md=setDest(11); md->srcRaw=RawSource(SOURCE_TYPE_STICK, 2); md->weight=100; md->swtch=RawSwitch(SWITCH_TYPE_SWITCH,DSW_ID1); md->curve=CV(5); md->carryTrim=TRIM_OFF;
|
||||||
|
md=setDest(11); md->srcRaw=RawSource(SOURCE_TYPE_STICK, 2); md->weight=100; md->swtch=RawSwitch(SWITCH_TYPE_SWITCH,DSW_ID2); md->curve=CV(6); md->carryTrim=TRIM_OFF;
|
||||||
|
|
||||||
|
model.swashRingData.type = HELI_SWASH_TYPE_120;
|
||||||
|
model.swashRingData.collectiveSource = RawSource(SOURCE_TYPE_CH, 10);
|
||||||
|
|
||||||
|
// set up Curves
|
||||||
|
setCurve(CURVE5(1),heli_ar1);
|
||||||
|
setCurve(CURVE5(2),heli_ar2);
|
||||||
|
setCurve(CURVE5(3),heli_ar3);
|
||||||
|
setCurve(CURVE5(4),heli_ar4);
|
||||||
|
setCurve(CURVE5(5),heli_ar5);
|
||||||
|
setCurve(CURVE5(6),heli_ar5);
|
||||||
|
|
||||||
|
// make sure curves are redrawn
|
||||||
|
updateHeliTab();
|
||||||
|
updateCurvesTab();
|
||||||
|
resizeEvent();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Heli setup futaba style with gyro gain control
|
||||||
|
if(idx==j++) {
|
||||||
|
clearMixes(); //This time we want a clean slate
|
||||||
|
clearCurves();
|
||||||
|
|
||||||
|
// Set up Mixes
|
||||||
|
// 3 cyclic channels
|
||||||
|
md=setDest(1); md->srcRaw=RawSource(SOURCE_TYPE_CYC, 1); md->weight= 100; md->swtch=RawSwitch();
|
||||||
|
md=setDest(2); md->srcRaw=RawSource(SOURCE_TYPE_CYC, 0); md->weight= 100; md->swtch=RawSwitch();
|
||||||
|
md=setDest(6); md->srcRaw=RawSource(SOURCE_TYPE_CYC, 2); md->weight= 100; md->swtch=RawSwitch();
|
||||||
|
|
||||||
|
// rudder
|
||||||
|
md=setDest(4); md->srcRaw=RawSource(SOURCE_TYPE_STICK, 0); md->weight=100; md->swtch=RawSwitch();
|
||||||
|
|
||||||
|
// throttle
|
||||||
|
md=setDest(3); md->srcRaw=RawSource(SOURCE_TYPE_STICK, 2); md->weight= 100; md->swtch=RawSwitch(SWITCH_TYPE_SWITCH,DSW_ID0); md->curve=CV(1); md->carryTrim=TRIM_OFF;
|
||||||
|
md=setDest(3); md->srcRaw=RawSource(SOURCE_TYPE_STICK, 2); md->weight= 100; md->swtch=RawSwitch(SWITCH_TYPE_SWITCH,DSW_ID1); md->curve=CV(2); md->carryTrim=TRIM_OFF;
|
||||||
|
md=setDest(3); md->srcRaw=RawSource(SOURCE_TYPE_STICK, 2); md->weight= 100; md->swtch=RawSwitch(SWITCH_TYPE_SWITCH,DSW_ID2); md->curve=CV(3); md->carryTrim=TRIM_OFF;
|
||||||
|
md=setDest(3); md->srcRaw=RawSource(SOURCE_TYPE_MAX); md->weight=-100; md->swtch=RawSwitch(SWITCH_TYPE_SWITCH,thrsw); md->mltpx=MLTPX_REP;
|
||||||
|
|
||||||
|
// gyro gain
|
||||||
|
md=setDest(5); md->srcRaw=RawSource(SOURCE_TYPE_STICK, 5); md->weight= 50; md->swtch=RawSwitch(SWITCH_TYPE_SWITCH,-DSW_GEA); md->sOffset=100;
|
||||||
|
md=setDest(5); md->srcRaw=RawSource(SOURCE_TYPE_STICK, 5); md->weight=-50; md->swtch=RawSwitch(SWITCH_TYPE_SWITCH,DSW_GEA); md->sOffset=100;
|
||||||
|
|
||||||
|
// collective
|
||||||
|
md=setDest(11); md->srcRaw=RawSource(SOURCE_TYPE_STICK, 2); md->weight=100; md->swtch=RawSwitch(SWITCH_TYPE_SWITCH,DSW_ID0); md->curve=CV(4); md->carryTrim=TRIM_OFF;
|
||||||
|
md=setDest(11); md->srcRaw=RawSource(SOURCE_TYPE_STICK, 2); md->weight=100; md->swtch=RawSwitch(SWITCH_TYPE_SWITCH,DSW_ID1); md->curve=CV(5); md->carryTrim=TRIM_OFF;
|
||||||
|
md=setDest(11); md->srcRaw=RawSource(SOURCE_TYPE_STICK, 2); md->weight=100; md->swtch=RawSwitch(SWITCH_TYPE_SWITCH,DSW_ID2); md->curve=CV(6); md->carryTrim=TRIM_OFF;
|
||||||
|
|
||||||
|
model.swashRingData.type = HELI_SWASH_TYPE_120;
|
||||||
|
model.swashRingData.collectiveSource = RawSource(SOURCE_TYPE_CH, 10);
|
||||||
|
|
||||||
|
// set up Curves
|
||||||
|
setCurve(CURVE5(1),heli_ar1);
|
||||||
|
setCurve(CURVE5(2),heli_ar2);
|
||||||
|
setCurve(CURVE5(3),heli_ar3);
|
||||||
|
setCurve(CURVE5(4),heli_ar4);
|
||||||
|
setCurve(CURVE5(5),heli_ar5);
|
||||||
|
setCurve(CURVE5(6),heli_ar5);
|
||||||
|
|
||||||
|
// make sure curves are redrawn
|
||||||
|
updateHeliTab();
|
||||||
|
updateCurvesTab();
|
||||||
|
resizeEvent();
|
||||||
|
}
|
||||||
|
|
||||||
|
// gyro gain control futaba style
|
||||||
|
if(idx==j++) {
|
||||||
|
int res = QMessageBox::question(this,tr("Clear Mixes?"),tr("Really clear existing mixes on CH5?"),QMessageBox::Yes | QMessageBox::No);
|
||||||
|
if(res!=QMessageBox::Yes) return;
|
||||||
|
// first clear mix on ch6
|
||||||
|
bool found=true;
|
||||||
|
while (found) {
|
||||||
|
found=false;
|
||||||
|
for (int i=0; i< GetEepromInterface()->getCapability(Mixes); i++) {
|
||||||
|
if (model.mixData[i].destCh==5) {
|
||||||
|
gm_deleteMix(i);
|
||||||
|
found=true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
md=setDest(5); md->srcRaw=RawSource(SOURCE_TYPE_STICK, 5); md->weight= 50; md->swtch=RawSwitch(SWITCH_TYPE_SWITCH,-DSW_GEA); md->sOffset=100;
|
||||||
|
md=setDest(5); md->srcRaw=RawSource(SOURCE_TYPE_STICK, 5); md->weight=-50; md->swtch=RawSwitch(SWITCH_TYPE_SWITCH,DSW_GEA); md->sOffset=100;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Servo Test
|
||||||
|
if(idx==j++) {
|
||||||
|
md=setDest(15); md->srcRaw=RawSource(SOURCE_TYPE_CH, 15); md->weight= 100; md->speedUp = 8; md->speedDown = 8; md->swtch=RawSwitch();
|
||||||
|
md=setDest(16); md->srcRaw=RawSource(SOURCE_TYPE_CUSTOM_SWITCH, 0); md->weight= 110; md->swtch=RawSwitch();
|
||||||
|
md=setDest(16); md->srcRaw=RawSource(SOURCE_TYPE_MAX); md->weight=-110; md->swtch=RawSwitch(SWITCH_TYPE_VIRTUAL, 2); md->mltpx=MLTPX_REP;
|
||||||
|
md=setDest(16); md->srcRaw=RawSource(SOURCE_TYPE_MAX); md->weight= 110; md->swtch=RawSwitch(SWITCH_TYPE_VIRTUAL, 3); md->mltpx=MLTPX_REP;
|
||||||
|
setSwitch(1, CS_FN_LESS, RawSource(SOURCE_TYPE_CH, 14).toValue(), RawSource(SOURCE_TYPE_CH, 15).toValue());
|
||||||
|
setSwitch(2, CS_FN_VPOS, RawSource(SOURCE_TYPE_CH, 14).toValue(), 105);
|
||||||
|
setSwitch(3, CS_FN_VNEG, RawSource(SOURCE_TYPE_CH, 14).toValue(), -105);
|
||||||
|
|
||||||
|
// redraw switches tab
|
||||||
|
updateSwitchesTab();
|
||||||
|
}
|
||||||
|
|
||||||
|
//MultiCopter
|
||||||
|
if(idx==j++) {
|
||||||
|
if (md->destCh)
|
||||||
|
clearMixes();
|
||||||
|
md=setDest(1); md->srcRaw=RawSource(SOURCE_TYPE_STICK, 3); md->weight=50; md->swtch=RawSwitch(); //CH1 AIL
|
||||||
|
md=setDest(2); md->srcRaw=RawSource(SOURCE_TYPE_STICK, 1); md->weight=-50; md->swtch=RawSwitch(); //CH2 ELE
|
||||||
|
md=setDest(3); md->srcRaw=RawSource(SOURCE_TYPE_STICK, 2); md->weight=100; md->swtch=RawSwitch(); //CH3 THR
|
||||||
|
md=setDest(4); md->srcRaw=RawSource(SOURCE_TYPE_STICK, 0); md->weight=100; md->swtch=RawSwitch(); //CH4 RUD
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MixData* Templates::setDest(uint8_t dch)
|
||||||
|
{
|
||||||
|
uint8_t i = 0;
|
||||||
|
while ((g_model.mixData[i].destCh<=dch) && (g_model.mixData[i].destCh) && (i<GetEepromInterface()->getCapability(Mixes))) i++;
|
||||||
|
if(i==GetEepromInterface()->getCapability(Mixes)) return &g_model.mixData[0];
|
||||||
|
|
||||||
|
memmove(&g_model.mixData[i+1],&g_model.mixData[i],
|
||||||
|
(GetEepromInterface()->getCapability(Mixes)-(i+1))*sizeof(MixData) );
|
||||||
|
memset(&g_model.mixData[i],0,sizeof(MixData));
|
||||||
|
g_model.mixData[i].destCh = dch;
|
||||||
|
return &g_model.mixData[i];
|
||||||
|
}
|
23
companion/src/modeledit/templates.h
Normal file
23
companion/src/modeledit/templates.h
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
#ifndef TEMPLATES_H
|
||||||
|
#define TEMPLATES_H
|
||||||
|
|
||||||
|
#include <QWidget>
|
||||||
|
#include "eeprominterface.h"
|
||||||
|
|
||||||
|
class Templates : public QWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
Templates(QWidget *parent, ModelData & model);
|
||||||
|
~Templates();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void onDoubleClicked(QModelIndex index);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void applyNumericTemplate(uint64_t tpl);
|
||||||
|
ModelData & model;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // TEMPLATES_H
|
|
@ -51,7 +51,7 @@ public:
|
||||||
}
|
}
|
||||||
bool general_settings;
|
bool general_settings;
|
||||||
uint8_t models_count;
|
uint8_t models_count;
|
||||||
uint8_t models[C9XMAX_MODELS];
|
uint8_t models[C9X_MAX_MODELS];
|
||||||
};
|
};
|
||||||
|
|
||||||
ModelsListWidget::ModelsListWidget(QWidget *parent):
|
ModelsListWidget::ModelsListWidget(QWidget *parent):
|
||||||
|
|
|
@ -48,7 +48,7 @@
|
||||||
struct CurrentSelection
|
struct CurrentSelection
|
||||||
{
|
{
|
||||||
QListWidgetItem *current_item;
|
QListWidgetItem *current_item;
|
||||||
bool selected[C9XMAX_MODELS+1];
|
bool selected[C9X_MAX_MODELS+1];
|
||||||
};
|
};
|
||||||
|
|
||||||
class ModelsListWidget : public QListWidget
|
class ModelsListWidget : public QListWidget
|
||||||
|
|
|
@ -157,7 +157,7 @@ QString printDialog::printPhases()
|
||||||
if ((GetCurrentFirmwareVariant() & GVARS_VARIANT ) || (!GetEepromInterface()->getCapability(HasVariants) && GetEepromInterface()->getCapability(Gvars))) {
|
if ((GetCurrentFirmwareVariant() & GVARS_VARIANT ) || (!GetEepromInterface()->getCapability(HasVariants) && GetEepromInterface()->getCapability(Gvars))) {
|
||||||
if (GetEepromInterface()->getCapability(GvarsFlightPhases)) {
|
if (GetEepromInterface()->getCapability(GvarsFlightPhases)) {
|
||||||
gvars=1;
|
gvars=1;
|
||||||
gvarnum=GetEepromInterface()->getCapability(GvarsNum);
|
gvarnum=GetEepromInterface()->getCapability(Gvars);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -787,7 +787,7 @@ void printDialog::printGvars()
|
||||||
int gvarnum=0;
|
int gvarnum=0;
|
||||||
if ((GetCurrentFirmwareVariant() & GVARS_VARIANT ) || (!GetEepromInterface()->getCapability(HasVariants) && GetEepromInterface()->getCapability(Gvars))) {
|
if ((GetCurrentFirmwareVariant() & GVARS_VARIANT ) || (!GetEepromInterface()->getCapability(HasVariants) && GetEepromInterface()->getCapability(Gvars))) {
|
||||||
gvars=1;
|
gvars=1;
|
||||||
gvarnum=GetEepromInterface()->getCapability(GvarsNum);
|
gvarnum=GetEepromInterface()->getCapability(Gvars);
|
||||||
}
|
}
|
||||||
if (!GetEepromInterface()->getCapability(GvarsFlightPhases) && (gvars==1 && GetEepromInterface()->getCapability(Gvars))) {
|
if (!GetEepromInterface()->getCapability(GvarsFlightPhases) && (gvars==1 && GetEepromInterface()->getCapability(Gvars))) {
|
||||||
QString str = "<table border=1 cellspacing=0 cellpadding=3 width=\"100%\">";
|
QString str = "<table border=1 cellspacing=0 cellpadding=3 width=\"100%\">";
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
#define SIMULATORDIALOG_H
|
#define SIMULATORDIALOG_H
|
||||||
|
|
||||||
#include <QDialog>
|
#include <QDialog>
|
||||||
#include "node.h"
|
#include "modeledit/node.h"
|
||||||
#include "eeprominterface.h"
|
#include "eeprominterface.h"
|
||||||
#ifdef JOYSTICKS
|
#ifdef JOYSTICKS
|
||||||
#include "joystick.h"
|
#include "joystick.h"
|
||||||
|
|
|
@ -195,7 +195,7 @@ bool XmlInterface::save(RadioData &radioData)
|
||||||
// the models
|
// the models
|
||||||
models xml_models;
|
models xml_models;
|
||||||
models::model_sequence & model_sequence (xml_models.model());
|
models::model_sequence & model_sequence (xml_models.model());
|
||||||
for (int i=0; i<C9XMAX_MODELS; i++) {
|
for (int i=0; i<C9X_MAX_MODELS; i++) {
|
||||||
ModelData & m = radioData.models[i];
|
ModelData & m = radioData.models[i];
|
||||||
if (m.used) {
|
if (m.used) {
|
||||||
model xm(m.name);
|
model xm(m.name);
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
#define XSIMULATORDIALOG_H
|
#define XSIMULATORDIALOG_H
|
||||||
|
|
||||||
#include <QDialog>
|
#include <QDialog>
|
||||||
#include "node.h"
|
#include "modeledit/node.h"
|
||||||
#include "eeprominterface.h"
|
#include "eeprominterface.h"
|
||||||
#ifdef JOYSTICKS
|
#ifdef JOYSTICKS
|
||||||
#include "joystick.h"
|
#include "joystick.h"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue