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