1 /*- 2 * Copyright (c) 2011 Nathan Whitehorn 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * 26 * $FreeBSD$ 27 */ 28 29 #include <stdio.h> 30 #include <unistd.h> 31 #include <libutil.h> 32 #include <dialog.h> 33 #include <dlg_keys.h> 34 35 #include "diskeditor.h" 36 37 static void 38 print_partedit_item(WINDOW *partitions, struct partedit_item *items, 39 int item, int nscroll, int selected) 40 { 41 chtype attr = A_NORMAL; 42 char sizetext[16]; 43 int y = item - nscroll + 1; 44 45 wattrset(partitions, selected ? item_selected_attr : item_attr); 46 wmove(partitions, y, MARGIN + items[item].indentation*2); 47 dlg_print_text(partitions, items[item].name, 8, &attr); 48 wmove(partitions, y, 15); 49 wattrset(partitions, item_attr); 50 51 humanize_number(sizetext, 7, items[item].size, "B", HN_AUTOSCALE, 52 HN_DECIMAL); 53 dlg_print_text(partitions, sizetext, 8, &attr); 54 wmove(partitions, y, 25); 55 dlg_print_text(partitions, items[item].type, 15, &attr); 56 wmove(partitions, y, 40); 57 if (items[item].mountpoint != NULL) 58 dlg_print_text(partitions, items[item].mountpoint, 8, &attr); 59 } 60 61 int 62 diskeditor_show(const char *title, const char *cprompt, 63 struct partedit_item *items, int nitems, int *selected, int *nscroll) 64 { 65 WINDOW *dialog, *partitions; 66 char *prompt; 67 const char *buttons[] = 68 { "Create", "Delete", "Modify", "Revert", "Auto", "Exit", NULL }; 69 int x, y; 70 int i; 71 int height, width, min_width; 72 int partlist_height, partlist_width, min_partlist_width; 73 int cur_scroll = 0; 74 int key, fkey; 75 int cur_button = 0, cur_part = 0; 76 int result = DLG_EXIT_UNKNOWN; 77 78 static DLG_KEYS_BINDING binding[] = { 79 ENTERKEY_BINDINGS, 80 DLG_KEYS_DATA( DLGK_ENTER, ' ' ), 81 DLG_KEYS_DATA( DLGK_ITEM_NEXT, KEY_DOWN ), 82 DLG_KEYS_DATA( DLGK_ITEM_PREV, KEY_UP ), 83 DLG_KEYS_DATA( DLGK_FIELD_NEXT, KEY_RIGHT ), 84 DLG_KEYS_DATA( DLGK_FIELD_NEXT, TAB ), 85 DLG_KEYS_DATA( DLGK_FIELD_PREV, KEY_BTAB ), 86 DLG_KEYS_DATA( DLGK_FIELD_PREV, KEY_LEFT ), 87 88 SCROLLKEY_BINDINGS, 89 END_KEYS_BINDING 90 }; 91 92 /* 93 * Set up editor window. 94 */ 95 prompt = dlg_strclone(cprompt); 96 97 min_width = 50; 98 height = width = 0; 99 partlist_height = 10; 100 min_partlist_width = 0; 101 dlg_tab_correct_str(prompt); 102 dlg_button_layout(buttons, &min_width); 103 dlg_auto_size(title, prompt, &height, &width, 2, min_width); 104 height += partlist_height; 105 partlist_width = width - 2*MARGIN; 106 dlg_print_size(height, width); 107 dlg_ctl_size(height, width); 108 109 x = dlg_box_x_ordinate(width); 110 y = dlg_box_y_ordinate(height); 111 112 dialog = dlg_new_window(height, width, y, x); 113 dlg_register_window(dialog, "diskeditorbox", binding); 114 dlg_register_buttons(dialog, "diskeditorbox", buttons); 115 116 dlg_draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr); 117 dlg_draw_bottom_box(dialog); 118 dlg_draw_title(dialog, title); 119 wattrset(dialog, dialog_attr); 120 121 /* Partition list sub-window */ 122 partitions = dlg_sub_window(dialog, partlist_height, partlist_width, 123 y + 3, x + 1); 124 dlg_register_window(partitions, "partlist", binding); 125 dlg_register_buttons(partitions, "partlist", buttons); 126 wattrset(partitions, menubox_attr); 127 128 dlg_draw_buttons(dialog, height - 2*MARGIN, 0, buttons, 129 cur_button, FALSE, width); 130 dlg_print_autowrap(dialog, prompt, height, width); 131 132 if (selected != NULL) 133 cur_part = *selected; 134 if (nscroll != NULL) 135 cur_scroll = *nscroll; 136 if (cur_part - cur_scroll >= partlist_height - 2 || 137 cur_part - cur_scroll < 0) 138 cur_scroll = cur_part; 139 140 repaint: 141 dlg_draw_box(dialog, 3, 1, partlist_height, partlist_width, 142 menubox_border_attr, menubox_attr); 143 for (i = cur_scroll; i < MIN(cur_scroll + partlist_height - 2, nitems); 144 i++) 145 print_partedit_item(partitions, items, i, cur_scroll, 146 i == cur_part); 147 if (nitems > partlist_height - 2) 148 dlg_draw_arrows(partitions, cur_scroll > 0, 149 nitems > cur_scroll + partlist_height - 2, 150 partlist_width - 5, 0, partlist_height - 1); 151 wrefresh(partitions); 152 153 while (result == DLG_EXIT_UNKNOWN) { 154 key = dlg_mouse_wgetch(dialog, &fkey); 155 if ((i = dlg_char_to_button(key, buttons)) >= 0) { 156 cur_button = i; 157 dlg_draw_buttons(dialog, height - 2*MARGIN, 0, buttons, 158 cur_button, FALSE, width); 159 break; 160 } 161 162 if (!fkey) 163 continue; 164 165 switch (key) { 166 case DLGK_FIELD_NEXT: 167 cur_button = dlg_next_button(buttons, cur_button); 168 if (cur_button < 0) 169 cur_button = 0; 170 dlg_draw_buttons(dialog, height - 2*MARGIN, 0, buttons, 171 cur_button, FALSE, width); 172 break; 173 case DLGK_FIELD_PREV: 174 cur_button = dlg_prev_button(buttons, cur_button); 175 if (cur_button < 0) 176 cur_button = 0; 177 dlg_draw_buttons(dialog, height - 2*MARGIN, 0, buttons, 178 cur_button, FALSE, width); 179 break; 180 case DLGK_ITEM_NEXT: 181 if (cur_part == nitems - 1) 182 break; /* End of list */ 183 184 /* Deselect old item */ 185 print_partedit_item(partitions, items, cur_part, 186 cur_scroll, 0); 187 /* Select new item */ 188 cur_part++; 189 if (cur_part - cur_scroll >= partlist_height - 2) { 190 cur_scroll = cur_part; 191 goto repaint; 192 } 193 print_partedit_item(partitions, items, cur_part, 194 cur_scroll, 1); 195 wrefresh(partitions); 196 break; 197 case DLGK_ITEM_PREV: 198 if (cur_part == 0) 199 break; /* Start of list */ 200 201 /* Deselect old item */ 202 print_partedit_item(partitions, items, cur_part, 203 cur_scroll, 0); 204 /* Select new item */ 205 cur_part--; 206 if (cur_part - cur_scroll < 0) { 207 cur_scroll = cur_part; 208 goto repaint; 209 } 210 print_partedit_item(partitions, items, cur_part, 211 cur_scroll, 1); 212 wrefresh(partitions); 213 break; 214 case DLGK_PAGE_NEXT: 215 cur_scroll += (partlist_height - 2); 216 if (cur_scroll + partlist_height - 2 >= nitems) 217 cur_scroll = nitems - (partlist_height - 2); 218 if (cur_part < cur_scroll) 219 cur_part = cur_scroll; 220 goto repaint; 221 case DLGK_PAGE_PREV: 222 cur_scroll -= (partlist_height - 2); 223 if (cur_scroll < 0) 224 cur_scroll = 0; 225 if (cur_part >= cur_scroll + partlist_height - 2) 226 cur_part = cur_scroll; 227 goto repaint; 228 case DLGK_PAGE_FIRST: 229 cur_scroll = 0; 230 cur_part = cur_scroll; 231 goto repaint; 232 case DLGK_PAGE_LAST: 233 cur_scroll = nitems - (partlist_height - 2); 234 cur_part = cur_scroll; 235 goto repaint; 236 case DLGK_ENTER: 237 goto done; 238 default: 239 if (is_DLGK_MOUSE(key)) { 240 cur_button = key - M_EVENT; 241 dlg_draw_buttons(dialog, height - 2*MARGIN, 0, 242 buttons, cur_button, FALSE, width); 243 goto done; 244 } 245 break; 246 } 247 } 248 249 done: 250 if (selected != NULL) 251 *selected = cur_part; 252 if (nscroll != NULL) 253 *nscroll = cur_scroll; 254 255 dlg_del_window(partitions); 256 dlg_del_window(dialog); 257 dlg_mouse_free_regions(); 258 259 return (cur_button); 260 } 261 262