implement very bad resizing support
This commit is contained in:
parent
6729d157f1
commit
fd43f38d2a
1 changed files with 154 additions and 120 deletions
274
src/main.c
274
src/main.c
|
|
@ -13,22 +13,25 @@ You should have received a copy of the GNU General Public License
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <ncurses.h>
|
#include <ncurses.h>
|
||||||
#include <menu.h>
|
#include <menu.h>
|
||||||
#include <panel.h>
|
#include <panel.h>
|
||||||
#include <mwchar/data.h>
|
#include <mwchar/data.h>
|
||||||
|
|
||||||
#define MAX(x, y) (((x) > (y)) ? (x) : (y))
|
#define STR(s) #s
|
||||||
#define MIN(x, y) (((x) < (y)) ? (x) : (y))
|
#define XSTR(s) STR(s)
|
||||||
#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
|
#define MIN_ROWS 24
|
||||||
|
#define MIN_COLS 80
|
||||||
|
#define ERR_TERM_TOO_SMALL "This program requires a terminal that is at least " XSTR(MIN_COLS) "x" XSTR(MIN_ROWS)
|
||||||
|
|
||||||
|
|
||||||
#define mvwclrtobot(win, y, x) (wmove((win), (y), (x)) == ERR ? ERR : wclrtobot((win)))
|
#define mvwclrtobot(win, y, x) (wmove((win), (y), (x)) == ERR ? ERR : wclrtobot((win)))
|
||||||
#define NUM_FIELDS 7
|
void draw_output(WINDOW* win, int race, int sex, int spec, int sign, const int attrs[ATTRIBUTE_COUNT], const int skills[SKILL_COUNT]);
|
||||||
void draw_output(WINDOW* win, int race, int sex, int spec, int sign, int attrs[ATTRIBUTE_COUNT], int skills[SKILL_COUNT]);
|
|
||||||
|
|
||||||
enum FIELDS {
|
enum FIELDS {
|
||||||
RACE, SEX, SPEC, ATTR, SKILL_MAJ, SKILL_MIN, SIGN
|
RACE, SEX, SPEC, ATTR, SKILL_MAJ, SKILL_MIN, SIGN, FIELD_COUNT
|
||||||
};
|
};
|
||||||
typedef struct mw_menu {
|
typedef struct mw_menu {
|
||||||
MENU *m;
|
MENU *m;
|
||||||
|
|
@ -44,6 +47,11 @@ int main() {
|
||||||
WINDOW *win_input, *win_output;
|
WINDOW *win_input, *win_output;
|
||||||
PANEL *panel_input, *panel_output;
|
PANEL *panel_input, *panel_output;
|
||||||
initscr();
|
initscr();
|
||||||
|
if (LINES < MIN_ROWS || COLS < MIN_COLS) {
|
||||||
|
endwin();
|
||||||
|
fprintf(stderr, "%s\n", ERR_TERM_TOO_SMALL);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
cbreak();
|
cbreak();
|
||||||
noecho();
|
noecho();
|
||||||
keypad(stdscr, 1);
|
keypad(stdscr, 1);
|
||||||
|
|
@ -61,19 +69,20 @@ int main() {
|
||||||
int out_skills[SKILL_COUNT] = {0};
|
int out_skills[SKILL_COUNT] = {0};
|
||||||
int out_attrs[ATTRIBUTE_COUNT] = {0};
|
int out_attrs[ATTRIBUTE_COUNT] = {0};
|
||||||
|
|
||||||
int input_col_width = (COLS - 2) / 5;
|
int input_col_width = (MIN_COLS - 2) / 5;
|
||||||
|
int input_col_spacing = (COLS - 2) / 5;
|
||||||
int input_col_height = 6;
|
int input_col_height = 6;
|
||||||
WINDOW *field_windows[NUM_FIELDS];
|
WINDOW *field_windows[FIELD_COUNT];
|
||||||
field_windows[0] = newwin(input_col_height/2, input_col_width, 1, 1 );
|
field_windows[0] = newwin(input_col_height/2, input_col_width, 1, 1 );
|
||||||
field_windows[1] = newwin(input_col_height/2, input_col_width, input_col_height/2+1, 1 );
|
field_windows[1] = newwin(input_col_height/2, input_col_width, input_col_height/2+1, 1 );
|
||||||
field_windows[2] = newwin(input_col_height/2, input_col_width, 1, input_col_width+1);
|
field_windows[2] = newwin(input_col_height/2, input_col_width, 1, input_col_spacing+1);
|
||||||
field_windows[3] = newwin(input_col_height/2, input_col_width, input_col_height/2+1, input_col_width+1);
|
field_windows[3] = newwin(input_col_height/2, input_col_width, input_col_height/2+1, input_col_spacing+1);
|
||||||
field_windows[4] = newwin(input_col_height, input_col_width, 1, input_col_width*2+1);
|
field_windows[4] = newwin(input_col_height, input_col_width, 1, input_col_spacing*2+1);
|
||||||
field_windows[5] = newwin(input_col_height, input_col_width, 1, input_col_width*3+1);
|
field_windows[5] = newwin(input_col_height, input_col_width, 1, input_col_spacing*3+1);
|
||||||
field_windows[6] = newwin(input_col_height, input_col_width, 1, input_col_width*4+1);
|
field_windows[6] = newwin(input_col_height, input_col_width, 1, input_col_spacing*4+1);
|
||||||
|
|
||||||
PANEL *field_panels[NUM_FIELDS];
|
PANEL *field_panels[FIELD_COUNT];
|
||||||
for (int i = 0; i < NUM_FIELDS; ++i) {
|
for (int i = 0; i < FIELD_COUNT; ++i) {
|
||||||
field_panels[i] = new_panel(field_windows[i]);
|
field_panels[i] = new_panel(field_windows[i]);
|
||||||
}
|
}
|
||||||
const char *field_headers[] = {
|
const char *field_headers[] = {
|
||||||
|
|
@ -127,8 +136,8 @@ int main() {
|
||||||
wattroff(w, A_BOLD);
|
wattroff(w, A_BOLD);
|
||||||
}
|
}
|
||||||
mvwchgat(field_windows[selected_field], 0, 0, -1, A_BOLD | A_REVERSE, 0, NULL);
|
mvwchgat(field_windows[selected_field], 0, 0, -1, A_BOLD | A_REVERSE, 0, NULL);
|
||||||
mw_menu field_menus[NUM_FIELDS] = {0};
|
mw_menu field_menus[FIELD_COUNT] = {0};
|
||||||
for (int i = 0; i < NUM_FIELDS; ++i) {
|
for (int i = 0; i < FIELD_COUNT; ++i) {
|
||||||
int x, y;
|
int x, y;
|
||||||
field_menus[i].num_selections = 0;
|
field_menus[i].num_selections = 0;
|
||||||
field_menus[i].max_selections = field_max_selections[i];
|
field_menus[i].max_selections = field_max_selections[i];
|
||||||
|
|
@ -187,115 +196,142 @@ int main() {
|
||||||
ITEM **cur_menu_items;
|
ITEM **cur_menu_items;
|
||||||
int *other_menu_selected;
|
int *other_menu_selected;
|
||||||
while ((ch = getch()) != KEY_F(1)) {
|
while ((ch = getch()) != KEY_F(1)) {
|
||||||
if (in_field_menu == -1) {
|
if (ch == KEY_RESIZE) {
|
||||||
switch(ch) {
|
if (LINES < MIN_ROWS || COLS < MIN_COLS) {
|
||||||
case KEY_LEFT:
|
endwin();
|
||||||
selected_col = (selected_col + 4) % 5;
|
fprintf(stderr, "%s\n", ERR_TERM_TOO_SMALL);
|
||||||
selection_changed = 1;
|
return 1;
|
||||||
break;
|
}
|
||||||
case KEY_RIGHT:
|
werase(win_input);
|
||||||
selected_col = (selected_col + 1) % 5;
|
box(win_input, 0, 0);
|
||||||
selection_changed = 1;
|
int old_spacing = input_col_spacing;
|
||||||
break;
|
input_col_spacing = (COLS - 2) / 5;
|
||||||
case KEY_UP:
|
if (input_col_spacing != old_spacing) {
|
||||||
case KEY_DOWN:
|
move_panel(field_panels[1], input_col_height/2+1, 1 );
|
||||||
selected_row = !selected_row;
|
move_panel(field_panels[2], 1, input_col_spacing+1);
|
||||||
selection_changed = 1;
|
move_panel(field_panels[3], input_col_height/2+1, input_col_spacing+1);
|
||||||
break;
|
move_panel(field_panels[4], 1, input_col_spacing*2+1);
|
||||||
case ' ':
|
move_panel(field_panels[5], 1, input_col_spacing*3+1);
|
||||||
if (selected_field == SEX) {
|
move_panel(field_panels[6], 1, input_col_spacing*4+1);
|
||||||
field_menus[SEX].selections[0] = !field_menus[SEX].selections[0];
|
menu_updated = 1;
|
||||||
mvwclrtobot(selected_field_window, 1, 0);
|
}
|
||||||
waddstr(selected_field_window, field_strings[SEX][field_menus[SEX].selections[0]]);
|
for (int i = 0; i < FIELD_COUNT; ++i) {
|
||||||
menu_updated = 1;
|
if (!field_menus[i].p) continue;
|
||||||
break;
|
int x, y;
|
||||||
}
|
getmaxyx(field_menus[i].w, y, x);
|
||||||
|
move_panel(field_menus[i].p, (LINES-y)/2, (COLS-x)/2);
|
||||||
cur_menu = &field_menus[selected_field];
|
|
||||||
other_menu_selected = NULL;
|
|
||||||
if (selected_field == SKILL_MAJ) {
|
|
||||||
other_menu_selected = field_menus[SKILL_MIN].selections;
|
|
||||||
} else if (selected_field == SKILL_MIN) {
|
|
||||||
other_menu_selected = field_menus[SKILL_MAJ].selections;
|
|
||||||
}
|
|
||||||
cur_menu_items = menu_items(cur_menu->m);
|
|
||||||
if (other_menu_selected != NULL) {
|
|
||||||
for (int i = 0; i < field_items[selected_field]; ++i) {
|
|
||||||
item_opts_on(cur_menu_items[i], O_SELECTABLE);
|
|
||||||
}
|
|
||||||
for (int i = 0; i < cur_menu->max_selections && other_menu_selected[i] != -1; ++i) {
|
|
||||||
item_opts_off(cur_menu_items[other_menu_selected[i]], O_SELECTABLE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
show_panel(cur_menu->p);
|
|
||||||
in_field_menu = selected_field;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (selection_changed) {
|
|
||||||
mvwchgat(selected_field_window, 0, 0, -1, A_BOLD, 0, NULL);
|
|
||||||
if (selected_col < 2) {
|
|
||||||
selected_field = selected_col * 2 + selected_row;
|
|
||||||
} else {
|
|
||||||
selected_field = selected_col + 2;
|
|
||||||
}
|
|
||||||
selected_field_window = field_windows[selected_field];
|
|
||||||
mvwchgat(selected_field_window, 0, 0, -1, A_BOLD | A_REVERSE, 0, NULL);
|
|
||||||
selection_changed = 0;
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
switch(ch) {
|
if (in_field_menu == -1) {
|
||||||
case KEY_UP:
|
switch(ch) {
|
||||||
menu_driver(cur_menu->m, REQ_UP_ITEM);
|
case KEY_LEFT:
|
||||||
break;
|
selected_col = (selected_col + 4) % 5;
|
||||||
case KEY_DOWN:
|
selection_changed = 1;
|
||||||
menu_driver(cur_menu->m, REQ_DOWN_ITEM);
|
break;
|
||||||
break;
|
case KEY_RIGHT:
|
||||||
case KEY_LEFT:
|
selected_col = (selected_col + 1) % 5;
|
||||||
menu_driver(cur_menu->m, REQ_LEFT_ITEM);
|
selection_changed = 1;
|
||||||
break;
|
break;
|
||||||
case KEY_RIGHT:
|
case KEY_UP:
|
||||||
menu_driver(cur_menu->m, REQ_RIGHT_ITEM);
|
case KEY_DOWN:
|
||||||
break;
|
selected_row = !selected_row;
|
||||||
case ' ':
|
selection_changed = 1;
|
||||||
if(cur_menu->max_selections > 1) {
|
break;
|
||||||
ITEM* cur_item = current_item(cur_menu->m);
|
case ' ':
|
||||||
if (item_opts(cur_item) & O_SELECTABLE) {
|
if (selected_field == SEX) {
|
||||||
menu_driver(cur_menu->m, REQ_TOGGLE_ITEM);
|
field_menus[SEX].selections[0] = !field_menus[SEX].selections[0];
|
||||||
if (item_value(cur_item)) {
|
mvwclrtobot(selected_field_window, 1, 0);
|
||||||
if(cur_menu->num_selections == cur_menu->max_selections) {
|
waddstr(selected_field_window, field_strings[SEX][field_menus[SEX].selections[0]]);
|
||||||
menu_driver(cur_menu->m, REQ_TOGGLE_ITEM);
|
menu_updated = 1;
|
||||||
} else {
|
break;
|
||||||
cur_menu->num_selections += 1;
|
}
|
||||||
}
|
|
||||||
} else {
|
cur_menu = &field_menus[selected_field];
|
||||||
cur_menu->num_selections -= 1;
|
other_menu_selected = NULL;
|
||||||
|
if (selected_field == SKILL_MAJ) {
|
||||||
|
other_menu_selected = field_menus[SKILL_MIN].selections;
|
||||||
|
} else if (selected_field == SKILL_MIN) {
|
||||||
|
other_menu_selected = field_menus[SKILL_MAJ].selections;
|
||||||
|
}
|
||||||
|
cur_menu_items = menu_items(cur_menu->m);
|
||||||
|
if (other_menu_selected != NULL) {
|
||||||
|
for (int i = 0; i < field_items[selected_field]; ++i) {
|
||||||
|
item_opts_on(cur_menu_items[i], O_SELECTABLE);
|
||||||
|
}
|
||||||
|
for (int i = 0; i < cur_menu->max_selections && other_menu_selected[i] != -1; ++i) {
|
||||||
|
item_opts_off(cur_menu_items[other_menu_selected[i]], O_SELECTABLE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
show_panel(cur_menu->p);
|
||||||
|
in_field_menu = selected_field;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case '\n':
|
if (selection_changed) {
|
||||||
if (cur_menu->max_selections > 1) {
|
mvwchgat(selected_field_window, 0, 0, -1, A_BOLD, 0, NULL);
|
||||||
for (int i = 0, j = 0; i < field_items[selected_field]; ++i){
|
if (selected_col < 2) {
|
||||||
if(item_value(cur_menu_items[i])) {
|
selected_field = selected_col * 2 + selected_row;
|
||||||
cur_menu->selections[j++] = i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (int j = cur_menu->num_selections; j < cur_menu->max_selections; ++j) {
|
|
||||||
cur_menu->selections[j] = -1;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
cur_menu->selections[0] = item_index(current_item(cur_menu->m));
|
selected_field = selected_col + 2;
|
||||||
}
|
|
||||||
mvwclrtobot(selected_field_window, 1, 0);
|
|
||||||
|
|
||||||
for (int i = 0; i < cur_menu->num_selections; ++i) {
|
|
||||||
mvwaddstr(selected_field_window, i+1, 0, field_strings[selected_field][cur_menu->selections[i]]);
|
|
||||||
}
|
}
|
||||||
|
selected_field_window = field_windows[selected_field];
|
||||||
|
mvwchgat(selected_field_window, 0, 0, -1, A_BOLD | A_REVERSE, 0, NULL);
|
||||||
|
selection_changed = 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
switch(ch) {
|
||||||
|
case KEY_UP:
|
||||||
|
menu_driver(cur_menu->m, REQ_UP_ITEM);
|
||||||
|
break;
|
||||||
|
case KEY_DOWN:
|
||||||
|
menu_driver(cur_menu->m, REQ_DOWN_ITEM);
|
||||||
|
break;
|
||||||
|
case KEY_LEFT:
|
||||||
|
menu_driver(cur_menu->m, REQ_LEFT_ITEM);
|
||||||
|
break;
|
||||||
|
case KEY_RIGHT:
|
||||||
|
menu_driver(cur_menu->m, REQ_RIGHT_ITEM);
|
||||||
|
break;
|
||||||
|
case ' ':
|
||||||
|
if(cur_menu->max_selections > 1) {
|
||||||
|
ITEM* cur_item = current_item(cur_menu->m);
|
||||||
|
if (item_opts(cur_item) & O_SELECTABLE) {
|
||||||
|
menu_driver(cur_menu->m, REQ_TOGGLE_ITEM);
|
||||||
|
if (item_value(cur_item)) {
|
||||||
|
if(cur_menu->num_selections == cur_menu->max_selections) {
|
||||||
|
menu_driver(cur_menu->m, REQ_TOGGLE_ITEM);
|
||||||
|
} else {
|
||||||
|
cur_menu->num_selections += 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
cur_menu->num_selections -= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case '\n':
|
||||||
|
if (cur_menu->max_selections > 1) {
|
||||||
|
for (int i = 0, j = 0; i < field_items[selected_field]; ++i){
|
||||||
|
if(item_value(cur_menu_items[i])) {
|
||||||
|
cur_menu->selections[j++] = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (int j = cur_menu->num_selections; j < cur_menu->max_selections; ++j) {
|
||||||
|
cur_menu->selections[j] = -1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
cur_menu->selections[0] = item_index(current_item(cur_menu->m));
|
||||||
|
}
|
||||||
|
mvwclrtobot(selected_field_window, 1, 0);
|
||||||
|
|
||||||
|
for (int i = 0; i < cur_menu->num_selections; ++i) {
|
||||||
|
mvwaddstr(selected_field_window, i+1, 0, field_strings[selected_field][cur_menu->selections[i]]);
|
||||||
|
}
|
||||||
|
|
||||||
hide_panel(cur_menu->p);
|
hide_panel(cur_menu->p);
|
||||||
menu_updated = 1;
|
menu_updated = 1;
|
||||||
in_field_menu = -1;
|
in_field_menu = -1;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (menu_updated) {
|
if (menu_updated) {
|
||||||
|
|
@ -324,7 +360,7 @@ int main() {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void draw_output(WINDOW* win, int race, int sex, int spec, int sign, int attrs[ATTRIBUTE_COUNT], int skills[SKILL_COUNT]) {
|
void draw_output(WINDOW* win, int race, int sex, int spec, int sign, const int attrs[ATTRIBUTE_COUNT], const int skills[SKILL_COUNT]) {
|
||||||
int y, x;
|
int y, x;
|
||||||
getmaxyx(win, y, x);
|
getmaxyx(win, y, x);
|
||||||
int col_width = x / 5;
|
int col_width = x / 5;
|
||||||
|
|
@ -472,6 +508,4 @@ void draw_output(WINDOW* win, int race, int sex, int spec, int sign, int attrs[A
|
||||||
|
|
||||||
mvwprintw(win, row, col, "%-12s%3d", MW_SKILL_STR[i], final_skills[i]);
|
mvwprintw(win, row, col, "%-12s%3d", MW_SKILL_STR[i], final_skills[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue