Mercurial > vim
comparison src/popupwin.c @ 17235:2a97167854fc v8.1.1617
patch 8.1.1617: no test for popup window with mask and position fixed
commit https://github.com/vim/vim/commit/d529ba58dc7566833546e4beb5c4c50d8b78816a
Author: Bram Moolenaar <Bram@vim.org>
Date: Tue Jul 2 23:13:53 2019 +0200
patch 8.1.1617: no test for popup window with mask and position fixed
Problem: No test for popup window with mask and position fixed.
Solution: Add a couple of screenshots. Fix deteced problems.
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Tue, 02 Jul 2019 23:15:06 +0200 |
parents | e9ebf3f27af6 |
children | 3ada3d207b33 |
comparison
equal
deleted
inserted
replaced
17234:7f61c9065eea | 17235:2a97167854fc |
---|---|
698 } | 698 } |
699 } | 699 } |
700 } | 700 } |
701 | 701 |
702 /* | 702 /* |
703 * Return the height of popup window "wp", including border and padding. | |
704 */ | |
705 int | |
706 popup_height(win_T *wp) | |
707 { | |
708 return wp->w_height | |
709 + wp->w_popup_padding[0] + wp->w_popup_border[0] | |
710 + wp->w_popup_padding[2] + wp->w_popup_border[2]; | |
711 } | |
712 | |
713 /* | |
714 * Return the width of popup window "wp", including border and padding. | |
715 */ | |
716 int | |
717 popup_width(win_T *wp) | |
718 { | |
719 return wp->w_width | |
720 + wp->w_popup_padding[3] + wp->w_popup_border[3] | |
721 + wp->w_popup_padding[1] + wp->w_popup_border[1] | |
722 + wp->w_has_scrollbar; | |
723 } | |
724 | |
725 /* | |
726 * Get the padding plus border at the top, adjusted to 1 if there is a title. | 703 * Get the padding plus border at the top, adjusted to 1 if there is a title. |
727 */ | 704 */ |
728 static int | 705 static int |
729 popup_top_extra(win_T *wp) | 706 popup_top_extra(win_T *wp) |
730 { | 707 { |
734 return 1; | 711 return 1; |
735 return extra; | 712 return extra; |
736 } | 713 } |
737 | 714 |
738 /* | 715 /* |
716 * Return the height of popup window "wp", including border and padding. | |
717 */ | |
718 int | |
719 popup_height(win_T *wp) | |
720 { | |
721 return wp->w_height | |
722 + popup_top_extra(wp) | |
723 + wp->w_popup_padding[2] + wp->w_popup_border[2]; | |
724 } | |
725 | |
726 /* | |
727 * Return the width of popup window "wp", including border, padding and | |
728 * scrollbar. | |
729 */ | |
730 int | |
731 popup_width(win_T *wp) | |
732 { | |
733 return wp->w_width + wp->w_leftcol | |
734 + wp->w_popup_padding[3] + wp->w_popup_border[3] | |
735 + wp->w_popup_padding[1] + wp->w_popup_border[1] | |
736 + wp->w_has_scrollbar | |
737 + wp->w_popup_rightoff; | |
738 } | |
739 | |
740 /* | |
739 * Adjust the position and size of the popup to fit on the screen. | 741 * Adjust the position and size of the popup to fit on the screen. |
740 */ | 742 */ |
741 void | 743 void |
742 popup_adjust_position(win_T *wp) | 744 popup_adjust_position(win_T *wp) |
743 { | 745 { |
744 linenr_T lnum; | 746 linenr_T lnum; |
745 int wrapped = 0; | 747 int wrapped = 0; |
746 int maxwidth; | 748 int maxwidth; |
749 int maxspace; | |
747 int center_vert = FALSE; | 750 int center_vert = FALSE; |
748 int center_hor = FALSE; | 751 int center_hor = FALSE; |
749 int allow_adjust_left = !wp->w_popup_fixed; | 752 int allow_adjust_left = !wp->w_popup_fixed; |
750 int top_extra = popup_top_extra(wp); | 753 int top_extra = popup_top_extra(wp); |
751 int right_extra = wp->w_popup_border[1] + wp->w_popup_padding[1]; | 754 int right_extra = wp->w_popup_border[1] + wp->w_popup_padding[1]; |
756 int org_winrow = wp->w_winrow; | 759 int org_winrow = wp->w_winrow; |
757 int org_wincol = wp->w_wincol; | 760 int org_wincol = wp->w_wincol; |
758 int org_width = wp->w_width; | 761 int org_width = wp->w_width; |
759 int org_height = wp->w_height; | 762 int org_height = wp->w_height; |
760 int org_leftcol = wp->w_leftcol; | 763 int org_leftcol = wp->w_leftcol; |
764 int org_leftoff = wp->w_popup_leftoff; | |
761 int minwidth; | 765 int minwidth; |
762 | 766 |
763 wp->w_winrow = 0; | 767 wp->w_winrow = 0; |
764 wp->w_wincol = 0; | 768 wp->w_wincol = 0; |
765 wp->w_leftcol = 0; | 769 wp->w_leftcol = 0; |
770 wp->w_popup_leftoff = 0; | |
771 wp->w_popup_rightoff = 0; | |
766 if (wp->w_popup_pos == POPPOS_CENTER) | 772 if (wp->w_popup_pos == POPPOS_CENTER) |
767 { | 773 { |
768 // center after computing the size | 774 // center after computing the size |
769 center_vert = TRUE; | 775 center_vert = TRUE; |
770 center_hor = TRUE; | 776 center_hor = TRUE; |
793 } | 799 } |
794 | 800 |
795 // When centering or right aligned, use maximum width. | 801 // When centering or right aligned, use maximum width. |
796 // When left aligned use the space available, but shift to the left when we | 802 // When left aligned use the space available, but shift to the left when we |
797 // hit the right of the screen. | 803 // hit the right of the screen. |
798 maxwidth = Columns - wp->w_wincol - left_extra; | 804 maxspace = Columns - wp->w_wincol - left_extra; |
805 maxwidth = maxspace; | |
799 if (wp->w_maxwidth > 0 && maxwidth > wp->w_maxwidth) | 806 if (wp->w_maxwidth > 0 && maxwidth > wp->w_maxwidth) |
800 { | 807 { |
801 allow_adjust_left = FALSE; | 808 allow_adjust_left = FALSE; |
802 maxwidth = wp->w_maxwidth; | 809 maxwidth = wp->w_maxwidth; |
803 } | 810 } |
866 } | 873 } |
867 | 874 |
868 if (minwidth > 0 && wp->w_width < minwidth) | 875 if (minwidth > 0 && wp->w_width < minwidth) |
869 wp->w_width = minwidth; | 876 wp->w_width = minwidth; |
870 if (wp->w_width > maxwidth) | 877 if (wp->w_width > maxwidth) |
878 { | |
879 if (wp->w_width > maxspace) | |
880 // some columns cut off on the right | |
881 wp->w_popup_rightoff = wp->w_width - maxspace; | |
871 wp->w_width = maxwidth; | 882 wp->w_width = maxwidth; |
883 } | |
872 if (center_hor) | 884 if (center_hor) |
873 { | 885 { |
874 wp->w_wincol = (Columns - wp->w_width - extra_width) / 2; | 886 wp->w_wincol = (Columns - wp->w_width - extra_width) / 2; |
875 if (wp->w_wincol < 0) | 887 if (wp->w_wincol < 0) |
876 wp->w_wincol = 0; | 888 wp->w_wincol = 0; |
885 if (leftoff >= 0) | 897 if (leftoff >= 0) |
886 wp->w_wincol = leftoff; | 898 wp->w_wincol = leftoff; |
887 else if (wp->w_popup_fixed) | 899 else if (wp->w_popup_fixed) |
888 { | 900 { |
889 // "col" specifies the right edge, but popup doesn't fit, skip some | 901 // "col" specifies the right edge, but popup doesn't fit, skip some |
890 // columns when displaying the window. | 902 // columns when displaying the window, minus left border and |
891 wp->w_leftcol = -leftoff; | 903 // padding. |
892 wp->w_width += leftoff; | 904 if (-leftoff > left_extra) |
905 wp->w_leftcol = -leftoff - left_extra; | |
906 wp->w_width -= wp->w_leftcol; | |
907 wp->w_popup_leftoff = -leftoff; | |
893 if (wp->w_width < 0) | 908 if (wp->w_width < 0) |
894 wp->w_width = 0; | 909 wp->w_width = 0; |
895 } | 910 } |
896 } | 911 } |
897 | 912 |
926 // Need to update popup_mask if the position or size changed. | 941 // Need to update popup_mask if the position or size changed. |
927 // And redraw windows that were behind the popup. | 942 // And redraw windows that were behind the popup. |
928 if (org_winrow != wp->w_winrow | 943 if (org_winrow != wp->w_winrow |
929 || org_wincol != wp->w_wincol | 944 || org_wincol != wp->w_wincol |
930 || org_leftcol != wp->w_leftcol | 945 || org_leftcol != wp->w_leftcol |
946 || org_leftoff != wp->w_popup_leftoff | |
931 || org_width != wp->w_width | 947 || org_width != wp->w_width |
932 || org_height != wp->w_height) | 948 || org_height != wp->w_height) |
933 { | 949 { |
934 redraw_all_later(VALID); | 950 redraw_all_later(VALID); |
935 popup_mask_refresh = TRUE; | 951 popup_mask_refresh = TRUE; |
2064 * "col" and "line" are screen coordinates. | 2080 * "col" and "line" are screen coordinates. |
2065 */ | 2081 */ |
2066 static int | 2082 static int |
2067 popup_masked(win_T *wp, int screencol, int screenline) | 2083 popup_masked(win_T *wp, int screencol, int screenline) |
2068 { | 2084 { |
2069 int col = screencol - wp->w_wincol + 1 + wp->w_leftcol; | 2085 int col = screencol - wp->w_wincol + 1 + wp->w_popup_leftoff; |
2070 int line = screenline - wp->w_winrow + 1; | 2086 int line = screenline - wp->w_winrow + 1; |
2071 listitem_T *lio, *li; | 2087 listitem_T *lio, *li; |
2072 int width, height; | 2088 int width, height; |
2073 | 2089 |
2074 if (wp->w_popup_mask == NULL) | 2090 if (wp->w_popup_mask == NULL) |
2143 linee = tv_get_number(&li->li_tv); | 2159 linee = tv_get_number(&li->li_tv); |
2144 if (linee < 0) | 2160 if (linee < 0) |
2145 linee = height + linee + 1; | 2161 linee = height + linee + 1; |
2146 | 2162 |
2147 --cols; | 2163 --cols; |
2148 cols -= wp->w_leftcol; | 2164 cols -= wp->w_popup_leftoff; |
2149 if (cols < 0) | 2165 if (cols < 0) |
2150 cols = 0; | 2166 cols = 0; |
2151 cole -= wp->w_leftcol; | 2167 cole -= wp->w_popup_leftoff; |
2152 --lines; | 2168 --lines; |
2153 if (lines < 0) | 2169 if (lines < 0) |
2154 lines = 0; | 2170 lines = 0; |
2155 for (line = lines; line < linee && line < screen_Rows; ++line) | 2171 for (line = lines; line < linee && line < screen_Rows; ++line) |
2156 for (col = cols; col < cole && col < screen_Columns; ++col) | 2172 for (col = cols; col < cole && col < screen_Columns; ++col) |
2213 // so that the window with a higher zindex overwrites the value in | 2229 // so that the window with a higher zindex overwrites the value in |
2214 // popup_mask. | 2230 // popup_mask. |
2215 popup_reset_handled(); | 2231 popup_reset_handled(); |
2216 while ((wp = find_next_popup(TRUE)) != NULL) | 2232 while ((wp = find_next_popup(TRUE)) != NULL) |
2217 { | 2233 { |
2218 int height = popup_height(wp); | 2234 int height; |
2219 int width = popup_width(wp); | 2235 int width; |
2220 | 2236 |
2221 popup_visible = TRUE; | 2237 popup_visible = TRUE; |
2222 | 2238 |
2223 // Recompute the position if the text changed. | 2239 // Recompute the position if the text changed. |
2224 if (redraw_all | 2240 if (redraw_all |
2225 || wp->w_popup_last_changedtick != CHANGEDTICK(wp->w_buffer)) | 2241 || wp->w_popup_last_changedtick != CHANGEDTICK(wp->w_buffer)) |
2226 popup_adjust_position(wp); | 2242 popup_adjust_position(wp); |
2227 | 2243 |
2244 height = popup_height(wp); | |
2245 width = popup_width(wp) - wp->w_popup_leftoff; | |
2228 for (line = wp->w_winrow; | 2246 for (line = wp->w_winrow; |
2229 line < wp->w_winrow + height && line < screen_Rows; ++line) | 2247 line < wp->w_winrow + height && line < screen_Rows; ++line) |
2230 for (col = wp->w_wincol; | 2248 for (col = wp->w_wincol; |
2231 col < wp->w_wincol + width && col < screen_Columns; ++col) | 2249 col < wp->w_wincol + width && col < screen_Columns; ++col) |
2232 if (!popup_masked(wp, col, line)) | 2250 if (!popup_masked(wp, col, line)) |
2308 void | 2326 void |
2309 update_popups(void (*win_update)(win_T *wp)) | 2327 update_popups(void (*win_update)(win_T *wp)) |
2310 { | 2328 { |
2311 win_T *wp; | 2329 win_T *wp; |
2312 int top_off; | 2330 int top_off; |
2313 int left_off; | 2331 int left_extra; |
2314 int total_width; | 2332 int total_width; |
2315 int total_height; | 2333 int total_height; |
2316 int top_padding; | 2334 int top_padding; |
2317 int popup_attr; | 2335 int popup_attr; |
2318 int border_attr[4]; | 2336 int border_attr[4]; |
2319 int border_char[8]; | 2337 int border_char[8]; |
2320 char_u buf[MB_MAXBYTES]; | 2338 char_u buf[MB_MAXBYTES]; |
2321 int row; | 2339 int row; |
2340 int padcol = 0; | |
2341 int padwidth = 0; | |
2322 int i; | 2342 int i; |
2323 int sb_thumb_top = 0; | 2343 int sb_thumb_top = 0; |
2324 int sb_thumb_height = 0; | 2344 int sb_thumb_height = 0; |
2325 int attr_scroll = 0; | 2345 int attr_scroll = 0; |
2326 int attr_thumb = 0; | 2346 int attr_thumb = 0; |
2340 update_popup_transparent(wp, 1); | 2360 update_popup_transparent(wp, 1); |
2341 | 2361 |
2342 // adjust w_winrow and w_wincol for border and padding, since | 2362 // adjust w_winrow and w_wincol for border and padding, since |
2343 // win_update() doesn't handle them. | 2363 // win_update() doesn't handle them. |
2344 top_off = popup_top_extra(wp); | 2364 top_off = popup_top_extra(wp); |
2345 left_off = wp->w_popup_padding[3] + wp->w_popup_border[3]; | 2365 left_extra = wp->w_popup_padding[3] + wp->w_popup_border[3] |
2366 - wp->w_popup_leftoff; | |
2367 if (wp->w_wincol + left_extra < 0) | |
2368 left_extra = -wp->w_wincol; | |
2346 wp->w_winrow += top_off; | 2369 wp->w_winrow += top_off; |
2347 wp->w_wincol += left_off; | 2370 wp->w_wincol += left_extra; |
2348 | 2371 |
2349 // Draw the popup text, unless it's off screen. | 2372 // Draw the popup text, unless it's off screen. |
2350 if (wp->w_winrow < screen_Rows && wp->w_wincol < screen_Columns) | 2373 if (wp->w_winrow < screen_Rows && wp->w_wincol < screen_Columns) |
2351 win_update(wp); | 2374 win_update(wp); |
2352 | 2375 |
2353 wp->w_winrow -= top_off; | 2376 wp->w_winrow -= top_off; |
2354 wp->w_wincol -= left_off; | 2377 wp->w_wincol -= left_extra; |
2355 | 2378 |
2356 total_width = wp->w_popup_border[3] + wp->w_popup_padding[3] | 2379 total_width = popup_width(wp); |
2357 + wp->w_width + wp->w_popup_padding[1] + wp->w_popup_border[1] | 2380 total_height = popup_height(wp); |
2358 + wp->w_has_scrollbar; | |
2359 total_height = popup_top_extra(wp) | |
2360 + wp->w_height + wp->w_popup_padding[2] + wp->w_popup_border[2]; | |
2361 popup_attr = get_wcr_attr(wp); | 2381 popup_attr = get_wcr_attr(wp); |
2362 | 2382 |
2363 // We can only use these line drawing characters when 'encoding' is | 2383 // We can only use these line drawing characters when 'encoding' is |
2364 // "utf-8" and 'ambiwidth' is "single". | 2384 // "utf-8" and 'ambiwidth' is "single". |
2365 if (enc_utf8 && *p_ambw == 's') | 2385 if (enc_utf8 && *p_ambw == 's') |
2407 } | 2427 } |
2408 } | 2428 } |
2409 else if (wp->w_popup_padding[0] == 0 && popup_top_extra(wp) > 0) | 2429 else if (wp->w_popup_padding[0] == 0 && popup_top_extra(wp) > 0) |
2410 top_padding = 1; | 2430 top_padding = 1; |
2411 | 2431 |
2432 if (top_padding > 0 || wp->w_popup_padding[2] > 0) | |
2433 { | |
2434 padcol = wp->w_wincol - wp->w_popup_leftoff + wp->w_popup_border[3]; | |
2435 padwidth = wp->w_wincol + total_width - wp->w_popup_border[1] | |
2436 - wp->w_has_scrollbar; | |
2437 if (padcol < 0) | |
2438 { | |
2439 padwidth += padcol; | |
2440 padcol = 0; | |
2441 } | |
2442 } | |
2412 if (top_padding > 0) | 2443 if (top_padding > 0) |
2413 { | 2444 { |
2414 // top padding | 2445 // top padding |
2415 row = wp->w_winrow + wp->w_popup_border[0]; | 2446 row = wp->w_winrow + wp->w_popup_border[0]; |
2416 screen_fill(row, row + top_padding, | 2447 screen_fill(row, row + top_padding, padcol, padwidth, |
2417 wp->w_wincol + wp->w_popup_border[3], | |
2418 wp->w_wincol + total_width - wp->w_popup_border[1] | |
2419 - wp->w_has_scrollbar, | |
2420 ' ', ' ', popup_attr); | 2448 ' ', ' ', popup_attr); |
2421 } | 2449 } |
2422 | 2450 |
2423 // Title goes on top of border or padding. | 2451 // Title goes on top of border or padding. |
2424 if (wp->w_popup_title != NULL) | 2452 if (wp->w_popup_title != NULL) |
2448 } | 2476 } |
2449 | 2477 |
2450 for (i = wp->w_popup_border[0]; | 2478 for (i = wp->w_popup_border[0]; |
2451 i < total_height - wp->w_popup_border[2]; ++i) | 2479 i < total_height - wp->w_popup_border[2]; ++i) |
2452 { | 2480 { |
2481 int pad_left; | |
2482 int col = wp->w_wincol - wp->w_popup_leftoff; | |
2483 // left and right padding only needed next to the body | |
2484 int do_padding = | |
2485 i >= wp->w_popup_border[0] + wp->w_popup_padding[0] | |
2486 && i < total_height - wp->w_popup_border[2] | |
2487 - wp->w_popup_padding[2]; | |
2488 | |
2453 row = wp->w_winrow + i; | 2489 row = wp->w_winrow + i; |
2454 | 2490 |
2455 // left border | 2491 // left border |
2456 if (wp->w_popup_border[3] > 0) | 2492 if (wp->w_popup_border[3] > 0 && col >= 0) |
2457 { | 2493 { |
2458 buf[mb_char2bytes(border_char[3], buf)] = NUL; | 2494 buf[mb_char2bytes(border_char[3], buf)] = NUL; |
2459 screen_puts(buf, row, wp->w_wincol, border_attr[3]); | 2495 screen_puts(buf, row, col, border_attr[3]); |
2460 } | 2496 } |
2461 // left padding | 2497 if (do_padding && wp->w_popup_padding[3] > 0) |
2462 if (wp->w_popup_padding[3] > 0) | 2498 { |
2463 screen_puts(get_spaces(wp->w_popup_padding[3]), row, | 2499 // left padding |
2464 wp->w_wincol + wp->w_popup_border[3], popup_attr); | 2500 col += wp->w_popup_border[3]; |
2501 pad_left = wp->w_popup_padding[3]; | |
2502 if (col < 0) | |
2503 { | |
2504 pad_left += col; | |
2505 col = 0; | |
2506 } | |
2507 if (pad_left > 0) | |
2508 screen_puts(get_spaces(pad_left), row, col, popup_attr); | |
2509 } | |
2465 // scrollbar | 2510 // scrollbar |
2466 if (wp->w_has_scrollbar) | 2511 if (wp->w_has_scrollbar) |
2467 { | 2512 { |
2468 int line = i - top_off; | 2513 int line = i - top_off; |
2469 int scroll_col = wp->w_wincol + total_width - 1 | 2514 int scroll_col = wp->w_wincol + total_width - 1 |
2483 buf[mb_char2bytes(border_char[1], buf)] = NUL; | 2528 buf[mb_char2bytes(border_char[1], buf)] = NUL; |
2484 screen_puts(buf, row, | 2529 screen_puts(buf, row, |
2485 wp->w_wincol + total_width - 1, border_attr[1]); | 2530 wp->w_wincol + total_width - 1, border_attr[1]); |
2486 } | 2531 } |
2487 // right padding | 2532 // right padding |
2488 if (wp->w_popup_padding[1] > 0) | 2533 if (do_padding && wp->w_popup_padding[1] > 0) |
2489 screen_puts(get_spaces(wp->w_popup_padding[1]), row, | 2534 screen_puts(get_spaces(wp->w_popup_padding[1]), row, |
2490 wp->w_wincol + wp->w_popup_border[3] | 2535 wp->w_wincol - wp->w_popup_leftoff |
2491 + wp->w_popup_padding[3] + wp->w_width, popup_attr); | 2536 + wp->w_popup_border[3] |
2537 + wp->w_popup_padding[3] + wp->w_width + wp->w_leftcol, | |
2538 popup_attr); | |
2492 } | 2539 } |
2493 | 2540 |
2494 if (wp->w_popup_padding[2] > 0) | 2541 if (wp->w_popup_padding[2] > 0) |
2495 { | 2542 { |
2496 // bottom padding | 2543 // bottom padding |
2497 row = wp->w_winrow + wp->w_popup_border[0] | 2544 row = wp->w_winrow + wp->w_popup_border[0] |
2498 + wp->w_popup_padding[0] + wp->w_height; | 2545 + wp->w_popup_padding[0] + wp->w_height; |
2499 screen_fill(row, row + wp->w_popup_padding[2], | 2546 screen_fill(row, row + wp->w_popup_padding[2], |
2500 wp->w_wincol + wp->w_popup_border[3], | 2547 padcol, padwidth, ' ', ' ', popup_attr); |
2501 wp->w_wincol + total_width - wp->w_popup_border[1], | |
2502 ' ', ' ', popup_attr); | |
2503 } | 2548 } |
2504 | 2549 |
2505 if (wp->w_popup_border[2] > 0) | 2550 if (wp->w_popup_border[2] > 0) |
2506 { | 2551 { |
2507 // bottom border | 2552 // bottom border |