/* * print a string in the window */ void wdg_scroll_print(wdg_t *wo, int color, char *fmt, ...) { WDG_WO_EXT(struct wdg_scroll, ww); size_t c = wdg_get_ncols(wo); size_t l = wdg_get_nlines(wo); size_t x = wdg_get_begin_x(wo); size_t y = wdg_get_begin_y(wo); va_list ap; WDG_DEBUG_MSG("wdg_scroll_print"); /* move to the bottom of the pad */ wdg_set_scroll(wo, ww->y_max - l + 1); wbkgdset(ww->sub, COLOR_PAIR(color)); /* print the message */ va_start(ap, fmt); vw_printw(ww->sub, fmt, ap); va_end(ap); wbkgdset(ww->sub, COLOR_PAIR(wo->window_color)); WDG_PAD_REFRESH(ww, c, l, x, y); }
/* * called by the messages dispatcher when the window is focused */ static int wdg_scroll_get_msg(struct wdg_object *wo, int key, struct wdg_mouse_event *mouse) { WDG_WO_EXT(struct wdg_scroll, ww); size_t c = wdg_get_ncols(wo); size_t l = wdg_get_nlines(wo); size_t x = wdg_get_begin_x(wo); size_t y = wdg_get_begin_y(wo); /* handle the message */ switch (key) { case KEY_MOUSE: /* is the mouse event within our edges ? */ if (wenclose(ww->win, mouse->y, mouse->x)) { /* get the focus only if it was not focused */ if (!(wo->flags & WDG_OBJ_FOCUSED)) wdg_set_focus(wo); if (mouse->x == x + c - 1 && (mouse->y >= y + 1 && mouse->y <= y + l - 1)) { wdg_mouse_scroll(wo, mouse->y); WDG_PAD_REFRESH(ww, c, l, x, y); wnoutrefresh(ww->win); } } else return -WDG_ENOTHANDLED; break; /* handle scrolling of the pad */ case KEY_UP: wdg_set_scroll(wo, ww->y_scroll - 1); WDG_PAD_REFRESH(ww, c, l, x, y); wnoutrefresh(ww->win); break; case KEY_DOWN: wdg_set_scroll(wo, ww->y_scroll + 1); WDG_PAD_REFRESH(ww, c, l, x, y); wnoutrefresh(ww->win); break; case KEY_NPAGE: wdg_set_scroll(wo, ww->y_scroll + (l - 2)); WDG_PAD_REFRESH(ww, c, l, x, y); wnoutrefresh(ww->win); break; case KEY_PPAGE: wdg_set_scroll(wo, ww->y_scroll - (l - 2)); WDG_PAD_REFRESH(ww, c, l, x, y); wnoutrefresh(ww->win); break; /* message not handled */ default: return -WDG_ENOTHANDLED; break; } return WDG_ESUCCESS; }
/* * erase the subwindow */ void wdg_scroll_erase(wdg_t *wo) { WDG_WO_EXT(struct wdg_scroll, ww); size_t c = wdg_get_ncols(wo); size_t l = wdg_get_nlines(wo); size_t x = wdg_get_begin_x(wo); size_t y = wdg_get_begin_y(wo); werase(ww->sub); WDG_PAD_REFRESH(ww, c, l, x, y); }
/* * set the dimension of the pad */ void wdg_scroll_set_lines(wdg_t *wo, size_t lines) { WDG_WO_EXT(struct wdg_scroll, ww); size_t c = wdg_get_ncols(wo); size_t l = wdg_get_nlines(wo); size_t oldlines = ww->y_max; WDG_DEBUG_MSG("wdg_scroll_set_lines"); /* resize the pad */ wresize(ww->sub, lines, c - 2); /* do the proper adjustements to the scroller */ ww->y_max = lines; wdg_set_scroll(wo, ww->y_max - l + 1); /* adjust only the first time (when the user requests the change) */ if (oldlines != lines) wmove(ww->sub, ww->y_scroll + 1, 0); }
/* * jump to a scroll position with the mouse */ static void wdg_mouse_scroll(struct wdg_object *wo, int s) { WDG_WO_EXT(struct wdg_scroll, ww); size_t l = wdg_get_nlines(wo); size_t y = wdg_get_begin_y(wo); size_t base; /* calculate the relative displacement */ base = s - y - 1; /* special case for top and bottom */ if (base == 0) s = 0; else if (base == l - 3) s = ww->y_max - l + 1; /* else calulate the proportion */ else s = base * ww->y_max / (l - 2); /* set the scroller */ wdg_set_scroll(wo, s); }
/* * set the scroll pointer and redraw * the window elevator */ static void wdg_set_scroll(struct wdg_object *wo, int s) { WDG_WO_EXT(struct wdg_scroll, ww); size_t c = wdg_get_ncols(wo); size_t l = wdg_get_nlines(wo); int min = 0; int max = ww->y_max - l + 1; size_t height, vpos; /* don't go above max and below min */ if (s < min) s = min; if (s > max) s = max; ww->y_scroll = s; /* compute the scroller cohordinates */ height = (l - 2) * (l - 2) / ww->y_max; vpos = l * ww->y_scroll / ww->y_max; height = (height < 1) ? 1 : height; vpos = (vpos == 0) ? 1 : vpos; vpos = (vpos > (l - 1) - height) ? (l - 1) - height : vpos; /* hack to make sure to hit the bottom */ if (ww->y_scroll == (size_t)max) vpos = l - 1 - height; /* draw the scroller */ wmove(ww->win, 1, c - 1); wvline(ww->win, ACS_CKBOARD, l - 2); wattron(ww->win, A_REVERSE); wmove(ww->win, vpos, c - 1); wvline(ww->win, ACS_DIAMOND, height); wattroff(ww->win, A_REVERSE); }
/* * called to redraw the file dialog */ static int wdg_file_redraw(struct wdg_object *wo) { WDG_WO_EXT(struct wdg_file_handle, ww); size_t c, l, x, y; WDG_DEBUG_MSG("wdg_file_redraw"); /* default dimentions */ wo->x1 = (current_screen.cols - ww->x) / 2; wo->y1 = (current_screen.lines - ww->y) / 2; wo->x2 = -wo->x1; wo->y2 = -wo->y1; c = wdg_get_ncols(wo); l = wdg_get_nlines(wo); x = wdg_get_begin_x(wo); y = wdg_get_begin_y(wo); /* deal with rouding */ if (l != ww->y) l = ww->y; if (c != ww->x) c = ww->x; /* the window already exist */ if (ww->win) { /* erase the border */ wbkgd(ww->win, COLOR_PAIR(wo->screen_color)); werase(ww->win); /* destroy the file list */ wdg_file_menu_destroy(wo); touchwin(ww->win); wnoutrefresh(ww->win); /* resize the window and draw the new border */ mvwin(ww->win, y, x); wresize(ww->win, l, c); wbkgd(ww->win, COLOR_PAIR(wo->window_color)); werase(ww->win); /* create the file list */ wdg_file_menu_create(wo); touchwin(ww->win); wdg_file_borders(wo); /* the first time we have to allocate the window */ } else { /* create the menu window (fixed dimensions) */ if ((ww->win = newwin(l, c, y, x)) == NULL) return -WDG_E_FATAL; /* create the file list */ wdg_file_menu_create(wo); /* set the window color */ wbkgd(ww->win, COLOR_PAIR(wo->window_color)); redrawwin(ww->win); /* draw the titles */ wdg_file_borders(wo); /* no scrolling */ scrollok(ww->win, FALSE); } /* refresh the window */ touchwin(ww->win); wnoutrefresh(ww->win); touchwin(ww->mwin); wnoutrefresh(ww->mwin); wo->flags |= WDG_OBJ_VISIBLE; return WDG_E_SUCCESS; }
/* * called to redraw a window */ static int wdg_scroll_redraw(struct wdg_object *wo) { WDG_WO_EXT(struct wdg_scroll, ww); size_t c = wdg_get_ncols(wo); size_t l = wdg_get_nlines(wo); size_t x = wdg_get_begin_x(wo); size_t y = wdg_get_begin_y(wo); WDG_DEBUG_MSG("wdg_scroll_redraw"); /* the window already exist */ if (ww->win) { /* erase the border */ wbkgd(ww->win, COLOR_PAIR(wo->screen_color)); werase(ww->win); touchwin(ww->win); wnoutrefresh(ww->win); /* resize the window and draw the new border */ mvwin(ww->win, y, x); wresize(ww->win, l, c); wdg_scroll_border(wo); /* set the window color */ wbkgd(ww->sub, COLOR_PAIR(wo->window_color)); touchwin(ww->sub); /* the pad is resized only orizzontally. * the vertical dimension can be larger than the screen */ wdg_scroll_set_lines(wo, ww->y_max); /* refresh it */ WDG_PAD_REFRESH(ww, c, l, x, y); /* the first time we have to allocate the window */ } else { /* a default value waiting for wdg_scroll_set_lines() */ ww->y_max = l * 5; /* create the outher window */ if ((ww->win = newwin(l, c, y, x)) == NULL) return -WDG_EFATAL; /* draw the borders */ wdg_scroll_border(wo); /* initialize the pointer */ wdg_set_scroll(wo, ww->y_max - l + 1); /* create the inner (actual) window */ if ((ww->sub = newpad(ww->y_max, c - 2)) == NULL) return -WDG_EFATAL; /* set the window color */ wbkgd(ww->sub, COLOR_PAIR(wo->window_color)); touchwin(ww->sub); /* move to the bottom of the pad */ wmove(ww->sub, ww->y_scroll + 1, 0); /* permit scroll in the pad */ scrollok(ww->sub, TRUE); } /* refresh the window */ touchwin(ww->sub); wnoutrefresh(ww->win); WDG_PAD_REFRESH(ww, c, l, x, y); wo->flags |= WDG_OBJ_VISIBLE; return WDG_ESUCCESS; }
/* * called to redraw a window */ static int wdg_window_redraw(struct wdg_object *wo) { WDG_WO_EXT(struct wdg_window, ww); size_t c = wdg_get_ncols(wo); size_t l = wdg_get_nlines(wo); size_t x = wdg_get_begin_x(wo); size_t y = wdg_get_begin_y(wo); WDG_DEBUG_MSG("wdg_window_redraw"); /* the window already exist */ if (ww->win) { /* erase the border */ wbkgd(ww->win, COLOR_PAIR(wo->screen_color)); werase(ww->win); touchwin(ww->win); wnoutrefresh(ww->win); /* resize the window and draw the new border */ mvwin(ww->win, y, x); wresize(ww->win, l, c); wdg_window_border(wo); /* resize the actual window and touch it */ mvwin(ww->sub, y + 1, x + 1); wresize(ww->sub, l - 2, c - 2); /* set the window color */ wbkgd(ww->sub, COLOR_PAIR(wo->window_color)); /* the first time we have to allocate the window */ } else { /* create the outher window */ if ((ww->win = newwin(l, c, y, x)) == NULL) return -WDG_EFATAL; /* draw the borders */ wdg_window_border(wo); /* create the inner (actual) window */ if ((ww->sub = newwin(l - 2, c - 2, y + 1, x + 1)) == NULL) return -WDG_EFATAL; /* set the window color */ wbkgd(ww->sub, COLOR_PAIR(wo->window_color)); werase(ww->sub); redrawwin(ww->sub); /* initialize the pointer */ wmove(ww->sub, 0, 0); scrollok(ww->sub, TRUE); } /* refresh the window */ redrawwin(ww->sub); redrawwin(ww->win); wnoutrefresh(ww->win); wnoutrefresh(ww->sub); wo->flags |= WDG_OBJ_VISIBLE; return WDG_ESUCCESS; }
/* * called to redraw a window */ static int wdg_dialog_redraw(struct wdg_object *wo) { WDG_WO_EXT(struct wdg_dialog, ww); size_t c, l, x, y; size_t lines, cols; WDG_DEBUG_MSG("wdg_dialog_redraw"); /* calculate the dimension and position */ wdg_dialog_get_size(wo, &lines, &cols); /* center on the screen, but not outside the edges */ if (cols + 4 >= current_screen.cols) wo->x1 = 0; else wo->x1 = (current_screen.cols - (cols + 4)) / 2; wo->y1 = (current_screen.lines - (lines + 4)) / 2; wo->x2 = -wo->x1; wo->y2 = -wo->y1; /* get the cohorditates as usual */ c = wdg_get_ncols(wo); l = wdg_get_nlines(wo); x = wdg_get_begin_x(wo); y = wdg_get_begin_y(wo); /* deal with rouding */ if (l != lines + 4) l = lines + 4; if (c != cols + 4) c = cols + 4; /* the window already exist */ if (ww->win) { /* erase the border */ wbkgd(ww->win, COLOR_PAIR(wo->screen_color)); werase(ww->win); touchwin(ww->win); wnoutrefresh(ww->win); /* resize the window and draw the new border */ mvwin(ww->win, y, x); wresize(ww->win, l, c); wdg_dialog_border(wo); wdg_dialog_buttons(wo); /* resize the actual window and touch it */ mvwin(ww->sub, y + 2, x + 2); wresize(ww->sub, l - 4, c - 4); /* set the window color */ wbkgdset(ww->sub, COLOR_PAIR(wo->window_color)); /* the first time we have to allocate the window */ } else { /* create the outher window */ if ((ww->win = newwin(l, c, y, x)) == NULL) return -WDG_EFATAL; /* draw the borders */ wdg_dialog_border(wo); wdg_dialog_buttons(wo); /* create the inner (actual) window */ if ((ww->sub = newwin(l - 4, c - 4, y + 2, x + 2)) == NULL) return -WDG_EFATAL; /* set the window color */ wbkgdset(ww->sub, COLOR_PAIR(wo->window_color)); werase(ww->sub); redrawwin(ww->sub); } /* print the message text */ wmove(ww->sub, 0, 0); wprintw(ww->sub, ww->text); /* refresh the window */ redrawwin(ww->sub); redrawwin(ww->win); wnoutrefresh(ww->win); wnoutrefresh(ww->sub); wo->flags |= WDG_OBJ_VISIBLE; return WDG_ESUCCESS; }
/* * called to redraw a window */ static int wdg_percentage_redraw(struct wdg_object *wo) { WDG_WO_EXT(struct wdg_percentage, ww); size_t c, l, x, y; size_t cols; /* calculate the dimension and position */ cols = strlen(wo->title) + 2; /* set the minimum */ if (cols < 45) cols = 45; /* center on the screen, but not outside the edges */ if (cols + 4 >= current_screen.cols) wo->x1 = 0; else wo->x1 = (current_screen.cols - (cols + 4)) / 2; wo->y1 = (current_screen.lines - 7) / 2; wo->x2 = -wo->x1; wo->y2 = -wo->y1; c = wdg_get_ncols(wo); l = wdg_get_nlines(wo); x = wdg_get_begin_x(wo); y = wdg_get_begin_y(wo); /* the window already exist */ if (ww->win) { /* erase the border */ wbkgd(ww->win, COLOR_PAIR(wo->screen_color)); werase(ww->win); touchwin(ww->win); wnoutrefresh(ww->win); /* resize the window and draw the new border */ mvwin(ww->win, y, x); wresize(ww->win, l, c); wdg_percentage_border(wo); /* resize the actual window and touch it */ mvwin(ww->sub, y + 1, x + 1); wresize(ww->sub, l - 2, c - 2); /* set the window color */ wbkgdset(ww->sub, COLOR_PAIR(wo->window_color)); /* the first time we have to allocate the window */ } else { /* create the outher window */ if ((ww->win = newwin(l, c, y, x)) == NULL) return -WDG_E_FATAL; /* draw the borders */ wdg_percentage_border(wo); /* create the inner (actual) window */ if ((ww->sub = newwin(l - 2, c - 2, y + 1, x + 1)) == NULL) return -WDG_E_FATAL; /* set the window color */ wbkgdset(ww->sub, COLOR_PAIR(wo->window_color)); werase(ww->sub); redrawwin(ww->sub); /* initialize the pointer */ wmove(ww->sub, 0, 0); scrollok(ww->sub, TRUE); } /* refresh the window */ redrawwin(ww->sub); redrawwin(ww->win); wnoutrefresh(ww->win); wnoutrefresh(ww->sub); wo->flags |= WDG_OBJ_VISIBLE; return WDG_E_SUCCESS; }