render.c (3089B)
1 2 #include "termbox2.h" 3 #include "tui.h" 4 #include "config.h" 5 #include "utils.h" 6 7 #define HORIZ_LINE 0x2500 8 #define VERT_LINE 0x2502 9 10 static void 11 draw_bars(void) 12 { 13 int i; 14 const int width = tb_width(); 15 const int height = tb_height(); 16 17 // verticals first 18 19 for (i = 2; i < height - 2; i++) { 20 tb_set_cell(0, i, VERT_LINE, LINE_COLOR, BACK_COLOR); 21 tb_set_cell(FEED_CAP + 5, i, VERT_LINE, LINE_COLOR, BACK_COLOR); /* separator line */ 22 tb_set_cell(width - 1, i, VERT_LINE, LINE_COLOR, BACK_COLOR); 23 } 24 25 for (i = 0; i < width; i++) { 26 tb_set_cell(i, 1, HORIZ_LINE, LINE_COLOR, BACK_COLOR); 27 tb_set_cell(i, height - 2, HORIZ_LINE, LINE_COLOR, BACK_COLOR); 28 } 29 30 tb_print(1, 0, LOGO_COLOR, BACK_COLOR, "readr"); 31 tb_print(width - 5, 0, TEXT_COLOR, BACK_COLOR, VERSION); 32 tb_print(width - 66, 33 height - 1, 34 TEXT_COLOR, 35 BACK_COLOR, 36 "[arrows] move [enter] open link [space] open comments [q] quit"); 37 38 // corners top 39 40 tb_set_cell(0, 1, 0x250C, LINE_COLOR, BACK_COLOR); 41 tb_set_cell(FEED_CAP + 5, 1, 0x252C, LINE_COLOR, BACK_COLOR); 42 tb_set_cell(width - 1, 1, 0x2510, LINE_COLOR, BACK_COLOR); 43 44 // corners bottom 45 46 tb_set_cell(0, height - 2, 0x2514, LINE_COLOR, BACK_COLOR); 47 tb_set_cell(FEED_CAP + 5, height - 2, 0x2534, LINE_COLOR, BACK_COLOR); 48 tb_set_cell(width - 1, height - 2, 0x2518, LINE_COLOR, BACK_COLOR); 49 } 50 51 static void 52 draw_background(void) 53 { 54 tb_set_clear_attrs(TEXT_COLOR, BACK_COLOR); 55 tb_clear(); 56 } 57 58 void 59 render(app_t* app) 60 { 61 int i; 62 uintattr_t color; 63 int title_len, domain_len; 64 char title[TITLE_CAP] = { 0 }; 65 char domain[DOMAIN_CAP] = { 0 }; 66 db_post_t* post; 67 feed_t* feed; 68 feed_t* selected_feed = app->feeds[app->selected_feed]; 69 int buffer_height = tb_height() - 3 - 3; 70 int width = tb_width(); 71 72 draw_background(); 73 draw_bars(); 74 75 for (i = 0; i < app->feeds_len; i++) { 76 feed = app->feeds[i]; 77 78 if (app->selected_panel == 0 && i == app->selected_feed) 79 color = (FEED_COLOR | TB_REVERSE | TB_BRIGHT | TB_BOLD); 80 else if (i == app->selected_feed) 81 color = (FEED_COLOR | TB_BOLD); 82 else 83 color = (FEED_COLOR | TB_DIM); 84 85 tb_print(2, 3 + i, color, BACK_COLOR, feed->title ? feed->title : "N/A"); 86 } 87 88 // posts 89 90 int visible_len = MIN(buffer_height, selected_feed->posts_len); 91 92 for (i = 0; i < visible_len; i++) { 93 post = selected_feed->posts[i]; 94 95 title_len = MIN(TITLE_CAP, strlen(post->title)) + 1; 96 strncpy(title, post->title, title_len - 1); 97 title[title_len - 1] = ' '; // overlapping with domain 98 title[title_len] = '\0'; 99 100 const char* domain_host = host_from_url(post->link); 101 domain_len = MIN(DOMAIN_CAP, strlen(domain_host)); 102 strncpy(domain, domain_host, domain_len); 103 domain[domain_len] = '\0'; 104 105 if (app->selected_panel == 1 && i == app->selected_post) 106 if (post->seen) 107 color = (POST_COLOR | TB_REVERSE | TB_DIM); 108 else 109 color = (POST_COLOR | TB_REVERSE | TB_BRIGHT | TB_BOLD); 110 else if (post->seen) 111 color = (SEEN_COLOR); 112 else 113 color = (POST_COLOR); 114 115 tb_print(width - domain_len - 2, 3 + i, DOMAIN_COLOR, BACK_COLOR, domain); 116 tb_print(FEED_CAP + 7, 3 + i, color, BACK_COLOR, title); 117 } 118 119 tb_present(); 120 }