1 #ifndef _FleetWnd_h_
2 #define _FleetWnd_h_
3 
4 #include <GG/GGFwd.h>
5 #include <GG/ListBox.h>
6 
7 #include "CUIWnd.h"
8 #include "MapWnd.h"
9 
10 class Fleet;
11 class FleetDataPanel;
12 class FleetDetailPanel;
13 class FleetsListBox;
14 class Ship;
15 class System;
16 class UniverseObject;
17 class StatisticIcon;
18 class ScanlineControl;
19 
20 
21 /* the new fleet aggression settings */
22 GG_ENUM(NewFleetAggression,
23     INVALID_FLEET_AGGRESSION = -1,
24     FLEET_AGGRESSIVE,
25     FLEET_PASSIVE
26 )
27 
28 /** Manages the lifetimes of FleetWnds. */
29 class FleetUIManager {
30 public:
31     typedef std::set<std::weak_ptr<FleetWnd>>::const_iterator iterator;
32 
33     //! \name Accessors //@{
34     bool            empty() const;
35     iterator        begin() const;
36     iterator        end() const;
37     FleetWnd*       ActiveFleetWnd() const;
38     std::shared_ptr<FleetWnd> WndForFleetID(int fleet_id) const;
39     std::shared_ptr<FleetWnd> WndForFleetIDs(const std::vector<int>& fleet_ids_) const;
40     int             SelectedShipID() const;     // if a single ship is selected in the active fleetwnd, returns that ship's ID.  Otherwise, returns INVALID_OBJECT_ID
41     std::set<int>   SelectedShipIDs() const;    // returns the ids of all selected ships in the active fleetwnd
42     //@}
43 
44     //! \name Mutators //@{
45     std::shared_ptr<FleetWnd> NewFleetWnd(const std::vector<int>& fleet_ids,
46                                           double allowed_bounding_box_leeway = 0,
47                                           int selected_fleet_id = INVALID_OBJECT_ID,
48                                           GG::Flags<GG::WndFlag> flags = GG::INTERACTIVE | GG::DRAGABLE | GG::ONTOP | CLOSABLE | GG::RESIZABLE);
49 
50     void            CullEmptyWnds();
51     void            SetActiveFleetWnd(std::shared_ptr<FleetWnd> fleet_wnd);
52     bool            CloseAll();
53     void            RefreshAll();
54 
55     /** Enables, or disables if \a enable is false, issuing orders via FleetWnds. */
56     void            EnableOrderIssuing(bool enable = true);
57     //@}
58 
59     /** emitted when the selected FleetWnd changes */
60     mutable boost::signals2::signal<void ()> ActiveFleetWndChangedSignal;
61 
62     /** emitted when the selected fleets in the active FleetWnd change */
63     mutable boost::signals2::signal<void ()> ActiveFleetWndSelectedFleetsChangedSignal;
64 
65     /** emitted when the selected ships in the active FleetWnd change */
66     mutable boost::signals2::signal<void ()> ActiveFleetWndSelectedShipsChangedSignal;
67 
68     /** emitted when a fleet is right-clicked */
69     mutable boost::signals2::signal<void (int)> FleetRightClickedSignal;
70 
71     /** emitted when a ship is right-clicked */
72     mutable boost::signals2::signal<void (int)> ShipRightClickedSignal;
73 
74     static FleetUIManager& GetFleetUIManager();
75 
76 private:
77     FleetUIManager();
78 
79     void            FleetWndClosing(FleetWnd* fleet_wnd);
80     void            FleetWndClicked(std::shared_ptr<FleetWnd> fleet_wnd);                          //!< sets active FleetWnd
81 
82     bool                                    m_order_issuing_enabled;
83 
84     /** All fleet windows.  mutable so expired ptrs can be reset(). */
85     mutable std::set<std::weak_ptr<FleetWnd>,
86                      std::owner_less<std::weak_ptr<FleetWnd>>> m_fleet_wnds;
87     /** Active fleet window.  mutable so expired ptr can be reset(). */
88     mutable std::weak_ptr<FleetWnd>                               m_active_fleet_wnd;
89 
90     std::vector<boost::signals2::connection> m_active_fleet_wnd_signals;
91 };
92 
93 /** This is the top level Fleet UI element.  It shows a list of fleets, a
94     new-fleet drop target, and a detail view of the currently selected fleet
95     (a FleetDetailPanel). */
96 class FleetWnd : public MapWndPopup {
97 public:
98     /** \name Structors */ //@{
99     FleetWnd();
100     FleetWnd(const std::vector<int>& fleet_ids, bool order_issuing_enabled,
101              double allowed_bounding_box_leeway = 0,
102              int selected_fleet_id = INVALID_OBJECT_ID,
103              GG::Flags<GG::WndFlag> flags = GG::INTERACTIVE | GG::DRAGABLE | GG::ONTOP | CLOSABLE | GG::RESIZABLE,
104              const std::string& config_name = "");
105 
106     ~FleetWnd();
107     //@}
108     void CompleteConstruction() override;
109 
110     //! \name Accessors //@{
111     int                     SystemID() const;                   ///< returns ID of system whose fleets are shown in this FleetWnd, which may be INVALID_OBJECT_ID if this FleetWnd isn't set to show fleets of a system
112     int                     EmpireID() const;                   ///< returns ID of empire whose fleets are shown in this FleetWnd, which may be ALL_EMPIRES if this FleetWnd isn't set to show fleets of a particular empire
113     bool                    ContainsFleet(int fleet_id) const;  ///< returns true if fleet with ID \a fleet_id is shown in this FleetWnd
114     /** Return true if this FleetWnd contains all \p fleet_ids. */
115     template <typename Set>
116     bool                    ContainsFleets(const Set& fleet_ids) const;
117     const std::set<int>&    FleetIDs() const;                   ///< returns IDs of all fleets shown in this FleetWnd
118     std::set<int>           SelectedFleetIDs() const;           ///< returns IDs of selected fleets in this FleetWnd
119     std::set<int>           SelectedShipIDs() const;            ///< returns IDs of selected ships in this FleetWnd
120     NewFleetAggression      GetNewFleetAggression() const;      ///< returns this FleetWnd's setting for new fleet aggression (auto, aggressive, or passive)
121 
122     GG::Rect CalculatePosition() const override;
123     //@}
124 
125     //! \name Mutators //@{
126     void PreRender() override;
127 
128     void SizeMove(const GG::Pt& ul, const GG::Pt& lr) override;
129 
130     /** Deselect all fleets. */
131     void DeselectAllFleets();
132     void SelectFleet(int fleet_id);                     ///< deselects any selected fleets, and selects the indicated fleet, bringing it into the fleet detail window
133     void SelectFleets(const std::set<int>& fleet_ids);  ///< deselects any selected fleets, and selects the fleets with the indicated ids
134     void SelectShips(const std::set<int>& ship_ids);    ///< deselected any selected ships, and selects the ships with the indicated ids if they are in the selected fleet.
135 
136     /** Enables, or disables if \a enable is false, issuing orders via this FleetWnd. */
137     void                    EnableOrderIssuing(bool enable = true);
138     //@}
139 
140     mutable boost::signals2::signal<void ()>    SelectedFleetsChangedSignal;
141     mutable boost::signals2::signal<void ()>    SelectedShipsChangedSignal;
142     mutable boost::signals2::signal<void (std::shared_ptr<FleetWnd>)> ClickedSignal;
143     mutable boost::signals2::signal<void (int)> FleetRightClickedSignal;
144     mutable boost::signals2::signal<void (int)> ShipRightClickedSignal;
145 
146 protected:
147     //! \name Mutators //@{
148     void CloseClicked() override;
149     void LClick(const GG::Pt& pt, GG::Flags<GG::ModKey> mod_keys) override;
150     void DoLayout();
151     //@}
152 
153 private:
154     void RequireRefresh();
155     void Refresh();                          ///< regenerates contents
156     void RefreshStateChangedSignals();
157 
158     void AddFleet(int fleet_id);     ///< adds a new fleet row to this FleetWnd's ListBox of FleetRows and updates internal fleets bookkeeping
159 
160     void FleetSelectionChanged(const GG::ListBox::SelectionSet& rows);
161     void FleetRightClicked(GG::ListBox::iterator it, const GG::Pt& pt, const GG::Flags<GG::ModKey>& modkeys);
162     void FleetLeftClicked(GG::ListBox::iterator it, const GG::Pt& pt, const GG::Flags<GG::ModKey>& modkeys);
163     void FleetDoubleClicked(GG::ListBox::iterator it, const GG::Pt& pt, const GG::Flags<GG::ModKey>& modkeys);
164 
165     int         FleetInRow(GG::ListBox::iterator it) const;
166     std::string TitleText() const;
167     void        CreateNewFleetFromDrops(const std::vector<int>& ship_ids);
168 
169     void ShipSelectionChanged(const GG::ListBox::SelectionSet& rows);
170     void UniverseObjectDeleted(std::shared_ptr<const UniverseObject> obj);
171 
172     void SetStatIconValues();          ///< sets values for multi-fleet aggregate stat icons at top of FleetWnd
173 
174     mutable boost::signals2::signal<void (FleetWnd*)> ClosingSignal;
175 
176     boost::signals2::connection              m_system_connection;
177     std::vector<boost::signals2::connection> m_fleet_connections;
178 
179     std::set<int>   m_fleet_ids;                    ///< IDs of fleets shown in this wnd (always.  set when creating wnd, either by being passed in directly, or found by checking indicated system for indicated empire's fleets.  If set directly, never updates.  If set by checking system, updates when the system has a fleet added or removed.
180     int             m_empire_id = ALL_EMPIRES;      ///< ID of empire whose fleets are shown in this wnd.  May be ALL_EMPIRES if this FleetWnd wasn't set to shown a particular empire's fleets.
181     int             m_system_id =INVALID_OBJECT_ID; ///< ID of system whose fleets are shown in this wnd.  May be INVALID_OBJECT_ID if this FleetWnd wasn't set to show a system's fleets.
182 
183     /** The size of box up to which moving fleets are still within the same fleet window.*/
184     GG::Rect        m_bounding_box;
185     bool            m_order_issuing_enabled = false;
186     bool            m_needs_refresh = false;
187 
188     std::shared_ptr<FleetsListBox>      m_fleets_lb;
189     std::shared_ptr<FleetDataPanel>     m_new_fleet_drop_target;
190     std::shared_ptr<FleetDetailPanel>   m_fleet_detail_panel;
191 
192     std::vector<std::pair<MeterType, std::shared_ptr<StatisticIcon>>> m_stat_icons; /// statistic icons and associated meter types for multi-fleet aggregate
193 
194     friend class FleetUIManager;
195 };
196 
197 #endif // _FleetWnd_h_
198