colored overlay

* first steps for colored overlay
* overlay color wip
* add option for overlay position
    if overlay_positiion_bottom is true overlay is at the bottom
* remove enum for overlay position
This commit is contained in:
Andreas Stallinger 2019-10-08 02:44:07 +02:00 committed by Harry Jeffery
parent afe155dcea
commit d1e4f7fcff

134
src/imv.c
View file

@ -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;
}