widget.c (3475B)
1 /* 2 * widget.c - handles widget objects and the widget stack 3 * Copyright (c) Clemens Ladisch <clemens@ladisch.de> 4 * 5 * This program is free software: you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation, either version 2 of the License, or 8 * (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program. If not, see <http://www.gnu.org/licenses/>. 17 */ 18 19 #include "aconfig.h" 20 #include <stdlib.h> 21 #include <term.h> 22 #include "die.h" 23 #include "widget.h" 24 25 int screen_lines; 26 int screen_cols; 27 28 static int cursor_visibility = -1; 29 30 static void widget_handle_key(int key) 31 { 32 } 33 34 static void update_cursor_visibility(void) 35 { 36 struct widget *active_widget; 37 38 active_widget = get_active_widget(); 39 if (active_widget && 40 active_widget->cursor_visibility != cursor_visibility) { 41 cursor_visibility = active_widget->cursor_visibility; 42 curs_set(cursor_visibility); 43 } 44 } 45 46 void widget_init(struct widget *widget, int lines_, int cols, int y, int x, 47 chtype bkgd, unsigned int flags) 48 { 49 WINDOW *old_window; 50 51 if (y == SCREEN_CENTER) 52 y = (screen_lines - lines_) / 2; 53 if (x == SCREEN_CENTER) 54 x = (screen_cols - cols) / 2; 55 56 old_window = widget->window; 57 widget->window = newwin(lines_, cols, y, x); 58 if (!widget->window) 59 fatal_error("cannot create window"); 60 keypad(widget->window, TRUE); 61 nodelay(widget->window, TRUE); 62 leaveok(widget->window, !(flags & WIDGET_CURSOR_VISIBLE)); 63 wbkgdset(widget->window, bkgd); 64 werase(widget->window); 65 66 if (flags & WIDGET_BORDER) 67 box(widget->window, 0, 0); 68 if (flags & WIDGET_SUBWINDOW) { 69 if (widget->subwindow) 70 delwin(widget->subwindow); 71 widget->subwindow = derwin(widget->window, 72 lines_ - 2, cols - 2, 1, 1); 73 if (!widget->subwindow) 74 fatal_error("cannot create subwindow"); 75 wbkgdset(widget->subwindow, bkgd); 76 } 77 widget->cursor_visibility = !!(flags & WIDGET_CURSOR_VISIBLE); 78 79 if (widget->panel) { 80 replace_panel(widget->panel, widget->window); 81 } else { 82 widget->panel = new_panel(widget->window); 83 if (!widget->panel) 84 fatal_error("cannot create panel"); 85 set_panel_userptr(widget->panel, widget); 86 } 87 88 if (!widget->handle_key) 89 widget->handle_key = widget_handle_key; 90 91 if (old_window) 92 delwin(old_window); 93 94 update_cursor_visibility(); 95 } 96 97 void widget_free(struct widget *widget) 98 { 99 if (widget->panel) { 100 del_panel(widget->panel); 101 widget->panel = NULL; 102 } 103 if (widget->subwindow) { 104 delwin(widget->subwindow); 105 widget->subwindow = NULL; 106 } 107 if (widget->window) { 108 delwin(widget->window); 109 widget->window = NULL; 110 } 111 112 update_cursor_visibility(); 113 } 114 115 struct widget *get_active_widget(void) 116 { 117 PANEL *active_panel; 118 119 active_panel = panel_below(NULL); 120 if (active_panel) 121 return panel_userptr(active_panel); 122 else 123 return NULL; 124 } 125 126 void window_size_changed(void) 127 { 128 PANEL *panel, *below; 129 struct widget *widget; 130 131 getmaxyx(stdscr, screen_lines, screen_cols); 132 if (tigetflag("xenl") != 1 && tigetflag("am") != 1) 133 --screen_lines; 134 135 for (panel = panel_below(NULL); panel; panel = below) { 136 below = panel_below(panel); 137 widget = panel_userptr(panel); 138 widget->window_size_changed(); 139 } 140 }