1 //------------------------------------------------------------------------------
2 // emWindow.h
3 //
4 // Copyright (C) 2005-2010,2016-2018 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 emWindow_h
22 #define emWindow_h
23 
24 #ifndef emScreen_h
25 #include <emCore/emScreen.h>
26 #endif
27 
28 #ifndef emView_h
29 #include <emCore/emView.h>
30 #endif
31 
32 class emWindowPort;
33 
34 
35 //==============================================================================
36 //================================== emWindow ==================================
37 //==============================================================================
38 
39 class emWindow : public emView {
40 
41 public:
42 
43 	// An emWindow is an emView which is shown as a window on a screen. See
44 	// also class emScreen. Such a screen interface has to be installed in a
45 	// context before windows can be constructed. This should be done at
46 	// program start, maybe with the help of an emGUIFramework.
47 
48 	typedef int WindowFlags;
49 		// Data type for the feature flags of a window. Possible flags
50 		// are:
51 	enum {
52 		WF_MODAL       = (1<<0),
53 			// Ancestor windows of same screen cannot get input
54 			// events or close signal. This flag has no effect if
55 			// the are no such ancestors.
56 		WF_UNDECORATED = (1<<1),
57 			// The window has no border and not title bar.
58 		WF_POPUP       = (1<<2),
59 			// Like WF_UNDECORATED, but the close signal is
60 			// generated as soon as the focus is lost.
61 		WF_MAXIMIZED   = (1<<3),
62 			// The window covers the whole work area of the desktop.
63 			// This flag may have no effect when combined with
64 			// WF_UNDECORATED, WF_POPUP or WF_FULLSCREEN.
65 		WF_FULLSCREEN  = (1<<4),
66 			// The window covers the whole screen. This flag may
67 			// have no effect when combined with WF_UNDECORATED or
68 			// WF_POPUP.
69 		WF_AUTO_DELETE = (1<<5)
70 			// The window deletes itself automatically three time
71 			// slices after the close signal is signaled.
72 	};
73 
74 	emWindow(
75 		emContext & parentContext,
76 		ViewFlags viewFlags=0,
77 		WindowFlags windowFlags=0,
78 		const emString & wmResName="emWindow"
79 	);
80 		// Construct a window. If the parent context or a higher
81 		// ancestor context is a window (without another emScreen in
82 		// between), this new window will be a slave of that ancestor
83 		// window ("Transient Window" in X11 speaking, "Owned Window" in
84 		// Windows speaking). The new window is not shown before the end
85 		// of the current time slice (by typical emWindowPort
86 		// derivatives). This gives a chance to prepare things like the
87 		// size and position of the window without any flicker on the
88 		// screen. If the position or size is not set before the window
89 		// is shown, a default is invented at the moment of showing the
90 		// window (the default depends on the emWindowPort derivative,
91 		// which may even forward the job to the window manager).
92 		// Arguments:
93 		//   parentContext - Parent context for this new context.
94 		//   viewFlags     - Initial view features.
95 		//   windowFlags   - Initial window features.
96 		//   wmResName     - A resource name for the window. This is
97 		//                   reported to the window manager.
98 
99 	virtual ~emWindow();
100 		// Destructor.
101 
102 	void LinkCrossPtr(emCrossPtrPrivate & crossPtr);
103 		// This means emCrossPtr<emWindow> is possible.
104 
105 	emScreen & GetScreen() const;
106 		// Get the screen where this window is shown.
107 
108 	WindowFlags GetWindowFlags() const;
109 	void SetWindowFlags(WindowFlags windowFlags);
110 		// Get or set the features of this window.
111 
112 	const emSignal & GetWindowFlagsSignal() const;
113 		// This signal is signaled when the features of this window have
114 		// changed.
115 
116 	const emString & GetWMResName() const;
117 		// Get the resource name of this window.
118 
119 	emWindowPort & GetWindowPort() const;
120 		// Get the window port of this window.
121 
122 	const emSignal & GetCloseSignal() const;
123 		// Get the close signal. It is signaled when the window should
124 		// be deleted.
125 
126 	void SignalClosing();
127 		// Signal the close signal.
128 
129 	void SetViewPos(double x, double y);
130 	void SetViewSize(double w, double h);
131 	void SetViewPosSize(double x, double y, double w, double h);
132 		// Set position and size of this window by the coordinates of
133 		// the view port. This sets the coordinates you can get with
134 		// GetHomeX, GetHomeY, GetHomeWidth and GetHomeHeight from the
135 		// base class. On X11, the position may not be exact.
136 
137 	void SetWinPos(double x, double y);
138 	void SetWinSize(double w, double h);
139 	void SetWinPosSize(double x, double y, double w, double h);
140 		// Set position and size of this window by the coordinates of
141 		// the whole window rectangle including the borders. On X11, the
142 		// size may not be exact.
143 
144 	void SetWinPosViewSize(double x, double y, double w, double h);
145 		// Like SetWinPos and SetViewSize.
146 
147 	bool SetWinPosViewSize(const char * geometry);
148 		// Like SetWinPosViewSize, but parse a typical X11 geometry
149 		// option string (e.g. "800x600+100-100"). As expected, the
150 		// position or size is not set if it is not specified (e.g.
151 		// "320x200" sets the size only). On parse error, false is
152 		// returned.
153 
154 	void GetBorderSizes(double * pL, double * pT, double * pR,
155 	                    double * pB) const;
156 		// Get the best known size (thickness) of the left, top, right
157 		// and bottom edges of the window border.
158 
159 	int GetMonitorIndex() const;
160 		// Get the index of the display monitor on which this window is.
161 
162 	const emImage & GetWindowIcon() const;
163 	void SetWindowIcon(const emImage & windowIcon);
164 		// Get or set the icon to be shown for this window. The default
165 		// is to inherit the icon from an ancestor window at
166 		// construction. But if there is no ancestor window, the default
167 		// is an empty image which means to have no specific icon.
168 
169 	void Raise();
170 		// Bring this window to the top of the stacking order. The
171 		// window is even restored from any iconified state.
172 
173 	void InhibitScreensaver();
174 	void AllowScreensaver();
175 		// Inhibit or re-allow the screensaver. This should implement an
176 		// internal counter for calls to InhibitScreensaver() which have
177 		// not yet been taken back by calls to AllowScreensaver().
178 		// Inhibiting only works while the window is shown quite large
179 		// and not iconified.
180 
181 protected:
182 
183 	virtual void InvalidateTitle();
184 		// The title of the view is taken for the title of the window.
185 		// This method has been overloaded just to update the window
186 		// title.
187 
188 private:
189 
190 	friend class emWindowPort;
191 
192 	class AutoDeleteEngineClass : public emEngine {
193 	public:
194 		AutoDeleteEngineClass(emWindow * window);
195 	protected:
196 		virtual bool Cycle();
197 	private:
198 		emWindow * Window;
199 		int CountDown;
200 	};
201 
202 	emRef<emScreen> Screen;
203 	emCrossPtrList CrossPtrList;
204 	WindowFlags WFlags;
205 	emString WMResName;
206 	emImage WindowIcon;
207 	emWindowPort * WindowPort;
208 	emSignal WindowFlagsSignal;
209 	emSignal CloseSignal;
210 	AutoDeleteEngineClass AutoDeleteEngine;
211 };
212 
213 
214 //==============================================================================
215 //================================ emWindowPort ================================
216 //==============================================================================
217 
218 class emWindowPort : public emViewPort {
219 
220 public:
221 
222 	// Abstract base class for the connection between an emWindow and the
223 	// operating system or the hardware or whatever. When an emWindow is
224 	// constructed, its constructor creates an emWindowPort by calling
225 	// CreateWindowPort on the emScreen.
226 
227 	emWindowPort(emWindow & window);
228 		// Only to be called through overloaded versions of
229 		// emScreen::CreateWindowPort.
230 
231 	virtual ~emWindowPort();
232 
233 	emWindow & GetWindow() const;
234 
235 protected:
236 
237 	emWindow::WindowFlags GetWindowFlags() const;
238 
239 	const emString & GetWMResName() const;
240 
241 	emString GetWindowTitle() const;
242 
243 	const emImage & GetWindowIcon() const;
244 
245 	virtual void WindowFlagsChanged() = 0;
246 
247 	enum PosSizeArgSpec {
248 		PSAS_IGNORE,
249 		PSAS_VIEW,
250 		PSAS_WINDOW
251 	};
252 	virtual void SetPosSize(
253 		double x, double y, PosSizeArgSpec posSpec,
254 		double w, double h, PosSizeArgSpec sizeSpec
255 	) = 0;
256 		// Should call GetWindow().SetViewGeometry(...) immediately with
257 		// appropriate values.
258 
259 	virtual void GetBorderSizes(
260 		double * pL, double * pT, double * pR, double * pB
261 	) const = 0;
262 
263 	virtual void Raise() = 0;
264 
265 	virtual void InhibitScreensaver() = 0;
266 	virtual void AllowScreensaver() = 0;
267 
268 	virtual void InvalidateTitle() = 0;
269 
270 	virtual void InvalidateIcon() = 0;
271 
272 	void SignalWindowClosing();
273 
274 private:
275 	friend class emWindow;
276 	emWindow & Window;
277 };
278 
279 
280 //==============================================================================
281 //============================== Implementations ===============================
282 //==============================================================================
283 
284 //---------------------------------- emWindow ----------------------------------
285 
LinkCrossPtr(emCrossPtrPrivate & crossPtr)286 inline void emWindow::LinkCrossPtr(emCrossPtrPrivate & crossPtr)
287 {
288 	CrossPtrList.LinkCrossPtr(crossPtr);
289 }
290 
GetScreen()291 inline emScreen & emWindow::GetScreen() const
292 {
293 	return *(Screen.Get());
294 }
295 
GetWindowFlags()296 inline emWindow::WindowFlags emWindow::GetWindowFlags() const
297 {
298 	return WFlags;
299 }
300 
GetWMResName()301 inline const emString & emWindow::GetWMResName() const
302 {
303 	return WMResName;
304 }
305 
GetWindowPort()306 inline emWindowPort & emWindow::GetWindowPort() const
307 {
308 	return *WindowPort;
309 }
310 
GetCloseSignal()311 inline const emSignal & emWindow::GetCloseSignal() const
312 {
313 	return CloseSignal;
314 }
315 
SignalClosing()316 inline void emWindow::SignalClosing()
317 {
318 	Signal(CloseSignal);
319 }
320 
SetViewPos(double x,double y)321 inline void emWindow::SetViewPos(double x, double y)
322 {
323 	WindowPort->SetPosSize(
324 		x,y,emWindowPort::PSAS_VIEW,
325 		0,0,emWindowPort::PSAS_IGNORE
326 	);
327 }
328 
SetViewSize(double w,double h)329 inline void emWindow::SetViewSize(double w, double h)
330 {
331 	WindowPort->SetPosSize(
332 		0,0,emWindowPort::PSAS_IGNORE,
333 		w,h,emWindowPort::PSAS_VIEW
334 	);
335 }
336 
SetViewPosSize(double x,double y,double w,double h)337 inline void emWindow::SetViewPosSize(double x, double y, double w, double h)
338 {
339 	WindowPort->SetPosSize(
340 		x,y,emWindowPort::PSAS_VIEW,
341 		w,h,emWindowPort::PSAS_VIEW
342 	);
343 }
344 
SetWinPos(double x,double y)345 inline void emWindow::SetWinPos(double x, double y)
346 {
347 	WindowPort->SetPosSize(
348 		x,y,emWindowPort::PSAS_WINDOW,
349 		0,0,emWindowPort::PSAS_IGNORE
350 	);
351 }
352 
SetWinSize(double w,double h)353 inline void emWindow::SetWinSize(double w, double h)
354 {
355 	WindowPort->SetPosSize(
356 		0,0,emWindowPort::PSAS_IGNORE,
357 		w,h,emWindowPort::PSAS_WINDOW
358 	);
359 }
360 
SetWinPosSize(double x,double y,double w,double h)361 inline void emWindow::SetWinPosSize(double x, double y, double w, double h)
362 {
363 	WindowPort->SetPosSize(
364 		x,y,emWindowPort::PSAS_WINDOW,
365 		w,h,emWindowPort::PSAS_WINDOW
366 	);
367 }
368 
SetWinPosViewSize(double x,double y,double w,double h)369 inline void emWindow::SetWinPosViewSize(double x, double y, double w, double h)
370 {
371 	WindowPort->SetPosSize(
372 		x,y,emWindowPort::PSAS_WINDOW,
373 		w,h,emWindowPort::PSAS_VIEW
374 	);
375 }
376 
GetBorderSizes(double * pL,double * pT,double * pR,double * pB)377 inline void emWindow::GetBorderSizes(
378 	double * pL, double * pT, double * pR, double * pB
379 ) const
380 {
381 	WindowPort->GetBorderSizes(pL,pT,pR,pB);
382 }
383 
GetWindowIcon()384 inline const emImage & emWindow::GetWindowIcon() const
385 {
386 	return WindowIcon;
387 }
388 
Raise()389 inline void emWindow::Raise()
390 {
391 	WindowPort->Raise();
392 }
393 
InhibitScreensaver()394 inline void emWindow::InhibitScreensaver()
395 {
396 	WindowPort->InhibitScreensaver();
397 }
398 
AllowScreensaver()399 inline void emWindow::AllowScreensaver()
400 {
401 	WindowPort->AllowScreensaver();
402 }
403 
404 
405 //-------------------------------- emWindowPort --------------------------------
406 
GetWindow()407 inline emWindow & emWindowPort::GetWindow() const
408 {
409 	return Window;
410 }
411 
GetWindowFlags()412 inline emWindow::WindowFlags emWindowPort::GetWindowFlags() const
413 {
414 	return Window.GetWindowFlags();
415 }
416 
GetWindowFlagsSignal()417 inline const emSignal & emWindow::GetWindowFlagsSignal() const
418 {
419 	return WindowFlagsSignal;
420 }
421 
GetWMResName()422 inline const emString & emWindowPort::GetWMResName() const
423 {
424 	return Window.GetWMResName();
425 }
426 
GetWindowTitle()427 inline emString emWindowPort::GetWindowTitle() const
428 {
429 	return Window.GetTitle();
430 }
431 
GetWindowIcon()432 inline const emImage & emWindowPort::GetWindowIcon() const
433 {
434 	return Window.GetWindowIcon();
435 }
436 
SignalWindowClosing()437 inline void emWindowPort::SignalWindowClosing()
438 {
439 	Window.SignalClosing();
440 }
441 
442 
443 #endif
444