예제 #1
0
int worldfactory::show_worldgen_tab_modselection(WINDOW *win, WORLDPTR world)
{
    // Use active_mod_order of the world,
    // saves us from writing 'world->active_mod_order' all the time.
    std::vector<std::string> &active_mod_order = world->active_mod_order;
    {
        std::vector<std::string> tmp_mod_order;
        // clear active_mod_order and re-add all the mods, his ensures
        // that changes (like changing dependencies) get updated
        tmp_mod_order.swap(active_mod_order);
        for( auto &elem : tmp_mod_order ) {
            mman_ui->try_add( elem, active_mod_order );
        }
    }

    input_context ctxt("MODMANAGER_DIALOG");
    ctxt.register_updown();
    ctxt.register_action("LEFT", _("Switch to other list"));
    ctxt.register_action("RIGHT", _("Switch to other list"));
    ctxt.register_action("HELP_KEYBINDINGS");
    ctxt.register_action("QUIT");
    ctxt.register_action("NEXT_TAB");
    ctxt.register_action("PREV_TAB");
    ctxt.register_action("CONFIRM", _("Activate / deactive mod"));
    ctxt.register_action("ADD_MOD");
    ctxt.register_action("REMOVE_MOD");
    ctxt.register_action("SAVE_DEFAULT_MODS");

    const int iOffsetX = (TERMX > FULL_SCREEN_WIDTH) ? (TERMX - FULL_SCREEN_WIDTH) / 2 : 0;
    const int iOffsetY = (TERMY > FULL_SCREEN_HEIGHT) ? (TERMY - FULL_SCREEN_HEIGHT) / 2 : 0;

    // lots of small windows so that each section can be drawn to independently of the others as necessary
    WINDOW *w_header1, *w_header2, *w_shift, *w_list, *w_active, *w_description;
    w_header1 = newwin(1, FULL_SCREEN_WIDTH / 2 - 5, 3 + iOffsetY, 1 + iOffsetX);
    w_header2 = newwin(1, FULL_SCREEN_WIDTH / 2 - 4, 3 + iOffsetY,
                       FULL_SCREEN_WIDTH / 2 + 3 + iOffsetX);
    w_shift   = newwin(13, 5, 3 + iOffsetY, FULL_SCREEN_WIDTH / 2 - 3 + iOffsetX);
    w_list    = newwin(11, FULL_SCREEN_WIDTH / 2 - 4, 5 + iOffsetY, iOffsetX);
    w_active  = newwin(11, FULL_SCREEN_WIDTH / 2 - 4, 5 + iOffsetY,
                       FULL_SCREEN_WIDTH / 2 + 2 + iOffsetX);
    w_description = newwin(4, FULL_SCREEN_WIDTH - 2, 19 + iOffsetY, 1 + iOffsetX);

    draw_modselection_borders(win, &ctxt);
    std::vector<std::string> headers;
    headers.push_back(_("Mod List"));
    headers.push_back(_("Mod Load Order"));
    std::vector<WINDOW *> header_windows;
    header_windows.push_back(w_header1);
    header_windows.push_back(w_header2);

    int tab_output = 0;
    int last_active_header = 0;
    size_t active_header = 0;
    size_t useable_mod_count = mman_ui->usable_mods.size();
    int startsel[2] = {0, 0};
    int cursel[2] = {0, 0};

    bool redraw_headers = true;
    bool redraw_shift = true;
    bool redraw_description = true;
    bool redraw_list = true;
    bool redraw_active = true;
    bool selection_changed = false;

    while (tab_output == 0) {
        if (redraw_headers) {
            for (size_t i = 0; i < headers.size(); ++i) {
                werase(header_windows[i]);
                const int header_x = (getmaxx(header_windows[i]) - headers[i].size()) / 2;
                mvwprintz(header_windows[i], 0, header_x , c_cyan, "%s", headers[i].c_str());

                if (active_header == i) {
                    mvwputch(header_windows[i], 0, header_x - 3, c_red, '<');
                    mvwputch(header_windows[i], 0, header_x + headers[i].size() + 2, c_red, '>');
                }
                wrefresh(header_windows[i]);
            }
            redraw_list = true;
            redraw_active = true;
            redraw_shift = true;
            redraw_headers = false;
        }
        if (selection_changed) {
            if (active_header == 0) {
                redraw_list = true;
            }
            if (active_header == 1) {
                redraw_shift = true;
                redraw_active = true;
            }
            selection_changed = false;
            redraw_description = true;
        }
        if (redraw_description) {
            werase(w_description);

            MOD_INFORMATION *selmod = NULL;
            if (mman_ui->usable_mods.empty()) {
                // Do nothing, leave selmod == NULL
            } else if (active_header == 0) {
                selmod = mman->mod_map[mman_ui->usable_mods[cursel[0]]];
            } else if (!active_mod_order.empty()) {
                selmod = mman->mod_map[active_mod_order[cursel[1]]];
            }

            if (selmod != NULL) {
                fold_and_print(w_description, 0, 1, getmaxx(w_description) - 1,
                               c_white, mman_ui->get_information(selmod));
            }
            redraw_description = false;
            wrefresh(w_description);
        }
        if (redraw_list) {
            draw_mod_list( w_list, startsel[0], cursel[0], mman_ui->usable_mods, active_header == 0, _("--NO AVAILABLE MODS--") );
        }
        if (redraw_active) {
            draw_mod_list( w_active, startsel[1], cursel[1], active_mod_order, active_header == 1, _("--NO ACTIVE MODS--") );
        }
        if (redraw_shift) {
            werase(w_shift);
            if (active_header == 1) {
                std::stringstream shift_display;
                // get shift information for whatever is visible in the active list
                for (size_t i = startsel[1], c = 0; i < active_mod_order.size() &&
                     (int)c < getmaxy(w_active); ++i, ++c) {
                    if (mman_ui->can_shift_up(i, active_mod_order)) {
                        shift_display << "<color_blue>+</color> ";
                    } else {
                        shift_display << "<color_dkgray>+</color> ";
                    }
                    if (mman_ui->can_shift_down(i, active_mod_order)) {
                        shift_display << "<color_blue>-</color>";
                    } else {
                        shift_display << "<color_dkgray>-</color>";
                    }
                    shift_display << "\n";
                }
                fold_and_print(w_shift, 2, 1, getmaxx(w_shift), c_white, shift_display.str());
            }
            redraw_shift = false;
            wrefresh(w_shift);
        }
        refresh();

        last_active_header = active_header;
        const int next_header = (active_header == 1) ? 0 : 1;
        const int prev_header = (active_header == 0) ? 1 : 0;

        int selection = (active_header == 0) ? cursel[0] : cursel[1];
        int last_selection = selection;
        unsigned int next_selection = selection + 1;
        int prev_selection = selection - 1;
        if (active_header == 0) {
            next_selection = (next_selection >= useable_mod_count) ? 0 : next_selection;
            prev_selection = (prev_selection < 0) ? useable_mod_count - 1 : prev_selection;
        } else {
            next_selection = (next_selection >= active_mod_order.size()) ? 0 : next_selection;
            prev_selection = (prev_selection < 0) ? active_mod_order.size() - 1 : prev_selection;
        }

        const std::string action = ctxt.handle_input();

        if (action == "DOWN") {
            selection = next_selection;
        } else if (action == "UP") {
            selection = prev_selection;
        } else if (action == "RIGHT") {
            active_header = next_header;
        } else if (action == "LEFT") {
            active_header = prev_header;
        } else if (action == "CONFIRM") {
            if (active_header == 0 && !mman_ui->usable_mods.empty()) {
#ifndef LUA
                if (mman->mod_map[mman_ui->usable_mods[cursel[0]]]->need_lua) {
                    popup(_("Can't add mod. This mod requires Lua support."));
                    redraw_active = true;
                    redraw_shift = true;
                    draw_modselection_borders(win, &ctxt);
                    continue;
                }
#endif
                // try-add
                mman_ui->try_add(mman_ui->usable_mods[cursel[0]], active_mod_order);
                redraw_active = true;
                redraw_shift = true;
            } else if (active_header == 1 && !active_mod_order.empty()) {
                // try-rem
                mman_ui->try_rem(cursel[1], active_mod_order);
                redraw_active = true;
                redraw_shift = true;
                if (active_mod_order.empty()) {
                    // switch back to other list, we can't change
                    // anything in the empty active mods list.
                    active_header = 0;
                }
            }
        } else if (action == "ADD_MOD") {
            if (active_header == 1 && active_mod_order.size() > 1) {
                mman_ui->try_shift('+', cursel[1], active_mod_order);
                redraw_active = true;
                redraw_shift = true;
            }
        } else if (action == "REMOVE_MOD") {
            if (active_header == 1 && active_mod_order.size() > 1) {
                mman_ui->try_shift('-', cursel[1], active_mod_order);
                redraw_active = true;
                redraw_shift = true;
            }
        } else if (action == "NEXT_TAB") {
            tab_output = 1;
        } else if (action == "PREV_TAB") {
            tab_output = -1;
        } else if (action == "SAVE_DEFAULT_MODS") {
            if(mman->set_default_mods(active_mod_order)) {
                popup(_("Saved list of active mods as default"));
                draw_modselection_borders(win, &ctxt);
                redraw_headers = true;
            }
        } else if (action == "HELP_KEYBINDINGS") {
            // Redraw all the things!
            redraw_headers = true;
            redraw_shift = true;
            redraw_description = true;
            redraw_list = true;
            redraw_active = true;
            draw_worldgen_tabs( win, 0 );
            draw_modselection_borders( win, &ctxt );
        } else if (action == "QUIT") {
            tab_output = -999;
        }
        // RESOLVE INPUTS
        if (last_active_header != (int)active_header) {
            redraw_headers = true;
            redraw_shift = true;
            redraw_description = true;
        }
        if (last_selection != selection) {
            if (active_header == 0) {
                redraw_list = true;
                cursel[0] = selection;
            } else {
                redraw_active = true;
                redraw_shift = true;
                cursel[1] = selection;
            }
            redraw_description = true;
        }
        if (active_mod_order.empty()) {
            redraw_active = true;
            cursel[1] = 0;
        }

        if (active_header == 1) {
            if (active_mod_order.empty()) {
                cursel[1] = 0;
            } else {
                if (cursel[1] < 0) {
                    cursel[1] = 0;
                } else if (cursel[1] >= (int)active_mod_order.size()) {
                    cursel[1] = active_mod_order.size() - 1;
                }
            }
        }
        // end RESOLVE INPUTS
    }
    werase(w_header1);
    werase(w_header2);
    werase(w_shift);
    werase(w_list);
    werase(w_active);
    werase(w_description);

    delwin(w_header1);
    delwin(w_header2);
    delwin(w_shift);
    delwin(w_list);
    delwin(w_active);
    delwin(w_description);
    return tab_output;
}
int worldfactory::show_worldgen_tab_modselection(WINDOW *win, WORLDPTR world)
{
    // Use active_mod_order of the world,
    // saves us from writting 'world->active_mod_order' all the time.
    std::vector<std::string> &active_mod_order = world->active_mod_order;
    {
        std::vector<std::string> tmp_mod_order;
        // clear active_mod_order and re-add all the mods, his ensures
        // that changes (like changing depencies) get updated
        tmp_mod_order.swap(active_mod_order);
        for(size_t i = 0; i < tmp_mod_order.size(); i++) {
            mman_ui->try_add(tmp_mod_order[i], active_mod_order);
        }
    }

    const int iOffsetX = (TERMX > FULL_SCREEN_WIDTH) ? (TERMX - FULL_SCREEN_WIDTH) / 2 : 0;
    const int iOffsetY = (TERMY > FULL_SCREEN_HEIGHT) ? (TERMY - FULL_SCREEN_HEIGHT) / 2 : 0;

    // lots of small windows so that each section can be drawn to independently of the others as necessary
    WINDOW *w_header1, *w_header2, *w_shift, *w_list, *w_active, *w_description;
    w_header1 = newwin(1, FULL_SCREEN_WIDTH / 2 - 5, 3 + iOffsetY, 1 + iOffsetX);
    w_header2 = newwin(1, FULL_SCREEN_WIDTH / 2 - 4, 3 + iOffsetY,
                       FULL_SCREEN_WIDTH / 2 + 3 + iOffsetX);
    w_shift   = newwin(13, 5, 3 + iOffsetY, FULL_SCREEN_WIDTH / 2 - 3 + iOffsetX);
    w_list    = newwin(11, FULL_SCREEN_WIDTH / 2 - 4, 5 + iOffsetY, iOffsetX);
    w_active  = newwin(11, FULL_SCREEN_WIDTH / 2 - 4, 5 + iOffsetY,
                       FULL_SCREEN_WIDTH / 2 + 2 + iOffsetX);
    w_description = newwin(6, FULL_SCREEN_WIDTH - 2, 17 + iOffsetY, 1 + iOffsetX);

    draw_modselection_borders(win);
    std::vector<std::string> headers;
    headers.push_back(_("Mod List"));
    headers.push_back(_("Mod Load Order"));
    std::vector<WINDOW *> header_windows;
    header_windows.push_back(w_header1);
    header_windows.push_back(w_header2);

    int tab_output = 0;
    int active_header = 0, last_active_header = -1;
    int useable_mod_count = mman_ui->usable_mods.size();
    int startsel[2] = {0, 0};
    int cursel[2] = {0, 0};

    bool redraw_headers = true;
    bool redraw_shift = true;
    bool redraw_description = true;
    bool redraw_list = true;
    bool redraw_active = true;
    bool selection_changed = false;

    while (tab_output == 0) {
        if (redraw_headers) {
            for (int i = 0; i < headers.size(); ++i) {
                werase(header_windows[i]);
                const int header_x = (getmaxx(header_windows[i]) - headers[i].size()) / 2;
                mvwprintz(header_windows[i], 0, header_x , c_cyan, headers[i].c_str());

                if (active_header == i) {
                    mvwputch(header_windows[i], 0, header_x - 3, c_red, '<');
                    mvwputch(header_windows[i], 0, header_x + headers[i].size() + 2, c_red, '>');
                }
                wrefresh(header_windows[i]);
            }
            redraw_list = true;
            redraw_active = true;
            redraw_shift = true;
            redraw_headers = false;
        }
        if (selection_changed) {
            if (active_header == 0) {
                redraw_list = true;
            }
            if (active_header == 1) {
                redraw_shift = true;
                redraw_active = true;
            }
            selection_changed = false;
            redraw_description = true;
        }
        if (redraw_description) {
            werase(w_description);

            MOD_INFORMATION *selmod = NULL;
            if (mman_ui->usable_mods.empty()) {
                // Do nothing, leave selmod == NULL
            } else if (active_header == 0) {
                selmod = mman->mod_map[mman_ui->usable_mods[cursel[0]]];
            } else if (active_mod_order.size() > 0) {
                selmod = mman->mod_map[active_mod_order[cursel[1]]];
            }

            if (selmod != NULL) {
                fold_and_print(w_description, 2, 1, getmaxx(w_description) - 1,
                               c_white, mman_ui->get_information(selmod).c_str());
            }
            center_print(w_description, 0, c_green, _("Press 's' to save the list of active mods as default"));
            redraw_description = false;
            wrefresh(w_description);
        }
        if (redraw_list) {
            werase(w_list);
            calcStartPos(startsel[0], cursel[0], getmaxy(w_list), useable_mod_count);

            if (useable_mod_count == 0) {
                center_print(w_list, 0, c_red, _("--NO AVAILABLE MODS--"));
            } else {
                std::stringstream list_output;

                for (int i = startsel[0], c = 0; i < useable_mod_count && c < getmaxy(w_list); ++i, ++c) {
                    if (i != cursel[0]) {
                        list_output << std::string(3, ' ');
                    } else {
                        if (active_header == 0) {
                            list_output << "<color_yellow>";
                        } else {
                            list_output << "<color_blue>";
                        }
                        list_output << ">></color> ";
                    }
                    list_output << mman->mod_map[mman_ui->usable_mods[i]]->name << "\n";
                }
                fold_and_print(w_list, 0, 1, getmaxx(w_list) - 1, c_white, list_output.str().c_str());
            }
            draw_scrollbar(w_list, cursel[0], getmaxy(w_list), useable_mod_count, 0, 0);

            wrefresh(w_list);
        }
        if (redraw_active) {
            werase(w_active);
            const int active_count = active_mod_order.size();
            calcStartPos(startsel[1], cursel[1], getmaxy(w_active), active_count);

            if (active_count == 0) {
                center_print(w_active, 0, c_red, _("--NO ACTIVE MODS--"));
            } else {
                std::stringstream list_output;

                for (int i = startsel[1], c = 0; i < active_count && c < getmaxy(w_active); ++i, ++c) {
                    if (i != cursel[1]) {
                        list_output << std::string(3, ' ');
                    } else {
                        if (active_header == 1) {
                            list_output << "<color_yellow>";
                        } else {
                            list_output << "<color_blue>";
                        }
                        list_output << ">></color> ";
                    }
                    list_output << mman->mod_map[active_mod_order[i]]->name << "\n";
                }
                fold_and_print(w_active, 0, 1, getmaxx(w_active) - 1, c_white, list_output.str().c_str());
            }

            draw_scrollbar(w_active, cursel[1], getmaxy(w_active), active_count, 0, 0);

            wrefresh(w_active);
        }
        if (redraw_shift) {
            werase(w_shift);
            if (active_header == 1) {
                std::stringstream shift_display;
                // get shift information for whatever is visible in the active list
                for (int i = startsel[1], c = 0; i < active_mod_order.size() && c < getmaxy(w_active); ++i, ++c) {
                    if (mman_ui->can_shift_up(i, active_mod_order)) {
                        shift_display << "<color_blue>+</color> ";
                    } else {
                        shift_display << "<color_dkgray>+</color> ";
                    }
                    if (mman_ui->can_shift_down(i, active_mod_order)) {
                        shift_display << "<color_blue>-</color>";
                    } else {
                        shift_display << "<color_dkgray>-</color>";
                    }
                    shift_display << "\n";
                }
                fold_and_print(w_shift, 2, 1, getmaxx(w_shift), c_white, shift_display.str().c_str());
            }
            redraw_shift = false;
            wrefresh(w_shift);
        }
        refresh();

        last_active_header = active_header;
        const int next_header = (active_header == 1) ? 0 : 1;
        const int prev_header = (active_header == 0) ? 1 : 0;

        int selection = (active_header == 0) ? cursel[0] : cursel[1];
        int last_selection = selection;
        int next_selection = selection + 1;
        int prev_selection = selection - 1;
        if (active_header == 0) {
            next_selection = (next_selection >= useable_mod_count) ? 0 : next_selection;
            prev_selection = (prev_selection < 0) ? useable_mod_count - 1 : prev_selection;
        } else {
            next_selection = (next_selection >= active_mod_order.size()) ? 0 : next_selection;
            prev_selection = (prev_selection < 0) ? active_mod_order.size() - 1 : prev_selection;
        }

        // GATHER INPUT
        long ch = input();

        switch (ch) {
            case 'j':
                selection = next_selection;
                break;
            case 'k':
                selection = prev_selection;
                break;
            case 'l':
                active_header = next_header;
                break;
            case 'h':
                active_header = prev_header;
                break;
            case '\n':
                if (active_header == 0 && mman_ui->usable_mods.size() > 0) {
                    // try-add
                    mman_ui->try_add(mman_ui->usable_mods[cursel[0]], active_mod_order);
                    redraw_active = true;
                    redraw_shift = true;
                } else if (active_header == 1 && active_mod_order.size() > 0) {
                    // try-rem
                    mman_ui->try_rem(cursel[1], active_mod_order);
                    redraw_active = true;
                    redraw_shift = true;
                    if (active_mod_order.empty()) {
                        // switch back to other list, we can't change
                        // anything in the empty active mods list.
                        active_header = 0;
                    }
                }
                break;
            case '+':
            case '-':
                if (active_header == 1 && active_mod_order.size() > 1) {
                    mman_ui->try_shift(char(ch), cursel[1], active_mod_order);
                    redraw_active = true;
                    redraw_shift = true;
                }
                break;
            case '>':
                tab_output = 1;
                break;
            case '<':
                tab_output = -1;
                break;
            case 's':
            case 'S':
                mman->set_default_mods(active_mod_order);
                popup("Saved list of active mods as default");
                draw_modselection_borders(win);
                redraw_headers = true;
                break;
            case 'q':
            case 'Q':
            case KEY_ESCAPE: // exit!
                tab_output = -999;
                break;
            default:
                break;
        }
        // end GATHER INPUT
        // RESOLVE INPUTS
        if (last_active_header != active_header) {
            redraw_headers = true;
            redraw_shift = true;
            redraw_description = true;
        }
        if (last_selection != selection) {
            if (active_header == 0) {
                redraw_list = true;
                cursel[0] = selection;
            } else {
                redraw_active = true;
                redraw_shift = true;
                cursel[1] = selection;
            }
            redraw_description = true;
        }
        if (active_mod_order.size() == 0) {
            redraw_active = true;
            cursel[1] = -1;
        }

        if (active_header == 1) {
            if (active_mod_order.size() == 0) {
                cursel[1] = -1;
            } else {
                if (cursel[1] < 0) {
                    cursel[1] = 0;
                } else if (cursel[1] >= active_mod_order.size()) {
                    cursel[1] = active_mod_order.size() - 1;
                }
            }
        }
        // end RESOLVE INPUTS
    }
    werase(w_header1);
    werase(w_header2);
    werase(w_shift);
    werase(w_list);
    werase(w_active);
    werase(w_description);

    delwin(w_header1);
    delwin(w_header2);
    delwin(w_shift);
    delwin(w_list);
    delwin(w_active);
    delwin(w_description);
    return tab_output;
}