Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
114 changes: 82 additions & 32 deletions src/ui/page_input.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,18 +31,44 @@ typedef enum page_input_rows {
ROW_COUNT
} rowType_t;

typedef struct Action {
uint16_t id;
const char *name;
union {
void (* const btnFunction);
void (* const rollerFunction)(uint8_t);
} functionPtr;
} action_t;

/**
* Compile-unit local variables, constants and fields
*/
static lv_coord_t col_dsc[] = {160, 200, 160, 160, 160, 120, LV_GRID_TEMPLATE_LAST};
static lv_coord_t row_dsc[] = {60, 60, 60, 60, 60, 60, 60, 60, 80, LV_GRID_TEMPLATE_LAST};

const char *btnOptions[] = {"Toggle OSD", "Main menu", "Toggle DVR", "Center HT", "Calibrate HT", "Go Sleep!", "Toggle fan speed", "Star DVR", "Toggle source", "Cycle source"};
void (* const btnFunctionPointers[])() = {&osd_toggle, &app_switch_to_menu, &dvr_toggle, &ht_set_center_position, &ht_calibrate, &go_sleep, &step_topfan, &dvr_star, &source_toggle, &source_cycle};
static void nop() {}
static void rollerNop(uint8_t key) { (void) key; }

static const action_t btnActions[] = {
{.id = 10, .name = "None", .functionPtr = &nop},
{.id = 0, .name = "Toggle OSD", .functionPtr = &osd_toggle},
{.id = 1, .name = "Main menu", .functionPtr = &app_switch_to_menu},
{.id = 2, .name = "Toggle DVR", .functionPtr = &dvr_toggle},
{.id = 3, .name = "Center HT", .functionPtr = &ht_set_center_position},
{.id = 4, .name = "Calibrate HT", .functionPtr = &ht_calibrate},
{.id = 5, .name = "Go Sleep!", .functionPtr = &go_sleep},
{.id = 6, .name = "Toggle fan speed", .functionPtr = &step_topfan},
{.id = 7, .name = "Star DVR", .functionPtr = &dvr_star},
{.id = 8, .name = "Toggle source", .functionPtr = &source_toggle},
{.id = 9, .name = "Cycle source", .functionPtr = &source_cycle},
};

const char *rollerOptions[] = {"Switch channel", "Change fan speed", "OLED Brightness"};
void (* const rollerFunctionPointers[])(uint8_t) = {&tune_channel, &change_topfan, &change_oled_brightness};
const uint16_t rollerDefaultOption = 0;
static const action_t rollerActions[] = {
{.id = 3, .name = "None", .functionPtr = &rollerNop},
{.id = 0, .name = "Switch channel", .functionPtr = &tune_channel},
{.id = 1, .name = "Change fan speed", .functionPtr = &change_topfan},
{.id = 2, .name = "OLED Brightness", .functionPtr = &change_oled_brightness}
};

static rowType_t selectedRow = ROW_COUNT;
static lv_obj_t *pageItems[ROW_COUNT];
Expand All @@ -52,16 +78,40 @@ static uint16_t previousSelection;
/**
* Build a '\n'-separated list of all available options for the dropdown element
*/
static void build_options_string(const char** input, size_t arraySize, char* output) {
output[0] = 0;
for (size_t i = 0; i < arraySize; i++) {
strcat(output, input[i]);
if (i < arraySize - 1) {
static void build_options_string(const action_t * const actions, size_t size, char* output) {
for (size_t i = 0; i < size; i++) {
strcat(output, actions[i].name);
if (i < size - 1) {
strcat(output, "\n");
}
}
}

/**
* Get the action_t item from btnActions by the given id
* @return The action_t item or NULL if id was not found
*/
static const action_t* actionFromId(const action_t * const actions, size_t size, uint16_t id) {
for (size_t i = 0; i < size; i++) {
if (actions[i].id == id) {
return &actions[i];
}
}

return NULL;
}
static const action_t* btnActionFromId(uint16_t id) { return actionFromId(btnActions, ARRAY_SIZE(btnActions), id); }
static const action_t* rollerActionFromId(uint16_t id) { return actionFromId(rollerActions, ARRAY_SIZE(rollerActions), id); }

/**
* Get the array index of the action that has the given id.
*/
static size_t indexFromId(const action_t * const actions, size_t size, uint16_t id) {
return actionFromId(actions, size, id) - actions;
}
static size_t btnIndexFromId(uint16_t id) { return indexFromId(btnActions, ARRAY_SIZE(btnActions), (id)); }
static size_t rollerIndexFromId(uint16_t id) { return indexFromId(rollerActions, ARRAY_SIZE(rollerActions), (id)); }

/**
* Update the UI elements as the user navigates the page
*/
Expand All @@ -75,12 +125,12 @@ static void reset_dropdown_styles() {
* Pick the associated function pointers for the globally configured actions
*/
static void update_inputs() {
roller_callback = rollerFunctionPointers[g_setting.inputs.roller];
btn_click_callback = btnFunctionPointers[g_setting.inputs.left_click];
btn_press_callback = btnFunctionPointers[g_setting.inputs.left_press];
rbtn_click_callback = btnFunctionPointers[g_setting.inputs.right_click];
rbtn_press_callback = btnFunctionPointers[g_setting.inputs.right_press];
rbtn_double_click_callback = btnFunctionPointers[g_setting.inputs.right_double_click];
roller_callback = rollerActionFromId(g_setting.inputs.roller)->functionPtr.rollerFunction;
btn_click_callback = btnActionFromId(g_setting.inputs.left_click)->functionPtr.btnFunction;
btn_press_callback = btnActionFromId(g_setting.inputs.left_press)->functionPtr.btnFunction;
rbtn_click_callback = btnActionFromId(g_setting.inputs.right_click)->functionPtr.btnFunction;
rbtn_press_callback = btnActionFromId(g_setting.inputs.right_press)->functionPtr.btnFunction;
rbtn_double_click_callback = btnActionFromId(g_setting.inputs.right_double_click)->functionPtr.btnFunction;
}

/**
Expand All @@ -91,28 +141,28 @@ static void accept_dropdown(lv_obj_t *obj) {
const uint16_t selectedOption = lv_dropdown_get_selected(obj);

if (selectedRow == ROLLER) {
g_setting.inputs.roller = selectedOption;
g_setting.inputs.roller = rollerActions[selectedOption].id;
ini_putl("inputs", "roller", g_setting.inputs.roller, SETTING_INI);
} else {
switch (selectedRow) {
case LEFT_SHORT:
g_setting.inputs.left_click = selectedOption;
g_setting.inputs.left_click = btnActions[selectedOption].id;
ini_putl("inputs", "left_click", g_setting.inputs.left_click, SETTING_INI);
break;
case LEFT_LONG:
g_setting.inputs.left_press = selectedOption;
g_setting.inputs.left_press = btnActions[selectedOption].id;
ini_putl("inputs", "left_press", g_setting.inputs.left_press, SETTING_INI);
break;
case RIGHT_SHORT:
g_setting.inputs.right_click = selectedOption;
g_setting.inputs.right_click = btnActions[selectedOption].id;
ini_putl("inputs", "right_click", g_setting.inputs.right_click, SETTING_INI);
break;
case RIGHT_LONG:
g_setting.inputs.right_press = selectedOption;
g_setting.inputs.right_press = btnActions[selectedOption].id;
ini_putl("inputs", "right_press", g_setting.inputs.right_press, SETTING_INI);
break;
case RIGHT_DOUBLE:
g_setting.inputs.right_double_click = selectedOption;
g_setting.inputs.right_double_click = btnActions[selectedOption].id;
ini_putl("inputs", "right_double_click", g_setting.inputs.right_double_click, SETTING_INI);
break;
default:
Expand Down Expand Up @@ -155,10 +205,10 @@ static lv_obj_t *page_input_create(lv_obj_t *parent, panel_arr_t *arr) {
contentWidth += col_dsc[i];
}

char rollerOptionsStr[128];
build_options_string(rollerOptions, ARRAY_SIZE(rollerOptions), rollerOptionsStr);
char btnOptionsStr[128];
build_options_string(btnOptions, ARRAY_SIZE(btnOptions), btnOptionsStr);
char rollerOptionsStr[128] = "";
build_options_string(rollerActions, ARRAY_SIZE(rollerActions), rollerOptionsStr);
char btnOptionsStr[128] = "";
build_options_string(btnActions, ARRAY_SIZE(btnActions), btnOptionsStr);

lv_obj_t *page = lv_menu_page_create(parent, NULL);
lv_obj_clear_flag(page, LV_OBJ_FLAG_SCROLLABLE);
Expand Down Expand Up @@ -186,27 +236,27 @@ static lv_obj_t *page_input_create(lv_obj_t *parent, panel_arr_t *arr) {

create_label_item(content, "Roller:", 1, ROLLER, 1);
pageItems[ROLLER] = create_dropdown_item(content, rollerOptionsStr, 2, ROLLER, 320, row_dsc[ROLLER], 2, 10, LV_GRID_ALIGN_START, &lv_font_montserrat_26);
lv_dropdown_set_selected(pageItems[ROLLER], g_setting.inputs.roller);
lv_dropdown_set_selected(pageItems[ROLLER], rollerIndexFromId(g_setting.inputs.roller));

create_label_item(content, "Left short:", 1, LEFT_SHORT, 1);
pageItems[LEFT_SHORT] = create_dropdown_item(content, btnOptionsStr, 2, LEFT_SHORT, 320, row_dsc[LEFT_SHORT], 2, 10, LV_GRID_ALIGN_START, &lv_font_montserrat_26);
lv_dropdown_set_selected(pageItems[LEFT_SHORT], g_setting.inputs.left_click);
lv_dropdown_set_selected(pageItems[LEFT_SHORT], btnIndexFromId(g_setting.inputs.left_click));

create_label_item(content, "Left long:", 1, LEFT_LONG, 1);
pageItems[LEFT_LONG] = create_dropdown_item(content, btnOptionsStr, 2, LEFT_LONG, 320, row_dsc[LEFT_LONG], 2, 10, LV_GRID_ALIGN_START, &lv_font_montserrat_26);
lv_dropdown_set_selected(pageItems[LEFT_LONG], g_setting.inputs.left_press);
lv_dropdown_set_selected(pageItems[LEFT_LONG], btnIndexFromId(g_setting.inputs.left_press));

create_label_item(content, "Right short:", 1, RIGHT_SHORT, 1);
pageItems[RIGHT_SHORT] = create_dropdown_item(content, btnOptionsStr, 2, RIGHT_SHORT, 320, row_dsc[RIGHT_SHORT], 2, 10, LV_GRID_ALIGN_START, &lv_font_montserrat_26);
lv_dropdown_set_selected(pageItems[RIGHT_SHORT], g_setting.inputs.right_click);
lv_dropdown_set_selected(pageItems[RIGHT_SHORT], btnIndexFromId(g_setting.inputs.right_click));

create_label_item(content, "Right long:", 1, RIGHT_LONG, 1);
pageItems[RIGHT_LONG] = create_dropdown_item(content, btnOptionsStr, 2, RIGHT_LONG, 320, row_dsc[RIGHT_LONG], 2, 10, LV_GRID_ALIGN_START, &lv_font_montserrat_26);
lv_dropdown_set_selected(pageItems[RIGHT_LONG], g_setting.inputs.right_press);
lv_dropdown_set_selected(pageItems[RIGHT_LONG], btnIndexFromId(g_setting.inputs.right_press));

create_label_item(content, "Right double:", 1, RIGHT_DOUBLE, 1);
pageItems[RIGHT_DOUBLE] = create_dropdown_item(content, btnOptionsStr, 2, RIGHT_DOUBLE, 320, row_dsc[RIGHT_DOUBLE], 2, 10, LV_GRID_ALIGN_START, &lv_font_montserrat_26);
lv_dropdown_set_selected(pageItems[RIGHT_DOUBLE], g_setting.inputs.right_double_click);
lv_dropdown_set_selected(pageItems[RIGHT_DOUBLE], btnIndexFromId(g_setting.inputs.right_double_click));

pageItems[BACK_BTN] = create_label_item(content, "< Back", 1, BACK_BTN, 1);

Expand Down