Add feature: progress bar
This commit is contained in:
		
							parent
							
								
									93b52df269
								
							
						
					
					
						commit
						bfcf655b1e
					
				
							
								
								
									
										12
									
								
								config.h
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								config.h
									
									
									
									
									
								
							| @ -6,10 +6,13 @@ struct settings defaults = { | ||||
| .markup = MARKUP_NO, | ||||
| .colors_norm.bg = "#1793D1", | ||||
| .colors_norm.fg = "#DDDDDD", | ||||
| .colors_norm.highlight = "#1745d1", | ||||
| .colors_crit.bg = "#ffaaaa", | ||||
| .colors_crit.fg = "#000000", | ||||
| .colors_crit.highlight = "#ff6666", | ||||
| .colors_low.bg = "#aaaaff", | ||||
| .colors_low.fg = "#000000", | ||||
| .colors_low.highlight = "#7f7fff", | ||||
| .format = "%s %b",         /* default format */ | ||||
| 
 | ||||
| .timeouts = { S2US(10), S2US(10), S2US(0) }, /* low, normal, critical */ | ||||
| @ -110,6 +113,15 @@ struct settings defaults = { | ||||
| 
 | ||||
| .mouse_right_click = (enum mouse_action []){MOUSE_CLOSE_ALL, -1}, | ||||
| 
 | ||||
| .progress_bar_height = 10, | ||||
| 
 | ||||
| .progress_bar_min_width = 150, | ||||
| 
 | ||||
| .progress_bar_max_width = 300, | ||||
| 
 | ||||
| .progress_bar_frame_width = 1, | ||||
| 
 | ||||
| .no_progress_bar = false, | ||||
| }; | ||||
| 
 | ||||
| struct rule default_rules[] = { | ||||
|  | ||||
							
								
								
									
										72
									
								
								src/draw.c
									
									
									
									
									
								
							
							
						
						
									
										72
									
								
								src/draw.c
									
									
									
									
									
								
							| @ -23,6 +23,7 @@ struct colored_layout { | ||||
|         PangoLayout *l; | ||||
|         struct color fg; | ||||
|         struct color bg; | ||||
|         struct color highlight; | ||||
|         struct color frame; | ||||
|         char *text; | ||||
|         PangoAttrList *attr; | ||||
| @ -166,6 +167,11 @@ static bool have_dynamic_width(void) | ||||
|         return (settings.geometry.width_set && settings.geometry.w == 0); | ||||
| } | ||||
| 
 | ||||
| static bool have_progress_bar(const struct notification *n) | ||||
| { | ||||
|         return (n->progress >= 0 && settings.no_progress_bar == false); | ||||
| } | ||||
| 
 | ||||
| static struct dimensions calculate_dimensions(GSList *layouts) | ||||
| { | ||||
|         struct dimensions dim = { 0 }; | ||||
| @ -237,6 +243,11 @@ static struct dimensions calculate_dimensions(GSList *layouts) | ||||
|                         text_width = MAX(w, text_width); | ||||
|                 } | ||||
| 
 | ||||
|                 if (have_progress_bar(cl->n)){ | ||||
|                         dim.h += settings.progress_bar_height + settings.padding; | ||||
|                         dim.w = MAX(dim.w, settings.progress_bar_min_width); | ||||
|                 } | ||||
| 
 | ||||
|                 dim.corner_radius = MIN(dim.corner_radius, h/2); | ||||
|         } | ||||
| 
 | ||||
| @ -299,6 +310,7 @@ static struct colored_layout *layout_init_shared(cairo_t *c, const struct notifi | ||||
| 
 | ||||
|         cl->fg = string_to_color(n->colors.fg); | ||||
|         cl->bg = string_to_color(n->colors.bg); | ||||
|         cl->highlight = string_to_color(n->colors.highlight); | ||||
|         cl->frame = string_to_color(n->colors.frame); | ||||
| 
 | ||||
|         cl->n = n; | ||||
| @ -354,7 +366,12 @@ static struct colored_layout *layout_from_notification(cairo_t *c, struct notifi | ||||
| 
 | ||||
|         pango_layout_get_pixel_size(cl->l, NULL, &(n->displayed_height)); | ||||
|         if (cl->icon) n->displayed_height = MAX(cairo_image_surface_get_height(cl->icon), n->displayed_height); | ||||
|         n->displayed_height = MAX(settings.notification_height, n->displayed_height + settings.padding * 2); | ||||
|         n->displayed_height = n->displayed_height + settings.padding * 2; | ||||
| 
 | ||||
|         // progress bar
 | ||||
|         if (have_progress_bar(n)) n->displayed_height += settings.progress_bar_height + settings.padding; | ||||
| 
 | ||||
|         n->displayed_height = MAX(settings.notification_height, n->displayed_height); | ||||
| 
 | ||||
|         n->first_render = false; | ||||
|         return cl; | ||||
| @ -397,11 +414,16 @@ static int layout_get_height(struct colored_layout *cl) | ||||
| { | ||||
|         int h; | ||||
|         int h_icon = 0; | ||||
|         int h_progress_bar = 0; | ||||
|         pango_layout_get_pixel_size(cl->l, NULL, &h); | ||||
|         if (cl->icon) | ||||
|                 h_icon = cairo_image_surface_get_height(cl->icon); | ||||
|         if (have_progress_bar(cl->n)){ | ||||
|                 h_progress_bar = settings.progress_bar_height + settings.padding; | ||||
|         } | ||||
| 
 | ||||
|         return MAX(h, h_icon); | ||||
|         int res = MAX(h, h_icon) + h_progress_bar; | ||||
|         return res; | ||||
| } | ||||
| 
 | ||||
| /* Attempt to make internal radius more organic.
 | ||||
| @ -563,11 +585,15 @@ static cairo_surface_t *render_background(cairo_surface_t *srf, | ||||
| static void render_content(cairo_t *c, struct colored_layout *cl, int width) | ||||
| { | ||||
|         const int h = layout_get_height(cl); | ||||
|         int h_without_progress_bar = h; | ||||
|         if (have_progress_bar(cl->n)){ | ||||
|                  h_without_progress_bar -= settings.progress_bar_height + settings.padding; | ||||
|         } | ||||
|         int h_text; | ||||
|         pango_layout_get_pixel_size(cl->l, NULL, &h_text); | ||||
| 
 | ||||
|         int text_x = settings.h_padding, | ||||
|             text_y = settings.padding + h / 2 - h_text / 2; | ||||
|             text_y = settings.padding + h_without_progress_bar / 2 - h_text / 2; | ||||
| 
 | ||||
|         // text positioning
 | ||||
|         if (cl->icon) { | ||||
| @ -575,7 +601,7 @@ static void render_content(cairo_t *c, struct colored_layout *cl, int width) | ||||
|                 if (settings.vertical_alignment == VERTICAL_TOP) { | ||||
|                         text_y = settings.padding; | ||||
|                 } else if (settings.vertical_alignment == VERTICAL_BOTTOM) { | ||||
|                         text_y = h + settings.padding - h_text; | ||||
|                         text_y = h_without_progress_bar + settings.padding - h_text; | ||||
|                         if (text_y < 0) | ||||
|                                 text_y = settings.padding; | ||||
|                 } // else VERTICAL_CENTER
 | ||||
| @ -597,14 +623,14 @@ static void render_content(cairo_t *c, struct colored_layout *cl, int width) | ||||
|                 unsigned int image_width = cairo_image_surface_get_width(cl->icon), | ||||
|                              image_height = cairo_image_surface_get_height(cl->icon), | ||||
|                              image_x = width - settings.h_padding - image_width, | ||||
|                              image_y = settings.padding + h/2 - image_height/2; | ||||
|                              image_y = settings.padding + h_without_progress_bar/2 - image_height/2; | ||||
| 
 | ||||
|                 // vertical alignment
 | ||||
|                 if (settings.vertical_alignment == VERTICAL_TOP) { | ||||
|                         image_y = settings.padding; | ||||
|                 } else if (settings.vertical_alignment == VERTICAL_BOTTOM) { | ||||
|                         image_y = h + settings.padding - image_height; | ||||
|                         if (image_y < settings.padding || image_y > h) | ||||
|                         image_y = h_without_progress_bar + settings.padding - image_height; | ||||
|                         if (image_y < settings.padding || image_y > h_without_progress_bar) | ||||
|                                 image_y = settings.padding; | ||||
|                 } // else VERTICAL_CENTER
 | ||||
| 
 | ||||
| @ -618,6 +644,38 @@ static void render_content(cairo_t *c, struct colored_layout *cl, int width) | ||||
|                 cairo_fill(c); | ||||
|         } | ||||
| 
 | ||||
|         // progress bar positioning
 | ||||
|         if (have_progress_bar(cl->n)){ | ||||
|                 int progress = cl->n->progress; | ||||
|                 unsigned int frame_width = settings.progress_bar_frame_width, | ||||
|                              progress_width = MIN(width - 2 * settings.h_padding, settings.progress_bar_max_width), | ||||
|                              progress_height = settings.progress_bar_height - frame_width, | ||||
|                              frame_x = settings.h_padding, | ||||
|                              frame_y = settings.padding + h - settings.progress_bar_height, | ||||
|                              progress_width_without_frame = progress_width - 2 * frame_width, | ||||
|                              progress_width_1 = progress_width_without_frame * progress / 100, | ||||
|                              progress_width_2 = progress_width_without_frame - progress_width_1, | ||||
|                              x_bar_1 = frame_x + frame_width, | ||||
|                              x_bar_2 = x_bar_1 + progress_width_1; | ||||
| 
 | ||||
|                 double half_frame_width = frame_width / 2.0; | ||||
| 
 | ||||
|                 // draw progress bar
 | ||||
|                 // Note: the bar could be drawn a bit smaller, because the frame is drawn on top
 | ||||
|                 // left side
 | ||||
|                 cairo_set_source_rgba(c, cl->highlight.r, cl->highlight.g, cl->highlight.b, cl->highlight.a); | ||||
|                 cairo_rectangle(c, x_bar_1, frame_y, progress_width_1, progress_height); | ||||
|                 cairo_fill(c); | ||||
|                 // right side
 | ||||
|                 cairo_set_source_rgba(c, cl->bg.r, cl->bg.g, cl->bg.b, cl->bg.a); | ||||
|                 cairo_rectangle(c, x_bar_2, frame_y, progress_width_2, progress_height); | ||||
|                 cairo_fill(c); | ||||
|                 // border
 | ||||
|                 cairo_set_source_rgba(c, cl->frame.r, cl->frame.g, cl->frame.b, cl->frame.a); | ||||
|                 cairo_rectangle(c, frame_x + half_frame_width, frame_y + half_frame_width, progress_width - frame_width, progress_height); | ||||
|                 cairo_set_line_width(c, frame_width); | ||||
|                 cairo_stroke(c); | ||||
|         } | ||||
| } | ||||
| 
 | ||||
| static struct dimensions layout_render(cairo_surface_t *srf, | ||||
|  | ||||
| @ -64,6 +64,7 @@ void notification_print(const struct notification *n) | ||||
|         printf("\tformatted: '%s'\n", n->msg); | ||||
|         printf("\tfg: %s\n", n->colors.fg); | ||||
|         printf("\tbg: %s\n", n->colors.bg); | ||||
|         printf("\thighlight: %s\n", n->colors.highlight); | ||||
|         printf("\tframe: %s\n", n->colors.frame); | ||||
|         printf("\tfullscreen: %s\n", enum_to_string_fullscreen(n->fullscreen)); | ||||
|         printf("\tprogress: %d\n", n->progress); | ||||
| @ -236,6 +237,7 @@ void notification_unref(struct notification *n) | ||||
|         g_free(n->urls); | ||||
|         g_free(n->colors.fg); | ||||
|         g_free(n->colors.bg); | ||||
|         g_free(n->colors.highlight); | ||||
|         g_free(n->colors.frame); | ||||
|         g_free(n->stack_tag); | ||||
|         g_free(n->desktop_entry); | ||||
| @ -393,6 +395,8 @@ void notification_init(struct notification *n) | ||||
|                 n->colors.fg = g_strdup(defcolors.fg); | ||||
|         if (!n->colors.bg) | ||||
|                 n->colors.bg = g_strdup(defcolors.bg); | ||||
|         if (!n->colors.highlight) | ||||
|                 n->colors.highlight = g_strdup(defcolors.highlight); | ||||
|         if (!n->colors.frame) | ||||
|                 n->colors.frame = g_strdup(defcolors.frame); | ||||
| 
 | ||||
|  | ||||
| @ -33,6 +33,7 @@ struct notification_colors { | ||||
|         char *frame; | ||||
|         char *bg; | ||||
|         char *fg; | ||||
|         char *highlight; | ||||
| }; | ||||
| 
 | ||||
| struct notification { | ||||
|  | ||||
| @ -38,6 +38,10 @@ void rule_apply(struct rule *r, struct notification *n) | ||||
|                 g_free(n->colors.bg); | ||||
|                 n->colors.bg = g_strdup(r->bg); | ||||
|         } | ||||
|         if (r->highlight) { | ||||
|                 g_free(n->colors.highlight); | ||||
|                 n->colors.highlight = g_strdup(r->highlight); | ||||
|         } | ||||
|         if (r->fc) { | ||||
|                 g_free(n->colors.frame); | ||||
|                 n->colors.frame = g_strdup(r->fc); | ||||
|  | ||||
| @ -31,6 +31,7 @@ struct rule { | ||||
|         char *new_icon; | ||||
|         char *fg; | ||||
|         char *bg; | ||||
|         char *highlight; | ||||
|         char *fc; | ||||
|         const char *format; | ||||
|         const char *script; | ||||
|  | ||||
| @ -355,6 +355,49 @@ void load_settings(char *cmdline_config_path) | ||||
|                 "Window corner radius" | ||||
|         ); | ||||
| 
 | ||||
|         settings.progress_bar_height = option_get_int( | ||||
|                 "global", | ||||
|                 "progress_bar_height", "-progress_bar_height", defaults.progress_bar_height, | ||||
|                 "Height of the progress bar" | ||||
|         ); | ||||
| 
 | ||||
|         settings.progress_bar_min_width = option_get_int( | ||||
|                 "global", | ||||
|                 "progress_bar_min_width", "-progress_bar_min_width", defaults.progress_bar_min_width, | ||||
|                 "Minimum width of the progress bar" | ||||
|         ); | ||||
| 
 | ||||
|         settings.progress_bar_max_width = option_get_int( | ||||
|                 "global", | ||||
|                 "progress_bar_max_width", "-progress_bar_max_width", defaults.progress_bar_max_width, | ||||
|                 "Maximum width of the progress bar" | ||||
|         ); | ||||
| 
 | ||||
|         settings.progress_bar_frame_width = option_get_int( | ||||
|                 "global", | ||||
|                 "progress_bar_frame_width", "-progress_bar_frame_width", defaults.progress_bar_frame_width, | ||||
|                 "Frame width of the progress bar" | ||||
|         ); | ||||
| 
 | ||||
|         settings.no_progress_bar = option_get_bool( | ||||
|                 "global", | ||||
|                 "no_progress_bar", "-no_progress_bar", false, | ||||
|                 "Hide the progress bar" | ||||
|         ); | ||||
| 
 | ||||
|         // check sanity of the progress bar options
 | ||||
|         { | ||||
|                 if (settings.progress_bar_height < (2 * settings.progress_bar_frame_width)){ | ||||
|                         LOG_E("setting progress_bar_frame_width is bigger than half of progress_bar_height"); | ||||
|                 } | ||||
|                 if (settings.progress_bar_max_width < (2 * settings.progress_bar_frame_width)){ | ||||
|                         LOG_E("setting progress_bar_frame_width is bigger than half of progress_bar_max_width"); | ||||
|                 } | ||||
|                 if (settings.progress_bar_max_width < settings.progress_bar_min_width){ | ||||
|                         LOG_E("setting progress_bar_max_width is smaller than progress_bar_min_width"); | ||||
|                 } | ||||
|         } | ||||
| 
 | ||||
|         { | ||||
|                 char *c = option_get_string( | ||||
|                         "global", | ||||
| @ -584,6 +627,12 @@ void load_settings(char *cmdline_config_path) | ||||
|                 "Foreground color for notifications with low urgency" | ||||
|         ); | ||||
| 
 | ||||
|         settings.colors_low.highlight = option_get_string( | ||||
|                 "urgency_low", | ||||
|                 "highlight", "-lh", defaults.colors_low.highlight, | ||||
|                 "Highlight color for notifications with low urgency" | ||||
|         ); | ||||
| 
 | ||||
|         settings.colors_low.frame = option_get_string( | ||||
|                 "urgency_low", | ||||
|                 "frame_color", "-lfr", settings.frame_color ? settings.frame_color : defaults.colors_low.frame, | ||||
| @ -614,6 +663,12 @@ void load_settings(char *cmdline_config_path) | ||||
|                 "Foreground color for notifications with normal urgency" | ||||
|         ); | ||||
| 
 | ||||
|         settings.colors_norm.highlight = option_get_string( | ||||
|                 "urgency_normal", | ||||
|                 "highlight", "-nh", defaults.colors_norm.highlight, | ||||
|                 "Highlight color for notifications with normal urgency" | ||||
|         ); | ||||
| 
 | ||||
|         settings.colors_norm.frame = option_get_string( | ||||
|                 "urgency_normal", | ||||
|                 "frame_color", "-nfr", settings.frame_color ? settings.frame_color : defaults.colors_norm.frame, | ||||
| @ -644,6 +699,12 @@ void load_settings(char *cmdline_config_path) | ||||
|                 "Foreground color for notifications with ciritical urgency" | ||||
|         ); | ||||
| 
 | ||||
|         settings.colors_crit.highlight = option_get_string( | ||||
|                 "urgency_critical", | ||||
|                 "highlight", "-ch", defaults.colors_crit.highlight, | ||||
|                 "Highlight color for notifications with ciritical urgency" | ||||
|         ); | ||||
| 
 | ||||
|         settings.colors_crit.frame = option_get_string( | ||||
|                 "urgency_critical", | ||||
|                 "frame_color", "-cfr", settings.frame_color ? settings.frame_color : defaults.colors_crit.frame, | ||||
| @ -756,6 +817,7 @@ void load_settings(char *cmdline_config_path) | ||||
|                 r->msg_urgency = ini_get_urgency(cur_section, "msg_urgency", r->msg_urgency); | ||||
|                 r->fg = ini_get_string(cur_section, "foreground", r->fg); | ||||
|                 r->bg = ini_get_string(cur_section, "background", r->bg); | ||||
|                 r->bg = ini_get_string(cur_section, "highlight", r->highlight); | ||||
|                 r->fc = ini_get_string(cur_section, "frame_color", r->fc); | ||||
|                 r->format = ini_get_string(cur_section, "format", r->format); | ||||
|                 r->new_icon = ini_get_string(cur_section, "new_icon", r->new_icon); | ||||
|  | ||||
| @ -92,6 +92,11 @@ struct settings { | ||||
|         enum mouse_action *mouse_left_click; | ||||
|         enum mouse_action *mouse_middle_click; | ||||
|         enum mouse_action *mouse_right_click; | ||||
|         int progress_bar_height; | ||||
|         int progress_bar_min_width; | ||||
|         int progress_bar_max_width; | ||||
|         int progress_bar_frame_width; | ||||
|         bool no_progress_bar; | ||||
| }; | ||||
| 
 | ||||
| extern struct settings settings; | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 fwsmit
						fwsmit