From 9877b0d45117f7f94a117d8da05c80195314b7b5 Mon Sep 17 00:00:00 2001 From: Rick Sprague <> Date: Mon, 28 Oct 2024 10:02:43 -0400 Subject: [PATCH] julia --- julia/genie/GenieFrameworkDemos_NewAPI | 1 + julia/genie/main.jl | 39 ++++ julia/gtk_example.jl | 302 +++++++++++++++++++++++++ julia/interface.glade | 17 ++ julia/main.jl | 5 + julia/packages | 1 + julia/process.jl | 86 +++++++ julia/rick.jld2 | 3 + julia/serialization.jld2 | 3 + julia/tlv_example.jl | 34 +++ 10 files changed, 491 insertions(+) create mode 160000 julia/genie/GenieFrameworkDemos_NewAPI create mode 100644 julia/genie/main.jl create mode 100644 julia/gtk_example.jl create mode 100644 julia/interface.glade create mode 100644 julia/main.jl create mode 160000 julia/packages create mode 100644 julia/process.jl create mode 100644 julia/rick.jld2 create mode 100644 julia/serialization.jld2 create mode 100644 julia/tlv_example.jl diff --git a/julia/genie/GenieFrameworkDemos_NewAPI b/julia/genie/GenieFrameworkDemos_NewAPI new file mode 160000 index 0000000..f95d68f --- /dev/null +++ b/julia/genie/GenieFrameworkDemos_NewAPI @@ -0,0 +1 @@ +Subproject commit f95d68fc99bdd0baddf98c597fbf770a0e2bb28c diff --git a/julia/genie/main.jl b/julia/genie/main.jl new file mode 100644 index 0000000..b0f7194 --- /dev/null +++ b/julia/genie/main.jl @@ -0,0 +1,39 @@ +using GenieFramework + +@genietools + + +@in my_button = false +@in text = "Some text" +@out function1 = jsfunction"""() => console.log("A")""" + +@handlers begin + @onchange text begin + println(text) + end + + @onchange my_button begin + println("pressed") + end +end + +function ui() + c = card([ + card_section("This is a section", class="bg-primary text-white") + separator() + card_section("RR") + card_section("{{ text }}") + ]) + rv = row([ + c + btn("A button", @click("my_button = !my_button")) + btn("A button", @click("function1")) + textfield("What is your name?", :text, placeholder="Type some text") + ]; class="q-gutter-sm") + println(rv |> string) + return rv +end + +@page("/", ui) + +Server.isrunning() || Server.up() diff --git a/julia/gtk_example.jl b/julia/gtk_example.jl new file mode 100644 index 0000000..f780391 --- /dev/null +++ b/julia/gtk_example.jl @@ -0,0 +1,302 @@ +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 + diff --git a/julia/interface.glade b/julia/interface.glade new file mode 100644 index 0000000..3a735a1 --- /dev/null +++ b/julia/interface.glade @@ -0,0 +1,17 @@ + + + + + False + + + button + False + True + True + True + False + + + + diff --git a/julia/main.jl b/julia/main.jl new file mode 100644 index 0000000..8870b88 --- /dev/null +++ b/julia/main.jl @@ -0,0 +1,5 @@ + +z = Dict(1=>10, 2=>20) +for a in z + println(a) +end diff --git a/julia/packages b/julia/packages new file mode 160000 index 0000000..feca907 --- /dev/null +++ b/julia/packages @@ -0,0 +1 @@ +Subproject commit feca90734fc35a6f81c994e72efe0857a6c6b3a3 diff --git a/julia/process.jl b/julia/process.jl new file mode 100644 index 0000000..312a70b --- /dev/null +++ b/julia/process.jl @@ -0,0 +1,86 @@ +#using Gtk + +@Base.kwdef mutable struct Lines + reminant::Union{String, Nothing} = nothing + lines::Vector{String} = String[] +end + +function Base.push!(ls::Lines, s::String) + if ls.reminant != nothing + s = ls.reminant * s + ls.reminant = nothing + end + + lines = split(s, '\n', keepempty=false) + + if s[end] == '\n' + for l in lines + push!(ls.lines, l) + end + return + end + + ls.reminant = String(lines[end]) + for l in lines[1:end - 1] + push!(ls.lines, l) + end +end + +function launch_process(running::Function, cmd::Cmd; start::Function=()->begin end, stop::Function=()->begin end) + Threads.@spawn begin + lines = Lines() + buf = IOBuffer() + process = run(pipeline(ignorestatus(cmd), stdout=buf), wait=false) + start() + while process_running(process) + sleep(1) + push!(lines, String(take!(buf))) + if length(lines.lines) > 0 + running(lines.lines) + empty!(lines.lines) + end + end + stop() + end +end + +launch_process(`./a.out`; start=()->println("Start"), stop=()->println("Stop")) do strings + for s in strings + println("Running: $s") + end +end +sleep(60) +#win = GtkWindow("Hello", 800, 600) +# +#function createMenuBar() +# mb = GtkMenuBar() +# +# # file menu +# begin +# fileMenu = GtkMenuItem("_File") +# fileSub = GtkMenu(fileMenu) +# push!(fileSub, GtkMenuItem("_New")) +# push!(fileSub, GtkMenuItem("_Open")) +# push!(fileSub, GtkSeparatorMenuItem()) +# fileExit = GtkMenuItem("E_xit") +# signal_connect(fileExit, :activate) do widget +# Gtk.destroy(win) +# end +# push!(fileSub, fileExit) +# push!(mb, fileMenu) +# end +# return mb +#end +# +# +#vbox = GtkBox(:v) +#tv = GtkTextView() +#push!(vbox, createMenuBar()) +#push!(vbox, GtkScrolledWindow(tv)) +#push!(win, vbox) +#showall(win) +# +#if !isinteractive() +# @async Gtk.gtk_main() +# Gtk.waitforsignal(win, :destroy) +#end diff --git a/julia/rick.jld2 b/julia/rick.jld2 new file mode 100644 index 0000000..4ec67e9 --- /dev/null +++ b/julia/rick.jld2 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ae94a0300f71329c488c039ecda954b0a77a4416fa0bd9057ab4cd7d1eb59146 +size 810 diff --git a/julia/serialization.jld2 b/julia/serialization.jld2 new file mode 100644 index 0000000..27caeca --- /dev/null +++ b/julia/serialization.jld2 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6f6259a58035300abcfbcdd6faeab9214a4315c23a51ba166af3a43b2c61acf1 +size 843108 diff --git a/julia/tlv_example.jl b/julia/tlv_example.jl new file mode 100644 index 0000000..6c2ef6b --- /dev/null +++ b/julia/tlv_example.jl @@ -0,0 +1,34 @@ +include("packages/TLV.jl") + +#const DATA_DIR = "/data/Data/181283340_06_06_2022_HIGHWAY" +const DATA_DIR = "/data/Data/166543251_10_27_2021_OVAL" + +@time points_east, points_north = TLV.cache("serialization.jld2"; force=false) do + east = [] + north = [] + function callback(header, msg) + pma = msg["s_Data"]["s_PMA_LocalizationPose"] + pose = pma["s_PoseLocation"] + push!(east, pose["e_l_east"]) + push!(north, pose["e_l_north"]) + return false + end + + topics = TLV.log_create_reader_config( + [ + # ["UC_SYSTEM", "GPS_DATA_SERVICE"] + # ["UC_SYSTEM", "PERCEIVED_ROAD_GEOMETRY"] + ["UC_LOC_OUT", "LOC_ASSOCIATED_ROAD_GEOMETRY"] + ] + ) + + TLV.log_read(DATA_DIR, topics, callback) + return east, north +end + + +using Plots +display(scatter(points_east, points_north; title="Oval Track", + legend=false, mc=:blue, ms=.05)) +readline() +#gui()