1 #ifndef _CUIWnd_h_
2 #define _CUIWnd_h_
3 
4 #include <GG/GGFwd.h>
5 #include <GG/Button.h>
6 #include <GG/Wnd.h>
7 #include <GG/WndEvent.h>
8 #include <GG/GLClientAndServerBuffer.h>
9 #include <unordered_set>
10 
11 
12 /** a simple minimize/restore button that toggles its appearance between the styles for minimize and restore*/
13 class CUI_MinRestoreButton : public GG::Button {
14 public:
15    /** the two modes of operation of this class of button: as a minimize button or as a restore button */
16    enum class Mode {
17        MINIMIZE,
18        RESTORE
19    };
20 
21    CUI_MinRestoreButton();
22 
GetMode()23    Mode GetMode() const {return m_mode;} ///< returns the current mode of this button (is it a minimize button or a restore button?)
24 
25    void Render() override;
26 
27    void Toggle(); ///< toggles modes between MIN_BUTTON and RESTORE_BUTTON
28 
29 private:
30    Mode m_mode;
31 };
32 
33 /** a basic Pin-shaped pin button. */
34 class CUI_PinButton : public GG::Button {
35 public:
36     CUI_PinButton();
37 
38     void Toggle(bool pinned); // Switches icon from Pin to Pinned and back
39 };
40 
41 // Aditional window creation flags
42 extern GG::WndFlag MINIMIZABLE;    ///< allows the window to be minimized
43 extern GG::WndFlag CLOSABLE;       ///< allows the window to be closed
44 extern GG::WndFlag PINABLE;        ///< allows the window to be pinned
45 
46 
47 //! This class is a superclass of all interface windows in GG.  It takes care of
48 /** the drawing and handling of common window interfaces like the close button, minimize
49     button, and resize handle, if applicable.<br>
50 
51     CUIWnd's contain built in close buttons.  They also have optional
52     minimize buttons.  Resizable windows will have a different look from non-resizable windows.
53 
54     All windows contain a close button.  Pressing this button will un-register the window
55     from the Zlist and de-allocate the memory associated with it.  Thus any pointers
56     referencing the window become invalid if the window is closed.
57 
58     The minimize button functionality is available as
59     a window creation flag: CUIWnd::MINIMIZE.  You can bitwise-OR it together
60     with regular GG::Wnd creation flags.
61 
62     When  the GG::Wnd::RESIZABLE flag is specified, the window will receive the
63     resizable graphic style.
64 
65     There are several things to keep in mind
66     when utilizing these classes.<br>
67 
68     - Pass the title of the window as the first argument of the constructor.<br>
69     - CUIWnd's do their own rendering.  Do not override the render function
70       unless you have specific needs.  If you do, make sure you call CUIWnd::Render() before
71       adding your own drawing. <br>
72     - Three functions are user-overridable so that new events may be responded to.  OnClose()
73       is called before the window's memory is deallocated after the user clicks the close button.
74       OnMinimize() is called before the window becomes minimized after clicking the Minimize button.
75       OnResize() is called as part of a response to the resize signal emitted via GG::Wnd.  Users
76       are advised to use this function instead of making a slot connection with boost::signals to respond
77       to the resize signal.
78 */
79 class CUIWnd : public GG::Wnd {
80 public:
81     //! \name Structors //@{
82     /** Constructs the window to be a CUI window. Specifying \a config_name
83       * causes the window to save its position and other properties to the
84       * OptionsDB under that name, if no other windows are currently using that
85       * name. */
86     CUIWnd(const std::string& wnd_name, GG::X x, GG::Y y, GG::X w, GG::Y h,
87            GG::Flags<GG::WndFlag> flags = GG::INTERACTIVE,
88            const std::string& config_name = "", bool visible = true);
89 
90     /** Constructs a CUI window without specifying the initial (default)
91       * position, either call InitSizeMove() if the window is positioned by
92       * something else or override CalculatePosition() then call
93       * ResetDefaultPosition() for windows that position themselves. */
94     CUIWnd(const std::string& wnd_name, GG::Flags<GG::WndFlag> flags = GG::INTERACTIVE,
95            const std::string& config_name = "", bool visible = true);
96 
97     void CompleteConstruction() override;
98     /** Virtual destructor. */
99     virtual ~CUIWnd();
100     //@}
101 
102     //! \name Accessors //@{
Minimized()103     bool    Minimized() const {return m_minimized;} //!< returns true if window is minimized
104     GG::Pt  ClientUpperLeft() const override;
105     GG::Pt  ClientLowerRight() const override;
106     bool    InWindow(const GG::Pt& pt) const override;
107     GG::X   LeftBorder() const;                 //!< the distance on the left side between the outer edge of the window and the inner border
108     GG::Y   TopBorder() const;                  //!< the distance at the top between the outer edge of the window and the inner border
109     GG::X   RightBorder() const;                //!< the distance on the right side between the outer edge of the window and the inner border
110     GG::Y   BottomBorder() const;               //!< the distance at the bottom between the outer edge of the window and the inner border
111     //@}
112 
113     //! \name Mutators //@{
114     void SizeMove(const GG::Pt& ul, const GG::Pt& lr) override;
115     void Render() override;
116     void LButtonDown(const GG::Pt& pt, GG::Flags<GG::ModKey> mod_keys) override;
117     void LDrag(const GG::Pt& pt, const GG::Pt& move, GG::Flags<GG::ModKey> mod_keys) override;
118     void LButtonUp(const GG::Pt& pt, GG::Flags<GG::ModKey> mod_keys) override;
119 
LClick(const GG::Pt & pt,GG::Flags<GG::ModKey> mod_keys)120     void LClick(const GG::Pt& pt, GG::Flags<GG::ModKey> mod_keys) override
121     { return LButtonUp(pt, mod_keys); }
122 
123     void MouseEnter(const GG::Pt& pt, GG::Flags<GG::ModKey> mod_keys) override;
124     void MouseHere(const GG::Pt& pt, GG::Flags<GG::ModKey> mod_keys) override;
125     void MouseLeave() override;
126     void Hide() override;
127     void Show() override;
128 
Flash()129     void Flash() { m_flashing = true; };
StopFlash()130     void StopFlash() { m_flashing = false; };
SetFlashDuration(int ms)131     void SetFlashDuration(int ms) { m_flash_duration = ms; }
132 
ToggleMinimized()133     void ToggleMinimized() { MinimizeClicked(); }
Close()134     void Close()           { CloseClicked(); }
135     void ValidatePosition();                                 //!< calls SizeMove() to trigger position-checking and position the window entirely within the parent window/app window
136     void InitSizeMove(const GG::Pt& ul, const GG::Pt& lr);   //!< sets default positions and if default positions were set beforehand, calls SizeMove()
137     //@}
138 
139     //! \name Mutators //@{
140     virtual void    CloseClicked();                     //!< called when window is closed via the close button
141     virtual void    PinClicked();                       //!< called when window is pinned or unpinned via the pin button
142     //@}
143 
144     //! \name Statics //@{
145     static void     InvalidateUnusedOptions();          //!< removes unregistered and registered-but-unused window options from the OptionsDB so that new windows fall back to their default properties.
146 
147     //@}
148 
149 protected:
150     //! \name Accessors //@{
151     virtual GG::Pt          MinimizedSize() const;              //!< the size of a minimized CUIWnd
152     int                     InnerBorderAngleOffset() const;     //!< the distance from where the lower right corner of the inner border should be to where the angled portion of the inner border meets the right and bottom lines of the border
153     bool                    InResizeTab(const GG::Pt& pt) const;//!< returns true iff the specified \a pt is in the region where dragging will resize this Wnd
154     void                    SaveOptions() const;                //!< saves options for this window to the OptionsDB if config_name was specified in the constructor
155 
156     virtual GG::Rect        CalculatePosition() const;          //!< override this if a class determines its own position/size and return the calculated values, called by ResetDefaultPosition()
157     //@}
158 
159     //! \name Statics //@{
160     static const std::string AddWindowOptions(const std::string& config_name,
161                                               int left, int top, int width, int height,
162                                               bool visible, bool pinned, bool minimized);   //!< Adds OptionsDB entries for a window under a given name along with default values.
163 
164     static const std::string AddWindowOptions(const std::string& config_name,
165                                               GG::X left, GG::Y top, GG::X width, GG::Y height,
166                                               bool visible, bool pinned, bool minimized);   //!< overload that accepts GG::X and GG::Y instead of ints
167 
168     static void              InvalidateWindowOptions(const std::string& config_name);       //!< removes options containing \a config_name, logs an error instead if "ui."+config_name+".initialized" exists (i.e. if a window is currently using that name)
169     //@}
170 
171     //! \name Mutators //@{
172     virtual void    MinimizeClicked();              //!< called when window is minimized or restored via the minimize/restore button
173     virtual void    InitButtons();                  //!< called to create the buttons, withtout positioning them
174     virtual void    PositionButtons();              //!< called to position the buttons
175 
176     virtual void    InitBuffers();
177     void            LoadOptions();                  //!< loads options for this window from the OptionsDB
178     void            Init();                         //!< performs initialization common to all CUIWnd constructors
179     void            ResetDefaultPosition();         //!< called via signal from the ClientUI, passes the value from CalculatePosition() to InitSizeMove()
180 
181     void SetParent(const std::shared_ptr<GG::Wnd>& wnd) override;
182     /** Flags options currently at their default values for later use in SaveDefaultedOptions */
183     void            SetDefaultedOptions();
184     /** Sets the default value any options previously determined from calls to SetDefaultedOptions to their current value */
185     void            SaveDefaultedOptions();
186     //@}
187 
188     bool                    m_resizable = false;    //!< true if the window is able to be resized
189     bool                    m_closable = false;     //!< true if the window is able to be closed with a button press
190     bool                    m_minimizable = false;  //!< true if the window is able to be minimized
191     bool                    m_minimized = false;    //!< true if the window is currently minimized
192     bool                    m_pinable = false;      //!< true if the window is able to be pinned
193     bool                    m_pinned = false;       //!< true if the window is currently pinned
194     bool                    m_flashing = false;     //!< true if the window is currently flashing
195 
196     int                     m_flash_duration = 1000;//!< time in milliseconds to switch between bright and dark
197 
198     GG::Pt                  m_drag_offset;          //!< offset from the lower-right corner of the point being used to drag-resize
199     GG::Pt                  m_original_size;        //!< keeps track of the size of the window before resizing
200 
201     bool                    m_mouse_in_resize_tab = false;
202 
203     bool                    m_config_save = true;   //!< true if SaveOptions() is currently allowed to write to the OptionsDB
204     const std::string       m_config_name;          //!< the name that this window will use to save its properties to the OptionsDB, the default empty string means "do not save"
205 
206     std::shared_ptr<GG::Button>             m_close_button;     //!< the close button
207     std::shared_ptr<CUI_MinRestoreButton>   m_minimize_button;  //!< the minimize/restore button
208     std::shared_ptr<CUI_PinButton>          m_pin_button;       //!< the pin button
209 
210     std::unordered_set<std::string> m_defaulted_options;
211 
212     GG::GL2DVertexBuffer                                m_vertex_buffer;
213     std::vector<std::pair<std::size_t, std::size_t>>    m_buffer_indices;
214 
215     static const GG::Y      BUTTON_TOP_OFFSET;
216     static const GG::X      BUTTON_RIGHT_OFFSET;
217     static const GG::X      MINIMIZED_WND_WIDTH;
218     static const GG::X      BORDER_LEFT;
219     static const GG::X      BORDER_RIGHT;
220     static const GG::Y      BORDER_BOTTOM;
221     static const int        OUTER_EDGE_ANGLE_OFFSET;
222     static const int        INNER_BORDER_ANGLE_OFFSET;
223     static const int        TITLE_OFFSET;
224     static const int        RESIZE_HASHMARK1_OFFSET;
225     static const int        RESIZE_HASHMARK2_OFFSET;
226 };
227 
228 
229 // This didn't seem big enough to warrant its own file, so this seemed like a good enough place for it....
230 /** provides a convenient modal wnd for getting text user input. */
231 class CUIEditWnd : public CUIWnd {
232 public:
233     CUIEditWnd(GG::X w, const std::string& prompt_text, const std::string& edit_text, GG::Flags<GG::WndFlag> flags = GG::MODAL);
234     void CompleteConstruction() override;
235     void ModalInit() override;
236     void KeyPress(GG::Key key, std::uint32_t key_code_point, GG::Flags<GG::ModKey> mod_keys) override;
237 
238     const std::string& Result() const;
239 
240 private:
241     void OkClicked();
242 
243     std::string m_result;
244 
245     std::shared_ptr<GG::Edit>   m_edit;
246     std::shared_ptr<GG::Button> m_ok_bn;
247     std::shared_ptr<GG::Button> m_cancel_bn;
248 
249     static const GG::X BUTTON_WIDTH;
250     static const int CONTROL_MARGIN;
251 };
252 
253 #endif // _CUIWnd_h_
254