1217309Snwhitehorn/* 2255852Sdteske * $Id: arrows.c,v 1.51 2013/09/02 15:10:09 tom Exp $ 3217309Snwhitehorn * 4217309Snwhitehorn * arrows.c -- draw arrows to indicate end-of-range for lists 5217309Snwhitehorn * 6251843Sbapt * Copyright 2000-2012,2013 Thomas E. Dickey 7217309Snwhitehorn * 8217309Snwhitehorn * This program is free software; you can redistribute it and/or modify 9217309Snwhitehorn * it under the terms of the GNU Lesser General Public License, version 2.1 10217309Snwhitehorn * as published by the Free Software Foundation. 11217309Snwhitehorn * 12217309Snwhitehorn * This program is distributed in the hope that it will be useful, but 13217309Snwhitehorn * WITHOUT ANY WARRANTY; without even the implied warranty of 14217309Snwhitehorn * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15217309Snwhitehorn * Lesser General Public License for more details. 16217309Snwhitehorn * 17217309Snwhitehorn * You should have received a copy of the GNU Lesser General Public 18217309Snwhitehorn * License along with this program; if not, write to 19217309Snwhitehorn * Free Software Foundation, Inc. 20217309Snwhitehorn * 51 Franklin St., Fifth Floor 21217309Snwhitehorn * Boston, MA 02110, USA. 22217309Snwhitehorn */ 23217309Snwhitehorn 24217309Snwhitehorn#include <dialog.h> 25217309Snwhitehorn 26217309Snwhitehorn#ifdef USE_WIDE_CURSES 27220749Snwhitehorn#if defined(CURSES_WACS_ARRAY) && !defined(CURSES_WACS_SYMBOLS) 28220749Snwhitehorn/* workaround for NetBSD 5.1 curses */ 29220749Snwhitehorn#undef WACS_DARROW 30220749Snwhitehorn#undef WACS_UARROW 31220749Snwhitehorn#define WACS_DARROW &(CURSES_WACS_ARRAY['.']) 32220749Snwhitehorn#define WACS_UARROW &(CURSES_WACS_ARRAY['-']) 33220749Snwhitehorn#endif 34217309Snwhitehorn#define add_acs(win, code) wadd_wch(win, W ## code) 35217309Snwhitehorn#else 36217309Snwhitehorn#define add_acs(win, code) waddch(win, dlg_boxchar(code)) 37217309Snwhitehorn#endif 38217309Snwhitehorn 39224014Snwhitehorn/* size of decorations */ 40224014Snwhitehorn#define ON_LEFT 4 41224014Snwhitehorn#define ON_RIGHT 3 42224014Snwhitehorn 43217309Snwhitehorn#ifdef HAVE_COLOR 44217309Snwhitehornstatic chtype 45217309Snwhitehornmerge_colors(chtype foreground, chtype background) 46217309Snwhitehorn{ 47217309Snwhitehorn chtype result = foreground; 48217309Snwhitehorn if ((foreground & A_COLOR) != (background & A_COLOR)) { 49217309Snwhitehorn short fg_f, bg_f; 50217309Snwhitehorn short fg_b, bg_b; 51217309Snwhitehorn short fg_pair = (short) PAIR_NUMBER(foreground); 52217309Snwhitehorn short bg_pair = (short) PAIR_NUMBER(background); 53217309Snwhitehorn 54217309Snwhitehorn if (pair_content(fg_pair, &fg_f, &bg_f) != ERR 55217309Snwhitehorn && pair_content(bg_pair, &fg_b, &bg_b) != ERR) { 56217309Snwhitehorn result &= ~A_COLOR; 57217309Snwhitehorn result |= dlg_color_pair(fg_f, bg_b); 58217309Snwhitehorn } 59217309Snwhitehorn } 60217309Snwhitehorn return result; 61217309Snwhitehorn} 62217309Snwhitehorn#else 63217309Snwhitehorn#define merge_colors(f,b) (f) 64217309Snwhitehorn#endif 65217309Snwhitehorn 66224014Snwhitehorn/* 67224014Snwhitehorn * If we have help-line text, e.g., from "--hline", draw it between the other 68224014Snwhitehorn * decorations at the bottom of the dialog window. 69224014Snwhitehorn */ 70217309Snwhitehornvoid 71224014Snwhitehorndlg_draw_helpline(WINDOW *win, bool decorations) 72224014Snwhitehorn{ 73224014Snwhitehorn int cur_x, cur_y; 74224014Snwhitehorn int bottom; 75224014Snwhitehorn 76224014Snwhitehorn if (dialog_vars.help_line != 0 77255852Sdteske && dialog_vars.help_line[0] != 0 78224014Snwhitehorn && (bottom = getmaxy(win) - 1) > 0) { 79224014Snwhitehorn chtype attr = A_NORMAL; 80255852Sdteske int cols = dlg_count_columns(dialog_vars.help_line); 81224014Snwhitehorn int other = decorations ? (ON_LEFT + ON_RIGHT) : 0; 82224014Snwhitehorn int avail = (getmaxx(win) - other - 2); 83251843Sbapt int limit = dlg_count_real_columns(dialog_vars.help_line) + 2; 84224014Snwhitehorn 85251843Sbapt if (limit < avail) { 86224014Snwhitehorn getyx(win, cur_y, cur_x); 87224014Snwhitehorn other = decorations ? ON_LEFT : 0; 88224014Snwhitehorn (void) wmove(win, bottom, other + (avail - limit) / 2); 89224014Snwhitehorn waddch(win, '['); 90255852Sdteske dlg_print_text(win, dialog_vars.help_line, cols, &attr); 91224014Snwhitehorn waddch(win, ']'); 92224014Snwhitehorn wmove(win, cur_y, cur_x); 93224014Snwhitehorn } 94224014Snwhitehorn } 95224014Snwhitehorn} 96224014Snwhitehorn 97224014Snwhitehornvoid 98217309Snwhitehorndlg_draw_arrows2(WINDOW *win, 99217309Snwhitehorn int top_arrow, 100217309Snwhitehorn int bottom_arrow, 101217309Snwhitehorn int x, 102217309Snwhitehorn int top, 103217309Snwhitehorn int bottom, 104217309Snwhitehorn chtype attr, 105217309Snwhitehorn chtype borderattr) 106217309Snwhitehorn{ 107220749Snwhitehorn chtype save = dlg_get_attrs(win); 108217309Snwhitehorn int cur_x, cur_y; 109217309Snwhitehorn int limit_x = getmaxx(win); 110217309Snwhitehorn bool draw_top = TRUE; 111251843Sbapt bool is_toplevel = (wgetparent(win) == stdscr); 112217309Snwhitehorn 113217309Snwhitehorn getyx(win, cur_y, cur_x); 114217309Snwhitehorn 115217309Snwhitehorn /* 116217309Snwhitehorn * If we're drawing a centered title, do not overwrite with the arrows. 117217309Snwhitehorn */ 118251843Sbapt if (dialog_vars.title && is_toplevel && (top - getbegy(win)) < MARGIN) { 119217309Snwhitehorn int have = (limit_x - dlg_count_columns(dialog_vars.title)) / 2; 120217309Snwhitehorn int need = x + 5; 121217309Snwhitehorn if (need > have) 122217309Snwhitehorn draw_top = FALSE; 123217309Snwhitehorn } 124217309Snwhitehorn 125217309Snwhitehorn if (draw_top) { 126217309Snwhitehorn (void) wmove(win, top, x); 127217309Snwhitehorn if (top_arrow) { 128251843Sbapt (void) wattrset(win, merge_colors(uarrow_attr, attr)); 129217309Snwhitehorn (void) add_acs(win, ACS_UARROW); 130217309Snwhitehorn (void) waddstr(win, "(-)"); 131217309Snwhitehorn } else { 132251843Sbapt (void) wattrset(win, attr); 133224014Snwhitehorn (void) whline(win, dlg_boxchar(ACS_HLINE), ON_LEFT); 134217309Snwhitehorn } 135217309Snwhitehorn } 136217309Snwhitehorn mouse_mkbutton(top, x - 1, 6, KEY_PPAGE); 137217309Snwhitehorn 138217309Snwhitehorn (void) wmove(win, bottom, x); 139217309Snwhitehorn if (bottom_arrow) { 140251843Sbapt (void) wattrset(win, merge_colors(darrow_attr, borderattr)); 141217309Snwhitehorn (void) add_acs(win, ACS_DARROW); 142217309Snwhitehorn (void) waddstr(win, "(+)"); 143217309Snwhitehorn } else { 144251843Sbapt (void) wattrset(win, borderattr); 145224014Snwhitehorn (void) whline(win, dlg_boxchar(ACS_HLINE), ON_LEFT); 146217309Snwhitehorn } 147217309Snwhitehorn mouse_mkbutton(bottom, x - 1, 6, KEY_NPAGE); 148217309Snwhitehorn 149217309Snwhitehorn (void) wmove(win, cur_y, cur_x); 150217309Snwhitehorn wrefresh(win); 151217309Snwhitehorn 152251843Sbapt (void) wattrset(win, save); 153217309Snwhitehorn} 154217309Snwhitehorn 155217309Snwhitehornvoid 156217309Snwhitehorndlg_draw_scrollbar(WINDOW *win, 157217309Snwhitehorn long first_data, 158217309Snwhitehorn long this_data, 159217309Snwhitehorn long next_data, 160217309Snwhitehorn long total_data, 161217309Snwhitehorn int left, 162217309Snwhitehorn int right, 163217309Snwhitehorn int top, 164217309Snwhitehorn int bottom, 165217309Snwhitehorn chtype attr, 166217309Snwhitehorn chtype borderattr) 167217309Snwhitehorn{ 168217309Snwhitehorn char buffer[80]; 169217309Snwhitehorn int percent; 170217309Snwhitehorn int len; 171251843Sbapt int oldy, oldx; 172217309Snwhitehorn 173220749Snwhitehorn chtype save = dlg_get_attrs(win); 174217309Snwhitehorn int top_arrow = (first_data != 0); 175217309Snwhitehorn int bottom_arrow = (next_data < total_data); 176217309Snwhitehorn 177217309Snwhitehorn getyx(win, oldy, oldx); 178217309Snwhitehorn 179224014Snwhitehorn dlg_draw_helpline(win, TRUE); 180217309Snwhitehorn if (bottom_arrow || top_arrow || dialog_state.use_scrollbar) { 181217309Snwhitehorn percent = (!total_data 182217309Snwhitehorn ? 100 183217309Snwhitehorn : (int) ((next_data * 100) 184217309Snwhitehorn / total_data)); 185217309Snwhitehorn 186217309Snwhitehorn if (percent < 0) 187217309Snwhitehorn percent = 0; 188217309Snwhitehorn else if (percent > 100) 189217309Snwhitehorn percent = 100; 190217309Snwhitehorn 191251843Sbapt (void) wattrset(win, position_indicator_attr); 192217309Snwhitehorn (void) sprintf(buffer, "%d%%", percent); 193217309Snwhitehorn (void) wmove(win, bottom, right - 7); 194217309Snwhitehorn (void) waddstr(win, buffer); 195217309Snwhitehorn if ((len = dlg_count_columns(buffer)) < 4) { 196251843Sbapt (void) wattrset(win, border_attr); 197217309Snwhitehorn whline(win, dlg_boxchar(ACS_HLINE), 4 - len); 198217309Snwhitehorn } 199217309Snwhitehorn } 200251843Sbapt#define BARSIZE(num) (int) (0.5 + (double) ((all_high * (int) (num)) / (double) total_data)) 201251843Sbapt#define ORDSIZE(num) (int) ((double) ((all_high * (int) (num)) / (double) all_diff)) 202217309Snwhitehorn 203217309Snwhitehorn if (dialog_state.use_scrollbar) { 204217309Snwhitehorn int all_high = (bottom - top - 1); 205217309Snwhitehorn 206251843Sbapt this_data = MAX(0, this_data); 207251843Sbapt 208217309Snwhitehorn if (total_data > 0 && all_high > 0) { 209251843Sbapt int all_diff = (int) (total_data + 1); 210251843Sbapt int bar_diff = (int) (next_data + 1 - this_data); 211217309Snwhitehorn int bar_high; 212217309Snwhitehorn int bar_y; 213217309Snwhitehorn 214251843Sbapt bar_high = ORDSIZE(bar_diff); 215217309Snwhitehorn if (bar_high <= 0) 216217309Snwhitehorn bar_high = 1; 217217309Snwhitehorn 218217309Snwhitehorn if (bar_high < all_high) { 219251843Sbapt int bar_last = BARSIZE(next_data); 220251843Sbapt 221217309Snwhitehorn wmove(win, top + 1, right); 222217309Snwhitehorn 223251843Sbapt (void) wattrset(win, save); 224217309Snwhitehorn wvline(win, ACS_VLINE | A_REVERSE, all_high); 225217309Snwhitehorn 226251843Sbapt bar_y = ORDSIZE(this_data); 227251843Sbapt if (bar_y >= bar_last && bar_y > 0) 228251843Sbapt bar_y = bar_last - 1; 229251843Sbapt if (bar_last - bar_y > bar_high && bar_high > 1) 230251843Sbapt ++bar_y; 231251843Sbapt bar_last = MIN(bar_last, all_high); 232217309Snwhitehorn 233217309Snwhitehorn wmove(win, top + 1 + bar_y, right); 234217309Snwhitehorn 235251843Sbapt (void) wattrset(win, position_indicator_attr); 236217309Snwhitehorn wattron(win, A_REVERSE); 237251843Sbapt#if defined(WACS_BLOCK) && defined(NCURSES_VERSION) && defined(USE_WIDE_CURSES) 238251843Sbapt wvline_set(win, WACS_BLOCK, bar_last - bar_y); 239251843Sbapt#else 240251843Sbapt wvline(win, ACS_BLOCK, bar_last - bar_y); 241251843Sbapt#endif 242217309Snwhitehorn } 243217309Snwhitehorn } 244217309Snwhitehorn } 245217309Snwhitehorn dlg_draw_arrows2(win, 246217309Snwhitehorn top_arrow, 247217309Snwhitehorn bottom_arrow, 248217309Snwhitehorn left + ARROWS_COL, 249217309Snwhitehorn top, 250217309Snwhitehorn bottom, 251217309Snwhitehorn attr, 252217309Snwhitehorn borderattr); 253217309Snwhitehorn 254251843Sbapt (void) wattrset(win, save); 255217309Snwhitehorn wmove(win, oldy, oldx); 256217309Snwhitehorn} 257217309Snwhitehorn 258217309Snwhitehornvoid 259217309Snwhitehorndlg_draw_arrows(WINDOW *win, 260217309Snwhitehorn int top_arrow, 261217309Snwhitehorn int bottom_arrow, 262217309Snwhitehorn int x, 263217309Snwhitehorn int top, 264217309Snwhitehorn int bottom) 265217309Snwhitehorn{ 266224014Snwhitehorn dlg_draw_helpline(win, TRUE); 267217309Snwhitehorn dlg_draw_arrows2(win, 268217309Snwhitehorn top_arrow, 269217309Snwhitehorn bottom_arrow, 270217309Snwhitehorn x, 271217309Snwhitehorn top, 272217309Snwhitehorn bottom, 273251843Sbapt menubox_border2_attr, 274217309Snwhitehorn menubox_border_attr); 275217309Snwhitehorn} 276