readr

Minimal Terminal RSS Reader
Log | Files | Refs | README | LICENSE

render.c (3043B)


      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 + 2, 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 + 2, 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 + 2, 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 	size_t i;
     62 	uintattr_t color;
     63 	char title[TITLE_CAP] = { 0 };
     64 	char domain[DOMAIN_CAP] = { 0 };
     65 	db_post_t* post;
     66 	feed_t* feed;
     67 	feed_t* selected_feed = app->feeds[app->selected_feed];
     68 	int buffer_height = tb_height() - 3 - 3;
     69 	int width = tb_width();
     70 
     71 	draw_background();
     72 	draw_bars();
     73 
     74 	for (i = 0; i < app->feeds_len; i++) {
     75 		feed = app->feeds[i];
     76 
     77 		if (app->selected_panel == 0 && i == app->selected_feed)
     78 			color = (FEED_COLOR | TB_REVERSE | TB_BRIGHT | TB_BOLD);
     79 		else if (i == app->selected_feed)
     80 			color = (FEED_COLOR | TB_BOLD);
     81 		else
     82 			color = (FEED_COLOR | TB_DIM);
     83 
     84 		tb_print(2, 3 + (int)i, color, BACK_COLOR, feed->title ? feed->title : "N/A");
     85 	}
     86 
     87 	// posts
     88 
     89 	int visible_len = MIN(buffer_height, selected_feed->posts_len);
     90 
     91 	for (int j = 0; j < visible_len; j++) {
     92 		post = selected_feed->posts[j];
     93 
     94 		// title - added space for when title and domain overlap
     95 		snprintf(title, TITLE_CAP, "%s ", post->title ? post->title : "(bad title");
     96 
     97 		// domain
     98 		const char* domain_host = host_from_url(post->link);
     99 		snprintf(domain, DOMAIN_CAP, "%s", domain_host ? domain_host : "(bad title)");
    100 		int domain_len = (int)strlen(domain);
    101 
    102 		if (app->selected_panel == 1 && j == app->selected_post)
    103 			if (post->seen)
    104 				color = (POST_COLOR | TB_REVERSE | TB_DIM);
    105 			else
    106 				color = (POST_COLOR | TB_REVERSE | TB_BRIGHT | TB_BOLD);
    107 		else if (post->seen)
    108 			color = (SEEN_COLOR);
    109 		else
    110 			color = (POST_COLOR);
    111 
    112 		tb_print(width - domain_len - 2, 3 + (int)j, DOMAIN_COLOR, BACK_COLOR, domain);
    113 		tb_print(FEED_CAP + 4, 3 + (int)j, color, BACK_COLOR, title);
    114 	}
    115 
    116 	tb_present();
    117 }