// callback handler for the squadon selection buttons when they are disabled (in single player) void barracks_squad_change_popup() { // show a popup popup( PF_USE_AFFIRMATIVE_ICON | PF_NO_NETWORKING, 1, POPUP_OK, XSTR("You cannot change your squadron in Single Player mode.", 1445)); }
void uimenu::show() { if (!started) { bool w_auto = (w_width == -1 || w_width == -2 ); bool w_autofold = ( w_width == -2); int realtextwidth = 0; if ( w_auto ) { w_width = 4; } bool h_auto = (w_height == -1); if ( h_auto ) { w_height = 4; } std::vector<int> autoassign; autoassign.clear(); int pad = pad_left + pad_right + 2; for ( int i = 0; i < entries.size(); i++ ) { int txtwidth = utf8_width(entries[ i ].txt.c_str()); if(entries[ i ].enabled) { if( entries[ i ].hotkey > 0 ) { keymap[ entries[ i ].hotkey ] = i; } else if ( entries[ i ].hotkey == -1 ) { autoassign.push_back(i); } if ( entries[ i ].retval == -1 ) { entries[ i ].retval = i; } if ( w_auto && w_width < txtwidth + pad + 4 ) { w_width = txtwidth + pad + 4; } } else { if ( w_auto && w_width < txtwidth + pad + 4 ) { w_width = txtwidth + pad + 4; // todo: or +5 if header } } } if ( autoassign.size() > 0 ) { for ( int a = 0; a < autoassign.size(); a++ ) { int palloc = autoassign[ a ]; if ( palloc < 9 ) { entries[ palloc ].hotkey = palloc + 49; // 1-9; } else if ( palloc == 9 ) { entries[ palloc ].hotkey = palloc + 39; // 0; } else if ( palloc < 36 ) { entries[ palloc ].hotkey = palloc + 87; // a-z } else if ( palloc < 61 ) { entries[ palloc ].hotkey = palloc + 29; // A-Z } if ( palloc < 61 ) { keymap[ entries[ palloc ].hotkey ] = palloc; } } } if (w_auto && w_width > TERMX) { w_width = TERMX; } if(text.size() > 0 ) { int twidth = utf8_width(text.c_str()); if ( textwidth == -1 ) { if ( w_autofold || !w_auto ) { realtextwidth = w_width - 4; } else { realtextwidth = twidth; if ( twidth + 4 > w_width ) { if ( realtextwidth + 4 > TERMX ) { realtextwidth = TERMX - 4; } w_width = realtextwidth + 4; } } } else if ( textwidth != -1 ) { realtextwidth = textwidth; } textformatted = foldstring(text, realtextwidth); } if (h_auto) { w_height = 2 + textformatted.size() + entries.size(); } vmax = entries.size(); if ( w_height > TERMY ) { w_height = TERMY; } if ( vmax + 2 + textformatted.size() > w_height ) { vmax = w_height - 2 - textformatted.size(); if ( vmax < 1 ) { popup("Can't display menu options, %d %d available screen rows are occupied by\n'%s\n(snip)\n%s'\nThis is probably a bug.\n", textformatted.size(),TERMY,textformatted[0].c_str(),textformatted[textformatted.size()-1].c_str() ); } } if (w_x == -1) { w_x = int((TERMX - w_width) / 2); } if (w_y == -1) { w_y = int((TERMY - w_height) / 2); } window = newwin(w_height, w_width, w_y, w_x); werase(window); wattron(window, border_color); wborder(window, LINE_XOXO, LINE_XOXO, LINE_OXOX, LINE_OXOX, LINE_OXXO, LINE_OOXX, LINE_XXOO, LINE_XOOX ); wattroff(window, border_color); if( title.size() > 0 ) { mvwprintz(window, 0, 1, border_color, "< "); wprintz(window, title_color, "%s", title.c_str() ); wprintz(window, border_color, " >"); } started = true; } std::string padspaces = std::string(w_width - 2 - pad_left - pad_right, ' '); for ( int i = 0; i < textformatted.size(); i++ ) { mvwprintz(window, 1+i, 2, text_color, "%s", textformatted[i].c_str()); } int estart = textformatted.size() + 1; // todo fold text + get offset if ( selected < vshift ) { vshift=selected; } else if ( selected >= vshift + vmax ) { vshift=1+selected-vmax; } for ( int ei = vshift, si=0; si < vmax; ei++,si++ ) { if ( ei < entries.size() ) { nc_color co = ( ei == selected ? hilight_color : ( entries[ ei ].enabled ? text_color : disabled_color ) ); if ( hilight_full ) { mvwprintz(window, estart + si, pad_left + 1, co , "%s", padspaces.c_str()); } if(entries[ ei ].enabled && entries[ ei ].hotkey > 33 && entries[ ei ].hotkey < 126 ) { mvwprintz(window, estart + si, pad_left + 2, ( ei == selected ? hilight_color : hotkey_color ) , "%c", entries[ ei ].hotkey); } mvwprintz(window, estart + si, pad_left + 4, co, "%s", entries[ ei ].txt.c_str() ); } else { mvwprintz(window, estart + si, pad_left + 1, c_ltgray , "%s", padspaces.c_str()); } } wrefresh(window); }
void complete_vehicle (game *g) { if (g->u.activity.values.size() < 7) { debugmsg ("Invalid activity ACT_VEHICLE values:%d", g->u.activity.values.size()); return; } vehicle *veh = g->m.veh_at (g->u.activity.values[0], g->u.activity.values[1]); if (!veh) { debugmsg ("Activity ACT_VEHICLE: vehicle not found"); return; } char cmd = (char) g->u.activity.index; int dx = g->u.activity.values[4]; int dy = g->u.activity.values[5]; int part = g->u.activity.values[6]; int type = g->u.activity.values[7]; std::vector<component> tools; int welder_charges = ((it_tool *) g->itypes["welder"])->charges_per_use; int welder_crude_charges = ((it_tool *) g->itypes["welder_crude"])->charges_per_use; itype_id itm; int partnum; item used_item; bool broken; int replaced_wheel; std::vector<int> parts; int dd = 2; switch (cmd) { case 'i': partnum = veh->install_part (dx, dy, (vpart_id) part); if(partnum < 0) debugmsg ("complete_vehicle install part fails dx=%d dy=%d id=%d", dx, dy, part); used_item = consume_vpart_item (g, (vpart_id) part); veh->get_part_properties_from_item(g, partnum, used_item); //transfer damage, etc. tools.push_back(component("welder", welder_charges)); tools.push_back(component("welder_crude", welder_crude_charges)); tools.push_back(component("toolset", welder_charges/20)); g->consume_tools(&g->u, tools, true); if ( part == vp_head_light ) { // Need map-relative coordinates to compare to output of look_around. int gx, gy; // Need to call coord_translate() directly since it's a new part. veh->coord_translate(dx, dy, gx, gy); // Stash offset and set it to the location of the part so look_around will start there. int px = g->u.view_offset_x; int py = g->u.view_offset_y; g->u.view_offset_x = veh->global_x() + gx - g->u.posx; g->u.view_offset_y = veh->global_y() + gy - g->u.posy; popup("Choose a facing direction for the new headlight."); point headlight_target = g->look_around(); // Restore previous view offsets. g->u.view_offset_x = px; g->u.view_offset_y = py; int delta_x = headlight_target.x - (veh->global_x() + gx); int delta_y = headlight_target.y - (veh->global_y() + gy); const double PI = 3.14159265358979f; int dir = (atan2(delta_y, delta_x) * 180.0 / PI); dir -= veh->face.dir(); while(dir < 0) dir += 360; while(dir > 360) dir -= 360; veh->parts[partnum].direction = dir; } g->add_msg (_("You install a %s into the %s."), vpart_list[part].name.c_str(), veh->name.c_str()); g->u.practice (g->turn, "mechanics", vpart_list[part].difficulty * 5 + 20); break; case 'r': if (veh->parts[part].hp <= 0) { used_item = consume_vpart_item (g, veh->parts[part].id); tools.push_back(component("wrench", -1)); g->consume_tools(&g->u, tools, true); tools.clear(); dd = 0; veh->insides_dirty = true; } tools.push_back(component("welder", welder_charges)); tools.push_back(component("welder_crude", welder_crude_charges)); tools.push_back(component("toolset", welder_charges/20)); g->consume_tools(&g->u, tools, true); veh->parts[part].hp = veh->part_info(part).durability; g->add_msg (_("You repair the %s's %s."), veh->name.c_str(), veh->part_info(part).name.c_str()); g->u.practice (g->turn, "mechanics", (vpart_list[part].difficulty + dd) * 5 + 20); break; case 'f': if (!g->pl_refill_vehicle(*veh, part, true)) debugmsg ("complete_vehicle refill broken"); g->pl_refill_vehicle(*veh, part); break; case 'o': // Dump contents of part at player's feet, if any. for (int i = 0; i < veh->parts[part].items.size(); i++) g->m.add_item_or_charges (g->u.posx, g->u.posy, veh->parts[part].items[i]); veh->parts[part].items.clear(); broken = veh->parts[part].hp <= 0; if (!broken) { used_item = veh->item_from_part( part ); g->m.add_item_or_charges(g->u.posx, g->u.posy, used_item); if(type!=SEL_JACK) // Changing tires won't make you a car mechanic g->u.practice (g->turn, "mechanics", 2 * 5 + 20); } if (veh->parts.size() < 2) { g->add_msg (_("You completely dismantle %s."), veh->name.c_str()); g->u.activity.type = ACT_NULL; g->m.destroy_vehicle (veh); } else { g->add_msg (_("You remove %s%s from %s."), broken? rm_prefix(_("<veh>broken ")).c_str() : "", veh->part_info(part).name.c_str(), veh->name.c_str()); veh->remove_part (part); } break; case 's': g->u.siphon( g, veh, "gasoline" ); break; case 'c': parts = veh->parts_at_relative( dx, dy ); if( parts.size() ) { item removed_wheel; replaced_wheel = veh->part_with_feature( parts[0], "WHEEL", false ); broken = veh->parts[replaced_wheel].hp <= 0; if( replaced_wheel != -1 ) { removed_wheel = veh->item_from_part( replaced_wheel ); veh->remove_part( replaced_wheel ); g->add_msg( _("You replace one of the %s's tires with %s."), veh->name.c_str(), vpart_list[part].name.c_str() ); } else { debugmsg( "no wheel to remove when changing wheels." ); return; } partnum = veh->install_part( dx, dy, (vpart_id) part ); if( partnum < 0 ) debugmsg ("complete_vehicle tire change fails dx=%d dy=%d id=%d", dx, dy, part); used_item = consume_vpart_item( g, (vpart_id) part ); veh->get_part_properties_from_item( g, partnum, used_item ); //transfer damage, etc. // Place the removed wheel on the map last so consume_vpart_item() doesn't pick it. if ( !broken ) { g->m.add_item_or_charges( g->u.posx, g->u.posy, removed_wheel ); } } break; case 'd': g->u.siphon( g, veh, "water" ); break; default:; } }
void construction_menu() { static bool hide_unconstructable = false; // only display constructions the player can theoretically perform std::vector<std::string> available; std::map<std::string, std::vector<std::string>> cat_available; load_available_constructions( available, cat_available, hide_unconstructable ); if( available.empty() ) { popup( _( "You can not construct anything here." ) ); return; } int w_height = TERMY; if( ( int )available.size() + 2 < w_height ) { w_height = available.size() + 2; } if( w_height < FULL_SCREEN_HEIGHT ) { w_height = FULL_SCREEN_HEIGHT; } const int w_width = std::max( FULL_SCREEN_WIDTH, TERMX * 2 / 3); const int w_y0 = ( TERMY > w_height ) ? ( TERMY - w_height ) / 2 : 0; const int w_x0 = ( TERMX > w_width ) ? ( TERMX - w_width ) / 2 : 0; WINDOW_PTR w_con_ptr {newwin( w_height, w_width, w_y0, w_x0 )}; WINDOW *const w_con = w_con_ptr.get(); const int w_list_width = int( .375 * w_width ); const int w_list_height = w_height - 4; const int w_list_x0 = 1; WINDOW_PTR w_list_ptr {newwin( w_list_height, w_list_width, w_y0 + 3, w_x0 + w_list_x0 )}; WINDOW *const w_list = w_list_ptr.get(); draw_grid( w_con, w_list_width + w_list_x0 ); //tabcount needs to be increased to add more categories int tabcount = 10; std::string construct_cat[] = {_( "All" ), _( "Constructions" ), _( "Furniture" ), _( "Digging and Mining" ), _( "Repairing" ), _( "Reinforcing" ), _( "Decorative" ), _( "Farming and Woodcutting" ), _( "Others" ), _( "Filter" ) }; bool update_info = true; bool update_cat = true; bool isnew = true; int tabindex = 0; int select = 0; int offset = 0; bool exit = false; std::string category_name = ""; std::vector<std::string> constructs; //storage for the color text so it can be scrolled std::vector< std::vector < std::string > > construct_buffers; std::vector<std::string> full_construct_buffer; std::vector<int> construct_buffer_breakpoints; int total_project_breakpoints = 0; int current_construct_breakpoint = 0; bool previous_hide_unconstructable = false; //track the cursor to determine when to refresh the list of construction recipes int previous_tabindex = -1; int previous_select = -1; const inventory &total_inv = g->u.crafting_inventory(); input_context ctxt( "CONSTRUCTION" ); ctxt.register_action( "UP", _( "Move cursor up" ) ); ctxt.register_action( "DOWN", _( "Move cursor down" ) ); ctxt.register_action( "RIGHT", _( "Move tab right" ) ); ctxt.register_action( "LEFT", _( "Move tab left" ) ); ctxt.register_action( "PAGE_UP" ); ctxt.register_action( "PAGE_DOWN" ); ctxt.register_action( "CONFIRM" ); ctxt.register_action( "TOGGLE_UNAVAILABLE_CONSTRUCTIONS" ); ctxt.register_action( "QUIT" ); ctxt.register_action( "HELP_KEYBINDINGS" ); ctxt.register_action( "FILTER" ); std::string filter; int previous_index = 0; do { if( update_cat ) { update_cat = false; switch( tabindex ) { case 0: category_name = "ALL"; break; case 1: category_name = "CONSTRUCT"; break; case 2: category_name = "FURN"; break; case 3: category_name = "DIG"; break; case 4: category_name = "REPAIR"; break; case 5: category_name = "REINFORCE"; break; case 6: category_name = "DECORATE"; break; case 7: category_name = "FARM_WOOD"; break; case 8: category_name = "OTHER"; break; case 9: category_name = "FILTER"; break; } if( category_name == "ALL" ) { constructs = available; previous_index = tabindex; } else if( category_name == "FILTER" ) { constructs.clear(); std::copy_if( available.begin(), available.end(), std::back_inserter( constructs ), [&](const std::string &a){ return lcmatch(a, filter); } ); } else { constructs = cat_available[category_name]; previous_index = tabindex; } if( isnew ){ if( !uistate.last_construction.empty() ){ select = std::distance(constructs.begin(), std::find( constructs.begin(), constructs.end(), uistate.last_construction )); } filter = uistate.construction_filter; } } // Erase existing tab selection & list of constructions mvwhline( w_con, 1, 1, ' ', w_list_width ); werase( w_list ); // Print new tab listing mvwprintz( w_con, 1, 1, c_yellow, "<< %s >>", construct_cat[tabindex].c_str() ); // Determine where in the master list to start printing calcStartPos( offset, select, w_list_height, constructs.size() ); // Print the constructions between offset and max (or how many will fit) for( size_t i = 0; ( int )i < w_list_height && ( i + offset ) < constructs.size(); i++ ) { int current = i + offset; std::string con_name = constructs[current]; bool highlight = ( current == select ); trim_and_print( w_list, i, 0, w_list_width, construction_color( con_name, highlight ), "%s", con_name.c_str() ); } if( update_info ) { update_info = false; // Clear out lines for tools & materials const int pos_x = w_list_width + w_list_x0 + 2; const int available_window_width = w_width - pos_x - 1; for( int i = 1; i < w_height - 1; i++ ) { mvwhline( w_con, i, pos_x, ' ', available_window_width ); } nc_color color_stage = c_white; std::vector<std::string> notes; notes.push_back( string_format( _( "Press %s or %s to tab." ), ctxt.get_desc( "LEFT" ).c_str(), ctxt.get_desc( "RIGHT" ).c_str() ) ); notes.push_back( string_format( _( "Press %s to search." ), ctxt.get_desc( "FILTER" ).c_str() ) ); notes.push_back( string_format( _( "Press %s to toggle unavailable constructions." ), ctxt.get_desc( "TOGGLE_UNAVAILABLE_CONSTRUCTIONS" ).c_str() ) ); notes.push_back( string_format( _( "Press %s to view and edit key-bindings." ), ctxt.get_desc( "HELP_KEYBINDINGS" ).c_str() ) ); //leave room for top and bottom UI text const int available_buffer_height = w_height - 3 - 3 - (int)notes.size(); // print the hotkeys regardless of if there are constructions for( size_t i = 0; i < notes.size(); ++i ) { trim_and_print( w_con, w_height - 1 - (int)notes.size() + (int)i, pos_x, available_window_width, c_white, "%s", notes[i].c_str() ); } if( !constructs.empty() ) { if( select >= (int) constructs.size() ){ select = 0; } std::string current_desc = constructs[select]; // Print construction name trim_and_print( w_con, 1, pos_x, available_window_width, c_white, "%s", current_desc.c_str() ); //only reconstruct the project list when moving away from the current item, or when changing the display mode if( previous_select != select || previous_tabindex != tabindex || previous_hide_unconstructable != hide_unconstructable ) { previous_select = select; previous_tabindex = tabindex; previous_hide_unconstructable = hide_unconstructable; //construct the project list buffer // Print stages and their requirement. std::vector<construction *> options = constructions_by_desc( current_desc ); construct_buffers.clear(); total_project_breakpoints = 0; current_construct_breakpoint = 0; construct_buffer_breakpoints.clear(); full_construct_buffer.clear(); int stage_counter = 0; for( std::vector<construction *>::iterator it = options.begin(); it != options.end(); ++it ) { stage_counter++; construction *current_con = *it; if( hide_unconstructable && !can_construct( *current_con ) ) { continue; } // Update the cached availability of components and tools in the requirement object current_con->requirements->can_make_with_inventory( total_inv ); std::vector<std::string> current_buffer; std::ostringstream current_line; // display result only if more than one step. // Assume single stage constructions should be clear // in their description what their result is. if( current_con->post_terrain != "" && options.size() > 1 ) { //also print out stage number when multiple stages are available current_line << _( "Stage #" ) << stage_counter; current_buffer.push_back( current_line.str() ); current_line.str( "" ); std::string result_string; if( current_con->post_is_furniture ) { result_string = furn_str_id( current_con->post_terrain ).obj().name; } else { result_string = ter_str_id( current_con->post_terrain ).obj().name; } current_line << "<color_" << string_from_color( color_stage ) << ">" << string_format( _( "Result: %s" ), result_string.c_str() ) << "</color>"; std::vector<std::string> folded_result_string = foldstring( current_line.str(), available_window_width ); current_buffer.insert( current_buffer.end(), folded_result_string.begin(), folded_result_string.end() ); } current_line.str( "" ); // display required skill and difficulty int pskill = g->u.get_skill_level( current_con->skill ); int diff = ( current_con->difficulty > 0 ) ? current_con->difficulty : 0; current_line << "<color_" << string_from_color( ( pskill >= diff ? c_white : c_red ) ) << ">" << string_format( _( "Skill Req: %d (%s)" ), diff, current_con->skill.obj().name().c_str() ) << "</color>"; current_buffer.push_back( current_line.str() ); // TODO: Textify pre_flags to provide a bit more information. // Example: First step of dig pit could say something about // requiring diggable ground. current_line.str( "" ); if( current_con->pre_terrain != "" ) { std::string require_string; if( current_con->pre_is_furniture ) { require_string = furn_str_id( current_con->pre_terrain ).obj().name; } else { require_string = ter_str_id( current_con->pre_terrain ).obj().name; } current_line << "<color_" << string_from_color( color_stage ) << ">" << string_format( _( "Requires: %s" ), require_string.c_str() ) << "</color>"; std::vector<std::string> folded_result_string = foldstring( current_line.str(), available_window_width ); current_buffer.insert( current_buffer.end(), folded_result_string.begin(), folded_result_string.end() ); } // get pre-folded versions of the rest of the construction project to be displayed later // get time needed std::vector<std::string> folded_time = current_con->get_folded_time_string( available_window_width ); current_buffer.insert( current_buffer.end(), folded_time.begin(), folded_time.end() ); std::vector<std::string> folded_tools = current_con->requirements->get_folded_tools_list( available_window_width, color_stage, total_inv ); current_buffer.insert( current_buffer.end(), folded_tools.begin(), folded_tools.end() ); std::vector<std::string> folded_components = current_con->requirements->get_folded_components_list( available_window_width, color_stage, total_inv ); current_buffer.insert( current_buffer.end(), folded_components.begin(), folded_components.end() ); construct_buffers.push_back( current_buffer ); } //determine where the printing starts for each project, so it can be scrolled to those points size_t current_buffer_location = 0; for( size_t i = 0; i < construct_buffers.size(); i++ ) { construct_buffer_breakpoints.push_back( static_cast<int>( current_buffer_location ) ); full_construct_buffer.insert( full_construct_buffer.end(), construct_buffers[i].begin(), construct_buffers[i].end() ); //handle text too large for one screen if( construct_buffers[i].size() > static_cast<size_t>( available_buffer_height ) ) { construct_buffer_breakpoints.push_back( static_cast<int>( current_buffer_location + static_cast<size_t>( available_buffer_height ) ) ); } current_buffer_location += construct_buffers[i].size(); if( i < construct_buffers.size() - 1 ) { full_construct_buffer.push_back( std::string( "" ) ); current_buffer_location++; } } total_project_breakpoints = static_cast<int>( construct_buffer_breakpoints.size() ); } if( current_construct_breakpoint > 0 ) { // Print previous stage indicator if breakpoint is past the beginning trim_and_print( w_con, 2, pos_x, available_window_width, c_white, _( "Press %s to show previous stage(s)." ), ctxt.get_desc( "PAGE_UP" ).c_str() ); } if( static_cast<size_t>( construct_buffer_breakpoints[current_construct_breakpoint] + available_buffer_height ) < full_construct_buffer.size() ) { // Print next stage indicator if more breakpoints are remaining after screen height trim_and_print( w_con, w_height - 2 - (int)notes.size(), pos_x, available_window_width, c_white, _( "Press %s to show next stage(s)." ), ctxt.get_desc( "PAGE_DOWN" ).c_str() ); } // Leave room for above/below indicators int ypos = 3; nc_color stored_color = color_stage; for( size_t i = static_cast<size_t>( construct_buffer_breakpoints[current_construct_breakpoint] ); i < full_construct_buffer.size(); i++ ) { //the value of 3 is from leaving room at the top of window if( ypos > available_buffer_height + 3 ) { break; } print_colored_text( w_con, ypos++, ( w_list_width + w_list_x0 + 2 ), stored_color, color_stage, full_construct_buffer[i] ); } } } // Finished updating draw_scrollbar( w_con, select, w_list_height, constructs.size(), 3 ); wrefresh( w_con ); wrefresh( w_list ); const std::string action = ctxt.handle_input(); if( action == "FILTER" ){ filter = string_input_popup( _( "Search" ), 50, filter, "", _( "Filter" ), 100, false ); if( !filter.empty() ){ update_info = true; update_cat = true; tabindex = 9; select = 0; }else if( previous_index !=9 ){ tabindex = previous_index; update_info = true; update_cat = true; select = 0; } uistate.construction_filter = filter; } else if( action == "DOWN" ) { update_info = true; if( select < ( int )constructs.size() - 1 ) { select++; } else { select = 0; } } else if( action == "UP" ) { update_info = true; if( select > 0 ) { select--; } else { select = constructs.size() - 1; } } else if( action == "LEFT" ) { update_info = true; update_cat = true; select = 0; tabindex--; if( tabindex < 0 ) { tabindex = tabcount - 1; } } else if( action == "RIGHT" ) { update_info = true; update_cat = true; select = 0; tabindex = ( tabindex + 1 ) % tabcount; } else if( action == "PAGE_UP" ) { update_info = true; if( current_construct_breakpoint > 0 ) { current_construct_breakpoint--; } if( current_construct_breakpoint < 0 ) { current_construct_breakpoint = 0; } } else if( action == "PAGE_DOWN" ) { update_info = true; if( current_construct_breakpoint < total_project_breakpoints - 1 ) { current_construct_breakpoint++; } if( current_construct_breakpoint >= total_project_breakpoints ) { current_construct_breakpoint = total_project_breakpoints - 1; } } else if( action == "QUIT" ) { exit = true; } else if( action == "HELP_KEYBINDINGS" ) { draw_grid( w_con, w_list_width + w_list_x0 ); } else if( action == "TOGGLE_UNAVAILABLE_CONSTRUCTIONS" ) { update_info = true; update_cat = true; hide_unconstructable = !hide_unconstructable; select = 0; offset = 0; load_available_constructions( available, cat_available, hide_unconstructable ); } else if( action == "CONFIRM" ) { if( constructs.empty() || select >= (int) constructs.size() ){ continue;// Nothing to be done here } if( player_can_build( g->u, total_inv, constructs[select] ) ) { place_construction( constructs[select] ); uistate.last_construction = constructs[select]; exit = true; } else { popup( _( "You can't build that!" ) ); draw_grid( w_con, w_list_width + w_list_x0 ); update_info = true; } } } while( !exit ); w_list_ptr.reset(); w_con_ptr.reset(); g->refresh_all(); }
void construction_menu() { static bool hide_unconstructable = false; // only display constructions the player can theoretically perform std::vector<std::string> available; load_available_constructions( available, hide_unconstructable ); if(available.empty()) { popup(_("You can not construct anything here.")); return; } int iMaxY = TERMY; if (available.size() + 2 < iMaxY) { iMaxY = available.size() + 2; } if (iMaxY < FULL_SCREEN_HEIGHT) { iMaxY = FULL_SCREEN_HEIGHT; } WINDOW *w_con = newwin( iMaxY, FULL_SCREEN_WIDTH, (TERMY > iMaxY) ? (TERMY - iMaxY) / 2 : 0, (TERMX > FULL_SCREEN_WIDTH) ? (TERMX - FULL_SCREEN_WIDTH) / 2 : 0 ); draw_border(w_con); mvwprintz(w_con, 0, 8, c_ltred, _(" Construction ")); mvwputch(w_con, 0, 30, c_ltgray, LINE_OXXX); mvwputch(w_con, iMaxY - 1, 30, c_ltgray, LINE_XXOX); for( int i = 1; i < iMaxY - 1; ++i ) { mvwputch(w_con, i, 30, c_ltgray, LINE_XOXO); } wrefresh(w_con); bool update_info = true; int select = 0; int chosen = 0; long ch; bool exit = false; inventory total_inv = g->crafting_inventory(&(g->u)); do { // Erase existing list of constructions for( int i = 1; i < iMaxY - 1; i++ ) { for( int j = 1; j < 30; j++ ) { mvwputch(w_con, i, j, c_black, ' '); } } //Draw Scrollbar draw_scrollbar(w_con, select, iMaxY - 2, available.size(), 1); // Determine where in the master list to start printing //int offset = select - 11; int offset = 0; if (select >= iMaxY - 2) { offset = select - iMaxY + 3; } // Print the constructions between offset and max (or how many will fit) for (int i = 0; i < iMaxY - 2 && (i + offset) < available.size(); i++) { int current = i + offset; nc_color col = (player_can_build(g->u, total_inv, available[current]) ? c_white : c_dkgray); // Map menu items to hotkey letters, skipping j, k, l, and q. unsigned char hotkey = 97 + current; if (hotkey > 122) { hotkey = hotkey - 58; } if (current == select) { col = hilite(col); } // print construction name with limited length. // limit(28) = 30(column len) - 2(letter + ' '). mvwprintz(w_con, 1 + i, 1, col, "%c %s", hotkey, utf8_substr(available[current].c_str(), 0, 27).c_str()); } if (update_info) { update_info = false; std::string current_desc = available[select]; // Clear out lines for tools & materials for (int i = 1; i < iMaxY - 1; i++) { for (int j = 31; j < 79; j++) { mvwputch(w_con, i, j, c_black, ' '); } } // Print instructions for toggling recipe hiding. mvwprintz(w_con, 1, 31, c_white, "%s", _("Press ';' to toggle unavailable constructions.")); // Print consruction name mvwprintz(w_con, 2, 31, c_white, "%s", current_desc.c_str()); // Print stages and their requirement int posx = 33, posy = 2; std::vector<construction *> options = constructions_by_desc(current_desc); for( unsigned i = 0; i < options.size(); ++i) { construction *current_con = options[i]; if( hide_unconstructable && !can_construct(current_con) ) { continue; } nc_color color_stage = c_white; // display required skill and difficulty int pskill = g->u.skillLevel(current_con->skill); int diff = (current_con->difficulty > 0) ? current_con->difficulty : 0; posy++; mvwprintz(w_con, posy, 31, c_white, _("Skill: %s"), Skill::skill(current_con->skill)->name().c_str()); posy++; mvwprintz(w_con, posy, 31, (pskill >= diff ? c_white : c_red), _("Difficulty: %d"), diff); // display required terrain if (current_con->pre_terrain != "") { posy++; if (current_con->pre_is_furniture) { mvwprintz(w_con, posy, 31, color_stage, _("Replaces: %s"), furnmap[current_con->pre_terrain].name.c_str()); } else { mvwprintz(w_con, posy, 31, color_stage, _("Replaces: %s"), termap[current_con->pre_terrain].name.c_str()); } } // display result if (current_con->post_terrain != "") { posy++; if (current_con->post_is_furniture) { mvwprintz(w_con, posy, 31, color_stage, _("Result: %s"), furnmap[current_con->post_terrain].name.c_str()); } else { mvwprintz(w_con, posy, 31, color_stage, _("Result: %s"), termap[current_con->post_terrain].name.c_str()); } } // display time needed posy++; mvwprintz(w_con, posy, 31, color_stage, _("Time: %1d minutes"), current_con->time); // Print tools std::vector<bool> has_tool; posy++; posx = 33; for (int i = 0; i < current_con->tools.size(); i++) { has_tool.push_back(false); mvwprintz(w_con, posy, posx - 2, c_white, ">"); for (unsigned j = 0; j < current_con->tools[i].size(); j++) { itype_id tool = current_con->tools[i][j].type; nc_color col = c_red; if (total_inv.has_amount(tool, 1)) { has_tool[i] = true; col = c_green; } int length = utf8_width(item_controller->find_template(tool)->name.c_str()); if( posx + length > FULL_SCREEN_WIDTH - 1 ) { posy++; posx = 33; } mvwprintz(w_con, posy, posx, col, item_controller->find_template(tool)->name.c_str()); posx += length + 1; // + 1 for an empty space if (j < current_con->tools[i].size() - 1) { // "OR" if there's more if (posx > FULL_SCREEN_WIDTH - 3) { posy++; posx = 33; } mvwprintz(w_con, posy, posx, c_white, _("OR")); posx += utf8_width(_("OR")) + 1; } } posy ++; posx = 33; } // Print components posx = 33; std::vector<bool> has_component; for( int i = 0; i < current_con->components.size(); i++ ) { has_component.push_back(false); mvwprintz(w_con, posy, posx - 2, c_white, ">"); for( unsigned j = 0; j < current_con->components[i].size(); j++ ) { nc_color col = c_red; component comp = current_con->components[i][j]; if( ( item_controller->find_template(comp.type)->is_ammo() && total_inv.has_charges(comp.type, comp.count)) || (!item_controller->find_template(comp.type)->is_ammo() && total_inv.has_amount(comp.type, comp.count)) ) { has_component[i] = true; col = c_green; } int length = utf8_width(item_controller->find_template(comp.type)->name.c_str()); if (posx + length > FULL_SCREEN_WIDTH - 1) { posy++; posx = 33; } mvwprintz(w_con, posy, posx, col, "%s x%d", item_controller->find_template(comp.type)->name.c_str(), comp.count); posx += length + 3; // + 2 for " x", + 1 for an empty space // Add more space for the length of the count if (comp.count < 10) { posx++; } else if (comp.count < 100) { posx += 2; } else { posx += 3; } if (j < current_con->components[i].size() - 1) { // "OR" if there's more if (posx > FULL_SCREEN_WIDTH - 3) { posy++; posx = 33; } mvwprintz(w_con, posy, posx, c_white, _("OR")); posx += utf8_width(_("OR")) + 1; } } posy ++; posx = 33; } } wrefresh(w_con); } // Finished updating ch = getch(); switch (ch) { case KEY_DOWN: update_info = true; if (select < available.size() - 1) { select++; } else { select = 0; } break; case KEY_UP: update_info = true; if (select > 0) { select--; } else { select = available.size() - 1; } break; case ' ': case KEY_ESCAPE: case 'q': case 'Q': exit = true; break; case ';': update_info = true; hide_unconstructable = !hide_unconstructable; load_available_constructions( available, hide_unconstructable ); break; case '\n': default: if (ch > 64 && ch < 91) { //A-Z chosen = ch - 65 + 26; } else if (ch > 96 && ch < 123) { //a-z chosen = ch - 97; } else if (ch == '\n') { chosen = select; } if (chosen < available.size()) { if (player_can_build(g->u, total_inv, available[chosen])) { place_construction(available[chosen]); exit = true; } else { popup(_("You can't build that!")); select = chosen; for (int i = 1; i < iMaxY - 1; i++) { mvwputch(w_con, i, 30, c_ltgray, LINE_XOXO); } update_info = true; } } break; } } while (!exit); for (int i = iMaxY - FULL_SCREEN_HEIGHT; i <= iMaxY; ++i) { for (int j = TERRAIN_WINDOW_WIDTH; j <= FULL_SCREEN_WIDTH; ++j) { mvwputch(w_con, i, j, c_black, ' '); } } wrefresh(w_con); g->refresh_all(); }
void defense_game::game_over(game *g) { popup("You managed to survive through wave %d!", current_wave); }
void defense_game::caravan(game *g) { std::vector<itype_id> items[NUM_CARAVAN_CATEGORIES]; std::vector<int> item_count[NUM_CARAVAN_CATEGORIES]; // Init the items for each category for (int i = 0; i < NUM_CARAVAN_CATEGORIES; i++) { items[i] = caravan_items( caravan_category(i) ); for (int j = 0; j < items[i].size(); j++) { if (current_wave == 0 || !one_in(4)) item_count[i].push_back(0); // Init counts to 0 for each item else { // Remove the item items[i].erase( items[i].begin() + j); j--; } } } int total_price = 0; WINDOW *w = newwin(25, 80, 0, 0); int offset = 0, item_selected = 0, category_selected = 0; int current_window = 0; draw_caravan_borders(w, current_window); draw_caravan_categories(w, category_selected, total_price, g->u.cash); bool done = false; bool cancel = false; while (!done) { char ch = input(); switch (ch) { case '?': popup_top("\ CARAVAN:\n\ Start by selecting a category using your favorite up/down keys.\n\ Switch between category selection and item selecting by pressing Tab.\n\ Pick an item with the up/down keys, press + to buy 1 more, - to buy 1 less.\n\ Press Enter to buy everything in your cart, Esc to buy nothing."); draw_caravan_categories(w, category_selected, total_price, g->u.cash); draw_caravan_items(w, g, &(items[category_selected]), &(item_count[category_selected]), offset, item_selected); draw_caravan_borders(w, current_window); break; case 'j': if (current_window == 0) { // Categories category_selected++; if (category_selected == NUM_CARAVAN_CATEGORIES) category_selected = CARAVAN_CART; draw_caravan_categories(w, category_selected, total_price, g->u.cash); offset = 0; item_selected = 0; draw_caravan_items(w, g, &(items[category_selected]), &(item_count[category_selected]), offset, item_selected); draw_caravan_borders(w, current_window); } else if (items[category_selected].size() > 0) { // Items if (item_selected < items[category_selected].size() - 1) item_selected++; else { item_selected = 0; offset = 0; } if (item_selected > offset + 22) offset++; draw_caravan_items(w, g, &(items[category_selected]), &(item_count[category_selected]), offset, item_selected); draw_caravan_borders(w, current_window); } break; case 'k': if (current_window == 0) { // Categories if (category_selected == 0) category_selected = NUM_CARAVAN_CATEGORIES - 1; else category_selected--; if (category_selected == NUM_CARAVAN_CATEGORIES) category_selected = CARAVAN_CART; draw_caravan_categories(w, category_selected, total_price, g->u.cash); offset = 0; item_selected = 0; draw_caravan_items(w, g, &(items[category_selected]), &(item_count[category_selected]), offset, item_selected); draw_caravan_borders(w, current_window); } else if (items[category_selected].size() > 0) { // Items if (item_selected > 0) item_selected--; else { item_selected = items[category_selected].size() - 1; offset = item_selected - 22; if (offset < 0) offset = 0; } if (item_selected < offset) offset--; draw_caravan_items(w, g, &(items[category_selected]), &(item_count[category_selected]), offset, item_selected); draw_caravan_borders(w, current_window); } break; case '+': case 'l': if (current_window == 1 && items[category_selected].size() > 0) { item_count[category_selected][item_selected]++; itype_id tmp_itm = items[category_selected][item_selected]; total_price += caravan_price(g->u, g->itypes[tmp_itm]->price); if (category_selected == CARAVAN_CART) { // Find the item in its category for (int i = 1; i < NUM_CARAVAN_CATEGORIES; i++) { for (int j = 0; j < items[i].size(); j++) { if (items[i][j] == tmp_itm) item_count[i][j]++; } } } else { // Add / increase the item in the shopping cart bool found_item = false; for (int i = 0; i < items[0].size() && !found_item; i++) { if (items[0][i] == tmp_itm) { found_item = true; item_count[0][i]++; } } if (!found_item) { items[0].push_back(items[category_selected][item_selected]); item_count[0].push_back(1); } } draw_caravan_categories(w, category_selected, total_price, g->u.cash); draw_caravan_items(w, g, &(items[category_selected]), &(item_count[category_selected]), offset, item_selected); draw_caravan_borders(w, current_window); } break; case '-': case 'h': if (current_window == 1 && items[category_selected].size() > 0 && item_count[category_selected][item_selected] > 0) { item_count[category_selected][item_selected]--; itype_id tmp_itm = items[category_selected][item_selected]; total_price -= caravan_price(g->u, g->itypes[tmp_itm]->price); if (category_selected == CARAVAN_CART) { // Find the item in its category for (int i = 1; i < NUM_CARAVAN_CATEGORIES; i++) { for (int j = 0; j < items[i].size(); j++) { if (items[i][j] == tmp_itm) item_count[i][j]--; } } } else { // Decrease / remove the item in the shopping cart bool found_item = false; for (int i = 0; i < items[0].size() && !found_item; i++) { if (items[0][i] == tmp_itm) { found_item = true; item_count[0][i]--; if (item_count[0][i] == 0) { item_count[0].erase(item_count[0].begin() + i); items[0].erase(items[0].begin() + i); } } } } draw_caravan_categories(w, category_selected, total_price, g->u.cash); draw_caravan_items(w, g, &(items[category_selected]), &(item_count[category_selected]), offset, item_selected); draw_caravan_borders(w, current_window); } break; case '\t': current_window = (current_window + 1) % 2; draw_caravan_borders(w, current_window); break; case KEY_ESCAPE: if (query_yn("Really buy nothing?")) { cancel = true; done = true; } else { draw_caravan_categories(w, category_selected, total_price, g->u.cash); draw_caravan_items(w, g, &(items[category_selected]), &(item_count[category_selected]), offset, item_selected); draw_caravan_borders(w, current_window); } break; case '\n': if (total_price > g->u.cash) popup("You can't afford those items!"); else if ((items[0].empty() && query_yn("Really buy nothing?")) || (!items[0].empty() && query_yn("Buy %d items, leaving you with $%d?", items[0].size(), g->u.cash - total_price))) done = true; if (!done) { // We canceled, so redraw everything draw_caravan_categories(w, category_selected, total_price, g->u.cash); draw_caravan_items(w, g, &(items[category_selected]), &(item_count[category_selected]), offset, item_selected); draw_caravan_borders(w, current_window); } break; } // switch (ch) } // while (!done) if (!cancel) { g->u.cash -= total_price; bool dropped_some = false; for (int i = 0; i < items[0].size(); i++) { item tmp(g->itypes[ items[0][i] ], g->turn); tmp = tmp.in_its_container(&(g->itypes)); for (int j = 0; j < item_count[0][i]; j++) { if (g->u.volume_carried() + tmp.volume() <= g->u.volume_capacity() && g->u.weight_carried() + tmp.weight() <= g->u.weight_capacity() && g->u.inv.size() < inv_chars.size()) g->u.i_add(tmp); else { // Could fit it in the inventory! dropped_some = true; g->m.add_item(g->u.posx, g->u.posy, tmp); } } } if (dropped_some) g->add_msg("You drop some items."); } }
void MainWindow::on_workmenset_btn_clicked() { workmen_select_popup popup(this); popup.exec(); }
void game_menus::inv::compare( player &p, const tripoint &offset ) { p.inv.restack( &p ); p.inv.sort(); inventory_compare_selector inv_s( p ); inv_s.add_character_items( p ); inv_s.set_title( _( "Compare" ) ); inv_s.set_hint( _( "Select two items to compare them." ) ); if( offset != tripoint_min ) { inv_s.add_map_items( p.pos() + offset ); inv_s.add_vehicle_items( p.pos() + offset ); } else { inv_s.add_nearby_items(); } if( inv_s.empty() ) { popup( std::string( _( "There are no items to compare." ) ), PF_GET_KEY ); return; } do { const auto to_compare = inv_s.execute(); if( to_compare.first == nullptr || to_compare.second == nullptr ) { break; } std::vector<iteminfo> vItemLastCh, vItemCh; std::string sItemLastCh, sItemCh, sItemLastTn, sItemTn; to_compare.first->info( true, vItemCh ); sItemCh = to_compare.first->tname(); sItemTn = to_compare.first->type_name(); to_compare.second->info( true, vItemLastCh ); sItemLastCh = to_compare.second->tname(); sItemLastTn = to_compare.second->type_name(); int iScrollPos = 0; int iScrollPosLast = 0; int ch = ( int ) ' '; do { draw_item_info( 0, ( TERMX - VIEW_OFFSET_X * 2 ) / 2, 0, TERMY - VIEW_OFFSET_Y * 2, sItemLastCh, sItemLastTn, vItemLastCh, vItemCh, iScrollPosLast, true ); //without getch( ch = draw_item_info( ( TERMX - VIEW_OFFSET_X * 2 ) / 2, ( TERMX - VIEW_OFFSET_X * 2 ) / 2, 0, TERMY - VIEW_OFFSET_Y * 2, sItemCh, sItemTn, vItemCh, vItemLastCh, iScrollPos ); if( ch == KEY_PPAGE ) { iScrollPos--; iScrollPosLast--; } else if( ch == KEY_NPAGE ) { iScrollPos++; iScrollPosLast++; } g->refresh_all(); } while( ch == KEY_PPAGE || ch == KEY_NPAGE ); } while( true ); }
void pilot_manage_button_pressed(int n) { switch (n) { //scroll pilot list up case PM_UP_BUTTON: pilot_manage_scroll_callsign_up(); break; // scroll pilot list down case PM_DOWN_BUTTON: pilot_manage_scroll_callsign_down(); break; // switch to single mode case PM_SINGLE_MODE_BUTTON: if (Player_sel_mode != PLAYER_SELECT_MODE_SINGLE) { gamesnd_play_iface(SND_USER_SELECT); // switching to multi so save multi player offset prev_multi_player = Selected_line; pilot_manage_init_player_stuff(PLAYER_SELECT_MODE_SINGLE); } break; // switch to multi mode case PM_MULTI_MODE_BUTTON: if (Player_sel_mode != PLAYER_SELECT_MODE_MULTI) { gamesnd_play_iface(SND_USER_SELECT); // switching to multi so save single player offset prev_single_player = Selected_line; pilot_manage_init_player_stuff(PLAYER_SELECT_MODE_MULTI); } break; //create new pilot case PM_CREATE_BUTTON: Clone_flag = 0; pilot_manage_create_new_pilot(); break; // select pilot case PM_ACTIVE_BUTTON: if (pilot_manage_new_pilot_selected()){ gamesnd_play_iface(SND_GENERAL_FAIL); // throw up a popup telling the player that he should create a pilot first if(Player_sel_mode == PLAYER_SELECT_MODE_SINGLE){ popup(PF_USE_AFFIRMATIVE_ICON,1,POPUP_OK,XSTR( "You must create a single player pilot.", 66)); } else { popup(PF_USE_AFFIRMATIVE_ICON,1,POPUP_OK,XSTR( "You must create a multi player pilot.", 67)); } } else { gamesnd_play_iface(SND_SCROLL); } break; // clone pilot case PM_CLONE_BUTTON: //case B_PILOT_CLONE_BUTTON: if (Num_pilots < 1) { gamesnd_play_error_beep(); break; } Clone_flag = 1; pilot_manage_create_new_pilot(); break; // convert pilot single/multi case PM_CONVERT_BUTTON: { char temp[256], *str; char old_pic[256] = ""; char old_squad_pic[256] = ""; char old_squad[256] = ""; int z; if (!pilot_manage_new_pilot_selected()) { if (Player_sel_mode == PLAYER_SELECT_MODE_SINGLE) str = XSTR( "multiplayer", 68); else str = XSTR( "single player", 69); sprintf(temp, XSTR( "This will overwrite your %s pilot. Proceed?", 70), str); if (!verify_pilot_file(Cur_pilot->callsign, Player_sel_mode == PLAYER_SELECT_MODE_MULTI)) { z = popup(0, 2, POPUP_CANCEL, POPUP_OK, temp); if (z != 1) break; } strcpy(old_pic, Cur_pilot->image_filename); strcpy(old_squad_pic, Cur_pilot->squad_filename); strcpy(old_squad, Cur_pilot->squad_name); init_new_pilot(Cur_pilot, 0); strcpy(Cur_pilot->image_filename, old_pic); strcpy(Cur_pilot->squad_filename, old_squad_pic); strcpy(Cur_pilot->squad_name, old_squad); if (Player_sel_mode == PLAYER_SELECT_MODE_SINGLE) { Cur_pilot->flags |= PLAYER_FLAGS_IS_MULTI; write_pilot_file(); pilot_manage_init_player_stuff(PLAYER_SELECT_MODE_MULTI); } else { write_pilot_file(); pilot_manage_init_player_stuff(PLAYER_SELECT_MODE_SINGLE); } gamesnd_play_iface(SND_USER_SELECT); } else { gamesnd_play_iface(SND_GENERAL_FAIL); } break; } // delete pilot case PM_DELETE_BUTTON: pilot_manage_delete_pilot(); break; // exit pilot selection case PM_EXIT_BUTTON: if (Num_pilots && !pilot_manage_pilot_accepted()) { gamesnd_play_iface(SND_COMMIT_PRESSED); gameseq_post_event(GS_EVENT_PREVIOUS_STATE); } else { gamesnd_play_iface(SND_GENERAL_FAIL); // throw up a popup telling the player that he should create a pilot first if(Player_sel_mode == PLAYER_SELECT_MODE_SINGLE){ popup(PF_USE_AFFIRMATIVE_ICON,1,POPUP_OK,XSTR( "You must create a single player pilot.", 66)); } else { popup(PF_USE_AFFIRMATIVE_ICON,1,POPUP_OK,XSTR( "You must create a multi player pilot.", 67)); } } break; case PM_TC_BUTTON: popup_tc(); // want to switch it over to multiplayer pilots prev_single_player = Selected_line; pilot_manage_init_player_stuff(PLAYER_SELECT_MODE_MULTI); break; } }
void MainWindow::on_mold_select_clicked() { mold_select_popup popup(this); popup.exec(); }
void CreateDialog::popup_create(bool p_dont_clear, bool p_replace_mode) { type_list.clear(); ClassDB::get_class_list(&type_list); ScriptServer::get_global_class_list(&type_list); type_list.sort_custom<StringName::AlphCompare>(); recent->clear(); FileAccess *f = FileAccess::open(EditorSettings::get_singleton()->get_project_settings_dir().plus_file("create_recent." + base_type), FileAccess::READ); if (f) { TreeItem *root = recent->create_item(); while (!f->eof_reached()) { String l = f->get_line().strip_edges(); if (l != String()) { TreeItem *ti = recent->create_item(root); ti->set_text(0, l); ti->set_icon(0, EditorNode::get_singleton()->get_class_icon(l, base_type)); } } memdelete(f); } favorites->clear(); f = FileAccess::open(EditorSettings::get_singleton()->get_project_settings_dir().plus_file("favorites." + base_type), FileAccess::READ); favorite_list.clear(); if (f) { while (!f->eof_reached()) { String l = f->get_line().strip_edges(); if (l != String()) { favorite_list.push_back(l); } } memdelete(f); } _save_and_update_favorite_list(); // Restore valid window bounds or pop up at default size. if (EditorSettings::get_singleton()->has_setting("interface/dialogs/create_new_node_bounds")) { popup(EditorSettings::get_singleton()->get("interface/dialogs/create_new_node_bounds")); } else { Size2 popup_size = Size2(900, 700) * editor_get_scale(); Size2 window_size = get_viewport_rect().size; popup_size.x = MIN(window_size.x * 0.8, popup_size.x); popup_size.y = MIN(window_size.y * 0.8, popup_size.y); popup_centered(popup_size); } if (p_dont_clear) { search_box->select_all(); } else { search_box->clear(); } search_box->grab_focus(); _update_search(); bool enable_rl = EditorSettings::get_singleton()->get("docks/scene_tree/draw_relationship_lines"); Color rl_color = EditorSettings::get_singleton()->get("docks/scene_tree/relationship_line_color"); if (enable_rl) { search_options->add_constant_override("draw_relationship_lines", 1); search_options->add_color_override("relationship_line_color", rl_color); } else { search_options->add_constant_override("draw_relationship_lines", 0); } is_replace_mode = p_replace_mode; if (p_replace_mode) { set_title(vformat(TTR("Change %s Type"), base_type)); get_ok()->set_text(TTR("Change")); } else { set_title(vformat(TTR("Create New %s"), base_type)); get_ok()->set_text(TTR("Create")); } }
void WPopupMenu::popup(const WMouseEvent& e) { popup(WPoint(e.document().x, e.document().y)); }
void barracks_button_pressed(int n) { switch (n) { case B_PILOT_SCROLL_UP_BUTTON: barracks_scroll_callsign_up(); break; case B_PILOT_SCROLL_DOWN_BUTTON: barracks_scroll_callsign_down(); break; case B_STATS_SCROLL_UP_BUTTON: barracks_scroll_stats_up(); break; case B_STATS_SCROLL_DOWN_BUTTON: barracks_scroll_stats_down(); break; case B_PIC_PREV_PILOT_BUTTON: barracks_prev_pic(); break; case B_PIC_NEXT_PILOT_BUTTON: barracks_next_pic(); break; case B_SQUAD_PREV_BUTTON: barracks_prev_squad_pic(); break; case B_SQUAD_NEXT_BUTTON: barracks_next_squad_pic(); break; case B_PILOT_SET_ACTIVE_BUTTON: if (barracks_new_pilot_selected()){ gamesnd_play_iface(SND_GENERAL_FAIL); // if it's just the missing campaign file that failed for us then don't give the second popup if (Campaign_file_missing) { break; } } else { gamesnd_play_iface(SND_SCROLL); if (Campaign_file_missing) { popup(PF_USE_AFFIRMATIVE_ICON, 1, POPUP_OK, XSTR( "The currently active campaign cannot be found. Please select another...", 1600)); gameseq_post_event(GS_EVENT_CAMPAIGN_ROOM); } } break; case B_ACCEPT_BUTTON: if (Num_pilots && !barracks_pilot_accepted()) { gamesnd_play_iface(SND_COMMIT_PRESSED); if (Campaign_file_missing) { popup(PF_USE_AFFIRMATIVE_ICON, 1, POPUP_OK, XSTR( "The currently active campaign cannot be found. Please select another...", 1600)); gameseq_post_event(GS_EVENT_CAMPAIGN_ROOM); } else { gameseq_post_event(GS_EVENT_MAIN_MENU); } } else { gamesnd_play_iface(SND_GENERAL_FAIL); // if it's just the missing campaign file that failed for us then don't give the second popup if (Campaign_file_missing) { break; } } break; case B_PILOT_CLONE_BUTTON: if (Num_pilots < 1) { gamesnd_play_error_beep(); break; } Clone_flag = 1; barracks_create_new_pilot(); break; case B_PILOT_CONVERT_BUTTON: { /* New Pilot code no longer needs a conversion function. */ popup(PF_TITLE_BIG | PF_TITLE_BLUE | PF_USE_AFFIRMATIVE_ICON, 1, POPUP_OK, XSTR("Disabled!\n\n\nMulti and Single Player Pilot files are now identical.\n\n" "Conversion between the two is no longer necessary.", 1601)); /* // no actual conversion with new pilot code if (Player_sel_mode == PLAYER_SELECT_MODE_SINGLE) { barracks_init_player_stuff(PLAYER_SELECT_MODE_MULTI); } else { // make sure we don't carry over the multi flag if (Cur_pilot->flags & PLAYER_FLAGS_IS_MULTI) { Cur_pilot->flags &= ~PLAYER_FLAGS_IS_MULTI; } barracks_init_player_stuff(PLAYER_SELECT_MODE_SINGLE); } gamesnd_play_iface(SND_USER_SELECT); */ break; } case B_PILOT_CREATE_BUTTON: Clone_flag = 0; barracks_create_new_pilot(); break; case B_HELP_BUTTON: launch_context_help(); gamesnd_play_iface(SND_HELP_PRESSED); break; case B_OPTION_BUTTON: gamesnd_play_iface(SND_SWITCH_SCREENS); gameseq_post_event(GS_EVENT_OPTIONS_MENU); break; case B_STATS_MEDAL_BUTTON: gamesnd_play_iface(SND_SWITCH_SCREENS); gameseq_post_event(GS_EVENT_VIEW_MEDALS); break; case B_PILOT_DELETE_BUTTON: barracks_delete_pilot(); break; case B_PILOT_SINGLE_MODE_BUTTON: if (Player_sel_mode != PLAYER_SELECT_MODE_SINGLE) { gamesnd_play_iface(SND_USER_SELECT); // make sure we don't carry over the multi flag if (Cur_pilot->flags & PLAYER_FLAGS_IS_MULTI) { Cur_pilot->flags &= ~PLAYER_FLAGS_IS_MULTI; } Pilot.save_player(Cur_pilot); barracks_init_player_stuff(PLAYER_SELECT_MODE_SINGLE); } break; case B_PILOT_MULTI_MODE_BUTTON: if ( Networking_disabled ) { game_feature_disabled_popup(); break; } if (Player_sel_mode != PLAYER_SELECT_MODE_MULTI) { gamesnd_play_iface(SND_USER_SELECT); Cur_pilot->flags |= PLAYER_FLAGS_IS_MULTI; Pilot.save_player(Cur_pilot); barracks_init_player_stuff(PLAYER_SELECT_MODE_MULTI); } break; } }
void player_select_process_noninput(int k) { int idx; // check for pressed buttons for (idx=0; idx<NUM_PLAYER_SELECT_BUTTONS; idx++) { if (Player_select_buttons[gr_screen.res][idx].button.pressed()) { player_select_button_pressed(idx); } } // check for keypresses switch (k) { // quit the game entirely case KEY_ESC: gameseq_post_event(GS_EVENT_QUIT_GAME); break; case KEY_ENTER | KEY_CTRLED: player_select_button_pressed(ACCEPT_BUTTON); break; // delete the currently highlighted pilot case KEY_DELETE: if (Player_select_pilot >= 0) { int ret; if (Player_select_mode == PLAYER_SELECT_MODE_MULTI) { popup(PF_TITLE_BIG | PF_USE_AFFIRMATIVE_ICON, 1, POPUP_OK, XSTR("Pilots can only be deleted from the single player menu!", 1611)); } else { // display a popup requesting confirmation ret = popup(PF_USE_AFFIRMATIVE_ICON | PF_USE_NEGATIVE_ICON,2,POPUP_NO,POPUP_YES,XSTR( "Are you sure you want to delete this pilot?", 383)); // delete the pilot if (ret == 1) { player_select_delete_pilot(); } } } break; } // check to see if the user has clicked on the "list region" button // and change the selected pilot appropriately if (Player_select_list_region.pressed()) { int click_y; // get the mouse position Player_select_list_region.get_mouse_pos(NULL, &click_y); // determine what index to select //idx = (click_y+5) / 10; idx = click_y / gr_get_font_height(); // if he selected a valid item if ( ((idx + Player_select_list_start) < Player_select_num_pilots) && (idx >= 0) ) { Player_select_pilot = idx + Player_select_list_start; } } // if the player has double clicked on a valid pilot, choose it and hit the accept button if (Player_select_list_region.double_clicked()) { if ((Player_select_pilot >= 0) && (Player_select_pilot < Player_select_num_pilots)) { player_select_button_pressed(ACCEPT_BUTTON); } } }
void CLexiconReadWindow::setupPopupMenu() { popup()->setTitle(tr("Lexicon window")); popup()->setIcon(CToolClass::getIconForModule(modules().first())); popup()->addAction(m_actions.findText); popup()->addAction(m_actions.findStrongs); popup()->addAction(m_actions.selectAll); popup()->addSeparator(); m_actions.copyMenu = new QMenu(tr("Copy..."), popup()); m_actions.copyMenu->addAction(m_actions.copy.reference); m_actions.copyMenu->addAction(m_actions.copy.entry); m_actions.copyMenu->addSeparator(); m_actions.copyMenu->addAction(m_actions.copy.selectedText); popup()->addMenu(m_actions.copyMenu); m_actions.saveMenu = new QMenu( tr("Save..."), popup() ); m_actions.saveMenu->addAction(m_actions.save.entryAsPlain); m_actions.saveMenu->addAction(m_actions.save.entryAsHTML); // Save raw HTML action for debugging purposes if (qApp->property("--debug").toBool()) { QAction* debugAction = new QAction("Raw HTML", this); QObject::connect(debugAction, SIGNAL(triggered()), this, SLOT(saveRawHTML())); m_actions.saveMenu->addAction(debugAction); } // end of Save Raw HTML popup()->addMenu(m_actions.saveMenu); m_actions.printMenu = new QMenu( tr("Print..."), popup() ); m_actions.printMenu->addAction(m_actions.print.reference); m_actions.printMenu->addAction(m_actions.print.entry); popup()->addMenu(m_actions.printMenu); }
void player::power_bionics() { std::vector <bionic *> passive = filtered_bionics( my_bionics, TAB_PASSIVE ); std::vector <bionic *> active = filtered_bionics( my_bionics, TAB_ACTIVE ); bionic *bio_last = NULL; bionic_tab_mode tab_mode = TAB_ACTIVE; //added title_tab_height for the tabbed bionic display int TITLE_HEIGHT = 2; int TITLE_TAB_HEIGHT = 3; // Main window /** Total required height is: * top frame line: + 1 * height of title window: + TITLE_HEIGHT * height of tabs: + TITLE_TAB_HEIGHT * height of the biggest list of active/passive bionics: + bionic_count * bottom frame line: + 1 * TOTAL: TITLE_HEIGHT + TITLE_TAB_HEIGHT + bionic_count + 2 */ const int HEIGHT = std::min( TERMY, std::max( FULL_SCREEN_HEIGHT, TITLE_HEIGHT + TITLE_TAB_HEIGHT + ( int )my_bionics.size() + 2 ) ); const int WIDTH = FULL_SCREEN_WIDTH + ( TERMX - FULL_SCREEN_WIDTH ) / 2; const int START_X = ( TERMX - WIDTH ) / 2; const int START_Y = ( TERMY - HEIGHT ) / 2; //wBio is the entire bionic window WINDOW *wBio = newwin( HEIGHT, WIDTH, START_Y, START_X ); WINDOW_PTR wBioptr( wBio ); const int LIST_HEIGHT = HEIGHT - TITLE_HEIGHT - TITLE_TAB_HEIGHT - 2; const int DESCRIPTION_WIDTH = WIDTH - 2 - 40; const int DESCRIPTION_START_Y = START_Y + TITLE_HEIGHT + TITLE_TAB_HEIGHT + 1; const int DESCRIPTION_START_X = START_X + 1 + 40; //w_description is the description panel that is controlled with ! key WINDOW *w_description = newwin( LIST_HEIGHT, DESCRIPTION_WIDTH, DESCRIPTION_START_Y, DESCRIPTION_START_X ); WINDOW_PTR w_descriptionptr( w_description ); // Title window const int TITLE_START_Y = START_Y + 1; const int HEADER_LINE_Y = TITLE_HEIGHT + TITLE_TAB_HEIGHT + 1; WINDOW *w_title = newwin( TITLE_HEIGHT, WIDTH - 2, TITLE_START_Y, START_X + 1 ); WINDOW_PTR w_titleptr( w_title ); const int TAB_START_Y = TITLE_START_Y + 2; //w_tabs is the tab bar for passive and active bionic groups WINDOW *w_tabs = newwin( TITLE_TAB_HEIGHT, WIDTH - 2, TAB_START_Y, START_X + 1 ); WINDOW_PTR w_tabsptr( w_tabs ); int scroll_position = 0; int cursor = 0; //generate the tab title string and a count of the bionics owned bionic_menu_mode menu_mode = ACTIVATING; // offset for display: bionic with index i is drawn at y=list_start_y+i // drawing the bionics starts with bionic[scroll_position] const int list_start_y = HEADER_LINE_Y;// - scroll_position; int half_list_view_location = LIST_HEIGHT / 2; int max_scroll_position = std::max( 0, ( tab_mode == TAB_ACTIVE ? ( int )active.size() : ( int )passive.size() ) - LIST_HEIGHT ); input_context ctxt( "BIONICS" ); ctxt.register_updown(); ctxt.register_action( "ANY_INPUT" ); ctxt.register_action( "TOGGLE_EXAMINE" ); ctxt.register_action( "REASSIGN" ); ctxt.register_action( "REMOVE" ); ctxt.register_action( "NEXT_TAB" ); ctxt.register_action( "PREV_TAB" ); ctxt.register_action( "CONFIRM" ); ctxt.register_action( "HELP_KEYBINDINGS" ); bool recalc = false; bool redraw = true; for( ;; ) { if( recalc ) { passive = filtered_bionics( my_bionics, TAB_PASSIVE ); active = filtered_bionics( my_bionics, TAB_ACTIVE ); if( active.empty() && !passive.empty() ) { tab_mode = TAB_PASSIVE; } if( --cursor < 0 ) { cursor = 0; } if( scroll_position > max_scroll_position && cursor - scroll_position < LIST_HEIGHT - half_list_view_location ) { scroll_position--; } recalc = false; // bionics were modified, so it's necessary to redraw the screen redraw = true; } //track which list we are looking at std::vector<bionic *> *current_bionic_list = ( tab_mode == TAB_ACTIVE ? &active : &passive ); max_scroll_position = std::max( 0, ( int )current_bionic_list->size() - LIST_HEIGHT ); if( redraw ) { redraw = false; werase( wBio ); draw_border( wBio, BORDER_COLOR, _( " BIONICS " ) ); // Draw symbols to connect additional lines to border mvwputch( wBio, HEADER_LINE_Y - 1, 0, BORDER_COLOR, LINE_XXXO ); // |- mvwputch( wBio, HEADER_LINE_Y - 1, WIDTH - 1, BORDER_COLOR, LINE_XOXX ); // -| if( current_bionic_list->empty() ) { std::string msg; switch( tab_mode ) { case TAB_ACTIVE: msg = _( "No activatable bionics installed." ); break; case TAB_PASSIVE: msg = _( "No passive bionics installed." ); break; } fold_and_print( wBio, list_start_y, 2, WIDTH - 3, c_ltgray, msg ); } else { for( size_t i = scroll_position; i < current_bionic_list->size(); i++ ) { if( list_start_y + static_cast<int>( i ) - scroll_position == HEIGHT - 1 ) { break; } const bool is_highlighted = cursor == static_cast<int>( i ); const nc_color col = get_bionic_text_color( *( *current_bionic_list )[i], is_highlighted ); const std::string desc = string_format( "%c %s", ( *current_bionic_list )[i]->invlet, build_bionic_powerdesc_string( *( *current_bionic_list )[i] ).c_str() ); trim_and_print( wBio, list_start_y + i - scroll_position, 2, WIDTH - 3, col, "%s", desc.c_str() ); // draw bodyparts if( is_highlighted && menu_mode != EXAMINING ) { int max_width = 0; std::vector<std::string>bps; for( int i = 0; i < num_bp; ++i ) { const body_part bp = bp_aBodyPart[i]; const int total = get_total_bionics_slots( bp ); const std::string s = string_format( "%s: %d/%d", body_part_name_as_heading( bp, 1 ).c_str(), total - get_free_bionics_slots( bp ), total ); bps.push_back( s ); max_width = std::max( max_width, utf8_width( s ) ); } const int pos_x = WIDTH - 2 - max_width; const std::string bio_id = ( *current_bionic_list )[i]->id; draw_connectors( wBio, list_start_y + i - scroll_position, utf8_width( desc ) + 3, pos_x - 2, bio_id ); for( int i = 0; i < num_bp; ++i ) { mvwprintz( wBio, i + list_start_y, pos_x, bionic_info( bio_id ).occupied_bodyparts.count( bp_aBodyPart[i] ) > 0 ? c_yellow : c_ltgray, "%s", bps[i].c_str() ); } } } } draw_scrollbar( wBio, cursor, LIST_HEIGHT, current_bionic_list->size(), list_start_y ); } wrefresh( wBio ); draw_bionics_tabs( w_tabs, active.size(), passive.size(), tab_mode ); draw_bionics_titlebar( w_title, this, menu_mode ); if( menu_mode == EXAMINING && !current_bionic_list->empty() ) { draw_description( w_description, *( *current_bionic_list )[cursor] ); } const std::string action = ctxt.handle_input(); const long ch = ctxt.get_raw_input().get_first_input(); bionic *tmp = NULL; bool confirmCheck = false; if( menu_mode == REASSIGNING ) { menu_mode = ACTIVATING; tmp = bionic_by_invlet( ch ); if( tmp == nullptr ) { // Selected an non-existing bionic (or escape, or ...) continue; } redraw = true; const long newch = popup_getkey( _( "%s; enter new letter." ), bionic_info( tmp->id ).name.c_str() ); wrefresh( wBio ); if( newch == ch || newch == ' ' || newch == KEY_ESCAPE ) { continue; } if( !bionic_chars.valid( newch ) ) { popup( _( "Invalid bionic letter. Only those characters are valid:\n\n%s" ), bionic_chars.get_allowed_chars().c_str() ); continue; } bionic *otmp = bionic_by_invlet( newch ); if( otmp != nullptr ) { std::swap( tmp->invlet, otmp->invlet ); } else { tmp->invlet = newch; } // TODO: show a message like when reassigning a key to an item? } else if( action == "NEXT_TAB" ) { redraw = true; scroll_position = 0; cursor = 0; if( tab_mode == TAB_ACTIVE ) { tab_mode = TAB_PASSIVE; } else { tab_mode = TAB_ACTIVE; } } else if( action == "PREV_TAB" ) { redraw = true; scroll_position = 0; cursor = 0; if( tab_mode == TAB_PASSIVE ) { tab_mode = TAB_ACTIVE; } else { tab_mode = TAB_PASSIVE; } } else if( action == "DOWN" ) { redraw = true; if( static_cast<size_t>( cursor ) < current_bionic_list->size() - 1 ) { cursor++; } if( scroll_position < max_scroll_position && cursor - scroll_position > LIST_HEIGHT - half_list_view_location ) { scroll_position++; } } else if( action == "UP" ) { redraw = true; if( cursor > 0 ) { cursor--; } if( scroll_position > 0 && cursor - scroll_position < half_list_view_location ) { scroll_position--; } } else if( action == "REASSIGN" ) { menu_mode = REASSIGNING; } else if( action == "TOGGLE_EXAMINE" ) { // switches between activation and examination menu_mode = menu_mode == ACTIVATING ? EXAMINING : ACTIVATING; redraw = true; } else if( action == "REMOVE" ) { menu_mode = REMOVING; redraw = true; } else if( action == "HELP_KEYBINDINGS" ) { redraw = true; } else if( action == "CONFIRM" ) { confirmCheck = true; } else { confirmCheck = true; } //confirmation either occurred by pressing enter where the bionic cursor is, or the hotkey was selected if( confirmCheck ) { auto &bio_list = tab_mode == TAB_ACTIVE ? active : passive; if( action == "CONFIRM" && !current_bionic_list->empty() ) { tmp = bio_list[cursor]; } else { tmp = bionic_by_invlet( ch ); if( tmp && tmp != bio_last ) { // new bionic selected, update cursor and scroll position int temp_cursor = 0; for( temp_cursor = 0; temp_cursor < ( int )bio_list.size(); temp_cursor++ ) { if( bio_list[temp_cursor] == tmp ) { break; } } // if bionic is not found in current list, ignore the attempt to view/activate if( temp_cursor >= ( int )bio_list.size() ) { continue; } //relocate cursor to the bionic that was found cursor = temp_cursor; scroll_position = 0; while( scroll_position < max_scroll_position && cursor - scroll_position > LIST_HEIGHT - half_list_view_location ) { scroll_position++; } } } if( !tmp ) { // entered a key that is not mapped to any bionic, // -> leave screen break; } bio_last = tmp; const std::string &bio_id = tmp->id; const bionic_data &bio_data = bionic_info( bio_id ); if( menu_mode == REMOVING ) { recalc = uninstall_bionic( bio_id ); redraw = true; continue; } if( menu_mode == ACTIVATING ) { if( bio_data.activated ) { int b = tmp - &my_bionics[0]; if( tmp->powered ) { deactivate_bionic( b ); } else { activate_bionic( b ); } // update message log and the menu g->refresh_all(); redraw = true; continue; } else { popup( _( "You can not activate %s!\n" "To read a description of %s, press '!', then '%c'." ), bio_data.name.c_str(), bio_data.name.c_str(), tmp->invlet ); redraw = true; } } else if( menu_mode == EXAMINING ) { // Describing bionics, allow user to jump to description key redraw = true; if( action != "CONFIRM" ) { for( size_t i = 0; i < active.size(); i++ ) { if( active[i] == tmp ) { tab_mode = TAB_ACTIVE; cursor = static_cast<int>( i ); int max_scroll_check = std::max( 0, ( int )active.size() - LIST_HEIGHT ); if( static_cast<int>( i ) > max_scroll_check ) { scroll_position = max_scroll_check; } else { scroll_position = i; } break; } } for( size_t i = 0; i < passive.size(); i++ ) { if( passive[i] == tmp ) { tab_mode = TAB_PASSIVE; cursor = static_cast<int>( i ); int max_scroll_check = std::max( 0, ( int )passive.size() - LIST_HEIGHT ); if( static_cast<int>( i ) > max_scroll_check ) { scroll_position = max_scroll_check; } else { scroll_position = i; } break; } } } } } } }
void input_context::display_help() { inp_mngr.set_timeout(-1); // Shamelessly stolen from help.cpp WINDOW *w_help = newwin(FULL_SCREEN_HEIGHT - 2, FULL_SCREEN_WIDTH - 2, 1 + (int)((TERMY > FULL_SCREEN_HEIGHT) ? (TERMY - FULL_SCREEN_HEIGHT) / 2 : 0), 1 + (int)((TERMX > FULL_SCREEN_WIDTH) ? (TERMX - FULL_SCREEN_WIDTH) / 2 : 0)); // has the user changed something? bool changed = false; // keybindings before the user changed anything. input_manager::t_action_contexts old_action_contexts(inp_mngr.action_contexts); // current status: adding/removing/showing keybindings enum { s_remove, s_add, s_add_global, s_show } status = s_show; // copy of registered_actions, but without the ANY_INPUT and COORDINATE, which should not be shown std::vector<std::string> org_registered_actions(registered_actions); std::vector<std::string>::iterator any_input = std::find(org_registered_actions.begin(), org_registered_actions.end(), ANY_INPUT); if (any_input != org_registered_actions.end()) { org_registered_actions.erase(any_input); } std::vector<std::string>::iterator coordinate = std::find(org_registered_actions.begin(), org_registered_actions.end(), COORDINATE); if (coordinate != org_registered_actions.end()) { org_registered_actions.erase(coordinate); } // colors of the keybindings static const nc_color global_key = c_ltgray; static const nc_color local_key = c_ltgreen; static const nc_color unbound_key = c_ltred; // (vertical) scroll offset size_t scroll_offset = 0; // height of the area usable for display of keybindings, excludes headers & borders const size_t display_height = FULL_SCREEN_HEIGHT - 2 - 2; // -2 for the border // width of the legend const size_t legwidth = FULL_SCREEN_WIDTH - 51 - 2; // keybindings help std::ostringstream legend; legend << "<color_" << string_from_color(unbound_key) << ">" << _("Unbound keys") << "</color>\n"; legend << "<color_" << string_from_color(local_key) << ">" << _("Keybinding active only on this screen") << "</color>\n"; legend << "<color_" << string_from_color(global_key) << ">" << _("Keybinding active globally") << "</color>\n"; legend << _("Press - to remove keybinding\nPress + to add local keybinding\nPress = to add global keybinding\n"); input_context ctxt("HELP_KEYBINDINGS"); ctxt.register_action("UP", _("Scroll up")); ctxt.register_action("DOWN", _("Scroll down")); ctxt.register_action("PAGE_DOWN"); ctxt.register_action("PAGE_UP"); ctxt.register_action("REMOVE"); ctxt.register_action("ADD_LOCAL"); ctxt.register_action("ADD_GLOBAL"); ctxt.register_action("QUIT"); ctxt.register_action("ANY_INPUT"); if (category != "HELP_KEYBINDINGS") { // avoiding inception! ctxt.register_action("HELP_KEYBINDINGS"); } std::string hotkeys = ctxt.get_available_single_char_hotkeys(display_help_hotkeys); while(true) { werase(w_help); draw_border(w_help); draw_scrollbar(w_help, scroll_offset, display_height, org_registered_actions.size() - display_height, 1); mvwprintz(w_help, 0, (FULL_SCREEN_WIDTH - utf8_width(_("Keybindings"))) / 2 - 1, c_ltred, " %s ", _("Keybindings")); fold_and_print(w_help, 1, 51, legwidth, c_white, legend.str()); for (size_t i = 0; i + scroll_offset < org_registered_actions.size() && i < display_height; i++) { const std::string &action_id = org_registered_actions[i + scroll_offset]; bool overwrite_default; const action_attributes &attributes = inp_mngr.get_action_attributes(action_id, category, &overwrite_default); char invlet; if (i < hotkeys.size()) { invlet = hotkeys[i]; } else { invlet = ' '; } if (status == s_add_global && overwrite_default) { // We're trying to add a global, but this action has a local // defined, so gray out the invlet. mvwprintz(w_help, i + 1, 2, c_dkgray, "%c ", invlet); } else if (status == s_add || status == s_add_global) { mvwprintz(w_help, i + 1, 2, c_blue, "%c ", invlet); } else if (status == s_remove) { mvwprintz(w_help, i + 1, 2, c_blue, "%c ", invlet); } else { mvwprintz(w_help, i + 1, 2, c_blue, " "); } nc_color col; if (attributes.input_events.empty()) { col = unbound_key; } else if (overwrite_default) { col = local_key; } else { col = global_key; } mvwprintz(w_help, i + 1, 4, col, "%s: ", get_action_name(action_id).c_str()); mvwprintz(w_help, i + 1, 30, col, "%s", get_desc(action_id).c_str()); } wrefresh(w_help); refresh(); // In addition to the modifiable hotkeys, we also check for hardcoded // keys, e.g. '+', '-', '=', in order to prevent the user from // entering an unrecoverable state. const std::string action = ctxt.handle_input(); const long raw_input_char = ctxt.get_raw_input().get_first_input(); if (action == "ADD_LOCAL" || raw_input_char == '+') { status = s_add; } else if (action == "ADD_GLOBAL" || raw_input_char == '=') { status = s_add_global; } else if (action == "REMOVE" || raw_input_char == '-') { status = s_remove; } else if (action == "ANY_INPUT") { const size_t hotkey_index = hotkeys.find_first_of(raw_input_char); if (status == s_show || hotkey_index == std::string::npos ) { continue; } const size_t action_index = hotkey_index + scroll_offset; if( action_index >= org_registered_actions.size() ) { continue; } const std::string &action_id = org_registered_actions[action_index]; // Check if this entry is local or global. bool is_local = false; inp_mngr.get_action_attributes(action_id, category, &is_local); const std::string name = get_action_name(action_id); if (status == s_remove && (!OPTIONS["QUERY_KEYBIND_REMOVAL"] || query_yn(_("Clear keys for %s?"), name.c_str()))) { // If it's global, reset the global actions. std::string category_to_access = category; if (!is_local) { category_to_access = default_context_id; } inp_mngr.remove_input_for_action(action_id, category_to_access); changed = true; } else if (status == s_add_global && is_local) { // Disallow adding global actions to an action that already has a local defined. popup(_("There are already local keybindings defined for this action, please remove them first.")); } else if (status == s_add || status == s_add_global) { const long newbind = popup_getkey(_("New key for %s:"), name.c_str()); const input_event new_event(newbind, CATA_INPUT_KEYBOARD); const std::string conflicts = get_conflicts(new_event); const bool has_conflicts = !conflicts.empty(); bool resolve_conflicts = false; if (has_conflicts) { resolve_conflicts = query_yn( _("This key conflicts with %s. Remove this key from the conflicting command(s), and continue?"), conflicts.c_str()); } if (!has_conflicts || resolve_conflicts) { if (resolve_conflicts) { clear_conflicting_keybindings(new_event); } // We might be adding a local or global action. std::string category_to_access = category; if (status == s_add_global) { category_to_access = default_context_id; } inp_mngr.add_input_for_action(action_id, category_to_access, new_event); changed = true; } } status = s_show; } else if (action == "DOWN") { if (scroll_offset < org_registered_actions.size() - display_height) { scroll_offset++; } } else if (action == "UP") { if (scroll_offset > 0) { scroll_offset--; } } else if (action == "PAGE_DOWN") { if( scroll_offset + display_height < org_registered_actions.size() ) { scroll_offset += std::min(display_height, org_registered_actions.size() - display_height - scroll_offset); } else if( org_registered_actions.size() > display_height ) { scroll_offset = 0; } } else if( action == "PAGE_UP" ) { if( scroll_offset >= display_height ) { scroll_offset -= display_height; } else if( scroll_offset > 0 ) { scroll_offset = 0; } else if( org_registered_actions.size() > display_height ) { scroll_offset = org_registered_actions.size() - display_height; } } else if (action == "QUIT") { if (status != s_show) { status = s_show; } else { break; } } else if (action == "HELP_KEYBINDINGS") { // update available hotkeys in case they've changed hotkeys = ctxt.get_available_single_char_hotkeys(display_help_hotkeys); } } if (changed && query_yn(_("Save changes?"))) { try { inp_mngr.save(); } catch(std::exception &err) { popup(_("saving keybindings failed: %s"), err.what()); } catch(std::string &err) { popup(_("saving keybindings failed: %s"), err.c_str()); } } else if(changed) { inp_mngr.action_contexts.swap(old_action_contexts); } werase(w_help); wrefresh(w_help); delwin(w_help); }
void defense_game::setup() { WINDOW* w = newwin(25, 80, 0, 0); int selection = 1; refresh_setup(w, selection); while (true) { char ch = input(); if (ch == 'S') { if (!zombies && !specials && !spiders && !triffids && !robots && !subspace) { popup("You must choose at least one monster group!"); refresh_setup(w, selection); } else return; } else if (ch == '+' || ch == '>' || ch == 'j') { if (selection == 19) selection = 1; else selection++; refresh_setup(w, selection); } else if (ch == '-' || ch == '<' || ch == 'k') { if (selection == 1) selection = 19; else selection--; refresh_setup(w, selection); } else if (ch == '!') { std::string name = string_input_popup("Template Name:", 20); refresh_setup(w, selection); } else if (ch == 'S') return; else { switch (selection) { case 1: // Scenario selection if (ch == 'l') { if (style == defense_style(NUM_DEFENSE_STYLES - 1)) style = defense_style(1); else style = defense_style(style + 1); } if (ch == 'h') { if (style == defense_style(1)) style = defense_style(NUM_DEFENSE_STYLES - 1); else style = defense_style(style - 1); } init_to_style(style); break; case 2: // Location selection if (ch == 'l') { if (location == defense_location(NUM_DEFENSE_LOCATIONS - 1)) location = defense_location(1); else location = defense_location(location + 1); } if (ch == 'h') { if (location == defense_location(1)) location = defense_location(NUM_DEFENSE_LOCATIONS - 1); else location = defense_location(location - 1); } mvwprintz(w, 5, 2, c_black, "\ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"); mvwprintz(w, 5, 2, c_yellow, defense_location_name(location).c_str()); mvwprintz(w, 5, 28, c_ltgray, defense_location_description(location).c_str()); break; case 3: // Difficulty of the first wave if (ch == 'h' && initial_difficulty > 10) initial_difficulty -= 5; if (ch == 'l' && initial_difficulty < 995) initial_difficulty += 5; mvwprintz(w, 7, 22, c_black, "xxx"); mvwprintz(w, 7, NUMALIGN(initial_difficulty), c_yellow, "%d", initial_difficulty); break; case 4: // Wave Difficulty if (ch == 'h' && wave_difficulty > 10) wave_difficulty -= 5; if (ch == 'l' && wave_difficulty < 995) wave_difficulty += 5; mvwprintz(w, 8, 22, c_black, "xxx"); mvwprintz(w, 8, NUMALIGN(wave_difficulty), c_yellow, "%d", wave_difficulty); break; case 5: if (ch == 'h' && time_between_waves > 5) time_between_waves -= 5; if (ch == 'l' && time_between_waves < 995) time_between_waves += 5; mvwprintz(w, 10, 22, c_black, "xxx"); mvwprintz(w, 10, NUMALIGN(time_between_waves), c_yellow, "%d", time_between_waves); break; case 6: if (ch == 'h' && waves_between_caravans > 1) waves_between_caravans -= 1; if (ch == 'l' && waves_between_caravans < 50) waves_between_caravans += 1; mvwprintz(w, 11, 22, c_black, "xxx"); mvwprintz(w, 11, NUMALIGN(waves_between_caravans), c_yellow, "%d", waves_between_caravans); break; case 7: if (ch == 'h' && initial_cash > 0) initial_cash -= 100; if (ch == 'l' && initial_cash < 99900) initial_cash += 100; mvwprintz(w, 13, 20, c_black, "xxxxx"); mvwprintz(w, 13, NUMALIGN(initial_cash), c_yellow, "%d", initial_cash); break; case 8: if (ch == 'h' && cash_per_wave > 0) cash_per_wave -= 100; if (ch == 'l' && cash_per_wave < 9900) cash_per_wave += 100; mvwprintz(w, 14, 21, c_black, "xxxx"); mvwprintz(w, 14, NUMALIGN(cash_per_wave), c_yellow, "%d", cash_per_wave); break; case 9: if (ch == 'h' && cash_increase > 0) cash_increase -= 50; if (ch == 'l' && cash_increase < 9950) cash_increase += 50; mvwprintz(w, 15, 21, c_black, "xxxx"); mvwprintz(w, 15, NUMALIGN(cash_increase), c_yellow, "%d", cash_increase); break; case 10: if (ch == ' ' || ch == '\n') { zombies = !zombies; specials = false; } mvwprintz(w, 18, 2, (zombies ? c_ltgreen : c_yellow), "Zombies"); mvwprintz(w, 18, 14, c_yellow, "Special Zombies"); break; case 11: if (ch == ' ' || ch == '\n') { specials = !specials; zombies = false; } mvwprintz(w, 18, 2, c_yellow, "Zombies"); mvwprintz(w, 18, 14, (specials ? c_ltgreen : c_yellow), "Special Zombies"); break; case 12: if (ch == ' ' || ch == '\n') spiders = !spiders; mvwprintz(w, 18, 34, (spiders ? c_ltgreen : c_yellow), "Spiders"); break; case 13: if (ch == ' ' || ch == '\n') triffids = !triffids; mvwprintz(w, 18, 46, (triffids ? c_ltgreen : c_yellow), "Triffids"); break; case 14: if (ch == ' ' || ch == '\n') robots = !robots; mvwprintz(w, 18, 59, (robots ? c_ltgreen : c_yellow), "Robots"); break; case 15: if (ch == ' ' || ch == '\n') subspace = !subspace; mvwprintz(w, 18, 70, (subspace ? c_ltgreen : c_yellow), "Subspace"); break; case 16: if (ch == ' ' || ch == '\n') hunger = !hunger; mvwprintz(w, 21, 2, (hunger ? c_ltgreen : c_yellow), "Food"); break; case 17: if (ch == ' ' || ch == '\n') thirst = !thirst; mvwprintz(w, 21, 16, (thirst ? c_ltgreen : c_yellow), "Water"); break; case 18: if (ch == ' ' || ch == '\n') sleep = !sleep; mvwprintz(w, 21, 31, (sleep ? c_ltgreen : c_yellow), "Sleep"); break; case 19: if (ch == ' ' || ch == '\n') mercenaries = !mercenaries; mvwprintz(w, 21, 46, (mercenaries ? c_ltgreen : c_yellow), "Mercenaries"); break; } } if (ch == 'h' || ch == 'l' || ch == ' ' || ch == '\n') refresh_setup(w, selection); } }
void player::power_mutations() { if( !is_player() ) { // TODO: Implement NPCs activating muts return; } std::vector <std::string> passive; std::vector <std::string> active; for( auto &mut : my_mutations ) { if (!mutation_branch::get( mut.first ).activated) { passive.push_back(mut.first); } else { active.push_back(mut.first); } // New mutations are initialized with no key at all, so we have to do this here. if( mut.second.key == ' ' ) { for( const auto &letter : mutation_chars ) { if( trait_by_invlet( letter ).empty() ) { mut.second.key = letter; break; } } } } // maximal number of rows in both columns const int mutations_count = std::max(passive.size(), active.size()); int TITLE_HEIGHT = 2; int DESCRIPTION_HEIGHT = 5; // Main window /** Total required height is: * top frame line: + 1 * height of title window: + TITLE_HEIGHT * line after the title: + 1 * line with active/passive mutation captions: + 1 * height of the biggest list of active/passive mutations: + mutations_count * line before mutation description: + 1 * height of description window: + DESCRIPTION_HEIGHT * bottom frame line: + 1 * TOTAL: TITLE_HEIGHT + mutations_count + DESCRIPTION_HEIGHT + 5 */ int HEIGHT = std::min(TERMY, std::max(FULL_SCREEN_HEIGHT, TITLE_HEIGHT + mutations_count + DESCRIPTION_HEIGHT + 5)); int WIDTH = FULL_SCREEN_WIDTH + (TERMX - FULL_SCREEN_WIDTH) / 2; int START_X = (TERMX - WIDTH) / 2; int START_Y = (TERMY - HEIGHT) / 2; WINDOW *wBio = newwin(HEIGHT, WIDTH, START_Y, START_X); // Description window @ the bottom of the bio window int DESCRIPTION_START_Y = START_Y + HEIGHT - DESCRIPTION_HEIGHT - 1; int DESCRIPTION_LINE_Y = DESCRIPTION_START_Y - START_Y - 1; WINDOW *w_description = newwin(DESCRIPTION_HEIGHT, WIDTH - 2, DESCRIPTION_START_Y, START_X + 1); // Title window int TITLE_START_Y = START_Y + 1; int HEADER_LINE_Y = TITLE_HEIGHT + 1; // + lines with text in titlebar, local WINDOW *w_title = newwin(TITLE_HEIGHT, WIDTH - 2, TITLE_START_Y, START_X + 1); int scroll_position = 0; int second_column = 32 + (TERMX - FULL_SCREEN_WIDTH) / 4; // X-coordinate of the list of active mutations input_context ctxt("MUTATIONS"); ctxt.register_updown(); ctxt.register_action("ANY_INPUT"); ctxt.register_action("TOGGLE_EXAMINE"); ctxt.register_action("REASSIGN"); ctxt.register_action("HELP_KEYBINDINGS"); bool redraw = true; std::string menu_mode = "activating"; while(true) { // offset for display: mutation with index i is drawn at y=list_start_y+i // drawing the mutation starts with mutation[scroll_position] const int list_start_y = HEADER_LINE_Y + 2 - scroll_position; int max_scroll_position = HEADER_LINE_Y + 2 + mutations_count - ((menu_mode == "examining") ? DESCRIPTION_LINE_Y : (HEIGHT - 1)); if(redraw) { redraw = false; werase(wBio); draw_border(wBio); // Draw line under title mvwhline(wBio, HEADER_LINE_Y, 1, LINE_OXOX, WIDTH - 2); // Draw symbols to connect additional lines to border mvwputch(wBio, HEADER_LINE_Y, 0, BORDER_COLOR, LINE_XXXO); // |- mvwputch(wBio, HEADER_LINE_Y, WIDTH - 1, BORDER_COLOR, LINE_XOXX); // -| // Captions mvwprintz(wBio, HEADER_LINE_Y + 1, 2, c_ltblue, _("Passive:")); mvwprintz(wBio, HEADER_LINE_Y + 1, second_column, c_ltblue, _("Active:")); draw_exam_window(wBio, DESCRIPTION_LINE_Y, menu_mode == "examining"); nc_color type; if (passive.empty()) { mvwprintz(wBio, list_start_y, 2, c_ltgray, _("None")); } else { for (size_t i = scroll_position; i < passive.size(); i++) { const auto &md = mutation_branch::get( passive[i] ); const auto &td = my_mutations[passive[i]]; if (list_start_y + static_cast<int>(i) == (menu_mode == "examining" ? DESCRIPTION_LINE_Y : HEIGHT - 1)) { break; } type = c_cyan; mvwprintz(wBio, list_start_y + i, 2, type, "%c %s", td.key, md.name.c_str()); } } if (active.empty()) { mvwprintz(wBio, list_start_y, second_column, c_ltgray, _("None")); } else { for (size_t i = scroll_position; i < active.size(); i++) { const auto &md = mutation_branch::get( active[i] ); const auto &td = my_mutations[active[i]]; if (list_start_y + static_cast<int>(i) == (menu_mode == "examining" ? DESCRIPTION_LINE_Y : HEIGHT - 1)) { break; } if (!td.powered) { type = c_red; }else if (td.powered) { type = c_ltgreen; } else { type = c_ltred; } // TODO: track resource(s) used and specify mvwputch( wBio, list_start_y + i, second_column, type, td.key ); std::stringstream mut_desc; mut_desc << md.name; if ( md.cost > 0 && md.cooldown > 0 ) { mut_desc << string_format( _(" - %d RU / %d turns"), md.cost, md.cooldown ); } else if ( md.cost > 0 ) { mut_desc << string_format( _(" - %d RU"), md.cost ); } else if ( md.cooldown > 0 ) { mut_desc << string_format( _(" - %d turns"), md.cooldown ); } if ( td.powered ) { mut_desc << _(" - Active"); } mvwprintz( wBio, list_start_y + i, second_column + 2, type, mut_desc.str().c_str() ); } } // Scrollbar if(scroll_position > 0) { mvwputch(wBio, HEADER_LINE_Y + 2, 0, c_ltgreen, '^'); } if(scroll_position < max_scroll_position && max_scroll_position > 0) { mvwputch(wBio, (menu_mode == "examining" ? DESCRIPTION_LINE_Y : HEIGHT - 1) - 1, 0, c_ltgreen, 'v'); } } wrefresh(wBio); show_mutations_titlebar(w_title, this, menu_mode); const std::string action = ctxt.handle_input(); const long ch = ctxt.get_raw_input().get_first_input(); if (menu_mode == "reassigning") { menu_mode = "activating"; const auto mut_id = trait_by_invlet( ch ); if( mut_id.empty() ) { // Selected an non-existing mutation (or escape, or ...) continue; } redraw = true; const long newch = popup_getkey(_("%s; enter new letter."), mutation_branch::get_name( mut_id ).c_str()); wrefresh(wBio); if(newch == ch || newch == ' ' || newch == KEY_ESCAPE) { continue; } if( !mutation_chars.valid( newch ) ) { popup( _("Invalid mutation letter. Only those characters are valid:\n\n%s"), mutation_chars.get_allowed_chars().c_str() ); continue; } const auto other_mut_id = trait_by_invlet( newch ); if( !other_mut_id.empty() ) { std::swap(my_mutations[mut_id].key, my_mutations[other_mut_id].key); } else { my_mutations[mut_id].key = newch; } // TODO: show a message like when reassigning a key to an item? } else if (action == "DOWN") { if(scroll_position < max_scroll_position) { scroll_position++; redraw = true; } } else if (action == "UP") { if(scroll_position > 0) { scroll_position--; redraw = true; } } else if (action == "REASSIGN") { menu_mode = "reassigning"; } else if (action == "TOGGLE_EXAMINE") { // switches between activation and examination menu_mode = menu_mode == "activating" ? "examining" : "activating"; werase(w_description); draw_exam_window(wBio, DESCRIPTION_LINE_Y, false); redraw = true; }else if (action == "HELP_KEYBINDINGS") { redraw = true; } else { const auto mut_id = trait_by_invlet( ch ); if( mut_id.empty() ) { // entered a key that is not mapped to any mutation, // -> leave screen break; } const auto &mut_data = mutation_branch::get( mut_id ); if (menu_mode == "activating") { if (mut_data.activated) { if (my_mutations[mut_id].powered) { add_msg_if_player(m_neutral, _("You stop using your %s."), mut_data.name.c_str()); deactivate_mutation( mut_id ); delwin(w_title); delwin(w_description); delwin(wBio); // Action done, leave screen break; } else if( (!mut_data.hunger || get_hunger() <= 400) && (!mut_data.thirst || get_thirst() <= 400) && (!mut_data.fatigue || get_fatigue() <= 400) ) { // this will clear the mutations menu for targeting purposes werase(wBio); wrefresh(wBio); delwin(w_title); delwin(w_description); delwin(wBio); g->draw(); add_msg_if_player( m_neutral, _("You activate your %s."), mut_data.name.c_str() ); activate_mutation( mut_id ); // Action done, leave screen break; } else { popup( _( "You don't have enough in you to activate your %s!" ), mut_data.name.c_str() ); redraw = true; continue; } } else { popup(_("\ You cannot activate %s! To read a description of \ %s, press '!', then '%c'."), mut_data.name.c_str(), mut_data.name.c_str(), my_mutations[mut_id].key ); redraw = true; } } if (menu_mode == "examining") { // Describing mutations, not activating them! draw_exam_window(wBio, DESCRIPTION_LINE_Y, true); // Clear the lines first werase(w_description); fold_and_print(w_description, 0, 0, WIDTH - 2, c_ltblue, mut_data.description); wrefresh(w_description); } } } //if we activated a mutation, already killed the windows if(!(menu_mode == "activating")) { werase(wBio); wrefresh(wBio); delwin(w_title); delwin(w_description); delwin(wBio); } }
void faction_manager::display() const { std::vector<const faction *> valfac; // Factions that we know of. for( const faction &elem : factions ) { if( elem.known_by_u ) { valfac.push_back( &elem ); } } if( valfac.empty() ) { // We don't know of any factions! popup( _( "You don't know of any factions. Press Spacebar..." ) ); return; } catacurses::window w_list = catacurses::newwin( FULL_SCREEN_HEIGHT, FULL_SCREEN_WIDTH, ( ( TERMY > FULL_SCREEN_HEIGHT ) ? ( TERMY - FULL_SCREEN_HEIGHT ) / 2 : 0 ), ( TERMX > FULL_SCREEN_WIDTH ) ? ( TERMX - FULL_SCREEN_WIDTH ) / 2 : 0 ); catacurses::window w_info = catacurses::newwin( FULL_SCREEN_HEIGHT - 2, FULL_SCREEN_WIDTH - 1 - MAX_FAC_NAME_SIZE, 1 + ( ( TERMY > FULL_SCREEN_HEIGHT ) ? ( TERMY - FULL_SCREEN_HEIGHT ) / 2 : 0 ), MAX_FAC_NAME_SIZE + ( ( TERMX > FULL_SCREEN_WIDTH ) ? ( TERMX - FULL_SCREEN_WIDTH ) / 2 : 0 ) ); const int maxlength = FULL_SCREEN_WIDTH - 1 - MAX_FAC_NAME_SIZE; size_t sel = 0; bool redraw = true; input_context ctxt( "FACTIONS" ); ctxt.register_action( "UP", _( "Move cursor up" ) ); ctxt.register_action( "DOWN", _( "Move cursor down" ) ); ctxt.register_action( "QUIT" ); ctxt.register_action( "HELP_KEYBINDINGS" ); while( true ) { const faction &cur_frac = *valfac[sel]; if( redraw ) { werase( w_list ); draw_border( w_list ); mvwprintz( w_list, 1, 1, c_white, _( "FACTIONS:" ) ); for( size_t i = 0; i < valfac.size(); i++ ) { nc_color col = ( i == sel ? h_white : c_white ); mvwprintz( w_list, i + 2, 1, col, _( valfac[i]->name.c_str() ) ); } wrefresh( w_list ); werase( w_info ); mvwprintz( w_info, 0, 0, c_white, _( "Ranking: %s" ), fac_ranking_text( cur_frac.likes_u ) ); mvwprintz( w_info, 1, 0, c_white, _( "Respect: %s" ), fac_respect_text( cur_frac.respects_u ) ); mvwprintz( w_info, 2, 0, c_white, _( "Wealth: %s" ), fac_wealth_text( cur_frac.wealth, cur_frac.size ) ); mvwprintz( w_info, 3, 0, c_white, _( "Food Supply: %s" ), fac_food_supply_text( cur_frac.food_supply, cur_frac.size ) ); mvwprintz( w_info, 4, 0, c_white, _( "Combat Ability: %s" ), fac_combat_ability_text( cur_frac.combat_ability ) ); fold_and_print( w_info, 6, 0, maxlength, c_white, cur_frac.describe() ); wrefresh( w_info ); redraw = false; } const std::string action = ctxt.handle_input(); if( action == "DOWN" ) { mvwprintz( w_list, sel + 2, 1, c_white, cur_frac.name ); sel = ( sel + 1 ) % valfac.size(); redraw = true; } else if( action == "UP" ) { mvwprintz( w_list, sel + 2, 1, c_white, cur_frac.name ); sel = ( sel + valfac.size() - 1 ) % valfac.size(); redraw = true; } else if( action == "HELP_KEYBINDINGS" ) { redraw = true; } else if( action == "QUIT" ) { break; } else if( action == "CONFIRM" ) { break; } } }
/** Reimplementation. */ void CBibleReadWindow::setupPopupMenu() { popup()->setTitle(tr("Bible window")); popup()->setIcon(util::tool::getIconForModule(modules().first()) ); popup()->addAction(m_actions.findText); QKeySequence ks = m_actions.findText->shortcut(); QString keys = ks.toString(); popup()->addAction(m_actions.findStrongs); popup()->addAction(m_actions.selectAll); popup()->addSeparator(); m_actions.copyMenu = new QMenu(tr("Copy..."), popup()); m_actions.copyMenu->addAction(m_actions.copy.referenceOnly); m_actions.copyMenu->addAction(m_actions.copy.referenceTextOnly); m_actions.copyMenu->addAction(m_actions.copy.referenceAndText); m_actions.copyMenu->addAction(m_actions.copy.chapter); m_actions.copyMenu->addSeparator(); m_actions.copyMenu->addAction(m_actions.copy.selectedText); popup()->addMenu(m_actions.copyMenu); m_actions.saveMenu = new QMenu(tr("Save..."), popup()); m_actions.saveMenu->addAction(m_actions.save.referenceAndText); m_actions.saveMenu->addAction(m_actions.save.chapterAsPlain); m_actions.saveMenu->addAction(m_actions.save.chapterAsHTML); // Save raw HTML action for debugging purposes if (qApp->property("--debug").toBool()) { QAction* debugAction = new QAction("Raw HTML", this); QObject::connect(debugAction, SIGNAL(triggered()), this, SLOT(saveRawHTML())); m_actions.saveMenu->addAction(debugAction); } // end of Save Raw HTML popup()->addMenu(m_actions.saveMenu); m_actions.printMenu = new QMenu(tr("Print..."), popup()); m_actions.printMenu->addAction(m_actions.print.reference); m_actions.printMenu->addAction(m_actions.print.chapter); popup()->addMenu(m_actions.printMenu); }
void TaskbarProxy::showMenu (const QString& widStr, int x, int y) { auto& w = Util::XWrapper::Instance (); const auto& wid = widStr.toULong (); const auto state = w.GetWindowState (wid); const auto actions = w.GetWindowActions (wid); auto menu = new QMenu; menu->setAttribute (Qt::WA_DeleteOnClose); { auto minimizeAct = menu->addAction (tr ("Minimize")); minimizeAct->setCheckable (true); if (state & Util::WinStateFlag::Hidden) minimizeAct->setChecked (true); else minimizeAct->setEnabled (actions & Util::AllowedActionFlag::Minimize); minimizeAct->setProperty ("Actor", QVariant::fromValue<Actor_f> ([this, state] (const QString& wid) { state & Util::WinStateFlag::Hidden ? raiseWindow (wid) : minimizeWindow (wid); })); } { auto maximizeAct = menu->addAction (tr ("Maximize")); maximizeAct->setCheckable (true); const bool isMaximized = state & Util::WinStateFlag::MaximizedHorz || state & Util::WinStateFlag::MaximizedVert; if (isMaximized) maximizeAct->setChecked (true); else maximizeAct->setEnabled (actions & Util::AllowedActionFlag::MaximizeHorz || actions & Util::AllowedActionFlag::MaximizeVert); maximizeAct->setProperty ("Actor", QVariant::fromValue<Actor_f> ([this, isMaximized] (const QString& wid) { isMaximized ? unmaximizeWindow (wid) : maximizeWindow (wid); })); } auto moreMenu = menu->addMenu (tr ("More")); { auto keepAbove = moreMenu->addAction (tr ("Keep above others")); keepAbove->setEnabled (actions & Util::AllowedActionFlag::MoveToTop); keepAbove->setCheckable (true); const bool isTop = state & Util::WinStateFlag::OnTop; keepAbove->setChecked (isTop); keepAbove->setProperty ("Actor", QVariant::fromValue<Actor_f> ([this, isTop] (const QString& wid) { moveWindowTo (wid, isTop ? "normal" : "top"); })); keepAbove->setIcon (Proxy_->GetIconThemeManager ()->GetIcon ("go-top")); } { auto keepBelow = moreMenu->addAction (tr ("Keep below others")); keepBelow->setEnabled (actions & Util::AllowedActionFlag::MoveToBottom); keepBelow->setCheckable (true); const bool isBottom = state & Util::WinStateFlag::OnBottom; keepBelow->setChecked (isBottom); keepBelow->setProperty ("Actor", QVariant::fromValue<Actor_f> ([this, isBottom] (const QString& wid) { moveWindowTo (wid, isBottom ? "normal" : "bottom"); })); keepBelow->setIcon (Proxy_->GetIconThemeManager ()->GetIcon ("go-bottom")); } { auto shadeAct = moreMenu->addAction (tr ("Shade")); shadeAct->setEnabled (actions & Util::AllowedActionFlag::Shade); shadeAct->setCheckable (true); shadeAct->setChecked (state & Util::WinStateFlag::Shaded); shadeAct->setProperty ("Actor", QVariant::fromValue<Actor_f> ([this] (const QString& wid) { toggleShadeWindow (wid); })); } QMenu *desksMenu = 0; { const auto numDesks = w.GetDesktopCount (); if (numDesks > 1) { desksMenu = menu->addMenu (tr ("Move to desktop")); const auto winDesk = w.GetWindowDesktop (wid); auto addAct = [this, actions, winDesk, desksMenu] (int num, const QString& name) { auto act = desksMenu->addAction (name); act->setEnabled (actions & Util::AllowedActionFlag::ChangeDesktop); act->setCheckable (true); act->setChecked (winDesk == num); act->setProperty ("Actor", QVariant::fromValue<Actor_f> ([this, num] (const QString& wid) { moveToDesktop (wid, num); })); }; const auto& deskNames = w.GetDesktopNames (); for (int i = 0; i < numDesks; ++i) addAct (i, deskNames.value (i, QString::number (i))); desksMenu->addSeparator (); addAct (0xFFFFFFFF, tr ("All desktops")); } } menu->addSeparator (); { auto closeAct = menu->addAction (tr ("Close")); closeAct->setEnabled (actions & Util::AllowedActionFlag::Close); closeAct->setProperty ("Actor", QVariant::fromValue<Actor_f> ([this] (const QString& wid) { closeWindow (wid); })); closeAct->setIcon (Proxy_->GetIconThemeManager ()->GetIcon ("window-close")); } auto allActions = menu->actions () + moreMenu->actions (); if (desksMenu) allActions += desksMenu->actions (); for (auto act : allActions) { act->setProperty ("WID", widStr); connect (act, SIGNAL (triggered ()), this, SLOT (handleAction ())); } menu->popup ({ x, y }); }
void iuse::two_way_radio(game *g, player *p, item *it, bool t) { WINDOW* w = newwin(6, 36, 9, 5); wborder(w, LINE_XOXO, LINE_XOXO, LINE_OXOX, LINE_OXOX, LINE_OXXO, LINE_OOXX, LINE_XXOO, LINE_XOOX ); // TODO: More options here. Thoughts... // > Respond to the SOS of an NPC // > Report something to a faction // > Call another player mvwprintz(w, 1, 1, c_white, "1: Radio a faction for help..."); mvwprintz(w, 2, 1, c_white, "2: Call Acquaitance..."); mvwprintz(w, 3, 1, c_white, "3: General S.O.S."); mvwprintz(w, 4, 1, c_white, "0: Cancel"); wrefresh(w); char ch = getch(); if (ch == '1') { p->moves -= 300; faction* fac = g->list_factions("Call for help..."); if (fac == NULL) { it->charges++; return; } int bonus = 0; if (fac->goal == FACGOAL_CIVILIZATION) bonus += 2; if (fac->has_job(FACJOB_MERCENARIES)) bonus += 4; if (fac->has_job(FACJOB_DOCTORS)) bonus += 2; if (fac->has_value(FACVAL_CHARITABLE)) bonus += 3; if (fac->has_value(FACVAL_LONERS)) bonus -= 3; if (fac->has_value(FACVAL_TREACHERY)) bonus -= rng(0, 8); bonus += fac->respects_u + 3 * fac->likes_u; if (bonus >= 25) { popup("They reply, \"Help is on the way!\""); g->add_event(EVENT_HELP, g->turn + fac->response_time(g), fac->id, -1, -1); fac->respects_u -= rng(0, 8); fac->likes_u -= rng(3, 5); } else if (bonus >= -5) { popup("They reply, \"Sorry, you're on your own!\""); fac->respects_u -= rng(0, 5); } else { popup("They reply, \"Hah! We hope you die!\""); fac->respects_u -= rng(1, 8); } } else if (ch == '2') { // Call Acquaitance // TODO: Implement me! } else if (ch == '3') { // General S.O.S. p->moves -= 150; std::vector<npc*> in_range; for (int i = 0; i < g->cur_om.npcs.size(); i++) { if (g->cur_om.npcs[i].op_of_u.value >= 4 && trig_dist(g->levx, g->levy, g->cur_om.npcs[i].mapx, g->cur_om.npcs[i].mapy) <= 30) in_range.push_back(&(g->cur_om.npcs[i])); } if (in_range.size() > 0) { npc* coming = in_range[rng(0, in_range.size() - 1)]; popup("A reply! %s says, \"I'm on my way; give me %d minutes!\"", coming->name.c_str(), coming->minutes_to_u(g)); coming->mission = NPC_MISSION_RESCUE_U; } else popup("No-one seems to reply..."); } else it->charges++; // Canceled the call, get our charge back werase(w); wrefresh(w); delwin(w); refresh(); }
bool MultiIconValueIndicator::EventFilter(GG::Wnd* w, const GG::WndEvent& event) { if (event.Type() != GG::WndEvent::RClick) return false; const GG::Pt& pt = event.Point(); MeterType meter_type = INVALID_METER_TYPE; for (unsigned int i = 0; i < m_icons.size(); ++i) { try { if (m_icons.at(i) == w) { meter_type = m_meter_types.at(i).first; break; } } catch(std::out_of_range &e) { ErrorLogger() << e.what(); return false; } } if (meter_type == INVALID_METER_TYPE) return false; std::string meter_string = boost::lexical_cast<std::string>(meter_type); std::string meter_title; if (UserStringExists(meter_string)) meter_title = UserString(meter_string); GG::MenuItem menu_contents; std::string species_name; std::shared_ptr<const PopCenter> pc = GetPopCenter(*m_object_ids.begin()); if (meter_type == METER_POPULATION && pc && m_object_ids.size() == 1) { species_name = pc->SpeciesName(); if (!species_name.empty()) { std::string species_label = boost::io::str(FlexibleFormat(UserString("ENC_LOOKUP")) % UserString(species_name)); menu_contents.next_level.push_back(GG::MenuItem(species_label, 1, false, false)); } } if (!meter_title.empty()) { std::string popup_label = boost::io::str(FlexibleFormat(UserString("ENC_LOOKUP")) % meter_title); menu_contents.next_level.push_back(GG::MenuItem(popup_label, 2, false, false)); } CUIPopupMenu popup(pt.x, pt.y, menu_contents); bool retval = false; if (popup.Run()) { switch (popup.MenuID()) { case 1: { retval = ClientUI::GetClientUI()->ZoomToSpecies(species_name); break; } case 2: { retval = ClientUI::GetClientUI()->ZoomToMeterTypeArticle(meter_string); break; } default: break; } } return retval; }
void player_select_do() { int k; // Goober5000 - display a popup warning about problems in the mod if ((Global_warning_count > 10 || Global_error_count > 0) && !Startup_warning_dialog_displayed) { char text[512]; sprintf(text, "Warning!\n\nThe currently active mod has generated %d warnings and/or errors during program startup. These could have been caused by anything from incorrectly formated table files to corrupt models. While FreeSpace Open will attempt to compensate for these issues, it cannot guarantee a trouble-free gameplay experience. Source Code Project staff cannot provide assistance or support for these problems, as they are caused by the mod's data files, not FreeSpace Open's source code.", Global_warning_count + Global_error_count); popup(PF_TITLE_BIG | PF_TITLE_RED | PF_USE_AFFIRMATIVE_ICON, 1, POPUP_OK, text); Startup_warning_dialog_displayed = true; } // set the input box at the "virtual" line 0 to be active so the player can enter a callsign if (Player_select_input_mode) { Player_select_input_box.set_focus(); } // process any ui window stuff k = Player_select_window.process(); if (k) { extern void game_process_cheats(int k); game_process_cheats(k); } switch (k) { // switch between single and multiplayer modes case KEY_TAB: { if (Player_select_input_mode) { gamesnd_play_iface(SND_GENERAL_FAIL); break; } // play a little sound gamesnd_play_iface(SND_USER_SELECT); if (Player_select_mode == PLAYER_SELECT_MODE_MULTI) { player_select_set_bottom_text(XSTR( "Single-Player Mode", 376)); // reinitialize as single player mode player_select_init_player_stuff(PLAYER_SELECT_MODE_SINGLE); } else if (Player_select_mode == PLAYER_SELECT_MODE_SINGLE) { player_select_set_bottom_text(XSTR( "Multiplayer Mode", 377)); // reinitialize as multiplayer mode player_select_init_player_stuff(PLAYER_SELECT_MODE_MULTI); } break; } case KEY_ESC: { // we can hit ESC to get out of text input mode, and we don't want // to set this var in that case since it will crash on a NULL Player // ptr when going to the mainhall if ( !Player_select_input_mode ) { Player_select_no_save_pilot = 1; } break; } } // draw the player select pseudo-dialog over it GR_MAYBE_CLEAR_RES(Player_select_background_bitmap); gr_set_bitmap(Player_select_background_bitmap); gr_bitmap(0,0,GR_RESIZE_MENU); // press the accept button if (Player_select_autoaccept) { Player_select_buttons[gr_screen.res][ACCEPT_BUTTON].button.press_button(); } // draw any ui window stuf Player_select_window.draw(); // light up the correct mode button (single or multi) if (Player_select_mode == PLAYER_SELECT_MODE_SINGLE) { Player_select_buttons[gr_screen.res][SINGLE_BUTTON].button.draw_forced(2); } else { Player_select_buttons[gr_screen.res][MULTI_BUTTON].button.draw_forced(2); } // draw the pilot list text player_select_draw_list(); // draw copyright message on the bottom on the screen player_select_display_copyright(); if (!Player_select_input_mode) { player_select_process_noninput(k); } else { player_select_process_input(k); } // draw any pending messages on the bottom or middle of the screen player_select_display_all_text(); gr_flip(); }
void SectionPopup::show_popup() { popup(QCursor::pos()); }
void player_select_button_pressed(int n) { int ret; switch (n) { case SCROLL_LIST_UP_BUTTON: player_select_set_bottom_text(""); player_select_scroll_list_up(); break; case SCROLL_LIST_DOWN_BUTTON: player_select_set_bottom_text(""); player_select_scroll_list_down(); break; case ACCEPT_BUTTON: // make sure he has a valid pilot selected if (Player_select_pilot < 0) { popup(PF_USE_AFFIRMATIVE_ICON,1,POPUP_OK,XSTR( "You must select a valid pilot first", 378)); } else { if (valid_pilot_lang(Pilots[Player_select_pilot])) { player_select_commit(); } else { popup(PF_USE_AFFIRMATIVE_ICON,1,POPUP_OK,XSTR( "Selected pilot was created with a different language\n" "to the currently active language.\n\n" "Please select a different pilot or change the language", 1637)); } } break; case CLONE_BUTTON: // if we're at max-pilots, don't allow another to be added if (Player_select_num_pilots >= MAX_PILOTS) { player_select_set_bottom_text(XSTR( "You already have the maximum # of pilots!", 379)); gamesnd_play_iface(SND_GENERAL_FAIL); break; } if (Player_select_pilot >= 0) { // first we have to make sure this guy is actually loaded for when we create the clone if (Player == NULL) { Player = &Players[0]; Player->flags |= PLAYER_FLAGS_STRUCTURE_IN_USE; } // attempt to read in the pilot file of the guy to be cloned if ( !Pilot.load_player(Pilots[Player_select_pilot], Player) ) { Error(LOCATION,"Couldn't load pilot file, bailing"); Player = NULL; Int3(); } // set the clone flag Player_select_clone_flag = 1; // create the new pilot (will be cloned with Player_select_clone_flag_set) if ( !player_select_create_new_pilot() ) { player_select_set_bottom_text(XSTR( "Error creating new pilot file!", 380)); Player_select_clone_flag = 0; Player->reset(); Player = NULL; break; } // display some text on the bottom of the dialog player_select_set_bottom_text(XSTR( "Type Callsign and Press Enter", 381)); // gray out all controls in the dialog player_select_set_controls(1); } break; case CREATE_PILOT_BUTTON: // if we're at max-pilots, don't allow another to be added if(Player_select_num_pilots >= MAX_PILOTS) { player_select_set_bottom_text(XSTR( "You already have the maximum # of pilots!", 379)); gamesnd_play_iface(SND_GENERAL_FAIL); break; } // create a new pilot if ( !player_select_create_new_pilot() ) { player_select_set_bottom_text(XSTR( "Type Callsign and Press Enter", 381)); } // don't clone anyone Player_select_clone_flag = 0; // display some text on the bottom of the dialog player_select_set_bottom_text(XSTR( "Type Callsign and Press Enter", 381)); // gray out all controls player_select_set_controls(1); break; case DELETE_BUTTON: player_select_set_bottom_text(""); if (Player_select_pilot >= 0) { if (Player_select_mode == PLAYER_SELECT_MODE_MULTI) { popup(PF_TITLE_BIG | PF_TITLE_RED | PF_USE_AFFIRMATIVE_ICON, 1, POPUP_OK, XSTR("Disabled!\n\nMulti and single player pilots are now identical. " "Deleting a multi-player pilot will also delete all single-player data for that pilot.\n\nAs a safety precaution, pilots can only be " "deleted from the single-player menu.", 1610)); } else { // display a popup requesting confirmation ret = popup(PF_TITLE_BIG | PF_TITLE_RED, 2, POPUP_NO, POPUP_YES, XSTR( "Warning!\n\nAre you sure you wish to delete this pilot?", 382)); // delete the pilot if (ret == 1) { player_select_delete_pilot(); } } } break; case SINGLE_BUTTON: player_select_set_bottom_text(""); Player_select_autoaccept = 0; // switch to single player mode if (Player_select_mode != PLAYER_SELECT_MODE_SINGLE) { // play a little sound gamesnd_play_iface(SND_USER_SELECT); player_select_set_bottom_text(XSTR( "Single Player Mode", 376)); // reinitialize as single player mode player_select_init_player_stuff(PLAYER_SELECT_MODE_SINGLE); } else { gamesnd_play_iface(SND_GENERAL_FAIL); } break; case MULTI_BUTTON: player_select_set_bottom_text(""); Player_select_autoaccept = 0; if ( Networking_disabled ) { game_feature_disabled_popup(); break; } // switch to multiplayer mode if (Player_select_mode != PLAYER_SELECT_MODE_MULTI) { // play a little sound gamesnd_play_iface(SND_USER_SELECT); player_select_set_bottom_text(XSTR( "Multiplayer Mode", 377)); // reinitialize as multiplayer mode player_select_init_player_stuff(PLAYER_SELECT_MODE_MULTI); } else { gamesnd_play_iface(SND_GENERAL_FAIL); } break; } }
void PStatus::MouseDown(BPoint where) { bigtime_t longEnough = system_time() + 250000; do { BPoint p; unsigned long btns; GetMouse(&p, &btns); if (!btns) { Window()->PostMessage(msg_GoToLine, fText); return; } if (fabs(where.x - p.x) > 2 || fabs(where.y - p.y) > 2) break; } while (system_time() < longEnough); if (fPath) { BPopUpMenu popup("no title"); popup.SetFont(be_plain_font); char *s = strdup(fPath), *d; d = strrchr(s, '/'); if (d) *d = 0; d = strtok(s, "/"); while (d) { popup.AddItem(new BMenuItem(d, NULL), 0); d = strtok(NULL, "/"); } where.y = Bounds().bottom + 1; BMenuItem *i = popup.Go(ConvertToScreen(where), true, false, ConvertToScreen(Bounds())); if (i) { free(s); s = strdup(fPath); d = strchr(s, '/'); FailNil(d); int ix = popup.CountItems() - popup.IndexOf(i); while (ix--) d = strchr(d + 1, '/'); FailNil(d); *d = 0; entry_ref ref; FailOSErr(get_ref_for_path(s, &ref)); OpenInTracker(ref); } free(s); } else beep(); } /* PStatus::MouseDown */
void barracks_delete_pilot() { char buf[MAX_FILENAME_LEN]; int active = 0; int del_rval; if (!Num_pilots) { gamesnd_play_iface(SND_GENERAL_FAIL); return; } if (Player_sel_mode == PLAYER_SELECT_MODE_MULTI) { gamesnd_play_iface(SND_GENERAL_FAIL); popup(PF_TITLE_BIG | PF_TITLE_RED | PF_USE_AFFIRMATIVE_ICON, 1, POPUP_OK, XSTR("Disabled!\n\nMulti and single player pilots are now identical. " "Deleting a multi-player pilot will also delete all single-player data for that pilot.\n\nAs a safety precaution, pilots can only be " "deleted from the single-player menu.", 1598)); return; } int popup_rval = popup(PF_TITLE_BIG | PF_TITLE_RED, 2, POPUP_NO, POPUP_YES, XSTR( "Warning!\n\nAre you sure you wish to delete this pilot?", 65)); if (popup_rval != 1) { return; } if (!stricmp(Pilots[Selected_line], Cur_pilot->callsign)) { active = 1; } strcpy_s(buf, Pilots[Selected_line]); del_rval = delete_pilot_file(buf); if ( !del_rval ) { popup(PF_USE_AFFIRMATIVE_ICON | PF_TITLE_BIG | PF_TITLE_RED, 1, POPUP_OK, XSTR("Error\nFailed to delete pilot file. File may be read-only.", 1599)); return; } else { if (active) { Cur_pilot->callsign[0] = 0; } } for (int i=Selected_line; i<Num_pilots-1; i++) { strcpy(Pilots[i], Pilots[i + 1]); Pilot_ranks[i] = Pilot_ranks[i + 1]; } Num_pilots--; if (Selected_line >= Num_pilots) { Selected_line = Num_pilots - 1; } if (active) { if (Selected_line >= 0) { barracks_new_pilot_selected(); } else { Cur_pilot->callsign[0] = 0; } } gamesnd_play_iface(SND_USER_SELECT); }