Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use new dialogs (breaking) #49

Merged
merged 10 commits into from
Jun 24, 2024
1 change: 0 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ jobs:
fail-fast: false
matrix:
julia-version:
- "1.6"
- "1"
#- "nightly"
os:
Expand Down
8 changes: 5 additions & 3 deletions GI/src/giimport.jl
Original file line number Diff line number Diff line change
Expand Up @@ -86,11 +86,14 @@ function decl(structinfo::GIStructInfo,force_opaque=false)
gstructname = get_full_name(structinfo)
gtype=get_g_type(structinfo)
isboxed = GLib.g_isa(gtype,GLib.g_type(GBoxed))
ustructname=get_struct_name(structinfo,force_opaque)
opaque = force_opaque || isopaque(structinfo)
ctypename = opaque ? :GBoxed : :(Union{GBoxed,$ustructname})
exprs=Expr[]
if isboxed
fin = quote
$(unblock(typeinit_def(structinfo,gstructname)))
function $gstructname(ref::Ptr{T}, own::Bool = false) where {T <: GBoxed}
function $gstructname(ref::Ptr{T}, own::Bool = false) where {T <: $ctypename}
#println("constructing ",$(QuoteNode(gstructname)), " ",own)
x = new(ref)
if own
Expand All @@ -105,8 +108,6 @@ function decl(structinfo::GIStructInfo,force_opaque=false)
end
end
conv=nothing
opaque = force_opaque || isopaque(structinfo)
ustructname=get_struct_name(structinfo,force_opaque)
if !opaque
fieldsexpr=Expr[]
for field in get_fields(structinfo)
Expand All @@ -123,6 +124,7 @@ function decl(structinfo::GIStructInfo,force_opaque=false)
push!(exprs,ustruc)
conv = quote
unsafe_convert(::Type{Ptr{$ustructname}}, box::$gstructname) = convert(Ptr{$ustructname}, box.handle)
convert(::Type{$gstructname}, p::Ptr{$ustructname}, owns = false) = $gstructname(p, owns)
end
end
decl = isboxed ? :($gstructname <: GBoxed) : gstructname
Expand Down
2 changes: 1 addition & 1 deletion docs/src/doc/reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,8 @@ Gtk4.selected_string

## Dialogs
```@docs
Gtk4.ask_dialog
Gtk4.info_dialog
Gtk4.ask_dialog
Gtk4.input_dialog
Gtk4.open_dialog
Gtk4.save_dialog
Expand Down
40 changes: 18 additions & 22 deletions docs/src/manual/dialogs.md
Original file line number Diff line number Diff line change
@@ -1,25 +1,25 @@
# Dialogs

Dialogs are transient windows that show information or ask the user for information.
Dialogs are transient windows that show messages or ask the user for information.

!!! note "Example"
Some of the code on this page can be found in "dialogs.jl" in the "example" subdirectory.

!!! tip "Creating dialogs in callbacks"
When creating dialogs in signal or action callbacks, you have to use the methods that take a function as the first argument (equivalently the `do` syntax).
When creating dialogs in signal or action callbacks, you must use the methods that take a function as the first argument (equivalently the `do` syntax).

## Message dialogs

Gtk4.jl supports `GtkMessageDialog` and provides several convenience functions: `info_dialog`, `ask_dialog`, `warn_dialog`, and `error_dialog`. Each takes a string for a message to show and an optional parent container, and returns nothing, except for `ask_dialog` which returns `true` if the user clicks the button corresponding to yes.
Gtk4.jl supports `GtkAlertDialog` and wraps it in convenience functions `info_dialog` and `ask_dialog`.
Each takes a string for a message to show and an optional parent container.

For all dialog convenience functions, there are two ways of using them. For use in the REPL or an interactive script, the following forms can be used:

```julia
info_dialog("Julia rocks!")
ask_dialog("Do you like chocolate ice cream?", "Not at all", "I like it") && println("That's my favorite too.")
warn_dialog("Oops!... I did it again")
```
These take an optional argument `timeout` (in seconds) that can be used to make the dialog disappear after a certain time.
Note that `ask_dialog` returns `true` if the user clicks the button corresponding to yes. These functions take an optional argument `timeout` (in seconds) that can be used to make the dialog disappear after a certain time.

In callbacks (for example when a user clicks a button in a GUI), you _must_ use a different form, which takes a callback as the first argument that will be called when the user closes the dialog. A full example:
```julia
Expand All @@ -31,9 +31,9 @@ function on_click(b)
end
signal_connect(on_click, b, "clicked")
```
If you are using these functions in the context of a GUI, you should set the third argument of `info_dialog`, `parent`, to be the top-level window. Otherwise, for standalone usage in scripts, do not set it.
If you are using these functions in the context of a GUI, you should set the third argument of `info_dialog`, `parent`, to be the top-level window.

The callback can alternatively be constructed using Julia's `do` syntax:
The callback function can alternatively be constructed using Julia's `do` syntax:
```julia
info_dialog("Julia rocks!", win) do
println("message received")
Expand Down Expand Up @@ -76,18 +76,7 @@ open_dialog(f, "Pick a file to open", parent; start_folder = "/data")
```
The same syntax works for `save_dialog`.

### Filters
Filters can be used to limit the type of files that the user can pick. Filters can be specified as a Tuple or Vector.
A filter can be specified as a string, in which case it specifies a globbing pattern, for example `"*.png"`.
You can specify multiple match types for a single filter by separating the patterns with a comma, for example `"*.png,*.jpg"`.
You can alternatively specify MIME types, or if no specification is provided it defaults to types supported by `GdkPixbuf`.
The generic specification of a filter is
```julia
GtkFileFilter(pattern = "", mimetype = "")
```
A human-readable name can optionally be provided using a keyword argument.

If on the other hand you want to choose a folder instead of a file, use `select_folder = true` in `open_dialog`:
If you want to choose a folder instead of a file, use `select_folder = true` in `open_dialog`:
```julia
dir=Ref{String}()
open_dialog("Select Dataset Folder"; select_folder = true) do name
Expand All @@ -99,6 +88,13 @@ if isdir(dir[])
end
```

## Custom dialogs

TODO
### Filters
Filters can be used to limit the type of files that the user can pick. Filters can be specified as a Tuple or Vector.
A filter can be specified as a string, in which case it specifies a globbing pattern, for example `"*.png"`.
You can specify multiple match types for a single filter by separating the patterns with a comma, for example `"*.png,*.jpg"`.
You can alternatively specify MIME types, or if no specification is provided it defaults to types supported by `GdkPixbuf`.
The generic specification of a filter is
```julia
GtkFileFilter(pattern = "", mimetype = "")
```
A human-readable name can optionally be provided using a keyword argument.
14 changes: 14 additions & 0 deletions src/GLib/gio.jl
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,17 @@ end
cancel(c::GCancellable) = G_.cancel(c)
iscancelled(c::GCancellable) = G_.is_cancelled(c)

"""
cancel_after_delay(timeout)
Creates and returns a `GCancellable` and after `timeout` seconds, cancels it.
"""
function cancel_after_delay(timeout)
cancellable = GCancellable()
if timeout > 0
Timer(timeout) do timer
cancel(cancellable)
end
end
cancellable
end
2 changes: 1 addition & 1 deletion src/Gdk4.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ keyval(name::AbstractString) = G_.keyval_from_name(name)

function GdkRGBA(r,g,b,a = 1.0)
s=_GdkRGBA(r,g,b,a)
r=ccall((:gdk_rgba_copy, libgtk4), Ptr{GdkRGBA}, (Ptr{_GdkRGBA},), Ref(s))
r=ccall((:gdk_rgba_copy, libgtk4), Ptr{_GdkRGBA}, (Ptr{_GdkRGBA},), Ref(s))
GdkRGBA(r)
end

Expand Down
47 changes: 44 additions & 3 deletions src/deprecated.jl
Original file line number Diff line number Diff line change
@@ -1,6 +1,47 @@
GtkAdjustment(spinButton::GtkSpinButton) = G_.get_adjustment(spinButton)
GtkAdjustment(range::GtkRange) = G_.get_adjustment(range)
GtkAdjustment(scale::GtkScaleButton) = G_.get_adjustment(scale)
@deprecate GtkAdjustment(spinButton::GtkSpinButton) adjustment(spinButton::GtkSpinButton)
@deprecate GtkAdjustment(range::GtkRange) adjustment(range::GtkRange)
@deprecate GtkAdjustment(scale::GtkScaleButton) adjustment(scale::GtkScaleButton)

setindex!(buffer::GtkEntryBuffer, content::String, ::Type{String}) =
G_.set_text(buffer, content, -1)

## GtkDialog

function push!(d::GtkDialog, s::AbstractString, response)
G_.add_button(d, s, Int32(response))
d
end

function response(widget::GtkDialog, response_id)
G_.response(widget, Int32(response_id))
end

function GtkDialog(title::AbstractString, buttons, flags, parent = nothing; kwargs...)
parent = (parent === nothing ? C_NULL : parent)
w = GtkDialogLeaf(ccall((:gtk_dialog_new_with_buttons, libgtk4), Ptr{GObject},
(Ptr{UInt8}, Ptr{GObject}, Cint, Ptr{Nothing}),
title, parent, flags, C_NULL))
GLib.setproperties!(w; kwargs...)
for (k, v) in buttons
push!(w, k, v)
end
w
end

function GtkMessageDialog(message::AbstractString, buttons, flags, typ, parent = nothing; kwargs...)
parent = (parent === nothing ? C_NULL : parent)
w = GtkMessageDialogLeaf(ccall((:gtk_message_dialog_new, libgtk4), Ptr{GObject},
(Ptr{GObject}, Cuint, Cint, Cint, Ptr{UInt8}),
parent, flags, typ, ButtonsType_NONE, message))
GLib.setproperties!(w; kwargs...)
for (k, v) in buttons
push!(w, k, v)
end
w
end

warn_dialog(callback::Function, message::AbstractString, parent = nothing; timeout = -1) = info_dialog(callback, message, parent; timeout = -1)
error_dialog(callback::Function, message::AbstractString, parent = nothing; timeout = -1) = info_dialog(callback, message, parent; timeout = -1)

@deprecate warn_dialog info_dialog
@deprecate error_dialog info_dialog
26 changes: 18 additions & 8 deletions src/gen/cairo_structs
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ $(Expr(:toplevel, quote
(GLib.g_type(::Type{T}) where T <: cairoRectangle) = begin
ccall(("cairo_gobject_rectangle_get_type", libcairo_gobject), GType, ())
end
function cairoRectangle(ref::Ptr{T}, own::Bool = false) where T <: GBoxed
function cairoRectangle(ref::Ptr{T}, own::Bool = false) where T <: Union{GBoxed, _cairoRectangle}
x = new(ref)
if own
finalizer(x) do x
Expand All @@ -176,9 +176,14 @@ $(Expr(:toplevel, quote
push!(gboxed_types, cairoRectangle)
end
end
unsafe_convert(::Type{Ptr{_cairoRectangle}}, box::cairoRectangle) = begin
convert(Ptr{_cairoRectangle}, box.handle)
end
begin
unsafe_convert(::Type{Ptr{_cairoRectangle}}, box::cairoRectangle) = begin
convert(Ptr{_cairoRectangle}, box.handle)
end
convert(::Type{cairoRectangle}, p::Ptr{_cairoRectangle}, owns = false) = begin
cairoRectangle(p, owns)
end
end
end
begin
struct _cairoRectangleInt
Expand All @@ -193,7 +198,7 @@ $(Expr(:toplevel, quote
(GLib.g_type(::Type{T}) where T <: cairoRectangleInt) = begin
ccall(("cairo_gobject_rectangle_int_get_type", libcairo_gobject), GType, ())
end
function cairoRectangleInt(ref::Ptr{T}, own::Bool = false) where T <: GBoxed
function cairoRectangleInt(ref::Ptr{T}, own::Bool = false) where T <: Union{GBoxed, _cairoRectangleInt}
x = new(ref)
if own
finalizer(x) do x
Expand All @@ -205,9 +210,14 @@ $(Expr(:toplevel, quote
push!(gboxed_types, cairoRectangleInt)
end
end
unsafe_convert(::Type{Ptr{_cairoRectangleInt}}, box::cairoRectangleInt) = begin
convert(Ptr{_cairoRectangleInt}, box.handle)
end
begin
unsafe_convert(::Type{Ptr{_cairoRectangleInt}}, box::cairoRectangleInt) = begin
convert(Ptr{_cairoRectangleInt}, box.handle)
end
convert(::Type{cairoRectangleInt}, p::Ptr{_cairoRectangleInt}, owns = false) = begin
cairoRectangleInt(p, owns)
end
end
end
gboxed_cache_init() = begin
append!(GLib.gboxed_types, gboxed_types)
Expand Down
37 changes: 26 additions & 11 deletions src/gen/gdk4_structs
Original file line number Diff line number Diff line change
Expand Up @@ -103,9 +103,14 @@ $(Expr(:toplevel, quote
mutable struct GdkKeymapKey
handle::Ptr{_GdkKeymapKey}
end
unsafe_convert(::Type{Ptr{_GdkKeymapKey}}, box::GdkKeymapKey) = begin
convert(Ptr{_GdkKeymapKey}, box.handle)
end
begin
unsafe_convert(::Type{Ptr{_GdkKeymapKey}}, box::GdkKeymapKey) = begin
convert(Ptr{_GdkKeymapKey}, box.handle)
end
convert(::Type{GdkKeymapKey}, p::Ptr{_GdkKeymapKey}, owns = false) = begin
GdkKeymapKey(p, owns)
end
end
end
mutable struct GdkPopupLayout <: GBoxed
handle::Ptr{GdkPopupLayout}
Expand Down Expand Up @@ -138,7 +143,7 @@ $(Expr(:toplevel, quote
(GLib.g_type(::Type{T}) where T <: GdkRGBA) = begin
ccall(("gdk_rgba_get_type", libgtk4), GType, ())
end
function GdkRGBA(ref::Ptr{T}, own::Bool = false) where T <: GBoxed
function GdkRGBA(ref::Ptr{T}, own::Bool = false) where T <: Union{GBoxed, _GdkRGBA}
x = new(ref)
if own
finalizer(x) do x
Expand All @@ -150,9 +155,14 @@ $(Expr(:toplevel, quote
push!(gboxed_types, GdkRGBA)
end
end
unsafe_convert(::Type{Ptr{_GdkRGBA}}, box::GdkRGBA) = begin
convert(Ptr{_GdkRGBA}, box.handle)
end
begin
unsafe_convert(::Type{Ptr{_GdkRGBA}}, box::GdkRGBA) = begin
convert(Ptr{_GdkRGBA}, box.handle)
end
convert(::Type{GdkRGBA}, p::Ptr{_GdkRGBA}, owns = false) = begin
GdkRGBA(p, owns)
end
end
end
begin
struct _GdkRectangle
Expand All @@ -167,7 +177,7 @@ $(Expr(:toplevel, quote
(GLib.g_type(::Type{T}) where T <: GdkRectangle) = begin
ccall(("gdk_rectangle_get_type", libgtk4), GType, ())
end
function GdkRectangle(ref::Ptr{T}, own::Bool = false) where T <: GBoxed
function GdkRectangle(ref::Ptr{T}, own::Bool = false) where T <: Union{GBoxed, _GdkRectangle}
x = new(ref)
if own
finalizer(x) do x
Expand All @@ -179,9 +189,14 @@ $(Expr(:toplevel, quote
push!(gboxed_types, GdkRectangle)
end
end
unsafe_convert(::Type{Ptr{_GdkRectangle}}, box::GdkRectangle) = begin
convert(Ptr{_GdkRectangle}, box.handle)
end
begin
unsafe_convert(::Type{Ptr{_GdkRectangle}}, box::GdkRectangle) = begin
convert(Ptr{_GdkRectangle}, box.handle)
end
convert(::Type{GdkRectangle}, p::Ptr{_GdkRectangle}, owns = false) = begin
GdkRectangle(p, owns)
end
end
end
mutable struct GdkTextureDownloader <: GBoxed
handle::Ptr{GdkTextureDownloader}
Expand Down
24 changes: 17 additions & 7 deletions src/gen/gdkpixbuf_structs
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,14 @@ $(Expr(:toplevel, quote
mutable struct GdkPixbufModulePattern
handle::Ptr{_GdkPixbufModulePattern}
end
unsafe_convert(::Type{Ptr{_GdkPixbufModulePattern}}, box::GdkPixbufModulePattern) = begin
convert(Ptr{_GdkPixbufModulePattern}, box.handle)
end
begin
unsafe_convert(::Type{Ptr{_GdkPixbufModulePattern}}, box::GdkPixbufModulePattern) = begin
convert(Ptr{_GdkPixbufModulePattern}, box.handle)
end
convert(::Type{GdkPixbufModulePattern}, p::Ptr{_GdkPixbufModulePattern}, owns = false) = begin
GdkPixbufModulePattern(p, owns)
end
end
end
begin
struct _GdkPixbufFormat
Expand All @@ -32,7 +37,7 @@ $(Expr(:toplevel, quote
(GLib.g_type(::Type{T}) where T <: GdkPixbufFormat) = begin
ccall(("gdk_pixbuf_format_get_type", libgdkpixbuf), GType, ())
end
function GdkPixbufFormat(ref::Ptr{T}, own::Bool = false) where T <: GBoxed
function GdkPixbufFormat(ref::Ptr{T}, own::Bool = false) where T <: Union{GBoxed, _GdkPixbufFormat}
x = new(ref)
if own
finalizer(x) do x
Expand All @@ -44,9 +49,14 @@ $(Expr(:toplevel, quote
push!(gboxed_types, GdkPixbufFormat)
end
end
unsafe_convert(::Type{Ptr{_GdkPixbufFormat}}, box::GdkPixbufFormat) = begin
convert(Ptr{_GdkPixbufFormat}, box.handle)
end
begin
unsafe_convert(::Type{Ptr{_GdkPixbufFormat}}, box::GdkPixbufFormat) = begin
convert(Ptr{_GdkPixbufFormat}, box.handle)
end
convert(::Type{GdkPixbufFormat}, p::Ptr{_GdkPixbufFormat}, owns = false) = begin
GdkPixbufFormat(p, owns)
end
end
end
gboxed_cache_init() = begin
append!(GLib.gboxed_types, gboxed_types)
Expand Down
Loading
Loading