1 /*
2  * This file is part of gtkD.
3  *
4  * gtkD is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU Lesser General Public License
6  * as published by the Free Software Foundation; either version 3
7  * of the License, or (at your option) any later version, with
8  * some exceptions, please read the COPYING file.
9  *
10  * gtkD is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public License
16  * along with gtkD; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
18  */
19 
20 // generated automatically - do not change
21 // find conversion definition on APILookup.txt
22 // implement new conversion functionalities on the wrap.utils pakage
23 
24 
25 module gdk.FrameClock;
26 
27 private import gdk.FrameTimings;
28 private import gobject.ObjectG;
29 private import gobject.Signals;
30 private import gtkc.gdk;
31 public  import gtkc.gdktypes;
32 
33 
34 /**
35  * A #GdkFrameClock tells the application when to update and repaint a
36  * window. This may be synced to the vertical refresh rate of the
37  * monitor, for example. Even when the frame clock uses a simple timer
38  * rather than a hardware-based vertical sync, the frame clock helps
39  * because it ensures everything paints at the same time (reducing the
40  * total number of frames). The frame clock can also automatically
41  * stop painting when it knows the frames will not be visible, or
42  * scale back animation framerates.
43  * 
44  * #GdkFrameClock is designed to be compatible with an OpenGL-based
45  * implementation or with mozRequestAnimationFrame in Firefox,
46  * for example.
47  * 
48  * A frame clock is idle until someone requests a frame with
49  * gdk_frame_clock_request_phase(). At some later point that makes
50  * sense for the synchronization being implemented, the clock will
51  * process a frame and emit signals for each phase that has been
52  * requested. (See the signals of the #GdkFrameClock class for
53  * documentation of the phases. %GDK_FRAME_CLOCK_PHASE_UPDATE and the
54  * #GdkFrameClock::update signal are most interesting for application
55  * writers, and are used to update the animations, using the frame time
56  * given by gdk_frame_clock_get_frame_time().
57  * 
58  * The frame time is reported in microseconds and generally in the same
59  * timescale as g_get_monotonic_time(), however, it is not the same
60  * as g_get_monotonic_time(). The frame time does not advance during
61  * the time a frame is being painted, and outside of a frame, an attempt
62  * is made so that all calls to gdk_frame_clock_get_frame_time() that
63  * are called at a “similar” time get the same value. This means that
64  * if different animations are timed by looking at the difference in
65  * time between an initial value from gdk_frame_clock_get_frame_time()
66  * and the value inside the #GdkFrameClock::update signal of the clock,
67  * they will stay exactly synchronized.
68  */
69 public class FrameClock : ObjectG
70 {
71 	/** the main Gtk struct */
72 	protected GdkFrameClock* gdkFrameClock;
73 
74 	/** Get the main Gtk struct */
75 	public GdkFrameClock* getFrameClockStruct()
76 	{
77 		return gdkFrameClock;
78 	}
79 
80 	/** the main Gtk struct as a void* */
81 	protected override void* getStruct()
82 	{
83 		return cast(void*)gdkFrameClock;
84 	}
85 
86 	protected override void setStruct(GObject* obj)
87 	{
88 		gdkFrameClock = cast(GdkFrameClock*)obj;
89 		super.setStruct(obj);
90 	}
91 
92 	/**
93 	 * Sets our main struct and passes it to the parent class.
94 	 */
95 	public this (GdkFrameClock* gdkFrameClock, bool ownedRef = false)
96 	{
97 		this.gdkFrameClock = gdkFrameClock;
98 		super(cast(GObject*)gdkFrameClock, ownedRef);
99 	}
100 
101 	/**
102 	 */
103 
104 	public static GType getType()
105 	{
106 		return gdk_frame_clock_get_type();
107 	}
108 
109 	/**
110 	 * Starts updates for an animation. Until a matching call to
111 	 * gdk_frame_clock_end_updating() is made, the frame clock will continually
112 	 * request a new frame with the %GDK_FRAME_CLOCK_PHASE_UPDATE phase.
113 	 * This function may be called multiple times and frames will be
114 	 * requested until gdk_frame_clock_end_updating() is called the same
115 	 * number of times.
116 	 *
117 	 * Since: 3.8
118 	 */
119 	public void beginUpdating()
120 	{
121 		gdk_frame_clock_begin_updating(gdkFrameClock);
122 	}
123 
124 	/**
125 	 * Stops updates for an animation. See the documentation for
126 	 * gdk_frame_clock_begin_updating().
127 	 *
128 	 * Since: 3.8
129 	 */
130 	public void endUpdating()
131 	{
132 		gdk_frame_clock_end_updating(gdkFrameClock);
133 	}
134 
135 	/**
136 	 * Gets the frame timings for the current frame.
137 	 *
138 	 * Return: the #GdkFrameTimings for the frame currently
139 	 *     being processed, or even no frame is being processed, for the
140 	 *     previous frame. Before any frames have been procesed, returns
141 	 *     %NULL.
142 	 *
143 	 * Since: 3.8
144 	 */
145 	public FrameTimings getCurrentTimings()
146 	{
147 		auto p = gdk_frame_clock_get_current_timings(gdkFrameClock);
148 		
149 		if(p is null)
150 		{
151 			return null;
152 		}
153 		
154 		return ObjectG.getDObject!(FrameTimings)(cast(GdkFrameTimings*) p);
155 	}
156 
157 	/**
158 	 * A #GdkFrameClock maintains a 64-bit counter that increments for
159 	 * each frame drawn.
160 	 *
161 	 * Return: inside frame processing, the value of the frame counter
162 	 *     for the current frame. Outside of frame processing, the frame
163 	 *     counter for the last frame.
164 	 *
165 	 * Since: 3.8
166 	 */
167 	public long getFrameCounter()
168 	{
169 		return gdk_frame_clock_get_frame_counter(gdkFrameClock);
170 	}
171 
172 	/**
173 	 * Gets the time that should currently be used for animations.  Inside
174 	 * the processing of a frame, it’s the time used to compute the
175 	 * animation position of everything in a frame. Outside of a frame, it's
176 	 * the time of the conceptual “previous frame,” which may be either
177 	 * the actual previous frame time, or if that’s too old, an updated
178 	 * time.
179 	 *
180 	 * Return: a timestamp in microseconds, in the timescale of
181 	 *     of g_get_monotonic_time().
182 	 *
183 	 * Since: 3.8
184 	 */
185 	public long getFrameTime()
186 	{
187 		return gdk_frame_clock_get_frame_time(gdkFrameClock);
188 	}
189 
190 	/**
191 	 * #GdkFrameClock internally keeps a history of #GdkFrameTimings
192 	 * objects for recent frames that can be retrieved with
193 	 * gdk_frame_clock_get_timings(). The set of stored frames
194 	 * is the set from the counter values given by
195 	 * gdk_frame_clock_get_history_start() and
196 	 * gdk_frame_clock_get_frame_counter(), inclusive.
197 	 *
198 	 * Return: the frame counter value for the oldest frame
199 	 *     that is available in the internal frame history of the
200 	 *     #GdkFrameClock.
201 	 *
202 	 * Since: 3.8
203 	 */
204 	public long getHistoryStart()
205 	{
206 		return gdk_frame_clock_get_history_start(gdkFrameClock);
207 	}
208 
209 	/**
210 	 * Using the frame history stored in the frame clock, finds the last
211 	 * known presentation time and refresh interval, and assuming that
212 	 * presentation times are separated by the refresh interval,
213 	 * predicts a presentation time that is a multiple of the refresh
214 	 * interval after the last presentation time, and later than @base_time.
215 	 *
216 	 * Params:
217 	 *     baseTime = base time for determining a presentaton time
218 	 *     refreshIntervalReturn = a location to store the determined refresh
219 	 *         interval, or %NULL. A default refresh interval of 1/60th of
220 	 *         a second will be stored if no history is present.
221 	 *     presentationTimeReturn = a location to store the next
222 	 *         candidate presentation time after the given base time.
223 	 *         0 will be will be stored if no history is present.
224 	 *
225 	 * Since: 3.8
226 	 */
227 	public void getRefreshInfo(long baseTime, long* refreshIntervalReturn, long* presentationTimeReturn)
228 	{
229 		gdk_frame_clock_get_refresh_info(gdkFrameClock, baseTime, refreshIntervalReturn, presentationTimeReturn);
230 	}
231 
232 	/**
233 	 * Retrieves a #GdkFrameTimings object holding timing information
234 	 * for the current frame or a recent frame. The #GdkFrameTimings
235 	 * object may not yet be complete: see gdk_frame_timings_get_complete().
236 	 *
237 	 * Params:
238 	 *     frameCounter = the frame counter value identifying the frame to
239 	 *         be received.
240 	 *
241 	 * Return: the #GdkFrameTimings object for the specified
242 	 *     frame, or %NULL if it is not available. See
243 	 *     gdk_frame_clock_get_history_start().
244 	 *
245 	 * Since: 3.8
246 	 */
247 	public FrameTimings getTimings(long frameCounter)
248 	{
249 		auto p = gdk_frame_clock_get_timings(gdkFrameClock, frameCounter);
250 		
251 		if(p is null)
252 		{
253 			return null;
254 		}
255 		
256 		return ObjectG.getDObject!(FrameTimings)(cast(GdkFrameTimings*) p);
257 	}
258 
259 	/**
260 	 * Asks the frame clock to run a particular phase. The signal
261 	 * corresponding the requested phase will be emitted the next
262 	 * time the frame clock processes. Multiple calls to
263 	 * gdk_frame_clock_request_phase() will be combined together
264 	 * and only one frame processed. If you are displaying animated
265 	 * content and want to continually request the
266 	 * %GDK_FRAME_CLOCK_PHASE_UPDATE phase for a period of time,
267 	 * you should use gdk_frame_clock_begin_updating() instead, since
268 	 * this allows GTK+ to adjust system parameters to get maximally
269 	 * smooth animations.
270 	 *
271 	 * Params:
272 	 *     phase = the phase that is requested
273 	 *
274 	 * Since: 3.8
275 	 */
276 	public void requestPhase(GdkFrameClockPhase phase)
277 	{
278 		gdk_frame_clock_request_phase(gdkFrameClock, phase);
279 	}
280 
281 	int[string] connectedSignals;
282 
283 	void delegate(FrameClock)[] onAfterPaintListeners;
284 	/**
285 	 * This signal ends processing of the frame. Applications
286 	 * should generally not handle this signal.
287 	 */
288 	void addOnAfterPaint(void delegate(FrameClock) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
289 	{
290 		if ( "after-paint" !in connectedSignals )
291 		{
292 			Signals.connectData(
293 				this,
294 				"after-paint",
295 				cast(GCallback)&callBackAfterPaint,
296 				cast(void*)this,
297 				null,
298 				connectFlags);
299 			connectedSignals["after-paint"] = 1;
300 		}
301 		onAfterPaintListeners ~= dlg;
302 	}
303 	extern(C) static void callBackAfterPaint(GdkFrameClock* frameclockStruct, FrameClock _frameclock)
304 	{
305 		foreach ( void delegate(FrameClock) dlg; _frameclock.onAfterPaintListeners )
306 		{
307 			dlg(_frameclock);
308 		}
309 	}
310 
311 	void delegate(FrameClock)[] onBeforePaintListeners;
312 	/**
313 	 * This signal begins processing of the frame. Applications
314 	 * should generally not handle this signal.
315 	 */
316 	void addOnBeforePaint(void delegate(FrameClock) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
317 	{
318 		if ( "before-paint" !in connectedSignals )
319 		{
320 			Signals.connectData(
321 				this,
322 				"before-paint",
323 				cast(GCallback)&callBackBeforePaint,
324 				cast(void*)this,
325 				null,
326 				connectFlags);
327 			connectedSignals["before-paint"] = 1;
328 		}
329 		onBeforePaintListeners ~= dlg;
330 	}
331 	extern(C) static void callBackBeforePaint(GdkFrameClock* frameclockStruct, FrameClock _frameclock)
332 	{
333 		foreach ( void delegate(FrameClock) dlg; _frameclock.onBeforePaintListeners )
334 		{
335 			dlg(_frameclock);
336 		}
337 	}
338 
339 	void delegate(FrameClock)[] onFlushEventsListeners;
340 	/**
341 	 * This signal is used to flush pending motion events that
342 	 * are being batched up and compressed together. Applications
343 	 * should not handle this signal.
344 	 */
345 	void addOnFlushEvents(void delegate(FrameClock) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
346 	{
347 		if ( "flush-events" !in connectedSignals )
348 		{
349 			Signals.connectData(
350 				this,
351 				"flush-events",
352 				cast(GCallback)&callBackFlushEvents,
353 				cast(void*)this,
354 				null,
355 				connectFlags);
356 			connectedSignals["flush-events"] = 1;
357 		}
358 		onFlushEventsListeners ~= dlg;
359 	}
360 	extern(C) static void callBackFlushEvents(GdkFrameClock* frameclockStruct, FrameClock _frameclock)
361 	{
362 		foreach ( void delegate(FrameClock) dlg; _frameclock.onFlushEventsListeners )
363 		{
364 			dlg(_frameclock);
365 		}
366 	}
367 
368 	void delegate(FrameClock)[] onLayoutListeners;
369 	/**
370 	 * This signal is emitted as the second step of toolkit and
371 	 * application processing of the frame. Any work to update
372 	 * sizes and positions of application elements should be
373 	 * performed. GTK+ normally handles this internally.
374 	 */
375 	void addOnLayout(void delegate(FrameClock) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
376 	{
377 		if ( "layout" !in connectedSignals )
378 		{
379 			Signals.connectData(
380 				this,
381 				"layout",
382 				cast(GCallback)&callBackLayout,
383 				cast(void*)this,
384 				null,
385 				connectFlags);
386 			connectedSignals["layout"] = 1;
387 		}
388 		onLayoutListeners ~= dlg;
389 	}
390 	extern(C) static void callBackLayout(GdkFrameClock* frameclockStruct, FrameClock _frameclock)
391 	{
392 		foreach ( void delegate(FrameClock) dlg; _frameclock.onLayoutListeners )
393 		{
394 			dlg(_frameclock);
395 		}
396 	}
397 
398 	void delegate(FrameClock)[] onPaintListeners;
399 	/**
400 	 * This signal is emitted as the third step of toolkit and
401 	 * application processing of the frame. The frame is
402 	 * repainted. GDK normally handles this internally and
403 	 * produces expose events, which are turned into GTK+
404 	 * #GtkWidget::draw signals.
405 	 */
406 	void addOnPaint(void delegate(FrameClock) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
407 	{
408 		if ( "paint" !in connectedSignals )
409 		{
410 			Signals.connectData(
411 				this,
412 				"paint",
413 				cast(GCallback)&callBackPaint,
414 				cast(void*)this,
415 				null,
416 				connectFlags);
417 			connectedSignals["paint"] = 1;
418 		}
419 		onPaintListeners ~= dlg;
420 	}
421 	extern(C) static void callBackPaint(GdkFrameClock* frameclockStruct, FrameClock _frameclock)
422 	{
423 		foreach ( void delegate(FrameClock) dlg; _frameclock.onPaintListeners )
424 		{
425 			dlg(_frameclock);
426 		}
427 	}
428 
429 	void delegate(FrameClock)[] onResumeEventsListeners;
430 	/**
431 	 * This signal is emitted after processing of the frame is
432 	 * finished, and is handled internally by GTK+ to resume normal
433 	 * event processing. Applications should not handle this signal.
434 	 */
435 	void addOnResumeEvents(void delegate(FrameClock) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
436 	{
437 		if ( "resume-events" !in connectedSignals )
438 		{
439 			Signals.connectData(
440 				this,
441 				"resume-events",
442 				cast(GCallback)&callBackResumeEvents,
443 				cast(void*)this,
444 				null,
445 				connectFlags);
446 			connectedSignals["resume-events"] = 1;
447 		}
448 		onResumeEventsListeners ~= dlg;
449 	}
450 	extern(C) static void callBackResumeEvents(GdkFrameClock* frameclockStruct, FrameClock _frameclock)
451 	{
452 		foreach ( void delegate(FrameClock) dlg; _frameclock.onResumeEventsListeners )
453 		{
454 			dlg(_frameclock);
455 		}
456 	}
457 
458 	void delegate(FrameClock)[] onUpdateListeners;
459 	/**
460 	 * This signal is emitted as the first step of toolkit and
461 	 * application processing of the frame. Animations should
462 	 * be updated using gdk_frame_clock_get_frame_time().
463 	 * Applications can connect directly to this signal, or
464 	 * use gtk_widget_add_tick_callback() as a more convenient
465 	 * interface.
466 	 */
467 	void addOnUpdate(void delegate(FrameClock) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
468 	{
469 		if ( "update" !in connectedSignals )
470 		{
471 			Signals.connectData(
472 				this,
473 				"update",
474 				cast(GCallback)&callBackUpdate,
475 				cast(void*)this,
476 				null,
477 				connectFlags);
478 			connectedSignals["update"] = 1;
479 		}
480 		onUpdateListeners ~= dlg;
481 	}
482 	extern(C) static void callBackUpdate(GdkFrameClock* frameclockStruct, FrameClock _frameclock)
483 	{
484 		foreach ( void delegate(FrameClock) dlg; _frameclock.onUpdateListeners )
485 		{
486 			dlg(_frameclock);
487 		}
488 	}
489 }