Skip to content

Commit

Permalink
optionally initialize a GtkCanvas immediately
Browse files Browse the repository at this point in the history
This is helpful for precompilation. GtkCanvas was one of the few widgets where being realized was important to calling its functions. With this we can avoid popping up windows during precompilation.

This also changes the behavior of the width and height arguments of the GtkCanvas constructor. We now set the "content area" size rather than the initial size of the widget. I think this is more useful because it sets a minimum size for the widget. The initial size can still be set by calling "size_request" on the widget after construction.
  • Loading branch information
jwahlstrand committed Aug 4, 2023
1 parent 7ff168b commit ce3d3c5
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 6 deletions.
2 changes: 1 addition & 1 deletion examples/canvas.jl
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
using Gtk4

c = GtkCanvas()
c = GtkCanvas(100,100)

# define a function that will be called every time the widget needs to be drawn
@guarded draw(c) do widget
Expand Down
2 changes: 1 addition & 1 deletion src/GLib/loop.jl
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ Does not affect loop operation if GApplication's `run()` method is being used in
See also [`start_main_loop`](@ref).
"""
function stop_main_loop(wait=false)
if !g_main_running[] # we are either already stopped, or in a GApplication
if !g_main_running[] # we are either already stopped or in a GApplication
return
end
g_main_running[] = false
Expand Down
41 changes: 37 additions & 4 deletions src/cairo.jl
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,22 @@ function canvas_draw_backing_store(w, cr, width, height, user_data) # cr is a Ca
ccall((:cairo_paint, libcairo), Nothing, (Ptr{Nothing},), cr)
end

function _init_canvas!(widget, w, h)
widget.back = CairoARGBSurface(w, h)
widget.backcc = CairoContext(widget.back)
end

"""
GtkCanvas(w = -1, h = -1, init_back = false; kwargs...)
Create a GtkCanvas widget for drawing using Cairo (based on GtkDrawingArea).
Optional arguments `w` and `h` can be used to set the minimum width and height
of the drawing area in pixels. If `init_back` is set to true, the canvas's
image CairoSurface will be initialized immediately, which is useful for
precompilation.
Keyword arguments can be used to set properties of the GtkDrawingArea widget.
"""
mutable struct GtkCanvas <: GtkDrawingArea # NOT a GType
handle::Ptr{GObject}
is_sized::Bool
Expand All @@ -18,10 +34,18 @@ mutable struct GtkCanvas <: GtkDrawingArea # NOT a GType
back::CairoSurface # backing store
backcc::CairoContext

function GtkCanvas(w = -1, h = -1; kwargs...)
function GtkCanvas(w = -1, h = -1, init_back = false; kwargs...)
da = GtkDrawingArea(; kwargs...)
G_.set_size_request(da, w, h)
if w > 0 && h > 0
G_.set_content_height(da, h)
G_.set_content_width(da, w)
elseif init_back
error("Width and height arguments must be provided to immediately initialize GtkCanvas.")
end
widget = new(getfield(da,:handle), false, nothing, nothing)
if init_back
_init_canvas!(widget, w, h)
end

function on_realize(da::GtkWidget)
if widget.is_sized
Expand All @@ -34,8 +58,7 @@ mutable struct GtkCanvas <: GtkDrawingArea # NOT a GType
function on_resize(da::GtkDrawingArea, width::Cint, height::Cint)
widget.is_sized = true
if G_.get_realized(widget)
widget.back = CairoARGBSurface(width, height)
widget.backcc = CairoContext(widget.back)
_init_canvas!(widget, width, height)

if isa(widget.resize, Function)
widget.resize(widget)
Expand Down Expand Up @@ -83,13 +106,23 @@ function draw(widget::GtkCanvas)
G_.queue_draw(widget)
end

"""
getgc(c::GtkCanvas)
Return the CairoContext of the CairoSurface for a GtkCanvas.
"""
function getgc(c::GtkCanvas)
if !isdefined(c,:backcc)
error("GtkCanvas not yet initialized.")
end
return c.backcc
end

"""
cairo_surface(c::GtkCanvas)
Return the image CairoSurface for a GtkCanvas.
"""
function cairo_surface(c::GtkCanvas)
if !isdefined(c,:back)
error("GtkCanvas not yet initialized.")
Expand Down

0 comments on commit ce3d3c5

Please sign in to comment.