1 /*
2  * CRRCsim - the Charles River Radio Control Club Flight Simulator Project
3  *
4  * Copyright (C) 2004, 2005, 2008 Jan Reucker (original author)
5  * Copyright (C) 2008 Jens Wilhelm Wulf
6  *               2012 Joel Lienard
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License version 2
10  * as published by the Free Software Foundation.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330,
20  * Boston, MA 02111-1307, USA.
21  *
22  */
23 
24 
25 #ifndef CRRC_GUI_DIALOG_H
26 #define CRRC_GUI_DIALOG_H
27 
28 #include <plib/pu.h>
29 #include <vector>
30 
31 enum
32 {
33   CRRC_DIALOG_CANCEL  = 1,
34   CRRC_DIALOG_OK      = 2
35 };
36 
37 // some constants for unified dialog style
38 extern const int DLG_DEF_SPACE;         // space between two widgets
39 extern const int DLG_DEF_BUTTON_WIDTH;  // width of a puButton
40 extern const int DLG_DEF_BUTTON_HEIGHT; // height of a puButton
41 extern const int DLG_CHECK_W;   // width of a puButton (checkbox type)
42 extern const int DLG_CHECK_H;  // height of a puButton (checkbox type)
43 
44 class CRRCDialog;
45 
46 
47 /** \brief The base class for all CRRCsim dialogs.
48  *
49  *  This class provides a very basic dialog which only
50  *  consists of a frame and up to two buttons (OK and/or
51  *  Cancel). The frame is just big enough to contain the
52  *  two buttons and nothing else.
53  *
54  *  The class also manages the callbacks for all currently
55  *  visible dialogs. Basically all instances of CRRCDialog
56  *  and derived classes share only two callbacks. All
57  *  dialogs are registered in a static list, so the callbacks
58  *  can use the data from the list to determine which dialog
59  *  received the event which caused the callback. The
60  *  event is then dispatched by activating the dialog's
61  *  callback directly.
62  *
63  *  This somehow complicated mechanism eliminates the need
64  *  to provide seperate callbacks for each button in all
65  *  derived classes. It also takes care of the fact that
66  *  PUI only knows which button's callback was activated,
67  *  and not which dialog the button belongs to.
68  *
69  *  To do something useful with this class you should
70  *  derive a new dialog class from CRRCDialog. All you
71  *  have to do is the following:
72  *
73  *  -# Create a derived class.
74  *  -# In the derived class' ctor:
75  *    - add widgets as needed
76  *    - call CRRCDialog::close() (inherited from puDialogBox) after
77  *      all widgets have been added
78  *    - determine how many space your widgets need and call
79  *      CRRCDialog::setSize() to adjust the dialog's frame
80  *      (otherwise the widgets will appear outside the frame)
81  *    - set a callback for the dialog (see below)
82  *    - You might also need to care about the dialog's placement
83  *      on screen. By default the dialog is placed horizontally
84  *      centered with its lower edge one third from the screen's
85  *      top. Use centerOnScreen() if you want to automatically
86  *      place the dialog in the middle of the screen.
87  *    - reveal() the dialog
88  *  -# Provide a callback function for the dialog. The callback
89  *     should take care of the data the user entered in the
90  *     dialog. It can determine how the user left the dialog
91  *     by querying the dialog's integer value (a pointer to
92  *     the dialog is provided as the callback's argument). This will
93  *     be set to either CRRC_DIALOG_OK or CRRC_DIALOG_CANCEL.
94  *     However, <b>the callback must take care of the
95  *     dialog's destruction</b> by calling puDeleteObject() on
96  *     the dialog object.
97  */
98 class CRRCDialog : public puDialogBox
99 {
100   public:
101     puColour dlgCol;
102     puColour dlgCol1;
103 
104     CRRCDialog( int width = 0, int height = 0,
105                 int style = CRRC_DIALOG_OK | CRRC_DIALOG_CANCEL);
106     virtual ~CRRCDialog();
107 
108     virtual void setSize(int w, int h);
109     virtual void setPosition(int x, int y);
110     virtual void setOKButtonLegend(const char *text);
111     virtual void setCancelButtonLegend(const char *text);
112 
113     virtual bool hasCancelButton();
114     virtual bool hasOKButton();
115 
116     virtual void lock();
117     virtual void unlock();
118 
119     virtual void centerOnScreen();
120     virtual void hideOthers();
121     virtual void revealAll();
122     virtual void setTransparency(float t);
123 
124     /** \brief Cyclic update function
125      *
126      *  This function will be called periodically for the
127      *  toplevel dialog. The call is performed instead of
128      *  the flight model's idle() call.
129      *  Overload it if your dialog needs periodic updates.
130      */
update()131     virtual void update() {};
132 
133     static CRRCDialog* getToplevel();
134 
135   private:
136     puFrame   *dlgFrame;
137     puButton  *butCancel;
138     puButton  *butOK;
139 
140     void centerButtons();
141     static std::vector<CRRCDialog*> instances;
142 
143     /** \brief Dummy assignment operator
144      *
145      *  I assume that this operator isn't needed. To prevent
146      *  the compiler from generating a non-working assignment
147      *  operator this declaration is needed.
148      */
149     CRRCDialog& operator=(const CRRCDialog&);
150 
151     /** \brief Dummy copy constructor
152      *
153      *  I assume that there's no need for copying dialogs. To prevent
154      *  the compiler from generating a non-working copy
155      *  constructor this declaration is needed.
156      */
157     CRRCDialog(const CRRCDialog&);
158 };
159 
160 
161 #endif
162