2 * $Id: arrows.c,v 1.54 2022/04/03 22:38:16 tom Exp $
4 * arrows.c -- draw arrows to indicate end-of-range for lists
6 * Copyright 2000-2019,2022 Thomas E. Dickey
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU Lesser General Public License, version 2.1
10 * as published by the Free Software Foundation.
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this program; if not, write to
19 * Free Software Foundation, Inc.
20 * 51 Franklin St., Fifth Floor
21 * Boston, MA 02110, USA.
24 #include <dlg_internals.h>
26 #ifdef USE_WIDE_CURSES
27 #if defined(CURSES_WACS_ARRAY) && !defined(CURSES_WACS_SYMBOLS)
28 /* workaround for NetBSD 5.1 curses */
31 #define WACS_DARROW &(CURSES_WACS_ARRAY['.'])
32 #define WACS_UARROW &(CURSES_WACS_ARRAY['-'])
34 #define add_acs(win, code) wadd_wch(win, W ## code)
36 #define add_acs(win, code) waddch(win, dlg_boxchar(code))
39 /* size of decorations */
45 merge_colors(chtype foreground
, chtype background
)
47 chtype result
= foreground
;
48 if ((foreground
& A_COLOR
) != (background
& A_COLOR
)) {
51 short fg_pair
= (short) PAIR_NUMBER(foreground
);
52 short bg_pair
= (short) PAIR_NUMBER(background
);
54 if (pair_content(fg_pair
, &fg_f
, &bg_f
) != ERR
55 && pair_content(bg_pair
, &fg_b
, &bg_b
) != ERR
) {
57 result
|= dlg_color_pair(fg_f
, bg_b
);
63 #define merge_colors(f,b) (f)
67 * If we have help-line text, e.g., from "--hline", draw it between the other
68 * decorations at the bottom of the dialog window.
71 dlg_draw_helpline(WINDOW
*win
, bool decorations
)
75 if (dialog_vars
.help_line
!= 0
76 && dialog_vars
.help_line
[0] != 0
77 && (bottom
= getmaxy(win
) - 1) > 0) {
78 chtype attr
= A_NORMAL
;
79 int cols
= dlg_count_columns(dialog_vars
.help_line
);
80 int other
= decorations
? (ON_LEFT
+ ON_RIGHT
) : 0;
81 int avail
= (getmaxx(win
) - other
- 2);
82 int limit
= dlg_count_real_columns(dialog_vars
.help_line
) + 2;
87 getyx(win
, cur_y
, cur_x
);
88 other
= decorations
? ON_LEFT
: 0;
89 (void) wmove(win
, bottom
, other
+ (avail
- limit
) / 2);
91 dlg_print_text(win
, dialog_vars
.help_line
, cols
, &attr
);
93 wmove(win
, cur_y
, cur_x
);
99 dlg_draw_arrows2(WINDOW
*win
,
108 chtype save
= dlg_get_attrs(win
);
110 int limit_x
= getmaxx(win
);
111 bool draw_top
= TRUE
;
112 bool is_toplevel
= (wgetparent(win
) == stdscr
);
114 getyx(win
, cur_y
, cur_x
);
117 * If we're drawing a centered title, do not overwrite with the arrows.
119 if (dialog_vars
.title
&& is_toplevel
&& (top
- getbegy(win
)) < MARGIN
) {
120 int have
= (limit_x
- dlg_count_columns(dialog_vars
.title
)) / 2;
127 (void) wmove(win
, top
, x
);
129 dlg_attrset(win
, merge_colors(uarrow_attr
, attr
));
130 (void) add_acs(win
, ACS_UARROW
);
131 (void) waddstr(win
, "(-)");
133 dlg_attrset(win
, attr
);
134 (void) whline(win
, dlg_boxchar(ACS_HLINE
), ON_LEFT
);
137 mouse_mkbutton(top
, x
- 1, 6, KEY_PPAGE
);
139 (void) wmove(win
, bottom
, x
);
141 dlg_attrset(win
, merge_colors(darrow_attr
, borderattr
));
142 (void) add_acs(win
, ACS_DARROW
);
143 (void) waddstr(win
, "(+)");
145 dlg_attrset(win
, borderattr
);
146 (void) whline(win
, dlg_boxchar(ACS_HLINE
), ON_LEFT
);
148 mouse_mkbutton(bottom
, x
- 1, 6, KEY_NPAGE
);
150 (void) wmove(win
, cur_y
, cur_x
);
153 dlg_attrset(win
, save
);
157 dlg_draw_scrollbar(WINDOW
*win
,
171 chtype save
= dlg_get_attrs(win
);
172 int top_arrow
= (first_data
!= 0);
173 int bottom_arrow
= (next_data
< total_data
);
175 getyx(win
, oldy
, oldx
);
177 dlg_draw_helpline(win
, TRUE
);
178 if (bottom_arrow
|| top_arrow
|| dialog_state
.use_scrollbar
) {
183 percent
= (!total_data
185 : (int) ((next_data
* 100)
190 else if (percent
> 100)
193 dlg_attrset(win
, position_indicator_attr
);
194 (void) sprintf(buffer
, "%d%%", percent
);
195 (void) wmove(win
, bottom
, right
- 7);
196 (void) waddstr(win
, buffer
);
197 if ((len
= dlg_count_columns(buffer
)) < 4) {
198 dlg_attrset(win
, border_attr
);
199 whline(win
, dlg_boxchar(ACS_HLINE
), 4 - len
);
202 #define BARSIZE(num) (int) (0.5 + (double) ((all_high * (int) (num)) / (double) total_data))
203 #define ORDSIZE(num) (int) ((double) ((all_high * (int) (num)) / (double) all_diff))
205 if (dialog_state
.use_scrollbar
) {
206 int all_high
= (bottom
- top
- 1);
208 this_data
= MAX(0, this_data
);
210 if (total_data
> 0 && all_high
> 0) {
211 int all_diff
= (int) (total_data
+ 1);
212 int bar_diff
= (int) (next_data
+ 1 - this_data
);
215 bar_high
= ORDSIZE(bar_diff
);
219 if (bar_high
< all_high
) {
220 int bar_last
= BARSIZE(next_data
);
223 wmove(win
, top
+ 1, right
);
225 dlg_attrset(win
, save
);
226 wvline(win
, ACS_VLINE
| A_REVERSE
, all_high
);
228 bar_y
= ORDSIZE(this_data
);
229 if (bar_y
>= bar_last
&& bar_y
> 0)
230 bar_y
= bar_last
- 1;
231 if (bar_last
- bar_y
> bar_high
&& bar_high
> 1)
233 bar_last
= MIN(bar_last
, all_high
);
235 wmove(win
, top
+ 1 + bar_y
, right
);
237 dlg_attrset(win
, position_indicator_attr
);
238 dlg_attron(win
, A_REVERSE
);
239 #if defined(WACS_BLOCK) && defined(NCURSES_VERSION) && defined(USE_WIDE_CURSES)
240 wvline_set(win
, WACS_BLOCK
, bar_last
- bar_y
);
242 wvline(win
, ACS_BLOCK
, bar_last
- bar_y
);
247 dlg_draw_arrows2(win
,
256 dlg_attrset(win
, save
);
257 wmove(win
, oldy
, oldx
);
261 dlg_draw_arrows(WINDOW
*win
,
268 dlg_draw_helpline(win
, TRUE
);
269 dlg_draw_arrows2(win
,
275 menubox_border2_attr
,
276 menubox_border_attr
);