void ItemInfoDisplay::CheckHover(const Table &table, const string &label) const { Point distance = hoverPoint - table.GetCenterPoint(); Point radius = .5 * table.GetRowSize(); if(abs(distance.X()) < radius.X() && abs(distance.Y()) < radius.Y()) { hoverCount += 2 * (label == hover); hover = label; if(hoverCount >= HOVER_TIME) { hoverCount = HOVER_TIME; hoverText.Wrap(GameData::Tooltip(label)); } } }
void PreferencesPanel::DrawPlugins() { const Color &back = *GameData::Colors().Get("faint"); const Color &medium = *GameData::Colors().Get("medium"); const Color &bright = *GameData::Colors().Get("bright"); Table table; table.AddColumn(-115, Table::LEFT); table.SetUnderline(-120, 120); int firstY = -238; table.DrawAt(Point(-130, firstY)); table.DrawUnderline(medium); table.Draw("Installed plugins:", bright); table.DrawGap(5); const int MAX_TEXT_WIDTH = 230; const Font &font = FontSet::Get(14); for(const pair<string, string> &plugin : GameData::PluginAboutText()) { pluginZones.emplace_back(table.GetCenterPoint(), table.GetRowSize(), plugin.first); bool isSelected = (plugin.first == selectedPlugin); if(isSelected || plugin.first == hoverPlugin) table.DrawHighlight(back); table.Draw(font.TruncateMiddle(plugin.first, MAX_TEXT_WIDTH), isSelected ? bright : medium); if(isSelected) { const Sprite *sprite = SpriteSet::Get(plugin.first); Point top(15., firstY); if(sprite) { Point center(130., top.Y() + .5 * sprite->Height()); SpriteShader::Draw(sprite, center); top.Y() += sprite->Height() + 10.; } WrappedText wrap(font); wrap.SetWrapWidth(MAX_TEXT_WIDTH); static const string EMPTY = "(No description given.)"; wrap.Wrap(plugin.second.empty() ? EMPTY : plugin.second); wrap.Draw(top, medium); } } }
void PreferencesPanel::DrawControls() { const Color &back = *GameData::Colors().Get("faint"); const Color &dim = *GameData::Colors().Get("dim"); const Color &medium = *GameData::Colors().Get("medium"); const Color &bright = *GameData::Colors().Get("bright"); // Check for conflicts. Color red(.3, 0., 0., .3); Table table; table.AddColumn(-115, Table::LEFT); table.AddColumn(115, Table::RIGHT); table.SetUnderline(-120, 120); int firstY = -248; table.DrawAt(Point(-130, firstY)); static const string CATEGORIES[] = { "Navigation", "Weapons", "Targeting", "Menus", "Fleet" }; const string *category = CATEGORIES; static const Command COMMANDS[] = { Command::NONE, Command::FORWARD, Command::LEFT, Command::RIGHT, Command::BACK, Command::AFTERBURNER, Command::LAND, Command::JUMP, Command::NONE, Command::PRIMARY, Command::SELECT, Command::SECONDARY, Command::CLOAK, Command::NONE, Command::NEAREST, Command::TARGET, Command::HAIL, Command::BOARD, Command::SCAN, Command::NONE, Command::MENU, Command::MAP, Command::INFO, Command::FULLSCREEN, Command::NONE, Command::DEPLOY, Command::FIGHT, Command::GATHER, Command::HOLD, Command::AMMO }; static const Command *BREAK = &COMMANDS[19]; for(const Command &command : COMMANDS) { // The "BREAK" line is where to go to the next column. if(&command == BREAK) table.DrawAt(Point(130, firstY)); if(!command) { table.DrawGap(10); table.DrawUnderline(medium); if(category != end(CATEGORIES)) table.Draw(*category++, bright); else table.Advance(); table.Draw("Key", bright); table.DrawGap(5); } else { int index = zones.size(); // Mark conflicts. bool isConflicted = command.HasConflict(); bool isEditing = (index == editing); if(isConflicted || isEditing) { table.SetHighlight(66, 120); table.DrawHighlight(isEditing ? dim: red); } // Mark the selected row. bool isHovering = (index == hover && !isEditing); if(!isHovering && index == selected) { table.SetHighlight(-120, 64); table.DrawHighlight(back); } // Highlight whichever row the mouse hovers over. table.SetHighlight(-120, 120); if(isHovering) table.DrawHighlight(back); zones.emplace_back(table.GetCenterPoint(), table.GetRowSize(), command); table.Draw(command.Description(), medium); table.Draw(command.KeyName(), isEditing ? bright : medium); } } Table shiftTable; shiftTable.AddColumn(125, Table::RIGHT); shiftTable.SetUnderline(0, 130); shiftTable.DrawAt(Point(-400, 52)); shiftTable.DrawUnderline(medium); shiftTable.Draw("With <shift> key", bright); shiftTable.DrawGap(5); shiftTable.Draw("Select nearest ship", medium); shiftTable.Draw("Select next escort", medium); shiftTable.Draw("Talk to planet", medium); shiftTable.Draw("Board disabled escort", medium); }
void PreferencesPanel::DrawSettings() { const Color &back = *GameData::Colors().Get("faint"); const Color &dim = *GameData::Colors().Get("dim"); const Color &medium = *GameData::Colors().Get("medium"); const Color &bright = *GameData::Colors().Get("bright"); Table table; table.AddColumn(-115, Table::LEFT); table.AddColumn(115, Table::RIGHT); table.SetUnderline(-120, 120); int firstY = -248; table.DrawAt(Point(-130, firstY)); static const string SETTINGS[] = { "Display", ZOOM_FACTOR, VIEW_ZOOM_FACTOR, "Show status overlays", "Highlight player's flagship", "Rotate flagship in HUD", "Show planet labels", "Show mini-map", "", "AI", "Automatic aiming", "Automatic firing", EXPEND_AMMO, TURRET_TRACKING, "", "Performance", "Show CPU / GPU load", "Render motion blur", "Reduce large graphics", "Draw background haze", "Show hyperspace flash", "\n", "Other", "Clickable radar display", "Hide unexplored map regions", REACTIVATE_HELP, "Rehire extra crew when lost", SCROLL_SPEED, "Show escort systems on map", "Warning siren" }; bool isCategory = true; for(const string &setting : SETTINGS) { // Check if this is a category break or column break. if(setting.empty() || setting == "\n") { isCategory = true; if(!setting.empty()) table.DrawAt(Point(130, firstY)); continue; } if(isCategory) { isCategory = false; table.DrawGap(10); table.DrawUnderline(medium); table.Draw(setting, bright); table.Advance(); table.DrawGap(5); continue; } // Record where this setting is displayed, so the user can click on it. prefZones.emplace_back(table.GetCenterPoint(), table.GetRowSize(), setting); // Get the "on / off" text for this setting. bool isOn = Preferences::Has(setting); string text; if(setting == ZOOM_FACTOR) { isOn = true; text = to_string(Screen::Zoom()); } else if(setting == VIEW_ZOOM_FACTOR) { isOn = true; text = to_string(static_cast<int>(100. * Preferences::ViewZoom())); } else if(setting == EXPEND_AMMO) text = Preferences::AmmoUsage(); else if(setting == TURRET_TRACKING) { isOn = true; text = Preferences::Has(FOCUS_PREFERENCE) ? "focused" : "opportunistic"; } else if(setting == REACTIVATE_HELP) { // Check how many help messages have been displayed. const map<string, string> &help = GameData::HelpTemplates(); int shown = 0; for(const auto &it : help) shown += Preferences::Has("help: " + it.first); // Don't count the "basic help" messages in the total. if(shown) text = to_string(shown) + " / " + to_string(help.size() - 2); else { isOn = true; text = "done"; } } else if(setting == SCROLL_SPEED) { isOn = true; text = to_string(Preferences::ScrollSpeed()); } else text = isOn ? "on" : "off"; if(setting == hoverPreference) table.DrawHighlight(back); table.Draw(setting, isOn ? medium : dim); table.Draw(text, isOn ? bright : medium); } }
void ShipInfoPanel::DrawCargo(const Rectangle &bounds) { Color dim = *GameData::Colors().Get("medium"); Color bright = *GameData::Colors().Get("bright"); Color backColor = *GameData::Colors().Get("faint"); const Ship &ship = **shipIt; // Cargo list. const CargoHold &cargo = (player.Cargo().Used() ? player.Cargo() : ship.Cargo()); Table table; table.AddColumn(0, Table::LEFT); table.AddColumn(WIDTH - 20, Table::RIGHT); table.SetUnderline(-5, WIDTH - 15); table.DrawAt(bounds.TopLeft() + Point(10., 8.)); double endY = bounds.Bottom() - 30. * (cargo.Passengers() != 0); bool hasSpace = (table.GetRowBounds().Bottom() < endY); if((cargo.CommoditiesSize() || cargo.HasOutfits() || cargo.MissionCargoSize()) && hasSpace) { table.Draw("Cargo", bright); table.Advance(); hasSpace = (table.GetRowBounds().Bottom() < endY); } if(cargo.CommoditiesSize() && hasSpace) { for(const auto &it : cargo.Commodities()) { if(!it.second) continue; commodityZones.emplace_back(table.GetCenterPoint(), table.GetRowSize(), it.first); if(it.first == selectedCommodity) table.DrawHighlight(backColor); table.Draw(it.first, dim); table.Draw(to_string(it.second), bright); // Truncate the list if there is not enough space. if(table.GetRowBounds().Bottom() >= endY) { hasSpace = false; break; } } table.DrawGap(10.); } if(cargo.HasOutfits() && hasSpace) { for(const auto &it : cargo.Outfits()) { if(!it.second) continue; plunderZones.emplace_back(table.GetCenterPoint(), table.GetRowSize(), it.first); if(it.first == selectedPlunder) table.DrawHighlight(backColor); // For outfits, show how many of them you have and their total mass. bool isSingular = (it.second == 1 || it.first->Get("installable") < 0.); string name = (isSingular ? it.first->Name() : it.first->PluralName()); if(!isSingular) name += " (" + to_string(it.second) + "x)"; table.Draw(name, dim); double mass = it.first->Mass() * it.second; table.Draw(Format::Number(mass), bright); // Truncate the list if there is not enough space. if(table.GetRowBounds().Bottom() >= endY) { hasSpace = false; break; } } table.DrawGap(10.); } if(cargo.HasMissionCargo() && hasSpace) { for(const auto &it : cargo.MissionCargo()) { // Capitalize the name of the cargo. table.Draw(Format::Capitalize(it.first->Cargo()), dim); table.Draw(to_string(it.second), bright); // Truncate the list if there is not enough space. if(table.GetRowBounds().Bottom() >= endY) break; } table.DrawGap(10.); } if(cargo.Passengers() && endY >= bounds.Top()) { table.DrawAt(Point(bounds.Left(), endY) + Point(10., 8.)); table.Draw("passengers:", dim); table.Draw(to_string(cargo.Passengers()), bright); } }