portico/Sources/Portico/Generated/GLArea.swift

544 lines
27 KiB
Swift

// Generated by PorticoGen. DO NOT EDIT. See Sources/PorticoGen to make changes.
import Adw
import Gtk
import Gio
import Gdk
// PorticoGen: generateStruct | source: Gtk.GLArea
/// Allows drawing with OpenGL.
///
/// <picture>
/// <source srcset="glarea-dark.png" media="(prefers-color-scheme: dark)">
/// <img alt="An example GtkGLArea" src="glarea.png">
/// </picture>
///
/// `GtkGLArea` sets up its own [class`Gdk`.GLContext], and creates a custom
/// GL framebuffer that the widget will do GL rendering onto. It also ensures
/// that this framebuffer is the default GL rendering target when rendering.
/// The completed rendering is integrated into the larger GTK scene graph as
/// a texture.
///
/// In order to draw, you have to connect to the [signal`Gtk`.GLArea::render]
/// signal, or subclass `GtkGLArea` and override the GtkGLAreaClass.render
/// virtual function.
///
/// The `GtkGLArea` widget ensures that the `GdkGLContext` is associated with
/// the widget's drawing area, and it is kept updated when the size and
/// position of the drawing area changes.
///
/// ## Drawing with GtkGLArea
///
/// The simplest way to draw using OpenGL commands in a `GtkGLArea` is to
/// create a widget instance and connect to the [signal`Gtk`.GLArea::render] signal:
///
/// The `render()` function will be called when the `GtkGLArea` is ready
/// for you to draw its content:
///
/// The initial contents of the framebuffer are transparent.
///
/// ```c
/// static gboolean
/// render (GtkGLArea *area, GdkGLContext *context)
/// {
/// // inside this function it's safe to use GL; the given
/// // GdkGLContext has been made current to the drawable
/// // surface used by the `GtkGLArea` and the viewport has
/// // already been set to be the size of the allocation
///
/// // we can start by clearing the buffer
/// glClearColor (0, 0, 0, 0);
/// glClear (GL_COLOR_BUFFER_BIT);
///
/// // record the active framebuffer ID, so we can return to it
/// // with `glBindFramebuffer (GL_FRAMEBUFFER, screen_fb)` should
/// // we, for instance, intend on utilizing the results of an
/// // intermediate render texture pass
/// GLuint screen_fb = 0;
/// glGetIntegerv (GL_FRAMEBUFFER_BINDING, &screen_fb);
///
/// // draw your object
/// // draw_an_object ();
///
/// // we completed our drawing; the draw commands will be
/// // flushed at the end of the signal emission chain, and
/// // the buffers will be drawn on the window
/// return TRUE;
/// }
///
/// void setup_glarea (void)
/// {
/// // create a GtkGLArea instance
/// GtkWidget *gl_area = gtk_gl_area_new ();
///
/// // connect to the "render" signal
/// g_signal_connect (gl_area, "render", G_CALLBACK (render), NULL);
/// }
/// ```
///
/// If you need to initialize OpenGL state, e.g. buffer objects or
/// shaders, you should use the [signal`Gtk`.Widget::realize] signal;
/// you can use the [signal`Gtk`.Widget::unrealize] signal to clean up.
/// Since the `GdkGLContext` creation and initialization may fail, you
/// will need to check for errors, using [method`Gtk`.GLArea.get_error].
///
/// An example of how to safely initialize the GL state is:
///
/// ```c
/// static void
/// on_realize (GtkGLArea *area)
/// {
/// // We need to make the context current if we want to
/// // call GL API
/// gtk_gl_area_make_current (area);
///
/// // If there were errors during the initialization or
/// // when trying to make the context current, this
/// // function will return a GError for you to catch
/// if (gtk_gl_area_get_error (area) != NULL)
/// return;
///
/// // You can also use gtk_gl_area_set_error() in order
/// // to show eventual initialization errors on the
/// // GtkGLArea widget itself
/// GError *internal_error = NULL;
/// init_buffer_objects (&error);
/// if (error != NULL)
/// {
/// gtk_gl_area_set_error (area, error);
/// g_error_free (error);
/// return;
/// }
///
/// init_shaders (&error);
/// if (error != NULL)
/// {
/// gtk_gl_area_set_error (area, error);
/// g_error_free (error);
/// return;
/// }
/// }
/// ```
///
/// If you need to change the options for creating the `GdkGLContext`
/// you should use the [signal`Gtk`.GLArea::create-context] signal.
///
/// A Portico view that mounts a `Gtk.GLArea`.
@MainActor public struct GLArea: View {
private let make: (MountContext) -> Gtk.GLArea
private var configure: [(Gtk.GLArea, MountContext) -> Void] = []
public var body: Never { fatalError() }
// PorticoGen: generateInits(static) | source: Gtk.GLArea.init()
/// Creates a new `GtkGLArea` widget.
///
/// Applied once at mount; use the `Binding` or closure overload for values that change.
/// Optional value parameters are applied only when non-`nil`; a `nil` argument leaves the widget's own default in place and cannot clear a nullable property - use the matching modifier for that.
///
/// - Parameter allowedApis: The allowed APIs.
/// - Parameter autoRender: If set to `true` the ::render signal will be emitted every time the widget draws.
/// - Parameter hasDepthBuffer: If set to `true` the widget will allocate and enable a depth buffer for the target framebuffer.
/// - Parameter hasStencilBuffer: If set to `true` the widget will allocate and enable a stencil buffer for the target framebuffer.
/// - Parameter useEs: If set to `true` the widget will try to create a `GdkGLContext` using OpenGL ES instead of OpenGL.
/// - Parameter onCreateContext: Invoked when the widget emits the `create-context` signal. Its return value is forwarded to GTK as the signal's result.
/// - Parameter onRender: Invoked when the widget emits the `render` signal. The closure receives the signal's arguments in order. Its return value is forwarded to GTK as the signal's result.
/// - Parameter onResize: Invoked when the widget emits the `resize` signal. The closure receives the signal's arguments in order.
public init(allowedApis: Gtk.GLAPI? = nil, autoRender: Bool? = nil, hasDepthBuffer: Bool? = nil, hasStencilBuffer: Bool? = nil, useEs: Bool? = nil, onCreateContext: (() -> Gtk.GLContext)? = nil, onRender: ((Gtk.GLContext) -> Bool)? = nil, onResize: ((Int32, Int32) -> Void)? = nil) {
make = { _ in Gtk.GLArea() }
configure.append { w, ctx in
if let allowedApis { w.setAllowedApis(apis: allowedApis) }
if let autoRender { w.setAutoRender(autoRender: autoRender) }
if let hasDepthBuffer { w.setHasDepthBuffer(hasDepthBuffer: hasDepthBuffer) }
if let hasStencilBuffer { w.setHasStencilBuffer(hasStencilBuffer: hasStencilBuffer) }
if let useEs { w.setUseEs(useEs: useEs) }
if let onCreateContext { ctx.registry.add(w.connectCreateContext { _ in onCreateContext() }) }
if let onRender { ctx.registry.add(w.connectRender { _, a0 in onRender(a0) }) }
if let onResize { ctx.registry.add(w.connectResize { _, a0, a1 in onResize(a0, a1) }) }
}
}
}
extension GLArea: WidgetView {
public typealias Target = Gtk.GLArea
@_spi(Portico) public func appending(
_ step: @escaping (Gtk.GLArea, MountContext) -> Void
) -> Self {
var c = self
c.configure.append(step)
return c
}
}
@_spi(Portico) extension GLArea: Mountable {
@_spi(Portico) public func mount(_ ctx: MountContext) -> Gtk.Widget {
let w = make(ctx)
for step in configure { step(w, ctx) }
return w
}
}
// PorticoGen: generateModifierExtension | source: Gtk.GLArea
/// Modifiers for `Gtk.GLArea`, available on every Portico view whose
/// backing widget is `Gtk.GLArea` or one of its subclasses.
extension WidgetView where Target: Gtk.GLArea {
// PorticoGen: generateModifierExtension -> generatePropertyModifiers(static) | source: Gtk.GLArea.setAllowedApis(apis:)
/// Sets the allowed APIs to create a context with.
///
/// You should check [property`Gtk`.GLArea:api] before drawing
/// with either API.
///
/// By default, all APIs are allowed.
///
/// Applied once at mount; use the `Binding` or closure overload for a value that changes.
///
/// - Parameter allowedApis: The allowed APIs.
/// - Returns: A copy of this view with the modifier applied.
public func allowedApis(_ allowedApis: Gtk.GLAPI) -> Self {
appending { w, _ in
w.setAllowedApis(apis: allowedApis)
}
}
// PorticoGen: generateModifierExtension -> generatePropertyModifiers -> bindingModifier(twoWay) | source: Gtk.GLArea.setAllowedApis(apis:), GObject.Object.connectNotify(detail:_:), Gtk.GLArea.getAllowedApis()
/// Sets the allowed APIs to create a context with.
///
/// You should check [property`Gtk`.GLArea:api] before drawing
/// with either API.
///
/// By default, all APIs are allowed.
///
/// Applied at mount and re-applied on every change the binding publishes.
/// When `Gtk.GLAPI` conforms to `Equatable` this binds in both directions: the widget's `notify` signal writes its current value back into the binding, so changes made in the UI propagate to the bound state. Each direction compares before writing, which terminates the echo after one hop. A value type that is not `Equatable` binds one way only, because the echo cannot be broken.
///
/// - Returns: A copy of this view with the modifier applied.
public func allowedApis(_ allowedApis: Portico.Binding<Gtk.GLAPI>) -> Self {
appending { w, ctx in
Portico.bindProperty(
w, allowedApis, registry: ctx.registry, notifyDetail: "allowed-apis",
read: { [w] in w.getAllowedApis() },
write: { [w] v in w.setAllowedApis(apis: v) }
)
}
}
// PorticoGen: generateModifierExtension -> generatePropertyModifiers(closure) | source: Gtk.GLArea.setAllowedApis(apis:)
/// Sets the allowed APIs to create a context with.
///
/// You should check [property`Gtk`.GLArea:api] before drawing
/// with either API.
///
/// By default, all APIs are allowed.
///
/// The closure runs inside a `DependencyTracker`, so any `@State` it reads re-runs it and pushes the new value through `Gtk.GLArea.setAllowedApis(apis:)`.
///
/// - Parameter allowedApis: The allowed APIs.
/// - Returns: A copy of this view with the modifier applied.
public func allowedApis(_ allowedApis: @escaping () -> Gtk.GLAPI) -> Self {
appending { w, ctx in
let tracker = DependencyTracker { [w] in w.setAllowedApis(apis: allowedApis()) }
tracker.run()
ctx.registry.add(tracker)
}
}
// PorticoGen: generateModifierExtension -> generatePropertyModifiers(static) | source: Gtk.GLArea.setAutoRender(autoRender:)
/// Sets whether the `GtkGLArea` is in auto render mode.
///
/// If `auto_render` is `true` the [signal`Gtk`.GLArea::render] signal will
/// be emitted every time the widget draws. This is the default and is
/// useful if drawing the widget is faster.
///
/// If `auto_render` is `false` the data from previous rendering is kept
/// around and will be used for drawing the widget the next time,
/// unless the window is resized. In order to force a rendering
/// [method`Gtk`.GLArea.queue_render] must be called. This mode is
/// useful when the scene changes seldom, but takes a long time to redraw.
///
/// Applied once at mount; use the `Binding` or closure overload for a value that changes.
///
/// - Parameter autoRender: If set to `true` the ::render signal will be emitted every time the widget draws.
/// - Returns: A copy of this view with the modifier applied.
public func autoRender(_ autoRender: Bool) -> Self {
appending { w, _ in
w.setAutoRender(autoRender: autoRender)
}
}
// PorticoGen: generateModifierExtension -> generatePropertyModifiers -> bindingModifier(twoWay) | source: Gtk.GLArea.setAutoRender(autoRender:), GObject.Object.connectNotify(detail:_:), Gtk.GLArea.getAutoRender()
/// Sets whether the `GtkGLArea` is in auto render mode.
///
/// If `auto_render` is `true` the [signal`Gtk`.GLArea::render] signal will
/// be emitted every time the widget draws. This is the default and is
/// useful if drawing the widget is faster.
///
/// If `auto_render` is `false` the data from previous rendering is kept
/// around and will be used for drawing the widget the next time,
/// unless the window is resized. In order to force a rendering
/// [method`Gtk`.GLArea.queue_render] must be called. This mode is
/// useful when the scene changes seldom, but takes a long time to redraw.
///
/// Applied at mount and re-applied on every change the binding publishes.
/// When `Bool` conforms to `Equatable` this binds in both directions: the widget's `notify` signal writes its current value back into the binding, so changes made in the UI propagate to the bound state. Each direction compares before writing, which terminates the echo after one hop. A value type that is not `Equatable` binds one way only, because the echo cannot be broken.
///
/// - Returns: A copy of this view with the modifier applied.
public func autoRender(_ autoRender: Portico.Binding<Bool>) -> Self {
appending { w, ctx in
Portico.bindProperty(
w, autoRender, registry: ctx.registry, notifyDetail: "auto-render",
read: { [w] in w.getAutoRender() },
write: { [w] v in w.setAutoRender(autoRender: v) }
)
}
}
// PorticoGen: generateModifierExtension -> generatePropertyModifiers(closure) | source: Gtk.GLArea.setAutoRender(autoRender:)
/// Sets whether the `GtkGLArea` is in auto render mode.
///
/// If `auto_render` is `true` the [signal`Gtk`.GLArea::render] signal will
/// be emitted every time the widget draws. This is the default and is
/// useful if drawing the widget is faster.
///
/// If `auto_render` is `false` the data from previous rendering is kept
/// around and will be used for drawing the widget the next time,
/// unless the window is resized. In order to force a rendering
/// [method`Gtk`.GLArea.queue_render] must be called. This mode is
/// useful when the scene changes seldom, but takes a long time to redraw.
///
/// The closure runs inside a `DependencyTracker`, so any `@State` it reads re-runs it and pushes the new value through `Gtk.GLArea.setAutoRender(autoRender:)`.
///
/// - Parameter autoRender: If set to `true` the ::render signal will be emitted every time the widget draws.
/// - Returns: A copy of this view with the modifier applied.
public func autoRender(_ autoRender: @escaping () -> Bool) -> Self {
appending { w, ctx in
let tracker = DependencyTracker { [w] in w.setAutoRender(autoRender: autoRender()) }
tracker.run()
ctx.registry.add(tracker)
}
}
// PorticoGen: generateModifierExtension -> generatePropertyModifiers(static) | source: Gtk.GLArea.setHasDepthBuffer(hasDepthBuffer:)
/// Sets whether the `GtkGLArea` should use a depth buffer.
///
/// If `has_depth_buffer` is `true` the widget will allocate and
/// enable a depth buffer for the target framebuffer. Otherwise
/// there will be none.
///
/// Applied once at mount; use the `Binding` or closure overload for a value that changes.
///
/// - Parameter hasDepthBuffer: If set to `true` the widget will allocate and enable a depth buffer for the target framebuffer.
/// - Returns: A copy of this view with the modifier applied.
public func hasDepthBuffer(_ hasDepthBuffer: Bool) -> Self {
appending { w, _ in
w.setHasDepthBuffer(hasDepthBuffer: hasDepthBuffer)
}
}
// PorticoGen: generateModifierExtension -> generatePropertyModifiers -> bindingModifier(twoWay) | source: Gtk.GLArea.setHasDepthBuffer(hasDepthBuffer:), GObject.Object.connectNotify(detail:_:), Gtk.GLArea.getHasDepthBuffer()
/// Sets whether the `GtkGLArea` should use a depth buffer.
///
/// If `has_depth_buffer` is `true` the widget will allocate and
/// enable a depth buffer for the target framebuffer. Otherwise
/// there will be none.
///
/// Applied at mount and re-applied on every change the binding publishes.
/// When `Bool` conforms to `Equatable` this binds in both directions: the widget's `notify` signal writes its current value back into the binding, so changes made in the UI propagate to the bound state. Each direction compares before writing, which terminates the echo after one hop. A value type that is not `Equatable` binds one way only, because the echo cannot be broken.
///
/// - Returns: A copy of this view with the modifier applied.
public func hasDepthBuffer(_ hasDepthBuffer: Portico.Binding<Bool>) -> Self {
appending { w, ctx in
Portico.bindProperty(
w, hasDepthBuffer, registry: ctx.registry, notifyDetail: "has-depth-buffer",
read: { [w] in w.getHasDepthBuffer() },
write: { [w] v in w.setHasDepthBuffer(hasDepthBuffer: v) }
)
}
}
// PorticoGen: generateModifierExtension -> generatePropertyModifiers(closure) | source: Gtk.GLArea.setHasDepthBuffer(hasDepthBuffer:)
/// Sets whether the `GtkGLArea` should use a depth buffer.
///
/// If `has_depth_buffer` is `true` the widget will allocate and
/// enable a depth buffer for the target framebuffer. Otherwise
/// there will be none.
///
/// The closure runs inside a `DependencyTracker`, so any `@State` it reads re-runs it and pushes the new value through `Gtk.GLArea.setHasDepthBuffer(hasDepthBuffer:)`.
///
/// - Parameter hasDepthBuffer: If set to `true` the widget will allocate and enable a depth buffer for the target framebuffer.
/// - Returns: A copy of this view with the modifier applied.
public func hasDepthBuffer(_ hasDepthBuffer: @escaping () -> Bool) -> Self {
appending { w, ctx in
let tracker = DependencyTracker { [w] in w.setHasDepthBuffer(hasDepthBuffer: hasDepthBuffer()) }
tracker.run()
ctx.registry.add(tracker)
}
}
// PorticoGen: generateModifierExtension -> generatePropertyModifiers(static) | source: Gtk.GLArea.setHasStencilBuffer(hasStencilBuffer:)
/// Sets whether the `GtkGLArea` should use a stencil buffer.
///
/// If `has_stencil_buffer` is `true` the widget will allocate and
/// enable a stencil buffer for the target framebuffer. Otherwise
/// there will be none.
///
/// Applied once at mount; use the `Binding` or closure overload for a value that changes.
///
/// - Parameter hasStencilBuffer: If set to `true` the widget will allocate and enable a stencil buffer for the target framebuffer.
/// - Returns: A copy of this view with the modifier applied.
public func hasStencilBuffer(_ hasStencilBuffer: Bool) -> Self {
appending { w, _ in
w.setHasStencilBuffer(hasStencilBuffer: hasStencilBuffer)
}
}
// PorticoGen: generateModifierExtension -> generatePropertyModifiers -> bindingModifier(twoWay) | source: Gtk.GLArea.setHasStencilBuffer(hasStencilBuffer:), GObject.Object.connectNotify(detail:_:), Gtk.GLArea.getHasStencilBuffer()
/// Sets whether the `GtkGLArea` should use a stencil buffer.
///
/// If `has_stencil_buffer` is `true` the widget will allocate and
/// enable a stencil buffer for the target framebuffer. Otherwise
/// there will be none.
///
/// Applied at mount and re-applied on every change the binding publishes.
/// When `Bool` conforms to `Equatable` this binds in both directions: the widget's `notify` signal writes its current value back into the binding, so changes made in the UI propagate to the bound state. Each direction compares before writing, which terminates the echo after one hop. A value type that is not `Equatable` binds one way only, because the echo cannot be broken.
///
/// - Returns: A copy of this view with the modifier applied.
public func hasStencilBuffer(_ hasStencilBuffer: Portico.Binding<Bool>) -> Self {
appending { w, ctx in
Portico.bindProperty(
w, hasStencilBuffer, registry: ctx.registry, notifyDetail: "has-stencil-buffer",
read: { [w] in w.getHasStencilBuffer() },
write: { [w] v in w.setHasStencilBuffer(hasStencilBuffer: v) }
)
}
}
// PorticoGen: generateModifierExtension -> generatePropertyModifiers(closure) | source: Gtk.GLArea.setHasStencilBuffer(hasStencilBuffer:)
/// Sets whether the `GtkGLArea` should use a stencil buffer.
///
/// If `has_stencil_buffer` is `true` the widget will allocate and
/// enable a stencil buffer for the target framebuffer. Otherwise
/// there will be none.
///
/// The closure runs inside a `DependencyTracker`, so any `@State` it reads re-runs it and pushes the new value through `Gtk.GLArea.setHasStencilBuffer(hasStencilBuffer:)`.
///
/// - Parameter hasStencilBuffer: If set to `true` the widget will allocate and enable a stencil buffer for the target framebuffer.
/// - Returns: A copy of this view with the modifier applied.
public func hasStencilBuffer(_ hasStencilBuffer: @escaping () -> Bool) -> Self {
appending { w, ctx in
let tracker = DependencyTracker { [w] in w.setHasStencilBuffer(hasStencilBuffer: hasStencilBuffer()) }
tracker.run()
ctx.registry.add(tracker)
}
}
// PorticoGen: generateModifierExtension -> generatePropertyModifiers(static) | source: Gtk.GLArea.setUseEs(useEs:)
/// Sets whether the `area` should create an OpenGL or an OpenGL ES context.
///
/// You should check the capabilities of the `GdkGLContext` before drawing
/// with either API.
///
/// Applied once at mount; use the `Binding` or closure overload for a value that changes.
///
/// - Parameter useEs: If set to `true` the widget will try to create a `GdkGLContext` using OpenGL ES instead of OpenGL.
/// - Returns: A copy of this view with the modifier applied.
public func useEs(_ useEs: Bool) -> Self {
appending { w, _ in
w.setUseEs(useEs: useEs)
}
}
// PorticoGen: generateModifierExtension -> generatePropertyModifiers -> bindingModifier(twoWay) | source: Gtk.GLArea.setUseEs(useEs:), GObject.Object.connectNotify(detail:_:), Gtk.GLArea.getUseEs()
/// Sets whether the `area` should create an OpenGL or an OpenGL ES context.
///
/// You should check the capabilities of the `GdkGLContext` before drawing
/// with either API.
///
/// Applied at mount and re-applied on every change the binding publishes.
/// When `Bool` conforms to `Equatable` this binds in both directions: the widget's `notify` signal writes its current value back into the binding, so changes made in the UI propagate to the bound state. Each direction compares before writing, which terminates the echo after one hop. A value type that is not `Equatable` binds one way only, because the echo cannot be broken.
///
/// - Returns: A copy of this view with the modifier applied.
public func useEs(_ useEs: Portico.Binding<Bool>) -> Self {
appending { w, ctx in
Portico.bindProperty(
w, useEs, registry: ctx.registry, notifyDetail: "use-es",
read: { [w] in w.getUseEs() },
write: { [w] v in w.setUseEs(useEs: v) }
)
}
}
// PorticoGen: generateModifierExtension -> generatePropertyModifiers(closure) | source: Gtk.GLArea.setUseEs(useEs:)
/// Sets whether the `area` should create an OpenGL or an OpenGL ES context.
///
/// You should check the capabilities of the `GdkGLContext` before drawing
/// with either API.
///
/// The closure runs inside a `DependencyTracker`, so any `@State` it reads re-runs it and pushes the new value through `Gtk.GLArea.setUseEs(useEs:)`.
///
/// - Parameter useEs: If set to `true` the widget will try to create a `GdkGLContext` using OpenGL ES instead of OpenGL.
/// - Returns: A copy of this view with the modifier applied.
public func useEs(_ useEs: @escaping () -> Bool) -> Self {
appending { w, ctx in
let tracker = DependencyTracker { [w] in w.setUseEs(useEs: useEs()) }
tracker.run()
ctx.registry.add(tracker)
}
}
// PorticoGen: generateModifierExtension -> generateSignalModifier | source: Gtk.GLArea.connectCreateContext(_:)
/// Emitted when the widget is being realized.
///
/// This allows you to override how the GL context is created.
/// This is useful when you want to reuse an existing GL context,
/// or if you want to try creating different kinds of GL options.
///
/// If context creation fails then the signal handler can use
/// [method`Gtk`.GLArea.set_error] to register a more detailed error
/// of how the construction failed.
///
/// - Parameter handler: Invoked when the widget emits the `create-context` signal. Its return value is forwarded to GTK as the signal's result.
/// - Returns: A copy of this view with the modifier applied.
public func onCreateContext(_ handler: @escaping () -> Gtk.GLContext) -> Self {
appending { w, ctx in
ctx.registry.add(w.connectCreateContext { _ in handler() })
}
}
// PorticoGen: generateModifierExtension -> generateSignalModifier | source: Gtk.GLArea.connectRender(_:)
/// Emitted every time the contents of the `GtkGLArea` should be redrawn.
///
/// The `context` is bound to the `area` prior to emitting this function,
/// and the buffers are painted to the window once the emission terminates.
///
/// - Parameter handler: Invoked when the widget emits the `render` signal. The closure receives the signal's arguments in order. Its return value is forwarded to GTK as the signal's result.
/// - Returns: A copy of this view with the modifier applied.
public func onRender(_ handler: @escaping (Gtk.GLContext) -> Bool) -> Self {
appending { w, ctx in
ctx.registry.add(w.connectRender { _, a0 in handler(a0) })
}
}
// PorticoGen: generateModifierExtension -> generateSignalModifier | source: Gtk.GLArea.connectResize(_:)
/// Emitted once when the widget is realized, and then each time the widget
/// is changed while realized.
///
/// This is useful in order to keep GL state up to date with the widget size,
/// like for instance camera properties which may depend on the width/height
/// ratio.
///
/// The GL context for the area is guaranteed to be current when this signal
/// is emitted.
///
/// The default handler sets up the GL viewport.
///
/// - Parameter handler: Invoked when the widget emits the `resize` signal. The closure receives the signal's arguments in order.
/// - Returns: A copy of this view with the modifier applied.
public func onResize(_ handler: @escaping (Int32, Int32) -> Void) -> Self {
appending { w, ctx in
ctx.registry.add(w.connectResize { _, a0, a1 in handler(a0, a1) })
}
}
}