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 }