X-Git-Url: https://ncurses.scripts.mit.edu/?p=ncurses.git;a=blobdiff_plain;f=test%2Fmovewindow.c;h=91c7266ad77998834cfe1b499303638342fc08a4;hp=d826e58dcbd4d66d21bcf443ce7a8efcc894321a;hb=a924c24b2535cccdc0f5f991cd8ddcadcfa1f0d2;hpb=396a05943b7da5039dd15d79c4385c7d2a75d6d4 diff --git a/test/movewindow.c b/test/movewindow.c index d826e58d..91c7266a 100644 --- a/test/movewindow.c +++ b/test/movewindow.c @@ -1,5 +1,5 @@ /**************************************************************************** - * Copyright (c) 2006-2007,2008 Free Software Foundation, Inc. * + * Copyright (c) 2006-2013,2017 Free Software Foundation, Inc. * * * * Permission is hereby granted, free of charge, to any person obtaining a * * copy of this software and associated documentation files (the * @@ -26,18 +26,22 @@ * authorization. * ****************************************************************************/ /* - * $Id: movewindow.c,v 1.22 2008/04/12 22:01:41 tom Exp $ + * $Id: movewindow.c,v 1.40 2017/04/08 23:01:47 tom Exp $ * * Demonstrate move functions for windows and derived windows from the curses * library. * - * Thomas Dickey - 2006/2/11 + * Author: Thomas E. Dickey */ /* derwin mvderwin subwin mvwin + +TODO: + add command to reset subwindow's origin to coincide with parent. + add command to delete subwindow (check if it has subwindows though) */ #include @@ -75,6 +79,14 @@ static void tail_line(CONST_FMT char *fmt,...) GCC_PRINTFLIKE(1, 2); static unsigned num_windows; static FRAME *all_windows; +static void +failed(const char *s) +{ + perror(s); + endwin(); + ExitProgram(EXIT_FAILURE); +} + static void message(int lineno, CONST_FMT char *fmt, va_list argp) { @@ -122,7 +134,12 @@ tail_line(CONST_FMT char *fmt,...) * Arrow keys move cursor, return location at current on non-arrow key. */ static PAIR * -selectcell(WINDOW *parent, int uli, int ulj, int lri, int lrj) +selectcell(WINDOW *parent, + WINDOW *child, + int uli, int ulj, + int lri, int lrj, + bool relative, + bool * more) { static PAIR res; /* result cell */ int si = lri - uli + 1; /* depth of the select area */ @@ -131,25 +148,46 @@ selectcell(WINDOW *parent, int uli, int ulj, int lri, int lrj) res.y = uli; res.x = ulj; + + if (child != 0) { + if (relative) { + getparyx(child, i, j); + } else { + getbegyx(child, i, j); + i -= uli + getbegy(parent); + j -= ulj + getbegx(parent); + } + } + + if (more) + *more = FALSE; + for (;;) { - tail_line("Upper left [%2d,%2d] Lower right [%2d,%2d] -> %d,%d", + bool moved = FALSE; + + tail_line("Upper left [%2d,%2d] Lower right [%2d,%2d] -> %d,%d -> %d,%d", uli, ulj, lri, lrj, + i, j, uli + i, ulj + j); wmove(parent, uli + i, ulj + j); switch (wgetch(parent)) { case KEY_UP: i += si - 1; + moved = TRUE; break; case KEY_DOWN: i++; + moved = TRUE; break; case KEY_LEFT: j += sj - 1; + moved = TRUE; break; case KEY_RIGHT: j++; + moved = TRUE; break; case QUIT: case ESCAPE: @@ -161,8 +199,13 @@ selectcell(WINDOW *parent, int uli, int ulj, int lri, int lrj) getmouse(&event); if (event.y > uli && event.x > ulj) { - i = event.y - uli; - j = event.x - ulj; + if (parent != stdscr) { + i = event.y - getbegy(parent) - uli; + j = event.x - getbegx(parent) - ulj; + } else { + i = event.y - uli; + j = event.x - ulj; + } } else { beep(); break; @@ -175,8 +218,26 @@ selectcell(WINDOW *parent, int uli, int ulj, int lri, int lrj) res.x = ulj + j; return (&res); } - i %= si; - j %= sj; + + if (si <= 0) + i = 0; + else + i %= si; + + if (sj <= 0) + j = 0; + else + j %= sj; + + /* + * If the caller can handle continuous movement, return the result. + */ + if (moved && more) { + *more = TRUE; + res.y = uli + i; + res.x = ulj + j; + return (&res); + } } } @@ -194,14 +255,22 @@ getwindow(WINDOW *parent, PAIR * ul, PAIR * lr) bool result = FALSE; head_line("Use arrows to move cursor, anything else to mark corner 1"); - if ((tmp = selectcell(parent, min_line, min_col, max_line, max_col)) != 0) { + if ((tmp = selectcell(parent, 0, + min_line, min_col, + max_line, max_col, + FALSE, + (bool *) 0)) != 0) { *ul = *tmp; - mvwaddch(parent, ul->y, ul->x, '*'); + MvWAddCh(parent, ul->y, ul->x, '*'); head_line("Use arrows to move cursor, anything else to mark corner 2"); - if ((tmp = selectcell(parent, ul->y, ul->x, max_line, max_col)) != 0) { + if ((tmp = selectcell(parent, 0, + ul->y, ul->x, + max_line, max_col, + FALSE, + (bool *) 0)) != 0) { *lr = *tmp; - mvwaddch(parent, lr->y, lr->x, '*'); + MvWAddCh(parent, lr->y, lr->x, '*'); wmove(parent, lr->y, lr->x); wsyncdown(parent); wrefresh(parent); @@ -224,16 +293,16 @@ box_inside(WINDOW *win) getyx(win, y0, x0); getmaxyx(win, y1, x1); - mvwhline(win, 0, 0, ACS_HLINE, x1); - mvwhline(win, y1 - 1, 0, ACS_HLINE, x1); + MvWHLine(win, 0, 0, ACS_HLINE, x1); + MvWHLine(win, y1 - 1, 0, ACS_HLINE, x1); - mvwvline(win, 0, 0, ACS_VLINE, y1); - mvwvline(win, 0, x1 - 1, ACS_VLINE, y1); + MvWVLine(win, 0, 0, ACS_VLINE, y1); + MvWVLine(win, 0, x1 - 1, ACS_VLINE, y1); - mvwaddch(win, 0, 0, ACS_ULCORNER); - mvwaddch(win, y1 - 1, 0, ACS_LLCORNER); - mvwaddch(win, 0, x1 - 1, ACS_URCORNER); - mvwaddch(win, y1 - 1, x1 - 1, ACS_LRCORNER); + MvWAddCh(win, 0, 0, ACS_ULCORNER); + MvWAddCh(win, y1 - 1, 0, ACS_LLCORNER); + MvWAddCh(win, 0, x1 - 1, ACS_URCORNER); + MvWAddCh(win, y1 - 1, x1 - 1, ACS_LRCORNER); wsyncdown(win); wmove(win, y0, x0); @@ -252,6 +321,8 @@ add_window(WINDOW *parent, WINDOW *child) keypad(child, TRUE); if (need > have) { all_windows = typeRealloc(FRAME, need, all_windows); + if (!all_windows) + failed("add_window"); } all_windows[num_windows].parent = parent; all_windows[num_windows].child = child; @@ -311,7 +382,7 @@ next_window(WINDOW *win) int n = window2num(win); if (n++ >= 0) { - result = all_windows[n % num_windows].child; + result = all_windows[(unsigned) n % num_windows].child; wmove(result, 0, 0); wrefresh(result); } @@ -326,8 +397,8 @@ prev_window(WINDOW *win) if (n-- >= 0) { if (n < 0) - n = num_windows - 1; - result = all_windows[n % num_windows].child; + n = (int) (num_windows - 1); + result = all_windows[(unsigned) n % num_windows].child; wmove(result, 0, 0); wrefresh(result); } @@ -341,10 +412,7 @@ recur_move_window(WINDOW *parent, int dy, int dx) for (n = 0; n < num_windows; ++n) { if (all_windows[n].parent == parent) { - int y0, x0; - - getbegyx(all_windows[n].child, y0, x0); - mvwin(all_windows[n].child, y0 + dy, x0 + dx); + mvwin(all_windows[n].child, dy, dx); recur_move_window(all_windows[n].child, dy, dx); } } @@ -366,20 +434,24 @@ move_window(WINDOW *win, bool recur) int min_line = top ? LINE_MIN : 0; int max_line = top ? LINE_MAX : getmaxy(parent); PAIR *tmp; + bool more; head_line("Select new position for %swindow", top ? "" : "sub"); - if ((tmp = selectcell(parent, - min_line, min_col, - max_line, max_col)) != 0) { + while ((tmp = selectcell(parent, + win, + min_line, min_col, + max_line, max_col, + FALSE, + &more)) != 0) { int y0, x0; getbegyx(parent, y0, x0); /* - * Note: Moving a subwindow has the effect of moving a viewport - * around the screen. The parent window retains the contents of - * the subwindow in the original location, but the viewport will - * show the contents (again) at the new location. So it will look - * odd when testing. + * Moving a subwindow has the effect of moving a viewport around + * the screen. The parent window retains the contents of the + * subwindow in the original location, but the viewport will show + * the contents (again) at the new location. So it will look odd + * when testing. */ if (mvwin(win, y0 + tmp->y, x0 + tmp->x) != ERR) { if (recur) { @@ -388,45 +460,69 @@ move_window(WINDOW *win, bool recur) refresh_all(win); doupdate(); result = TRUE; + } else { + result = FALSE; } + if (!more) + break; } } + head_line("done"); return result; } +static void +show_derwin(WINDOW *win) +{ + int pary, parx, maxy, maxx; + + getmaxyx(win, maxy, maxx); + getparyx(win, pary, parx); + + head_line("Select new position for derived window at %d,%d (%d,%d)", + pary, parx, maxy, maxx); +} + /* * test mvderwin(). */ static bool -move_subwin(WINDOW *win) +move_derwin(WINDOW *win) { WINDOW *parent = parent_of(win); bool result = FALSE; if (parent != 0) { bool top = (parent == stdscr); - if (!top) { - int min_col = top ? COL_MIN : 0; - int max_col = top ? COL_MAX : getmaxx(parent); - int min_line = top ? LINE_MIN : 0; - int max_line = top ? LINE_MAX : getmaxy(parent); - PAIR *tmp; - - head_line("Select new position for subwindow"); - - if ((tmp = selectcell(parent, - min_line, min_col, - max_line, max_col)) != 0) { - int y0, x0; - getbegyx(parent, y0, x0); - if (mvderwin(win, y0 + tmp->y, x0 + tmp->x) != ERR) { - refresh_all(win); - doupdate(); - result = TRUE; - } + int min_col = top ? COL_MIN : 0; + int max_col = top ? COL_MAX : getmaxx(parent); + int min_line = top ? LINE_MIN : 0; + int max_line = top ? LINE_MAX : getmaxy(parent); + PAIR *tmp; + bool more; + + show_derwin(win); + while ((tmp = selectcell(parent, + win, + min_line, min_col, + max_line, max_col, + TRUE, + &more)) != 0) { + if (mvderwin(win, tmp->y, tmp->x) != ERR) { + refresh_all(win); + doupdate(); + repaint_one(win); + doupdate(); + result = TRUE; + show_derwin(win); + } else { + flash(); } + if (!more) + break; } } + head_line("done"); return result; } @@ -441,7 +537,29 @@ fill_window(WINDOW *win, chtype ch) getmaxyx(win, y1, x1); for (y = 0; y < y1; ++y) { for (x = 0; x < x1; ++x) { - mvwaddch(win, y, x, ch); + MvWAddCh(win, y, x, ch); + } + } + wsyncdown(win); + wmove(win, y0, x0); + wrefresh(win); +} + +static void +fill_with_pattern(WINDOW *win) +{ + int y, x; + int y0, x0; + int y1, x1; + int ch = 'a'; + + getyx(win, y0, x0); + getmaxyx(win, y1, x1); + for (y = 0; y < y1; ++y) { + for (x = 0; x < x1; ++x) { + MvWAddCh(win, y, x, (chtype) ch); + if (++ch > 'z') + ch = 'a'; } } wsyncdown(win); @@ -523,12 +641,13 @@ show_help(WINDOW *current) { 'b', "Draw a box inside the current window" }, { 'c', "Create a new window" }, { 'd', "Create a new derived window" }, + { 'D', "Move derived window (moves viewport)" }, { 'f', "Fill the current window with the next character" }, + { 'F', "Fill the current window with a pattern" }, { 'm', "Move the current window" }, { 'M', "Move the current window (and its children)" }, { 'q', "Quit" }, { 's', "Create a new subwindow" }, - { 't', "Move the current subwindow (moves content)" }, { CTRL('L'), "Repaint all windows, doing current one last" }, { CTRL('N'), "Cursor to next window" }, { CTRL('P'), "Cursor to previous window" }, @@ -571,6 +690,10 @@ main(int argc GCC_UNUSED, char *argv[]GCC_UNUSED) #endif /* NCURSES_MOUSE_VERSION */ while (!done && (ch = wgetch(current_win)) != ERR) { + int y, x; + + getyx(current_win, y, x); + switch (ch) { case '?': show_help(current_win); @@ -584,9 +707,18 @@ main(int argc GCC_UNUSED, char *argv[]GCC_UNUSED) case 'd': current_win = create_my_derwin(current_win); break; + case 'D': + if (!move_derwin(current_win)) { + tail_line("error"); + continue; + } + break; case 'f': fill_window(current_win, (chtype) wgetch(current_win)); break; + case 'F': + fill_with_pattern(current_win); + break; case 'm': case 'M': if (!move_window(current_win, (ch == 'M'))) { @@ -600,12 +732,6 @@ main(int argc GCC_UNUSED, char *argv[]GCC_UNUSED) case 's': current_win = create_my_subwin(current_win); break; - case 't': - if (!move_subwin(current_win)) { - tail_line("error"); - continue; - } - break; case CTRL('L'): refresh_all(current_win); break; @@ -621,6 +747,7 @@ main(int argc GCC_UNUSED, char *argv[]GCC_UNUSED) /* want to allow deleting a window also */ #endif default: + wmove(current_win, y, x); tail_line("unrecognized key (use '?' for help)"); beep(); continue; @@ -635,5 +762,8 @@ main(int argc GCC_UNUSED, char *argv[]GCC_UNUSED) wmove(current_win, 0, 0); } endwin(); +#if NO_LEAKS + free(all_windows); +#endif ExitProgram(EXIT_SUCCESS); }