/*! * \brief * Creates a Combo box by reading the items table * * \param tuid Pointer to the active tuid_t structure * \param key User input * \param items The Combo Box table * \param id Pointer to combo box id (current and returned) * \param ln The language to use. * * * \return ui_return_t * \arg EXIT_RETURN : Indicates that function returns * \arg EXIT_STAY : Indicates that functions has not returned * * This function can create a Combo box based on the context of a table. * While the function returns EXIT_STAY it is still in progress. When the function * is done returns EXIT_RETURN. This assumes that the caller must handle with return * status in order to continues call or not the function. * * For example: * const combobox_item_t cb [] = * { * {{"ITEMS", "ANTIKEIMENA"}, 0}, // <-- Caption with whatever id * {{"item 1", "antik 1"}, 1}, // <-- item and item's id * {{"item 2", "antik 2"}, 2}, // " " * {{"item 3", "antik 3"}, 3}, // " " * {{0,0},0} // <-- Terminator strings must be NULL * }; * * Navigation * ========================== * UP -- Previous item on the list (table) * DOWN -- Next item on the list * RIGHT -- Selected and return the item. * LEFT -- Exit with the previous selected item * ESC -- " " " */ __Os__ ui_return_t tui_comboboxd (tuid_t *tuid, int live, int key, combobox_item_t *items, int *id, Lang_en ln) { static uint8_t ev=1; static int cur; static int vi, vfrm, i, frm; if (ev) { // It is the first call of combobox // Find cur in combobox table for (i=1 ; 1 ; ++i) { if (!items[i].text[ln]) { i=1; break; } if (items[i].id == *id) break; } // Print caption _mk_caption (tuid, items, ln); // Update counters cur = vi = vfrm = frm = i; ev = 0; } if (live) *id = items[i].id; // UI loop - Navigating if (key == tuid->keys.UP) { _cmb_prev_item (items, &i); --vi; } if (key == tuid->keys.DOWN) { _cmb_next_item (items, &i); ++vi; } if (key == tuid->keys.ESC || key == tuid->keys.LEFT) { // Restore previous value *id = items[cur].id; ev = 1; return EXIT_RETURN; } if (key == tuid->keys.RIGHT || key == tuid->keys.ENTER) { // Apply the new value *id = items[i].id; ev = 1; return EXIT_RETURN; } // Roll frame if (vi < vfrm) { vfrm = vi; frm = i; } else if (vi - vfrm>= tuid->frame_buffer.l - 1) { ++vfrm; _cmb_next_item (items, &frm); } // Printing frame _mk_frame (tuid, items, frm, i, ln); return EXIT_STAY; }
/*! * \brief * Paints the combobox frame lines in the frame buffer * \param fb Pointer to the frame buffer * \param items Pointer to the active combo-box * \param frame The frame buffer's start position * \param item The frame buffer's active line * \param ln The language to use * \return none */ __Os__ void _cmb_frame_lines (fb_t *fb, combobox_item_t *items, int frame, int item, Lang_en ln) { #define _LINE(_l) (fb->c*(_l)) int line, offset; int start; char post; // Print each line start = frame; for (line=1 ; line < fb->l ; ++line) { offset=0; if (frame == item) { offset = sprintf ((char*)&fb->fb[_LINE(line)], "[%s", (char*)items[frame].text[ln]); post = ']'; } else { offset = sprintf ((char*)&fb->fb[_LINE(line)], "%s", (char*)items[frame].text[ln]); post = ' '; } // discard null termination inside frame buffer fb->fb[_LINE(line)+offset] = post; // Escape if no items left _cmb_next_item (items, &frame); if (frame == start) break; } #undef _LINE }