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 = """My Bold text\n GTK+ website""" 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