diff --git a/src/gui/gui2_element.h b/src/gui/gui2_element.h index bfb364fbb4..b900954c88 100644 --- a/src/gui/gui2_element.h +++ b/src/gui/gui2_element.h @@ -1,5 +1,4 @@ -#ifndef GUI2_ELEMENT_H -#define GUI2_ELEMENT_H +#pragma once #include #include "stringImproved.h" @@ -70,6 +69,7 @@ class GuiElement : public GuiContainer GuiElement* enable(); GuiElement* disable(); bool isEnabled() const; + bool hasFocus() const { return focus; } void moveToFront(); void moveToBack(); @@ -91,5 +91,3 @@ class GuiElement : public GuiContainer protected: State getState() const; }; - -#endif//GUI2_ELEMENT_H diff --git a/src/gui/hotkeyConfig.cpp b/src/gui/hotkeyConfig.cpp index 253cfbf83f..0fe35950cb 100644 --- a/src/gui/hotkeyConfig.cpp +++ b/src/gui/hotkeyConfig.cpp @@ -313,6 +313,14 @@ Keys::Keys() : relay_alert_level_none("RELAY_ALERT_NONE"), relay_alert_level_yellow("RELAY_ALERT_YELLOW"), relay_alert_level_red("RELAY_ALERT_RED"), + relay_open_comms("RELAY_OPEN_COMMS", "M"), + relay_start_hacking("RELAY_START_HACKING", "H"), + relay_link_to_science("RELAY_LINK_TO_SCIENCE", "K"), + relay_toggle_waypoint("RELAY_TOGGLE_WAYPOINT", "W"), + relay_delete_waypoint("RELAY_DELETE_WAYPOINT", "Delete"), + relay_launch_probe("RELAY_LAUNCH_PROBE", "L"), + relay_center_on_ship("RELAY_CENTER_ON_SHIP", "F"), + relay_toggle_ships_log("RELAY_TOGGLE_SHIPS_LOG", "V"), // GM screen gm_delete("GM_DELETE", "Delete"), @@ -498,6 +506,14 @@ void Keys::init() relay_alert_level_none.setLabel(tr("hotkey_menu", "Relay"), tr("hotkey_Relay", "Alert level: Normal")); relay_alert_level_yellow.setLabel(tr("hotkey_menu", "Relay"), tr("hotkey_Relay", "Alert level: Yellow")); relay_alert_level_red.setLabel(tr("hotkey_menu", "Relay"), tr("hotkey_Relay", "Alert level: Red")); + relay_open_comms.setLabel(tr("hotkey_menu", "Relay"), tr("hotkey_Relay", "Open comms with target")); + relay_start_hacking.setLabel(tr("hotkey_menu", "Relay"), tr("hotkey_Relay", "Start hacking target")); + relay_link_to_science.setLabel(tr("hotkey_menu", "Relay"), tr("hotkey_Relay", "Link to Science")); + relay_toggle_waypoint.setLabel(tr("hotkey_menu", "Relay"), tr("hotkey_Relay", "Toggle waypoint placement")); + relay_delete_waypoint.setLabel(tr("hotkey_menu", "Relay"), tr("hotkey_Relay", "Delete selected waypoint")); + relay_launch_probe.setLabel(tr("hotkey_menu", "Relay"), tr("hotkey_Relay", "Toggle probe launch")); + relay_center_on_ship.setLabel(tr("hotkey_menu", "Relay"), tr("hotkey_Relay", "Center view on ship")); + relay_toggle_ships_log.setLabel(tr("hotkey_menu", "Relay"), tr("hotkey_Relay", "Toggle ships log")); // Cinematic view cinematic.init(); diff --git a/src/gui/hotkeyConfig.h b/src/gui/hotkeyConfig.h index 67d2172338..579685711a 100644 --- a/src/gui/hotkeyConfig.h +++ b/src/gui/hotkeyConfig.h @@ -158,6 +158,14 @@ class Keys sp::io::Keybinding relay_alert_level_none; sp::io::Keybinding relay_alert_level_yellow; sp::io::Keybinding relay_alert_level_red; + sp::io::Keybinding relay_open_comms; + sp::io::Keybinding relay_start_hacking; + sp::io::Keybinding relay_link_to_science; + sp::io::Keybinding relay_toggle_waypoint; + sp::io::Keybinding relay_delete_waypoint; + sp::io::Keybinding relay_launch_probe; + sp::io::Keybinding relay_center_on_ship; + sp::io::Keybinding relay_toggle_ships_log; // Cinematic view binds struct CinematicKeys { diff --git a/src/screenComponents/commsOverlay.cpp b/src/screenComponents/commsOverlay.cpp index 146d2a9dc2..e24d424e05 100644 --- a/src/screenComponents/commsOverlay.cpp +++ b/src/screenComponents/commsOverlay.cpp @@ -198,6 +198,11 @@ void GuiCommsOverlay::onUpdate() } } +bool GuiCommsOverlay::isChatEntryFocused() const +{ + return chat_comms_box->isVisible() && chat_comms_message_entry->hasFocus(); +} + void GuiCommsOverlay::clearElements() { // Force all panels to hide, in case hiding the overlay doesn't hide its diff --git a/src/screenComponents/commsOverlay.h b/src/screenComponents/commsOverlay.h index 5eb8706003..90b32781fa 100644 --- a/src/screenComponents/commsOverlay.h +++ b/src/screenComponents/commsOverlay.h @@ -1,5 +1,4 @@ -#ifndef COMMS_OVERLAY_H -#define COMMS_OVERLAY_H +#pragma once #include "gui/gui2_element.h" @@ -44,6 +43,5 @@ class GuiCommsOverlay : public GuiElement virtual void onUpdate() override; void clearElements(); + bool isChatEntryFocused() const; }; - -#endif//COMMS_OVERLAY_H diff --git a/src/screenComponents/shipsLogControl.cpp b/src/screenComponents/shipsLogControl.cpp index f808a76664..60ccf3ec93 100644 --- a/src/screenComponents/shipsLogControl.cpp +++ b/src/screenComponents/shipsLogControl.cpp @@ -75,12 +75,14 @@ void ShipsLog::onDraw(sp::RenderTarget& renderer) } } -bool ShipsLog::onMouseDown(sp::io::Pointer::Button button, glm::vec2 position, sp::io::Pointer::ID id) +void ShipsLog::toggle() { open = !open; - if (open) - setSize(getSize().x, 800); - else - setSize(getSize().x, 50); + setSize(getSize().x, open ? 800.0f : 50.0f); +} + +bool ShipsLog::onMouseDown(sp::io::Pointer::Button button, glm::vec2 position, sp::io::Pointer::ID id) +{ + toggle(); return true; } diff --git a/src/screenComponents/shipsLogControl.h b/src/screenComponents/shipsLogControl.h index 1128a82728..08386da263 100644 --- a/src/screenComponents/shipsLogControl.h +++ b/src/screenComponents/shipsLogControl.h @@ -1,5 +1,4 @@ -#ifndef SHIPS_LOG_CONTROL_H -#define SHIPS_LOG_CONTROL_H +#pragma once #include "gui/gui2_element.h" @@ -11,11 +10,12 @@ class ShipsLog : public GuiElement public: ShipsLog(GuiContainer* owner); + // Toggle panel min/maximized state. + void toggle(); + virtual void onDraw(sp::RenderTarget& target) override; virtual bool onMouseDown(sp::io::Pointer::Button button, glm::vec2 position, sp::io::Pointer::ID id) override; private: bool open; GuiAdvancedScrollText* log_text; -}; - -#endif//SHIPS_LOG_CONTROL_H +}; \ No newline at end of file diff --git a/src/screens/crew4/operationsScreen.cpp b/src/screens/crew4/operationsScreen.cpp index e29ec69d78..c0feb2821d 100644 --- a/src/screens/crew4/operationsScreen.cpp +++ b/src/screens/crew4/operationsScreen.cpp @@ -117,14 +117,14 @@ OperationScreen::OperationScreen(GuiContainer* owner) info_reputation->setTextSize(20)->setSize(200, 40); // Scenario clock display. - info_clock = new GuiKeyValueDisplay(stats, "INFO_CLOCK", 0.55f, tr("Clock") + ":", ""); info_clock->setTextSize(20)->setSize(200, 40); mode = TargetSelection; - new ShipsLog(this); - (new GuiCommsOverlay(this))->setSize(GuiElement::GuiSizeMax, GuiElement::GuiSizeMax); + ships_log = new ShipsLog(this); + comms_overlay = new GuiCommsOverlay(this); + comms_overlay->setSize(GuiElement::GuiSizeMax, GuiElement::GuiSizeMax); } void OperationScreen::onDraw(sp::RenderTarget& target) @@ -132,12 +132,18 @@ void OperationScreen::onDraw(sp::RenderTarget& target) GuiOverlay::onDraw(target); if (!my_spaceship) return; + if (science->radar_view->isVisible()) { - info_reputation->setValue(string(Faction::getInfo(my_spaceship).reputation_points, 0))->show(); - - // Update mission clock - info_clock->setValue(gameGlobalInfo->getMissionTime())->show(); + // Update reputation counter. + info_reputation + ->setValue(string(Faction::getInfo(my_spaceship).reputation_points, 0)) + ->show(); + + // Update mission clock. + info_clock + ->setValue(gameGlobalInfo->getMissionTime()) + ->show(); } else { @@ -145,3 +151,35 @@ void OperationScreen::onDraw(sp::RenderTarget& target) info_clock->hide(); } } + +void OperationScreen::onUpdate() +{ + // Relay keybinds, copied from Relay screen. + // Don't process hotkeys while the chat text entry has keyboard focus. + if (comms_overlay && comms_overlay->isChatEntryFocused()) return; + + // Open comms with the selected target. + if (keys.relay_open_comms.getDown()) + { + auto target = science->targets.get(); + if (target) my_player_info->commandOpenTextComm(target); + } + + // Toggle waypoint placement mode. + if (keys.relay_toggle_waypoint.getDown()) + { + if (mode == TargetSelection) mode = WaypointPlacement; + else if (mode == WaypointPlacement) mode = TargetSelection; + } + + // Delete the selected waypoint. + if (keys.relay_delete_waypoint.getDown()) + { + if (science->targets.getWaypointIndex() >= 0) + my_player_info->commandRemoveWaypoint(science->targets.getWaypointIndex()); + } + + // Toggle ship's log min/maximized state. + if (ships_log && keys.relay_toggle_ships_log.getDown()) + ships_log->toggle(); +} diff --git a/src/screens/crew4/operationsScreen.h b/src/screens/crew4/operationsScreen.h index 55243b217d..7a4b23084e 100644 --- a/src/screens/crew4/operationsScreen.h +++ b/src/screens/crew4/operationsScreen.h @@ -5,8 +5,10 @@ class GuiOverlay; class GuiKeyValueDisplay; class GuiButton; +class GuiCommsOverlay; class GuiToggleButton; class ScienceScreen; +class ShipsLog; class OperationScreen : public GuiOverlay { @@ -29,8 +31,13 @@ class OperationScreen : public GuiOverlay GuiToggleButton* place_waypoint_button; GuiButton* delete_waypoint_button; + GuiCommsOverlay* comms_overlay; + ShipsLog* ships_log; + glm::vec2 mouse_down_position{0, 0}; public: OperationScreen(GuiContainer* owner); + virtual void onDraw(sp::RenderTarget& target) override; + virtual void onUpdate() override; }; diff --git a/src/screens/crew6/relayScreen.cpp b/src/screens/crew6/relayScreen.cpp index d7bd665eac..94d41a6221 100644 --- a/src/screens/crew6/relayScreen.cpp +++ b/src/screens/crew6/relayScreen.cpp @@ -11,10 +11,10 @@ #include "components/radar.h" #include "components/name.h" +#include "screenComponents/commsOverlay.h" #include "screenComponents/radarView.h" #include "screenComponents/radarZoomSlider.h" #include "screenComponents/openCommsButton.h" -#include "screenComponents/commsOverlay.h" #include "screenComponents/shipsLogControl.h" #include "screenComponents/hackingDialog.h" #include "screenComponents/customShipFunctions.h" @@ -39,7 +39,8 @@ static bool canHack(sp::ecs::Entity entity) } RelayScreen::RelayScreen(GuiContainer* owner, bool allow_comms) -: GuiOverlay(owner, "RELAY_SCREEN", GuiTheme::getColor("background")), mode(TargetSelection) +: GuiOverlay(owner, "RELAY_SCREEN", GuiTheme::getColor("background")), mode(TargetSelection), + allow_comms(allow_comms) { targets.setAllowWaypointSelection(); radar = new GuiRadarView(this, "RELAY_RADAR", MAX_ZOOM_DISTANCE, &targets); @@ -134,7 +135,7 @@ RelayScreen::RelayScreen(GuiContainer* owner, bool allow_comms) option_buttons = new GuiElement(this, "BUTTONS"); option_buttons->setPosition(20, 50, sp::Alignment::TopLeft)->setSize(250, GuiElement::GuiSizeMax)->setAttribute("layout", "vertical"); - // Cancel + // Mode cancellation button. cancel_button = new GuiButton(this, "CANCEL_MODE", tr("Cancel"), [this]() { @@ -143,62 +144,84 @@ RelayScreen::RelayScreen(GuiContainer* owner, bool allow_comms) cancel_button->hide(); } ); - cancel_button->setPosition(20, 50)->setSize(250, 50)->hide(); + cancel_button + ->setPosition(20.0f, 50.0f) + ->setSize(250.0f, 50.0f) + ->hide(); // Open comms button. - (new GuiOpenCommsButton(option_buttons, "OPEN_COMMS_BUTTON", allow_comms == true ? tr("Open comms") : tr("Link to comms"), &targets))->setSize(GuiElement::GuiSizeMax, 50.0f); + (new GuiOpenCommsButton(option_buttons, "OPEN_COMMS_BUTTON", allow_comms == true ? tr("Open comms") : tr("Link to comms"), &targets)) + ->setSize(GuiElement::GuiSizeMax, 50.0f); // Hack target - hack_target_button = new GuiButton(option_buttons, "HACK_TARGET", tr("Start hacking"), [this](){ - auto target = targets.get(); - if (canHack(target)) { - hacking_dialog->open(target); + hack_target_button = new GuiButton(option_buttons, "HACK_TARGET", tr("Start hacking"), + [this]() + { + auto target = targets.get(); + if (target && canHack(target)) hacking_dialog->open(target); } - }); - hack_target_button->setSize(GuiElement::GuiSizeMax, 50); + ); + hack_target_button->setSize(GuiElement::GuiSizeMax, 50.0f); // Link probe to science button. - link_to_science_button = new GuiToggleButton(option_buttons, "LINK_TO_SCIENCE", tr("Link to science"), [this](bool value){ - if (value) + link_to_science_button = new GuiToggleButton(option_buttons, "LINK_TO_SCIENCE", tr("Link to science"), + [this](bool value) { - my_player_info->commandSetScienceLink(targets.get()); + if (value) + my_player_info->commandSetScienceLink(targets.get()); + else + my_player_info->commandClearScienceLink(); } - else + ); + link_to_science_button + ->setSize(GuiElement::GuiSizeMax, 50.0f) + ->setVisible(my_spaceship.hasComponent() && my_spaceship.hasComponent() && my_spaceship.hasComponent()); + + // Manage waypoints. + (new GuiButton(option_buttons, "WAYPOINT_PLACE_BUTTON", tr("Place waypoint"), + [this]() { - my_player_info->commandClearScienceLink(); + mode = WaypointPlacement; + option_buttons->hide(); + cancel_button + ->setText(tr("Cancel waypoint")) + ->show(); } - }); - link_to_science_button->setSize(GuiElement::GuiSizeMax, 50)->setVisible(my_spaceship.hasComponent() && my_spaceship.hasComponent() && my_spaceship.hasComponent()); + ))->setSize(GuiElement::GuiSizeMax, 50.0f); - // Manage waypoints. - (new GuiButton(option_buttons, "WAYPOINT_PLACE_BUTTON", tr("Place waypoint"), [this]() { - mode = WaypointPlacement; - option_buttons->hide(); - cancel_button->setText(tr("Cancel waypoint"))->show(); - }))->setSize(GuiElement::GuiSizeMax, 50); - - delete_waypoint_button = new GuiButton(option_buttons, "WAYPOINT_DELETE_BUTTON", tr("Delete waypoint"), [this]() { - if (my_spaceship && targets.getWaypointIndex() >= 0) + delete_waypoint_button = new GuiButton(option_buttons, "WAYPOINT_DELETE_BUTTON", tr("Delete waypoint"), + [this]() { - my_player_info->commandRemoveWaypoint(targets.getWaypointIndex()); + if (my_spaceship && targets.getWaypointIndex() >= 0) + my_player_info->commandRemoveWaypoint(targets.getWaypointIndex()); } - }); - delete_waypoint_button->setSize(GuiElement::GuiSizeMax, 50); + ); + delete_waypoint_button->setSize(GuiElement::GuiSizeMax, 50.0f); // Launch probe button. - launch_probe_button = new GuiButton(option_buttons, "LAUNCH_PROBE_BUTTON", tr("Launch probe"), [this]() { - mode = LaunchProbe; - option_buttons->hide(); - cancel_button->setText(tr("Cancel probe"))->show(); - }); - launch_probe_button->setSize(GuiElement::GuiSizeMax, 50)->setVisible(my_spaceship.hasComponent()); + launch_probe_button = new GuiButton(option_buttons, "LAUNCH_PROBE_BUTTON", tr("Launch probe"), + [this]() + { + mode = LaunchProbe; + option_buttons->hide(); + cancel_button + ->setText(tr("Cancel probe")) + ->show(); + } + ); + launch_probe_button + ->setSize(GuiElement::GuiSizeMax, 50.0f) + ->setVisible(my_spaceship.hasComponent()); // Center on ship - center_button = new GuiToggleButton(option_buttons, "CENTER_ON_SHIP", tr("Center on ship"), [this](bool value) { - if(!my_spaceship) return; - radar->setAutoCentering(value); - }); - center_button->setSize(GuiElement::GuiSizeMax, 50); + center_button = new GuiToggleButton(option_buttons, "CENTER_ON_SHIP", tr("Center on ship"), + [this](bool value) + { + if (!my_spaceship) return; + radar->setAutoCentering(value); + } + ); + center_button->setSize(GuiElement::GuiSizeMax, 50.0f); // Reputation display. info_reputation = new GuiKeyValueDisplay(option_buttons, "INFO_REPUTATION", 0.4f, tr("Reputation") + ":", ""); @@ -217,8 +240,9 @@ RelayScreen::RelayScreen(GuiContainer* owner, bool allow_comms) if (allow_comms) { - new ShipsLog(this); - (new GuiCommsOverlay(this))->setSize(GuiElement::GuiSizeMax, GuiElement::GuiSizeMax); + ships_log = new ShipsLog(this); + comms_overlay = new GuiCommsOverlay(this); + comms_overlay->setSize(GuiElement::GuiSizeMax, GuiElement::GuiSizeMax); } } @@ -261,7 +285,6 @@ void RelayScreen::onDraw(sp::RenderTarget& renderer) // If the target is within the short-range radar range/5U of the // object, consider it near a friendly object. - if (glm::length2(transform.getPosition() - target_transform->getPosition()) < r * r) { near_friendly = true; @@ -330,7 +353,9 @@ void RelayScreen::onDraw(sp::RenderTarget& renderer) launch_probe_button->setEnable(spl ? spl->stock > 0 : false); link_to_science_button->setVisible(my_spaceship.hasComponent() && spl && my_spaceship.hasComponent()); hack_target_button->setVisible(my_spaceship.hasComponent()); + center_button->setValue(radar->getAutoCentering()); + // Update reputation counter. info_reputation->setValue(string(Faction::getInfo(my_spaceship).reputation_points, 0)); // Update mission clock @@ -342,3 +367,102 @@ void RelayScreen::onDraw(sp::RenderTarget& renderer) delete_waypoint_button->setEnable(targets.getWaypointIndex() >= 0); } + +void RelayScreen::onUpdate() +{ + if (!my_spaceship || !isVisible()) return; + + // Don't process hotkeys while the chat text entry has keyboard focus. + if (comms_overlay && comms_overlay->isChatEntryFocused()) return; + + // Open comms with the selected target. + if (allow_comms && keys.relay_open_comms.getDown()) + { + auto target = targets.get(); + if (target) my_player_info->commandOpenTextComm(target); + } + + // Start hacking the selected target. + if (keys.relay_start_hacking.getDown()) + { + auto target = targets.get(); + if (target && canHack(target)) hacking_dialog->open(target); + } + + // Toggle science link on the selected probe. + if (keys.relay_link_to_science.getDown()) + { + auto target = targets.get(); + if (target) + { + if (auto radar_link = my_spaceship.getComponent()) + { + auto linked_entity = radar_link->linked_entity; + if (linked_entity == target) + my_player_info->commandClearScienceLink(); + else if (auto target_arl = target.getComponent()) + { + if (target_arl->owner == my_spaceship) + my_player_info->commandSetScienceLink(target); + } + } + } + } + + // Toggle waypoint placement mode. + if (keys.relay_toggle_waypoint.getDown()) + { + if (mode == TargetSelection) + { + mode = WaypointPlacement; + option_buttons->hide(); + cancel_button + ->setText(tr("Cancel waypoint")) + ->show(); + } + else if (mode == WaypointPlacement) + { + mode = TargetSelection; + option_buttons->show(); + cancel_button->hide(); + } + } + + // Delete the selected waypoint. + if (keys.relay_delete_waypoint.getDown()) + { + if (targets.getWaypointIndex() >= 0) + my_player_info->commandRemoveWaypoint(targets.getWaypointIndex()); + } + + // Toggle probe launch mode. + if (keys.relay_launch_probe.getDown()) + { + if (mode == LaunchProbe) + { + mode = TargetSelection; + option_buttons->show(); + cancel_button->hide(); + } + else if (mode == TargetSelection) + { + auto spl = my_spaceship.getComponent(); + if (spl && spl->stock > 0) + { + mode = LaunchProbe; + option_buttons->hide(); + cancel_button + ->setText(tr("Cancel probe")) + ->show(); + } + } + } + + // Toggle view centered on ship. + if (keys.relay_center_on_ship.getDown()) + radar->setAutoCentering(!radar->getAutoCentering()); + + // Toggle ship's log min/maximized state. + if (ships_log && keys.relay_toggle_ships_log.getDown()) + ships_log->toggle(); +} diff --git a/src/screens/crew6/relayScreen.h b/src/screens/crew6/relayScreen.h index 60c86f1e1b..6c8a8ce37d 100644 --- a/src/screens/crew6/relayScreen.h +++ b/src/screens/crew6/relayScreen.h @@ -4,6 +4,7 @@ #include "gui/gui2_overlay.h" class GuiButton; +class GuiCommsOverlay; class GuiHackingDialog; class GuiKeyValueDisplay; class GuiLabel; @@ -11,6 +12,7 @@ class GuiRadarView; class GuiRadarZoomSlider; class GuiSlider; class GuiToggleButton; +class ShipsLog; class RelayScreen : public GuiOverlay { @@ -47,10 +49,14 @@ class RelayScreen : public GuiOverlay GuiLabel* zoom_label; GuiHackingDialog* hacking_dialog; + GuiCommsOverlay* comms_overlay = nullptr; + ShipsLog* ships_log = nullptr; + bool allow_comms = false; glm::vec2 mouse_down_position{}; public: RelayScreen(GuiContainer* owner, bool allow_comms); virtual void onDraw(sp::RenderTarget& target) override; + virtual void onUpdate() override; };