diff options
Diffstat (limited to 'swaynagbar/render.c')
-rw-r--r-- | swaynagbar/render.c | 160 |
1 files changed, 153 insertions, 7 deletions
diff --git a/swaynagbar/render.c b/swaynagbar/render.c index c0f59298..7bc2961e 100644 --- a/swaynagbar/render.c +++ b/swaynagbar/render.c | |||
@@ -23,11 +23,149 @@ static uint32_t render_message(cairo_t *cairo, struct sway_nagbar *nagbar) { | |||
23 | } | 23 | } |
24 | 24 | ||
25 | cairo_set_source_u32(cairo, nagbar->colors.text); | 25 | cairo_set_source_u32(cairo, nagbar->colors.text); |
26 | cairo_move_to(cairo, padding, (int)(height / 2.0 - text_height / 2.0)); | 26 | cairo_move_to(cairo, padding, (int)(ideal_height - text_height) / 2); |
27 | pango_printf(cairo, nagbar->font, nagbar->scale, true, "%s", | 27 | pango_printf(cairo, nagbar->font, nagbar->scale, true, "%s", |
28 | nagbar->message); | 28 | nagbar->message); |
29 | 29 | ||
30 | return nagbar->height; | 30 | return ideal_height; |
31 | } | ||
32 | |||
33 | static void render_details_scroll_button(cairo_t *cairo, | ||
34 | struct sway_nagbar *nagbar, struct sway_nagbar_button *button) { | ||
35 | int text_width, text_height; | ||
36 | get_text_size(cairo, nagbar->font, &text_width, &text_height, | ||
37 | nagbar->scale, true, "%s", button->text); | ||
38 | |||
39 | int border = NAGBAR_BUTTON_BORDER_THICKNESS * nagbar->scale; | ||
40 | int padding = NAGBAR_BUTTON_PADDING * nagbar->scale; | ||
41 | |||
42 | cairo_set_source_u32(cairo, nagbar->colors.border); | ||
43 | cairo_rectangle(cairo, button->x, button->y, | ||
44 | button->width, button->height); | ||
45 | cairo_fill(cairo); | ||
46 | |||
47 | cairo_set_source_u32(cairo, nagbar->colors.button_background); | ||
48 | cairo_rectangle(cairo, button->x + border, button->y + border, | ||
49 | button->width - (border * 2), button->height - (border * 2)); | ||
50 | cairo_fill(cairo); | ||
51 | |||
52 | cairo_set_source_u32(cairo, nagbar->colors.text); | ||
53 | cairo_move_to(cairo, button->x + border + padding, | ||
54 | button->y + border + (button->height - text_height) / 2); | ||
55 | pango_printf(cairo, nagbar->font, nagbar->scale, true, "%s", button->text); | ||
56 | } | ||
57 | |||
58 | static int get_detailed_scroll_button_width(cairo_t *cairo, | ||
59 | struct sway_nagbar *nagbar) { | ||
60 | int up_width, down_width, temp_height; | ||
61 | get_text_size(cairo, nagbar->font, &up_width, &temp_height, | ||
62 | nagbar->scale, true, "%s", nagbar->details.button_up.text); | ||
63 | get_text_size(cairo, nagbar->font, &down_width, &temp_height, | ||
64 | nagbar->scale, true, "%s", nagbar->details.button_down.text); | ||
65 | |||
66 | int text_width = up_width > down_width ? up_width : down_width; | ||
67 | int border = NAGBAR_BUTTON_BORDER_THICKNESS * nagbar->scale; | ||
68 | int padding = NAGBAR_BUTTON_PADDING * nagbar->scale; | ||
69 | |||
70 | return text_width + border * 2 + padding * 2; | ||
71 | } | ||
72 | |||
73 | static uint32_t render_detailed(cairo_t *cairo, struct sway_nagbar *nagbar, | ||
74 | uint32_t y) { | ||
75 | uint32_t width = nagbar->width * nagbar->scale; | ||
76 | uint32_t height = nagbar->height * nagbar->scale; | ||
77 | height -= NAGBAR_BAR_BORDER_THICKNESS * nagbar->scale; | ||
78 | |||
79 | int border = NAGBAR_DETAILS_BORDER_THICKNESS * nagbar->scale; | ||
80 | int padding = NAGBAR_MESSAGE_PADDING * nagbar->scale; | ||
81 | int decor = padding + border; | ||
82 | |||
83 | nagbar->details.x = decor; | ||
84 | nagbar->details.y = y + decor; | ||
85 | nagbar->details.width = width - decor * 2; | ||
86 | |||
87 | PangoLayout *layout = get_pango_layout(cairo, nagbar->font, | ||
88 | nagbar->details.message, nagbar->scale, true); | ||
89 | pango_layout_set_width(layout, | ||
90 | (nagbar->details.width - padding * 2) * PANGO_SCALE); | ||
91 | pango_layout_set_wrap(layout, PANGO_WRAP_WORD_CHAR); | ||
92 | pango_layout_set_single_paragraph_mode(layout, false); | ||
93 | pango_cairo_update_layout(cairo, layout); | ||
94 | nagbar->details.total_lines = pango_layout_get_line_count(layout); | ||
95 | |||
96 | PangoLayoutLine *line; | ||
97 | line = pango_layout_get_line_readonly(layout, nagbar->details.offset); | ||
98 | gint offset = line->start_index; | ||
99 | const char *text = pango_layout_get_text(layout); | ||
100 | pango_layout_set_text(layout, text + offset, strlen(text) - offset); | ||
101 | |||
102 | int text_width, text_height; | ||
103 | pango_cairo_update_layout(cairo, layout); | ||
104 | pango_layout_get_pixel_size(layout, &text_width, &text_height); | ||
105 | |||
106 | bool show_buttons = nagbar->details.offset > 0; | ||
107 | int button_width = get_detailed_scroll_button_width(cairo, nagbar); | ||
108 | if (show_buttons) { | ||
109 | nagbar->details.width -= button_width; | ||
110 | pango_layout_set_width(layout, | ||
111 | (nagbar->details.width - padding * 2) * PANGO_SCALE); | ||
112 | } | ||
113 | |||
114 | uint32_t ideal_height; | ||
115 | do { | ||
116 | ideal_height = nagbar->details.y + text_height + decor + padding * 2; | ||
117 | if (ideal_height > NAGBAR_MAX_HEIGHT) { | ||
118 | ideal_height = NAGBAR_MAX_HEIGHT; | ||
119 | |||
120 | if (!show_buttons) { | ||
121 | show_buttons = true; | ||
122 | nagbar->details.width -= button_width; | ||
123 | pango_layout_set_width(layout, | ||
124 | (nagbar->details.width - padding * 2) * PANGO_SCALE); | ||
125 | } | ||
126 | } | ||
127 | |||
128 | nagbar->details.height = ideal_height - nagbar->details.y - decor; | ||
129 | pango_layout_set_height(layout, | ||
130 | (nagbar->details.height - padding * 2) * PANGO_SCALE); | ||
131 | pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_END); | ||
132 | pango_cairo_update_layout(cairo, layout); | ||
133 | pango_layout_get_pixel_size(layout, &text_width, &text_height); | ||
134 | } while (text_height != (nagbar->details.height - padding * 2)); | ||
135 | |||
136 | nagbar->details.visible_lines = pango_layout_get_line_count(layout); | ||
137 | |||
138 | if (show_buttons) { | ||
139 | nagbar->details.button_up.x = | ||
140 | nagbar->details.x + nagbar->details.width; | ||
141 | nagbar->details.button_up.y = nagbar->details.y; | ||
142 | nagbar->details.button_up.width = button_width; | ||
143 | nagbar->details.button_up.height = nagbar->details.height / 2; | ||
144 | render_details_scroll_button(cairo, nagbar, | ||
145 | &nagbar->details.button_up); | ||
146 | |||
147 | nagbar->details.button_down.x = | ||
148 | nagbar->details.x + nagbar->details.width; | ||
149 | nagbar->details.button_down.y = | ||
150 | nagbar->details.button_up.y + nagbar->details.button_up.height; | ||
151 | nagbar->details.button_down.width = button_width; | ||
152 | nagbar->details.button_down.height = nagbar->details.height / 2; | ||
153 | render_details_scroll_button(cairo, nagbar, | ||
154 | &nagbar->details.button_down); | ||
155 | } | ||
156 | |||
157 | cairo_set_source_u32(cairo, nagbar->colors.border); | ||
158 | cairo_rectangle(cairo, nagbar->details.x, nagbar->details.y, | ||
159 | nagbar->details.width, nagbar->details.height); | ||
160 | cairo_fill(cairo); | ||
161 | |||
162 | cairo_move_to(cairo, nagbar->details.x + padding, | ||
163 | nagbar->details.y + padding); | ||
164 | cairo_set_source_u32(cairo, nagbar->colors.text); | ||
165 | pango_cairo_show_layout(cairo, layout); | ||
166 | g_object_unref(layout); | ||
167 | |||
168 | return ideal_height; | ||
31 | } | 169 | } |
32 | 170 | ||
33 | static uint32_t render_button(cairo_t *cairo, struct sway_nagbar *nagbar, | 171 | static uint32_t render_button(cairo_t *cairo, struct sway_nagbar *nagbar, |
@@ -50,7 +188,7 @@ static uint32_t render_button(cairo_t *cairo, struct sway_nagbar *nagbar, | |||
50 | } | 188 | } |
51 | 189 | ||
52 | button->x = *x - border - text_width - padding * 2; | 190 | button->x = *x - border - text_width - padding * 2; |
53 | button->y = (int)(height / 2.0 - text_height / 2.0) - padding; | 191 | button->y = (int)(ideal_height - text_height) / 2 - padding; |
54 | button->width = text_width + padding * 2; | 192 | button->width = text_width + padding * 2; |
55 | button->height = text_height + padding * 2; | 193 | button->height = text_height + padding * 2; |
56 | 194 | ||
@@ -70,7 +208,7 @@ static uint32_t render_button(cairo_t *cairo, struct sway_nagbar *nagbar, | |||
70 | 208 | ||
71 | *x = button->x - border; | 209 | *x = button->x - border; |
72 | 210 | ||
73 | return nagbar->height; | 211 | return ideal_height; |
74 | } | 212 | } |
75 | 213 | ||
76 | static uint32_t render_to_cairo(cairo_t *cairo, struct sway_nagbar *nagbar) { | 214 | static uint32_t render_to_cairo(cairo_t *cairo, struct sway_nagbar *nagbar) { |
@@ -93,6 +231,11 @@ static uint32_t render_to_cairo(cairo_t *cairo, struct sway_nagbar *nagbar) { | |||
93 | } | 231 | } |
94 | } | 232 | } |
95 | 233 | ||
234 | if (nagbar->details.visible) { | ||
235 | h = render_detailed(cairo, nagbar, max_height); | ||
236 | max_height = h > max_height ? h : max_height; | ||
237 | } | ||
238 | |||
96 | int border = NAGBAR_BAR_BORDER_THICKNESS * nagbar->scale; | 239 | int border = NAGBAR_BAR_BORDER_THICKNESS * nagbar->scale; |
97 | if (max_height > nagbar->height) { | 240 | if (max_height > nagbar->height) { |
98 | max_height += border; | 241 | max_height += border; |
@@ -102,7 +245,7 @@ static uint32_t render_to_cairo(cairo_t *cairo, struct sway_nagbar *nagbar) { | |||
102 | nagbar->width * nagbar->scale, border); | 245 | nagbar->width * nagbar->scale, border); |
103 | cairo_fill(cairo); | 246 | cairo_fill(cairo); |
104 | 247 | ||
105 | return max_height > nagbar->height ? max_height : nagbar->height; | 248 | return max_height; |
106 | } | 249 | } |
107 | 250 | ||
108 | void render_frame(struct sway_nagbar *nagbar) { | 251 | void render_frame(struct sway_nagbar *nagbar) { |
@@ -129,13 +272,16 @@ void render_frame(struct sway_nagbar *nagbar) { | |||
129 | nagbar->buffers, | 272 | nagbar->buffers, |
130 | nagbar->width * nagbar->scale, | 273 | nagbar->width * nagbar->scale, |
131 | nagbar->height * nagbar->scale); | 274 | nagbar->height * nagbar->scale); |
132 | cairo_t *shm = nagbar->current_buffer->cairo; | 275 | if (!nagbar->current_buffer) { |
276 | wlr_log(WLR_DEBUG, "Failed to get buffer. Skipping frame."); | ||
277 | return; | ||
278 | } | ||
133 | 279 | ||
280 | cairo_t *shm = nagbar->current_buffer->cairo; | ||
134 | cairo_save(shm); | 281 | cairo_save(shm); |
135 | cairo_set_operator(shm, CAIRO_OPERATOR_CLEAR); | 282 | cairo_set_operator(shm, CAIRO_OPERATOR_CLEAR); |
136 | cairo_paint(shm); | 283 | cairo_paint(shm); |
137 | cairo_restore(shm); | 284 | cairo_restore(shm); |
138 | |||
139 | cairo_set_source_surface(shm, recorder, 0.0, 0.0); | 285 | cairo_set_source_surface(shm, recorder, 0.0, 0.0); |
140 | cairo_paint(shm); | 286 | cairo_paint(shm); |
141 | 287 | ||