~strahinja/poe

98c022a9ac6e1af0c0ebd5f13569229a66ddae38 — Страхиња Радић 7 days ago 894ca28
Moved global variables to struct DrawState

Signed-off-by: Страхиња Радић <contact@strahinja.org>
5 files changed, 141 insertions(+), 92 deletions(-)

M config.def.h
M config.h
M draw.c
M draw.h
M poe.c
M config.def.h => config.def.h +4 -2
@@ 1,6 1,8 @@
/* See the file LICENSE for copyright and license details. */
void format_filename(char* result, size_t result_size, const char* format);
void format_msgs(char* result, size_t result_size, const char* format);
void format_filename(char* result, size_t result_size, const char* format,
		const DrawState* state);
void format_msgs(char* result, size_t result_size, const char* format,
		const DrawState* state);

static const StatusSegment status_segments[] = {
	{ "%s",			format_filename, TB_BLACK,	     TB_WHITE,	LEFT	},

M config.h => config.h +4 -2
@@ 1,6 1,8 @@
/* See the file LICENSE for copyright and license details. */
void format_filename(char* result, size_t result_size, const char* format);
void format_msgs(char* result, size_t result_size, const char* format);
void format_filename(char* result, size_t result_size, const char* format,
		const DrawState* state);
void format_msgs(char* result, size_t result_size, const char* format,
		const DrawState* state);

static const StatusSegment status_segments[] = {
	{ "%s",			format_filename, TB_BLACK,	     TB_WHITE,	LEFT	},

M draw.c => draw.c +46 -27
@@ 117,12 117,17 @@ draw_string(const int x, const int y, const uint16_t fg, const uint16_t bg,
}

void
draw_help()
draw_help(const DrawState* state)
{
	if (!state)
		return;

	int startx, endx, starty, endy;
	int w = 50;
	int h = 20;
	int row = 0;
	int maxx = state->maxx;
	int maxy = state->maxy;

	startx = w > maxx ? 0 : (maxx - w) / 2;
	endx = w > maxx ? maxx-1 : maxx-startx;


@@ 142,26 147,30 @@ draw_help()
}

void
draw_status()
draw_status(const DrawState* state)
{
	if (!state)
		return;

	char buf[MAXBUF];
	int seg_size = maxx/3;
	int current_start = 0;
	int seg_size              = state->maxx/3;
	int current_start         = 0;
	const StatusSegment* pseg = status_segments;

	if (error[0])
		draw_string(0, maxy-1, ERROR_FG, ERROR_BG, error, maxx, maxx, 
				1, CENTER);
	if (state->error && state->error[0])
		draw_string(0, state->maxy-1, ERROR_FG, ERROR_BG, state->error, 
				state->maxx, state->maxx, 1, CENTER);
	else
		while (pseg < status_segments + LEN(status_segments))
		{
			buf[0] = 0;
			if (pseg->callback)
				pseg->callback(buf, MAXBUF, pseg->format); 
				pseg->callback(buf, MAXBUF, pseg->format, 
						state); 
			else
				strncpy(buf, pseg->format, MAXBUF);
			buf[MAXBUF-1] = 0;
			draw_string(current_start, maxy-1, pseg->fg, pseg->bg,
			draw_string(current_start, state->maxy-1, pseg->fg, pseg->bg,
					buf, seg_size, seg_size, 1, 
					pseg->alignment);
			pseg++;


@@ 170,14 179,17 @@ draw_status()
}

void
draw_entry(PoEntry* entry)
draw_entry(const PoEntry* entry, const DrawState* state)
{
	if (!state)
		return;

	uint16_t flags;

	if (entry)
	{
		draw_string(0, maxy/3, MSGID_FG, MSGID_BG, entry->msgid,
			maxx, maxx, maxx/4, LEFT);
		draw_string(0, state->maxy/3, MSGID_FG, MSGID_BG, entry->msgid,
			state->maxx, state->maxx, state->maxx/4, LEFT);
		flags = entry->flags;
		while (flags)
		{


@@ 185,38 197,45 @@ draw_entry(PoEntry* entry)
			{
				flags &= ~FL_C_FORMAT;
				draw_string(0, 1, FLAG_FG, FLAG_BG,
					flag_strings[FL_C_FORMAT], maxx, maxx, 1, LEFT);
					flag_strings[FL_C_FORMAT], 
					state->maxx, state->maxx, 1, LEFT);
			}
			else if (flags & FL_FUZZY)
			{
				flags &= ~FL_FUZZY;
				draw_string(10, 1, FLAG_FG, FLAG_BG,
					flag_strings[FL_FUZZY], maxx-10, maxx-10, 1, LEFT);
					flag_strings[FL_FUZZY], state->maxx-10, 
					state->maxx-10, 1, LEFT);
			}
		}
		draw_string(0, 2*maxy/3, MSGSTR_FG, MSGSTR_BG, entry->msgstr,
			maxx, maxx, maxx/4, LEFT);
		draw_string(0, 2*state->maxy/3, MSGSTR_FG, MSGSTR_BG, 
				entry->msgstr, state->maxx, state->maxx, 
				state->maxx/4, LEFT);
	}
	else
	{
		draw_string(0, maxy/3, MSGID_FG, MSGID_BG, empty_msgid,
			maxx, maxx, maxx/4, LEFT);
		draw_string(0, 2*maxy/3, MSGSTR_FG, MSGSTR_BG, empty_msgstr,
			maxx, maxx, maxx/4, LEFT);
		draw_string(0, state->maxy/3, MSGID_FG, MSGID_BG, empty_msgid,
			state->maxx, state->maxx, state->maxx/4, LEFT);
		draw_string(0, 2*state->maxy/3, MSGSTR_FG, MSGSTR_BG, empty_msgstr,
			state->maxx, state->maxx, state->maxx/4, LEFT);
	}
}

void
draw()
draw(const DrawState* state)
{
	if (msgid_number > 0)
		draw_entry(&entries[msgid_number-1]);
	if (!state)
		return;

	if (state->msgid_number > 0 
			&& state->msgid_number < state->msgid_count+1)
		draw_entry(&state->entries[state->msgid_number-1], state);
	else
		draw_entry(NULL);
		draw_entry(NULL, state);

	if (show_help)
		draw_help();
	if (state->show_help)
		draw_help(state);

	draw_status();
	draw_status(state);
}


M draw.h => draw.h +17 -10
@@ 24,27 24,34 @@ typedef enum {
} Alignment;

typedef struct {
	char* error;
	char* filename;
	PoEntry* entries;
	int running;
	int show_help;
	int maxx;
	int maxy;
	long msgid_number;
	long msgid_count;
} DrawState;

typedef struct {
	const char* format;
	void (*callback)(char*, size_t, const char*);
	void (*callback)(char*, size_t, const char*, const DrawState*);
	uint16_t fg;
	uint16_t bg;
	Alignment alignment;
} StatusSegment;

extern char error[MAXBUF];
extern PoEntry entries[];
extern long msgid_count;
extern long msgid_number;
extern int show_help;
extern int maxx, maxy;

void draw_box(const int startx, const int endx, const int starty, const int endy,
		const uint16_t fg, const uint16_t bg);
void draw_string(const int x, const int y, const uint16_t fg, const uint16_t bg,
		const char* s, const int max_cols, const int fill_cols,
		const int padding, const Alignment align);
void draw_help();
void draw_status();
void draw_entry(PoEntry* entry);
void draw();
void draw_help(const DrawState* st);
void draw_status(const DrawState* st);
void draw_entry(const PoEntry* entry, const DrawState* st);
void draw(const DrawState* st);


M poe.c => poe.c +70 -51
@@ 18,23 18,6 @@
extern const char* errors[];
extern const char* program_name;

char filename[MAXPATH];
char error[MAXBUF];
/* Test */
PoEntry entries[] = {
	{ flags: FL_C_FORMAT | FL_FUZZY,	msgid: "First msgid: %s", 
						msgstr: "Први msgid: %s" },
	{ flags: FL_NONE,			msgid: "Test msgid",	  
						msgstr: "Пробни msgstr"	 },
	{ flags: FL_FUZZY,			msgid: "Final text",	  
						msgstr: "Последњи текст" },
};

long msgid_count  = 0;
long msgid_number = 0;
int show_help     = 0;
int maxx, maxy;

int
print_error(const int code, const char* msg, ...)
{


@@ 48,90 31,113 @@ print_error(const int code, const char* msg, ...)
}

void
format_filename(char* result, size_t result_size, const char* format)
format_filename(char* result, size_t result_size, const char* format, 
		const DrawState* state)
{
	if (!result)
		return;

	snprintf(result, result_size, format, filename);
	snprintf(result, result_size, format, state->filename);
}

void
format_msgs(char* result, size_t result_size, const char* format)
format_msgs(char* result, size_t result_size, const char* format,
		const DrawState* state)
{
	if (!result)
		return;

	snprintf(result, result_size, format, msgid_number, msgid_count);
	snprintf(result, result_size, format, 
			state ? state->msgid_number : 0, 
			state ? state->msgid_count : 0);
}

void
handle_key_event(const struct tb_event* ev, int* running)
handle_key_event(const struct tb_event* ev, DrawState* state)
{
	if (!state)
		return;

	if (ev->key == TB_KEY_ESC)
	{
		if (error[0])
			error[0] = 0;
		if (show_help)
			show_help = 0;
		if (state->error[0])
			state->error[0] = 0;
		if (state->show_help)
			state->show_help = 0;
		else
			strcpy(error, errors[ERR_EXIT_KEY]);
			strcpy(state->error, errors[ERR_EXIT_KEY]);
	}
	else if (ev->ch == 'q')
		*running = 0;
	else if (show_help)
		strcpy(error, errors[ERR_DLG_OPEN]);
		state->running = 0;
	else if (state->show_help)
		strcpy(state->error, errors[ERR_DLG_OPEN]);
	else if (ev->key == TB_KEY_F1 
			|| ev->ch == 'H')
	{
		show_help = 1;
		error[0] = 0;
		state->show_help = 1;
		state->error[0] = 0;
	}
	else if (ev->key == TB_KEY_HOME
			|| ev->ch == 'g')
	{
		error[0] = 0;
		msgid_number = msgid_count ? 1 : 0;
		state->error[0] = 0;
		state->msgid_number = state->msgid_count ? 1 : 0;
	}
	else if (ev->key == TB_KEY_ARROW_UP 
			|| ev->ch == 'k')
	{
		if (msgid_number < 2)
			strcpy(error, errors[ERR_NO_PREV]);
		if (state->msgid_number < 2)
			strcpy(state->error, errors[ERR_NO_PREV]);
		else
		{
			error[0] = 0;
			msgid_number--;
			state->error[0] = 0;
			state->msgid_number--;
		}
	}
	else if (ev->key == TB_KEY_ARROW_DOWN 
			|| ev->ch == 'j')
	{
		if (msgid_number == msgid_count)
			strcpy(error, errors[ERR_NO_NEXT]);
		if (state->msgid_number == state->msgid_count)
			strcpy(state->error, errors[ERR_NO_NEXT]);
		else
		{
			error[0] = 0;
			msgid_number++;
			state->error[0] = 0;
			state->msgid_number++;
		}
	}
	else if (ev->key == TB_KEY_END
			|| ev->ch == 'G')
	{
		error[0] = 0;
		msgid_number = msgid_count;
		state->error[0] = 0;
		state->msgid_number = state->msgid_count;
	}
	else
		strcpy(error, errors[ERR_UNKNOWN_KEY]);
		strcpy(state->error, errors[ERR_UNKNOWN_KEY]);
}

int
main(int argc, char** argv)
{
	int running = 1;
	struct tb_event ev;
	struct timespec sleep_spec;
	FILE* input = NULL;
	char error[MAXBUF];
	int maxx, maxy;
	DrawState state;
	long msgid_count  = 0;
	long msgid_number = 0;
	int running       = 1;
	int show_help     = 0;
	FILE* input       = NULL;
	char filename[MAXPATH];
	/* Test */
	PoEntry entries[] = {
		{ flags: FL_C_FORMAT | FL_FUZZY,	msgid: "First msgid: %s", 
							msgstr: "Први msgid: %s" },
		{ flags: FL_NONE,			msgid: "Test msgid",	  
							msgstr: "Пробни msgstr"	 },
		{ flags: FL_FUZZY,			msgid: "Final text",	  
							msgstr: "Последњи текст" },
	};

	filename[0] = 0;



@@ 153,16 159,29 @@ main(int argc, char** argv)
	error[0] = 0;
	msgid_count = LEN(entries);
	msgid_number = msgid_count > 0 ? 1 : 0;
	while (running)

	state.error        = error;
	state.filename     = filename;
	state.entries      = entries;
	state.running      = running;
	state.show_help    = show_help;
	state.msgid_number = msgid_number;
	state.msgid_count  = msgid_count;

	while (state.running)
	{
		tb_clear();
		maxx = tb_width();
		maxy = tb_height();
		draw();

		state.maxx = maxx;
		state.maxy = maxy;

		draw(&state);
		tb_present();
		if (tb_peek_event(&ev, 20) > 0 && ev.type == TB_EVENT_KEY)
			handle_key_event(&ev, &running);
		if (running)
			handle_key_event(&ev, &state);
		if (state.running)
		{
			sleep_spec.tv_nsec = 500;
			sleep_spec.tv_sec = 0;