comparison src/popupwin.c @ 17045:7fe328ad5573 v8.1.1522

patch 8.1.1522: poup_notification() not implemented yet commit https://github.com/vim/vim/commit/68d48f40a4da79547b53e3164b658812e154d411 Author: Bram Moolenaar <Bram@vim.org> Date: Wed Jun 12 22:42:41 2019 +0200 patch 8.1.1522: poup_notification() not implemented yet Problem: Popup_notification() not implemented yet. Solution: Implement it.
author Bram Moolenaar <Bram@vim.org>
date Wed, 12 Jun 2019 22:45:07 +0200
parents 5ed4965ebc7b
children 6400d1ad5e4b
comparison
equal deleted inserted replaced
17044:687ec0a10570 17045:7fe328ad5573
108 static void 108 static void
109 get_padding_border(dict_T *dict, int *array, char *name, int max_val) 109 get_padding_border(dict_T *dict, int *array, char *name, int max_val)
110 { 110 {
111 dictitem_T *di; 111 dictitem_T *di;
112 112
113 vim_memset(array, 0, sizeof(int) * 4);
114 di = dict_find(dict, (char_u *)name, -1); 113 di = dict_find(dict, (char_u *)name, -1);
115 if (di != NULL) 114 if (di != NULL)
116 { 115 {
117 if (di->di_tv.v_type != VAR_LIST) 116 if (di->di_tv.v_type != VAR_LIST)
118 emsg(_(e_listreq)); 117 emsg(_(e_listreq));
163 wp->w_popup_mincol = (int)(ptr - ml_get_curline()); 162 wp->w_popup_mincol = (int)(ptr - ml_get_curline());
164 wp->w_popup_maxcol = wp->w_popup_mincol + len - 1; 163 wp->w_popup_maxcol = wp->w_popup_mincol + len - 1;
165 } 164 }
166 } 165 }
167 166
167
168 #if defined(FEAT_TIMERS)
169 static void
170 popup_add_timeout(win_T *wp, int time)
171 {
172 char_u cbbuf[50];
173 char_u *ptr = cbbuf;
174 typval_T tv;
175
176 vim_snprintf((char *)cbbuf, sizeof(cbbuf),
177 "{_ -> popup_close(%d)}", wp->w_id);
178 if (get_lambda_tv(&ptr, &tv, TRUE) == OK)
179 {
180 wp->w_popup_timer = create_timer(time, 0);
181 wp->w_popup_timer->tr_callback = get_callback(&tv);
182 clear_tv(&tv);
183 }
184 }
185 #endif
186
168 /* 187 /*
169 * Go through the options in "dict" and apply them to buffer "buf" displayed in 188 * Go through the options in "dict" and apply them to buffer "buf" displayed in
170 * popup window "wp". 189 * popup window "wp".
171 */ 190 */
172 static void 191 static void
182 wp->w_maxwidth = dict_get_number(dict, (char_u *)"maxwidth"); 201 wp->w_maxwidth = dict_get_number(dict, (char_u *)"maxwidth");
183 wp->w_maxheight = dict_get_number(dict, (char_u *)"maxheight"); 202 wp->w_maxheight = dict_get_number(dict, (char_u *)"maxheight");
184 203
185 get_pos_options(wp, dict); 204 get_pos_options(wp, dict);
186 205
187 wp->w_zindex = dict_get_number(dict, (char_u *)"zindex"); 206 di = dict_find(dict, (char_u *)"zindex", -1);
188 if (wp->w_zindex < 1) 207 if (di != NULL)
189 wp->w_zindex = POPUPWIN_DEFAULT_ZINDEX; 208 {
190 if (wp->w_zindex > 32000) 209 wp->w_zindex = dict_get_number(dict, (char_u *)"zindex");
191 wp->w_zindex = 32000; 210 if (wp->w_zindex < 1)
192 211 wp->w_zindex = POPUPWIN_DEFAULT_ZINDEX;
193 # if defined(FEAT_TIMERS) 212 if (wp->w_zindex > 32000)
213 wp->w_zindex = 32000;
214 }
215
216 #if defined(FEAT_TIMERS)
194 // Add timer to close the popup after some time. 217 // Add timer to close the popup after some time.
195 nr = dict_get_number(dict, (char_u *)"time"); 218 nr = dict_get_number(dict, (char_u *)"time");
196 if (nr > 0) 219 if (nr > 0)
197 { 220 popup_add_timeout(wp, nr);
198 char_u cbbuf[50]; 221 #endif
199 char_u *ptr = cbbuf;
200 typval_T tv;
201
202 vim_snprintf((char *)cbbuf, sizeof(cbbuf),
203 "{_ -> popup_close(%d)}", wp->w_id);
204 if (get_lambda_tv(&ptr, &tv, TRUE) == OK)
205 {
206 wp->w_popup_timer = create_timer(nr, 0);
207 wp->w_popup_timer->tr_callback = get_callback(&tv);
208 clear_tv(&tv);
209 }
210 }
211 # endif
212 222
213 // Option values resulting in setting an option. 223 // Option values resulting in setting an option.
214 str = dict_get_string(dict, (char_u *)"highlight", FALSE); 224 str = dict_get_string(dict, (char_u *)"highlight", FALSE);
215 if (str != NULL) 225 if (str != NULL)
216 set_string_option_direct_in_win(wp, (char_u *)"wincolor", -1, 226 set_string_option_direct_in_win(wp, (char_u *)"wincolor", -1,
599 } 609 }
600 610
601 typedef enum 611 typedef enum
602 { 612 {
603 TYPE_NORMAL, 613 TYPE_NORMAL,
604 TYPE_ATCURSOR 614 TYPE_ATCURSOR,
615 TYPE_NOTIFICATION
605 } create_type_T; 616 } create_type_T;
606 617
607 /* 618 /*
608 * popup_create({text}, {options}) 619 * popup_create({text}, {options})
609 * popup_atcursor({text}, {options}) 620 * popup_atcursor({text}, {options})
657 wp->w_p_wrap = TRUE; // 'wrap' is default on 668 wp->w_p_wrap = TRUE; // 'wrap' is default on
658 669
659 // Avoid that 'buftype' is reset when this buffer is entered. 670 // Avoid that 'buftype' is reset when this buffer is entered.
660 buf->b_p_initialized = TRUE; 671 buf->b_p_initialized = TRUE;
661 672
662 nr = (int)dict_get_number(d, (char_u *)"tab"); 673 if (dict_find(d, (char_u *)"tab", -1) != NULL)
674 nr = (int)dict_get_number(d, (char_u *)"tab");
675 else if (type == TYPE_NOTIFICATION)
676 nr = -1; // notifications are global by default
677 else
678 nr = 0;
679
663 if (nr == 0) 680 if (nr == 0)
664 { 681 {
665 // popup on current tab 682 // popup on current tab
666 wp->w_next = curtab->tp_first_popupwin; 683 wp->w_next = curtab->tp_first_popupwin;
667 curtab->tp_first_popupwin = wp; 684 curtab->tp_first_popupwin = wp;
668 } 685 }
669 else if (nr < 0) 686 else if (nr < 0)
670 { 687 {
671 // global popup 688 win_T *prev = first_popupwin;
672 wp->w_next = first_popupwin; 689
673 first_popupwin = wp; 690 // Global popup: add at the end, so that it gets displayed on top of
691 // older ones with the same zindex. Matters for notifications.
692 if (first_popupwin == NULL)
693 first_popupwin = wp;
694 else
695 {
696 while (prev->w_next != NULL)
697 prev = prev->w_next;
698 prev->w_next = wp;
699 }
674 } 700 }
675 else 701 else
676 // TODO: find tab page "nr" 702 // TODO: find tab page "nr"
677 emsg("Not implemented yet"); 703 emsg("Not implemented yet");
678 704
718 } 744 }
719 745
720 // set default values 746 // set default values
721 wp->w_zindex = POPUPWIN_DEFAULT_ZINDEX; 747 wp->w_zindex = POPUPWIN_DEFAULT_ZINDEX;
722 748
749 if (type == TYPE_NOTIFICATION)
750 {
751 win_T *twp, *nextwin;
752 int height = buf->b_ml.ml_line_count + 3;
753 int i;
754
755 // Try to not overlap with another global popup. Guess we need 3
756 // more screen lines than buffer lines.
757 wp->w_wantline = 1;
758 for (twp = first_popupwin; twp != NULL; twp = nextwin)
759 {
760 nextwin = twp->w_next;
761 if (twp != wp
762 && twp->w_zindex == POPUPWIN_NOTIFICATION_ZINDEX
763 && twp->w_winrow <= wp->w_wantline - 1 + height
764 && twp->w_winrow + popup_height(twp) > wp->w_wantline - 1)
765 {
766 // move to below this popup and restart the loop to check for
767 // overlap with other popups
768 wp->w_wantline = twp->w_winrow + popup_height(twp) + 1;
769 nextwin = first_popupwin;
770 }
771 }
772 if (wp->w_wantline + height > Rows)
773 {
774 // can't avoid overlap, put on top in the hope that message goes
775 // away soon.
776 wp->w_wantline = 1;
777 }
778
779 wp->w_wantcol = 10;
780 wp->w_zindex = POPUPWIN_NOTIFICATION_ZINDEX;
781 for (i = 0; i < 4; ++i)
782 wp->w_popup_border[i] = 1;
783 wp->w_popup_padding[1] = 1;
784 wp->w_popup_padding[3] = 1;
785 set_string_option_direct_in_win(wp, (char_u *)"wincolor", -1,
786 (char_u *)"WarningMsg", OPT_FREE|OPT_LOCAL, 0);
787 }
788
723 // Deal with options. 789 // Deal with options.
724 apply_options(wp, buf, argvars[1].vval.v_dict); 790 apply_options(wp, buf, argvars[1].vval.v_dict);
725 791
792 if (type == TYPE_NOTIFICATION && wp->w_popup_timer == NULL)
793 popup_add_timeout(wp, 3000);
794
726 popup_adjust_position(wp); 795 popup_adjust_position(wp);
727 796
728 wp->w_vsep_width = 0; 797 wp->w_vsep_width = 0;
729 798
730 redraw_all_later(NOT_VALID); 799 redraw_all_later(NOT_VALID);
754 */ 823 */
755 void 824 void
756 f_popup_atcursor(typval_T *argvars, typval_T *rettv) 825 f_popup_atcursor(typval_T *argvars, typval_T *rettv)
757 { 826 {
758 popup_create(argvars, rettv, TYPE_ATCURSOR); 827 popup_create(argvars, rettv, TYPE_ATCURSOR);
828 }
829
830 /*
831 * popup_notification({text}, {options})
832 */
833 void
834 f_popup_notification(typval_T *argvars, typval_T *rettv)
835 {
836 popup_create(argvars, rettv, TYPE_NOTIFICATION);
759 } 837 }
760 838
761 /* 839 /*
762 * Find the popup window with window-ID "id". 840 * Find the popup window with window-ID "id".
763 * If the popup window does not exist NULL is returned. 841 * If the popup window does not exist NULL is returned.
1015 1093
1016 dict = rettv->vval.v_dict; 1094 dict = rettv->vval.v_dict;
1017 1095
1018 dict_add_number(dict, "line", wp->w_winrow + 1); 1096 dict_add_number(dict, "line", wp->w_winrow + 1);
1019 dict_add_number(dict, "col", wp->w_wincol + 1); 1097 dict_add_number(dict, "col", wp->w_wincol + 1);
1020 dict_add_number(dict, "width", wp->w_width + left_extra + wp->w_popup_border[1] + wp->w_popup_padding[1]); 1098 dict_add_number(dict, "width", wp->w_width + left_extra
1021 dict_add_number(dict, "height", wp->w_height + top_extra + wp->w_popup_border[2] + wp->w_popup_padding[2]); 1099 + wp->w_popup_border[1] + wp->w_popup_padding[1]);
1100 dict_add_number(dict, "height", wp->w_height + top_extra
1101 + wp->w_popup_border[2] + wp->w_popup_padding[2]);
1022 1102
1023 dict_add_number(dict, "core_line", wp->w_winrow + 1 + top_extra); 1103 dict_add_number(dict, "core_line", wp->w_winrow + 1 + top_extra);
1024 dict_add_number(dict, "core_col", wp->w_wincol + 1 + left_extra); 1104 dict_add_number(dict, "core_col", wp->w_wincol + 1 + left_extra);
1025 dict_add_number(dict, "core_width", wp->w_width); 1105 dict_add_number(dict, "core_width", wp->w_width);
1026 dict_add_number(dict, "core_height", wp->w_height); 1106 dict_add_number(dict, "core_height", wp->w_height);