#include "RadioSet.h" #include #include #include #include #include #include #include "tt_app_alertdialog.h" constexpr const char* TAG = "RadioSet"; void crash(const char* const message) { tt_app_alertdialog_start("RadioSet has crashed!", message, nullptr, 0); } class TermView { }; class SettingsView { private: static constexpr size_t MAX_RADIOS = 32; std::vector radios; lv_obj_t *deviceForm = nullptr; lv_obj_t *radioDropdown = nullptr; lv_obj_t *radioSwitch = nullptr; lv_obj_t *propertiesForm = nullptr; public: void queryRadios() { std::vector 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 { 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)); } } } } bool getRadioNames(std::vector &names) { int count = 1; names.clear(); for (auto radio : radios) { std::string name(tt_hal_radio_get_name(radio)); if (name == "") { std::ostringstream oss("Unknown Radio "); oss << count; name = oss.str(); } names.push_back(name); count++; } return !names.empty(); } 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; } 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_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(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_grid_dsc_array(container, lora_col_dsc, lora_row_dsc); std::ostringstream item_oss(""); std::vector 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); return container; } void initUi(lv_obj_t *parent) { 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(container, (lv_obj_flag_t)(LV_OBJ_FLAG_CLICKABLE | LV_OBJ_FLAG_SCROLL_ON_FOCUS)); deviceForm = initDeviceForm(container); } explicit SettingsView(lv_obj_t *parent) { queryRadios(); initUi(parent); } }; void RadioSet::onShow(AppHandle appHandle, lv_obj_t* parent) { lv_obj_remove_flag(parent, LV_OBJ_FLAG_SCROLLABLE); lv_obj_set_flex_flow(parent, LV_FLEX_FLOW_COLUMN); lv_obj_set_style_pad_row(parent, 0, LV_STATE_DEFAULT); lv_obj_t* toolbar = tt_lvgl_toolbar_create_for_app(parent, appHandle); lv_obj_align(toolbar, LV_ALIGN_TOP_MID, 0, 0); uiDropDownMenu = lv_dropdown_create(toolbar); lv_dropdown_set_options(uiDropDownMenu, LV_SYMBOL_ENVELOPE " Terminal\n" LV_SYMBOL_SETTINGS " Settings"); lv_dropdown_set_text(uiDropDownMenu, "Menu"); lv_dropdown_set_symbol(uiDropDownMenu, LV_SYMBOL_DOWN); lv_dropdown_set_selected_highlight(uiDropDownMenu, true); 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_t* wrapper = lv_obj_create(parent); lv_obj_set_flex_flow(wrapper, LV_FLEX_FLOW_COLUMN); lv_obj_set_flex_align(wrapper, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_START); lv_obj_set_flex_grow(wrapper, 1); lv_obj_set_width(wrapper, LV_PCT(100)); lv_obj_set_height(wrapper, LV_PCT(100)); lv_obj_set_style_pad_all(wrapper, 0, LV_PART_MAIN); lv_obj_set_style_pad_row(wrapper, 0, LV_PART_MAIN); lv_obj_set_style_border_width(wrapper, 0, 0); lv_obj_remove_flag(wrapper, LV_OBJ_FLAG_SCROLLABLE); settingsView = std::make_shared(wrapper); } // ???? extern "C" void __cxa_pure_virtual() { crash("Entered the Virtual Zone..."); }