1 //------------------------------------------------------------------------------
2 // emDialog.h
3 //
4 // Copyright (C) 2005-2010,2014-2016 Oliver Hamann.
5 //
6 // Homepage: http://eaglemode.sourceforge.net/
7 //
8 // This program is free software: you can redistribute it and/or modify it under
9 // the terms of the GNU General Public License version 3 as published by the
10 // Free Software Foundation.
11 //
12 // This program is distributed in the hope that it will be useful, but WITHOUT
13 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14 // FOR A PARTICULAR PURPOSE. See the GNU General Public License version 3 for
15 // more details.
16 //
17 // You should have received a copy of the GNU General Public License version 3
18 // along with this program. If not, see <http://www.gnu.org/licenses/>.
19 //------------------------------------------------------------------------------
20 
21 #ifndef emDialog_h
22 #define emDialog_h
23 
24 #ifndef emButton_h
25 #include <emCore/emButton.h>
26 #endif
27 
28 #ifndef emLinearLayout_h
29 #include <emCore/emLinearLayout.h>
30 #endif
31 
32 
33 //==============================================================================
34 //================================== emDialog ==================================
35 //==============================================================================
36 
37 class emDialog : public emWindow {
38 
39 public:
40 
41 	// Class for a dialog window. Such a dialog has a content area and a
42 	// button area. The content area is an emLinearLayout which can be given
43 	// individual child panels. The button area can have buttons like "OK"
44 	// and "Cancel" for finishing the dialog.
45 
46 	emDialog(
47 		emContext & parentContext,
48 		ViewFlags viewFlags=VF_POPUP_ZOOM|VF_ROOT_SAME_TALLNESS,
49 		WindowFlags windowFlags=WF_MODAL,
50 		const emString & wmResName="emDialog"
51 	);
52 		// Like the constructor of emWindow, but see that the default
53 		// argument values are different (it's a modal dialog with
54 		// popup-zoom by default).
55 
56 	virtual ~emDialog();
57 		// Destructor.
58 
59 	void SetRootTitle(const emString & title);
60 		// Set the title for this dialog. More precise, set the title
61 		// for the private root panel of this view. If you create some
62 		// content panel with another title, and if it gets focus, that
63 		// title is shown. The default title is an empty string.
64 
65 	emLinearLayout * GetContentPanel() const;
66 		// This panel makes up the content area of the dialog, not
67 		// including the buttons. For convenience, it is an emLinearLayout
68 		// with default properties, except that the inner border is set
69 		// to emBorder::IBT_CUSTOM_RECT. You may change the properties
70 		// as you wish, and you should give it one or more child panels
71 		// as the content.
72 
73 	void AddPositiveButton(
74 		const emString & caption,
75 		const emString & description=emString(),
76 		const emImage & icon=emImage()
77 	);
78 	void AddNegativeButton(
79 		const emString & caption,
80 		const emString & description=emString(),
81 		const emImage & icon=emImage()
82 	);
83 	void AddCustomButton(
84 		const emString & caption,
85 		const emString & description=emString(),
86 		const emImage & icon=emImage()
87 	);
88 		// Add a button to the button area. These buttons are finishing
89 		// the dialog. For the meaning of "Positive", "Negative" and
90 		// "Custom", please see GetResult().
91 
92 	void AddOKButton();
93 	void AddCancelButton();
94 	void AddOKCancelButtons();
95 		// AddOKButton() is like AddPositiveButton("OK").
96 		// AddCancelButton() is like AddNegativeButton("Cancel").
97 		// AddOKCancelButtons() is like AddOKButton() plus
98 		// AddCancelButton().
99 
100 	emButton * GetButton(int index) const;
101 		// Get a button. The index is: 0 for the first added button, 1
102 		// for the second added button, and so on.
103 
104 	emButton * GetButtonForResult(int result) const;
105 		// Get the first button, whose result is the given result.
106 
107 	emButton * GetOKButton() const;
108 		// Get the first button with positive result.
109 
110 	emButton * GetCancelButton() const;
111 		// Get the first button with negative result.
112 
113 	const emSignal & GetFinishSignal() const;
114 		// Signaled when any of the buttons has been triggered, or by
115 		// pressing the Enter key or the Escape key, or by the window
116 		// close signal. It is okay not to destruct the dialog and to
117 		// wait for another finish signal.
118 
119 	enum {
120 		// Possible results:
121 		POSITIVE=1, // Positive button triggered or Enter key pressed.
122 		NEGATIVE=0, // Negative button triggered or Escape key pressed
123 		            // or window-closing commanded (see GetCloseSignal).
124 		CUSTOM1 =2, // First custom button triggered.
125 		CUSTOM2 =3, // Second custom button triggered.
126 		CUSTOM3 =4  // ...
127 		// Continued (customIndex=result+1-CUSTOM1)
128 	};
129 	int GetResult() const;
130 		// The result should be asked after the finish signal has been
131 		// signaled. Before that, the result is not valid.
132 
133 	bool Finish(int result);
134 		// Finish this dialog with the given result programmatically.
135 		// Returns true on success, or false if the finishing was aborted
136 		// by a call to CheckFinish(result).
137 
138 	void EnableAutoDeletion(bool autoDelete=true);
139 	bool IsAutoDeletionEnabled() const;
140 		// Whether to delete this object automatically a few time slices
141 		// after the dialog has finished.
142 
143 	static void ShowMessage(
144 		emContext & parentContext,
145 		const emString & title,
146 		const emString & message,
147 		const emString & description=emString(),
148 		const emImage & icon=emImage()
149 	);
150 		// This function creates a modal dialog with an emLabel as the
151 		// content, and with an OK button. The dialog deletes itself
152 		// when finished. The argument 'message' is the caption of the
153 		// label.
154 
155 protected:
156 
157 	virtual bool CheckFinish(int result);
158 		// Check whether finishing is allowed with the given result at
159 		// this moment. The default implementation always returns true.
160 
161 	virtual void Finished(int result);
162 		// Like the finish signal. Default implementation does nothing.
163 		// It's allowed to delete (destruct) this dialog herein.
164 
165 private:
166 
167 	bool PrivateCycle();
168 
169 	class DlgButton : public emButton {
170 	public:
171 		DlgButton(
172 			ParentArg parent, const emString & name,
173 			const emString & caption,
174 			const emString & description,
175 			const emImage & icon,
176 			int result
177 		);
178 		int GetResult() const;
179 	protected:
180 		virtual void Clicked();
181 	private:
182 		int Result;
183 	};
184 
185 	class DlgPanel : public emBorder {
186 	public:
187 		DlgPanel(ParentArg parent, const emString & name);
188 		virtual ~DlgPanel();
189 		void SetTitle(const emString & title);
190 		virtual emString GetTitle() const;
191 		emString Title;
192 		emLinearLayout * ContentPanel;
193 		emLinearLayout * ButtonsPanel;
194 	protected:
195 		virtual void Input(
196 			emInputEvent & event, const emInputState & state,
197 			double mx, double my
198 		);
199 		virtual void LayoutChildren();
200 	};
201 
202 	class PrivateEngineClass : public emEngine {
203 	public:
204 		PrivateEngineClass(emDialog & dlg);
205 	protected:
206 		virtual bool Cycle();
207 		emDialog & Dlg;
208 	};
209 	friend class PrivateEngineClass;
210 
211 	PrivateEngineClass PrivateEngine;
212 	emSignal FinishSignal;
213 	int Result;
214 	int ButtonNum,CustomRes;
215 	int FinishState;
216 	bool ADEnabled;
217 };
218 
GetContentPanel()219 inline emLinearLayout * emDialog::GetContentPanel() const
220 {
221 	return ((DlgPanel*)GetRootPanel())->ContentPanel;
222 }
223 
GetOKButton()224 inline emButton * emDialog::GetOKButton() const
225 {
226 	return GetButtonForResult(POSITIVE);
227 }
228 
GetCancelButton()229 inline emButton * emDialog::GetCancelButton() const
230 {
231 	return GetButtonForResult(NEGATIVE);
232 }
233 
GetFinishSignal()234 inline const emSignal & emDialog::GetFinishSignal() const
235 {
236 	return FinishSignal;
237 }
238 
GetResult()239 inline int emDialog::GetResult() const
240 {
241 	return Result;
242 }
243 
IsAutoDeletionEnabled()244 inline bool emDialog::IsAutoDeletionEnabled() const
245 {
246 	return ADEnabled;
247 }
248 
GetResult()249 inline int emDialog::DlgButton::GetResult() const
250 {
251 	return Result;
252 }
253 
254 
255 #endif
256