21
21
#include "settings.h"
22
22
#include "utils.h"
23
23
#include "icon-lookup.h"
24
+ #include "menu.h"
24
25
25
26
struct colored_layout {
26
27
PangoLayout * l ;
@@ -233,6 +234,13 @@ static bool have_progress_bar(const struct colored_layout *cl)
233
234
!cl -> is_xmore );
234
235
}
235
236
237
+ static bool have_built_in_menu (const struct colored_layout * cl )
238
+ {
239
+ return (g_hash_table_size (cl -> n -> actions )> 0 &&
240
+ settings .built_in_menu == true &&
241
+ !cl -> is_xmore );
242
+ }
243
+
236
244
static void get_text_size (PangoLayout * l , int * w , int * h , double scale ) {
237
245
pango_layout_get_pixel_size (l , w , h );
238
246
// scale the size down, because it may be rendered at higher DPI
@@ -298,6 +306,7 @@ static struct dimensions calculate_notification_dimensions(struct colored_layout
298
306
int icon_width = cl -> icon ? get_icon_width (cl -> icon , scale ) + horizontal_padding : 0 ;
299
307
int icon_height = cl -> icon ? get_icon_height (cl -> icon , scale ) : 0 ;
300
308
int progress_bar_height = have_progress_bar (cl ) ? settings .progress_bar_height + settings .padding : 0 ;
309
+ int menu_height = have_built_in_menu (cl ) ? settings .menu_height + settings .padding : 0 ;
301
310
302
311
int vertical_padding ;
303
312
if (cl -> n -> hide_text ) {
@@ -318,6 +327,8 @@ static struct dimensions calculate_notification_dimensions(struct colored_layout
318
327
dim .h += progress_bar_height + settings .padding * 2 ;
319
328
dim .w = dim .text_width + icon_width + 2 * settings .h_padding ;
320
329
330
+ dim .h += menu_height + settings .padding * 2 ;
331
+
321
332
if (have_progress_bar (cl ))
322
333
dim .w = MAX (settings .progress_bar_min_width , dim .w );
323
334
@@ -442,6 +453,10 @@ static struct colored_layout *layout_from_notification(cairo_t *c, struct notifi
442
453
g_error_free (err );
443
454
}
444
455
456
+ if (have_built_in_menu (cl )) {
457
+ menu_init (n );
458
+ }
459
+
445
460
n -> first_render = false;
446
461
return cl ;
447
462
}
@@ -484,6 +499,7 @@ static int layout_get_height(struct colored_layout *cl, double scale)
484
499
int h_text = 0 ;
485
500
int h_icon = 0 ;
486
501
int h_progress_bar = 0 ;
502
+ int h_action_menu = 0 ;
487
503
488
504
int vertical_padding ;
489
505
if (cl -> n -> hide_text ) {
@@ -500,9 +516,13 @@ static int layout_get_height(struct colored_layout *cl, double scale)
500
516
h_progress_bar = settings .progress_bar_height + settings .padding ;
501
517
}
502
518
519
+ if (have_built_in_menu (cl )){
520
+ h_action_menu += settings .menu_height + settings .padding ;
521
+ }
522
+
503
523
return (cl -> n -> icon_position == ICON_TOP && cl -> n -> icon )
504
524
? h_icon + h_text + h_progress_bar + vertical_padding
505
- : MAX (h_text , h_icon ) + h_progress_bar ;
525
+ : MAX (h_text , h_icon ) + h_progress_bar + h_action_menu ;
506
526
}
507
527
508
528
/* Attempt to make internal radius more organic.
@@ -699,6 +719,58 @@ void draw_rounded_rect(cairo_t *c, float x, float y, int width, int height, int
699
719
cairo_close_path (c );
700
720
}
701
721
722
+ static void draw_built_in_menu (cairo_t * c ,
723
+ struct colored_layout * cl ,
724
+ int area_x ,
725
+ int area_y ,
726
+ int area_width ,
727
+ int area_height ,
728
+ double scale )
729
+ {
730
+ if (!have_built_in_menu (cl ))
731
+ return ;
732
+
733
+ int buttons = menu_get_count (cl -> n );
734
+ if (buttons == 0 ) {
735
+ return ;
736
+ }
737
+
738
+ int total_gap = settings .padding * (buttons + 1 );
739
+
740
+ int button_width = (area_width - total_gap ) / buttons ;
741
+ if (button_width < settings .menu_min_width ) {
742
+ button_width = settings .menu_min_width ;
743
+ }
744
+
745
+ for (int i = 0 ; i < buttons ; i ++ ) {
746
+ char * label = menu_get_label (cl -> n , i );
747
+ if (label == NULL )
748
+ continue ;
749
+ int x = area_x + settings .padding + i * (button_width + settings .padding );
750
+ int y = area_y ;
751
+
752
+ double r = settings .menu_frame_color .r ;
753
+ double g = settings .menu_frame_color .g ;
754
+ double b = settings .menu_frame_color .b ;
755
+
756
+ cairo_set_source_rgb (c , r ,g ,b );
757
+ draw_rect (c , x , y , button_width , settings .menu_height , scale );
758
+ cairo_fill (c );
759
+
760
+ cairo_set_source_rgba (c , COLOR (cl , fg .r ), COLOR (cl , fg .g ), COLOR (cl , fg .b ), COLOR (cl , fg .a ));
761
+
762
+ cairo_text_extents_t extents ;
763
+ cairo_text_extents (c , label , & extents );
764
+
765
+ double text_x = x + (button_width - extents .width ) / 2 ;
766
+ double text_y = y + (settings .menu_height + extents .height ) / 2 ;
767
+
768
+ cairo_move_to (c , round (text_x * scale ), round (text_y * scale ));
769
+ cairo_show_text (c , label );
770
+ menu_set_position (cl -> n , i , x , y , button_width , settings .menu_height );
771
+ }
772
+ }
773
+
702
774
static cairo_surface_t * render_background (cairo_surface_t * srf ,
703
775
struct colored_layout * cl ,
704
776
struct colored_layout * cl_next ,
@@ -784,10 +856,12 @@ static void render_content(cairo_t *c, struct colored_layout *cl, int width, int
784
856
layout_setup (cl , width , height , scale );
785
857
786
858
// NOTE: Includes paddings!
787
- int h_without_progress_bar = height ;
788
- if (have_progress_bar (cl )) {
789
- h_without_progress_bar -= settings .progress_bar_height + settings .padding ;
790
- }
859
+ int h_text_and_icon = height ;
860
+ if (have_progress_bar (cl ))
861
+ h_text_and_icon -= settings .progress_bar_height + settings .padding ;
862
+
863
+ if (have_built_in_menu (cl ))
864
+ h_text_and_icon -= settings .menu_height + settings .padding ;
791
865
792
866
int text_h = 0 ;
793
867
if (!cl -> n -> hide_text ) {
@@ -799,9 +873,9 @@ static void render_content(cairo_t *c, struct colored_layout *cl, int width, int
799
873
text_y = settings .padding ;
800
874
801
875
if (settings .vertical_alignment == VERTICAL_CENTER ) {
802
- text_y = h_without_progress_bar / 2 - text_h / 2 ;
876
+ text_y = h_text_and_icon / 2 - text_h / 2 ;
803
877
} else if (settings .vertical_alignment == VERTICAL_BOTTOM ) {
804
- text_y = h_without_progress_bar - settings .padding - text_h ;
878
+ text_y = h_text_and_icon - settings .padding - text_h ;
805
879
if (text_y < 0 ) text_y = settings .padding ;
806
880
} // else VERTICAL_TOP
807
881
@@ -867,7 +941,7 @@ static void render_content(cairo_t *c, struct colored_layout *cl, int width, int
867
941
unsigned int frame_width = settings .progress_bar_frame_width ,
868
942
progress_width = MIN (width - 2 * settings .h_padding , settings .progress_bar_max_width ),
869
943
progress_height = settings .progress_bar_height - frame_width ,
870
- frame_y = h_without_progress_bar ,
944
+ frame_y = h_text_and_icon ,
871
945
progress_width_without_frame = progress_width - 2 * frame_width ,
872
946
progress_width_1 = progress_width_without_frame * progress / 100 ,
873
947
progress_width_2 = progress_width_without_frame - 1 ;
@@ -922,6 +996,15 @@ static void render_content(cairo_t *c, struct colored_layout *cl, int width, int
922
996
scale , settings .progress_bar_corners );
923
997
cairo_stroke (c );
924
998
}
999
+
1000
+ if (have_built_in_menu (cl )) {
1001
+ int y = h_text_and_icon ;
1002
+ if (have_progress_bar (cl )) {
1003
+ y += settings .progress_bar_height + settings .padding ;
1004
+ }
1005
+ draw_built_in_menu (c , cl , 0 , y , width , height , scale );
1006
+ }
1007
+
925
1008
}
926
1009
927
1010
static struct dimensions layout_render (cairo_surface_t * srf ,
0 commit comments