rhx / SwiftGtk

A Swift wrapper around gtk-3.x and gtk-4.x that is largely auto-generated from gobject-introspection
https://rhx.github.io/SwiftGtk/
BSD 2-Clause "Simplified" License
317 stars 26 forks source link

Add code snippets to override functions #33

Closed Dadoum closed 2 years ago

Dadoum commented 3 years ago

Wanted to know if on_drawn, on_get_preferred_width could be overriden

Dadoum commented 3 years ago

have an idea on how it could be implemented: gir2swift would have to create functions like

var onGetPreferredWidth: @convention(c) (UnsafeMutablePointer<Int>!, UnsafeMutablePointer<Int>!) -> () = { (minimumWidth, naturalWidth) in
    self.getPreferredWidth(UnsafeMutablePointer<Int>!, UnsafeMutablePointer<Int>!)
}

and to override

ptr.getPreferredWidth = onGetPreferredWidth

then, we just have to write

onGetPreferredWidth = { ... }
mikolasstuchlik commented 3 years ago

Hello.

It is not clear to me what you mean by "override". As of now, I am not aware that "overriding" of GLib classes from Swift would be possible. Also I failed to find any virtual method called "on_drawn" and "on_get_preffered_width" in my local .gir files.

Therefore I assume by "on_drawn" you refer to signal "draw" in class GtkWidget. In this case, I would like to inform you, that I currently work on generation of idiomatic signal wrappers. You can find my "work in progress" in my fork of gir2swift, I plan to open PR into rhx's repositories when I'm done.

For the time being, there is a version of idiomatic wrapper currently generated by my code, I think it is safe to just "copy-paste" it into your project as a Widget extension.

    /// This signal is emitted when a widget is supposed to render itself.
    /// The `widget`'s top left corner must be painted at the origin of
    /// the passed in context and be sized to the values returned by
    /// `gtk_widget_get_allocated_width()` and
    /// `gtk_widget_get_allocated_height()`.
    /// 
    /// Signal handlers connected to this signal can modify the cairo
    /// context passed as `cr` in any way they like and don't need to
    /// restore it. The signal emission takes care of calling `cairo_save()`
    /// before and `cairo_restore()` after invoking the handler.
    /// 
    /// The signal handler will get a `cr` with a clip region already set to the
    /// widget's dirty region, i.e. to the area that needs repainting.  Complicated
    /// widgets that want to avoid redrawing themselves completely can get the full
    /// extents of the clip region with `gdk_cairo_get_clip_rectangle()`, or they can
    /// get a finer-grained representation of the dirty region with
    /// `cairo_copy_clip_rectangle_list()`.
    /// - Note: This function represents signal `draw`
    /// - Parameter flags: Flags
    /// - Parameter handler: `true` to stop other handlers from being invoked for the event. `false` to propagate the event further.
    /// - Parameter unownedSelf: Reference to instance of self
    /// - Parameter cr: the cairo context to draw to
    public func _onDraw(flags: ConnectFlags = ConnectFlags(0), handler: @escaping ( _ unownedSelf: WidgetRef, _ cr: Cairo.ContextRef) -> Bool ) -> Int {
        typealias SwiftHandler = Tmp__DualClosureHolder<WidgetRef, Cairo.ContextRef, Bool>
        let swiftHandlerBoxed = Unmanaged.passRetained(SwiftHandler(handler)).toOpaque()
        let cCallback: @convention(c) (gpointer, gpointer, gpointer) -> gboolean = { 
            let holder = Unmanaged<SwiftHandler>.fromOpaque($2).takeUnretainedValue()
            let output = holder.call(WidgetRef(raw: $0), Cairo.ContextRef(raw: $1))
            return gboolean((output) ? 1 : 0)
        }
        let __gCallback__ = unsafeBitCast(cCallback, to: GCallback.self)
        let rv = signalConnectData(
            detailedSignal: "draw", 
            cHandler: __gCallback__, 
            data: swiftHandlerBoxed, 
            destroyData: {
                if let swift = $0 {
                    let holder = Unmanaged<SwiftHandler>.fromOpaque(swift)
                    holder.release()
                }
                let _ = $1
            }, 
            connectFlags: flags
        )
        return rv
    }
rhx commented 2 years ago

Wrapper-function generation has been merged into main now.