0
0
mirror of https://github.com/vim/vim.git synced 2025-10-12 06:44:06 -04:00

patch 8.1.1443: popup window padding and border not implemented yet

Problem:    Popup window padding and border not implemented yet.
Solution:   Implement padding and border.  Add core position and size to
            popup_getpos().
This commit is contained in:
Bram Moolenaar
2019-06-01 20:16:48 +02:00
parent 8caaf82569
commit 2fd8e35e16
7 changed files with 254 additions and 33 deletions

View File

@@ -101,6 +101,38 @@ get_pos_options(win_T *wp, dict_T *dict)
}
}
static void
get_padding_border(dict_T *dict, int *array, char *name, int max_val)
{
dictitem_T *di;
vim_memset(array, 0, sizeof(int) * 4);
di = dict_find(dict, (char_u *)name, -1);
if (di != NULL)
{
if (di->di_tv.v_type != VAR_LIST)
emsg(_(e_listreq));
else
{
list_T *list = di->di_tv.vval.v_list;
listitem_T *li;
int i;
int nr;
for (i = 0; i < 4; ++i)
array[i] = 1;
if (list != NULL)
for (i = 0, li = list->lv_first; i < 4 && i < list->lv_len;
++i, li = li->li_next)
{
nr = (int)tv_get_number(&li->li_tv);
if (nr >= 0)
array[i] = nr > max_val ? max_val : nr;
}
}
}
}
/*
* Go through the options in "dict" and apply them to buffer "buf" displayed in
* popup window "wp".
@@ -176,6 +208,9 @@ apply_options(win_T *wp, buf_T *buf UNUSED, dict_T *dict, int atcursor)
if (callback.cb_name != NULL)
set_callback(&wp->w_filter_cb, &callback);
}
get_padding_border(dict, wp->w_popup_padding, "padding", 999);
get_padding_border(dict, wp->w_popup_border, "border", 1);
}
/*
@@ -700,16 +735,28 @@ f_popup_getpos(typval_T *argvars, typval_T *rettv)
dict_T *dict;
int id = (int)tv_get_number(argvars);
win_T *wp = find_popup_win(id);
int top_extra;
int left_extra;
if (rettv_dict_alloc(rettv) == OK)
{
if (wp == NULL)
return; // invalid {id}
top_extra = wp->w_popup_border[0] + wp->w_popup_padding[0];
left_extra = wp->w_popup_border[3] + wp->w_popup_padding[3];
dict = rettv->vval.v_dict;
dict_add_number(dict, "line", wp->w_winrow + 1);
dict_add_number(dict, "col", wp->w_wincol + 1);
dict_add_number(dict, "width", wp->w_width);
dict_add_number(dict, "height", wp->w_height);
dict_add_number(dict, "width", wp->w_width + left_extra + wp->w_popup_border[1] + wp->w_popup_padding[1]);
dict_add_number(dict, "height", wp->w_height + top_extra + wp->w_popup_border[2] + wp->w_popup_padding[2]);
dict_add_number(dict, "core_line", wp->w_winrow + 1 + top_extra);
dict_add_number(dict, "core_col", wp->w_wincol + 1 + left_extra);
dict_add_number(dict, "core_width", wp->w_width);
dict_add_number(dict, "core_height", wp->w_height);
dict_add_number(dict, "visible",
(wp->w_popup_flags & POPF_HIDDEN) == 0);
}

View File

@@ -991,28 +991,6 @@ update_debug_sign(buf_T *buf, linenr_T lnum)
}
#endif
#ifdef FEAT_TEXT_PROP
static void
update_popups(void)
{
win_T *wp;
// Find the window with the lowest zindex that hasn't been updated yet,
// so that the window with a higher zindex is drawn later, thus goes on
// top.
// TODO: don't redraw every popup every time.
popup_reset_handled();
while ((wp = find_next_popup(TRUE)) != NULL)
{
// Recompute the position if the text changed.
if (wp->w_popup_last_changedtick != CHANGEDTICK(wp->w_buffer))
popup_adjust_position(wp);
win_update(wp);
}
}
#endif
/*
* Get 'wincolor' attribute for window "wp". If not set and "wp" is a popup
* window then get the "Pmenu" highlight attribute.
@@ -1031,6 +1009,132 @@ get_wcr_attr(win_T *wp)
return wcr_attr;
}
#ifdef FEAT_TEXT_PROP
/*
* Return a string of "len" spaces in IObuff.
*/
static char_u *
get_spaces(int len)
{
vim_memset(IObuff, ' ', (size_t)len);
IObuff[len] = NUL;
return IObuff;
}
static void
update_popups(void)
{
win_T *wp;
int top_off;
int left_off;
int total_width;
int total_height;
int popup_attr;
int row;
// Find the window with the lowest zindex that hasn't been updated yet,
// so that the window with a higher zindex is drawn later, thus goes on
// top.
// TODO: don't redraw every popup every time.
popup_reset_handled();
while ((wp = find_next_popup(TRUE)) != NULL)
{
// Recompute the position if the text changed.
if (wp->w_popup_last_changedtick != CHANGEDTICK(wp->w_buffer))
popup_adjust_position(wp);
// adjust w_winrow and w_wincol for border and padding, since
// win_update() doesn't handle them.
top_off = wp->w_popup_padding[0] + wp->w_popup_border[0];
left_off = wp->w_popup_padding[3] + wp->w_popup_border[3];
wp->w_winrow += top_off;
wp->w_wincol += left_off;
// Draw the popup text.
win_update(wp);
wp->w_winrow -= top_off;
wp->w_wincol -= left_off;
total_width = wp->w_popup_border[3] + wp->w_popup_padding[3]
+ wp->w_width + wp->w_popup_padding[1] + wp->w_popup_border[1];
total_height = wp->w_popup_border[0] + wp->w_popup_padding[0]
+ wp->w_height + wp->w_popup_padding[2] + wp->w_popup_border[2];
popup_attr = get_wcr_attr(wp);
if (wp->w_popup_border[0] > 0)
{
// top border
screen_fill(wp->w_winrow, wp->w_winrow + 1,
wp->w_wincol,
wp->w_wincol + total_width,
wp->w_popup_border[3] != 0 ? '+' : '-',
'-', popup_attr);
if (wp->w_popup_border[1] > 0)
screen_puts((char_u *)"+", wp->w_winrow,
wp->w_wincol + total_width - 1, popup_attr);
}
if (wp->w_popup_padding[0] > 0)
{
// top padding
row = wp->w_winrow + wp->w_popup_border[0];
screen_fill(row, row + wp->w_popup_padding[0],
wp->w_wincol + wp->w_popup_border[3],
wp->w_wincol + total_width - wp->w_popup_border[1],
' ', ' ', popup_attr);
}
for (row = wp->w_winrow + wp->w_popup_border[0];
row < wp->w_winrow + total_height - wp->w_popup_border[2];
++row)
{
// left border
if (wp->w_popup_border[3] > 0)
screen_puts((char_u *)"|", row, wp->w_wincol, popup_attr);
// left padding
if (wp->w_popup_padding[3] > 0)
screen_puts(get_spaces(wp->w_popup_padding[3]), row,
wp->w_wincol + wp->w_popup_border[3], popup_attr);
// right border
if (wp->w_popup_border[1] > 0)
screen_puts((char_u *)"|", row,
wp->w_wincol + total_width - 1, popup_attr);
// right padding
if (wp->w_popup_padding[1] > 0)
screen_puts(get_spaces(wp->w_popup_padding[1]), row,
wp->w_wincol + wp->w_popup_border[3]
+ wp->w_popup_padding[3] + wp->w_width, popup_attr);
}
if (wp->w_popup_padding[2] > 0)
{
// bottom padding
row = wp->w_winrow + wp->w_popup_border[0]
+ wp->w_popup_padding[0] + wp->w_height;
screen_fill(row, row + wp->w_popup_padding[2],
wp->w_wincol + wp->w_popup_border[3],
wp->w_wincol + total_width - wp->w_popup_border[1],
' ', ' ', popup_attr);
}
if (wp->w_popup_border[2] > 0)
{
// bottom border
row = wp->w_winrow + total_height - 1;
screen_fill(row , row + 1,
wp->w_wincol,
wp->w_wincol + total_width,
wp->w_popup_border[3] != 0 ? '+' : '-',
'-', popup_attr);
if (wp->w_popup_border[1] > 0)
screen_puts((char_u *)"+", row,
wp->w_wincol + total_width - 1, popup_attr);
}
}
}
#endif
#if defined(FEAT_GUI) || defined(PROTO)
/*
* Update a single window, its status line and maybe the command line msg.

View File

@@ -2888,6 +2888,8 @@ struct window_S
int w_maxwidth; // "maxwidth" for popup window
int w_wantline; // "line" for popup window
int w_wantcol; // "col" for popup window
int w_popup_padding[4]; // popup padding top/right/bot/left
int w_popup_border[4]; // popup border top/right/bot/left
varnumber_T w_popup_last_changedtick; // b:changedtick when position was
// computed
callback_T w_filter_cb; // popup filter callback

View File

@@ -0,0 +1,15 @@
>1+0&#ffffff0| @73
|2| |++0#0000001#ffd7ff255|-@11|+| +0#0000000#ffffff0@5| +0#0000001#ffd7ff255@14| +0#0000000#ffffff0@4|++0#0000001#ffd7ff255|-@11|+| +0#0000000#ffffff0@18
|3| ||+0#0000001#ffd7ff255|h|e|l@1|o| |b|o|r|d|e|r||| +0#0000000#ffffff0@5| +0#0000001#ffd7ff255|h|e|l@1|o| |p|a|d@1|i|n|g| | +0#0000000#ffffff0@4||+0#0000001#ffd7ff255| @11||| +0#0000000#ffffff0@18
|4| |++0#0000001#ffd7ff255|-@11|+| +0#0000000#ffffff0@5| +0#0000001#ffd7ff255@14| +0#0000000#ffffff0@4||+0#0000001#ffd7ff255| |h|e|l@1|o| |b|o|t|h| ||| +0#0000000#ffffff0@18
|5| @40||+0#0000001#ffd7ff255| @11||| +0#0000000#ffffff0@18
|6| |++0#0000001#ffd7ff255|-@8| +0#0000000#ffffff0@9| +0#0000001#ffd7ff255@14| +0#0000000#ffffff0@4|++0#0000001#ffd7ff255|-@11|+| +0#0000000#ffffff0@18
|7| ||+0#0000001#ffd7ff255|b|o|r|d|e|r| |T|L| +0#0000000#ffffff0@9| +0#0000001#ffd7ff255@3|p|a|d@1|i|n|g|s| @2| +0#0000000#ffffff0@37
|8| @20| +0#0000001#ffd7ff255@14| +0#0000000#ffffff0@37
|9| @20| +0#0000001#ffd7ff255@14| +0#0000000#ffffff0@37
|1|0| @72
|1@1| @72
|1|2| @72
|1|3| @72
|1|4| @72
@57|1|,|1| @10|T|o|p|

View File

@@ -56,6 +56,54 @@ func Test_simple_popup()
call delete('XtestPopup')
endfunc
func Test_popup_with_border_and_padding()
if !CanRunVimInTerminal()
return
endif
call writefile([
\ "call setline(1, range(1, 100))",
\ "call popup_create('hello border', {'line': 2, 'col': 3, 'border': []})",
\ "call popup_create('hello padding', {'line': 2, 'col': 23, 'padding': []})",
\ "call popup_create('hello both', {'line': 2, 'col': 43, 'border': [], 'padding': []})",
\ "call popup_create('border TL', {'line': 6, 'col': 3, 'border': [1, 0, 0, 4]})",
\ "call popup_create('paddings', {'line': 6, 'col': 23, 'padding': [1, 3, 2, 4]})",
\], 'XtestPopupBorder')
let buf = RunVimInTerminal('-S XtestPopupBorder', {'rows': 15})
call VerifyScreenDump(buf, 'Test_popupwin_20', {})
" clean up
call StopVimInTerminal(buf)
call delete('XtestPopupBorder')
let with_border_or_padding = {
\ 'line': 2,
\ 'core_line': 3,
\ 'col': 3,
\ 'core_col': 4,
\ 'width': 14,
\ 'core_width': 12,
\ 'height': 3,
\ 'core_height': 1,
\ 'visible': 1}
let winid = popup_create('hello border', {'line': 2, 'col': 3, 'border': []})",
call assert_equal(with_border_or_padding, popup_getpos(winid))
let winid = popup_create('hello paddng', {'line': 2, 'col': 3, 'padding': []})
call assert_equal(with_border_or_padding, popup_getpos(winid))
let winid = popup_create('hello both', {'line': 3, 'col': 8, 'border': [], 'padding': []})
call assert_equal({
\ 'line': 3,
\ 'core_line': 5,
\ 'col': 8,
\ 'core_col': 10,
\ 'width': 14,
\ 'core_width': 10,
\ 'height': 5,
\ 'core_height': 1,
\ 'visible': 1}, popup_getpos(winid))
endfunc
func Test_popup_with_syntax_win_execute()
if !CanRunVimInTerminal()
return

View File

@@ -767,6 +767,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
1443,
/**/
1442,
/**/