mirror of
https://github.com/opentx/opentx.git
synced 2025-07-14 20:10:08 +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
|
||||
)
|
||||
|
||||
add_subdirectory(modeledit)
|
||||
|
||||
SET( companion9x_SRCS
|
||||
eeprominterface.cpp
|
||||
hexinterface.cpp
|
||||
|
@ -137,15 +139,11 @@ SET( companion9x_SRCS
|
|||
firmwares/ersky9x/ersky9xeeprom.cpp
|
||||
firmwares/ersky9x/ersky9xinterface.cpp
|
||||
${ERSKY9X_CHECKOUT_DIRECTORY}/ersky9xsimulator.cpp
|
||||
node.cpp
|
||||
edge.cpp
|
||||
helpers.cpp
|
||||
mdichild.cpp
|
||||
generaledit.cpp
|
||||
modeledit.cpp
|
||||
modelslist.cpp
|
||||
mountlist.cpp
|
||||
mixerslist.cpp
|
||||
avroutputdialog.cpp
|
||||
preferencesdialog.cpp
|
||||
burnconfigdialog.cpp
|
||||
|
@ -155,8 +153,6 @@ SET( companion9x_SRCS
|
|||
burndialog.cpp
|
||||
printdialog.cpp
|
||||
fusesdialog.cpp
|
||||
expodialog.cpp
|
||||
mixerdialog.cpp
|
||||
logsdialog.cpp
|
||||
downloaddialog.cpp
|
||||
simulatordialog.cpp
|
||||
|
@ -175,9 +171,7 @@ SET( companion9x_MOC_HDRS
|
|||
comparedialog.h
|
||||
printdialog.h
|
||||
fusesdialog.h
|
||||
mixerdialog.h
|
||||
logsdialog.h
|
||||
expodialog.h
|
||||
contributorsdialog.h
|
||||
customizesplashdialog.h
|
||||
splashlibrary.h
|
||||
|
@ -191,9 +185,7 @@ SET( companion9x_MOC_HDRS
|
|||
xmenuwidget.h
|
||||
xsimulatordialog.h
|
||||
generaledit.h
|
||||
modeledit.h
|
||||
modelslist.h
|
||||
mixerslist.h
|
||||
mdichild.h
|
||||
mainwindow.h
|
||||
myslider.h
|
||||
|
@ -206,16 +198,13 @@ SET( companion9x_UIS
|
|||
avroutputdialog.ui
|
||||
comparedialog.ui
|
||||
fusesdialog.ui
|
||||
expodialog.ui
|
||||
logsdialog.ui
|
||||
mixerdialog.ui
|
||||
preferencesdialog.ui
|
||||
simulatordialog.ui
|
||||
xsimulatordialog.ui
|
||||
burnconfigdialog.ui
|
||||
downloaddialog.ui
|
||||
generaledit.ui
|
||||
modeledit.ui
|
||||
printdialog.ui
|
||||
contributorsdialog.ui
|
||||
customizesplashdialog.ui
|
||||
|
@ -314,7 +303,7 @@ ELSE( )
|
|||
ADD_EXECUTABLE( ${PROJECT_NAME} WIN32 ${companion9x_SRCS} ${companion9x_QM} )
|
||||
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")
|
||||
INSTALL( TARGETS ${PROJECT_NAME} DESTINATION ${CMAKE_INSTALL_PREFIX}/bin )
|
||||
|
|
|
@ -21,7 +21,7 @@ public:
|
|||
}
|
||||
bool general_settings;
|
||||
uint8_t models_count;
|
||||
uint8_t models[C9XMAX_MODELS];
|
||||
uint8_t models[C9X_MAX_MODELS];
|
||||
};
|
||||
|
||||
compareDialog::compareDialog(QWidget *parent, GeneralSettings *gg) :
|
||||
|
@ -342,7 +342,7 @@ void compareDialog::printPhases()
|
|||
gvars=1;
|
||||
}
|
||||
if (gvars==1) {
|
||||
gvarnum=GetEepromInterface()->getCapability(GvarsNum);
|
||||
gvarnum=GetEepromInterface()->getCapability(Gvars);
|
||||
}
|
||||
if ((gvars==1 && GetEepromInterface()->getCapability(GvarsFlightPhases)) || GetEepromInterface()->getCapability(RotaryEncoders)) {
|
||||
str.append("<br><table border=1 cellspacing=0 cellpadding=1 width=\"100%\">");
|
||||
|
@ -564,7 +564,7 @@ void compareDialog::printGvars()
|
|||
int gvarnum=0;
|
||||
if ((GetCurrentFirmwareVariant() & GVARS_VARIANT ) || (!GetEepromInterface()->getCapability(HasVariants) && GetEepromInterface()->getCapability(Gvars))) {
|
||||
gvars=1;
|
||||
gvarnum=GetEepromInterface()->getCapability(GvarsNum);
|
||||
gvarnum=GetEepromInterface()->getCapability(Gvars);
|
||||
}
|
||||
|
||||
if (!GetEepromInterface()->getCapability(GvarsFlightPhases) && (gvars==1 && GetEepromInterface()->getCapability(Gvars))) {
|
||||
|
|
|
@ -534,6 +534,18 @@ ModelData::ModelData()
|
|||
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()
|
||||
{
|
||||
memset(this, 0, sizeof(ModelData));
|
||||
|
@ -553,10 +565,8 @@ void ModelData::clear()
|
|||
}
|
||||
for (int i=0; i<C9X_MAX_PHASES; i++)
|
||||
phaseData[i].clear();
|
||||
for (int i=0; i<C9X_MAX_EXPOS; i++)
|
||||
expoData[i].clear();
|
||||
for (int i=0; i<C9X_MAX_MIXERS; i++)
|
||||
mixData[i].clear();
|
||||
clearInputs();
|
||||
clearMixes();
|
||||
for(int i=0; i<4; i++){
|
||||
mixData[i].destCh = i+1;
|
||||
mixData[i].srcRaw = RawSource(SOURCE_TYPE_STICK, i);
|
||||
|
|
|
@ -59,13 +59,14 @@ const uint8_t modn12x3[4][4]= {
|
|||
{4, 2, 3, 1},
|
||||
{4, 3, 2, 1} };
|
||||
|
||||
#define C9XMAX_MODELS 60
|
||||
#define C9X_MAX_MODELS 60
|
||||
#define C9X_MAX_PHASES 9
|
||||
#define C9X_MAX_MIXERS 64
|
||||
#define C9X_MAX_EXPOS 32
|
||||
#define C9X_MAX_CURVES 16
|
||||
#define MAX_POINTS 17
|
||||
#define C9X_MAX_GVARS 9
|
||||
#define C9X_MAX_POINTS 17
|
||||
#define C9X_MAX_GVARS 9
|
||||
#define C9X_MAX_ENCODERS 2
|
||||
#define NUM_SAFETY_CHNOUT 16
|
||||
#define C9X_NUM_CHNOUT 32 // number of real output channels
|
||||
#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,
|
||||
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!
|
||||
enum EnumKeys {
|
||||
KEY_MENU,
|
||||
|
@ -477,7 +490,7 @@ class CurveData {
|
|||
CurveData() { clear(5); }
|
||||
bool custom; // 0=end, 1=pos, 2=neg, 3=both
|
||||
uint8_t count;
|
||||
CurvePoint points[MAX_POINTS];
|
||||
CurvePoint points[C9X_MAX_POINTS];
|
||||
char name[6+1];
|
||||
void clear(int count) { memset(this, 0, sizeof(CurveData)); this->count = count; }
|
||||
};
|
||||
|
@ -828,6 +841,9 @@ class ModelData {
|
|||
|
||||
ModelData removeGlobalVars();
|
||||
|
||||
void clearMixes();
|
||||
void clearInputs();
|
||||
|
||||
protected:
|
||||
void removeGlobalVar(int & var);
|
||||
};
|
||||
|
@ -835,13 +851,14 @@ class ModelData {
|
|||
class RadioData {
|
||||
public:
|
||||
GeneralSettings generalSettings;
|
||||
ModelData models[C9XMAX_MODELS];
|
||||
ModelData models[C9X_MAX_MODELS];
|
||||
};
|
||||
|
||||
// TODO rename FlightPhase to FlightMode
|
||||
enum Capability {
|
||||
OwnerName,
|
||||
FlightPhases,
|
||||
FlightPhasesAreNamed,
|
||||
FlightModesName,
|
||||
FlightPhasesHaveFades,
|
||||
SimulatorType,
|
||||
Mixes,
|
||||
|
@ -867,6 +884,7 @@ enum Capability {
|
|||
CustomSwitchesExt,
|
||||
RotaryEncoders,
|
||||
Outputs,
|
||||
ChannelsName,
|
||||
ExtraChannels,
|
||||
ExtraInputs,
|
||||
ExtraTrims,
|
||||
|
@ -931,7 +949,7 @@ enum Capability {
|
|||
GvarsHaveSources,
|
||||
GvarsAsSources,
|
||||
GvarsAsWeight,
|
||||
GvarsNum,
|
||||
GvarsName,
|
||||
GvarsOfsNum,
|
||||
NoTelemetryProtocol,
|
||||
TelemetryCSFields,
|
||||
|
|
|
@ -286,8 +286,6 @@ int Er9xInterface::getCapability(const Capability capability)
|
|||
return 12;
|
||||
case CustomAndSwitches:
|
||||
return 5;
|
||||
case GvarsNum:
|
||||
return 7;
|
||||
case GvarsOfsNum:
|
||||
return 5;
|
||||
case CSFunc:
|
||||
|
@ -332,7 +330,9 @@ int Er9xInterface::getCapability(const Capability capability)
|
|||
case DiffMixers:
|
||||
case HasNegCurves:
|
||||
case HasFixOffset:
|
||||
return 1;
|
||||
case Gvars:
|
||||
return 7;
|
||||
case GvarsHaveSources:
|
||||
case GvarsAsSources:
|
||||
case GvarsAsWeight:
|
||||
|
|
|
@ -306,7 +306,7 @@ int Ersky9xInterface::getCapability(const Capability capability)
|
|||
return 2;
|
||||
case Pots:
|
||||
return 3;
|
||||
case GvarsNum:
|
||||
case Gvars:
|
||||
return 7;
|
||||
case GvarsOfsNum:
|
||||
return 5;
|
||||
|
@ -350,7 +350,6 @@ int Ersky9xInterface::getCapability(const Capability capability)
|
|||
return 125;
|
||||
case MaxVolume:
|
||||
return 23;
|
||||
case Gvars:
|
||||
case GvarsHaveSources:
|
||||
case GvarsAsSources:
|
||||
case GvarsAsWeight:
|
||||
|
|
|
@ -562,9 +562,13 @@ int Open9xInterface::getCapability(const Capability capability)
|
|||
return 6;
|
||||
else
|
||||
return 5;
|
||||
case FlightPhasesAreNamed:
|
||||
case FlightPhasesHaveFades:
|
||||
return 1;
|
||||
case Gvars:
|
||||
return 5;
|
||||
case FlightModesName:
|
||||
case GvarsName:
|
||||
return (IS_TARANIS(board) ? 10 : 6);
|
||||
case GvarsInCS:
|
||||
case GvarsAsWeight:
|
||||
case ExpoIsCurve:
|
||||
|
@ -692,8 +696,8 @@ int Open9xInterface::getCapability(const Capability capability)
|
|||
return (IS_ARM(board) ? (IS_TARANIS(board) ? 8 : 6) : false);
|
||||
case HasExpoNames:
|
||||
return (IS_ARM(board) ? (IS_TARANIS(board) ? 8 : 6) : false);
|
||||
case HasChNames:
|
||||
return (IS_TARANIS(board) ? 1 : 0);
|
||||
case ChannelsName:
|
||||
return (IS_TARANIS(board) ? 6 : 0);
|
||||
case HasCvNames:
|
||||
return (IS_TARANIS(board) ? 1 : 0);
|
||||
case NoTimerDirs:
|
||||
|
@ -777,7 +781,6 @@ int Open9xInterface::getCapability(const Capability capability)
|
|||
return (IS_ARM(board) ? 250 : 15);
|
||||
case CSFunc:
|
||||
return 18;
|
||||
case GvarsNum:
|
||||
case GvarsOfsNum:
|
||||
return 5;
|
||||
case HasSDLogs:
|
||||
|
|
|
@ -560,12 +560,9 @@ void populateTrimUseCB(QComboBox *b, unsigned int phase)
|
|||
void populateGvarUseCB(QComboBox *b, unsigned int phase)
|
||||
{
|
||||
b->addItem(QObject::tr("Own value"));
|
||||
unsigned int num_phases = GetEepromInterface()->getCapability(FlightPhases);
|
||||
if (num_phases>0) {
|
||||
for (unsigned int i = 0; i < num_phases; i++) {
|
||||
if (i != phase) {
|
||||
b->addItem(QObject::tr("Flight mode %1 value").arg(i));
|
||||
}
|
||||
for (int i=0; i<GetEepromInterface()->getCapability(FlightPhases); i++) {
|
||||
if (i != (int)phase) {
|
||||
b->addItem(QObject::tr("Flight mode %1 value").arg(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -983,7 +980,7 @@ void populateSourceCB(QComboBox *b, const RawSource &source, unsigned int flags)
|
|||
}
|
||||
|
||||
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);
|
||||
b->addItem(item.toString(), item.toValue());
|
||||
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)
|
||||
|
||||
//convert from mode 1 to mode g_eeGeneral.stickMode
|
||||
//convert from mode 1 to mode generalSettings.stickMode
|
||||
//NOTICE! => 1..4 -> 1..4
|
||||
#define CONVERT_MODE(x) (((x)<=4) ? modn12x3[g_eeGeneral.stickMode][((x)-1)] : (x))
|
||||
#define CHANNEL_ORDER(x) (chout_ar[g_eeGeneral.templateSetup*4 + (x)-1])
|
||||
#define CONVERT_MODE(x) (((x)<=4) ? modn12x3[generalSettings.stickMode][((x)-1)] : (x))
|
||||
#define CHANNEL_ORDER(x) (chout_ar[generalSettings.templateSetup*4 + (x)-1])
|
||||
|
||||
#define CURVE_BASE 7
|
||||
#define CH(x) (SRC_CH1+(x)-1-(SRC_SWC-SRC_3POS))
|
||||
|
|
|
@ -44,7 +44,7 @@
|
|||
#include "xmlinterface.h"
|
||||
#include "hexinterface.h"
|
||||
#include "mainwindow.h"
|
||||
#include "modeledit.h"
|
||||
#include "modeledit/modeledit.h"
|
||||
#include "generaledit.h"
|
||||
#include "avroutputdialog.h"
|
||||
#include "burnconfigdialog.h"
|
||||
|
@ -192,9 +192,9 @@ void MdiChild::OpenEditWindow(bool wizard=false)
|
|||
}
|
||||
}
|
||||
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);
|
||||
connect(t, SIGNAL(modelValuesChanged()), this, SLOT(setModified()));
|
||||
connect(t, SIGNAL(modified()), this, SLOT(setModified()));
|
||||
//t->exec();
|
||||
t->show();
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ modelConfigDialog::modelConfigDialog(RadioData &radioData, uint64_t * result, QW
|
|||
ui(new Ui::modelConfigDialog),
|
||||
radioData(radioData),
|
||||
result(result),
|
||||
g_eeGeneral(radioData.generalSettings)
|
||||
generalSettings(radioData.generalSettings)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
rxLock=false;
|
||||
|
@ -930,4 +930,4 @@ void modelConfigDialog::asUpdate()
|
|||
ui->asspo2_CB->hide();
|
||||
}
|
||||
rxLock=false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ private:
|
|||
int ModelType;
|
||||
RadioData &radioData;
|
||||
uint64_t * result;
|
||||
GeneralSettings g_eeGeneral;
|
||||
GeneralSettings generalSettings;
|
||||
QStringList ruddercolor;
|
||||
QStringList aileroncolor;
|
||||
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,32 +46,28 @@
|
|||
|
||||
#include "edge.h"
|
||||
#include "node.h"
|
||||
#include "modeledit.h"
|
||||
|
||||
Node::Node(QSpinBox *sb,QSpinBox *sbx)
|
||||
Node::Node():
|
||||
minX(-100),
|
||||
maxX(+100)
|
||||
{
|
||||
setFlag(ItemIsMovable);
|
||||
setFlag(ItemSendsGeometryChanges);
|
||||
setCacheMode(DeviceCoordinateCache);
|
||||
setZValue(-1);
|
||||
nodecolor = QColor(Qt::yellow);
|
||||
qsb = sb;
|
||||
qsbx = sbx;
|
||||
bPressed = false;
|
||||
centerX = true;
|
||||
centerY = true;
|
||||
fixedX = false;
|
||||
fixedY = false;
|
||||
ballSize = DEFAULT_BALL_SIZE;
|
||||
minX=-100;
|
||||
maxX=100;
|
||||
|
||||
setFlag(ItemIsMovable);
|
||||
setFlag(ItemSendsGeometryChanges);
|
||||
setCacheMode(DeviceCoordinateCache);
|
||||
setZValue(-1);
|
||||
nodecolor = QColor(Qt::yellow);
|
||||
bPressed = false;
|
||||
centerX = true;
|
||||
centerY = true;
|
||||
fixedX = false;
|
||||
fixedY = false;
|
||||
ballSize = DEFAULT_BALL_SIZE;
|
||||
}
|
||||
|
||||
void Node::addEdge(Edge *edge)
|
||||
{
|
||||
edgeList << edge;
|
||||
edge->adjust();
|
||||
edgeList << edge;
|
||||
edge->adjust();
|
||||
}
|
||||
|
||||
void Node::stepToCenter(qreal step)
|
||||
|
@ -105,7 +101,7 @@ void Node::stepToCenter(qreal step)
|
|||
|
||||
}
|
||||
|
||||
void Node::setColor(QColor color)
|
||||
void Node::setColor(const QColor & color)
|
||||
{
|
||||
nodecolor=color;
|
||||
}
|
||||
|
@ -190,26 +186,23 @@ QVariant Node::itemChange(GraphicsItemChange change, const QVariant &value)
|
|||
if(fixedY) newPos.setY(y());//make sure x doesn't change
|
||||
newPos.setX(qMin(rect.right(), qMax(newPos.x(), rect.left())));// bound X
|
||||
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();
|
||||
if (newX < minX) newX = minX;
|
||||
if (newX > maxX) newX = maxX;
|
||||
newPos.setX(((newX+100)*rect.width()/200+rect.left()));
|
||||
qsbx->setValue(newX);
|
||||
}
|
||||
modeledit->redrawCurve = true;
|
||||
|
||||
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 > maxX) newX = maxX;
|
||||
|
||||
if (!getFixedX()) {
|
||||
newPos.setX(((newX+100)*rect.width()/200+rect.left()));
|
||||
}
|
||||
|
||||
emit moved(newX, newY);
|
||||
return newPos;
|
||||
}
|
||||
break;
|
||||
case ItemPositionHasChanged:
|
||||
|
||||
foreach (Edge *edge, edgeList)
|
||||
edge->adjust();
|
||||
edge->adjust();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -222,25 +215,19 @@ void Node::mousePressEvent(QGraphicsSceneMouseEvent *event)
|
|||
{
|
||||
update();
|
||||
bPressed = true;
|
||||
if(qsb) qsb->setFocus();
|
||||
QGraphicsItem::mousePressEvent(event);
|
||||
emit focus();
|
||||
}
|
||||
|
||||
void Node::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
|
||||
{
|
||||
update();
|
||||
bPressed = false;
|
||||
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);
|
||||
}
|
||||
//need to tell SB that it needs to write the value
|
||||
} else {
|
||||
if (scene()) {
|
||||
QGraphicsItem::mouseReleaseEvent(event);
|
||||
emit unfocus();
|
||||
}
|
||||
else {
|
||||
QGraphicsItem::mouseReleaseEvent(event);
|
||||
}
|
||||
}
|
|
@ -52,11 +52,12 @@ QT_BEGIN_NAMESPACE
|
|||
class QGraphicsSceneMouseEvent;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
class Node : public QGraphicsItem
|
||||
class Node : public QGraphicsObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
Node(QSpinBox *sb = 0, QSpinBox *sbx = 0);
|
||||
public:
|
||||
Node();
|
||||
|
||||
void addEdge(Edge *edge);
|
||||
QList<Edge *> edges() const;
|
||||
|
@ -80,16 +81,19 @@ public:
|
|||
bool getFixedY() {return fixedY;}
|
||||
void setMinX(int val) {minX = val;};
|
||||
void setMaxX(int val) {maxX = val;};
|
||||
void setColor(QColor color);
|
||||
void setColor(const QColor & color);
|
||||
|
||||
protected:
|
||||
QVariant itemChange(GraphicsItemChange change, const QVariant &value);
|
||||
signals:
|
||||
void moved(int x, int y);
|
||||
void focus();
|
||||
void unfocus();
|
||||
|
||||
protected:
|
||||
QVariant itemChange(GraphicsItemChange change, const QVariant &value);
|
||||
void mousePressEvent(QGraphicsSceneMouseEvent *event);
|
||||
void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
|
||||
|
||||
private:
|
||||
|
||||
private:
|
||||
bool bPressed;
|
||||
bool centerX;
|
||||
bool centerY;
|
||||
|
@ -98,8 +102,6 @@ private:
|
|||
int ballSize;
|
||||
int minX;
|
||||
int maxX;
|
||||
QSpinBox *qsb;
|
||||
QSpinBox *qsbx;
|
||||
QList<Edge *> edgeList;
|
||||
QPointF newPos;
|
||||
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;
|
||||
uint8_t models_count;
|
||||
uint8_t models[C9XMAX_MODELS];
|
||||
uint8_t models[C9X_MAX_MODELS];
|
||||
};
|
||||
|
||||
ModelsListWidget::ModelsListWidget(QWidget *parent):
|
||||
|
|
|
@ -48,7 +48,7 @@
|
|||
struct CurrentSelection
|
||||
{
|
||||
QListWidgetItem *current_item;
|
||||
bool selected[C9XMAX_MODELS+1];
|
||||
bool selected[C9X_MAX_MODELS+1];
|
||||
};
|
||||
|
||||
class ModelsListWidget : public QListWidget
|
||||
|
|
|
@ -157,7 +157,7 @@ QString printDialog::printPhases()
|
|||
if ((GetCurrentFirmwareVariant() & GVARS_VARIANT ) || (!GetEepromInterface()->getCapability(HasVariants) && GetEepromInterface()->getCapability(Gvars))) {
|
||||
if (GetEepromInterface()->getCapability(GvarsFlightPhases)) {
|
||||
gvars=1;
|
||||
gvarnum=GetEepromInterface()->getCapability(GvarsNum);
|
||||
gvarnum=GetEepromInterface()->getCapability(Gvars);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -787,7 +787,7 @@ void printDialog::printGvars()
|
|||
int gvarnum=0;
|
||||
if ((GetCurrentFirmwareVariant() & GVARS_VARIANT ) || (!GetEepromInterface()->getCapability(HasVariants) && GetEepromInterface()->getCapability(Gvars))) {
|
||||
gvars=1;
|
||||
gvarnum=GetEepromInterface()->getCapability(GvarsNum);
|
||||
gvarnum=GetEepromInterface()->getCapability(Gvars);
|
||||
}
|
||||
if (!GetEepromInterface()->getCapability(GvarsFlightPhases) && (gvars==1 && GetEepromInterface()->getCapability(Gvars))) {
|
||||
QString str = "<table border=1 cellspacing=0 cellpadding=3 width=\"100%\">";
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
#define SIMULATORDIALOG_H
|
||||
|
||||
#include <QDialog>
|
||||
#include "node.h"
|
||||
#include "modeledit/node.h"
|
||||
#include "eeprominterface.h"
|
||||
#ifdef JOYSTICKS
|
||||
#include "joystick.h"
|
||||
|
|
|
@ -195,7 +195,7 @@ bool XmlInterface::save(RadioData &radioData)
|
|||
// the models
|
||||
models xml_models;
|
||||
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];
|
||||
if (m.used) {
|
||||
model xm(m.name);
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
#define XSIMULATORDIALOG_H
|
||||
|
||||
#include <QDialog>
|
||||
#include "node.h"
|
||||
#include "modeledit/node.h"
|
||||
#include "eeprominterface.h"
|
||||
#ifdef JOYSTICKS
|
||||
#include "joystick.h"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue