1 /* 2 * $Id: arrows.c,v 1.33 2011/01/19 00:27:53 tom Exp $ 3 * 4 * arrows.c -- draw arrows to indicate end-of-range for lists 5 * 6 * Copyright 2000-2010,2011 Thomas E. Dickey 7 * 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. 11 * 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. 16 * 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. 22 */ 23 24 #include <dialog.h> 25 26 #ifdef USE_WIDE_CURSES 27 #if defined(CURSES_WACS_ARRAY) && !defined(CURSES_WACS_SYMBOLS) 28 /* workaround for NetBSD 5.1 curses */ 29 #undef WACS_DARROW 30 #undef WACS_UARROW 31 #define WACS_DARROW &(CURSES_WACS_ARRAY['.']) 32 #define WACS_UARROW &(CURSES_WACS_ARRAY['-']) 33 #endif 34 #define add_acs(win, code) wadd_wch(win, W ## code) 35 #else 36 #define add_acs(win, code) waddch(win, dlg_boxchar(code)) 37 #endif 38 39 #ifdef HAVE_COLOR 40 static chtype 41 merge_colors(chtype foreground, chtype background) 42 { 43 chtype result = foreground; 44 if ((foreground & A_COLOR) != (background & A_COLOR)) { 45 short fg_f, bg_f; 46 short fg_b, bg_b; 47 short fg_pair = (short) PAIR_NUMBER(foreground); 48 short bg_pair = (short) PAIR_NUMBER(background); 49 50 if (pair_content(fg_pair, &fg_f, &bg_f) != ERR 51 && pair_content(bg_pair, &fg_b, &bg_b) != ERR) { 52 result &= ~A_COLOR; 53 result |= dlg_color_pair(fg_f, bg_b); 54 } 55 } 56 return result; 57 } 58 #else 59 #define merge_colors(f,b) (f) 60 #endif 61 62 void 63 dlg_draw_arrows2(WINDOW *win, 64 int top_arrow, 65 int bottom_arrow, 66 int x, 67 int top, 68 int bottom, 69 chtype attr, 70 chtype borderattr) 71 { 72 chtype save = dlg_get_attrs(win); 73 int cur_x, cur_y; 74 int limit_x = getmaxx(win); 75 bool draw_top = TRUE; 76 77 getyx(win, cur_y, cur_x); 78 79 /* 80 * If we're drawing a centered title, do not overwrite with the arrows. 81 */ 82 if (dialog_vars.title) { 83 int have = (limit_x - dlg_count_columns(dialog_vars.title)) / 2; 84 int need = x + 5; 85 if (need > have) 86 draw_top = FALSE; 87 } 88 89 if (draw_top) { 90 (void) wmove(win, top, x); 91 if (top_arrow) { 92 wattrset(win, merge_colors(uarrow_attr, attr)); 93 (void) add_acs(win, ACS_UARROW); 94 (void) waddstr(win, "(-)"); 95 } else { 96 wattrset(win, attr); 97 (void) whline(win, dlg_boxchar(ACS_HLINE), 4); 98 } 99 } 100 mouse_mkbutton(top, x - 1, 6, KEY_PPAGE); 101 102 (void) wmove(win, bottom, x); 103 if (bottom_arrow) { 104 wattrset(win, merge_colors(darrow_attr, attr)); 105 (void) add_acs(win, ACS_DARROW); 106 (void) waddstr(win, "(+)"); 107 } else { 108 wattrset(win, borderattr); 109 (void) whline(win, dlg_boxchar(ACS_HLINE), 4); 110 } 111 mouse_mkbutton(bottom, x - 1, 6, KEY_NPAGE); 112 113 (void) wmove(win, cur_y, cur_x); 114 wrefresh(win); 115 116 wattrset(win, save); 117 } 118 119 void 120 dlg_draw_scrollbar(WINDOW *win, 121 long first_data, 122 long this_data, 123 long next_data, 124 long total_data, 125 int left, 126 int right, 127 int top, 128 int bottom, 129 chtype attr, 130 chtype borderattr) 131 { 132 char buffer[80]; 133 int percent; 134 int len; 135 int oldy, oldx, maxy, maxx; 136 137 chtype save = dlg_get_attrs(win); 138 int top_arrow = (first_data != 0); 139 int bottom_arrow = (next_data < total_data); 140 141 getyx(win, oldy, oldx); 142 getmaxyx(win, maxy, maxx); 143 144 if (bottom_arrow || top_arrow || dialog_state.use_scrollbar) { 145 percent = (!total_data 146 ? 100 147 : (int) ((next_data * 100) 148 / total_data)); 149 150 if (percent < 0) 151 percent = 0; 152 else if (percent > 100) 153 percent = 100; 154 155 wattrset(win, position_indicator_attr); 156 (void) sprintf(buffer, "%d%%", percent); 157 (void) wmove(win, bottom, right - 7); 158 (void) waddstr(win, buffer); 159 if ((len = dlg_count_columns(buffer)) < 4) { 160 wattrset(win, border_attr); 161 whline(win, dlg_boxchar(ACS_HLINE), 4 - len); 162 } 163 } 164 #define BARSIZE(num) (int) (((all_high * (num)) + all_high - 1) / total_data) 165 166 if (dialog_state.use_scrollbar) { 167 int all_high = (bottom - top - 1); 168 169 if (total_data > 0 && all_high > 0) { 170 int bar_high; 171 int bar_y; 172 173 bar_high = BARSIZE(next_data - this_data); 174 if (bar_high <= 0) 175 bar_high = 1; 176 177 if (bar_high < all_high) { 178 wmove(win, top + 1, right); 179 180 wattrset(win, save); 181 wvline(win, ACS_VLINE | A_REVERSE, all_high); 182 183 bar_y = BARSIZE(this_data); 184 if (bar_y > all_high - bar_high) 185 bar_y = all_high - bar_high; 186 187 wmove(win, top + 1 + bar_y, right); 188 189 wattrset(win, position_indicator_attr); 190 wattron(win, A_REVERSE); 191 wvline(win, ACS_BLOCK, bar_high); 192 } 193 } 194 } 195 dlg_draw_arrows2(win, 196 top_arrow, 197 bottom_arrow, 198 left + ARROWS_COL, 199 top, 200 bottom, 201 attr, 202 borderattr); 203 204 wattrset(win, save); 205 wmove(win, oldy, oldx); 206 } 207 208 void 209 dlg_draw_arrows(WINDOW *win, 210 int top_arrow, 211 int bottom_arrow, 212 int x, 213 int top, 214 int bottom) 215 { 216 dlg_draw_arrows2(win, 217 top_arrow, 218 bottom_arrow, 219 x, 220 top, 221 bottom, 222 menubox_attr, 223 menubox_border_attr); 224 } 225