чување 1ed89deb279fadcba0fab94618c978ded26a56e1
родитељ 770e59f4ccd8c98180d611dc0f5b0974d1edc9e5
Аутор: Страхиња Радић <contact@strahinja.org>
Датум: Mon, 14 Jun 2021 18:39:32 +0200
Added dirty state, quit prompt
Signed-off-by: Страхиња Радић <contact@strahinja.org>
Diffstat:
измењених датотека: 5, додавања: 75(+), брисања: 16(-)
diff --git a/config.def.h b/config.def.h
@@ -25,6 +25,8 @@
#define MSGID_BG TB_DEFAULT
#define MSGSTR_FG TB_WHITE
#define MSGSTR_BG TB_DEFAULT
+#define PROMPT_FG TB_YELLOW | TB_BOLD
+#define PROMPT_BG TB_MAGENTA
#define SHADOW_FG TB_BLACK
#define SHADOW_BG TB_BLACK | TB_BOLD
#define TITLE_FG TB_BLACK
@@ -38,7 +40,7 @@ void format_msgs(char* result, size_t result_size, const char* format,
static const struct StatusSegment status_segments[] = {
{ .format = "%s", .callback = format_filename,
.fg = TB_BLACK, .bg = TB_WHITE, .alignment = LEFT },
- { .format = "msg:%ld/%ld (%ld fuzzy)",
+ { .format = "%ld/%ld (%ld fuzzy)",
.callback = format_msgs,
.fg = TB_WHITE | TB_BOLD, .bg = TB_BLUE, .alignment = CENTER },
{ .format = "H=HELP, q=QUIT", .callback = NULL,
diff --git a/config.h b/config.h
@@ -25,6 +25,8 @@
#define MSGID_BG TB_DEFAULT
#define MSGSTR_FG TB_WHITE
#define MSGSTR_BG TB_DEFAULT
+#define PROMPT_FG TB_YELLOW | TB_BOLD
+#define PROMPT_BG TB_MAGENTA
#define SHADOW_FG TB_BLACK
#define SHADOW_BG TB_BLACK | TB_BOLD
#define TITLE_FG TB_BLACK
@@ -38,7 +40,7 @@ void format_msgs(char* result, size_t result_size, const char* format,
static const struct StatusSegment status_segments[] = {
{ .format = "%s", .callback = format_filename,
.fg = TB_BLACK, .bg = TB_WHITE, .alignment = LEFT },
- { .format = "msg:%ld/%ld (%ld fuzzy)",
+ { .format = "%ld/%ld (%ld fuzzy)",
.callback = format_msgs,
.fg = TB_WHITE | TB_BOLD, .bg = TB_BLUE, .alignment = CENTER },
{ .format = "H=HELP, q=QUIT", .callback = NULL,
diff --git a/draw.c b/draw.c
@@ -36,6 +36,7 @@ const char* flag_strings[] = {
};
const char* empty_file_text = "*** Empty file ***";
const char* program_name = "poe";
+const char* prompt_dirty = "File changed, save [y/n/ESC]?";
void
draw_rect(const int startx, const int endx, const int starty, const int endy,
@@ -225,7 +226,11 @@ draw_status(const struct DrawState* state)
int current_start = 0;
const struct StatusSegment* pseg = status_segments;
- if (state->error && state->error[0])
+ if (state->in_prompt && state->prompt[0])
+ draw_string(0, state->maxy-1, PROMPT_FG, PROMPT_BG,
+ state->prompt, state->maxx, state->maxx, 1, 1,
+ CENTER);
+ else if (state->error && state->error[0])
draw_string(0, state->maxy-1, ERROR_FG, ERROR_BG, state->error,
state->maxx, state->maxx, 1, 1, CENTER);
else
diff --git a/draw.h b/draw.h
@@ -1,4 +1,5 @@
/* See the file LICENSE for copyright and license details. */
+#include "termbox.h"
#define BORDER_NW ((uint32_t)L'\u250c')
#define BORDER_NE ((uint32_t)L'\u2510')
#define BORDER_SW ((uint32_t)L'\u2514')
@@ -14,9 +15,13 @@ typedef enum {
struct DrawState {
char* error;
+ char* prompt;
char* filename;
struct PoEntry* entries;
+ void (*prompt_callback)(struct DrawState*, struct tb_event*);
int running;
+ int dirty;
+ int in_prompt;
int show_help;
int show_edit;
int maxx;
diff --git a/poe.c b/poe.c
@@ -19,6 +19,7 @@
#include "config.h"
extern const char* errors[];
+extern const char* prompt_dirty;
extern const char* program_name;
int
@@ -64,13 +65,31 @@ format_msgs(char* result, size_t result_size, const char* format,
}
void
-handle_key_event(const struct tb_event* ev, struct DrawState* state)
+quit_callback(struct DrawState* state, struct tb_event* ev)
+{
+ if (state)
+ {
+ // if (ev->ch == 'y')...
+ state->dirty = 0;
+ state->prompt_callback = NULL;
+ state->running = 0;
+ }
+}
+
+void
+handle_key_event(struct tb_event* ev, struct DrawState* state)
{
if (!state)
return;
if (ev->key == TB_KEY_ESC)
{
+ if (state->in_prompt)
+ {
+ state->in_prompt = 0;
+ state->prompt[0] = 0;
+ return;
+ }
if (state->error[0])
state->error[0] = 0;
if (!(state->show_help || state->show_edit))
@@ -82,18 +101,34 @@ handle_key_event(const struct tb_event* ev, struct DrawState* state)
}
else if (ev->ch == 'q' || ev->key == TB_KEY_CTRL_Q)
{
- if (state->show_edit)
- strcpy(state->error, errors[ERR_DLG_OPEN_QUIT]);
+ if (state->dirty)
+ {
+ state->in_prompt = 1;
+ strcpy(state->prompt, prompt_dirty);
+ state->prompt_callback = quit_callback;
+ }
else
state->running = 0;
}
+ else if ((ev->ch == 'y' || ev->ch == 'n') && state->in_prompt)
+ {
+ if (state->prompt_callback)
+ state->prompt_callback(state, ev);
+ state->in_prompt = 0;
+ state->prompt[0] = 0;
+ }
else if (state->show_help)
strcpy(state->error, errors[ERR_DLG_OPEN]);
else if (ev->key == TB_KEY_F1
|| ev->ch == 'H')
{
- state->show_help = 1;
- state->error[0] = 0;
+ if (state->show_edit)
+ strcpy(state->error, errors[ERR_DLG_OPEN]);
+ else
+ {
+ state->show_help = 1;
+ state->error[0] = 0;
+ }
}
else if (ev->key == TB_KEY_ENTER)
{
@@ -109,7 +144,10 @@ handle_key_event(const struct tb_event* ev, struct DrawState* state)
|| (ev->ch == 'f' && !state->show_edit))
{
if (state->msgid_count > 0)
+ {
state->entries[state->msgid_number-1].flags ^= FL_FUZZY;
+ state->dirty = 1;
+ }
}
else if (ev->key == TB_KEY_HOME
|| ev->ch == 'g')
@@ -151,6 +189,7 @@ main(int argc, char** argv)
struct tb_event ev;
struct timespec sleep_spec;
char error[MAXBUF];
+ char prompt[MAXBUF];
struct DrawState state;
FILE* input = NULL;
char filename[MAXPATH];
@@ -166,6 +205,8 @@ main(int argc, char** argv)
.msgid = "Final text", .msgstr = "Последњи текст" },
};
+ error[0] = 0;
+ prompt[0] = 0;
filename[0] = 0;
if (argc > 1)
@@ -185,14 +226,18 @@ main(int argc, char** argv)
tb_init();
error[0] = 0;
- state.error = error;
- state.filename = filename;
- state.entries = &entries[0];
- state.running = 1;
- state.show_edit = 0;
- state.show_help = 0;
- state.msgid_count = LEN(entries);
- state.msgid_number = state.msgid_count > 0 ? 1 : 0;
+ state.error = error;
+ state.filename = filename;
+ state.prompt = prompt;
+ state.entries = &entries[0];
+ state.prompt_callback = NULL;
+ state.running = 1;
+ state.dirty = 0;
+ state.in_prompt = 0;
+ state.show_edit = 0;
+ state.show_help = 0;
+ state.msgid_count = LEN(entries);
+ state.msgid_number = state.msgid_count > 0 ? 1 : 0;
state.first_shown_msgid = state.msgid_number;
while (state.running)