fix(color): trims and sliders UI creation slows down model switch (#6492)

This commit is contained in:
philmoz
2025-08-02 11:42:27 +10:00
committed by GitHub
parent b8af047e72
commit a1cf7564a5
11 changed files with 111 additions and 75 deletions
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

+10
View File
@@ -360,6 +360,13 @@ static const uint8_t mask_model_list_two[] = {
#include "mask_model_list_two.lbm"
};
static const uint8_t mask_trim[] = {
#include "mask_trim.lbm"
};
static const uint8_t mask_trim_shadow[] = {
#include "mask_trim_shadow.lbm"
};
struct _BuiltinIcon {
const uint8_t* lz4_compressed_bitmap;
};
@@ -478,6 +485,9 @@ static const _BuiltinIcon _builtinIcons[EDGETX_ICONS_COUNT] = {
BI(ICON_MODEL_GRID_SMALL, mask_model_grid_small),
BI(ICON_MODEL_LIST_TWO, mask_model_list_two),
BI(ICON_MODEL_LIST_ONE, mask_model_list_one),
BI(ICON_TRIM, mask_trim),
BI(ICON_TRIM_SHADOW, mask_trim_shadow),
};
static MaskBitmap* _builtinIconsDecompressed[EDGETX_ICONS_COUNT] = {0};
+3
View File
@@ -133,6 +133,9 @@ enum EdgeTxIcon {
ICON_MODEL_LIST_TWO,
ICON_MODEL_LIST_ONE,
ICON_TRIM,
ICON_TRIM_SHADOW,
EDGETX_ICONS_COUNT
};
+85 -69
View File
@@ -26,86 +26,41 @@
#include "edgetx.h"
#include "switches.h"
static const lv_style_const_prop_t shadow1_props[] = {
// LV_STYLE_CONST_SHADOW_COLOR does not compile in GitHub ???
{.prop = LV_STYLE_SHADOW_COLOR, .value = {.color = {.full = 0}}},
LV_STYLE_CONST_SHADOW_OPA(LV_OPA_20),
LV_STYLE_CONST_SHADOW_OFS_X(1),
LV_STYLE_CONST_SHADOW_OFS_Y(1),
LV_STYLE_CONST_SHADOW_WIDTH(1),
LV_STYLE_PROP_INV,
};
static LV_STYLE_CONST_MULTI_INIT(shadow1_style, shadow1_props);
static const lv_style_const_prop_t shadow2_props[] = {
// LV_STYLE_CONST_SHADOW_COLOR does not compile in GitHub ???
{.prop = LV_STYLE_SHADOW_COLOR, .value = {.color = {.full = 0}}},
LV_STYLE_CONST_SHADOW_OPA(LV_OPA_40),
LV_STYLE_CONST_SHADOW_OFS_X(1),
LV_STYLE_CONST_SHADOW_OFS_Y(1),
LV_STYLE_CONST_SHADOW_WIDTH(1),
LV_STYLE_PROP_INV,
};
static LV_STYLE_CONST_MULTI_INIT(shadow2_style, shadow2_props);
SliderIcon::SliderIcon(Window* parent) :
Window(parent, rect_t{0, 0, MainViewSlider::SLIDER_ICON_SIZE + 2, MainViewSlider::SLIDER_ICON_SIZE + 2})
Window(parent, rect_t{0, 0, MainViewSlider::SLIDER_BAR_SIZE, MainViewSlider::SLIDER_BAR_SIZE})
{
setWindowFlag(NO_FOCUS);
auto shad = lv_obj_create(lvobj);
etx_obj_add_style(shad, shadow1_style, LV_PART_MAIN);
lv_obj_set_pos(shad, 1, 1);
lv_obj_set_size(shad, MainViewSlider::SLIDER_ICON_SIZE, MainViewSlider::SLIDER_ICON_SIZE);
auto icon = getBuiltinIcon(ICON_TRIM_SHADOW);
shadow = lv_canvas_create(lvobj);
lv_canvas_set_buffer(shadow, (void*)icon->data, icon->width, icon->height, LV_IMG_CF_ALPHA_8BIT);
etx_img_color(shadow, COLOR_THEME_PRIMARY1_INDEX);
fill = lv_obj_create(lvobj);
etx_obj_add_style(fill, shadow2_style, LV_PART_MAIN);
lv_obj_set_pos(fill, 0, 0);
lv_obj_set_size(fill, MainViewSlider::SLIDER_ICON_SIZE, MainViewSlider::SLIDER_ICON_SIZE);
etx_solid_bg(fill, COLOR_THEME_FOCUS_INDEX);
icon = getBuiltinIcon(ICON_TRIM);
mask = lv_canvas_create(lvobj);
lv_canvas_set_buffer(mask, (void*)icon->data, icon->width, icon->height, LV_IMG_CF_ALPHA_8BIT);
etx_img_color(mask, COLOR_THEME_FOCUS_INDEX);
}
std::vector<MaskBitmap*> MainViewSlider::tickMasks;
MainViewSlider::MainViewSlider(Window* parent, const rect_t& rect, uint8_t idx,
bool isVertical) :
Window(parent, rect), isVertical(isVertical)
{
potIdx = adcGetInputOffset(ADC_INPUT_FLEX) + idx;
if (isVertical) {
int sliderTicksCount = (height() - SLIDER_BAR_SIZE) / SLIDER_TICK_SPACING;
tickPoints = new lv_point_t[(sliderTicksCount + 1) * 2];
auto mask = getTicksMask();
lv_coord_t y = SLIDER_BAR_SIZE / 2;
for (uint8_t i = 0; i <= sliderTicksCount; i++) {
if (i == 0 || i == sliderTicksCount / 2 || i == sliderTicksCount) {
tickPoints[i * 2] = {PAD_TINY, y};
tickPoints[i * 2 + 1] = {SLIDER_ICON_SIZE, y};
} else {
tickPoints[i * 2] = {PAD_TINY + 2, y};
tickPoints[i * 2 + 1] = {SLIDER_ICON_SIZE - 2, y};
}
auto line = lv_line_create(lvobj);
etx_obj_add_style(line, styles->div_line, LV_PART_MAIN);
lv_line_set_points(line, &tickPoints[i * 2], 2);
y += SLIDER_TICK_SPACING;
}
} else {
int sliderTicksCount = (width() - SLIDER_BAR_SIZE) / SLIDER_TICK_SPACING;
tickPoints = new lv_point_t[(sliderTicksCount + 1) * 2];
if (mask) {
maskCanvas = lv_canvas_create(lvobj);
etx_img_color(maskCanvas, COLOR_THEME_SECONDARY1_INDEX);
lv_canvas_set_buffer(maskCanvas, mask->data, mask->width, mask->height, LV_IMG_CF_ALPHA_8BIT);
lv_coord_t x = SLIDER_BAR_SIZE / 2;
for (uint8_t i = 0; i <= sliderTicksCount; i++) {
if (i == 0 || i == sliderTicksCount / 2 || i == sliderTicksCount) {
tickPoints[i * 2] = {x, PAD_TINY};
tickPoints[i * 2 + 1] = {x, SLIDER_ICON_SIZE};
} else {
tickPoints[i * 2] = {x, PAD_TINY + 2};
tickPoints[i * 2 + 1] = {x, SLIDER_ICON_SIZE - 2};
}
auto line = lv_line_create(lvobj);
etx_obj_add_style(line, styles->div_line, LV_PART_MAIN);
lv_line_set_points(line, &tickPoints[i * 2], 2);
x += SLIDER_TICK_SPACING;
if (isVertical) {
lv_obj_set_pos(maskCanvas, PAD_TINY, SLIDER_BAR_SIZE / 2);
} else {
lv_obj_set_pos(maskCanvas, SLIDER_BAR_SIZE / 2, PAD_TINY);
}
}
@@ -114,12 +69,73 @@ MainViewSlider::MainViewSlider(Window* parent, const rect_t& rect, uint8_t idx,
setPos();
}
void MainViewSlider::deleteLater(bool detach, bool trash)
MaskBitmap* MainViewSlider::getTicksMask()
{
if (!deleted()) {
if (tickPoints) delete tickPoints;
Window::deleteLater(detach, trash);
coord_t l, x, y, w, h;
// Mask size
if (isVertical) {
h = height() - SLIDER_BAR_SIZE + 1;
if ((h & 1) == 0) h += 1;
w = MASK_SHORT_DIM;
} else {
w = width() - SLIDER_BAR_SIZE + 1;
if ((w & 1) == 0) w += 1;
h = MASK_SHORT_DIM;
}
for (auto mask : tickMasks) {
// TRACE("Found Mask %d %d",w,h);
if (mask->width == w && mask->height == h) return mask;
}
MaskBitmap* mask =(MaskBitmap*)malloc(w * h + sizeof(uint16_t) * 2);
if (!mask) {
TRACE("Could not create Slider mask");
return nullptr;
}
mask->width = w;
mask->height = h;
memset(mask->data, 0, w * h);
if (isVertical) {
// Create vertical mask for tick lines
int sliderTicksCount = h / SLIDER_TICK_SPACING;
y = 0;
for (uint8_t i = 0; i <= sliderTicksCount; i++) {
if (i == 0 || i == sliderTicksCount / 2 || i == sliderTicksCount) {
x = 0;
l = w;
} else {
x = PAD_TINY;
l = w - PAD_TINY * 2;
}
memset(&mask->data[y * w + x], 0xFF, l);
y += SLIDER_TICK_SPACING;
}
} else {
// Create horizontal mask for tick lines
int sliderTicksCount = w / SLIDER_TICK_SPACING;
x = 0;
for (uint8_t i = 0; i <= sliderTicksCount; i++) {
if (i == 0 || i == sliderTicksCount / 2 || i == sliderTicksCount) {
y = 0;
l = h;
} else {
y = PAD_TINY;
l = h - PAD_TINY * 2;
}
for (uint8_t n = y; n < y + l; n += 1)
mask->data[n * w + x] = 0xFF;
x += SLIDER_TICK_SPACING;
}
}
// TRACE("Created Mask %d %d",w,h);
tickMasks.emplace_back(mask);
return mask;
}
void MainViewSlider::setPos()
+10 -3
View File
@@ -23,6 +23,9 @@
#include "dataconstants.h"
#include "window.h"
#include <vector>
class MaskBitmap;
class SliderIcon : public Window
{
@@ -30,7 +33,8 @@ class SliderIcon : public Window
SliderIcon(Window* parent);
protected:
lv_obj_t* fill = nullptr;
lv_obj_t* mask = nullptr;
lv_obj_t* shadow = nullptr;
};
class MainViewSlider : public Window
@@ -49,19 +53,22 @@ class MainViewSlider : public Window
static LAYOUT_VAL_SCALED(SLIDER_TICK_SPACING, 4)
static constexpr coord_t HORIZONTAL_SLIDERS_WIDTH = SLIDER_SIZE + SLIDER_BAR_SIZE;
static constexpr coord_t VERTICAL_SLIDERS_HEIGHT = SLIDER_SIZE + SLIDER_BAR_SIZE;
static constexpr coord_t MASK_SHORT_DIM = SLIDER_ICON_SIZE - PAD_TINY;
static constexpr coord_t MASK_LONG_DIM = SLIDER_SIZE + 1;
protected:
uint8_t potIdx;
int16_t value = 0;
bool isVertical;
lv_obj_t* maskCanvas = nullptr;
SliderIcon* sliderIcon = nullptr;
lv_point_t* tickPoints = nullptr;
static std::vector<MaskBitmap*> tickMasks;
void setPos();
void checkEvents() override;
void deleteLater(bool detach = true, bool trash = true) override;
MaskBitmap* getTicksMask();
};
class MainViewHorizontalSlider : public MainViewSlider
+3 -3
View File
@@ -60,17 +60,17 @@ class TrimIcon : public SliderIcon
lv_obj_set_style_line_width(bar2, lw, LV_PART_MAIN);
lv_line_set_points(bar2, &barPoints[2], 2);
etx_bg_color(fill, COLOR_THEME_ACTIVE_INDEX, LV_STATE_USER_1);
etx_img_color(mask, COLOR_THEME_ACTIVE_INDEX, LV_STATE_USER_1);
}
void setState(int value)
{
if (value < TRIM_MIN || value > TRIM_MAX) {
lv_obj_add_state(fill, LV_STATE_USER_1);
lv_obj_add_state(mask, LV_STATE_USER_1);
lv_obj_add_state(bar1, LV_STATE_USER_1);
lv_obj_add_state(bar2, LV_STATE_USER_1);
} else {
lv_obj_clear_state(fill, LV_STATE_USER_1);
lv_obj_clear_state(mask, LV_STATE_USER_1);
lv_obj_clear_state(bar1, LV_STATE_USER_1);
lv_obj_clear_state(bar2, LV_STATE_USER_1);
}