luacairogtk4drawingarealgi

How to draw_area with cairo


i am trying to 'update' lgi (lua gtk binding) examples, which are for gtk3

purpose is to draw geocentric view of solar system, in 2d, for start

app has top row for input, below are

2 x 2 panned widget group - 1 x vertical layout, inside are 2 x horizontal layout

ingredients :

xml main.ui :

<interface>
    <requires lib="gtk" version="4.0" />
    <object class="GtkApplicationWindow" id="app_win">
    ...
    <child>
        <object class="GtkPaned" id="lyt_pnd_main_vert">
        ...
            <child>
                <object class="GtkPaned" id="lyt_pnd_top_hor">
                ...
                    <child>
                        <object class="GtkFrame" id="frame_top_left">
                            <child>
                                <object class="GtkDrawingArea" id="draw_astro">
                                    <property name="height-request">80</property>
                                    <property name="width-request">200</property>
                                    ...

next gui.lua :

Lgi = require('lgi')
Gtk = Lgi.require('Gtk', '4.0')
Gdk = Lgi.require 'Gdk'

local builder = Gtk.Builder()
builder:add_from_file('uis/main.ui')
Ui = builder.objects
local window = Ui.app_win
...
function app:on_activate()
    self.active_window:present()
end
...
local draw = Ui.draw_astro
-- not sure if below is needed, i tried dozens of answers from net
draw:set_content_width(200)
draw:set_content_height(200)
-- print(draw.width) --> 0
-- print(type(draw)) --> userdata

lower down the code, derived from lgi gtk3 samples folder, cairo.lua :

local cairo = Lgi.cairo
local surface = cairo.ImageSurface('ARGB32',256, 256)
local cr = cairo.Context.create(surface)
-- checked lgi docs, cairo.md, tried cr = cairo.surface --> failed
-- next the 2d graphics of our interest :
-- exact copy of samples.arc(cr), with added iter func cr:copy_path(), defunct
function arc(cr)
    local xc, yc = 128, 128
    ...
    cr:stroke()
end

upto here it works as expected; if i add code :

arc(cr)
surface:write_to_png('path/to/png')

and run $ luajit gui.lua, i get expected .png file


but, i want to draw this surface / image to my draw DrawingArea

comparing gtk3 vs gtk4 docs, drawing_area, and some more gtk3 lgi samples ...

i tried (of course what not and some more, lol), including draw:realize() ... :

draw:set_draw_func(
-- draw,
    arc(cr),
    nil,
    nil
)

app runeth, but top left panned widgeth remaineth empty ... such was the cruel destiny of 1st month of that app - god disliked it very much.

q1 : how do i draw into existing gtk_drawing_area widget, with cairo 2d library ? ie a circle, which will resize on panned widget resize ? i believe this requires gtkDrawingArea:resize() func

q2 : do i need explicitly destroy cr & surface ?

i just need a kick start ... hopefully

i gratefully thank you for your precious input

would not mind at all if someone can share some gtk4 lgi examples [chuckles]

godspeed

app 2 x 2 panned widgets with frame:

1


Solution

  • ok, figured this out, took me 2 weeks, lol

    instead of arc function, we draw draw_function:

    ...
    local width, height = 800, 800
    ...
    local function draw_function(draw, cr, width, height, user_data)
        cr:set_line_width(2.0)
        cr:set_source_rgb(0.0, 0.0, 0.0) -- black color
        cr:rectangle(width / 2.0 - 20, height / 2.0 - 20, 40.0, 40.0)
        cr:stroke(cr) -- draw
    end
    

    one needs to call drawing_area widget from app :

    ...
    function app:on_activate()
        draw:set_draw_func(
            draw_function,
            nil,
            nil
        )
        self.active_window:present()
    end
    ...
    

    app panned top left with rectangle