feat(color): Quick Model Select, keep active model in view when changing labels (#2895)

* Fix rebase merge issue.

* Incorporate solution from @ParkerEde in PR #2626

* Fix selection logic for models.

* Select model on first press.

* Fix quick model selection when using scroll wheel & enter button.
Add setting to enable quick model selection.

* German translation.

* Fix behaviour when 'model quick select' is off to work like existing 2.8 logic.

* Add translations.

* Prioritise active model as selected model when the set of visible models changes.

* Fix selection ordering when using scroll wheel.
Minor code cleanup.
This commit is contained in:
philmoz
2022-12-23 09:58:49 +10:00
committed by GitHub
parent c099a74da4
commit 3f08af6120
28 changed files with 218 additions and 57 deletions
@@ -213,6 +213,9 @@ Node convert<GeneralSettings>::encode(const GeneralSettings& rhs)
node["varioRange"] = rhs.varioRange * 15;
node["varioRepeat"] = rhs.varioRepeat;
node["backgroundVolume"] = rhs.backgroundVolume + 2;
if (Boards::getCapability(getCurrentFirmware()->getBoard(), Board::HasColorLcd)) {
node["modelQuickSelect"] = (int)rhs.modelQuickSelect;
}
Node serialPort;
for (int i = 0; i < GeneralSettings::SP_COUNT; i++) {
@@ -408,6 +411,7 @@ bool convert<GeneralSettings>::decode(const Node& node, GeneralSettings& rhs)
node["varioRange"] >> ifactor<int>(rhs.varioRange, 15);
node["varioRepeat"] >> rhs.varioRepeat;
node["backgroundVolume"] >> ioffset_int(rhs.backgroundVolume, 2);
node["modelQuickSelect"] >> rhs.modelQuickSelect;
// depreciated v2.7 replaced by serialPort
if (node["auxSerialMode"]) {
@@ -255,6 +255,7 @@ class GeneralSettings {
bool serialPower[SP_COUNT];
int antennaMode;
unsigned int backlightColor;
bool modelQuickSelect;
CustomFunctionData customFn[CPN_MAX_SPECIAL_FUNCTIONS];
char switchName[CPN_MAX_SWITCHES][HARDWARE_NAME_LEN + 1];
unsigned int switchConfig[CPN_MAX_SWITCHES];
@@ -471,6 +471,13 @@ void GeneralSetupPanel::setValues()
ui->pwrOffDelay->setValue(2 - generalSettings.pwrOffSpeed);
ui->registrationId->setText(generalSettings.registrationId);
if (Boards::getCapability(firmware->getBoard(), Board::HasColorLcd)) {
ui->modelQuickSelect_CB->setChecked(generalSettings.modelQuickSelect);
} else {
ui->label_modelQuickSelect->hide();
ui->modelQuickSelect_CB->hide();
}
}
void GeneralSetupPanel::on_faimode_CB_stateChanged(int)
@@ -799,3 +806,9 @@ void GeneralSetupPanel::stickReverseEdited()
generalSettings.stickReverse = ((int)ui->stickReverse1->isChecked()) | ((int)ui->stickReverse2->isChecked()<<1) | ((int)ui->stickReverse3->isChecked()<<2) | ((int)ui->stickReverse4->isChecked()<<3);
emit modified();
}
void GeneralSetupPanel::on_modelQuickSelect_CB_stateChanged(int)
{
generalSettings.modelQuickSelect = ui->modelQuickSelect_CB->isChecked();
emit modified();
}
+2
View File
@@ -93,6 +93,8 @@ class GeneralSetupPanel : public GeneralPanel
void on_pwrOnDelay_valueChanged(int);
void on_pwrOffDelay_valueChanged(int);
void on_modelQuickSelect_CB_stateChanged(int);
private:
Ui::GeneralSetup *ui;
+18 -1
View File
@@ -807,7 +807,7 @@
</property>
</widget>
</item>
<item row="22" column="0">
<item row="23" column="0">
<spacer name="verticalSpacer_3">
<property name="orientation">
<enum>Qt::Vertical</enum>
@@ -1152,6 +1152,23 @@ p, li { white-space: pre-wrap; }
<item row="21" column="1">
<widget class="QComboBox" name="rotEncMode_CB"/>
</item>
<item row="22" column="0">
<widget class="QLabel" name="label_modelQuickSelect">
<property name="text">
<string>Model quick select</string>
</property>
</widget>
</item>
<item row="22" column="1">
<widget class="QCheckBox" name="modelQuickSelect_CB">
<property name="toolTip">
<string>Enable this to quickly change model on the model select page (a long press can then be used to open the model edit menu).</string>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
</layout>
</item>
<item row="0" column="0" colspan="2">
+1 -1
View File
@@ -769,7 +769,7 @@ PACK(struct TrainerData {
NOBACKUP(char switchNames[STORAGE_NUM_SWITCHES][LEN_SWITCH_NAME] SKIP); \
NOBACKUP(char anaNames[NUM_STICKS + STORAGE_NUM_POTS + STORAGE_NUM_SLIDERS][LEN_ANA_NAME] SKIP); \
NOBACKUP(char currModelFilename[LEN_MODEL_FILENAME+1]); \
NOBACKUP(uint8_t spare5:1 SKIP); \
NOBACKUP(uint8_t modelQuickSelect:1); \
NOBACKUP(uint8_t blOffBright:7); \
NOBACKUP(char bluetoothName[LEN_BLUETOOTH_NAME]);
#else
+102 -51
View File
@@ -240,9 +240,11 @@ class ButtonHolder : public FormWindow
class ModelButton : public Button
{
public:
ModelButton(FormGroup *parent, const rect_t &rect, ModelCell *modelCell) :
ModelButton(FormGroup *parent, const rect_t &rect, ModelCell *modelCell, std::function<void()> setSelected) :
Button(parent, rect), modelCell(modelCell)
{
m_setSelected = std::move(setSelected);
lv_obj_clear_flag(lvobj, LV_OBJ_FLAG_CLICK_FOCUSABLE);
setWidth(MODEL_SELECT_CELL_WIDTH);
setHeight(MODEL_SELECT_CELL_HEIGHT);
@@ -300,39 +302,38 @@ class ModelButton : public Button
if (modelCell == modelslist.getCurrentModel()) {
dc->drawSolidFilledRect(0, 0, width(), 20, COLOR_THEME_ACTIVE);
dc->drawSizedText(width() / 2, 2, modelCell->modelName, LEN_MODEL_NAME,
COLOR_THEME_SECONDARY1 | CENTERED);
} else {
LcdFlags textColor;
dc->drawFilledRect(0, 0, width(), 20, SOLID, COLOR_THEME_PRIMARY2);
textColor = COLOR_THEME_SECONDARY1;
dc->drawSizedText(width() / 2, 2, modelCell->modelName, LEN_MODEL_NAME,
textColor | CENTERED);
}
dc->drawSizedText(width() / 2, 2, modelCell->modelName, LEN_MODEL_NAME,
COLOR_THEME_SECONDARY1 | CENTERED);
if (!hasFocus()) {
dc->drawSolidRect(0, 0, width(), height(), 1, COLOR_THEME_SECONDARY2);
} else {
dc->drawSolidRect(0, 0, width(), height(), 2, COLOR_THEME_FOCUS);
if (m_setSelected) m_setSelected();
}
}
const char *modelFilename() { return modelCell->modelFilename; }
ModelCell *getModelCell() const { return modelCell; }
void setFocused() {
if (!lv_obj_has_state(lvobj, LV_STATE_FOCUSED)) {
lv_group_focus_obj(lvobj);
}
}
protected:
bool loaded = false;
ModelCell *modelCell;
BitmapBuffer *buffer = nullptr;
std::function<void()> m_setSelected = nullptr;
void onClicked() override {
if (!lv_obj_has_state(lvobj, LV_STATE_FOCUSED)) {
lv_group_focus_obj(lvobj);
} else {
Button::onClicked();
}
setFocused();
Button::onClicked();
}
};
@@ -366,23 +367,25 @@ ModelsPageBody::ModelsPageBody(Window *parent, const rect_t &rect) :
{
setFlexLayout(LV_FLEX_FLOW_ROW_WRAP, MODEL_CELL_PADDING);
padRow(MODEL_CELL_PADDING);
update();
}
void ModelsPageBody::selectModel(ModelCell *model)
{
bool modelConnected =
TELEMETRY_STREAMING() && !g_eeGeneral.disableRssiPoweroffAlarm;
if (modelConnected) {
AUDIO_ERROR_MESSAGE(AU_MODEL_STILL_POWERED);
if (!confirmationDialog(STR_MODEL_STILL_POWERED, nullptr, false, []() {
tmr10ms_t startTime = getTicks();
while (!TELEMETRY_STREAMING()) {
if (getTicks() - startTime > TELEMETRY_CHECK_DELAY10ms) break;
}
return !TELEMETRY_STREAMING() || g_eeGeneral.disableRssiPoweroffAlarm;
})) {
return; // stop if connected but not confirmed
// Don't need to check connection to receiver if re-selecting the active model
if (model != modelslist.getCurrentModel()) {
bool modelConnected =
TELEMETRY_STREAMING() && !g_eeGeneral.disableRssiPoweroffAlarm;
if (modelConnected) {
AUDIO_ERROR_MESSAGE(AU_MODEL_STILL_POWERED);
if (!confirmationDialog(STR_MODEL_STILL_POWERED, nullptr, false, []() {
tmr10ms_t startTime = getTicks();
while (!TELEMETRY_STREAMING()) {
if (getTicks() - startTime > TELEMETRY_CHECK_DELAY10ms) break;
}
return !TELEMETRY_STREAMING() || g_eeGeneral.disableRssiPoweroffAlarm;
})) {
return; // stop if connected but not confirmed
}
}
}
@@ -390,17 +393,20 @@ void ModelsPageBody::selectModel(ModelCell *model)
auto w = Layer::back();
if (w) w->onCancel();
// store changes (if any) and load selected model
storageFlushCurrentModel();
storageCheck(true);
memcpy(g_eeGeneral.currModelFilename, model->modelFilename,
LEN_MODEL_FILENAME);
// Skip reloading model if re-selecting the active model
if (model != modelslist.getCurrentModel()) {
// store changes (if any) and load selected model
storageFlushCurrentModel();
storageCheck(true);
memcpy(g_eeGeneral.currModelFilename, model->modelFilename,
LEN_MODEL_FILENAME);
loadModel(g_eeGeneral.currModelFilename, true);
modelslist.setCurrentModel(model);
loadModel(g_eeGeneral.currModelFilename, true);
modelslist.setCurrentModel(model);
storageDirty(EE_GENERAL);
storageCheck(true);
storageDirty(EE_GENERAL);
storageCheck(true);
}
}
void ModelsPageBody::duplicateModel(ModelCell* model)
@@ -491,7 +497,22 @@ void ModelsPageBody::editLabels(ModelCell* model)
}
}
void ModelsPageBody::update(int selected)
void ModelsPageBody::openMenu()
{
Menu *menu = new Menu(this);
menu->setTitle(focusedModel->modelName);
if (g_eeGeneral.modelQuickSelect || focusedModel != modelslist.getCurrentModel()) {
menu->addLine(STR_SELECT_MODEL, [=]() { selectModel(focusedModel); });
}
menu->addLine(STR_DUPLICATE_MODEL, [=]() { duplicateModel(focusedModel); });
menu->addLine(STR_EDIT_LABELS, [=]() { editLabels(focusedModel); });
menu->addLine(STR_SAVE_TEMPLATE, [=]() { saveAsTemplate(focusedModel);});
if (focusedModel != modelslist.getCurrentModel()) {
menu->addLine(STR_DELETE_MODEL, [=]() { deleteModel(focusedModel); });
}
}
void ModelsPageBody::update()
{
clear();
@@ -502,24 +523,54 @@ void ModelsPageBody::update(int selected)
models = modelslabels.getAllModels();
}
for (auto &model : models) {
auto button = new ModelButton(this, rect_t{}, model);
// Used to work out which button to set focus to.
// Priority -
// current active model
// previously selected model
// first model in the list
ModelButton* firstButton = nullptr;
ModelButton* focusedButton = nullptr;
// Long Press Handler for Models
for (auto &model : models) {
auto button = new ModelButton(this, rect_t{}, model, [=]() {
focusedModel = model;
});
if (!firstButton)
firstButton = button;
if (model == modelslist.getCurrentModel())
focusedButton = button;
if (model == focusedModel && !focusedButton)
focusedButton = button;
// Press Handler for Models
button->setPressHandler([=]() -> uint8_t {
Menu *menu = new Menu(this);
menu->setTitle(model->modelName);
if (model != modelslist.getCurrentModel()) {
menu->addLine(STR_SELECT_MODEL, [=]() { selectModel(model); });
if (model == focusedModel) {
if (g_eeGeneral.modelQuickSelect)
selectModel(model);
else
openMenu();
} else {
focusedModel = model;
}
menu->addLine(STR_DUPLICATE_MODEL, [=]() { duplicateModel(model); });
if (model != modelslist.getCurrentModel()) {
menu->addLine(STR_DELETE_MODEL, [=]() { deleteModel(model); });
}
menu->addLine(STR_EDIT_LABELS, [=]() { editLabels(model); });
menu->addLine(STR_SAVE_TEMPLATE, [=]() { saveAsTemplate(model);});
return 0;
});
// Long Press Handler for Models
button->setLongPressHandler([=]() -> uint8_t {
if (model == focusedModel) {
openMenu();
}
return 0;
});
}
if (!focusedButton)
focusedButton = firstButton;
if (focusedButton) {
focusedButton->setFocused();
focusedModel = focusedButton->getModelCell();
}
}
@@ -580,8 +631,8 @@ class LabelDialog : public Dialog
ModelLabelsWindow::ModelLabelsWindow() : Page(ICON_MODEL)
{
buildBody(&body);
buildHead(&header);
buildBody(&body);
// find the first label of the current model and make that label active
auto currentModel = modelslist.getCurrentModel();
+4 -1
View File
@@ -37,12 +37,13 @@ class ModelsPageBody : public FormWindow
public:
ModelsPageBody(Window *parent, const rect_t &rect);
void update();
void setLabels(LabelsVector labels)
{
selectedLabels = labels;
update();
}
void update(int selected = -1);
inline void setSortOrder(ModelsSortBy sortOrder)
{
@@ -61,8 +62,10 @@ class ModelsPageBody : public FormWindow
bool refresh = false;
std::string selectedLabel;
LabelsVector selectedLabels;
ModelCell *focusedModel = nullptr;
std::function<void()> refreshLabels = nullptr;
void openMenu();
void selectModel(ModelCell* model);
void duplicateModel(ModelCell* model);
void deleteModel(ModelCell* model);
+6
View File
@@ -765,4 +765,10 @@ void RadioSetupPage::build(FormWindow * window)
std::string(
&getSourceString(MIXSRC_Rud + modn12x3[4 * value + 1])[1]);
});
grid.setColSpan(1);
// Model quick select
line = window->newLine(&grid);
new StaticText(line, rect_t{}, STR_MODEL_QUICK_SELECT, 0, COLOR_THEME_PRIMARY1);
new CheckBox(line, rect_t{}, GET_SET_DEFAULT(g_eeGeneral.modelQuickSelect));
}
@@ -434,7 +434,7 @@ static const struct YamlNode struct_RadioData[] = {
YAML_PADDING( 192 ),
YAML_PADDING( 216 ),
YAML_STRING("currModelFilename", 17),
YAML_PADDING( 1 ),
YAML_UNSIGNED( "modelQuickSelect", 1 ),
YAML_UNSIGNED( "blOffBright", 7 ),
YAML_STRING("bluetoothName", 10),
YAML_STRING("themeName", 8),
@@ -463,7 +463,7 @@ static const struct YamlNode struct_RadioData[] = {
YAML_PADDING( 240 ),
YAML_PADDING( 360 ),
YAML_STRING("currModelFilename", 17),
YAML_PADDING( 1 ),
YAML_UNSIGNED( "modelQuickSelect", 1 ),
YAML_UNSIGNED( "blOffBright", 7 ),
YAML_STRING("bluetoothName", 10),
YAML_STRING("themeName", 8),
@@ -461,7 +461,7 @@ static const struct YamlNode struct_RadioData[] = {
YAML_PADDING( 240 ),
YAML_PADDING( 312 ),
YAML_STRING("currModelFilename", 17),
YAML_PADDING( 1 ),
YAML_UNSIGNED( "modelQuickSelect", 1 ),
YAML_UNSIGNED( "blOffBright", 7 ),
YAML_STRING("bluetoothName", 10),
YAML_STRING("themeName", 8),
+1
View File
@@ -814,6 +814,7 @@ const char STR_WIDGET_VALUE[] = TR_WIDGET_VALUE;
const char STR_MODULES_RX_VERSION[] = TR_MODULES_RX_VERSION;
const char STR_LEFT_STICK[] = TR_LEFT_STICK;
const char STR_SHOW_MIXER_MONITORS[] = TR_SHOW_MIXER_MONITORS;
const char STR_MODEL_QUICK_SELECT[] = TR_MODEL_QUICK_SELECT;
#endif
#if !defined(COLORLCD)
+1
View File
@@ -723,6 +723,7 @@ extern const char STR_WIDGET_VALUE[];
extern const char STR_MODULES_RX_VERSION[];
extern const char STR_LEFT_STICK[];
extern const char STR_SHOW_MIXER_MONITORS[];
extern const char STR_MODEL_QUICK_SELECT[];
#endif
extern const char STR_EXECUTE_FILE[];
extern const char STR_DELETE_FILE[];
+4
View File
@@ -762,6 +762,10 @@
#define TR_SAMPLE_MODE "采样模式"
#define TR_SAMPLE_MODES "标准","OneBit"
#if defined(COLORLCD)
#define TR_MODEL_QUICK_SELECT "快速选择模型"
#endif
#define TR_SELECT_TEMPLATE_FOLDER "选择一个模板文件夹:"
#define TR_SELECT_TEMPLATE "选择一个模板:"
#define TR_NO_TEMPLATES "在此文件夹中未找到模型模板"
+4
View File
@@ -780,6 +780,10 @@
#define TR_SAMPLE_MODE "Sample Mode"
#define TR_SAMPLE_MODES "Normal","OneBit"
#if defined(COLORLCD)
#define TR_MODEL_QUICK_SELECT "Rychlý výběr modelu"
#endif
#define TR_SELECT_TEMPLATE_FOLDER "VYBRAT SLOŽKU SE ŠABLONOU:"
#define TR_SELECT_TEMPLATE "VYBRAT ŠABLONU MODELU:"
#define TR_NO_TEMPLATES "Žádná šablona modelu v této složce nebyla nalezena"
+4
View File
@@ -767,6 +767,10 @@
#define TR_SAMPLE_MODE "Måle tilstand"
#define TR_SAMPLE_MODES "Normal","EnBit"
#if defined(COLORLCD)
#define TR_MODEL_QUICK_SELECT "Hurtigvalg af model"
#endif
#define TR_SELECT_TEMPLATE_FOLDER "VÆLG EN SKABELON MAPPE:"
#define TR_SELECT_TEMPLATE "VÆLG EN SKABELON til MODEL:"
#define TR_NO_TEMPLATES "Ingen model skabeloner fundet i mappe"
+4
View File
@@ -763,6 +763,10 @@
#define TR_SAMPLE_MODES "Normal","OneBit"
#if defined(COLORLCD)
#define TR_MODEL_QUICK_SELECT "schnelle Modellauswahl"
#endif
#define TR_SELECT_TEMPLATE_FOLDER "WÄHLE VORLAGENVERZEICHNIS:"
#define TR_SELECT_TEMPLATE "WÄHLE MODELLVORLAGE:"
#define TR_NO_TEMPLATES "Es wurden keine Modellvorlagen in diesem Verzeichnis gefunden"
+4
View File
@@ -762,6 +762,10 @@
#define TR_SAMPLE_MODE "Sample Mode"
#define TR_SAMPLE_MODES "Normal","OneBit"
#if defined(COLORLCD)
#define TR_MODEL_QUICK_SELECT "Model quick select"
#endif
#define TR_SELECT_TEMPLATE_FOLDER "Select a template folder"
#define TR_SELECT_TEMPLATE "SELECT A MODEL TEMPLATE:"
#define TR_NO_TEMPLATES "No model templates were found in this folder"
+5
View File
@@ -763,6 +763,11 @@
#define TR_SAMPLE_MODE "Modo de muestra"
#define TR_SAMPLE_MODES "Normal","OneBit"
#if defined(COLORLCD)
#define TR_MODEL_QUICK_SELECT "Model quick select"
#endif
#define TR_SELECT_TEMPLATE_FOLDER "Select a template folder"
#define TR_SELECT_TEMPLATE "SELECT A MODEL TEMPLATE:"
#define TR_NO_TEMPLATES "No model templates were found in this folder"
+4
View File
@@ -789,6 +789,10 @@
#define TR_SAMPLE_MODE "Sample Mode"
#define TR_SAMPLE_MODES "Normal","OneBit"
#if defined(COLORLCD)
#define TR_MODEL_QUICK_SELECT "Mallin pikavalinta"
#endif
#define TR_SELECT_TEMPLATE_FOLDER "SELECT A TEMPLATE FOLDER:"
#define TR_SELECT_TEMPLATE "SELECT A MODEL TEMPLATE:"
#define TR_NO_TEMPLATES "No model templates were found in this folder"
+5
View File
@@ -782,6 +782,11 @@
#define TR_BAUDRATE "Baudrate"
#define TR_SAMPLE_MODE "Sample Mode"
#define TR_SAMPLE_MODES "Normal""OneBit"
#if defined(COLORLCD)
#define TR_MODEL_QUICK_SELECT "Model quick select"
#endif
#define TR_SELECT_TEMPLATE_FOLDER "Select a template folder"
#define TR_SELECT_TEMPLATE "SELECT A MODEL TEMPLATE:"
#define TR_NO_TEMPLATES "No model templates were found in this folder"
+5
View File
@@ -762,6 +762,11 @@
#define TR_BAUDRATE "Baudrate"
#define TR_SAMPLE_MODE "Modo Semplice"
#define TR_SAMPLE_MODES "Normale","OneBit"
#if defined(COLORLCD)
#define TR_MODEL_QUICK_SELECT "Selezione veloce modello"
#endif
#define TR_SELECT_TEMPLATE_FOLDER "SELEZIONA CARTELLA TEMPLATE:"
#define TR_SELECT_TEMPLATE "SELEZIONA TEMPLATE MODELLO:"
#define TR_NO_TEMPLATES "Nessun modello template in questa cartella"
+4
View File
@@ -762,6 +762,10 @@
#define TR_SAMPLE_MODE "サンプルモード"
#define TR_SAMPLE_MODES "標準","OneBit"
#if defined(COLORLCD)
#define TR_MODEL_QUICK_SELECT "モデル クイックセレクト"
#endif
#define TR_SELECT_TEMPLATE_FOLDER "テンプレートフォルダを選択:"
#define TR_SELECT_TEMPLATE "モデルテンプレートを選択:"
#define TR_NO_TEMPLATES "このフォルダにモデルテンプレートは見つかりませんでした"
+5
View File
@@ -767,6 +767,11 @@
#define TR_BAUDRATE "Baudrate"
#define TR_SAMPLE_MODE "Sample Mode"
#define TR_SAMPLE_MODES "Normal""OneBit"
#if defined(COLORLCD)
#define TR_MODEL_QUICK_SELECT "Model quick select"
#endif
#define TR_SELECT_TEMPLATE_FOLDER "Select a template folder"
#define TR_SELECT_TEMPLATE "SELECT A MODEL TEMPLATE:"
#define TR_NO_TEMPLATES "No model templates were found in this folder"
+5
View File
@@ -758,6 +758,11 @@
#define TR_BAUDRATE "Baudrate"
#define TR_SAMPLE_MODE "Sample Mode"
#define TR_SAMPLE_MODES "Normal","OneBit"
#if defined(COLORLCD)
#define TR_MODEL_QUICK_SELECT "Szybki wybór modelu"
#endif
#define TR_SELECT_TEMPLATE_FOLDER "Wybierz folder szablonu"
#define TR_SELECT_TEMPLATE "WYBIERZ SZABLON MODELU:"
#define TR_NO_TEMPLATES "Brak szablonów modeli w tym folderze"
+5
View File
@@ -764,6 +764,11 @@
#define TR_BAUDRATE "Baudrate"
#define TR_SAMPLE_MODE "Sample Mode"
#define TR_SAMPLE_MODES "Normal","OneBit"
#if defined(COLORLCD)
#define TR_MODEL_QUICK_SELECT "Model quick select"
#endif
#define TR_SELECT_TEMPLATE_FOLDER "Select a template folder"
#define TR_SELECT_TEMPLATE "SELECT A MODEL TEMPLATE:"
#define TR_NO_TEMPLATES "No model templates were found in this folder"
+4
View File
@@ -803,6 +803,10 @@
#define TR_SAMPLE_MODE TR("Sample mod.", "Sample Mode")
#define TR_SAMPLE_MODES "Normal","OneBit"
#if defined(COLORLCD)
#define TR_MODEL_QUICK_SELECT "Snabbval av modell"
#endif
#define TR_SELECT_TEMPLATE_FOLDER "VÄLJ EN MALLKATALOG:"
#define TR_SELECT_TEMPLATE "VÄLJ EN MODELLMALL:"
#define TR_NO_TEMPLATES "Ingen modellmall finns i denna katalog"