예제 #1
0
static void
play_game(struct rnd *rnd)
{
    struct game *game = game_alloc_or_die(rnd);
    struct result result = game_show(game);
    if (result_is_success(result)) result = game_run(game);
    game_hide(game);
    if (!result_is_success(result)) result_print_error(result);
    game_free_or_die(game);
}
예제 #2
0
struct result
app_activate_view(struct app *app, struct view *view)
{
    struct result result = view_enable_keyboard(view);
    if (!result_is_success(result)) return result;
    
    app->active_view = view;
    return result_success();
}
예제 #3
0
struct result
app_run(struct app *app)
{
    sig_t previous_sigwinch_handler = signal(SIGWINCH, terminal_window_did_change);
    if (SIG_ERR == previous_sigwinch_handler) {
        return result_system_error();
    }
    
    struct result result = result_success();
    
    for (int i = 0; i < app->views_count; ++i) {
        result = app->views[i]->create(app->views[i], app);
        if (!result_is_success(result)) break;
    }
    
    if (result_is_success(result)) {
        for (int i = 0; i < app->views_count; ++i) {
            result = app->views[i]->draw(app->views[i], app);
            if (!result_is_success(result)) break;
            wnoutrefresh(app->views[i]->window);
        }
    }
    
    if (!app->active_view) {
        int i = app->views_count - 1;
        result = app_activate_view(app, app->views[i]);
    }
    
    doupdate();
    
    if (result_is_success(result)) {
        result = dispatch_events(app);
    }
    
    for (int i = app->views_count - 1; i >= 0; --i) {
        app->views[i]->destroy(app->views[i], app);
    }
    
    signal(SIGWINCH, previous_sigwinch_handler);
    return result;
}
예제 #4
0
static void
run_tui(void)
{
    struct app *app = app_alloc();
    
    struct result result = app_run(app);
    if (!result_is_success(result)) {
        result_print_error(result);
    }
    
    app_free(app);
}
예제 #5
0
static struct result
dispatch_events(struct app *app)
{
    struct result result = result_success();
    app->is_running = true;
    do {
        int key = view_read_key(app->active_view);
        if (ERR == key) {
            result = result_ncurses_err();
            app_quit(app);
            break;
        }
        
        result = app->active_view->on_key(app->active_view, app, key);
        if (!result_is_success(result)) {
            app_quit(app);
            break;
        }
    } while (app->is_running);
    return result;
}
예제 #6
0
struct result
selection_show(struct selection *selection, WINDOW *parent)
{
    if (!selection) return result_set_system_error(EINVAL);
    
    selection->menu = new_menu(selection->items);
    if (!selection->menu) return result_ncurses_errno();
    
    int menu_height;
    int menu_width;
    int code = scale_menu(selection->menu, &menu_height, &menu_width);
    if (E_OK != code) return result_ncurses_error(code);
    
    int title_width = (int)strlen(selection->title) + 1;
    if (title_width > menu_width) menu_width = title_width;
    
    int main_window_height;
    int main_window_width;
    getmaxyx(parent, main_window_height, main_window_width);
    
    int menu_window_height = menu_height + 4;
    int menu_window_width = menu_width + 5;
    int menu_window_y = (main_window_height - menu_window_height) / 2;
    int menu_window_x = (main_window_width - menu_window_width) / 2;
    
    selection->window = newwin(menu_window_height, menu_window_width,
                               menu_window_y, menu_window_x);
    if (!selection->window) return result_ncurses_err();
    
    code = keypad(selection->window, TRUE);
    if (ERR == code) return result_ncurses_err();
        
    struct result result = draw_window(selection);
    if (!result_is_success(result)) return result;
    
    code = set_menu_win(selection->menu, selection->window);
    if (E_OK != code) return result_ncurses_error(code);
    
    int menu_sub_height = menu_height;
    int menu_sub_width = menu_width;
    int menu_sub_y = 2;
    int menu_sub_x = 2;
    
    selection->sub_window = derwin(selection->window,
                                   menu_sub_height, menu_sub_width,
                                   menu_sub_y, menu_sub_x);
    if (!selection->sub_window) return result_ncurses_err();
    
    code = set_menu_sub(selection->menu, selection->sub_window);
    if (E_OK != code) return result_ncurses_error(code);
    
    selection->index = 0;
    code = post_menu(selection->menu);
    if (E_OK != code) return result_ncurses_error(code);
    
    code = wrefresh(selection->window);
    if (ERR == code) return result_ncurses_err();
        
    result = get_selection(selection);
    if (!result_is_success(result)) return result;
    
    ITEM *selected_item = current_item(selection->menu);
    if (selected_item) selection->index = item_index(selected_item);
    
    code = unpost_menu(selection->menu);
    if (E_OK != code) return result_ncurses_error(code);
    
    code = wclear(selection->window);
    if (ERR == code) return result_ncurses_err();
        
    code = wrefresh(selection->window);
    if (ERR == code) return result_ncurses_err();
    
    code = free_menu(selection->menu);
    if (E_OK != code) return result_ncurses_error(code);
    selection->menu = NULL;
    
    code = delwin(selection->sub_window);
    if (E_OK != code) return result_ncurses_error(code);
    selection->sub_window = NULL;
        
    code = delwin(selection->window);
    if (E_OK != code) return result_ncurses_error(code);
    selection->window = NULL;
    
    return result_success();
}