/* * widget.c - handles widget objects and the widget stack * Copyright (c) Clemens Ladisch * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "aconfig.h" #include #include #include #include #include "die.h" #include "widget.h" int screen_lines; int screen_cols; static int cursor_visibility = -1; static void widget_handle_key(int key) { } static void update_cursor_visibility(void) { const struct widget *active_widget; active_widget = get_active_widget(); if (active_widget && active_widget->cursor_visibility != cursor_visibility) { cursor_visibility = active_widget->cursor_visibility; curs_set(cursor_visibility); } } void widget_init(struct widget *widget, int lines_, int cols, int y, int x, chtype bkgd, unsigned int flags) { WINDOW *old_window; if (y == SCREEN_CENTER) y = (screen_lines - lines_) / 2; if (x == SCREEN_CENTER) x = (screen_cols - cols) / 2; old_window = widget->window; widget->window = newwin(lines_, cols, y, x); if (!widget->window) fatal_error("cannot create window"); keypad(widget->window, TRUE); nodelay(widget->window, TRUE); leaveok(widget->window, !(flags & WIDGET_CURSOR_VISIBLE)); wbkgdset(widget->window, bkgd); werase(widget->window); if (flags & WIDGET_BORDER) box(widget->window, 0, 0); if (flags & WIDGET_SUBWINDOW) { if (widget->subwindow) delwin(widget->subwindow); widget->subwindow = derwin(widget->window, lines_ - 2, cols - 2, 1, 1); if (!widget->subwindow) fatal_error("cannot create subwindow"); wbkgdset(widget->subwindow, bkgd); } widget->cursor_visibility = !!(flags & WIDGET_CURSOR_VISIBLE); if (widget->panel) { replace_panel(widget->panel, widget->window); } else { widget->panel = new_panel(widget->window); if (!widget->panel) fatal_error("cannot create panel"); set_panel_userptr(widget->panel, widget); } if (!widget->handle_key) widget->handle_key = widget_handle_key; if (old_window) delwin(old_window); update_cursor_visibility(); } void widget_free(struct widget *widget) { if (widget->panel) { del_panel(widget->panel); widget->panel = NULL; } if (widget->subwindow) { delwin(widget->subwindow); widget->subwindow = NULL; } if (widget->window) { delwin(widget->window); widget->window = NULL; } update_cursor_visibility(); } const struct widget *get_active_widget(void) { PANEL *active_panel; active_panel = panel_below(NULL); if (active_panel) return panel_userptr(active_panel); else return NULL; } void window_size_changed(void) { PANEL *panel, *below; const struct widget *widget; struct winsize size; if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &size) == 0) resize_term(size.ws_row, size.ws_col); getmaxyx(stdscr, screen_lines, screen_cols); if (tigetflag("xenl") != 1 && tigetflag("am") != 1) --screen_lines; for (panel = panel_below(NULL); panel; panel = below) { below = panel_below(panel); widget = panel_userptr(panel); widget->window_size_changed(); } }