void GUI_DrawLabelHelper(u16 obj_x, u16 obj_y, u16 obj_w, u16 obj_h, const char *str, const struct LabelDesc *desc, u8 is_selected) { u16 txt_w, txt_h; u16 txt_x, txt_y; u16 offset = (LCD_DEPTH > 1 && desc->font==NARROW_FONT.font) ? 1 : 0; LCD_SetFont(desc->font); LCD_GetStringDimensions((const u8 *)str, &txt_w, &txt_h); txt_w++; if (obj_w == 0) obj_w = txt_w; if (obj_h == 0) obj_h = txt_h; if (offset && obj_y >= offset) { obj_y -= offset; } if (desc->style == LABEL_BOX) { // draw round rect for the textsel widget when it is pressable if (is_selected) { LCD_FillRoundRect(obj_x, obj_y, obj_w, obj_h , 3, 1); } else { GUI_DrawBackground(obj_x, obj_y, obj_w, obj_h); LCD_DrawRoundRect(obj_x, obj_y, obj_w, obj_h , 3, 1); } } else if (desc->style == LABEL_FILL) { LCD_FillRect(obj_x, obj_y, obj_w, obj_h, desc->fill_color); } else { GUI_DrawBackground(obj_x, obj_y, obj_w, obj_h); } if (desc->fill_color != desc->outline_color) { LCD_DrawRect(obj_x, obj_y, obj_w, obj_h, desc->outline_color); obj_x+=2; obj_w-=4; } if (desc->style == LABEL_RIGHT) { txt_x = obj_x + obj_w - txt_w; } else if (obj_w > txt_w && !(desc->style == LABEL_LEFT)) { txt_x = obj_x+1 + (obj_w - txt_w + 1) / 2; } else { txt_x = obj_x+1; } txt_y = obj_y + offset + (obj_h - txt_h + 1) / 2; if (desc->style != LABEL_FILL && is_selected) { LCD_SetFontColor(~desc->font_color); } else { LCD_SetFontColor(desc->font_color); } LCD_PrintStringXY(txt_x, txt_y, str); }
static int scroll_cb(guiObject_t *parent, u8 pos, s8 direction, void *data) { (void)data; (void)parent; int page = pos + (direction > 0 ? 1 : -1); if (page < 0) { return pos; } else if(page >= GUI_GetScrollbarNumItems(&gui->scrollbar)) { return pos; } int idx = 0; if (page) { for(int i = 0; i < NUM_SYMBOL_COLS * page; i++) { idx = get_next_icon(idx); if (idx < 0) { idx = 0; break; } } } GUI_RemoveHierObjects((guiObject_t *)&gui->symbolicon[0]); FullRedraw = REDRAW_ONLY_DIRTY; GUI_DrawBackground(0, 79, LCD_WIDTH - 16, LCD_HEIGHT - 79); show_icons((long)data, idx); return page; }
static void show_page(int page) { enum { COL1 = (30 + ((LCD_WIDTH - 320) / 2)), COL2 = (150 + ((LCD_WIDTH - 320) / 2)), LABEL_WIDTH = (COL2 - COL1), ROW1 = (40 + ((LCD_HEIGHT - 240) / 2)), ROW_HEIGHT = 24, }; struct mixer_page * mp = &pagemem.u.mixer_page; if (mp->firstObj) { GUI_RemoveHierObjects(mp->firstObj); FullRedraw = REDRAW_ONLY_DIRTY; mp->firstObj = NULL; GUI_DrawBackground(0, 32, LCD_WIDTH - 16, LCD_HEIGHT - 32); } for (long i = 0; i < ENTRIES_PER_PAGE; i++) { int row = ROW1 + ROW_HEIGHT * i; long ch = page + i; if (ch >= Model.num_channels) break; guiObject_t *obj = GUI_CreateLabelBox(&gui->name[i], COL1, row, LABEL_WIDTH, 16, &LABEL_FONT, STDMIX_channelname_cb, NULL, (void *)(ch)); if (! mp->firstObj) mp->firstObj = obj; GUI_CreateTextSelect(&gui->value[i], COL2, row, TEXTSELECT_128, toggle_reverse_cb, reverse_cb, (void *)(ch)); } }
void _GUI_RefreshScreen(struct guiObject *headObj) { struct guiObject *modalObj = GUI_IsModal(); struct guiObject *obj; if (FullRedraw) { #ifdef DEBUG_DRAW printf("Full Redraw requested: %d\n", FullRedraw); #endif if (modalObj && modalObj->Type == Dialog && FullRedraw != REDRAW_EVERYTHING) { //Handle Dialog redraw as an incremental FullRedraw = REDRAW_ONLY_DIRTY; } else { GUI_DrawScreen(); return; } } GUI_HideObjects(headObj, modalObj); //Only start drawing from headObj(scrollable) or 1st modal if either is set obj = headObj ? headObj : modalObj ? modalObj : objHEAD; while(obj) { if(! OBJ_IS_HIDDEN(obj)) { if (obj->Type == Scrollable && ((guiScrollable_t *)obj)->head) { //Redraw scrollable contents _GUI_RefreshScreen(((guiScrollable_t *)obj)->head); } else if(OBJ_IS_DIRTY(obj)) { if(OBJ_IS_TRANSPARENT(obj) || OBJ_IS_HIDDEN(obj)) { GUI_DrawBackground(obj->box.x, obj->box.y, obj->box.width, obj->box.height); } GUI_DrawObject(obj); } } obj = obj->next; } }
void _DrawTextSelectHelper(struct guiTextSelect *select, const char *str) { struct guiBox *box = &select->header.box; // plate text select for devo 10, copy most behavior from label.c GUI_DrawBackground(box->x, box->y, box->width, box->height); u8 arrow_width = ARROW_WIDTH - 1; if (select->enable & 0x01) { u16 y = box->y + box->height / 2; // Bug fix: since the logic view is introduce, a coordinate could be greater than 10000 u16 x1 = box->x + arrow_width -1; LCD_DrawLine(box->x, y, x1, y - 2, 0xffff); LCD_DrawLine(box->x, y, x1, y + 2, 0xffff); //"<" x1 = box->x + box->width - arrow_width; u16 x2 = box->x + box->width -1; LCD_DrawLine(x1, y - 2, x2, y, 0xffff); LCD_DrawLine(x1, y + 2, x2, y, 0xffff); //">" } else if (select->enable == 2) { // ENBALBE == 2 means the textsel can be pressed but not be selected select->desc.style = LABEL_BOX; } else { if (!select->enable) { // avoid drawing button box when it is disable select->desc.style = LABEL_NO_BOX; } } GUI_DrawLabelHelper(box->x + arrow_width, box->y, box->width - 2 * arrow_width, box->height, str, &select->desc, (guiObject_t *)select == objSELECTED); }
void GUI_HideObjects(struct guiObject *headObj, struct guiObject *modalObj) { struct guiObject *obj; //Only start drawing from headObj(scrollable) or 1st modal if either is set obj = headObj ? headObj : modalObj ? modalObj : objHEAD; while(obj) { if(OBJ_IS_HIDDEN(obj) && OBJ_IS_DIRTY(obj)) { GUI_DrawBackground(obj->box.x, obj->box.y, obj->box.width, obj->box.height); OBJ_SET_DIRTY(obj, 0); } obj = obj->next; } }
void _GUI_ChangeImage(struct guiImage *image, const char *file, u16 x_off, u16 y_off, u8 replace) { guiObject_t *obj = (guiObject_t *)image; //Use a CRC for comparison because the filename may change without the pointer changing u32 crc = Crc(file, strlen(file)); if (image->file != file || image->crc != crc || image->x_off != x_off || image->y_off != y_off) { if (replace) { // draw background where the old picture was bigger struct guiBox *box = &obj->box; u16 w, h; LCD_ImageDimensions(file, &w, &h); if (h < box->height) GUI_DrawBackground(box->x, box->y + h, box->width, box->height - h); // remove lower left part of old image if (w < box->width) GUI_DrawBackground(box->x + w, box->y, box->width - w, h < box->height ? h : box->height); // remove upper right part of old image box->width = w; box->height = h; } image->crc = crc; image->file = file; image->x_off = x_off; image->y_off = y_off; OBJ_SET_TRANSPARENT(obj, LCD_ImageIsTransparent(file)); OBJ_SET_DIRTY(obj, 1); } }
static unsigned _action_cb_calibrate(u32 button, unsigned flags, void *data) { (void)data; u8 i; if (flags & BUTTON_PRESS) return 1; if (flags & BUTTON_RELEASE) { if (CHAN_ButtonIsPressed(button, BUT_EXIT)) { // bug fix: when most users see the "Calibration done", it is very likely tha they will press ext to exit, // then all calibration data are rollback, and cause the calibration failed -- what a tough bug!! if (calibrate_state == CALI_SUCCESS) calibrate_state = CALI_SUCCESSEXIT; else calibrate_state = CALI_EXIT; } else if (CHAN_ButtonIsPressed(button, BUT_ENTER)) { switch (calibrate_state){ case CALI_CENTER: for (i = 0; i < INP_HAS_CALIBRATION; i++) { s32 value = CHAN_ReadRawInput(i + 1); Transmitter.calibration[i].max = 0x0000; Transmitter.calibration[i].min = 0xFFFF; Transmitter.calibration[i].zero = value; } snprintf(tempstring, sizeof(tempstring), "%s", _tr("Move sticks and knobs\nto max & min positions\nthen press ENT")); GUI_Redraw(&guic->msg); calibrate_state = CALI_MAXMIN; break; case CALI_MAXMIN: for (i = 0; i < INP_HAS_CALIBRATION; i++) { printf("Input %d: Max: %d Min: %d Zero: %d\n", i+1, Transmitter.calibration[i].max, Transmitter.calibration[i].min, Transmitter.calibration[i].zero); } GUI_DrawBackground(0, 0, LCD_WIDTH, LCD_HEIGHT); snprintf(tempstring, sizeof(tempstring), "%s", _tr("Calibration done.\n \nPress ENT.")); GUI_Redraw(&guic->msg); calibrate_state = CALI_SUCCESS; break; case CALI_SUCCESS: calibrate_state = CALI_SUCCESSEXIT; break; default: break; } }else { // only one callback can handle a button press, so we don't handle BUT_ENTER here, let it handled by press cb return 0; } } return 1; }
void GUI_DrawScreen(void) { #ifdef DEBUG_DRAW printf("DrawScreen\n"); #endif /* * First we need to draw the main background * */ GUI_DrawBackground(0, 0, LCD_WIDTH, LCD_HEIGHT); /* * Then we need to draw any supporting GUI */ FullRedraw = REDRAW_IF_NOT_MODAL; GUI_DrawObjects(); FullRedraw = REDRAW_ONLY_DIRTY; LCD_ForceUpdate(); }
void GUI_DrawLabelHelper(u16 obj_x, u16 obj_y, u16 obj_w, u16 obj_h, const char *str, const struct LabelDesc *desc, u8 is_selected) { u16 txt_w, txt_h; u16 txt_x, txt_y; // This is used to align text vertically u16 offset = (desc->font==NARROW_FONT.font) ? 1 : 0; LCD_SetFont(desc->font); LCD_GetStringDimensions((const u8 *)str, &txt_w, &txt_h); txt_w++; if (obj_w == 0) obj_w = txt_w; if (obj_h == 0) obj_h = txt_h; if (desc->style == LABEL_LISTBOX) { LCD_FillRect(obj_x, obj_y, obj_w, obj_h, is_selected ? Display.listbox.fg_color : Display.listbox.bg_color); } else if (desc->style == LABEL_FILL) { LCD_FillRect(obj_x, obj_y, obj_w, obj_h, desc->fill_color); } else { GUI_DrawBackground(obj_x, obj_y, obj_w, obj_h); } if (desc->style != LABEL_LISTBOX && desc->fill_color != desc->outline_color) { LCD_DrawRect(obj_x, obj_y, obj_w, obj_h, desc->outline_color); obj_x+=2; obj_w-=4; } if (desc->style == LABEL_RIGHT) { txt_x = obj_x + obj_w - txt_w; } else if (obj_w > txt_w && !(desc->style == LABEL_LEFT)) { txt_x = obj_x+1 + (obj_w - txt_w + 1) / 2; } else { txt_x = obj_x+1; } txt_y = obj_y + offset + (obj_h - txt_h + 1) / 2; if (desc->style == LABEL_LISTBOX) { LCD_SetFontColor(is_selected ? Display.listbox.fg_select : Display.listbox.bg_select); } else { if (desc->style != LABEL_FILL && is_selected) { LCD_SetFontColor(~desc->font_color); } else { LCD_SetFontColor(desc->font_color); } } LCD_PrintStringXY(txt_x, txt_y, str); }
void GUI_DrawImage(struct guiObject *obj) { #define SELECT_BORDER_OFFSET 1 struct guiImage *image = (struct guiImage *)obj; struct guiBox *box = &obj->box; // clear the whole widget, including its selected border for devo10/7e if (LCD_DEPTH == 1) GUI_DrawBackground(box->x -SELECT_BORDER_OFFSET, box->y -SELECT_BORDER_OFFSET, box->width + SELECT_BORDER_OFFSET + SELECT_BORDER_OFFSET, box->height + SELECT_BORDER_OFFSET + SELECT_BORDER_OFFSET); LCD_DrawWindowedImageFromFile(box->x, box->y, image->file, box->width, box->height, image->x_off, image->y_off); if (LCD_DEPTH == 1 && GUI_GetSelected() == obj) LCD_DrawRect(box->x -SELECT_BORDER_OFFSET, box->y -SELECT_BORDER_OFFSET, box->width + SELECT_BORDER_OFFSET + SELECT_BORDER_OFFSET, box->height + SELECT_BORDER_OFFSET + SELECT_BORDER_OFFSET, 1); }
static const char *rtc_text_cb(guiObject_t *obj, const void *data) { (void)obj; unsigned int idx = (long)data; if (idx <= (sizeof(Rtc.value) / sizeof(Rtc.value[0]))) { GUI_DrawBackground(X(idx/3, 32) + ((idx%3 == 2) ? 67 : 0) - ((idx%3 == 0) ? 67 : 0), 84, 64, 16); idx = order[idx]; } switch (idx) { case SECOND: return _tr("Second"); case MINUTE: return _tr("Minute"); case HOUR: return _tr("Hour"); case DAY: return _tr("Day"); case MONTH: return _tr("Month"); case YEAR: return _tr("Year"); case ACTTIME: { RTC_GetTimeFormatted(tempstring, RTC_GetValue()); return tempstring; } case ACTDATE: { RTC_GetDateFormatted(tempstring, RTC_GetValue()); return tempstring; } case NEWTIME: { RTC_GetTimeFormatted(tempstring, RTC_GetSerial(Rtc.value[YEAR], Rtc.value[MONTH], Rtc.value[DAY], Rtc.value[HOUR], Rtc.value[MINUTE], Rtc.value[SECOND])); return tempstring; } case NEWDATE: { RTC_GetDateFormatted(tempstring, RTC_GetSerial(Rtc.value[YEAR], Rtc.value[MONTH], Rtc.value[DAY], Rtc.value[HOUR], Rtc.value[MINUTE], Rtc.value[SECOND])); return tempstring; } case TIMEBUTTON: return _tr("Set time"); case DATEBUTTON: return _tr("Set date"); case TIMELABEL: return _tr("Time format"); case DATELABEL: return _tr("Date format"); case SETLABEL: return _tr("value to set"); case RESULTLABEL: return _tr("resulting value"); } return _tr("Unknown"); }
void GUI_DrawLabelHelper(u16 obj_x, u16 obj_y, u16 obj_w, u16 obj_h, const char *str, const struct LabelDesc *desc, u8 is_selected) { u16 txt_w, txt_h; u16 txt_x, txt_y; u16 offset = (LCD_DEPTH > 1 && desc->font==NARROW_FONT.font) ? 1 : 0; LCD_SetFont(desc->font); LCD_GetStringDimensions((const u8 *)str, &txt_w, &txt_h); txt_w++; if (obj_w == 0) obj_w = txt_w; if (obj_h == 0) obj_h = txt_h; if (offset && obj_y >= offset) { obj_y -= offset; } if (desc->style != LABEL_TRANSPARENT) { GUI_DrawBackground(obj_x, obj_y, obj_w, obj_h); } if (desc->style == LABEL_BOX || desc->style == LABEL_BRACKET || desc->style == LABEL_SQUAREBOX) { // draw round rect for the textsel widget when it is pressable if (is_selected) { if (desc->style == LABEL_SQUAREBOX ||obj_w < 5) LCD_FillRect(obj_x, obj_y, obj_w, obj_h , 1); else LCD_FillRoundRect(obj_x, obj_y, obj_w, obj_h , 3, 1); } else { if (desc->style == LABEL_SQUAREBOX) if (desc->fill_color == 0) LCD_DrawRect(obj_x, obj_y, obj_w, obj_h, 1); else LCD_FillRect(obj_x, obj_y, obj_w, obj_h, desc->fill_color); else if (desc->style == LABEL_BRACKET) { struct pos { int i1; int i2; int i3; int i4;}; struct { union { int p[4]; struct pos pos;} u;} x[2], y[2]; //int x[2][4]; //int y[2][4]; if (obj_h > 2 * obj_w) { x[0].u.pos = (struct pos){ 0, 2, obj_w -3, obj_w -1}; y[0].u.pos = (struct pos){ 2, 0, 0, 2}; x[1].u.pos = x[0].u.pos; y[1].u.pos = (struct pos){ obj_h -3, obj_h -1, obj_h -1, obj_h -3}; } else { x[0].u.pos = (struct pos){ 2, 0, 0, 2}; y[0].u.pos = (struct pos){ 0, 2, obj_h -3, obj_h -1}; x[1].u.pos = (struct pos){ obj_w -3, obj_w -1, obj_w -1, obj_w -3}; y[1].u.pos = y[0].u.pos; } for(int oc = 0; oc < 2; oc++) { for(int i = 0; i < 3; i++) { LCD_DrawLine(obj_x + x[oc].u.p[i], obj_y+y[oc].u.p[i], obj_x+x[oc].u.p[i+1], obj_y + y[oc].u.p[i+1], 1); } } } else LCD_DrawRoundRect(obj_x, obj_y, obj_w, obj_h , 3, 1); } } else if (desc->style == LABEL_FILL) { LCD_FillRect(obj_x, obj_y, obj_w, obj_h, desc->fill_color); } else if (desc->style == LABEL_INVERTED || is_selected) { LCD_FillRect(obj_x, obj_y, obj_w, obj_h, 0xffff); } if (desc->style == LABEL_TRANSPARENT || (LCD_DEPTH > 1 && desc->fill_color != desc->outline_color)) { LCD_DrawRect(obj_x, obj_y, obj_w, obj_h, desc->outline_color); obj_x+=2; obj_w-=4; } if (desc->style == LABEL_RIGHT) { txt_x = obj_x + obj_w - txt_w; } else if (obj_w > txt_w && !(desc->style == LABEL_LEFT || desc->style == LABEL_NO_BOX || desc->style == LABEL_UNDERLINE)) { txt_x = obj_x+1 + (obj_w - txt_w + 1) / 2; } else { txt_x = obj_x+1; } txt_y = obj_y + offset + (obj_h - txt_h + 1) / 2; if (desc->style == LABEL_UNDERLINE) { LCD_DrawFastHLine(--txt_x, txt_y + txt_h - 1, obj_w, 1); } if (desc->style == LABEL_BLINK) { blink_fontcolor = ~blink_fontcolor; LCD_SetFontColor(blink_fontcolor); } else if (desc->style == LABEL_INVERTED || (desc->style != LABEL_FILL && is_selected)) { LCD_SetFontColor(~desc->font_color); } else { LCD_SetFontColor(desc->font_color); } LCD_PrintStringXY(txt_x, txt_y, str); }