2 * $Id: arrows.c,v 1.51 2013/09/02 15:10:09 tom Exp $
4 * arrows.c -- draw arrows to indicate end-of-range for lists
6 * Copyright 2000-2012,2013 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.
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
)
76 if (dialog_vars
.help_line
!= 0
77 && dialog_vars
.help_line
[0] != 0
78 && (bottom
= getmaxy(win
) - 1) > 0) {
79 chtype attr
= A_NORMAL
;
80 int cols
= dlg_count_columns(dialog_vars
.help_line
);
81 int other
= decorations
? (ON_LEFT
+ ON_RIGHT
) : 0;
82 int avail
= (getmaxx(win
) - other
- 2);
83 int limit
= dlg_count_real_columns(dialog_vars
.help_line
) + 2;
86 getyx(win
, cur_y
, cur_x
);
87 other
= decorations
? ON_LEFT
: 0;
88 (void) wmove(win
, bottom
, other
+ (avail
- limit
) / 2);
90 dlg_print_text(win
, dialog_vars
.help_line
, cols
, &attr
);
92 wmove(win
, cur_y
, cur_x
);
98 dlg_draw_arrows2(WINDOW
*win
,
107 chtype save
= dlg_get_attrs(win
);
109 int limit_x
= getmaxx(win
);
110 bool draw_top
= TRUE
;
111 bool is_toplevel
= (wgetparent(win
) == stdscr
);
113 getyx(win
, cur_y
, cur_x
);
116 * If we're drawing a centered title, do not overwrite with the arrows.
118 if (dialog_vars
.title
&& is_toplevel
&& (top
- getbegy(win
)) < MARGIN
) {
119 int have
= (limit_x
- dlg_count_columns(dialog_vars
.title
)) / 2;
126 (void) wmove(win
, top
, x
);
128 (void) wattrset(win
, merge_colors(uarrow_attr
, attr
));
129 (void) add_acs(win
, ACS_UARROW
);
130 (void) waddstr(win
, "(-)");
132 (void) wattrset(win
, attr
);
133 (void) whline(win
, dlg_boxchar(ACS_HLINE
), ON_LEFT
);
136 mouse_mkbutton(top
, x
- 1, 6, KEY_PPAGE
);
138 (void) wmove(win
, bottom
, x
);
140 (void) wattrset(win
, merge_colors(darrow_attr
, borderattr
));
141 (void) add_acs(win
, ACS_DARROW
);
142 (void) waddstr(win
, "(+)");
144 (void) wattrset(win
, borderattr
);
145 (void) whline(win
, dlg_boxchar(ACS_HLINE
), ON_LEFT
);
147 mouse_mkbutton(bottom
, x
- 1, 6, KEY_NPAGE
);
149 (void) wmove(win
, cur_y
, cur_x
);
152 (void) wattrset(win
, save
);
156 dlg_draw_scrollbar(WINDOW
*win
,
173 chtype save
= dlg_get_attrs(win
);
174 int top_arrow
= (first_data
!= 0);
175 int bottom_arrow
= (next_data
< total_data
);
177 getyx(win
, oldy
, oldx
);
179 dlg_draw_helpline(win
, TRUE
);
180 if (bottom_arrow
|| top_arrow
|| dialog_state
.use_scrollbar
) {
181 percent
= (!total_data
183 : (int) ((next_data
* 100)
188 else if (percent
> 100)
191 (void) wattrset(win
, position_indicator_attr
);
192 (void) sprintf(buffer
, "%d%%", percent
);
193 (void) wmove(win
, bottom
, right
- 7);
194 (void) waddstr(win
, buffer
);
195 if ((len
= dlg_count_columns(buffer
)) < 4) {
196 (void) wattrset(win
, border_attr
);
197 whline(win
, dlg_boxchar(ACS_HLINE
), 4 - len
);
200 #define BARSIZE(num) (int) (0.5 + (double) ((all_high * (int) (num)) / (double) total_data))
201 #define ORDSIZE(num) (int) ((double) ((all_high * (int) (num)) / (double) all_diff))
203 if (dialog_state
.use_scrollbar
) {
204 int all_high
= (bottom
- top
- 1);
206 this_data
= MAX(0, this_data
);
208 if (total_data
> 0 && all_high
> 0) {
209 int all_diff
= (int) (total_data
+ 1);
210 int bar_diff
= (int) (next_data
+ 1 - this_data
);
214 bar_high
= ORDSIZE(bar_diff
);
218 if (bar_high
< all_high
) {
219 int bar_last
= BARSIZE(next_data
);
221 wmove(win
, top
+ 1, right
);
223 (void) wattrset(win
, save
);
224 wvline(win
, ACS_VLINE
| A_REVERSE
, all_high
);
226 bar_y
= ORDSIZE(this_data
);
227 if (bar_y
>= bar_last
&& bar_y
> 0)
228 bar_y
= bar_last
- 1;
229 if (bar_last
- bar_y
> bar_high
&& bar_high
> 1)
231 bar_last
= MIN(bar_last
, all_high
);
233 wmove(win
, top
+ 1 + bar_y
, right
);
235 (void) wattrset(win
, position_indicator_attr
);
236 wattron(win
, A_REVERSE
);
237 #if defined(WACS_BLOCK) && defined(NCURSES_VERSION) && defined(USE_WIDE_CURSES)
238 wvline_set(win
, WACS_BLOCK
, bar_last
- bar_y
);
240 wvline(win
, ACS_BLOCK
, bar_last
- bar_y
);
245 dlg_draw_arrows2(win
,
254 (void) wattrset(win
, save
);
255 wmove(win
, oldy
, oldx
);
259 dlg_draw_arrows(WINDOW
*win
,
266 dlg_draw_helpline(win
, TRUE
);
267 dlg_draw_arrows2(win
,
273 menubox_border2_attr
,
274 menubox_border_attr
);