Moved main screen decoration to ViewMain
This commit is contained in:
@@ -99,7 +99,7 @@ void loadCustomScreens()
|
||||
|
||||
void Layout::decorate()
|
||||
{
|
||||
// check if deco setting are still up-to-date
|
||||
// Check if deco setting are still up-to-date
|
||||
uint8_t checkSettings =
|
||||
(hasTopbar() ? 1 << 0 : 0) |
|
||||
(hasSliders() ? 1 << 1 : 0) |
|
||||
@@ -111,139 +111,20 @@ void Layout::decorate()
|
||||
return;
|
||||
}
|
||||
|
||||
// kill all decorations & re-decorate
|
||||
for (auto deco: decorations) {
|
||||
deco->deleteLater();
|
||||
}
|
||||
decorations.clear();
|
||||
topBar = nullptr;
|
||||
|
||||
// effect a full redraw
|
||||
invalidate();
|
||||
|
||||
// save settings
|
||||
// Save settings
|
||||
decorationSettings = checkSettings;
|
||||
|
||||
if (hasTopbar()) {
|
||||
topBar = new TopBar(this);
|
||||
topBar->load();
|
||||
decorations.push_back(topBar);
|
||||
}
|
||||
auto viewMain = ViewMain::instance();
|
||||
|
||||
if (hasSliders()) {
|
||||
#if defined(HARDWARE_EXT1) || defined(HARDWARE_EXT2)
|
||||
coord_t yOffset = (hasTrims() ? - TRIM_SQUARE_SIZE : 0) + (hasTopbar() ? TOPBAR_HEIGHT / 2 : 0);
|
||||
#endif
|
||||
// Set visible decoration
|
||||
viewMain->setTopbarVisible(hasTopbar());
|
||||
viewMain->setSlidersVisible(hasSliders());
|
||||
viewMain->setTrimsVisible(hasTrims());
|
||||
viewMain->setFlightModeVisible(hasFlightMode());
|
||||
|
||||
decorations.push_back(
|
||||
new MainViewHorizontalSlider(this, {HMARGIN, LCD_H - TRIM_SQUARE_SIZE, HORIZONTAL_SLIDERS_WIDTH, TRIM_SQUARE_SIZE},
|
||||
[=] { return calibratedAnalogs[CALIBRATED_POT1]; })
|
||||
);
|
||||
|
||||
if (IS_POT_MULTIPOS(POT2)) {
|
||||
decorations.push_back(
|
||||
new MainView6POS(this, {LCD_W / 2 - MULTIPOS_W / 2, LCD_H - TRIM_SQUARE_SIZE, MULTIPOS_W + 1, MULTIPOS_H},
|
||||
[=] { return (1 + (potsPos[1] & 0x0f)); })
|
||||
);
|
||||
}
|
||||
else if (IS_POT(POT2)) {
|
||||
decorations.push_back(
|
||||
new MainViewHorizontalSlider(this, {LCD_W - HORIZONTAL_SLIDERS_WIDTH - HMARGIN, LCD_H - TRIM_SQUARE_SIZE, HORIZONTAL_SLIDERS_WIDTH, TRIM_SQUARE_SIZE},
|
||||
[=] { return calibratedAnalogs[CALIBRATED_POT2]; })
|
||||
);
|
||||
}
|
||||
|
||||
#if defined(HARDWARE_POT3)
|
||||
decorations.push_back(
|
||||
new MainViewHorizontalSlider(this, {LCD_W - HORIZONTAL_SLIDERS_WIDTH - HMARGIN, LCD_H - TRIM_SQUARE_SIZE, HORIZONTAL_SLIDERS_WIDTH, TRIM_SQUARE_SIZE},
|
||||
[=] { return calibratedAnalogs[CALIBRATED_POT3]; })
|
||||
);
|
||||
#endif
|
||||
|
||||
#if defined(HARDWARE_EXT1)
|
||||
if (IS_POT_SLIDER_AVAILABLE(EXT1)) {
|
||||
decorations.push_back(
|
||||
new MainViewVerticalSlider(this, {HMARGIN, LCD_H / 2 - VERTICAL_SLIDERS_HEIGHT(hasTopbar()) / 2 + yOffset, TRIM_SQUARE_SIZE, VERTICAL_SLIDERS_HEIGHT(hasTopbar()) / 2},
|
||||
[=] { return calibratedAnalogs[CALIBRATED_SLIDER_REAR_LEFT]; })
|
||||
);
|
||||
decorations.push_back(
|
||||
new MainViewVerticalSlider(this, {HMARGIN, LCD_H / 2 + yOffset, TRIM_SQUARE_SIZE, VERTICAL_SLIDERS_HEIGHT(hasTopbar()) / 2},
|
||||
[=] { return calibratedAnalogs[CALIBRATED_POT_EXT1]; })
|
||||
);
|
||||
}
|
||||
else {
|
||||
decorations.push_back(
|
||||
new MainViewVerticalSlider(this, {HMARGIN, LCD_H / 2 - VERTICAL_SLIDERS_HEIGHT(hasTopbar()) / 2 + yOffset, TRIM_SQUARE_SIZE, VERTICAL_SLIDERS_HEIGHT(hasTopbar())},
|
||||
[=] { return calibratedAnalogs[CALIBRATED_SLIDER_REAR_LEFT]; })
|
||||
);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(HARDWARE_EXT2)
|
||||
if (IS_POT_SLIDER_AVAILABLE(EXT2)) {
|
||||
decorations.push_back(
|
||||
new MainViewVerticalSlider(this, {LCD_W - HMARGIN - TRIM_SQUARE_SIZE, LCD_H / 2 - VERTICAL_SLIDERS_HEIGHT(hasTopbar()) / 2 + yOffset, TRIM_SQUARE_SIZE,
|
||||
VERTICAL_SLIDERS_HEIGHT(hasTopbar()) / 2},
|
||||
[=] { return calibratedAnalogs[CALIBRATED_SLIDER_REAR_RIGHT]; })
|
||||
);
|
||||
decorations.push_back(
|
||||
new MainViewVerticalSlider(this, {LCD_W - HMARGIN - TRIM_SQUARE_SIZE, LCD_H / 2 + yOffset, TRIM_SQUARE_SIZE,
|
||||
VERTICAL_SLIDERS_HEIGHT(hasTopbar()) / 2},
|
||||
[=] { return calibratedAnalogs[CALIBRATED_POT_EXT2]; })
|
||||
);
|
||||
}
|
||||
else {
|
||||
decorations.push_back(
|
||||
new MainViewVerticalSlider(this, {LCD_W - HMARGIN - TRIM_SQUARE_SIZE, LCD_H / 2 - VERTICAL_SLIDERS_HEIGHT(hasTopbar()) / 2 + yOffset, TRIM_SQUARE_SIZE,
|
||||
VERTICAL_SLIDERS_HEIGHT(hasTopbar())},
|
||||
[=] { return calibratedAnalogs[CALIBRATED_SLIDER_REAR_RIGHT]; })
|
||||
);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (hasTrims()) {
|
||||
#if defined(HARDWARE_POT3) || defined(HARDWARE_EXT1)
|
||||
coord_t xOffset = hasSliders() ? TRIM_SQUARE_SIZE : 0;
|
||||
#else
|
||||
coord_t xOffset = 0;
|
||||
#endif
|
||||
coord_t yOffset = (hasTrims() ? - TRIM_SQUARE_SIZE : 0);
|
||||
|
||||
// Trim order TRIM_LH, TRIM_LV, TRIM_RV, TRIM_RH
|
||||
|
||||
// Left
|
||||
decorations.push_back(
|
||||
new MainViewHorizontalTrim(this, {HMARGIN, LCD_H - TRIM_SQUARE_SIZE + yOffset, HORIZONTAL_SLIDERS_WIDTH, TRIM_SQUARE_SIZE},
|
||||
[=] { return getTrimValue(mixerCurrentFlightMode, 0); })
|
||||
);
|
||||
|
||||
// Right
|
||||
decorations.push_back(
|
||||
new MainViewHorizontalTrim(this, {LCD_W - HORIZONTAL_SLIDERS_WIDTH - HMARGIN, LCD_H - TRIM_SQUARE_SIZE + yOffset, HORIZONTAL_SLIDERS_WIDTH, TRIM_SQUARE_SIZE},
|
||||
[=] { return getTrimValue(mixerCurrentFlightMode, 3); })
|
||||
);
|
||||
|
||||
// Left
|
||||
decorations.push_back(
|
||||
new MainViewVerticalTrim(this, {HMARGIN + xOffset, LCD_H /2 - VERTICAL_SLIDERS_HEIGHT(hasTopbar()) / 2 + yOffset + (hasTopbar() ? TOPBAR_HEIGHT / 2 : 0), TRIM_SQUARE_SIZE, VERTICAL_SLIDERS_HEIGHT(hasTopbar())},
|
||||
[=] { return getTrimValue(mixerCurrentFlightMode, 1); })
|
||||
);
|
||||
|
||||
// Right
|
||||
decorations.push_back(
|
||||
new MainViewVerticalTrim(this, {LCD_W - HMARGIN - TRIM_SQUARE_SIZE - xOffset, LCD_H /2 - VERTICAL_SLIDERS_HEIGHT(hasTopbar()) / 2 + yOffset + (hasTopbar() ? TOPBAR_HEIGHT / 2 : 0), TRIM_SQUARE_SIZE, VERTICAL_SLIDERS_HEIGHT(hasTopbar())},
|
||||
[=] { return getTrimValue(mixerCurrentFlightMode, 2); })
|
||||
);
|
||||
}
|
||||
|
||||
if (hasFlightMode()) {
|
||||
decorations.push_back(
|
||||
new DynamicText(this, {50, LCD_H - 4 - (hasSliders() ? 2 * TRIM_SQUARE_SIZE: TRIM_SQUARE_SIZE), LCD_W - 100, 20}, [=] {
|
||||
return g_model.flightModeData[mixerCurrentFlightMode].name;
|
||||
}, CENTERED)
|
||||
);
|
||||
}
|
||||
// Re-compute positions
|
||||
viewMain->adjustDecoration();
|
||||
viewMain->invalidate();
|
||||
}
|
||||
|
||||
rect_t Layout::getMainZone(rect_t zone) const
|
||||
|
||||
@@ -111,14 +111,14 @@ class Layout: public LayoutBase
|
||||
|
||||
protected:
|
||||
const LayoutFactory * factory;
|
||||
TopBar * topBar = nullptr;
|
||||
uint8_t decorationSettings = 0;
|
||||
std::list<Window*> decorations;
|
||||
|
||||
// adds trims, sliders, pots, etc...
|
||||
// Decoration settings bitmask to detect updates
|
||||
uint8_t decorationSettings = 0;
|
||||
|
||||
// Updates settings for trims, sliders, pots, etc...
|
||||
void decorate();
|
||||
|
||||
// get the Zone rect without decoration
|
||||
// Get the Zone rect without decoration
|
||||
rect_t getMainZone(rect_t zone) const;
|
||||
};
|
||||
|
||||
|
||||
@@ -32,6 +32,7 @@ constexpr coord_t HMARGIN = 5;
|
||||
constexpr coord_t HORIZONTAL_SLIDERS_WIDTH = SLIDER_TICKS_COUNT * 4 + TRIM_SQUARE_SIZE;
|
||||
constexpr coord_t MULTIPOS_H = 20;
|
||||
constexpr coord_t MULTIPOS_W = 50;
|
||||
|
||||
inline coord_t VERTICAL_SLIDERS_HEIGHT(bool topbar)
|
||||
{
|
||||
return topbar ? SLIDER_TICKS_COUNT * 4 + TRIM_SQUARE_SIZE : SLIDER_TICKS_COUNT * 5 + TRIM_SQUARE_SIZE;
|
||||
@@ -40,16 +41,16 @@ inline coord_t VERTICAL_SLIDERS_HEIGHT(bool topbar)
|
||||
class MainViewSlider : public Window
|
||||
{
|
||||
public:
|
||||
MainViewSlider(Window * parent, const rect_t & rect, std::function<int16_t()> getValue):
|
||||
MainViewSlider(Window * parent, const rect_t & rect, uint8_t idx):
|
||||
Window(parent, rect),
|
||||
getValue(std::move(getValue))
|
||||
idx(idx)
|
||||
{
|
||||
}
|
||||
|
||||
void checkEvents() override
|
||||
{
|
||||
Window::checkEvents();
|
||||
int16_t newValue = getValue();
|
||||
int16_t newValue = calibratedAnalogs[idx];
|
||||
if (value != newValue) {
|
||||
value = newValue;
|
||||
invalidate();
|
||||
@@ -57,8 +58,8 @@ class MainViewSlider : public Window
|
||||
}
|
||||
|
||||
protected:
|
||||
std::function<int16_t()> getValue;
|
||||
int8_t value = 0;
|
||||
uint8_t idx;
|
||||
int16_t value = 0;
|
||||
};
|
||||
|
||||
class MainViewHorizontalSlider : public MainViewSlider
|
||||
@@ -80,7 +81,6 @@ class MainViewHorizontalSlider : public MainViewSlider
|
||||
}
|
||||
|
||||
// The square
|
||||
auto value = - getValue();
|
||||
x = width() - TRIM_SQUARE_SIZE - divRoundClosest((width() - TRIM_SQUARE_SIZE) * (value + RESX), 2 * RESX);
|
||||
drawTrimSquare(dc, x, 0, TRIM_BGCOLOR);
|
||||
}
|
||||
@@ -102,7 +102,7 @@ class MainView6POS : public MainViewSlider
|
||||
}
|
||||
|
||||
// The square
|
||||
auto value = getValue();
|
||||
auto value = 1 + (potsPos[idx] & 0x0f);
|
||||
x = TRIM_SQUARE_SIZE / 2 + divRoundClosest((width() - TRIM_SQUARE_SIZE) * (value -1) , 6);
|
||||
drawTrimSquare(dc, x, 0, TRIM_BGCOLOR);
|
||||
dc->drawNumber(x + 1, 0, value, FOCUS_COLOR);
|
||||
@@ -129,7 +129,6 @@ class MainViewVerticalSlider : public MainViewSlider
|
||||
}
|
||||
|
||||
// The square
|
||||
auto value = getValue();
|
||||
y = height() - TRIM_SQUARE_SIZE - divRoundClosest((height() - TRIM_SQUARE_SIZE) * (value + RESX), 2 * RESX);
|
||||
drawTrimSquare(dc, 0, y, TRIM_BGCOLOR);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "trims.h"
|
||||
#include "opentx.h"
|
||||
|
||||
void MainViewTrim::checkEvents()
|
||||
{
|
||||
Window::checkEvents();
|
||||
int8_t newValue = getTrimValue(mixerCurrentFlightMode, idx);
|
||||
if (value != newValue) {
|
||||
value = newValue;
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
void MainViewHorizontalTrim::paint(BitmapBuffer * dc)
|
||||
{
|
||||
int32_t trimMin, trimMax;
|
||||
if (g_model.extendedTrims) {
|
||||
trimMin = TRIM_EXTENDED_MIN;
|
||||
trimMax = TRIM_EXTENDED_MAX;
|
||||
}
|
||||
else {
|
||||
trimMin = TRIM_MIN;
|
||||
trimMax = TRIM_MAX;
|
||||
}
|
||||
|
||||
// Trim line
|
||||
lcdSetColor(GREY); // TODO add a color
|
||||
dc->drawSolidFilledRect(TRIM_SQUARE_SIZE / 2, (height() - TRIM_LINE_WIDTH - 1) / 2, width() - TRIM_SQUARE_SIZE + 1, TRIM_LINE_WIDTH, CUSTOM_COLOR);
|
||||
|
||||
// Trim square
|
||||
coord_t x = divRoundClosest((width() - TRIM_SQUARE_SIZE) * (value - trimMin), trimMax - trimMin);
|
||||
drawTrimSquare(dc, x, 0, (value < TRIM_MIN || value > TRIM_MAX) ? HIGHLIGHT_COLOR /* TODO add a color */ : TRIM_BGCOLOR);
|
||||
|
||||
// Trim value / small lines on the square
|
||||
if (g_model.displayTrims == DISPLAY_TRIMS_ALWAYS) {
|
||||
// TODO DISPLAY_TRIMS_CHANGE
|
||||
dc->drawNumber(x + (TRIM_SQUARE_SIZE + 1) / 2, 3, divRoundClosest(value * 100, trimMax), FONT(XXS) | FOCUS_COLOR | CENTERED);
|
||||
}
|
||||
else {
|
||||
if (value >= 0) {
|
||||
dc->drawSolidVerticalLine(x + 4, 3, 9, FOCUS_COLOR);
|
||||
}
|
||||
if (value <= 0) {
|
||||
dc->drawSolidVerticalLine(x + 10, 3, 9, FOCUS_COLOR);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MainViewVerticalTrim::paint(BitmapBuffer * dc)
|
||||
{
|
||||
int32_t trimMin, trimMax;
|
||||
if (g_model.extendedTrims) {
|
||||
trimMin = TRIM_EXTENDED_MIN;
|
||||
trimMax = TRIM_EXTENDED_MAX;
|
||||
}
|
||||
else {
|
||||
trimMin = TRIM_MIN;
|
||||
trimMax = TRIM_MAX;
|
||||
}
|
||||
|
||||
// Trim line
|
||||
lcdSetColor(GREY); // TODO add a color
|
||||
dc->drawSolidFilledRect((width() - TRIM_LINE_WIDTH) / 2, TRIM_SQUARE_SIZE / 2, TRIM_LINE_WIDTH, height() - TRIM_SQUARE_SIZE + 1, CUSTOM_COLOR);
|
||||
|
||||
// Trim square
|
||||
coord_t y = height() - TRIM_SQUARE_SIZE - divRoundClosest((height() - TRIM_SQUARE_SIZE) * (value - trimMin), trimMax - trimMin);
|
||||
drawTrimSquare(dc, 0, y, (value < TRIM_MIN || value > TRIM_MAX) ? HIGHLIGHT_COLOR /* TODO add a color */ : TRIM_BGCOLOR);
|
||||
|
||||
// Trim value / small lines on the square
|
||||
if (g_model.displayTrims == DISPLAY_TRIMS_ALWAYS) {
|
||||
// TODO DISPLAY_TRIMS_CHANGE
|
||||
dc->drawNumber((TRIM_SQUARE_SIZE + 1) / 2, y + 3, divRoundClosest(value * 100, trimMax), FONT(XXS) | FOCUS_COLOR | CENTERED);
|
||||
}
|
||||
else {
|
||||
if (value >= 0) {
|
||||
dc->drawSolidHorizontalLine(3, y + 4, 9, FOCUS_COLOR);
|
||||
}
|
||||
if (value <= 0) {
|
||||
dc->drawSolidHorizontalLine(3, y + 10, 9, FOCUS_COLOR);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -25,25 +25,17 @@
|
||||
class MainViewTrim : public Window
|
||||
{
|
||||
public:
|
||||
MainViewTrim(Window * parent, const rect_t & rect, std::function<int16_t()> getValue):
|
||||
MainViewTrim(Window * parent, const rect_t & rect, uint8_t idx):
|
||||
Window(parent, rect),
|
||||
getValue(std::move(getValue))
|
||||
idx(idx)
|
||||
{
|
||||
}
|
||||
|
||||
void checkEvents() override
|
||||
{
|
||||
Window::checkEvents();
|
||||
int8_t newValue = getValue();
|
||||
if (value != newValue) {
|
||||
value = newValue;
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
void checkEvents() override;
|
||||
|
||||
protected:
|
||||
std::function<int16_t()> getValue;
|
||||
int8_t value = 0;
|
||||
uint8_t idx;
|
||||
int value = 0;
|
||||
};
|
||||
|
||||
class MainViewHorizontalTrim : public MainViewTrim
|
||||
@@ -51,41 +43,7 @@ class MainViewHorizontalTrim : public MainViewTrim
|
||||
public:
|
||||
using MainViewTrim::MainViewTrim;
|
||||
|
||||
void paint(BitmapBuffer * dc) override
|
||||
{
|
||||
int32_t trimMin, trimMax;
|
||||
if (g_model.extendedTrims) {
|
||||
trimMin = TRIM_EXTENDED_MIN;
|
||||
trimMax = TRIM_EXTENDED_MAX;
|
||||
}
|
||||
else {
|
||||
trimMin = TRIM_MIN;
|
||||
trimMax = TRIM_MAX;
|
||||
}
|
||||
|
||||
// Trim line
|
||||
lcdSetColor(GREY); // TODO add a color
|
||||
dc->drawSolidFilledRect(TRIM_SQUARE_SIZE / 2, (height() - TRIM_LINE_WIDTH - 1) / 2, width() - TRIM_SQUARE_SIZE + 1, TRIM_LINE_WIDTH, CUSTOM_COLOR);
|
||||
|
||||
// Trim square
|
||||
auto value = getValue();
|
||||
coord_t x = divRoundClosest((width() - TRIM_SQUARE_SIZE) * (value - trimMin), trimMax - trimMin);
|
||||
drawTrimSquare(dc, x, 0, (value < TRIM_MIN || value > TRIM_MAX) ? HIGHLIGHT_COLOR /* TODO add a color */ : TRIM_BGCOLOR);
|
||||
|
||||
// Trim value / small lines on the square
|
||||
if (g_model.displayTrims == DISPLAY_TRIMS_ALWAYS) {
|
||||
// TODO DISPLAY_TRIMS_CHANGE
|
||||
dc->drawNumber(x + (TRIM_SQUARE_SIZE + 1) / 2, 3, divRoundClosest(value * 100, trimMax), FONT(XXS) | FOCUS_COLOR | CENTERED);
|
||||
}
|
||||
else {
|
||||
if (value >= 0) {
|
||||
dc->drawSolidVerticalLine(x + 4, 3, 9, FOCUS_COLOR);
|
||||
}
|
||||
if (value <= 0) {
|
||||
dc->drawSolidVerticalLine(x + 10, 3, 9, FOCUS_COLOR);
|
||||
}
|
||||
}
|
||||
}
|
||||
void paint(BitmapBuffer * dc) override;
|
||||
};
|
||||
|
||||
class MainViewVerticalTrim : public MainViewTrim
|
||||
@@ -93,39 +51,5 @@ class MainViewVerticalTrim : public MainViewTrim
|
||||
public:
|
||||
using MainViewTrim::MainViewTrim;
|
||||
|
||||
void paint(BitmapBuffer * dc) override
|
||||
{
|
||||
int32_t trimMin, trimMax;
|
||||
if (g_model.extendedTrims) {
|
||||
trimMin = TRIM_EXTENDED_MIN;
|
||||
trimMax = TRIM_EXTENDED_MAX;
|
||||
}
|
||||
else {
|
||||
trimMin = TRIM_MIN;
|
||||
trimMax = TRIM_MAX;
|
||||
}
|
||||
|
||||
// Trim line
|
||||
lcdSetColor(GREY); // TODO add a color
|
||||
dc->drawSolidFilledRect((width() - TRIM_LINE_WIDTH) / 2, TRIM_SQUARE_SIZE / 2, TRIM_LINE_WIDTH, height() - TRIM_SQUARE_SIZE + 1, CUSTOM_COLOR);
|
||||
|
||||
// Trim square
|
||||
auto value = getValue();
|
||||
coord_t y = height() - TRIM_SQUARE_SIZE - divRoundClosest((height() - TRIM_SQUARE_SIZE) * (value - trimMin), trimMax - trimMin);
|
||||
drawTrimSquare(dc, 0, y, (value < TRIM_MIN || value > TRIM_MAX) ? HIGHLIGHT_COLOR /* TODO add a color */ : TRIM_BGCOLOR);
|
||||
|
||||
// Trim value / small lines on the square
|
||||
if (g_model.displayTrims == DISPLAY_TRIMS_ALWAYS) {
|
||||
// TODO DISPLAY_TRIMS_CHANGE
|
||||
dc->drawNumber((TRIM_SQUARE_SIZE + 1) / 2, y + 3, divRoundClosest(value * 100, trimMax), FONT(XXS) | FOCUS_COLOR | CENTERED);
|
||||
}
|
||||
else {
|
||||
if (value >= 0) {
|
||||
dc->drawSolidHorizontalLine(3, y + 4, 9, FOCUS_COLOR);
|
||||
}
|
||||
if (value <= 0) {
|
||||
dc->drawSolidHorizontalLine(3, y + 10, 9, FOCUS_COLOR);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
void paint(BitmapBuffer * dc) override;
|
||||
};
|
||||
|
||||
@@ -83,28 +83,25 @@ void RadioCalibrationPage::buildBody(FormWindow * window)
|
||||
|
||||
#if defined(PCBHORUS)
|
||||
|
||||
new MainViewHorizontalSlider(this, {HMARGIN, LCD_H - TRIM_SQUARE_SIZE, HORIZONTAL_SLIDERS_WIDTH, TRIM_SQUARE_SIZE},
|
||||
[=] { return calibratedAnalogs[CALIBRATED_POT1]; });
|
||||
new MainViewHorizontalSlider(this, {HMARGIN, LCD_H - TRIM_SQUARE_SIZE, HORIZONTAL_SLIDERS_WIDTH, TRIM_SQUARE_SIZE}, CALIBRATED_POT1);
|
||||
|
||||
if (IS_POT_MULTIPOS(POT2)) {
|
||||
new MainView6POS(this, {LCD_W / 2 - MULTIPOS_W / 2, LCD_H - TRIM_SQUARE_SIZE, MULTIPOS_W + 1, MULTIPOS_H},
|
||||
[=] { return (1 + (potsPos[1] & 0x0f)); });
|
||||
new MainView6POS(this, {LCD_W / 2 - MULTIPOS_W / 2, LCD_H - TRIM_SQUARE_SIZE, MULTIPOS_W + 1, MULTIPOS_H}, 1);
|
||||
}
|
||||
|
||||
new MainViewHorizontalSlider(this, {LCD_W - HORIZONTAL_SLIDERS_WIDTH - HMARGIN, LCD_H - TRIM_SQUARE_SIZE, HORIZONTAL_SLIDERS_WIDTH, TRIM_SQUARE_SIZE},
|
||||
[=] { return calibratedAnalogs[CALIBRATED_POT3]; });
|
||||
new MainViewHorizontalSlider(this, {LCD_W - HORIZONTAL_SLIDERS_WIDTH - HMARGIN, LCD_H - TRIM_SQUARE_SIZE, HORIZONTAL_SLIDERS_WIDTH, TRIM_SQUARE_SIZE}, CALIBRATED_POT3);
|
||||
#if defined(HARDWARE_EXT1)
|
||||
coord_t yOffset = TOPBAR_HEIGHT / 2;
|
||||
|
||||
if (IS_POT_SLIDER_AVAILABLE(EXT1)) {
|
||||
new MainViewVerticalSlider(this, {HMARGIN, LCD_H / 2 - VERTICAL_SLIDERS_HEIGHT(true) / 2 + yOffset, TRIM_SQUARE_SIZE, VERTICAL_SLIDERS_HEIGHT(true) / 2},
|
||||
[=] { return calibratedAnalogs[CALIBRATED_SLIDER_REAR_LEFT]; });
|
||||
CALIBRATED_SLIDER_REAR_LEFT);
|
||||
new MainViewVerticalSlider(this, {HMARGIN, LCD_H / 2 + yOffset, TRIM_SQUARE_SIZE, VERTICAL_SLIDERS_HEIGHT(true) / 2},
|
||||
[=] { return calibratedAnalogs[CALIBRATED_POT_EXT1]; });
|
||||
CALIBRATED_POT_EXT1);
|
||||
}
|
||||
else {
|
||||
new MainViewVerticalSlider(this, {HMARGIN, LCD_H / 2 - VERTICAL_SLIDERS_HEIGHT(true) / 2 + yOffset, TRIM_SQUARE_SIZE, VERTICAL_SLIDERS_HEIGHT(true)},
|
||||
[=] { return calibratedAnalogs[CALIBRATED_SLIDER_REAR_LEFT]; });
|
||||
CALIBRATED_SLIDER_REAR_LEFT);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -112,23 +109,22 @@ void RadioCalibrationPage::buildBody(FormWindow * window)
|
||||
if (IS_POT_SLIDER_AVAILABLE(EXT2)) {
|
||||
new MainViewVerticalSlider(this, {LCD_W - HMARGIN - TRIM_SQUARE_SIZE, LCD_H / 2 - VERTICAL_SLIDERS_HEIGHT(true) / 2 + yOffset, TRIM_SQUARE_SIZE,
|
||||
VERTICAL_SLIDERS_HEIGHT(true) / 2},
|
||||
[=] { return calibratedAnalogs[CALIBRATED_SLIDER_REAR_RIGHT]; });
|
||||
CALIBRATED_SLIDER_REAR_RIGHT);
|
||||
new MainViewVerticalSlider(this, {LCD_W - HMARGIN - TRIM_SQUARE_SIZE, LCD_H / 2 + yOffset, TRIM_SQUARE_SIZE,
|
||||
VERTICAL_SLIDERS_HEIGHT(true) / 2},
|
||||
[=] { return calibratedAnalogs[CALIBRATED_POT_EXT2]; });
|
||||
CALIBRATED_POT_EXT2);
|
||||
}
|
||||
else {
|
||||
new MainViewVerticalSlider(this, {LCD_W - HMARGIN - TRIM_SQUARE_SIZE, LCD_H / 2 - VERTICAL_SLIDERS_HEIGHT(true) / 2 + yOffset, TRIM_SQUARE_SIZE,
|
||||
VERTICAL_SLIDERS_HEIGHT(true)},
|
||||
[=] { return calibratedAnalogs[CALIBRATED_SLIDER_REAR_RIGHT]; });
|
||||
CALIBRATED_SLIDER_REAR_RIGHT);
|
||||
}
|
||||
#endif
|
||||
#elif defined(PCBNV14)
|
||||
new MainViewHorizontalSlider(this, {HMARGIN, LCD_H - TRIM_SQUARE_SIZE, HORIZONTAL_SLIDERS_WIDTH, TRIM_SQUARE_SIZE},
|
||||
[=] { return calibratedAnalogs[CALIBRATED_POT1]; });
|
||||
|
||||
new MainViewHorizontalSlider(this, {LCD_W - HORIZONTAL_SLIDERS_WIDTH - HMARGIN, LCD_H - TRIM_SQUARE_SIZE, HORIZONTAL_SLIDERS_WIDTH, TRIM_SQUARE_SIZE},
|
||||
[=] { return calibratedAnalogs[CALIBRATED_POT2]; });
|
||||
#elif defined(PCBNV14)
|
||||
new MainViewHorizontalSlider(this, {HMARGIN, LCD_H - TRIM_SQUARE_SIZE, HORIZONTAL_SLIDERS_WIDTH, TRIM_SQUARE_SIZE}, CALIBRATED_POT1);
|
||||
|
||||
new MainViewHorizontalSlider(this, {LCD_W - HORIZONTAL_SLIDERS_WIDTH - HMARGIN, LCD_H - TRIM_SQUARE_SIZE, HORIZONTAL_SLIDERS_WIDTH, TRIM_SQUARE_SIZE}, CALIBRATED_POT2);
|
||||
|
||||
new TextButton(window, {LCD_W - 120, LCD_H - 140, 90, 40}, "Next",
|
||||
[=]() -> uint8_t {
|
||||
|
||||
@@ -1,690 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "opentx.h"
|
||||
|
||||
uint8_t THEME_ICONS[] = {
|
||||
ICON_THEME,
|
||||
ICON_THEME_SETUP,
|
||||
ICON_THEME_VIEW1,
|
||||
ICON_THEME_VIEW2,
|
||||
ICON_THEME_VIEW3,
|
||||
ICON_THEME_VIEW4,
|
||||
ICON_THEME_VIEW5,
|
||||
ICON_THEME_ADD_VIEW,
|
||||
};
|
||||
|
||||
Layout * currentScreen;
|
||||
WidgetsContainerInterface * currentContainer;
|
||||
Widget * currentWidget;
|
||||
uint8_t currentZone;
|
||||
bool widgetNeedsSettings;
|
||||
|
||||
#define SCREENS_SETUP_2ND_COLUMN 200
|
||||
|
||||
char fileSelection[LEN_ZONE_OPTION_STRING];
|
||||
uint8_t fileSelectionDone;
|
||||
|
||||
int updateMainviewsMenu();
|
||||
bool menuScreenAdd(event_t event);
|
||||
void onScreenSetupMenu(const char * result);
|
||||
|
||||
void onZoneOptionFileSelectionMenu(const char * result)
|
||||
{
|
||||
if (result == STR_UPDATE_LIST) {
|
||||
if (!sdListFiles(BITMAPS_PATH, BITMAPS_EXT, LEN_ZONE_OPTION_STRING, nullptr)) {
|
||||
POPUP_WARNING(STR_NO_BITMAPS_ON_SD);
|
||||
}
|
||||
}
|
||||
else if (result != STR_EXIT) {
|
||||
fileSelectionDone = true;
|
||||
memcpy(fileSelection, result, sizeof(fileSelection));
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t getZoneOptionColumns(const ZoneOption * option)
|
||||
{
|
||||
if (option->type == ZoneOption::Color) {
|
||||
return uint8_t(2 | NAVIGATION_LINE_BY_LINE);
|
||||
}
|
||||
else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t editColorPart(coord_t x, coord_t y, event_t event, uint8_t part, uint8_t value, LcdFlags attr, uint32_t i_flags)
|
||||
{
|
||||
const char * STR_COLOR_PARTS = "\002" "R:" "G:" "B:";
|
||||
uint8_t PART_BITS[] = { 5, 6, 5 };
|
||||
lcdDrawTextAtIndex(x, y, STR_COLOR_PARTS, part, (attr && menuHorizontalPosition < 0) ? FOCUS_COLOR : DEFAULT_COLOR);
|
||||
lcdDrawNumber(x + 20, y, value << (8-PART_BITS[part]), LEFT|DEFAULT_COLOR|((attr && (menuHorizontalPosition < 0 || menuHorizontalPosition == part)) ? attr : DEFAULT_COLOR));
|
||||
if (attr && menuHorizontalPosition == part) {
|
||||
value = checkIncDec(event, value, 0, (1 << PART_BITS[part])-1, i_flags);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
bool editZoneOption(coord_t y, const ZoneOption * option, ZoneOptionValue * value, LcdFlags attr, uint32_t i_flags, event_t event)
|
||||
{
|
||||
lcdDrawText(MENUS_MARGIN_LEFT, y, option->name);
|
||||
|
||||
if (option->type == ZoneOption::Bool) {
|
||||
value->boolValue = editCheckBox(value->boolValue, SCREENS_SETUP_2ND_COLUMN, y, attr, event); // TODO always does storageDirty(EE_MODEL)
|
||||
}
|
||||
else if (option->type == ZoneOption::Integer) {
|
||||
lcdDrawNumber(SCREENS_SETUP_2ND_COLUMN, y, value->signedValue, attr | LEFT);
|
||||
if (attr) {
|
||||
CHECK_INCDEC_MODELVAR(event, value->signedValue, option->min.signedValue, option->max.signedValue); // TODO i_flags
|
||||
}
|
||||
}
|
||||
else if (option->type == ZoneOption::String) {
|
||||
editName(SCREENS_SETUP_2ND_COLUMN, y, value->stringValue, sizeof(value->stringValue), event, attr); // TODO i_flags?
|
||||
}
|
||||
else if (option->type == ZoneOption::File) {
|
||||
if (ZEXIST(value->stringValue))
|
||||
lcdDrawSizedText(SCREENS_SETUP_2ND_COLUMN, y, value->stringValue, sizeof(value->stringValue), attr);
|
||||
else
|
||||
lcdDrawTextAtIndex(SCREENS_SETUP_2ND_COLUMN, y, STR_VCSWFUNC, 0, attr); // TODO define
|
||||
if (attr) {
|
||||
if (event==EVT_KEY_FIRST(KEY_ENTER)) {
|
||||
s_editMode = 0;
|
||||
if (sdListFiles(BITMAPS_PATH, BITMAPS_EXT, sizeof(value->stringValue), value->stringValue, LIST_NONE_SD_FILE)) {
|
||||
fileSelectionDone = false;
|
||||
POPUP_MENU_START(onZoneOptionFileSelectionMenu);
|
||||
}
|
||||
else {
|
||||
POPUP_WARNING(STR_NO_BITMAPS_ON_SD);
|
||||
}
|
||||
}
|
||||
else if (fileSelectionDone) {
|
||||
memcpy(value->stringValue, fileSelection, sizeof(fileSelection));
|
||||
fileSelectionDone = false;
|
||||
storageDirty(i_flags);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (option->type == ZoneOption::TextSize) {
|
||||
lcdDrawTextAtIndex(SCREENS_SETUP_2ND_COLUMN, y, STR_TEXT_SIZE, value->unsignedValue, attr);
|
||||
if (attr) {
|
||||
value->unsignedValue = checkIncDec(event, value->unsignedValue, 0, 4, i_flags);
|
||||
}
|
||||
}
|
||||
else if (option->type == ZoneOption::Timer) {
|
||||
drawStringWithIndex(SCREENS_SETUP_2ND_COLUMN, y, STR_TIMER, value->unsignedValue + 1, attr);
|
||||
if (attr) {
|
||||
value->unsignedValue = checkIncDec(event, value->unsignedValue, 0, MAX_TIMERS - 1, i_flags);
|
||||
}
|
||||
}
|
||||
else if (option->type == ZoneOption::Source) {
|
||||
drawSource(SCREENS_SETUP_2ND_COLUMN, y, value->unsignedValue, attr);
|
||||
if (attr) {
|
||||
CHECK_INCDEC_MODELSOURCE(event, value->unsignedValue, 1, MIXSRC_LAST_TELEM);
|
||||
}
|
||||
}
|
||||
else if (option->type == ZoneOption::Color) {
|
||||
RGB_SPLIT(value->unsignedValue, r, g, b);
|
||||
|
||||
if (attr && menuHorizontalPosition < 0) {
|
||||
lcdDrawSolidFilledRect(SCREENS_SETUP_2ND_COLUMN-3, y-1, 230, FH+1, FOCUS_BGCOLOR);
|
||||
}
|
||||
|
||||
lcdSetColor(value->unsignedValue);
|
||||
lcdDrawSolidFilledRect(SCREENS_SETUP_2ND_COLUMN-1, y+1, 42, 17, DEFAULT_COLOR);
|
||||
lcdDrawSolidFilledRect(SCREENS_SETUP_2ND_COLUMN, y+2, 40, 15, CUSTOM_COLOR);
|
||||
|
||||
r = editColorPart(SCREENS_SETUP_2ND_COLUMN + 50, y, event, 0, r, attr, i_flags);
|
||||
g = editColorPart(SCREENS_SETUP_2ND_COLUMN + 110, y, event, 1, g, attr, i_flags);
|
||||
b = editColorPart(SCREENS_SETUP_2ND_COLUMN + 170, y, event, 2, b, attr, i_flags);
|
||||
|
||||
if (attr && checkIncDec_Ret) {
|
||||
value->unsignedValue = RGB_JOIN(r, g, b);
|
||||
}
|
||||
}
|
||||
|
||||
return (attr && checkIncDec_Ret);
|
||||
}
|
||||
|
||||
int getOptionsCount(const ZoneOption * options)
|
||||
{
|
||||
if (options == nullptr) {
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
int count = 0;
|
||||
for (const ZoneOption * option = options; option->name; option++) {
|
||||
count++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
}
|
||||
|
||||
template <class T>
|
||||
bool menuSettings(const char * title, T * object, uint32_t i_flags, event_t event)
|
||||
{
|
||||
|
||||
if (object->getErrorMessage()) {
|
||||
// display error instead of widget settings
|
||||
// TODO nicer display (proper word-wrap)
|
||||
SIMPLE_SUBMENU("Widget Error", ICON_MODEL_LUA_SCRIPTS, 1);
|
||||
int len = strlen(object->getErrorMessage());
|
||||
int y = 3*FH;
|
||||
const char * p = object->getErrorMessage();
|
||||
while (len > 0) {
|
||||
lcdDrawSizedText(MENUS_MARGIN_LEFT, y, p, 30);
|
||||
p += 30;
|
||||
y += FH;
|
||||
len -= 30;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
const ZoneOption * options = object->getOptions();
|
||||
linesCount = getOptionsCount(options);
|
||||
uint8_t mstate_tab[MAX_WIDGET_OPTIONS];
|
||||
for (int i=0; i<linesCount; i++) {
|
||||
mstate_tab[i] = getZoneOptionColumns(&options[i]);
|
||||
}
|
||||
|
||||
CUSTOM_SUBMENU_WITH_OPTIONS(title, ICON_THEME, linesCount, OPTION_MENU_TITLE_BAR);
|
||||
|
||||
for (int i=0; i<NUM_BODY_LINES+1; i++) {
|
||||
coord_t y = MENU_CONTENT_TOP + i * FH;
|
||||
int k = i + menuVerticalOffset;
|
||||
LcdFlags blink = ((s_editMode>0) ? BLINK|INVERS : INVERS);
|
||||
LcdFlags attr = (menuVerticalPosition == k ? blink : 0);
|
||||
if (k < linesCount) {
|
||||
const ZoneOption * option = &options[k];
|
||||
ZoneOptionValue * value = object->getOptionValue(k);
|
||||
if (editZoneOption(y, option, value, attr, i_flags, event)) {
|
||||
object->update();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool menuWidgetSettings(event_t event)
|
||||
{
|
||||
return menuSettings<Widget>(STR_WIDGET_SETTINGS, currentWidget, EE_MODEL, event);
|
||||
}
|
||||
|
||||
bool menuWidgetChoice(event_t event)
|
||||
{
|
||||
static Widget * previousWidget = nullptr;
|
||||
static Widget * currentWidget = nullptr;
|
||||
static std::list<const WidgetFactory *>::const_iterator iterator;
|
||||
static Widget::PersistentData tempData;
|
||||
|
||||
switch (event) {
|
||||
case EVT_ENTRY:
|
||||
{
|
||||
previousWidget = currentContainer->getWidget(currentZone);
|
||||
currentContainer->setWidget(currentZone, nullptr);
|
||||
iterator = getRegisteredWidgets().cbegin();
|
||||
if (previousWidget) {
|
||||
const WidgetFactory * factory = previousWidget->getFactory();
|
||||
std::list<const WidgetFactory *>::const_iterator it = getRegisteredWidgets().cbegin();
|
||||
for (; it != getRegisteredWidgets().cend(); ++it) {
|
||||
if (factory->getName() == (*it)->getName()) {
|
||||
iterator = it;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (iterator != getRegisteredWidgets().cend())
|
||||
currentWidget = (*iterator)->create(currentContainer->getZone(currentZone), &tempData);
|
||||
break;
|
||||
}
|
||||
|
||||
case EVT_KEY_FIRST(KEY_EXIT):
|
||||
if (previousWidget) {
|
||||
if (currentWidget)
|
||||
delete currentWidget;
|
||||
currentContainer->setWidget(currentZone, previousWidget);
|
||||
}
|
||||
popMenu();
|
||||
return false;
|
||||
|
||||
case EVT_KEY_FIRST(KEY_ENTER):
|
||||
if (iterator != getRegisteredWidgets().cend()) {
|
||||
if (previousWidget)
|
||||
delete previousWidget;
|
||||
currentContainer->createWidget(currentZone, *iterator);
|
||||
widgetNeedsSettings = currentContainer->getWidget(currentZone)->getFactory()->getOptions();
|
||||
storageDirty(EE_MODEL);
|
||||
}
|
||||
popMenu();
|
||||
return false;
|
||||
|
||||
case EVT_ROTARY_RIGHT:
|
||||
if (iterator != getRegisteredWidgets().cend() && iterator != --getRegisteredWidgets().cend()) {
|
||||
++iterator;
|
||||
if (currentWidget)
|
||||
delete currentWidget;
|
||||
currentWidget = (*iterator)->create(currentContainer->getZone(currentZone), &tempData);
|
||||
}
|
||||
break;
|
||||
|
||||
case EVT_ROTARY_LEFT:
|
||||
if (iterator != getRegisteredWidgets().cbegin()) {
|
||||
--iterator;
|
||||
if (currentWidget)
|
||||
delete currentWidget;
|
||||
currentWidget = (*iterator)->create(currentContainer->getZone(currentZone), &tempData);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
currentScreen->refresh();
|
||||
|
||||
Zone zone = currentContainer->getZone(currentZone);
|
||||
lcdDrawFilledRect(0, 0, zone.x-2, LCD_H, SOLID, OVERLAY_COLOR | OPACITY(8));
|
||||
lcdDrawFilledRect(zone.x+zone.w+2, 0, LCD_W-zone.x-zone.w-2, LCD_H, SOLID, OVERLAY_COLOR | OPACITY(8));
|
||||
lcdDrawFilledRect(zone.x-2, 0, zone.w+4, zone.y-2, SOLID, OVERLAY_COLOR | OPACITY(8));
|
||||
lcdDrawFilledRect(zone.x-2, zone.y+zone.h+2, zone.w+4, LCD_H-zone.y-zone.h-2, SOLID, OVERLAY_COLOR | OPACITY(8));
|
||||
|
||||
if (currentWidget)
|
||||
currentWidget->refresh();
|
||||
|
||||
if (iterator != getRegisteredWidgets().cbegin()) {
|
||||
lcdDrawBitmapPattern(zone.x-10, zone.y+zone.h/2-10, LBM_SWIPE_CIRCLE, FOCUS_BGCOLOR);
|
||||
lcdDrawBitmapPattern(zone.x-10, zone.y+zone.h/2-10, LBM_SWIPE_LEFT, FOCUS_COLOR);
|
||||
}
|
||||
if (iterator != --getRegisteredWidgets().cend()) {
|
||||
lcdDrawBitmapPattern(zone.x+zone.w-9, zone.y+zone.h/2-10, LBM_SWIPE_CIRCLE, FOCUS_BGCOLOR);
|
||||
lcdDrawBitmapPattern(zone.x+zone.w-9, zone.y+zone.h/2-10, LBM_SWIPE_RIGHT, FOCUS_COLOR);
|
||||
}
|
||||
if (currentWidget)
|
||||
lcdDrawText(zone.x + zone.w, zone.y-1, currentWidget->getFactory()->getName(), RIGHT | DEFAULT_COLOR | FONT(XS) | INVERS);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void onZoneMenu(const char * result)
|
||||
{
|
||||
if (result == STR_SELECT_WIDGET) {
|
||||
pushMenu(menuWidgetChoice);
|
||||
}
|
||||
else if (result == STR_WIDGET_SETTINGS) {
|
||||
pushMenu(menuWidgetSettings);
|
||||
}
|
||||
else if (result == STR_REMOVE_WIDGET) {
|
||||
currentContainer->createWidget(currentZone, nullptr);
|
||||
storageDirty(EE_MODEL);
|
||||
}
|
||||
}
|
||||
|
||||
bool menuWidgetsSetup(event_t event)
|
||||
{
|
||||
switch (event) {
|
||||
case EVT_ENTRY:
|
||||
menuVerticalPosition = 0;
|
||||
break;
|
||||
case EVT_KEY_FIRST(KEY_EXIT):
|
||||
killEvents(KEY_EXIT);
|
||||
popMenu();
|
||||
return false;
|
||||
}
|
||||
|
||||
currentScreen->refresh();
|
||||
|
||||
for (int i = currentContainer->getZonesCount() - 1; i >= 0; i--) {
|
||||
Zone zone = currentContainer->getZone(i);
|
||||
LcdFlags color;
|
||||
int padding, thickness;
|
||||
if (currentContainer == topbar) {
|
||||
color = MENU_COLOR;
|
||||
padding = 2;
|
||||
thickness = 1;
|
||||
}
|
||||
else {
|
||||
color = FOCUS_BGCOLOR;
|
||||
padding = 4;
|
||||
thickness = 2;
|
||||
}
|
||||
if (menuVerticalPosition == i) {
|
||||
lcdDrawSolidRect(zone.x-padding, zone.y-padding, zone.w+2*padding, zone.h+2*padding, thickness, color);
|
||||
if (event == EVT_KEY_FIRST(KEY_ENTER)) {
|
||||
killEvents(KEY_ENTER);
|
||||
currentZone = menuVerticalPosition;
|
||||
currentWidget = currentContainer->getWidget(menuVerticalPosition);
|
||||
if (currentWidget) {
|
||||
POPUP_MENU_ADD_ITEM(STR_SELECT_WIDGET);
|
||||
if (currentWidget->getFactory()->getOptions())
|
||||
POPUP_MENU_ADD_ITEM(STR_WIDGET_SETTINGS);
|
||||
POPUP_MENU_ADD_ITEM(STR_REMOVE_WIDGET);
|
||||
POPUP_MENU_START(onZoneMenu);
|
||||
}
|
||||
else {
|
||||
onZoneMenu(STR_SELECT_WIDGET);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (widgetNeedsSettings) {
|
||||
currentWidget = currentContainer->getWidget(menuVerticalPosition);
|
||||
if (currentWidget) {
|
||||
widgetNeedsSettings = false;
|
||||
onZoneMenu(STR_WIDGET_SETTINGS);
|
||||
}
|
||||
}
|
||||
lcdDrawRect(zone.x-padding, zone.y-padding, zone.w+2*padding, zone.h+2*padding, thickness, 0x3F, color);
|
||||
}
|
||||
}
|
||||
navigate(event, currentContainer->getZonesCount(), currentContainer->getZonesCount(), 1);
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
T * editThemeChoice(coord_t x, coord_t y, std::list<T *> & elList, T * current, bool needsOffsetCheck, LcdFlags attr, event_t event)
|
||||
{
|
||||
static uint8_t menuHorizontalOffset = 0;
|
||||
uint8_t elCount = elList.size(), last, idx;
|
||||
coord_t pos;
|
||||
int currentIndex = 0;
|
||||
typename std::list<T *>::const_iterator elItr = elList.cbegin();
|
||||
|
||||
if (!elCount)
|
||||
return nullptr;
|
||||
|
||||
for (; elItr != elList.cend(); ++elItr, ++currentIndex) {
|
||||
if ((*elItr) == current)
|
||||
break;
|
||||
}
|
||||
|
||||
if (event == EVT_ENTRY) {
|
||||
menuHorizontalOffset = 0;
|
||||
needsOffsetCheck = true;
|
||||
}
|
||||
|
||||
if (needsOffsetCheck) {
|
||||
if (currentIndex < menuHorizontalOffset) {
|
||||
menuHorizontalOffset = currentIndex;
|
||||
}
|
||||
else if (currentIndex > menuHorizontalOffset + 3) {
|
||||
menuHorizontalOffset = currentIndex - 3;
|
||||
}
|
||||
}
|
||||
if (attr) {
|
||||
if (menuHorizontalPosition < 0) {
|
||||
lcdDrawSolidFilledRect(x-3, y-1, min<uint8_t>(4, elCount)*56+1, 2*FH-5, FOCUS_BGCOLOR);
|
||||
}
|
||||
else {
|
||||
if (needsOffsetCheck) {
|
||||
menuHorizontalPosition = currentIndex;
|
||||
}
|
||||
else if (menuHorizontalPosition < menuHorizontalOffset) {
|
||||
menuHorizontalOffset = menuHorizontalPosition;
|
||||
}
|
||||
else if (menuHorizontalPosition > menuHorizontalOffset + 3) {
|
||||
menuHorizontalOffset = menuHorizontalPosition - 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
last = min<uint8_t>(menuHorizontalOffset + 4, elCount);
|
||||
idx = menuHorizontalOffset;
|
||||
pos = x;
|
||||
elItr = elList.cbegin();
|
||||
std::advance(elItr, min<uint8_t>(menuHorizontalOffset, elCount - 1));
|
||||
for (; idx < last && elItr != elList.cend(); ++idx, ++elItr, pos += 56) {
|
||||
(*elItr)->drawThumb(pos, y+1, current == (*elItr) ? ((attr && menuHorizontalPosition < 0) ? FOCUS_COLOR : FOCUS_BGCOLOR) : LINE_COLOR);
|
||||
}
|
||||
if (elCount > 4) {
|
||||
lcdDrawBitmapPattern(x - 12, y+1, LBM_CARROUSSEL_LEFT, menuHorizontalOffset > 0 ? LINE_COLOR : DISABLE_COLOR);
|
||||
lcdDrawBitmapPattern(x + 4 * 56, y+1, LBM_CARROUSSEL_RIGHT, last < getRegisteredLayouts().size() ? LINE_COLOR : DISABLE_COLOR);
|
||||
}
|
||||
if (attr && menuHorizontalPosition >= 0) {
|
||||
lcdDrawSolidRect(x + (menuHorizontalPosition - menuHorizontalOffset) * 56 - 3, y - 1, 57, 35, 1, FOCUS_BGCOLOR);
|
||||
if (event == EVT_KEY_FIRST(KEY_ENTER)) {
|
||||
s_editMode = 0;
|
||||
elItr = elList.cbegin();
|
||||
if (menuHorizontalPosition < (int)elList.size())
|
||||
std::advance(elItr, menuHorizontalPosition);
|
||||
if (elItr != elList.cend())
|
||||
return (*elItr);
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
enum menuScreensThemeItems {
|
||||
ITEM_SCREEN_SETUP_THEME,
|
||||
ITEM_SCREEN_SETUP_THEME_OPTION1 = ITEM_SCREEN_SETUP_THEME+2
|
||||
};
|
||||
|
||||
bool menuScreensTheme(event_t event)
|
||||
{
|
||||
bool needsOffsetCheck = (menuVerticalPosition != 0 || menuHorizontalPosition < 0);
|
||||
const ZoneOption * options = theme->getOptions();
|
||||
int optionsCount = getOptionsCount(options);
|
||||
linesCount = ITEM_SCREEN_SETUP_THEME_OPTION1 + optionsCount + 1;
|
||||
|
||||
menuPageCount = updateMainviewsMenu();
|
||||
uint8_t mstate_tab[2 + MAX_THEME_OPTIONS + 1] = { uint8_t(NAVIGATION_LINE_BY_LINE | uint8_t(getRegisteredThemes().size()-1)), ORPHAN_ROW };
|
||||
for (int i=0; i<optionsCount; i++) {
|
||||
mstate_tab[2+i] = getZoneOptionColumns(&options[i]);
|
||||
}
|
||||
mstate_tab[2+optionsCount] = 0; // The button for the Topbar setup
|
||||
CUSTOM_MENU_WITH_OPTIONS(STR_USER_INTERFACE, THEME_ICONS, menuTabScreensSetup, menuPageCount, 0, linesCount);
|
||||
|
||||
for (int i=0; i<NUM_BODY_LINES; i++) {
|
||||
coord_t y = MENU_CONTENT_TOP + i * FH;
|
||||
int k = i + menuVerticalOffset;
|
||||
LcdFlags blink = ((s_editMode > 0) ? BLINK | INVERS : INVERS);
|
||||
LcdFlags attr = (menuVerticalPosition == k ? blink : 0);
|
||||
switch (k) {
|
||||
case ITEM_SCREEN_SETUP_THEME: {
|
||||
lcdDrawText(MENUS_MARGIN_LEFT, y + FH / 2, STR_THEME);
|
||||
Theme * new_theme = editThemeChoice<Theme>(SCREENS_SETUP_2ND_COLUMN, y, getRegisteredThemes(), theme, needsOffsetCheck, attr, event);
|
||||
if (new_theme) {
|
||||
new_theme->init();
|
||||
loadTheme(new_theme);
|
||||
strncpy(g_eeGeneral.themeName, new_theme->getName(), sizeof(g_eeGeneral.themeName));
|
||||
killEvents(KEY_ENTER);
|
||||
storageDirty(EE_GENERAL);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case ITEM_SCREEN_SETUP_THEME+1:
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
uint8_t index = k - ITEM_SCREEN_SETUP_THEME_OPTION1;
|
||||
if (index < optionsCount) {
|
||||
const ZoneOption * option = &options[index];
|
||||
ZoneOptionValue * value = theme->getOptionValue(index);
|
||||
bool ret = editZoneOption(y, option, value, attr, EE_GENERAL, event);
|
||||
if (option->type == ZoneOption::Color) {
|
||||
if (attr && event == EVT_KEY_FIRST(KEY_EXIT)) {
|
||||
theme->update();
|
||||
}
|
||||
}
|
||||
else if (ret) {
|
||||
theme->update();
|
||||
}
|
||||
}
|
||||
else if (index == optionsCount) {
|
||||
lcdDrawText(MENUS_MARGIN_LEFT, y, STR_TOP_BAR);
|
||||
drawButton(SCREENS_SETUP_2ND_COLUMN, y, STR_SETUP, attr);
|
||||
if (attr && event == EVT_KEY_FIRST(KEY_ENTER)) {
|
||||
currentScreen = customScreens[0];
|
||||
currentContainer = topbar;
|
||||
pushMenu(menuWidgetsSetup);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
enum MenuScreenSetupItems {
|
||||
ITEM_SCREEN_SETUP_LAYOUT,
|
||||
ITEM_SCREEN_SETUP_WIDGETS_SETUP = ITEM_SCREEN_SETUP_LAYOUT+2,
|
||||
ITEM_SCREEN_SETUP_LAYOUT_OPTION1,
|
||||
};
|
||||
|
||||
bool menuScreenSetup(int index, event_t event)
|
||||
{
|
||||
if (customScreens[index] == nullptr) {
|
||||
return menuScreenAdd(event);
|
||||
}
|
||||
|
||||
currentScreen = customScreens[index];
|
||||
currentContainer = currentScreen;
|
||||
bool needsOffsetCheck = (menuVerticalPosition != 0 || menuHorizontalPosition < 0);
|
||||
|
||||
char title[] = TR_MAIN_VIEW_X;
|
||||
title[sizeof(title)-2] = '1' + index;
|
||||
menuPageCount = updateMainviewsMenu();
|
||||
|
||||
const ZoneOption * options = currentScreen->getFactory()->getOptions();
|
||||
int optionsCount = getOptionsCount(options);
|
||||
linesCount = ITEM_SCREEN_SETUP_LAYOUT_OPTION1 + optionsCount;
|
||||
if (menuPageCount > 3)
|
||||
++linesCount;
|
||||
|
||||
uint8_t mstate_tab[2 + MAX_LAYOUT_OPTIONS + 1] = { uint8_t(NAVIGATION_LINE_BY_LINE | uint8_t(getRegisteredLayouts().size()-1)), ORPHAN_ROW };
|
||||
for (int i=0; i<optionsCount; i++) {
|
||||
mstate_tab[3+i] = getZoneOptionColumns(&options[i]);
|
||||
}
|
||||
mstate_tab[3+optionsCount] = 0; // The remove button
|
||||
|
||||
CUSTOM_MENU_WITH_OPTIONS(title, THEME_ICONS, menuTabScreensSetup, menuPageCount, index+1, linesCount);
|
||||
|
||||
for (int i=0; i<NUM_BODY_LINES; i++) {
|
||||
coord_t y = MENU_CONTENT_TOP + i * FH;
|
||||
int k = i + menuVerticalOffset;
|
||||
LcdFlags blink = ((s_editMode>0) ? BLINK|INVERS : INVERS);
|
||||
LcdFlags attr = (menuVerticalPosition == k ? blink : 0);
|
||||
switch(k) {
|
||||
case ITEM_SCREEN_SETUP_LAYOUT:
|
||||
{
|
||||
lcdDrawText(MENUS_MARGIN_LEFT, y + FH / 2, STR_LAYOUT);
|
||||
const LayoutFactory * factory = editThemeChoice<const LayoutFactory>(SCREENS_SETUP_2ND_COLUMN, y, getRegisteredLayouts(), currentScreen->getFactory(), needsOffsetCheck, attr, event);
|
||||
if (factory) {
|
||||
delete customScreens[index];
|
||||
currentScreen = customScreens[index] = factory->create(&g_model.screenData[index].layoutData);
|
||||
strncpy(g_model.screenData[index].layoutName, factory->getName(), sizeof(g_model.screenData[index].layoutName));
|
||||
killEvents(KEY_ENTER);
|
||||
storageDirty(EE_MODEL);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case ITEM_SCREEN_SETUP_LAYOUT+1:
|
||||
break;
|
||||
|
||||
case ITEM_SCREEN_SETUP_WIDGETS_SETUP:
|
||||
drawButton(SCREENS_SETUP_2ND_COLUMN, y, STR_SETUP_WIDGETS, attr);
|
||||
if (attr && event == EVT_KEY_FIRST(KEY_ENTER)) {
|
||||
pushMenu(menuWidgetsSetup);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
uint8_t o = k - ITEM_SCREEN_SETUP_LAYOUT_OPTION1;
|
||||
if (o < optionsCount) {
|
||||
const ZoneOption * option = &options[o];
|
||||
ZoneOptionValue * value = currentScreen->getOptionValue(o);
|
||||
if (editZoneOption(y, option, value, attr, EE_MODEL, event)) {
|
||||
currentScreen->update();
|
||||
loadCustomScreens();
|
||||
}
|
||||
}
|
||||
else if (menuPageCount > 3 && o == optionsCount) {
|
||||
drawButton(SCREENS_SETUP_2ND_COLUMN, y, STR_REMOVE_SCREEN, attr);
|
||||
if (attr && event == EVT_KEY_LONG(KEY_ENTER)) {
|
||||
delete currentScreen;
|
||||
if (index != MAX_CUSTOM_SCREENS-1) {
|
||||
memmove(&g_model.screenData[index], &g_model.screenData[index + 1], sizeof(CustomScreenData) * (MAX_CUSTOM_SCREENS - index - 1));
|
||||
memmove(&customScreens[index], &customScreens[index + 1], sizeof(Layout *) * (MAX_CUSTOM_SCREENS - index - 1));
|
||||
}
|
||||
memset(&g_model.screenData[MAX_CUSTOM_SCREENS-1], 0, sizeof(CustomScreenData));
|
||||
customScreens[MAX_CUSTOM_SCREENS-1] = nullptr;
|
||||
loadCustomScreens();
|
||||
killEvents(KEY_ENTER);
|
||||
chainMenu(menuTabScreensSetup[index > 0 ? index : 1]);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template<int N>
|
||||
bool menuCustomScreenSetup(event_t event)
|
||||
{
|
||||
return menuScreenSetup(N, event);
|
||||
}
|
||||
|
||||
const MenuHandlerFunc menuTabScreensSetup[1+MAX_CUSTOM_SCREENS] = {
|
||||
menuScreensTheme,
|
||||
menuCustomScreenSetup<0>,
|
||||
menuCustomScreenSetup<1>,
|
||||
menuCustomScreenSetup<2>,
|
||||
menuCustomScreenSetup<3>,
|
||||
menuCustomScreenSetup<4>
|
||||
};
|
||||
|
||||
int updateMainviewsMenu()
|
||||
{
|
||||
for (int index=1; index<MAX_CUSTOM_SCREENS; index++) {
|
||||
if (customScreens[index]) {
|
||||
THEME_ICONS[2+index] = ICON_THEME_VIEW1+index;
|
||||
}
|
||||
else {
|
||||
THEME_ICONS[2+index] = ICON_THEME_ADD_VIEW;
|
||||
return 2+index;
|
||||
}
|
||||
}
|
||||
return 1+MAX_CUSTOM_SCREENS;
|
||||
}
|
||||
|
||||
bool menuScreenAdd(event_t event)
|
||||
{
|
||||
menuPageCount = updateMainviewsMenu();
|
||||
|
||||
if (event == EVT_KEY_FIRST(KEY_ENTER) && getRegisteredLayouts().size()) {
|
||||
const LayoutFactory * lf = getRegisteredLayouts().front();
|
||||
customScreens[menuPageCount-2] = lf->create(&g_model.screenData[menuPageCount-2].layoutData);
|
||||
strncpy(g_model.screenData[menuPageCount-2].layoutName, lf->getName(), sizeof(g_model.screenData[menuPageCount-2].layoutName));
|
||||
s_editMode = 0;
|
||||
menuHorizontalPosition = -1;
|
||||
killEvents(KEY_ENTER);
|
||||
storageDirty(EE_MODEL);
|
||||
return false;
|
||||
}
|
||||
|
||||
SIMPLE_MENU_WITH_OPTIONS(STR_ADD_MAIN_VIEW, THEME_ICONS, menuTabScreensSetup, menuPageCount, menuPageCount-1, 0);
|
||||
return true;
|
||||
}
|
||||
@@ -41,6 +41,11 @@ rect_t TopBar::getZone(unsigned int index) const
|
||||
};
|
||||
}
|
||||
|
||||
void TopBar::setVisible(bool visible)
|
||||
{
|
||||
setHeight(visible ? TOPBAR_HEIGHT : 0);
|
||||
}
|
||||
|
||||
const char * const STR_MONTHS[] = TR_MONTHS;
|
||||
|
||||
void TopBar::paint(BitmapBuffer * dc)
|
||||
|
||||
@@ -38,6 +38,8 @@ class TopBar: public WidgetsContainer<MAX_TOPBAR_ZONES, MAX_TOPBAR_OPTIONS>
|
||||
|
||||
rect_t getZone(unsigned int index) const override;
|
||||
|
||||
void setVisible(bool visible);
|
||||
|
||||
void paint(BitmapBuffer * dc) override;
|
||||
|
||||
void checkEvents() override
|
||||
|
||||
@@ -22,30 +22,16 @@
|
||||
#include "menu_model.h"
|
||||
#include "menu_radio.h"
|
||||
#include "menu_screen.h"
|
||||
// #include "menu_screens.h"
|
||||
#include "model_select.h"
|
||||
#include "view_channels.h"
|
||||
#include "view_statistics.h"
|
||||
#include "topbar.h"
|
||||
#include "layouts/sliders.h"
|
||||
#include "layouts/trims.h"
|
||||
#include "opentx.h"
|
||||
|
||||
Layout * customScreens[MAX_CUSTOM_SCREENS] = {};
|
||||
|
||||
void onMainViewMenu(const char *result)
|
||||
{
|
||||
/*if (result == STR_VIEW_NOTES) {
|
||||
pushModelNotes();
|
||||
}
|
||||
else if (result == STR_STATISTICS) {
|
||||
pushMenu(menuTabStats[0]);
|
||||
}
|
||||
else if (result == STR_ABOUT_US) {
|
||||
chainMenu(menuAboutView);
|
||||
}
|
||||
else if (result == STR_MONITOR_SCREENS) {
|
||||
pushMenu(menuTabMonitors[lastMonitorPage]);
|
||||
}*/
|
||||
}
|
||||
|
||||
int getMainViewsCount()
|
||||
{
|
||||
for (int index=1; index<MAX_CUSTOM_SCREENS; index++) {
|
||||
@@ -61,7 +47,6 @@ ViewMain * ViewMain::_instance = nullptr;
|
||||
ViewMain::ViewMain():
|
||||
FormWindow(MainWindow::instance(), { 0, 0, LCD_W, LCD_H })
|
||||
{
|
||||
|
||||
#if defined(HARDWARE_TOUCH) && !defined(HARDWARE_KEYS)
|
||||
new FabButton(this, 50, 100, ICON_MODEL,
|
||||
[=]() -> uint8_t {
|
||||
@@ -87,7 +72,7 @@ ViewMain::ViewMain():
|
||||
return 0;
|
||||
}, NO_FOCUS);
|
||||
#endif
|
||||
|
||||
createDecoration();
|
||||
focusWindow = this;
|
||||
}
|
||||
|
||||
@@ -95,6 +80,72 @@ ViewMain::~ViewMain()
|
||||
{
|
||||
}
|
||||
|
||||
void ViewMain::setTopbarVisible(bool visible)
|
||||
{
|
||||
topbar->setVisible(visible);
|
||||
}
|
||||
|
||||
void ViewMain::setTrimsVisible(bool visible)
|
||||
{
|
||||
trims[TRIMS_LH]->setHeight(visible ? TRIM_SQUARE_SIZE : 0);
|
||||
trims[TRIMS_RH]->setHeight(visible ? TRIM_SQUARE_SIZE : 0);
|
||||
|
||||
trims[TRIMS_LV]->setWidth(visible ? TRIM_SQUARE_SIZE : 0);
|
||||
trims[TRIMS_RV]->setWidth(visible ? TRIM_SQUARE_SIZE : 0);
|
||||
}
|
||||
|
||||
void ViewMain::setSlidersVisible(bool visible)
|
||||
{
|
||||
//
|
||||
// Horizontal Sliders
|
||||
//
|
||||
sliders[SLIDERS_POT1]->setHeight(visible ? TRIM_SQUARE_SIZE : 0);
|
||||
|
||||
//TODO: might change depending on hardware settings
|
||||
if (IS_POT_MULTIPOS(POT2)) {
|
||||
sliders[SLIDERS_POT2]->setHeight(visible ? MULTIPOS_H : 0);
|
||||
}
|
||||
else if (IS_POT(POT2)) {
|
||||
sliders[SLIDERS_POT2]->setHeight(visible ? TRIM_SQUARE_SIZE : 0);
|
||||
}
|
||||
|
||||
#if defined(HARDWARE_POT3)
|
||||
sliders[SLIDERS_POT3]->setHeight(visible ? TRIM_SQUARE_SIZE : 0);
|
||||
#endif
|
||||
|
||||
//
|
||||
// Vertical sliders
|
||||
//
|
||||
sliders[SLIDERS_REAR_LEFT]->setWidth(visible ? TRIM_SQUARE_SIZE : 0);
|
||||
|
||||
#if defined(HARDWARE_EXT1)
|
||||
//TODO: might change depending on hardware settings
|
||||
if (IS_POT_SLIDER_AVAILABLE(EXT1)) {
|
||||
sliders[SLIDERS_EXT1]->setWidth(visible ? TRIM_SQUARE_SIZE : 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
sliders[SLIDERS_REAR_RIGHT]->setWidth(visible ? TRIM_SQUARE_SIZE : 0);
|
||||
|
||||
#if defined(HARDWARE_EXT2)
|
||||
//TODO: might change depending on hardware settings
|
||||
if (IS_POT_SLIDER_AVAILABLE(EXT2)) {
|
||||
sliders[SLIDERS_EXT2]->setWidth(visible ? TRIM_SQUARE_SIZE : 0);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void ViewMain::setFlightModeVisible(bool visible)
|
||||
{
|
||||
flightMode->setHeight(visible ? 20 : 0);
|
||||
}
|
||||
|
||||
void ViewMain::adjustDecoration()
|
||||
{
|
||||
// TODO:
|
||||
// -> re-compute all the components' positions
|
||||
}
|
||||
|
||||
#if defined(HARDWARE_KEYS)
|
||||
void ViewMain::onEvent(event_t event)
|
||||
{
|
||||
@@ -169,27 +220,204 @@ void ViewMain::paint(BitmapBuffer * dc)
|
||||
if (g_model.view >= getMainViewsCount()) {
|
||||
g_model.view = 0;
|
||||
}
|
||||
//
|
||||
// for (uint8_t i=0; i<MAX_CUSTOM_SCREENS; i++) {
|
||||
// if (customScreens[i]) {
|
||||
// if (i == g_model.view) {
|
||||
// customScreens[i]->refresh(); }
|
||||
// else
|
||||
// customScreens[i]->background();
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
#if 0
|
||||
bool menuMainViewChannelsMonitor(event_t event)
|
||||
void ViewMain::createDecoration()
|
||||
{
|
||||
switch (event) {
|
||||
case EVT_KEY_BREAK(KEY_EXIT):
|
||||
chainMenu(menuMainView);
|
||||
event = 0;
|
||||
return false;
|
||||
createTopbar();
|
||||
createSliders();
|
||||
createTrims();
|
||||
createFlightMode();
|
||||
}
|
||||
|
||||
void ViewMain::createTopbar()
|
||||
{
|
||||
topbar = new TopBar(this);
|
||||
topbar->load();
|
||||
}
|
||||
|
||||
void ViewMain::createSliders()
|
||||
{
|
||||
// TODO:
|
||||
// - layout must become really dynamic (see adjustDecoration())
|
||||
// - components should be created in "folded" state
|
||||
// - it should not be required to call hasXXXX() at all
|
||||
|
||||
#if defined(HARDWARE_EXT1) || defined(HARDWARE_EXT2)
|
||||
coord_t yOffset = /*(hasTrims() ?*/ - TRIM_SQUARE_SIZE /*: 0)*/ + /*(hasTopbar() ?*/ TOPBAR_HEIGHT / 2 /*: 0)*/;
|
||||
#endif
|
||||
|
||||
// fixed size array, so that works
|
||||
memset(sliders, 0, sizeof(sliders));
|
||||
|
||||
rect_t r = {
|
||||
HMARGIN,
|
||||
LCD_H - TRIM_SQUARE_SIZE,
|
||||
HORIZONTAL_SLIDERS_WIDTH,
|
||||
TRIM_SQUARE_SIZE
|
||||
};
|
||||
|
||||
sliders[SLIDERS_POT1] = new MainViewHorizontalSlider(this, r, CALIBRATED_POT1);
|
||||
|
||||
if (IS_POT_MULTIPOS(POT2)) {
|
||||
|
||||
r = rect_t {
|
||||
LCD_W / 2 - MULTIPOS_W / 2,
|
||||
LCD_H - TRIM_SQUARE_SIZE,
|
||||
MULTIPOS_W + 1,
|
||||
MULTIPOS_H
|
||||
};
|
||||
|
||||
sliders[SLIDERS_POT2] = new MainView6POS(this, r, 1);
|
||||
}
|
||||
else if (IS_POT(POT2)) {
|
||||
|
||||
r = {
|
||||
LCD_W - HORIZONTAL_SLIDERS_WIDTH - HMARGIN,
|
||||
LCD_H - TRIM_SQUARE_SIZE,
|
||||
HORIZONTAL_SLIDERS_WIDTH,
|
||||
TRIM_SQUARE_SIZE
|
||||
};
|
||||
|
||||
sliders[SLIDERS_POT2] = new MainViewHorizontalSlider(this, r, CALIBRATED_POT2);
|
||||
}
|
||||
|
||||
return menuChannelsView(event);
|
||||
}
|
||||
#if defined(HARDWARE_POT3)
|
||||
r = rect_t {
|
||||
LCD_W - HORIZONTAL_SLIDERS_WIDTH - HMARGIN,
|
||||
LCD_H - TRIM_SQUARE_SIZE,
|
||||
HORIZONTAL_SLIDERS_WIDTH,
|
||||
TRIM_SQUARE_SIZE
|
||||
};
|
||||
|
||||
sliders[SLIDERS_POT3] = new MainViewHorizontalSlider(this, r, CALIBRATED_POT3);
|
||||
#endif
|
||||
|
||||
#if defined(HARDWARE_EXT1)
|
||||
if (IS_POT_SLIDER_AVAILABLE(EXT1)) {
|
||||
r = rect_t {
|
||||
HMARGIN,
|
||||
LCD_H / 2 - VERTICAL_SLIDERS_HEIGHT(true/*hasTopbar()*/) / 2 + yOffset,
|
||||
TRIM_SQUARE_SIZE,
|
||||
VERTICAL_SLIDERS_HEIGHT(true/*hasTopbar()*/) / 2
|
||||
};
|
||||
|
||||
sliders[SLIDERS_REAR_LEFT] = new MainViewVerticalSlider(this, r, CALIBRATED_SLIDER_REAR_LEFT);
|
||||
|
||||
r = rect_t {
|
||||
HMARGIN,
|
||||
LCD_H / 2 + yOffset,
|
||||
TRIM_SQUARE_SIZE,
|
||||
VERTICAL_SLIDERS_HEIGHT(true/*hasTopbar()*/) / 2
|
||||
};
|
||||
|
||||
sliders[SLIDERS_EXT1] = new MainViewVerticalSlider(this, r, CALIBRATED_POT_EXT1);
|
||||
}
|
||||
else {
|
||||
r = rect_t {
|
||||
HMARGIN,
|
||||
LCD_H / 2 - VERTICAL_SLIDERS_HEIGHT(true/*hasTopbar()*/) / 2 + yOffset,
|
||||
TRIM_SQUARE_SIZE,
|
||||
VERTICAL_SLIDERS_HEIGHT(true/*hasTopbar()*/)
|
||||
};
|
||||
|
||||
sliders[SLIDERS_REAR_LEFT] = new MainViewVerticalSlider(this, r, CALIBRATED_SLIDER_REAR_LEFT);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(HARDWARE_EXT2)
|
||||
if (IS_POT_SLIDER_AVAILABLE(EXT2)) {
|
||||
r = rect_t {
|
||||
LCD_W - HMARGIN - TRIM_SQUARE_SIZE,
|
||||
LCD_H / 2 - VERTICAL_SLIDERS_HEIGHT(true/*hasTopbar()*/) / 2 + yOffset,
|
||||
TRIM_SQUARE_SIZE,
|
||||
VERTICAL_SLIDERS_HEIGHT(true/*hasTopbar()*/) / 2
|
||||
};
|
||||
|
||||
sliders[SLIDERS_REAR_RIGHT] = new MainViewVerticalSlider(this, r, CALIBRATED_SLIDER_REAR_RIGHT);
|
||||
|
||||
r = rect_t {
|
||||
LCD_W - HMARGIN - TRIM_SQUARE_SIZE,
|
||||
LCD_H / 2 + yOffset,
|
||||
TRIM_SQUARE_SIZE,
|
||||
VERTICAL_SLIDERS_HEIGHT(true/*hasTopbar()*/) / 2
|
||||
};
|
||||
|
||||
sliders[SLIDERS_EXT2] = new MainViewVerticalSlider(this, r, CALIBRATED_POT_EXT2);
|
||||
}
|
||||
else {
|
||||
r = rect_t {
|
||||
LCD_W - HMARGIN - TRIM_SQUARE_SIZE,
|
||||
LCD_H / 2 - VERTICAL_SLIDERS_HEIGHT(true/*hasTopbar()*/) / 2 + yOffset,
|
||||
TRIM_SQUARE_SIZE,
|
||||
VERTICAL_SLIDERS_HEIGHT(true/*hasTopbar()*/)
|
||||
};
|
||||
|
||||
sliders[SLIDERS_REAR_RIGHT] = new MainViewVerticalSlider(this, r, CALIBRATED_SLIDER_REAR_RIGHT);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void ViewMain::createTrims()
|
||||
{
|
||||
#if defined(HARDWARE_POT3) || defined(HARDWARE_EXT1)
|
||||
coord_t xOffset = /*hasSliders() ?*/ TRIM_SQUARE_SIZE /*: 0*/;
|
||||
#else
|
||||
coord_t xOffset = 0;
|
||||
#endif
|
||||
coord_t yOffset = /*hasTrims() ?*/ - TRIM_SQUARE_SIZE /*: 0)*/;
|
||||
|
||||
// Trim order TRIM_LH, TRIM_LV, TRIM_RV, TRIM_RH
|
||||
|
||||
rect_t r = {
|
||||
HMARGIN,
|
||||
LCD_H - TRIM_SQUARE_SIZE + yOffset,
|
||||
HORIZONTAL_SLIDERS_WIDTH,
|
||||
TRIM_SQUARE_SIZE
|
||||
};
|
||||
|
||||
trims[TRIMS_LH] = new MainViewHorizontalTrim(this, r, 0);
|
||||
|
||||
r = rect_t {
|
||||
LCD_W - HORIZONTAL_SLIDERS_WIDTH - HMARGIN,
|
||||
LCD_H - TRIM_SQUARE_SIZE + yOffset,
|
||||
HORIZONTAL_SLIDERS_WIDTH,
|
||||
TRIM_SQUARE_SIZE
|
||||
};
|
||||
|
||||
trims[TRIMS_RH] = new MainViewHorizontalTrim(this, r, 3);
|
||||
|
||||
r = rect_t {
|
||||
HMARGIN + xOffset,
|
||||
LCD_H /2 - VERTICAL_SLIDERS_HEIGHT(true/*hasTopbar()*/) / 2 + yOffset + /*(hasTopbar() ?*/ TOPBAR_HEIGHT / 2 /*: 0)*/,
|
||||
TRIM_SQUARE_SIZE,
|
||||
VERTICAL_SLIDERS_HEIGHT(true/*hasTopbar()*/)
|
||||
};
|
||||
|
||||
trims[TRIMS_LV] = new MainViewVerticalTrim(this, r, 1);
|
||||
|
||||
r = rect_t {
|
||||
LCD_W - HMARGIN - TRIM_SQUARE_SIZE - xOffset,
|
||||
LCD_H /2 - VERTICAL_SLIDERS_HEIGHT(true/*hasTopbar()*/) / 2 + yOffset + /*(hasTopbar() ?*/ TOPBAR_HEIGHT / 2 /*: 0)*/,
|
||||
TRIM_SQUARE_SIZE,
|
||||
VERTICAL_SLIDERS_HEIGHT(true/*hasTopbar()*/)
|
||||
};
|
||||
|
||||
trims[TRIMS_RV] = new MainViewVerticalTrim(this, r, 2);
|
||||
}
|
||||
|
||||
void ViewMain::createFlightMode()
|
||||
{
|
||||
rect_t r = {
|
||||
50,
|
||||
LCD_H - 4 - /*(hasSliders() ?*/ 2 * TRIM_SQUARE_SIZE /*: TRIM_SQUARE_SIZE)*/,
|
||||
LCD_W - 100,
|
||||
20
|
||||
};
|
||||
|
||||
std::function<std::string()> getFM = []() -> std::string {
|
||||
return g_model.flightModeData[mixerCurrentFlightMode].name;
|
||||
};
|
||||
|
||||
flightMode = new DynamicText(this, r, getFM, CENTERED);
|
||||
}
|
||||
|
||||
@@ -22,6 +22,9 @@
|
||||
#define _VIEW_MAIN_H_
|
||||
|
||||
#include "form.h"
|
||||
#include <memory>
|
||||
|
||||
class TopBar;
|
||||
|
||||
class ViewMain: public FormWindow
|
||||
{
|
||||
@@ -46,14 +49,54 @@ class ViewMain: public FormWindow
|
||||
}
|
||||
#endif
|
||||
|
||||
// Set decoration visibility
|
||||
void setTopbarVisible(bool visible);
|
||||
void setTrimsVisible(bool visible);
|
||||
void setSlidersVisible(bool visible);
|
||||
void setFlightModeVisible(bool visible);
|
||||
|
||||
// Re-calculate positions
|
||||
void adjustDecoration();
|
||||
|
||||
protected:
|
||||
static ViewMain * _instance;
|
||||
|
||||
enum {
|
||||
SLIDERS_POT1 = 0,
|
||||
SLIDERS_POT2,
|
||||
SLIDERS_POT3,
|
||||
SLIDERS_REAR_LEFT,
|
||||
SLIDERS_EXT1,
|
||||
SLIDERS_REAR_RIGHT,
|
||||
SLIDERS_EXT2,
|
||||
SLIDERS_MAX
|
||||
};
|
||||
|
||||
enum {
|
||||
TRIMS_LH = 0,
|
||||
TRIMS_LV,
|
||||
TRIMS_RV,
|
||||
TRIMS_RH,
|
||||
TRIMS_MAX
|
||||
};
|
||||
|
||||
TopBar* topbar;
|
||||
Window* sliders[SLIDERS_MAX];
|
||||
Window* trims[TRIMS_MAX];
|
||||
Window* flightMode;
|
||||
|
||||
#if defined(HARDWARE_KEYS)
|
||||
void onEvent(event_t event) override;
|
||||
#endif
|
||||
void paint(BitmapBuffer * dc) override;
|
||||
|
||||
void openMenu();
|
||||
|
||||
void createDecoration();
|
||||
void createTopbar();
|
||||
void createSliders();
|
||||
void createTrims();
|
||||
void createFlightMode();
|
||||
};
|
||||
|
||||
#endif // _VIEW_MAIN_H_
|
||||
|
||||
Reference in New Issue
Block a user