aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/imv.c134
1 files changed, 102 insertions, 32 deletions
diff --git a/src/imv.c b/src/imv.c
index 17b82b9..10936fa 100644
--- a/src/imv.c
+++ b/src/imv.c
@@ -52,6 +52,10 @@ enum internal_event_type {
COMMAND
};
+struct color_rgba {
+ unsigned char r, g, b, a;
+};
+
struct internal_event {
enum internal_event_type type;
union {
@@ -83,8 +87,25 @@ struct imv {
int initial_width;
int initial_height;
- /* display some textual info onscreen */
- bool overlay_enabled;
+ /* overlay */
+ struct {
+ /* display some textual info onscreen */
+ bool enabled;
+ /* the user-specified format strings for the overlay*/
+ char *text;
+ struct color_rgba text_color;
+ struct color_rgba background_color;
+
+ /* overlay position */
+ bool position_at_bottom;
+
+ /* overlay font */
+ struct {
+ char *name;
+ int size;
+ } font;
+ } overlay;
+
/* method for scaling up images: interpolate or nearest neighbour */
enum upscaling_method upscaling_method;
@@ -139,11 +160,6 @@ struct imv {
struct imv_image *current_image;
- /* overlay font */
- struct {
- char *name;
- int size;
- } font;
/* if specified by user, the path of the first image to display */
char *starting_path;
@@ -153,7 +169,6 @@ struct imv {
/* the user-specified format strings for the overlay and window title */
char *title_text;
- char *overlay_text;
/* imv subsystems */
struct imv_binds *binds;
@@ -451,6 +466,22 @@ static void event_handler(void *data, const struct imv_event *e)
}
+static bool hex_value_to_color_rgba(const char* hex, struct color_rgba* color)
+{
+ char *ep;
+ uint32_t n = strtoul(hex, &ep, 16);
+ if (*ep != '\0' || ep - hex != 8 || n > 0xFFFFFFFF) {
+ imv_log(IMV_ERROR, "Invalid hex color: '%s'\n", hex);
+ return false;
+ }
+ color->a = n & 0xFF;
+ color->b = (n >> 8) & 0xFF;
+ color->g = (n >> 16) & 0xFF;
+ color->r = (n >> 24);
+ return true;
+}
+
+
static void log_to_stderr(enum imv_log_level level, const char *text, void *data)
{
(void)data;
@@ -471,8 +502,8 @@ struct imv *imv_create(void)
imv->need_rescale = true;
imv->scaling_mode = SCALING_FULL;
imv->loop_input = true;
- imv->font.name = strdup("Monospace");
- imv->font.size = 24;
+ imv->overlay.font.name = strdup("Monospace");
+ imv->overlay.font.size = 24;
imv->binds = imv_binds_create();
imv->navigator = imv_navigator_create();
imv->backends = list_create();
@@ -486,11 +517,17 @@ struct imv *imv_create(void)
" [${imv_width}x${imv_height}] [${imv_scale}%]"
" $imv_current_file [$imv_scaling_mode]"
);
- imv->overlay_text = strdup(
+ imv->overlay.text = strdup(
"[${imv_current_index}/${imv_file_count}]"
" [${imv_width}x${imv_height}] [${imv_scale}%]"
" $imv_current_file [$imv_scaling_mode]"
);
+ imv->overlay.text_color.r = 255;
+ imv->overlay.text_color.g = 255;
+ imv->overlay.text_color.b = 255;
+ imv->overlay.text_color.a = 255;
+ imv->overlay.background_color.a = 195;
+ imv->overlay.position_at_bottom = false;
imv->startup_commands = list_create();
imv_command_register(imv->commands, "quit", &command_quit);
@@ -566,9 +603,9 @@ struct imv *imv_create(void)
void imv_free(struct imv *imv)
{
- free(imv->font.name);
+ free(imv->overlay.font.name);
free(imv->title_text);
- free(imv->overlay_text);
+ free(imv->overlay.text);
imv_binds_free(imv->binds);
imv_navigator_free(imv->navigator);
if (imv->current_source) {
@@ -750,7 +787,7 @@ bool imv_parse_args(struct imv *imv, int argc, char **argv)
switch(o) {
case 'f': imv->start_fullscreen = true; break;
case 'r': imv->recursive_load = true; break;
- case 'd': imv->overlay_enabled = true; break;
+ case 'd': imv->overlay.enabled = true; break;
case 'x': imv->loop_input = false; break;
case 'l': imv->list_files_at_exit = true; break;
case 'n': imv->starting_path = optarg; break;
@@ -1078,7 +1115,7 @@ static bool setup_window(struct imv *imv)
int ww, wh;
imv_window_get_size(imv->window, &ww, &wh);
imv->canvas = imv_canvas_create(ww, wh);
- imv_canvas_font(imv->canvas, imv->font.name, imv->font.size);
+ imv_canvas_font(imv->canvas, imv->overlay.font.name, imv->overlay.font.size);
}
return true;
@@ -1201,20 +1238,34 @@ static void render_window(struct imv *imv)
imv_canvas_clear(imv->canvas);
/* if the overlay needs to be drawn, draw that too */
- if (imv->overlay_enabled) {
- const int height = imv->font.size * 1.2;
- imv_canvas_color(imv->canvas, 0, 0, 0, 0.75);
- imv_canvas_fill_rectangle(imv->canvas, 0, 0, ww, height);
- imv_canvas_color(imv->canvas, 1, 1, 1, 1);
+ if (imv->overlay.enabled) {
+ const int height = imv->overlay.font.size * 1.2;
+ imv_canvas_color(imv->canvas,
+ imv->overlay.background_color.r / 255.f,
+ imv->overlay.background_color.g / 255.f,
+ imv->overlay.background_color.b / 255.f,
+ imv->overlay.background_color.a / 255.f);
+ int y = 0 ;
+ const int bottom_offset = 5;
+ if (imv->overlay.position_at_bottom)
+ {
+ y = wh - height - bottom_offset;
+ }
+ imv_canvas_fill_rectangle(imv->canvas, 0, y, ww, height + bottom_offset);
+ imv_canvas_color(imv->canvas,
+ imv->overlay.text_color.r / 255.f,
+ imv->overlay.text_color.g / 255.f,
+ imv->overlay.text_color.b / 255.f,
+ imv->overlay.text_color.a / 255.f);
char overlay_text[1024];
- generate_env_text(imv, overlay_text, sizeof overlay_text, imv->overlay_text);
- imv_canvas_printf(imv->canvas, 0, 0, "%s", overlay_text);
+ generate_env_text(imv, overlay_text, sizeof overlay_text, imv->overlay.text);
+ imv_canvas_printf(imv->canvas, 0, y, "%s", overlay_text);
}
/* draw command entry bar if needed */
if (imv_console_prompt(imv->console)) {
const int bottom_offset = 5;
- const int height = imv->font.size * 1.2;
+ const int height = imv->overlay.font.size * 1.2;
imv_canvas_color(imv->canvas, 0, 0, 0, 0.75);
imv_canvas_fill_rectangle(imv->canvas, 0, wh - height - bottom_offset,
ww, height + bottom_offset);
@@ -1317,7 +1368,7 @@ static int handle_ini_value(void *user, const char *section, const char *name,
}
if (!strcmp(name, "overlay")) {
- imv->overlay_enabled = parse_bool(value);
+ imv->overlay.enabled = parse_bool(value);
return 1;
}
@@ -1362,22 +1413,41 @@ static int handle_ini_value(void *user, const char *section, const char *name,
return 1;
}
+ if (!strcmp(name, "overlay_text_color")) {
+ if (!hex_value_to_color_rgba(value, &imv->overlay.text_color)) {
+ return false;
+ }
+ return 1;
+ }
+
+ if (!strcmp(name, "overlay_position_bottom")) {
+ imv->overlay.position_at_bottom = parse_bool(value);
+ return 1;
+ }
+
+ if (!strcmp(name, "overlay_background_color")) {
+ if (!hex_value_to_color_rgba(value, &imv->overlay.background_color)) {
+ return false;
+ }
+ return 1;
+ }
+
if (!strcmp(name, "overlay_font")) {
- free(imv->font.name);
- imv->font.name = strdup(value);
- char *sep = strchr(imv->font.name, ':');
+ free(imv->overlay.font.name);
+ imv->overlay.font.name = strdup(value);
+ char *sep = strchr(imv->overlay.font.name, ':');
if (sep) {
*sep = 0;
- imv->font.size = atoi(sep + 1);
+ imv->overlay.font.size = atoi(sep + 1);
} else {
- imv->font.size = 24;
+ imv->overlay.font.size = 24;
}
return 1;
}
if (!strcmp(name, "overlay_text")) {
- free(imv->overlay_text);
- imv->overlay_text = strdup(value);
+ free(imv->overlay.text);
+ imv->overlay.text = strdup(value);
return 1;
}
@@ -1599,7 +1669,7 @@ static void command_overlay(struct list *args, const char *argstr, void *data)
(void)args;
(void)argstr;
struct imv *imv = data;
- imv->overlay_enabled = !imv->overlay_enabled;
+ imv->overlay.enabled = !imv->overlay.enabled;
imv->need_redraw = true;
}