playground/julia/gtk_example.jl
Rick Sprague 9877b0d451 julia
2024-10-28 10:02:43 -04:00

303 lines
6.9 KiB
Julia

using Gtk, Distributed
function glade(win)
showall(win)
if !isinteractive()
c = Condition()
signal_connect(win, :destroy) do widget
notify(c)
end
@async Gtk.gtk_main()
wait(c)
end
end
function window(f)
win = GtkWindow("My First Gtk.jl program", 400, 200)
v = f(win)
if v != nothing
push!(win, v)
end
showall(win)
if !isinteractive()
c = Condition()
signal_connect(win, :destroy) do widget
notify(c)
end
@async Gtk.gtk_main()
wait(c)
end
end
@enum ToShow begin
Button
Label
Label_Accessor
Label_Markup
Entry
ComboBox
List
Tree
File_Dialog
Message_Dialog
Key_Event
Canvas
Sliders
Async
Async2
Glade
end
const start_times = Dict{UInt32, UInt32}()
target = Async2
target == Button && window() do
button = GtkButton("Click me")
signal_connect(button, "clicked") do widget
println("The button has been clicked")
end
return button
end
target == Label && window() do win
return GtkLabel("My Text")
end
target == Label_Accessor && window() do win
label = GtkLabel("My Text")
GAccessor.text(label, "My other text")
return label
end
target == Label_Markup && window() do win
label = GtkLabel("My Text")
format = """<b>My Bold text</b>\n
<a href=\"https://www.gtk.org\"
title=\"Our website\">GTK+ website</a>"""
GAccessor.markup(label, format)
GAccessor.selectable(label, true)
GAccessor.justify(label, Gtk.GConstants.GtkJustification.RIGHT)
return label
end
target == Entry && window() do win
entry = GtkEntry()
set_gtk_property!(entry, :text, "My String")
#str = get_gtk_property(entry, :text, String)
return entry
end
target == ComboBox && window() do win
cb = GtkComboBoxText()
choices = ["one", "two", "three", "four"]
for c in choices
push!(cb, c)
end
set_gtk_property!(cb, :active, 1)
signal_connect(cb, "changed") do width, others...
idx = get_gtk_property(cb, "active", Int)
str = Gtk.bytestring(GAccessor.active_text(cb))
println("Active element is \"$str\" at index $idx")
end
return cb
end
target == List && window() do win
ls = GtkListStore(String, Int, Bool, Bool)
push!(ls, ("Peter", 20, false, true))
push!(ls, ("Paul", 30, false, true))
push!(ls, ("Mary", 25, true, true))
push!(ls, ("Susanne", 35, true, true))
tmFiltered = GtkTreeModelFilter(ls)
GAccessor.visible_column(tmFiltered, 3)
tv = GtkTreeView(GtkTreeModel(tmFiltered))
rTxt = GtkCellRendererText()
rTog = GtkCellRendererToggle()
c1 = GtkTreeViewColumn("Name", rTxt, Dict([("text", 0)]))
c2 = GtkTreeViewColumn("Age", rTxt, Dict([("text", 1)]))
c3 = GtkTreeViewColumn("Female", rTog, Dict([("active", 2)]))
for (i, c) in enumerate([c1, c2, c3])
GAccessor.resizable(c, true)
GAccessor.sort_column_id(c, i-1)
GAccessor.reorderable(c, i)
end
selection = GAccessor.selection(tv)
# selection = GAccessor.mode(selection, Gtk.GConstants.GtkSelectionMode.MULTIPLE)
signal_connect(selection, "changed") do widget
if hasselection(selection)
currentIt = selected(selection)
#println("Name: ", ls[currentIt, 1], " Age: ", ls[currentIt, 2])
println("Name: ", GtkTreeModel(tmFiltered)[currentIt, 1],
"Age: ", GtkTreeModel(tmFiltered)[currentIt, 2])
end
end
push!(tv, c1, c2, c3)
entry = GtkEntry()
signal_connect(entry, "changed") do widget
searchText = get_gtk_property(entry, :text, String)
for l=1:length(ls)
showMe = true
if length(searchText) > 0
showMe = showMe && occursin(lowercase(searchText), lowercase(ls[l, 1]))
end
ls[l, 4] = showMe
end
end
vbox = GtkBox(:v)
push!(vbox, entry, tv)
return vbox
end
target == Tree && window() do win
ts = GtkTreeStore(String)
iter1 = push!(ts, ("one", ))
iter2 = push!(ts, ("two", ), iter1)
iter3 = push!(ts, ("three", ), iter2)
tv = GtkTreeView(GtkTreeModel(ts))
r1 = GtkCellRendererText()
c1 = GtkTreeViewColumn("A", r1, Dict([("text", 0)]))
push!(tv, c1)
return tv
end
target == File_Dialog && begin
result = open_dialog("Pick some files", GtkNullContainer(), ["*.jl, *.csv"], select_multiple=true)
println(result)
end
target == Message_Dialog && begin
info_dialog("Julia Rocks!")
end
target == Key_Event && window() do win
signal_connect(win, "key-press-event") do widget, event
k = event.keyval
if !(k in keys(start_times))
start_times[k] = event.time
println("You pressed key ", k, " which is '", Char(k), "'.")
else
println("repeating key ", k)
end
end
signal_connect(win, "key-release-event") do widget, event
k = event.keyval
start_time = pop!(start_times, k)
duration = event.time - start_time
println("You released key ", k, " after time ", duration, " msec.")
end
nothing
end
target == Canvas && window() do win
c = @GtkCanvas()
@guarded draw(c) do widget
ctx = getgc(c)
h = height(c)
w = width(c)
rectangle(ctx, 0, 0, w, h/2)
set_source_rgb(ctx, 1, 0, 0)
fill(ctx)
rectangle(ctx, 0, 3h/4, w, h/4)
set_source_rgb(ctx, 0, 0, 1)
fill(ctx)
end
c.mouse.button1press = @guarded (widget, event) -> begin
ctx = getgc(widget)
set_source_rgb(ctx, 0, 1, 0)
arc(ctx, event.x, event.y, 5, 0, 2pi)
stroke(ctx)
reveal(widget)
end
return c
end
target == Sliders && window() do win
slider1 = GtkScale(false, 0:10)
slider2 = GtkScale(false, 0:30)
signal_connect(slider1, "value-changed") do widget, others...
value = GAccessor.value(slider1)
GAccessor.value(slider2, value)
println("slider value is $value")
if value == 10
GAccessor.range(slider1, 1, 20)
end
end
g = GtkGrid()
g[1,1] = slider1
g[1,2] = slider2
set_gtk_property!(g, :column_homogeneous, true)
return g
end
target == Async && window() do win
btn = GtkButton("Start")
sp = GtkSpinner()
ent = GtkEntry()
grid = GtkGrid()
grid[1,1] = btn
grid[2,1] = sp
grid[1:2,2] = ent
signal_connect(btn, "clicked") do widget
start(sp)
Threads.@spawn begin
stop_time = time() + 3
counter = 0
while time() < stop_time
counter += 1
end
# Interacting with GTK from a thread other than the main thread is
# generally not allowed, so we register an idle callback instead.
Gtk.GLib.g_idle_add(nothing) do user_data
stop(sp)
set_gtk_property!(ent, :text, "I counted to $counter in a thread!")
Cint(false)
end
end
end
return grid
end
target == Async2 && window() do win
btn = GtkButton("Start")
sp = GtkSpinner()
ent = GtkEntry()
grid = GtkGrid()
grid[1,1]=btn
grid[2,1]=sp
grid[1:2,2] = ent
id = addprocs(1)[1]
signal_connect(btn, "clicked") do widget
start(sp)
@async begin
counter = @fetchfrom id begin
stop_time = time() + 3
counter = 0
while time() < stop_time
counter += 1
end
counter
end
# We are still in the main thread so it is okay to directly access widgets
stop(sp)
set_gtk_property!(ent, :text, "I counted to $counter in a separate process!")
end
end
return grid
end
target == Glade && begin
g = GtkBuilder(filename="interface.glade")
# g = GtkBuilder(buffer=myapp) # if pointing to string
win = g["window1"]
signal_connect(g["button1"], "clicked") do widget
println("The button has been clicked")
end
glade(win)
end