Compare commits
No commits in common. "cd4b67e68fd2e84a67764e2b550edbd3dfae445d" and "7cd8d821f6be7bd3015cddd24c28dd74566c9f28" have entirely different histories.
cd4b67e68f
...
7cd8d821f6
@ -4,5 +4,3 @@ idf_component_register(
|
||||
SRCS ${SOURCE_FILES}
|
||||
REQUIRES TactilitySDK
|
||||
)
|
||||
|
||||
target_compile_options(${COMPONENT_LIB} PRIVATE -Wno-error=uninitialized -Wno-error=maybe-uninitialized)
|
||||
|
||||
@ -1,12 +1,12 @@
|
||||
#include "RadioSet.h"
|
||||
#include "Str.h"
|
||||
|
||||
#include <cstdio>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <ctype.h>
|
||||
#include <tt_lvgl_toolbar.h>
|
||||
|
||||
#include <initializer_list>
|
||||
|
||||
#include "tt_app_alertdialog.h"
|
||||
|
||||
constexpr const char* TAG = "RadioSet";
|
||||
@ -15,605 +15,123 @@ void crash(const char* const message) {
|
||||
tt_app_alertdialog_start("RadioSet has crashed!", message, nullptr, 0);
|
||||
}
|
||||
|
||||
// Debug function which colors all children randomly
|
||||
// TODO: Remove before flight
|
||||
void clownvomit(lv_obj_t *obj) {
|
||||
static auto rng = []() {
|
||||
static int color = 0xC0FE;
|
||||
const int a = 4711;
|
||||
const int m = 0x10001;
|
||||
color = (a * color) % m;
|
||||
return color;
|
||||
};
|
||||
|
||||
const int darken = 0x0E0E0E;
|
||||
const int lighten = 0xFEFEFE;
|
||||
lv_obj_set_style_bg_color(obj, lv_color_hex(rng() & darken), 0);
|
||||
|
||||
uint32_t i;
|
||||
for(i = 0; i < lv_obj_get_child_count(obj); i++) {
|
||||
lv_obj_t * child = lv_obj_get_child(obj, i);
|
||||
lv_obj_set_style_bg_color(child, lv_color_hex(rng() & darken), 0);
|
||||
lv_obj_set_style_border_color(child, lv_color_hex(rng() | lighten), 0);
|
||||
lv_obj_set_style_border_width(child, 1, 0);
|
||||
clownvomit(child);
|
||||
}
|
||||
}
|
||||
/*
|
||||
void scrollbar_highlight(lv_event_t * e) {
|
||||
lv_obj_t * obj = lv_event_get_target(e);
|
||||
}*/
|
||||
|
||||
char *const toString(Modulation m) {
|
||||
switch (m) {
|
||||
case MODULATION_NONE:
|
||||
return "None";
|
||||
case MODULATION_LORA:
|
||||
return "LoRa";
|
||||
case MODULATION_FSK:
|
||||
return "FSK";
|
||||
case MODULATION_LRFHSS:
|
||||
return "LR-FHSS";
|
||||
default:
|
||||
break;
|
||||
}
|
||||
crash("Unknown modulation passed.");
|
||||
return "Unknown";
|
||||
}
|
||||
|
||||
char *const toString(RadioParameter p) {
|
||||
switch (p) {
|
||||
case RADIO_POWER:
|
||||
return "Power";
|
||||
case RADIO_FREQUENCY:
|
||||
return "Center Frequency";
|
||||
case RADIO_BANDWIDTH:
|
||||
return "Bandwidth";
|
||||
case RADIO_SPREADFACTOR:
|
||||
return "Spread Factor";
|
||||
case RADIO_CODINGRATE:
|
||||
return "Coding Rate";
|
||||
case RADIO_SYNCWORD:
|
||||
return "Sync Word";
|
||||
case RADIO_PREAMBLES:
|
||||
return "Preamble Length";
|
||||
case RADIO_FREQDIV:
|
||||
return "Frequency Deviation";
|
||||
case RADIO_DATARATE:
|
||||
return "Data Rate";
|
||||
case RADIO_ADDRWIDTH:
|
||||
return "Address Width";
|
||||
case RADIO_NARROWGRID:
|
||||
return "Narrow Grid";
|
||||
default:
|
||||
break;
|
||||
}
|
||||
crash("Unknown parameter passed.");
|
||||
return "Unknown";
|
||||
}
|
||||
|
||||
class TermView {
|
||||
|
||||
};
|
||||
|
||||
|
||||
static lv_obj_t* initGridDropdownInput(lv_obj_t *container, int row, const char* const label, const char* const items) {
|
||||
lv_obj_t* label_obj = lv_label_create(container);
|
||||
lv_label_set_text(label_obj, label);
|
||||
lv_obj_set_grid_cell(label_obj,
|
||||
LV_GRID_ALIGN_STRETCH, 0, 1,
|
||||
LV_GRID_ALIGN_CENTER, row, 1);
|
||||
lv_obj_set_size(label_obj, lv_pct(100), LV_SIZE_CONTENT);
|
||||
|
||||
lv_obj_t* input = lv_dropdown_create(container);
|
||||
lv_obj_set_grid_cell(input,
|
||||
LV_GRID_ALIGN_STRETCH, 1, 1,
|
||||
LV_GRID_ALIGN_CENTER, row, 1);
|
||||
lv_obj_set_size(input, lv_pct(100), LV_SIZE_CONTENT);
|
||||
lv_dropdown_set_options(input, items);
|
||||
|
||||
return input;
|
||||
}
|
||||
|
||||
static lv_obj_t* initGridTextInput(lv_obj_t *container, int row, const char* const label, const char* const defval, const char* const unit) {
|
||||
const int height = LV_SIZE_CONTENT;
|
||||
lv_obj_t* label_obj = lv_label_create(container);
|
||||
lv_label_set_text(label_obj, label);
|
||||
lv_obj_set_grid_cell(label_obj,
|
||||
LV_GRID_ALIGN_STRETCH, 0, 1,
|
||||
LV_GRID_ALIGN_CENTER, row, 1);
|
||||
lv_obj_set_size(label_obj, lv_pct(100), height);
|
||||
|
||||
lv_obj_t* input = lv_textarea_create(container);
|
||||
lv_obj_set_grid_cell(input,
|
||||
LV_GRID_ALIGN_STRETCH, 1, 1,
|
||||
LV_GRID_ALIGN_CENTER, row, 1);
|
||||
lv_obj_set_size(input, lv_pct(100), height);
|
||||
lv_textarea_set_text(input, defval);
|
||||
lv_textarea_set_one_line(input, true);
|
||||
|
||||
lv_obj_t* unit_obj = lv_label_create(container);
|
||||
lv_label_set_text(unit_obj, unit);
|
||||
lv_obj_set_grid_cell(unit_obj,
|
||||
LV_GRID_ALIGN_STRETCH, 2, 1,
|
||||
LV_GRID_ALIGN_CENTER, row, 1);
|
||||
lv_obj_set_size(unit_obj, lv_pct(100), height);
|
||||
lv_obj_set_style_text_align(unit_obj , LV_TEXT_ALIGN_CENTER, 0);
|
||||
|
||||
return input;
|
||||
}
|
||||
|
||||
struct ParameterInput {
|
||||
const RadioHandle handle;
|
||||
const RadioParameter param;
|
||||
|
||||
ParameterInput(RadioHandle handle, const RadioParameter param)
|
||||
: handle(handle)
|
||||
, param(param) {}
|
||||
virtual void updatePreview() = 0;
|
||||
};
|
||||
|
||||
struct NumericParameterInput : public ParameterInput {
|
||||
|
||||
lv_obj_t* label = nullptr;
|
||||
lv_obj_t* input = nullptr;
|
||||
lv_obj_t* unitlabel = nullptr;
|
||||
char* fmt;
|
||||
|
||||
NumericParameterInput(RadioHandle handle, const RadioParameter param, lv_obj_t* container, int row, char* fmt = "%f", char* unit_override = nullptr)
|
||||
: ParameterInput(handle, param)
|
||||
, fmt(fmt) {
|
||||
initUi(container, row, unit_override);
|
||||
loadFromRadio();
|
||||
}
|
||||
|
||||
void loadFromRadio() {
|
||||
|
||||
}
|
||||
|
||||
void initUi(lv_obj_t* container, int row, char* unit_override) {
|
||||
const int height = LV_SIZE_CONTENT;
|
||||
label = lv_label_create(container);
|
||||
lv_label_set_text(label, toString(param));
|
||||
lv_obj_set_grid_cell(label,
|
||||
LV_GRID_ALIGN_STRETCH, 0, 1,
|
||||
LV_GRID_ALIGN_CENTER, row, 1);
|
||||
lv_obj_set_size(label, lv_pct(100), height);
|
||||
|
||||
input = lv_textarea_create(container);
|
||||
lv_obj_set_grid_cell(input,
|
||||
LV_GRID_ALIGN_STRETCH, 1, 1,
|
||||
LV_GRID_ALIGN_CENTER, row, 1);
|
||||
lv_obj_set_size(input, lv_pct(100), height);
|
||||
//TODO: LOAD VALUE
|
||||
//lv_textarea_set_text(input, defval);
|
||||
lv_textarea_set_one_line(input, true);
|
||||
|
||||
unitlabel = lv_label_create(container);
|
||||
lv_obj_set_grid_cell(unitlabel,
|
||||
LV_GRID_ALIGN_STRETCH, 2, 1,
|
||||
LV_GRID_ALIGN_CENTER, row, 1);
|
||||
lv_obj_set_size(unitlabel, lv_pct(100), height);
|
||||
lv_obj_set_style_text_align(unitlabel , LV_TEXT_ALIGN_CENTER, 0);
|
||||
|
||||
if (unit_override) {
|
||||
lv_label_set_text(unitlabel, unit_override);
|
||||
} else {
|
||||
char unit[64] = {0};
|
||||
tt_hal_radio_get_parameter_unit_str(handle, param, unit, sizeof(unit));
|
||||
lv_label_set_text(unitlabel, unit);
|
||||
}
|
||||
}
|
||||
|
||||
virtual void updatePreview() override {}
|
||||
};
|
||||
|
||||
struct SliderParameterInput : public ParameterInput {
|
||||
char* fmt = nullptr;
|
||||
lv_obj_t* label = nullptr;
|
||||
lv_obj_t* slider = nullptr;
|
||||
lv_obj_t* preview = nullptr;
|
||||
|
||||
SliderParameterInput(RadioHandle handle, const RadioParameter param, lv_obj_t* container, int row, int min, int max, char* fmt = "%i")
|
||||
: ParameterInput(handle, param)
|
||||
, fmt(fmt) {
|
||||
initUi(container, row, min, max);
|
||||
}
|
||||
|
||||
void initUi(lv_obj_t* container, int row, int min, int max) {
|
||||
label = lv_label_create(container);
|
||||
lv_label_set_text(label, toString(param));
|
||||
lv_obj_set_grid_cell(label,
|
||||
LV_GRID_ALIGN_STRETCH, 0, 1,
|
||||
LV_GRID_ALIGN_CENTER, row, 1);
|
||||
lv_obj_set_size(label, lv_pct(100), LV_SIZE_CONTENT);
|
||||
|
||||
slider = lv_slider_create(container);
|
||||
lv_obj_set_grid_cell(slider,
|
||||
LV_GRID_ALIGN_STRETCH, 1, 1,
|
||||
LV_GRID_ALIGN_CENTER, row, 1);
|
||||
lv_obj_set_size(slider, lv_pct(100), 10);
|
||||
lv_slider_set_range(slider, min, max);
|
||||
|
||||
preview = lv_label_create(container);
|
||||
lv_obj_set_grid_cell(preview,
|
||||
LV_GRID_ALIGN_STRETCH, 2, 1,
|
||||
LV_GRID_ALIGN_CENTER, row, 1);
|
||||
lv_obj_set_size(preview, lv_pct(100), LV_SIZE_CONTENT);
|
||||
lv_obj_set_style_text_align(preview , LV_TEXT_ALIGN_LEFT, 0);
|
||||
updatePreview();
|
||||
lv_obj_add_event_cb(slider, [](lv_event_t * e) {
|
||||
lv_obj_t* slider = lv_event_get_target_obj(e);
|
||||
SliderParameterInput* self = (SliderParameterInput*)lv_event_get_user_data(e);
|
||||
self->updatePreview();
|
||||
}, LV_EVENT_VALUE_CHANGED, this);
|
||||
|
||||
}
|
||||
|
||||
virtual void updatePreview() override {
|
||||
char buf[64] = {0};
|
||||
lv_snprintf(buf, sizeof(buf), fmt, lv_slider_get_value(slider));
|
||||
lv_label_set_text(preview, buf);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct SliderSelectParameterInput : public ParameterInput {
|
||||
static constexpr float SELECT_END = -1;
|
||||
const float* selections;
|
||||
const size_t selectionsSize;
|
||||
|
||||
char unit[64] = {0};
|
||||
char* fmt;
|
||||
lv_obj_t* label = nullptr;
|
||||
lv_obj_t* slider = nullptr;
|
||||
lv_obj_t* preview = nullptr;
|
||||
|
||||
static constexpr size_t get_selection_num(const float selections[]) {
|
||||
constexpr size_t MAX_SELECTIONS = 32;
|
||||
|
||||
if (selections) {
|
||||
for (size_t i = 0; i < MAX_SELECTIONS; ++i) {
|
||||
if (selections[i] == SELECT_END) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
SliderSelectParameterInput(RadioHandle handle, const RadioParameter param, lv_obj_t* container, int row, const float selections[] = nullptr, char* fmt = "%f")
|
||||
: ParameterInput(handle, param)
|
||||
, selections(selections)
|
||||
, selectionsSize(get_selection_num(selections))
|
||||
, fmt(fmt) {
|
||||
initUi(container, row);
|
||||
}
|
||||
|
||||
void initUi(lv_obj_t* container, int row) {
|
||||
label = lv_label_create(container);
|
||||
lv_label_set_text(label, toString(param));
|
||||
lv_obj_set_grid_cell(label,
|
||||
LV_GRID_ALIGN_STRETCH, 0, 1,
|
||||
LV_GRID_ALIGN_CENTER, row, 1);
|
||||
lv_obj_set_size(label, lv_pct(100), LV_SIZE_CONTENT);
|
||||
|
||||
slider = lv_slider_create(container);
|
||||
lv_obj_set_grid_cell(slider,
|
||||
LV_GRID_ALIGN_STRETCH, 1, 1,
|
||||
LV_GRID_ALIGN_CENTER, row, 1);
|
||||
lv_obj_set_size(slider, lv_pct(100), 10);
|
||||
lv_slider_set_range(slider, 0, selectionsSize - 1);
|
||||
|
||||
preview = lv_label_create(container);
|
||||
lv_obj_set_grid_cell(preview,
|
||||
LV_GRID_ALIGN_STRETCH, 2, 1,
|
||||
LV_GRID_ALIGN_CENTER, row, 1);
|
||||
lv_obj_set_size(preview, lv_pct(100), LV_SIZE_CONTENT);
|
||||
lv_obj_set_style_text_align(preview , LV_TEXT_ALIGN_LEFT, 0);
|
||||
|
||||
tt_hal_radio_get_parameter_unit_str(handle, param, unit, sizeof(unit));
|
||||
updatePreview();
|
||||
|
||||
lv_obj_add_event_cb(slider, [](lv_event_t * e) {
|
||||
lv_obj_t* slider = lv_event_get_target_obj(e);
|
||||
SliderSelectParameterInput* self = (SliderSelectParameterInput*)lv_event_get_user_data(e);
|
||||
self->updatePreview();
|
||||
}, LV_EVENT_VALUE_CHANGED, this);
|
||||
|
||||
}
|
||||
|
||||
virtual void updatePreview() override {
|
||||
Str text;
|
||||
text.appendf(fmt, selections[lv_slider_get_value(slider)]);
|
||||
text.append(unit);
|
||||
lv_label_set_text(preview, text.c_str());
|
||||
}
|
||||
};
|
||||
|
||||
static ParameterInput* makeLoraInput(RadioHandle handle, const RadioParameter param, lv_obj_t* container, int row) {
|
||||
static constexpr float bw_values[] = {7.8, 10.4, 15.6, 20.8, 31.25, 41.7, 62.5, 125.0, 250.0, 500.0, SliderSelectParameterInput::SELECT_END};
|
||||
switch (param) {
|
||||
case RADIO_POWER: //no break
|
||||
case RADIO_FREQUENCY:
|
||||
return new NumericParameterInput(handle, param, container, row);
|
||||
case RADIO_BANDWIDTH:
|
||||
return new SliderSelectParameterInput(handle, param, container, row, bw_values, "%.1f");
|
||||
case RADIO_SPREADFACTOR:
|
||||
return new SliderParameterInput(handle, param, container, row, 7, 12);
|
||||
case RADIO_CODINGRATE:
|
||||
return new SliderParameterInput(handle, param, container, row, 5, 8);
|
||||
case RADIO_SYNCWORD:
|
||||
return new SliderParameterInput(handle, param, container, row, 0, 255, "%02X");
|
||||
case RADIO_PREAMBLES:
|
||||
return new SliderParameterInput(handle, param, container, row, 0, 0xFFFF);
|
||||
default:
|
||||
return new NumericParameterInput(handle, param, container, row);
|
||||
}
|
||||
}
|
||||
|
||||
static ParameterInput* makeParameterInput(RadioHandle handle, const RadioParameter param, const Modulation modulation, lv_obj_t* container, int row) {
|
||||
switch (modulation) {
|
||||
case MODULATION_LORA:
|
||||
return makeLoraInput(handle, param, container, row);
|
||||
default:
|
||||
return new NumericParameterInput(handle, param, container, row);
|
||||
}
|
||||
}
|
||||
|
||||
class SettingsView {
|
||||
private:
|
||||
static constexpr size_t MAX_RADIOS = 32;
|
||||
static constexpr Modulation FIRST_MODULATION = MODULATION_NONE;
|
||||
static constexpr Modulation LAST_MODULATION = MODULATION_LRFHSS;
|
||||
static constexpr size_t MAX_MODEMS = LAST_MODULATION + 1;
|
||||
static constexpr size_t MAX_PARAMS = RADIO_NARROWGRID + 1;
|
||||
std::vector<RadioHandle> radios;
|
||||
|
||||
RadioHandle radios[MAX_RADIOS] = {0};
|
||||
size_t radioCount = 0;
|
||||
|
||||
RadioHandle radioSelected = nullptr;
|
||||
Modulation modemsAvailable[MAX_MODEMS] = {};
|
||||
size_t modemsAvailableCount = 0;
|
||||
RadioParameter paramsAvailable[MAX_PARAMS] = {};
|
||||
ParameterInput* paramInputs[MAX_PARAMS] = {0};
|
||||
size_t paramsAvailableCount = 0;
|
||||
|
||||
|
||||
lv_obj_t *mainPanel = nullptr;
|
||||
lv_obj_t *deviceForm = nullptr;
|
||||
lv_obj_t *radioDropdown = nullptr;
|
||||
lv_obj_t *radioSwitch = nullptr;
|
||||
lv_obj_t *modemDropdown = nullptr;
|
||||
|
||||
lv_obj_t *propertiesForm = nullptr;
|
||||
|
||||
public:
|
||||
void queryRadios() {
|
||||
DeviceId devices[MAX_RADIOS];
|
||||
uint16_t device_count = 0;
|
||||
if(!tt_hal_device_find(DEVICE_TYPE_RADIO, devices, &device_count, MAX_RADIOS)) {
|
||||
std::vector<DeviceId> devices(MAX_RADIOS);
|
||||
uint16_t radioCount = 0;
|
||||
if(!tt_hal_device_find(DEVICE_TYPE_RADIO, devices.data(), &radioCount, devices.capacity())) {
|
||||
// TT_LOG_W(TAG, "No radios registered with the system?");
|
||||
} else {
|
||||
size_t radios_allocated = 0;
|
||||
for (size_t i = 0; (i < device_count) && (i < MAX_RADIOS); ++i) {
|
||||
auto radio = tt_hal_radio_alloc(devices[i]);
|
||||
if (radio) {
|
||||
// TT_LOG_I(TAG, "Discovered radio \"%s\"", tt_hal_radio_get_name(radio));
|
||||
radios[radios_allocated] = radio;
|
||||
radios_allocated++;
|
||||
} else {
|
||||
devices.resize(radioCount);
|
||||
radios.reserve(devices.size());
|
||||
for (auto devId : devices) {
|
||||
auto radio = tt_hal_radio_alloc(devId);
|
||||
if (!radio) {
|
||||
// TT_LOG_E(TAG, "Error allocating radio handle for id=%d", devId);
|
||||
} else {
|
||||
radios.push_back(radio);
|
||||
// TT_LOG_I(TAG, "Discovered radio \"%s\"", tt_hal_radio_get_name(radio));
|
||||
}
|
||||
}
|
||||
radioCount = radios_allocated;
|
||||
}
|
||||
}
|
||||
|
||||
void getRadioNames(Str &names, const char* const separator) {
|
||||
bool getRadioNames(std::vector<std::string> &names) {
|
||||
int count = 1;
|
||||
names.clear();
|
||||
//for (auto radio : radios) {
|
||||
for (size_t i = 0; i < radioCount; ++i) {
|
||||
Str name(tt_hal_radio_get_name(radios[i]));
|
||||
auto last = (i == (radioCount - 1));
|
||||
for (auto radio : radios) {
|
||||
std::string name(tt_hal_radio_get_name(radio));
|
||||
if (name == "") {
|
||||
name.appendf("Unknown Radio %d", count);
|
||||
std::ostringstream oss("Unknown Radio ");
|
||||
oss << count;
|
||||
name = oss.str();
|
||||
}
|
||||
names.append(name.c_str());
|
||||
names.push_back(name);
|
||||
count++;
|
||||
if (!last) {
|
||||
names.append(separator);
|
||||
}
|
||||
}
|
||||
|
||||
return !names.empty();
|
||||
}
|
||||
|
||||
int getModemAvailableIndex(Modulation m) {
|
||||
for (size_t i = 0; i < modemsAvailableCount; ++i) {
|
||||
if (modemsAvailable[i] == m) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
lv_obj_t* initGridDropdownInput(lv_obj_t *container, int row, const char* const label, const char* const items) {
|
||||
lv_obj_t* label_obj = lv_label_create(container);
|
||||
lv_label_set_text(label_obj, label);
|
||||
lv_obj_set_grid_cell(label_obj,
|
||||
LV_GRID_ALIGN_STRETCH, 0, 1,
|
||||
LV_GRID_ALIGN_CENTER, row, 1);
|
||||
lv_obj_set_size(label_obj, lv_pct(100), LV_SIZE_CONTENT);
|
||||
|
||||
lv_obj_t* initParameterFormGeneric(lv_obj_t *parent, const Modulation modem) {
|
||||
lv_obj_t *container = propertiesForm;
|
||||
if (container) {
|
||||
lv_obj_clean(container);
|
||||
lv_obj_del(container);
|
||||
}
|
||||
lv_obj_t* input = lv_dropdown_create(container);
|
||||
lv_obj_set_grid_cell(input,
|
||||
LV_GRID_ALIGN_STRETCH, 1, 1,
|
||||
LV_GRID_ALIGN_CENTER, row, 1);
|
||||
lv_obj_set_size(input, lv_pct(100), LV_SIZE_CONTENT);
|
||||
lv_dropdown_set_options(input, items);
|
||||
|
||||
paramsAvailableCount = 0;
|
||||
container = lv_obj_create(parent);
|
||||
lv_obj_set_style_pad_all(container, 0, 0);
|
||||
lv_obj_set_layout(container, LV_LAYOUT_GRID);
|
||||
lv_obj_align(container, LV_ALIGN_TOP_MID, 0, 0);
|
||||
|
||||
const int grid_row_size = 40;
|
||||
const int grid_col_size = 140;
|
||||
static constexpr size_t row_dsc_last = RADIO_NARROWGRID + 1;
|
||||
static lv_coord_t col_dsc[] = {LV_GRID_FR(1), LV_GRID_FR(1), grid_col_size, LV_GRID_TEMPLATE_LAST};
|
||||
static lv_coord_t row_dsc[row_dsc_last] = {0};
|
||||
for (size_t i = 0; i < row_dsc_last; ++i) {
|
||||
row_dsc[i] = grid_row_size; //LV_GRID_FR(1);
|
||||
}
|
||||
row_dsc[row_dsc_last - 1] = LV_GRID_TEMPLATE_LAST;
|
||||
lv_obj_set_grid_dsc_array(container, col_dsc, row_dsc);
|
||||
|
||||
char unit_buffer[32] = {0};
|
||||
for (RadioParameter param = RADIO_POWER;
|
||||
param <= RADIO_NARROWGRID;
|
||||
param = static_cast<RadioParameter>((size_t)param + 1)) {
|
||||
float value = 0.0;
|
||||
Str value_buffer;
|
||||
auto status = tt_hal_radio_get_parameter(radioSelected, param, &value);
|
||||
if (status == RADIO_PARAM_SUCCESS) {
|
||||
auto input = makeParameterInput(radioSelected, param, modem, container, paramsAvailableCount);
|
||||
paramInputs[paramsAvailableCount] = input;
|
||||
//lv_group_focus_obj(input);
|
||||
paramsAvailable[paramsAvailableCount] = param;
|
||||
paramsAvailableCount++;
|
||||
}
|
||||
}
|
||||
row_dsc[paramsAvailableCount] = LV_GRID_TEMPLATE_LAST;
|
||||
lv_obj_set_grid_dsc_array(container, col_dsc, row_dsc);
|
||||
lv_obj_set_size(container, lv_pct(100), lv_pct(100));
|
||||
|
||||
return container;
|
||||
}
|
||||
|
||||
void selectModulation(int modemIndex) {
|
||||
lv_dropdown_set_selected(modemDropdown, modemIndex);
|
||||
if (tt_hal_radio_set_modulation(radioSelected, modemsAvailable[modemIndex])) {
|
||||
propertiesForm = initParameterFormGeneric(mainPanel, modemsAvailable[modemIndex]);
|
||||
//clownvomit(propertiesForm);
|
||||
}
|
||||
}
|
||||
|
||||
void selectRadio(int index) {
|
||||
radioSelected = radios[index];
|
||||
assert(radioSelected);
|
||||
|
||||
for (size_t i = 0; i < MAX_MODEMS; ++i) {
|
||||
modemsAvailable[i] = MODULATION_NONE;
|
||||
}
|
||||
|
||||
Str modulation_list;
|
||||
modemsAvailableCount = 1;
|
||||
modemsAvailable[0] = MODULATION_NONE;
|
||||
modulation_list.append(LV_SYMBOL_MINUS);
|
||||
modulation_list.append(" ");
|
||||
modulation_list.append(LV_SYMBOL_MINUS);
|
||||
modulation_list.append(" ");
|
||||
modulation_list.append("Disabled\n");
|
||||
|
||||
|
||||
for (Modulation mod = FIRST_MODULATION;
|
||||
mod <= LAST_MODULATION;
|
||||
mod = static_cast<Modulation>((size_t)mod + 1)) {
|
||||
bool canRx = tt_hal_radio_can_receive(radioSelected, mod);
|
||||
bool canTx = tt_hal_radio_can_transmit(radioSelected, mod);
|
||||
bool place_sep = (canRx || canTx) && (mod != LAST_MODULATION);
|
||||
|
||||
if (!canRx && !canTx) {
|
||||
continue;
|
||||
}
|
||||
modemsAvailable[modemsAvailableCount] = mod;
|
||||
modemsAvailableCount++;
|
||||
|
||||
if (canRx) {
|
||||
modulation_list.append(LV_SYMBOL_DOWNLOAD);
|
||||
modulation_list.append(" ");
|
||||
} else {
|
||||
modulation_list.append(LV_SYMBOL_MINUS);
|
||||
modulation_list.append(" ");
|
||||
}
|
||||
|
||||
if (canTx) {
|
||||
modulation_list.append(LV_SYMBOL_UPLOAD);
|
||||
modulation_list.append(" ");
|
||||
} else {
|
||||
modulation_list.append(LV_SYMBOL_MINUS);
|
||||
modulation_list.append(" ");
|
||||
}
|
||||
|
||||
modulation_list.append(toString(mod));
|
||||
if (place_sep) {
|
||||
modulation_list.append("\n");
|
||||
}
|
||||
}
|
||||
|
||||
lv_dropdown_set_options(modemDropdown, modulation_list.c_str());
|
||||
auto modemIndexConfigured = getModemAvailableIndex(tt_hal_radio_get_modulation(radioSelected));
|
||||
if (modemIndexConfigured > -1) {
|
||||
lv_dropdown_set_selected(modemDropdown, modemIndexConfigured);
|
||||
selectModulation(modemIndexConfigured);
|
||||
}
|
||||
return input;
|
||||
}
|
||||
|
||||
lv_obj_t *initDeviceForm(lv_obj_t *parent) {
|
||||
lv_obj_t *container = lv_obj_create(parent);
|
||||
lv_obj_set_size(container, lv_pct(100), LV_SIZE_CONTENT);
|
||||
lv_obj_set_size(container, lv_pct(100), lv_pct(100));
|
||||
lv_obj_set_style_pad_all(container, 0, 0);
|
||||
|
||||
const int grid_row_size = 40;
|
||||
const int grid_col_size = 45;
|
||||
static lv_coord_t lora_col_dsc[] = {LV_GRID_FR(1), LV_GRID_FR(1), grid_col_size, LV_GRID_TEMPLATE_LAST};
|
||||
static lv_coord_t lora_col_dsc[] = {LV_GRID_FR(3), LV_GRID_FR(2), grid_col_size, LV_GRID_TEMPLATE_LAST};
|
||||
static lv_coord_t lora_row_dsc[] = {
|
||||
grid_row_size,
|
||||
grid_row_size,
|
||||
LV_GRID_TEMPLATE_LAST};
|
||||
lv_obj_set_layout(container, LV_LAYOUT_GRID);
|
||||
lv_obj_set_grid_dsc_array(container, lora_col_dsc, lora_row_dsc);
|
||||
|
||||
Str radio_names;
|
||||
getRadioNames(radio_names, "\n");
|
||||
radioDropdown = initGridDropdownInput(container, 0, "Device", radio_names.c_str());
|
||||
modemDropdown = initGridDropdownInput(container, 1, "Modulation", "none available");
|
||||
std::ostringstream item_oss("");
|
||||
std::vector<std::string> radio_names;
|
||||
if (getRadioNames(radio_names)) {
|
||||
for (size_t i = 0; i < radio_names.size(); ++i) {
|
||||
auto name = radio_names[i];
|
||||
auto last = (i != (radio_names.size() - 1));
|
||||
item_oss << name;
|
||||
if (!last) {
|
||||
item_oss << "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
radioDropdown = initGridDropdownInput(container, 0, "Device", item_oss.str().c_str());
|
||||
radioSwitch = lv_switch_create(container);
|
||||
lv_obj_set_grid_cell(radioSwitch,
|
||||
LV_GRID_ALIGN_STRETCH, 2, 1,
|
||||
LV_GRID_ALIGN_CENTER, 0, 1);
|
||||
lv_obj_set_size(radioSwitch, lv_pct(100), 20);
|
||||
|
||||
|
||||
lv_obj_add_event_cb(modemDropdown, [](lv_event_t * e) {
|
||||
SettingsView* self = (SettingsView*)lv_event_get_user_data(e);
|
||||
lv_obj_t* input = lv_event_get_target_obj(e);
|
||||
self->selectModulation(lv_dropdown_get_selected(input));
|
||||
}, LV_EVENT_VALUE_CHANGED, this);
|
||||
|
||||
selectRadio(0);
|
||||
return container;
|
||||
}
|
||||
|
||||
void initUi(lv_obj_t *parent) {
|
||||
mainPanel = lv_obj_create(parent);
|
||||
lv_obj_set_size(mainPanel, lv_pct(100), lv_pct(80));
|
||||
lv_obj_set_flex_flow(mainPanel, LV_FLEX_FLOW_COLUMN);
|
||||
lv_obj_align(mainPanel, LV_ALIGN_TOP_MID, 0, 0);
|
||||
lv_obj_set_style_border_width(mainPanel, 0, 0);
|
||||
lv_obj_set_style_pad_all(mainPanel, 0, 0);
|
||||
lv_obj_t *container = lv_obj_create(parent);
|
||||
lv_obj_set_size(container, lv_pct(100), lv_pct(80));
|
||||
lv_obj_set_flex_flow(container, LV_FLEX_FLOW_COLUMN);
|
||||
lv_obj_align(container, LV_ALIGN_TOP_MID, 0, 0);
|
||||
lv_obj_set_style_border_width(container, 0, 0);
|
||||
lv_obj_set_style_pad_all(container, 0, 0);
|
||||
// Only needed if container needs to be scrollable through encoder long long press
|
||||
lv_obj_add_flag(mainPanel, (lv_obj_flag_t)(LV_OBJ_FLAG_CLICKABLE | LV_OBJ_FLAG_SCROLL_ON_FOCUS));
|
||||
auto* group = lv_group_get_default();
|
||||
lv_group_add_obj(group, mainPanel);
|
||||
//lv_obj_add_event_cb(btn, scrollbar_highlight, LV_EVENT_FOCUS, NULL);
|
||||
//lv_obj_add_event_cb(btn, scrollbar_restore, LV_EVENT_DEFOCUSED, NULL);
|
||||
|
||||
// Create once (e.g. during init)
|
||||
static lv_style_t style_scroll_focus;
|
||||
lv_style_init(&style_scroll_focus);
|
||||
lv_style_set_bg_color(&style_scroll_focus, lv_color_make(0x40,0xA0,0xFF));
|
||||
lv_style_set_bg_opa(&style_scroll_focus, LV_OPA_COVER);
|
||||
lv_style_set_border_width(&style_scroll_focus, 1);
|
||||
lv_style_set_border_color(&style_scroll_focus, lv_color_black());
|
||||
|
||||
// Apply style targeted to the scrollbar part when the object is FOCUSED
|
||||
// LV_PART_SCROLLBAR | LV_STATE_FOCUSED will ensure the style is used only while focused.
|
||||
lv_obj_add_style(mainPanel, &style_scroll_focus, LV_PART_SCROLLBAR | LV_STATE_FOCUSED);
|
||||
|
||||
deviceForm = initDeviceForm(mainPanel);
|
||||
//lv_obj_add_flag(container, (lv_obj_flag_t)(LV_OBJ_FLAG_CLICKABLE | LV_OBJ_FLAG_SCROLL_ON_FOCUS));
|
||||
deviceForm = initDeviceForm(container);
|
||||
}
|
||||
|
||||
explicit SettingsView(lv_obj_t *parent) {
|
||||
@ -639,7 +157,6 @@ void RadioSet::onShow(AppHandle appHandle, lv_obj_t* parent) {
|
||||
lv_obj_set_style_border_color(uiDropDownMenu, lv_color_hex(0xFAFAFA), LV_PART_MAIN);
|
||||
lv_obj_set_style_border_width(uiDropDownMenu, 1, LV_PART_MAIN);
|
||||
lv_obj_align(uiDropDownMenu, LV_ALIGN_RIGHT_MID, 0, 0);
|
||||
lv_obj_set_width(uiDropDownMenu, 120);
|
||||
|
||||
lv_obj_t* wrapper = lv_obj_create(parent);
|
||||
lv_obj_set_flex_flow(wrapper, LV_FLEX_FLOW_COLUMN);
|
||||
@ -652,17 +169,7 @@ void RadioSet::onShow(AppHandle appHandle, lv_obj_t* parent) {
|
||||
lv_obj_set_style_border_width(wrapper, 0, 0);
|
||||
lv_obj_remove_flag(wrapper, LV_OBJ_FLAG_SCROLLABLE);
|
||||
|
||||
settingsView = new SettingsView(wrapper);
|
||||
}
|
||||
|
||||
|
||||
RadioSet::~RadioSet() {
|
||||
if (termView) {
|
||||
delete termView;
|
||||
}
|
||||
if (settingsView) {
|
||||
delete settingsView;
|
||||
}
|
||||
settingsView = std::make_shared<SettingsView>(wrapper);
|
||||
}
|
||||
|
||||
// ????
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "tt_app.h"
|
||||
#include "tt_hal_radio.h"
|
||||
#include <lvgl.h>
|
||||
@ -13,12 +15,10 @@ class RadioSet {
|
||||
lv_obj_t* progressBar = nullptr;
|
||||
lv_obj_t* progressText = nullptr;
|
||||
|
||||
TermView* termView = nullptr;
|
||||
SettingsView* settingsView = nullptr;
|
||||
std::shared_ptr<TermView> termView = nullptr;
|
||||
std::shared_ptr<SettingsView> settingsView = nullptr;
|
||||
|
||||
public:
|
||||
|
||||
~RadioSet();
|
||||
|
||||
void onShow(AppHandle context, lv_obj_t* parent);
|
||||
};
|
||||
|
||||
@ -1,2 +0,0 @@
|
||||
#define STR_IMPLEMENTATION
|
||||
#include "Str.h"
|
||||
@ -1,618 +0,0 @@
|
||||
// Str v0.33
|
||||
// Simple C++ string type with an optional local buffer, by Omar Cornut
|
||||
// https://github.com/ocornut/str
|
||||
|
||||
// LICENSE
|
||||
// This software is in the public domain. Where that dedication is not
|
||||
// recognized, you are granted a perpetual, irrevocable license to copy,
|
||||
// distribute, and modify this file as you see fit.
|
||||
|
||||
// USAGE
|
||||
// Include this file in whatever places need to refer to it.
|
||||
// In ONE .cpp file, write '#define STR_IMPLEMENTATION' before the #include of this file.
|
||||
// This expands out the actual implementation into that C/C++ file.
|
||||
|
||||
|
||||
/*
|
||||
- This isn't a fully featured string class.
|
||||
- It is a simple, bearable replacement to std::string that isn't heap abusive nor bloated (can actually be debugged by humans).
|
||||
- String are mutable. We don't maintain size so length() is not-constant time.
|
||||
- Maximum string size currently limited to 2 MB (we allocate 21 bits to hold capacity).
|
||||
- Local buffer size is currently limited to 1023 bytes (we allocate 10 bits to hold local buffer size).
|
||||
- In "non-owned" mode for literals/reference we don't do any tracking/counting of references.
|
||||
- Overhead is 8-bytes in 32-bits, 16-bytes in 64-bits (12 + alignment).
|
||||
- This code hasn't been tested very much. it is probably incomplete or broken. Made it for my own use.
|
||||
|
||||
The idea is that you can provide an arbitrary sized local buffer if you expect string to fit
|
||||
most of the time, and then you avoid using costly heap.
|
||||
|
||||
No local buffer, always use heap, sizeof()==8~16 (depends if your pointers are 32-bits or 64-bits)
|
||||
|
||||
Str s = "hey";
|
||||
|
||||
With a local buffer of 16 bytes, sizeof() == 8~16 + 16 bytes.
|
||||
|
||||
Str16 s = "filename.h"; // copy into local buffer
|
||||
Str16 s = "long_filename_not_very_long_but_longer_than_expected.h"; // use heap
|
||||
|
||||
With a local buffer of 256 bytes, sizeof() == 8~16 + 256 bytes.
|
||||
|
||||
Str256 s = "long_filename_not_very_long_but_longer_than_expected.h"; // copy into local buffer
|
||||
|
||||
Common sizes are defined at the bottom of Str.h, you may define your own.
|
||||
|
||||
Functions:
|
||||
|
||||
Str256 s;
|
||||
s.set("hello sailor"); // set (copy)
|
||||
s.setf("%s/%s.tmp", folder, filename); // set (w/format)
|
||||
s.append("hello"); // append. cost a length() calculation!
|
||||
s.appendf("hello %d", 42); // append (w/format). cost a length() calculation!
|
||||
s.set_ref("Hey!"); // set (literal/reference, just copy pointer, no tracking)
|
||||
|
||||
Constructor helper for format string: add a trailing 'f' to the type. Underlying type is the same.
|
||||
|
||||
Str256f filename("%s/%s.tmp", folder, filename); // construct (w/format)
|
||||
fopen(Str256f("%s/%s.tmp, folder, filename).c_str(), "rb"); // construct (w/format), use as function param, destruct
|
||||
|
||||
Constructor helper for reference/literal:
|
||||
|
||||
StrRef ref("literal"); // copy pointer, no allocation, no string copy
|
||||
StrRef ref2(GetDebugName()); // copy pointer. no tracking of anything whatsoever, know what you are doing!
|
||||
|
||||
All StrXXX types derives from Str and instance hold the local buffer capacity. So you can pass e.g. Str256* to a function taking base type Str* and it will be functional.
|
||||
|
||||
void MyFunc(Str& s) { s = "Hello"; } // will use local buffer if available in Str instance
|
||||
|
||||
(Using a template e.g. Str<N> we could remove the LocalBufSize storage but it would make passing typed Str<> to functions tricky.
|
||||
Instead we don't use template so you can pass them around as the base type Str*. Also, templates are ugly.)
|
||||
*/
|
||||
|
||||
/*
|
||||
CHANGELOG
|
||||
0.33 - fixed capacity() return value to match standard. e.g. a Str256's capacity() now returns 255, not 256.
|
||||
0.32 - added owned() accessor.
|
||||
0.31 - fixed various warnings.
|
||||
0.30 - turned into a single header file, removed Str.cpp.
|
||||
0.29 - fixed bug when calling reserve on non-owned strings (ie. when using StrRef or set_ref), and fixed <string> include.
|
||||
0.28 - breaking change: replaced Str32 by Str30 to avoid collision with Str32 from MacTypes.h .
|
||||
0.27 - added STR_API and basic .natvis file.
|
||||
0.26 - fixed set(cont char* src, const char* src_end) writing null terminator to the wrong position.
|
||||
0.25 - allow set(const char* NULL) or operator= NULL to clear the string. note that set() from range or other types are not allowed.
|
||||
0.24 - allow set_ref(const char* NULL) to clear the string. include fixes for linux.
|
||||
0.23 - added append(char). added append_from(int idx, XXX) functions. fixed some compilers warnings.
|
||||
0.22 - documentation improvements, comments. fixes for some compilers.
|
||||
0.21 - added StrXXXf() constructor to construct directly from a format string.
|
||||
*/
|
||||
|
||||
/*
|
||||
TODO
|
||||
- Since we lose 4-bytes of padding on 64-bits architecture, perhaps just spread the header to 8-bytes and lift size limits?
|
||||
- More functions/helpers.
|
||||
*/
|
||||
|
||||
#ifndef STR_INCLUDED
|
||||
#define STR_INCLUDED
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// CONFIGURATION
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
#ifndef STR_MEMALLOC
|
||||
#define STR_MEMALLOC malloc
|
||||
#include <cstdio>
|
||||
#endif
|
||||
#ifndef STR_MEMFREE
|
||||
#define STR_MEMFREE free
|
||||
#include <cstdlib>
|
||||
#endif
|
||||
#ifndef STR_ASSERT
|
||||
#define STR_ASSERT assert
|
||||
#include <cassert>
|
||||
#endif
|
||||
#ifndef STR_API
|
||||
#define STR_API
|
||||
#endif
|
||||
#include <cstdarg> // for va_list
|
||||
#include <cstring> // for strlen, strcmp, memcpy, etc.
|
||||
|
||||
// Configuration: #define STR_DEFINE_STR32 1 to keep defining Str32/Str32f, but be warned: on macOS/iOS, MacTypes.h also defines a type named Str32.
|
||||
#ifndef STR_DEFINE_STR32
|
||||
#define STR_DEFINE_STR32 0
|
||||
#endif
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// HEADERS
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
// This is the base class that you can pass around
|
||||
// Footprint is 8-bytes (32-bits arch) or 16-bytes (64-bits arch)
|
||||
class STR_API Str
|
||||
{
|
||||
char* Data; // Point to LocalBuf() or heap allocated
|
||||
int Capacity : 21; // Max 2 MB. Exclude zero terminator.
|
||||
int LocalBufSize : 10; // Max 1023 bytes
|
||||
unsigned int Owned : 1; // Set when we have ownership of the pointed data (most common, unless using set_ref() method or StrRef constructor)
|
||||
|
||||
public:
|
||||
inline char* c_str() { return Data; }
|
||||
inline const char* c_str() const { return Data; }
|
||||
inline bool empty() const { return Data[0] == 0; }
|
||||
inline int length() const { return (int)strlen(Data); } // by design, allow user to write into the buffer at any time
|
||||
inline int capacity() const { return Capacity; }
|
||||
inline bool owned() const { return Owned ? true : false; }
|
||||
|
||||
inline void set_ref(const char* src);
|
||||
int setf(const char* fmt, ...);
|
||||
int setfv(const char* fmt, va_list args);
|
||||
int setf_nogrow(const char* fmt, ...);
|
||||
int setfv_nogrow(const char* fmt, va_list args);
|
||||
int append(char c);
|
||||
int append(const char* s, const char* s_end = NULL);
|
||||
int appendf(const char* fmt, ...);
|
||||
int appendfv(const char* fmt, va_list args);
|
||||
int append_from(int idx, char c);
|
||||
int append_from(int idx, const char* s, const char* s_end = NULL); // If you know the string length or want to append from a certain point
|
||||
int appendf_from(int idx, const char* fmt, ...);
|
||||
int appendfv_from(int idx, const char* fmt, va_list args);
|
||||
|
||||
void clear();
|
||||
void reserve(int cap);
|
||||
void reserve_discard(int cap);
|
||||
void shrink_to_fit();
|
||||
|
||||
inline char& operator[](size_t i) { return Data[i]; }
|
||||
inline char operator[](size_t i) const { return Data[i]; }
|
||||
//explicit operator const char*() const{ return Data; }
|
||||
|
||||
inline Str();
|
||||
inline Str(const char* rhs);
|
||||
inline void set(const char* src);
|
||||
inline void set(const char* src, const char* src_end);
|
||||
inline Str& operator=(const char* rhs) { set(rhs); return *this; }
|
||||
inline bool operator==(const char* rhs) const { return strcmp(c_str(), rhs) == 0; }
|
||||
|
||||
inline Str(const Str& rhs);
|
||||
inline void set(const Str& src);
|
||||
inline void set(int count, char character);
|
||||
inline Str& operator=(const Str& rhs) { set(rhs); return *this; }
|
||||
inline bool operator==(const Str& rhs) const { return strcmp(c_str(), rhs.c_str()) == 0; }
|
||||
|
||||
inline Str(int amount, char character);
|
||||
|
||||
// Destructor for all variants
|
||||
inline ~Str()
|
||||
{
|
||||
if (Owned && !is_using_local_buf())
|
||||
STR_MEMFREE(Data);
|
||||
}
|
||||
|
||||
static char* EmptyBuffer;
|
||||
|
||||
protected:
|
||||
inline char* local_buf() { return (char*)this + sizeof(Str); }
|
||||
inline const char* local_buf() const { return (char*)this + sizeof(Str); }
|
||||
inline bool is_using_local_buf() const { return Data == local_buf() && LocalBufSize != 0; }
|
||||
|
||||
// Constructor for StrXXX variants with local buffer
|
||||
Str(unsigned short local_buf_size)
|
||||
{
|
||||
STR_ASSERT(local_buf_size < 1024);
|
||||
Data = local_buf();
|
||||
Data[0] = '\0';
|
||||
Capacity = local_buf_size ? local_buf_size - 1 : 0;
|
||||
LocalBufSize = local_buf_size;
|
||||
Owned = 1;
|
||||
}
|
||||
};
|
||||
|
||||
void Str::set(const char* src)
|
||||
{
|
||||
// We allow set(NULL) or via = operator to clear the string.
|
||||
if (src == NULL)
|
||||
{
|
||||
clear();
|
||||
return;
|
||||
}
|
||||
int buf_len = (int)strlen(src);
|
||||
if (Capacity < buf_len)
|
||||
reserve_discard(buf_len);
|
||||
memcpy(Data, src, (size_t)(buf_len + 1));
|
||||
Owned = 1;
|
||||
}
|
||||
|
||||
void Str::set(const char* src, const char* src_end)
|
||||
{
|
||||
STR_ASSERT(src != NULL && src_end >= src);
|
||||
int buf_len = (int)(src_end - src);
|
||||
if ((int)Capacity < buf_len)
|
||||
reserve_discard(buf_len);
|
||||
memcpy(Data, src, (size_t)buf_len);
|
||||
Data[buf_len] = 0;
|
||||
Owned = 1;
|
||||
}
|
||||
|
||||
void Str::set(const Str& src)
|
||||
{
|
||||
int buf_len = (int)strlen(src.c_str());
|
||||
if ((int)Capacity < buf_len)
|
||||
reserve_discard(buf_len);
|
||||
memcpy(Data, src.c_str(), (size_t)(buf_len + 1));
|
||||
Owned = 1;
|
||||
}
|
||||
|
||||
void Str::set(int count, char character) {
|
||||
int buf_len = count + 1;
|
||||
if ((int)Capacity < buf_len)
|
||||
reserve_discard(buf_len);
|
||||
memset(Data, character, count);
|
||||
Data[count] = 0;
|
||||
Owned = 1;
|
||||
}
|
||||
|
||||
inline void Str::set_ref(const char* src)
|
||||
{
|
||||
if (Owned && !is_using_local_buf())
|
||||
STR_MEMFREE(Data);
|
||||
Data = src ? (char*)src : EmptyBuffer;
|
||||
Capacity = 0;
|
||||
Owned = 0;
|
||||
}
|
||||
|
||||
Str::Str()
|
||||
{
|
||||
Data = EmptyBuffer; // Shared READ-ONLY initial buffer for 0 capacity
|
||||
Capacity = 0;
|
||||
LocalBufSize = 0;
|
||||
Owned = 0;
|
||||
}
|
||||
|
||||
Str::Str(const Str& rhs) : Str()
|
||||
{
|
||||
set(rhs);
|
||||
}
|
||||
|
||||
Str::Str(const char* rhs) : Str()
|
||||
{
|
||||
set(rhs);
|
||||
}
|
||||
|
||||
Str::Str(int amount, char character) : Str() {
|
||||
set(amount, character);
|
||||
}
|
||||
|
||||
// Literal/reference string
|
||||
class StrRef : public Str
|
||||
{
|
||||
public:
|
||||
StrRef(const char* s) : Str() { set_ref(s); }
|
||||
};
|
||||
|
||||
#define STR_DEFINETYPE(TYPENAME, LOCALBUFSIZE) \
|
||||
class TYPENAME : public Str \
|
||||
{ \
|
||||
char local_buf[LOCALBUFSIZE]; \
|
||||
public: \
|
||||
TYPENAME() : Str(LOCALBUFSIZE) {} \
|
||||
TYPENAME(const Str& rhs) : Str(LOCALBUFSIZE) { set(rhs); } \
|
||||
TYPENAME(const char* rhs) : Str(LOCALBUFSIZE) { set(rhs); } \
|
||||
TYPENAME(const TYPENAME& rhs) : Str(LOCALBUFSIZE) { set(rhs); } \
|
||||
TYPENAME& operator=(const char* rhs) { set(rhs); return *this; } \
|
||||
TYPENAME& operator=(const Str& rhs) { set(rhs); return *this; } \
|
||||
TYPENAME& operator=(const TYPENAME& rhs) { set(rhs); return *this; } \
|
||||
};
|
||||
|
||||
// Disable PVS-Studio warning V730: Not all members of a class are initialized inside the constructor (local_buf is not initialized and that is fine)
|
||||
// -V:STR_DEFINETYPE:730
|
||||
|
||||
// Helper to define StrXXXf constructors
|
||||
#define STR_DEFINETYPE_F(TYPENAME, TYPENAME_F) \
|
||||
class TYPENAME_F : public TYPENAME \
|
||||
{ \
|
||||
public: \
|
||||
TYPENAME_F(const char* fmt, ...) : TYPENAME() { va_list args; va_start(args, fmt); setfv(fmt, args); va_end(args); } \
|
||||
};
|
||||
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wunused-private-field" // warning : private field 'local_buf' is not used
|
||||
#endif
|
||||
|
||||
// Declaring types for common sizes here
|
||||
STR_DEFINETYPE(Str16, 16)
|
||||
STR_DEFINETYPE(Str30, 30)
|
||||
STR_DEFINETYPE(Str64, 64)
|
||||
STR_DEFINETYPE(Str128, 128)
|
||||
STR_DEFINETYPE(Str256, 256)
|
||||
STR_DEFINETYPE(Str512, 512)
|
||||
|
||||
// Declaring helper constructors to pass in format strings in one statement
|
||||
STR_DEFINETYPE_F(Str16, Str16f)
|
||||
STR_DEFINETYPE_F(Str30, Str30f)
|
||||
STR_DEFINETYPE_F(Str64, Str64f)
|
||||
STR_DEFINETYPE_F(Str128, Str128f)
|
||||
STR_DEFINETYPE_F(Str256, Str256f)
|
||||
STR_DEFINETYPE_F(Str512, Str512f)
|
||||
|
||||
#if STR_DEFINE_STR32
|
||||
STR_DEFINETYPE(Str32, 32)
|
||||
STR_DEFINETYPE_F(Str32, Str32f)
|
||||
#endif
|
||||
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
|
||||
#endif // #ifndef STR_INCLUDED
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// IMPLEMENTATION
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
#ifdef STR_IMPLEMENTATION
|
||||
|
||||
#include <stdio.h> // for vsnprintf
|
||||
|
||||
// On some platform vsnprintf() takes va_list by reference and modifies it.
|
||||
// va_copy is the 'correct' way to copy a va_list but Visual Studio prior to 2013 doesn't have it.
|
||||
#ifndef va_copy
|
||||
#define va_copy(dest, src) (dest = src)
|
||||
#endif
|
||||
|
||||
// Static empty buffer we can point to for empty strings
|
||||
// Pointing to a literal increases the like-hood of getting a crash if someone attempts to write in the empty string buffer.
|
||||
char* Str::EmptyBuffer = (char*)"\0NULL";
|
||||
|
||||
// Clear
|
||||
void Str::clear()
|
||||
{
|
||||
if (Owned && !is_using_local_buf())
|
||||
STR_MEMFREE(Data);
|
||||
if (LocalBufSize)
|
||||
{
|
||||
Data = local_buf();
|
||||
Data[0] = '\0';
|
||||
Capacity = LocalBufSize - 1;
|
||||
Owned = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
Data = EmptyBuffer;
|
||||
Capacity = 0;
|
||||
Owned = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Reserve memory, preserving the current of the buffer
|
||||
// Capacity doesn't include the zero terminator, so reserve(5) is enough to store "hello".
|
||||
void Str::reserve(int new_capacity)
|
||||
{
|
||||
if (new_capacity <= Capacity)
|
||||
return;
|
||||
|
||||
char* new_data;
|
||||
if (new_capacity <= LocalBufSize - 1)
|
||||
{
|
||||
// Disowned -> LocalBuf
|
||||
new_data = local_buf();
|
||||
new_capacity = LocalBufSize - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Disowned or LocalBuf -> Heap
|
||||
new_data = (char*)STR_MEMALLOC((size_t)(new_capacity + 1) * sizeof(char));
|
||||
}
|
||||
|
||||
// string in Data might be longer than new_capacity if it wasn't owned, don't copy too much
|
||||
#ifdef _MSC_VER
|
||||
strncpy_s(new_data, (size_t)new_capacity + 1, Data, (size_t)new_capacity);
|
||||
#else
|
||||
strncpy(new_data, Data, (size_t)new_capacity);
|
||||
#endif
|
||||
new_data[new_capacity] = 0;
|
||||
|
||||
if (Owned && !is_using_local_buf())
|
||||
STR_MEMFREE(Data);
|
||||
|
||||
Data = new_data;
|
||||
Capacity = new_capacity;
|
||||
Owned = 1;
|
||||
}
|
||||
|
||||
// Reserve memory, discarding the current of the buffer (if we expect to be fully rewritten)
|
||||
void Str::reserve_discard(int new_capacity)
|
||||
{
|
||||
if (new_capacity <= Capacity)
|
||||
return;
|
||||
|
||||
if (Owned && !is_using_local_buf())
|
||||
STR_MEMFREE(Data);
|
||||
|
||||
if (new_capacity <= LocalBufSize - 1)
|
||||
{
|
||||
// Disowned -> LocalBuf
|
||||
Data = local_buf();
|
||||
Capacity = LocalBufSize - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Disowned or LocalBuf -> Heap
|
||||
Data = (char*)STR_MEMALLOC((size_t)(new_capacity + 1) * sizeof(char));
|
||||
Capacity = new_capacity;
|
||||
}
|
||||
Owned = 1;
|
||||
}
|
||||
|
||||
void Str::shrink_to_fit()
|
||||
{
|
||||
if (!Owned || is_using_local_buf())
|
||||
return;
|
||||
int new_capacity = length();
|
||||
if (Capacity <= new_capacity)
|
||||
return;
|
||||
|
||||
char* new_data = (char*)STR_MEMALLOC((size_t)(new_capacity + 1) * sizeof(char));
|
||||
memcpy(new_data, Data, (size_t)(new_capacity + 1));
|
||||
STR_MEMFREE(Data);
|
||||
Data = new_data;
|
||||
Capacity = new_capacity;
|
||||
}
|
||||
|
||||
// FIXME: merge setfv() and appendfv()?
|
||||
int Str::setfv(const char* fmt, va_list args)
|
||||
{
|
||||
// Needed for portability on platforms where va_list are passed by reference and modified by functions
|
||||
va_list args2;
|
||||
va_copy(args2, args);
|
||||
|
||||
// MSVC returns -1 on overflow when writing, which forces us to do two passes
|
||||
// FIXME-OPT: Find a way around that.
|
||||
#ifdef _MSC_VER
|
||||
int len = vsnprintf(NULL, 0, fmt, args);
|
||||
STR_ASSERT(len >= 0);
|
||||
|
||||
if (Capacity < len)
|
||||
reserve_discard(len);
|
||||
len = vsnprintf(Data, (size_t)len + 1, fmt, args2);
|
||||
#else
|
||||
// First try
|
||||
int len = vsnprintf(Owned ? Data : NULL, Owned ? (size_t)(Capacity + 1): 0, fmt, args);
|
||||
STR_ASSERT(len >= 0);
|
||||
|
||||
if (Capacity < len)
|
||||
{
|
||||
reserve_discard(len);
|
||||
len = vsnprintf(Data, (size_t)len + 1, fmt, args2);
|
||||
}
|
||||
#endif
|
||||
|
||||
STR_ASSERT(Owned);
|
||||
return len;
|
||||
}
|
||||
|
||||
int Str::setf(const char* fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
int len = setfv(fmt, args);
|
||||
va_end(args);
|
||||
return len;
|
||||
}
|
||||
|
||||
int Str::setfv_nogrow(const char* fmt, va_list args)
|
||||
{
|
||||
STR_ASSERT(Owned);
|
||||
|
||||
if (Capacity == 0)
|
||||
return 0;
|
||||
|
||||
int w = vsnprintf(Data, (size_t)(Capacity + 1), fmt, args);
|
||||
Data[Capacity] = 0;
|
||||
Owned = 1;
|
||||
return (w == -1) ? Capacity : w;
|
||||
}
|
||||
|
||||
int Str::setf_nogrow(const char* fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
int len = setfv_nogrow(fmt, args);
|
||||
va_end(args);
|
||||
return len;
|
||||
}
|
||||
|
||||
int Str::append_from(int idx, char c)
|
||||
{
|
||||
int add_len = 1;
|
||||
if (Capacity < idx + add_len)
|
||||
reserve(idx + add_len);
|
||||
Data[idx] = c;
|
||||
Data[idx + add_len] = 0;
|
||||
STR_ASSERT(Owned);
|
||||
return add_len;
|
||||
}
|
||||
|
||||
int Str::append_from(int idx, const char* s, const char* s_end)
|
||||
{
|
||||
if (!s_end)
|
||||
s_end = s + strlen(s);
|
||||
int add_len = (int)(s_end - s);
|
||||
if (Capacity < idx + add_len)
|
||||
reserve(idx + add_len);
|
||||
memcpy(Data + idx, (const void*)s, (size_t)add_len);
|
||||
Data[idx + add_len] = 0; // Our source data isn't necessarily zero terminated
|
||||
STR_ASSERT(Owned);
|
||||
return add_len;
|
||||
}
|
||||
|
||||
// FIXME: merge setfv() and appendfv()?
|
||||
int Str::appendfv_from(int idx, const char* fmt, va_list args)
|
||||
{
|
||||
// Needed for portability on platforms where va_list are passed by reference and modified by functions
|
||||
va_list args2;
|
||||
va_copy(args2, args);
|
||||
|
||||
// MSVC returns -1 on overflow when writing, which forces us to do two passes
|
||||
// FIXME-OPT: Find a way around that.
|
||||
#ifdef _MSC_VER
|
||||
int add_len = vsnprintf(NULL, 0, fmt, args);
|
||||
STR_ASSERT(add_len >= 0);
|
||||
|
||||
if (Capacity < idx + add_len)
|
||||
reserve(idx + add_len);
|
||||
add_len = vsnprintf(Data + idx, add_len + 1, fmt, args2);
|
||||
#else
|
||||
// First try
|
||||
int add_len = vsnprintf(Owned ? Data + idx : NULL, Owned ? (size_t)(Capacity + 1 - idx) : 0, fmt, args);
|
||||
STR_ASSERT(add_len >= 0);
|
||||
|
||||
if (Capacity < idx + add_len)
|
||||
{
|
||||
reserve(idx + add_len);
|
||||
add_len = vsnprintf(Data + idx, (size_t)add_len + 1, fmt, args2);
|
||||
}
|
||||
#endif
|
||||
|
||||
STR_ASSERT(Owned);
|
||||
return add_len;
|
||||
}
|
||||
|
||||
int Str::appendf_from(int idx, const char* fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
int len = appendfv_from(idx, fmt, args);
|
||||
va_end(args);
|
||||
return len;
|
||||
}
|
||||
|
||||
int Str::append(char c)
|
||||
{
|
||||
int cur_len = length();
|
||||
return append_from(cur_len, c);
|
||||
}
|
||||
|
||||
int Str::append(const char* s, const char* s_end)
|
||||
{
|
||||
int cur_len = length();
|
||||
return append_from(cur_len, s, s_end);
|
||||
}
|
||||
|
||||
int Str::appendfv(const char* fmt, va_list args)
|
||||
{
|
||||
int cur_len = length();
|
||||
return appendfv_from(cur_len, fmt, args);
|
||||
}
|
||||
|
||||
int Str::appendf(const char* fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
int len = appendfv(fmt, args);
|
||||
va_end(args);
|
||||
return len;
|
||||
}
|
||||
|
||||
#endif // #define STR_IMPLEMENTATION
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
@ -6,8 +6,8 @@ platforms=esp32,esp32s3
|
||||
[app]
|
||||
id=com.d49406.RadioSet
|
||||
version=0.0.1
|
||||
name=Radio Terminal
|
||||
description=Receive and transmit radio packages
|
||||
name=RadioSet
|
||||
description=Receive and transmit radio messages
|
||||
[author]
|
||||
name=Dominic Hoeglinger
|
||||
website=https://github.com/ByteWelder/Tactility
|
||||
website=https://git.hoeglinger.eu
|
||||
|
||||
@ -13,7 +13,7 @@ bool RadioDevice::setModulation(const RadioDevice::Modulation newModulation) {
|
||||
const auto state = getState();
|
||||
if ((state == State::PendingOn) || (state == State::On)) {
|
||||
return false;
|
||||
} else if (!((newModulation == Modulation::None) || canTransmit(newModulation) || canReceive(newModulation))) {
|
||||
} else if (!(canTransmit(newModulation) || canReceive(newModulation))) {
|
||||
return false;
|
||||
} else {
|
||||
auto lock = mutex.asScopedLock();
|
||||
|
||||
@ -17,7 +17,6 @@ enum RadioState {
|
||||
};
|
||||
|
||||
enum Modulation {
|
||||
MODULATION_NONE,
|
||||
MODULATION_LORA,
|
||||
MODULATION_FSK,
|
||||
MODULATION_LRFHSS
|
||||
|
||||
@ -4,7 +4,6 @@
|
||||
#include "Tactility/hal/Device.h"
|
||||
#include "Tactility/hal/radio/RadioDevice.h"
|
||||
|
||||
auto constexpr TAG = "tt_hal_radio";
|
||||
|
||||
static RadioState fromCpp(tt::hal::radio::RadioDevice::State state);
|
||||
static tt::hal::radio::RadioDevice::State toCpp(RadioState state);
|
||||
@ -163,7 +162,6 @@ static RadioState fromCpp(tt::hal::radio::RadioDevice::State state) {
|
||||
case tt::hal::radio::RadioDevice::State::Off:
|
||||
return RADIO_OFF;
|
||||
default:
|
||||
TT_LOG_W(TAG, "Unknown enum \"%d\" passed!", state);
|
||||
tt_crash("Radio state not supported");
|
||||
}
|
||||
}
|
||||
@ -181,15 +179,12 @@ static tt::hal::radio::RadioDevice::State toCpp(RadioState state) {
|
||||
case RADIO_OFF:
|
||||
return tt::hal::radio::RadioDevice::State::Off;
|
||||
default:
|
||||
TT_LOG_W(TAG, "Unknown enum \"%d\" passed!", state);
|
||||
tt_crash("Radio state not supported");
|
||||
}
|
||||
}
|
||||
|
||||
static Modulation fromCpp(tt::hal::radio::RadioDevice::Modulation modulation) {
|
||||
switch (modulation) {
|
||||
case tt::hal::radio::RadioDevice::Modulation::None:
|
||||
return MODULATION_NONE;
|
||||
case tt::hal::radio::RadioDevice::Modulation::LoRa:
|
||||
return MODULATION_LORA;
|
||||
case tt::hal::radio::RadioDevice::Modulation::Fsk:
|
||||
@ -197,15 +192,12 @@ static Modulation fromCpp(tt::hal::radio::RadioDevice::Modulation modulation) {
|
||||
case tt::hal::radio::RadioDevice::Modulation::LrFhss:
|
||||
return MODULATION_LRFHSS;
|
||||
default:
|
||||
TT_LOG_W(TAG, "Unknown enum \"%d\" passed!", modulation);
|
||||
tt_crash("Modulation not supported");
|
||||
}
|
||||
}
|
||||
|
||||
static tt::hal::radio::RadioDevice::Modulation toCpp(Modulation modulation) {
|
||||
switch (modulation) {
|
||||
case MODULATION_NONE:
|
||||
return tt::hal::radio::RadioDevice::Modulation::None;
|
||||
case MODULATION_LORA:
|
||||
return tt::hal::radio::RadioDevice::Modulation::LoRa;
|
||||
case MODULATION_FSK:
|
||||
@ -213,7 +205,6 @@ static tt::hal::radio::RadioDevice::Modulation toCpp(Modulation modulation) {
|
||||
case MODULATION_LRFHSS:
|
||||
return tt::hal::radio::RadioDevice::Modulation::LrFhss;
|
||||
default:
|
||||
TT_LOG_W(TAG, "Unknown enum \"%d\" passed!", modulation);
|
||||
tt_crash("Modulation not supported");
|
||||
}
|
||||
}
|
||||
@ -243,7 +234,6 @@ static RadioParameter fromCpp(tt::hal::radio::RadioDevice::Parameter parameter)
|
||||
case tt::hal::radio::RadioDevice::Parameter::NarrowGrid:
|
||||
return RADIO_NARROWGRID;
|
||||
default:
|
||||
TT_LOG_W(TAG, "Unknown enum \"%d\" passed!", parameter);
|
||||
tt_crash("Parameter not supported");
|
||||
}
|
||||
}
|
||||
@ -273,7 +263,6 @@ static tt::hal::radio::RadioDevice::Parameter toCpp(RadioParameter parameter) {
|
||||
case RADIO_NARROWGRID:
|
||||
return tt::hal::radio::RadioDevice::Parameter::NarrowGrid;
|
||||
default:
|
||||
TT_LOG_W(TAG, "Unknown enum \"%d\" passed!", parameter);
|
||||
tt_crash("Parameter not supported");
|
||||
}
|
||||
}
|
||||
@ -287,7 +276,6 @@ static RadioParameterStatus fromCpp(tt::hal::radio::RadioDevice::ParameterStatus
|
||||
case tt::hal::radio::RadioDevice::ParameterStatus::Success:
|
||||
return RADIO_PARAM_SUCCESS;
|
||||
default:
|
||||
TT_LOG_W(TAG, "Unknown enum \"%d\" passed!", status);
|
||||
tt_crash("Parameter status not supported");
|
||||
}
|
||||
}
|
||||
@ -301,7 +289,6 @@ static tt::hal::radio::RadioDevice::ParameterStatus toCpp(RadioParameterStatus s
|
||||
case RADIO_PARAM_SUCCESS:
|
||||
return tt::hal::radio::RadioDevice::ParameterStatus::Success;
|
||||
default:
|
||||
TT_LOG_W(TAG, "Unknown enum \"%d\" passed!", status);
|
||||
tt_crash("Parameter status not supported");
|
||||
}
|
||||
}
|
||||
@ -319,7 +306,6 @@ static RadioTxState fromCpp(tt::hal::radio::RadioDevice::TransmissionState state
|
||||
case tt::hal::radio::RadioDevice::TransmissionState::Error:
|
||||
return RADIO_TX_ERROR;
|
||||
default:
|
||||
TT_LOG_W(TAG, "Unknown enum \"%d\" passed!", state);
|
||||
tt_crash("Transmission state not supported");
|
||||
}
|
||||
}
|
||||
@ -337,7 +323,6 @@ static tt::hal::radio::RadioDevice::TransmissionState toCpp(RadioTxState state)
|
||||
case RADIO_TX_ERROR:
|
||||
return tt::hal::radio::RadioDevice::TransmissionState::Error;
|
||||
default:
|
||||
TT_LOG_W(TAG, "Unknown enum \"%d\" passed!", state);
|
||||
tt_crash("Transmission state not supported");
|
||||
}
|
||||
}
|
||||
|
||||
@ -385,14 +385,11 @@ const esp_elfsym elf_symbols[] {
|
||||
ESP_ELFSYM_EXPORT(lv_color_hex),
|
||||
ESP_ELFSYM_EXPORT(lv_color_make),
|
||||
ESP_ELFSYM_EXPORT(lv_obj_create),
|
||||
ESP_ELFSYM_EXPORT(lv_obj_clean),
|
||||
ESP_ELFSYM_EXPORT(lv_obj_delete),
|
||||
ESP_ELFSYM_EXPORT(lv_obj_add_event_cb),
|
||||
ESP_ELFSYM_EXPORT(lv_obj_align),
|
||||
ESP_ELFSYM_EXPORT(lv_obj_align_to),
|
||||
ESP_ELFSYM_EXPORT(lv_obj_get_parent),
|
||||
ESP_ELFSYM_EXPORT(lv_obj_get_child),
|
||||
ESP_ELFSYM_EXPORT(lv_obj_get_child_count),
|
||||
ESP_ELFSYM_EXPORT(lv_obj_get_height),
|
||||
ESP_ELFSYM_EXPORT(lv_obj_get_width),
|
||||
ESP_ELFSYM_EXPORT(lv_obj_get_coords),
|
||||
@ -417,7 +414,6 @@ const esp_elfsym elf_symbols[] {
|
||||
ESP_ELFSYM_EXPORT(lv_obj_set_style_bg_image_opa),
|
||||
ESP_ELFSYM_EXPORT(lv_obj_set_style_bg_image_recolor),
|
||||
ESP_ELFSYM_EXPORT(lv_obj_set_style_bg_image_recolor_opa),
|
||||
ESP_ELFSYM_EXPORT(lv_obj_set_style_flex_grow),
|
||||
ESP_ELFSYM_EXPORT(lv_obj_set_style_margin_hor),
|
||||
ESP_ELFSYM_EXPORT(lv_obj_set_style_margin_ver),
|
||||
ESP_ELFSYM_EXPORT(lv_obj_set_style_margin_top),
|
||||
@ -449,7 +445,6 @@ const esp_elfsym elf_symbols[] {
|
||||
ESP_ELFSYM_EXPORT(lv_obj_set_style_text_outline_stroke_opa),
|
||||
ESP_ELFSYM_EXPORT(lv_obj_set_style_text_outline_stroke_width),
|
||||
ESP_ELFSYM_EXPORT(lv_obj_set_align),
|
||||
ESP_ELFSYM_EXPORT(lv_obj_set_layout),
|
||||
ESP_ELFSYM_EXPORT(lv_obj_set_x),
|
||||
ESP_ELFSYM_EXPORT(lv_obj_set_y),
|
||||
ESP_ELFSYM_EXPORT(lv_obj_set_size),
|
||||
@ -509,7 +504,6 @@ const esp_elfsym elf_symbols[] {
|
||||
ESP_ELFSYM_EXPORT(lv_dropdown_get_option_count),
|
||||
ESP_ELFSYM_EXPORT(lv_dropdown_get_option_index),
|
||||
ESP_ELFSYM_EXPORT(lv_dropdown_get_options),
|
||||
ESP_ELFSYM_EXPORT(lv_dropdown_get_selected),
|
||||
ESP_ELFSYM_EXPORT(lv_dropdown_set_dir),
|
||||
ESP_ELFSYM_EXPORT(lv_dropdown_set_options),
|
||||
ESP_ELFSYM_EXPORT(lv_dropdown_set_options_static),
|
||||
@ -587,38 +581,6 @@ const esp_elfsym elf_symbols[] {
|
||||
ESP_ELFSYM_EXPORT(lv_obj_get_style_grid_cell_row_span),
|
||||
ESP_ELFSYM_EXPORT(lv_obj_get_style_grid_cell_x_align),
|
||||
ESP_ELFSYM_EXPORT(lv_obj_get_style_grid_cell_y_align),
|
||||
ESP_ELFSYM_EXPORT(lv_group_focus_obj),
|
||||
ESP_ELFSYM_EXPORT(lv_group_get_default),
|
||||
ESP_ELFSYM_EXPORT(lv_group_add_obj),
|
||||
// lv_style
|
||||
ESP_ELFSYM_EXPORT(lv_style_init),
|
||||
ESP_ELFSYM_EXPORT(lv_style_set_bg_color),
|
||||
ESP_ELFSYM_EXPORT(lv_style_set_bg_opa),
|
||||
ESP_ELFSYM_EXPORT(lv_style_set_border_width),
|
||||
ESP_ELFSYM_EXPORT(lv_style_set_border_color),
|
||||
ESP_ELFSYM_EXPORT(lv_color_black),
|
||||
ESP_ELFSYM_EXPORT(lv_obj_add_style),
|
||||
// lv_slider
|
||||
ESP_ELFSYM_EXPORT(lv_slider_create),
|
||||
ESP_ELFSYM_EXPORT(lv_slider_set_value),
|
||||
ESP_ELFSYM_EXPORT(lv_slider_set_start_value),
|
||||
ESP_ELFSYM_EXPORT(lv_slider_set_range),
|
||||
//ESP_ELFSYM_EXPORT(lv_slider_set_min_value),
|
||||
//ESP_ELFSYM_EXPORT(lv_slider_set_max_value),
|
||||
ESP_ELFSYM_EXPORT(lv_slider_set_mode),
|
||||
ESP_ELFSYM_EXPORT(lv_slider_set_orientation),
|
||||
ESP_ELFSYM_EXPORT(lv_slider_get_value),
|
||||
ESP_ELFSYM_EXPORT(lv_slider_get_left_value),
|
||||
ESP_ELFSYM_EXPORT(lv_slider_get_min_value),
|
||||
ESP_ELFSYM_EXPORT(lv_slider_get_max_value),
|
||||
ESP_ELFSYM_EXPORT(lv_slider_is_dragged),
|
||||
ESP_ELFSYM_EXPORT(lv_slider_get_mode),
|
||||
ESP_ELFSYM_EXPORT(lv_slider_get_orientation),
|
||||
ESP_ELFSYM_EXPORT(lv_slider_is_symmetrical),
|
||||
ESP_ELFSYM_EXPORT(lv_slider_bind_value),
|
||||
//lv_snprintf
|
||||
ESP_ELFSYM_EXPORT(lv_snprintf),
|
||||
|
||||
// delimiter
|
||||
ESP_ELFSYM_END
|
||||
};
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user