static void drawname(ITEM *i, int y, char_t *name, char_t *msg, STRING_IDX name_length, STRING_IDX msg_length, _Bool color_overide, uint32_t color) { if (!color_overide) { color = (selected_item == i) ? COLOR_MAIN_TEXT : COLOR_LIST_TEXT; } setcolor(color); setfont(FONT_LIST_NAME); drawtextwidth(ROSTER_NAME_LEFT, SIDEBAR_WIDTH - ROSTER_NAME_LEFT - UTOX_SCALE(16), y + ROSTER_NAME_TOP, name, name_length); if (!color_overide) { color = (selected_item == i) ? COLOR_MAIN_SUBTEXT : COLOR_LIST_SUBTEXT; } setcolor(color); setfont(FONT_STATUS); drawtextwidth(ROSTER_NAME_LEFT, SIDEBAR_WIDTH - ROSTER_NAME_LEFT - UTOX_SCALE(16), y + ROSTER_STATUS_MSG_TOP, msg, msg_length); }
static void drawname(ITEM *i, int y, char_t *name, char_t *msg, STRING_IDX name_length, STRING_IDX msg_length, _Bool color_overide, uint32_t color) { if (!color_overide) { color = (selected_item == i) ? COLOR_MAIN_TEXT : COLOR_LIST_TEXT; } setcolor(color); setfont(FONT_LIST_NAME); drawtextwidth(LIST_NAME_X, LIST_RIGHT - LIST_NAME_X - SCALE * 16, y + LIST_NAME_Y, name, name_length); if (!color_overide) { color = (selected_item == i) ? COLOR_MAIN_SUBTEXT : COLOR_LIST_SUBTEXT; } setcolor(color); setfont(FONT_STATUS); drawtextwidth(LIST_STATUS_X, LIST_RIGHT - LIST_STATUS_X - SCALE * 16, y + LIST_STATUS_Y, msg, msg_length); }
void dropdown_draw(DROPDOWN *b, int x, int y, int width, int height) { if(!b->open) { framerect(x, y, x + width, y + height, (b->mouseover ? C_GRAY2 : C_GRAY)); drawrect(x + 1, y + 1, x + width - 1, y + height - 1, WHITE); if(b->dropcount) { setfont(FONT_TEXT); setcolor(COLOR_TEXT); STRING* e = b->ondisplay(b->selected, b); drawtextwidth(x + 2 * SCALE, width - 4 * SCALE, y + 2 * SCALE, e->str, e->length); } } else { active_x = x; active_y = y; active_width = width; active_height = height; } }
// Draw collapsed dropdown void dropdown_draw(DROPDOWN *b, int x, int y, int width, int height) { if(!b->open) { // load colors for this style uint32_t color_bg, color_border, color_border_h, color_text; switch(b->style) { case AUXILIARY_STYLE: color_bg = COLOR_BACKGROUND_AUX; color_border = COLOR_AUX_EDGE_NORMAL; color_border_h = COLOR_AUX_EDGE_HOVER; color_text = COLOR_AUX_TEXT; break; default: color_bg = COLOR_BACKGROUND_MAIN; color_border = COLOR_EDGE_NORMAL; color_border_h = COLOR_EDGE_HOVER; color_text = COLOR_MAIN_TEXT; break; } draw_rect_frame(x, y, width, height, (b->mouseover ? color_border_h : color_border)); draw_rect_fill(x + 1, y + 1, width - 1 * SCALE, height - 1 * SCALE, color_bg); if(b->dropcount) { setfont(FONT_TEXT); setcolor(color_text); STRING* e = b->ondisplay(b->selected, b); drawtextwidth(x + 2 * SCALE, width - 4 * SCALE, y + 2 * SCALE, e->str, e->length); } } else { active_x = x; active_y = y; active_width = width; active_height = height; } }
/** Formats all messages from self and friends, and then call draw functions * to write them to the UI. * * accepts: messages struct *pointer, int x,y positions, int width,height */ void messages_draw(MESSAGES *m, int x, int y, int width, int height) { // Do not draw author name next to every message uint8_t lastauthor = 0xFF; // Message iterator void **p = m->data->data; MSG_IDX i, n = m->data->n; // Go through messages for(i = 0; i != n; i++) { MESSAGE *msg = *p++; // Empty message if(msg->height == 0) { return; } //! NOTE: should not be constant 0 if(y + msg->height <= 0) { y += msg->height; continue; } //! NOTE: should not be constant 100 if(y >= height + 50 * SCALE) { break; } // Draw timestamps { char timestr[6]; STRING_IDX len; len = snprintf(timestr, sizeof(timestr), "%u:%.2u", msg->time / 60, msg->time % 60); if (len >= sizeof(timestr)) { len = sizeof(timestr) - 1; } setcolor(COLOR_MAIN_SUBTEXT); setfont(FONT_MISC); drawtext(x + width - TIME_WIDTH, y, (char_t*)timestr, len); } // Draw the names for groups or friends if(m->type) { // Group message authors are all the same colour setcolor(COLOR_MAIN_CHATTEXT); setfont(FONT_TEXT); drawtextwidth_right(x, MESSAGES_X - NAME_OFFSET, y, &msg->msg[msg->length] + 1, msg->msg[msg->length]); } else { FRIEND *f = &friend[m->data->id]; // Always draw name next to action message if(msg->msg_type == MSG_TYPE_ACTION_TEXT) lastauthor = 0xFF; if(msg->author != lastauthor) { // Draw author name // If author is current user setfont(FONT_TEXT); if(msg->msg_type == MSG_TYPE_ACTION_TEXT) setcolor(COLOR_MAIN_ACTIONTEXT); else if(msg->author) setcolor(COLOR_MAIN_SUBTEXT); else setcolor(COLOR_MAIN_CHATTEXT); if(msg->author) drawtextwidth_right(x, MESSAGES_X - NAME_OFFSET, y, self.name, self.name_length); else drawtextwidth_right(x, MESSAGES_X - NAME_OFFSET, y, f->name, f->name_length); lastauthor = msg->author; } } // Draw message contents switch(msg->msg_type) { case MSG_TYPE_TEXT: case MSG_TYPE_ACTION_TEXT: { // Normal message STRING_IDX h1 = STRING_IDX_MAX, h2 = STRING_IDX_MAX; if(i == m->data->istart) { h1 = m->data->start; h2 = ((i == m->data->iend) ? m->data->end : msg->length); } else if(i == m->data->iend) { h1 = 0; h2 = m->data->end; } else if(i > m->data->istart && i < m->data->iend) { h1 = 0; h2 = msg->length; } if((m->data->istart == m->data->iend && m->data->start == m->data->end) || h1 == h2) { h1 = STRING_IDX_MAX; h2 = STRING_IDX_MAX; } if(msg->author) { setcolor(COLOR_MAIN_SUBTEXT); } else { setcolor(COLOR_MAIN_CHATTEXT); } if (msg->msg_type == MSG_TYPE_ACTION_TEXT) { setcolor(COLOR_MAIN_ACTIONTEXT); } setfont(FONT_TEXT); int ny = drawtextmultiline(x + MESSAGES_X, x + width - TIME_WIDTH, y, y, y + msg->height, font_small_lineheight, msg->msg, msg->length, h1, h2 - h1, 1); if(ny < y || (uint32_t)(ny - y) + MESSAGES_SPACING != msg->height) { debug("error101 %u %u\n", ny -y, msg->height - MESSAGES_SPACING); } y = ny; break; } // Draw image case MSG_TYPE_IMAGE: { MSG_IMG *img = (void*)msg; int maxwidth = width - MESSAGES_X - TIME_WIDTH; draw_message_image(img->image, x + MESSAGES_X, y, img->w, img->h, maxwidth, img->zoom, img->position); y += (img->zoom || img->w <= maxwidth) ? img->h : img->h * maxwidth / img->w; break; } // Draw file transfer case MSG_TYPE_FILE: { MSG_FILE *file = (void*)msg; int dx = MESSAGES_X; /* Mouse Positions */ _Bool mo = (m->iover == i); _Bool mouse_over = (mo && m->over) ? 1 : 0; _Bool mouse_tbtn = (mo && m->over == 1) ? 1 : 0; _Bool mouse_bbtn = (mo && m->over == 2) ? 1 : 0; /* Old var kept for bug hunting int xx = x + dx; int xxx = xx + BM_FTM_WIDTH + SCALE; */ /* File transfer bar */ int ftbar_x = x + dx; int ftbar_y = y; int ftbar_w = BM_FT_WIDTH; int ftbar_sw = BM_FTM_WIDTH; int ftbar_h = BM_FT_HEIGHT; /* Button Background */ int btn_bg_x = ftbar_x + BM_FTM_WIDTH + SCALE; int btn_bg_w = BM_FTB_WIDTH; /* Button Background heights */ int tbtn_bg_y = y; int bbtn_bg_y = y + BM_FTB_HEIGHT + SCALE * 2; int tbtn_bg_h = BM_FTB_HEIGHT + SCALE; int bbtn_bg_h = BM_FTB_HEIGHT; /* Top button info */ int btnx = ((x + dx) + BM_FTM_WIDTH + SCALE) + (BM_FTB_WIDTH - BM_FB_WIDTH) / 2; int tbtn_y = y + SCALE * 4; int bbtn_y = y + BM_FTB_HEIGHT + SCALE * 5; int btnw = BM_FB_WIDTH; int btnh = BM_FB_HEIGHT; char_t size[16]; STRING_IDX sizelen = sprint_bytes(size, sizeof(size), file->size); uint64_t progress = file->progress; if(progress > file->size) { progress = file->size; } char_t size_text[16]; STRING_IDX size_text_len = sprint_bytes(size_text, sizeof(size_text), file->speed); size_text[size_text_len++] = '/'; size_text[size_text_len++] = 's'; uint64_t etasec = 0; if(file->speed) { etasec = (file->size - progress) / file->speed; } char_t text2[16]; STRING_IDX len2 = snprintf((char*)text2, sizeof(text2), "%us", (uint32_t)etasec); if (len2 >= sizeof(text2)) { len2 = sizeof(text2) - 1; } // progress rectangle uint32_t w = (file->size == 0) ? 0 : (progress * (uint64_t)106 * SCALE) / file->size; setfont(FONT_MISC); setcolor(COLOR_MAIN_BACKGROUND); switch (file->status){ case FILE_TRANSFER_STATUS_COMPLETED: { /* If mouse over use hover color */ setcolor((mouse_over) ? COLOR_BUTTON_SUCCESS_HOVER_TEXT : COLOR_BUTTON_SUCCESS_TEXT); drawalpha(BM_FT, ftbar_x, ftbar_y, ftbar_w, ftbar_h, (mouse_over) ? COLOR_BUTTON_SUCCESS_HOVER_BACKGROUND : COLOR_BUTTON_SUCCESS_BACKGROUND); drawalpha(BM_YES, btnx, tbtn_y, btnw, btnh, (mouse_over) ? COLOR_BUTTON_SUCCESS_HOVER_TEXT : COLOR_BUTTON_SUCCESS_TEXT); if(file->inline_png){ drawstr(x + dx + 5 * SCALE, y + 17 * SCALE, CLICKTOSAVE); } else { drawstr(x + dx + 5 * SCALE, y + 17 * SCALE, CLICKTOOPEN); } break; } case FILE_TRANSFER_STATUS_KILLED:{ setcolor(COLOR_BUTTON_DANGER_TEXT); drawalpha(BM_FT, ftbar_x, ftbar_y, ftbar_w, ftbar_h, COLOR_BUTTON_DANGER_BACKGROUND); drawalpha(BM_NO, btnx, tbtn_y, btnw, btnh, COLOR_BUTTON_DANGER_TEXT); drawstr(x + dx + 5 * SCALE, y + 17 * SCALE, TRANSFER_CANCELLED); break; } case FILE_TRANSFER_STATUS_BROKEN: { setcolor(COLOR_BUTTON_DANGER_TEXT); drawalpha(BM_FT, ftbar_x, ftbar_y, ftbar_w, ftbar_h, COLOR_BUTTON_DANGER_BACKGROUND); drawalpha(BM_NO, btnx, tbtn_y, btnw, btnh, COLOR_BUTTON_DANGER_TEXT); drawstr(x + dx + 5 * SCALE, y + 17 * SCALE, TRANSFER_BROKEN); break; } case FILE_TRANSFER_STATUS_NONE: { /* ↑ used for incoming transfers */ setcolor(COLOR_BUTTON_DISABLED_TRANSFER); drawalpha(BM_FTM, ftbar_x, ftbar_y, ftbar_sw, ftbar_h, COLOR_BUTTON_DISABLED_BACKGROUND); drawalpha(BM_FTB1, btn_bg_x, tbtn_bg_y, btn_bg_w, tbtn_bg_h, (mouse_tbtn ? COLOR_BUTTON_SUCCESS_HOVER_BACKGROUND : COLOR_BUTTON_SUCCESS_BACKGROUND)); drawalpha(BM_NO, btnx, tbtn_y, btnw, btnh, (mouse_tbtn ? COLOR_BUTTON_SUCCESS_HOVER_TEXT : COLOR_BUTTON_SUCCESS_TEXT)); drawalpha(BM_FTB2, btn_bg_x, bbtn_bg_y, btn_bg_w, bbtn_bg_h, (mouse_bbtn ? COLOR_BUTTON_SUCCESS_HOVER_BACKGROUND : COLOR_BUTTON_SUCCESS_BACKGROUND)); drawalpha(BM_YES, btnx, bbtn_y, btnw, btnh, (mouse_bbtn ? COLOR_BUTTON_SUCCESS_HOVER_TEXT : COLOR_BUTTON_SUCCESS_TEXT)); framerect((x + dx) + 5 * SCALE, y + 17 * SCALE, (x + dx) + 111 * SCALE, y + 24 * SCALE, COLOR_BUTTON_DISABLED_TRANSFER); drawrectw((x + dx) + 5 * SCALE, y + 17 * SCALE, w, 7 * SCALE, COLOR_BUTTON_DISABLED_TRANSFER); break; } case FILE_TRANSFER_STATUS_ACTIVE: { setcolor(COLOR_BUTTON_INPROGRESS_TEXT); drawalpha(BM_FTM, ftbar_x, ftbar_y, ftbar_sw, ftbar_h, COLOR_BUTTON_INPROGRESS_BACKGROUND); drawalpha(BM_FTB1, btn_bg_x, tbtn_bg_y, btn_bg_w, tbtn_bg_h, (mouse_tbtn ? COLOR_BUTTON_SUCCESS_HOVER_BACKGROUND : COLOR_BUTTON_SUCCESS_BACKGROUND)); drawalpha(BM_NO, btnx, tbtn_y, btnw, btnh, (mouse_tbtn ? COLOR_BUTTON_SUCCESS_HOVER_TEXT : COLOR_BUTTON_SUCCESS_TEXT)); drawalpha(BM_FTB2, btn_bg_x, bbtn_bg_y, btn_bg_w, bbtn_bg_h, (mouse_bbtn ? COLOR_BUTTON_SUCCESS_HOVER_BACKGROUND : COLOR_BUTTON_SUCCESS_BACKGROUND)); drawalpha(BM_PAUSE, btnx, bbtn_y, btnw, btnh, (mouse_bbtn ? COLOR_BUTTON_SUCCESS_HOVER_TEXT : COLOR_BUTTON_SUCCESS_TEXT)); drawtext(x + dx + 5 * SCALE + 53 * SCALE - textwidth(size_text, size_text_len) / 2, y + 10 * SCALE, size_text, size_text_len); drawtext(x + dx + 5 * SCALE + 106 * SCALE - textwidth(text2, len2), y + 10 * SCALE, text2, len2); framerect((x + dx) + 5 * SCALE, y + 17 * SCALE, (x + dx) + 111 * SCALE, y + 24 * SCALE, COLOR_BUTTON_INPROGRESS_TEXT); drawrectw((x + dx) + 5 * SCALE, y + 17 * SCALE, w, 7 * SCALE, COLOR_BUTTON_INPROGRESS_TEXT); break; } case FILE_TRANSFER_STATUS_PAUSED_US: case FILE_TRANSFER_STATUS_PAUSED_BOTH: case FILE_TRANSFER_STATUS_PAUSED_THEM: { setcolor(COLOR_BUTTON_DISABLED_TRANSFER); drawalpha(BM_FTM, ftbar_x, ftbar_y, ftbar_sw, ftbar_h, COLOR_BUTTON_DISABLED_BACKGROUND); drawalpha(BM_FTB1, btn_bg_x, tbtn_bg_y, btn_bg_w, tbtn_bg_h, (mouse_tbtn ? COLOR_BUTTON_SUCCESS_HOVER_BACKGROUND : COLOR_BUTTON_SUCCESS_BACKGROUND)); drawalpha(BM_NO, btnx, tbtn_y, btnw, btnh, (mouse_tbtn ? COLOR_BUTTON_SUCCESS_HOVER_TEXT : COLOR_BUTTON_SUCCESS_TEXT)); if(file->status <= FILE_TRANSFER_STATUS_PAUSED_BOTH){ /* Paused by at least us */ drawalpha(BM_FTB2, btn_bg_x, bbtn_bg_y, btn_bg_w, bbtn_bg_h, (mouse_bbtn ? COLOR_BUTTON_SUCCESS_HOVER_BACKGROUND : COLOR_BUTTON_SUCCESS_BACKGROUND)); drawalpha(BM_RESUME, btnx, bbtn_y, btnw, btnh, (mouse_bbtn ? COLOR_BUTTON_SUCCESS_HOVER_TEXT : COLOR_BUTTON_SUCCESS_TEXT)); } else { /* Paused only by them */ drawalpha(BM_FTB2, btn_bg_x, bbtn_bg_y, btn_bg_w, bbtn_bg_h, COLOR_BUTTON_DISABLED_BACKGROUND); drawalpha(BM_PAUSE, btnx, bbtn_y, btnw, btnh, COLOR_BUTTON_DISABLED_TRANSFER); } framerect((x + dx) + 5 * SCALE, y + 17 * SCALE, (x + dx) + 111 * SCALE, y + 24 * SCALE, COLOR_BUTTON_DISABLED_TRANSFER); drawrectw((x + dx) + 5 * SCALE, y + 17 * SCALE, w, 7 * SCALE, COLOR_BUTTON_DISABLED_TRANSFER); break; } } drawtext(x + dx + 5 * SCALE, y + 10 * SCALE, size, sizelen); drawtextwidth(x + dx + 5 * SCALE, 106 * SCALE, y + 3 * SCALE, file->name, file->name_length); y += BM_FT_HEIGHT; break; } } y += MESSAGES_SPACING; } if(i == n) { // Last message is visible. Append typing notifications, if needed. FRIEND *f = get_typers(m); if(f) { setfont(FONT_TEXT); // @TODO: separate these colours if needed setcolor(COLOR_MAIN_HINTTEXT); drawtextwidth_right(x, MESSAGES_X - NAME_OFFSET, y, f->name, f->name_length); drawtextwidth(x + MESSAGES_X, x + width, y, S(IS_TYPING), SLEN(IS_TYPING)); } } }