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

add highlevel gui + auto legend/colorbar #3491

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ FreeType = "b38be410-82b0-50bf-ab77-7b57e271db43"
FreeTypeAbstraction = "663a7486-cb36-511b-a19d-713bb74d65c9"
GeometryBasics = "5c1252a2-5f33-56bf-86c9-59e7332b4326"
GridLayoutBase = "3955a311-db13-416c-9275-1d80ed98e5e9"
ImageClipboard = "6db54171-f50f-4661-a74f-bc514ef16cee"
ImageIO = "82e4d734-157c-48bb-816b-45c225c6df19"
InteractiveUtils = "b77e0a4c-d291-57a0-90e8-8db25a27a240"
IntervalSets = "8197267c-284f-5f27-9208-e0e47529a953"
Expand All @@ -36,6 +37,7 @@ MacroTools = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09"
MakieCore = "20f20a25-4f0e-4fdf-b5d1-57303727442b"
Markdown = "d6f4376e-aef5-505a-96c1-9c027394607a"
MathTeXEngine = "0a4f8689-d25c-4efe-a92b-7142dfc1aa53"
NativeFileDialog_jll = "94d9ae2c-efc7-56f8-9a02-54c47b797961"
Observables = "510215fc-4207-5dde-b226-833fc4488ee2"
OffsetArrays = "6fe1bfb0-de20-5000-8ca7-80f57d26f881"
Packing = "19eb6ba3-879d-56ad-ad62-d5c202156566"
Expand Down
31 changes: 31 additions & 0 deletions src/GUI/file-dialogue.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
using NativeFileDialog_jll

function choose_file_dialogue(filter=C_NULL)
path = Ref(Ptr{UInt8}())
r = @ccall libnfd.NFD_OpenDialog(filter::Ptr{Cchar}, C_NULL::Ptr{Cchar},
path::Ref{Ptr{UInt8}})::Cint
if r == 2
# User clicked "Cancel"
out = nothing
elseif r == 1
out = unsafe_string(path[])
else
error()
end
return out
end

function save_file_dialogue(filter=C_NULL)
path = Ref(Ptr{UInt8}())
r = @ccall libnfd.NFD_SaveDialog(filter::Ptr{Cchar}, C_NULL::Ptr{Cchar},
path::Ref{Ptr{UInt8}})::Cint
if r == 2
# User clicked "Cancel"
out = nothing
elseif r == 1
out = unsafe_string(path[])
else
error()
end
return out
end
98 changes: 98 additions & 0 deletions src/GUI/gui.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
using ImageClipboard

include("file-dialogue.jl")

function set_vis!(scene::Scene, v::Bool)
return scene.visible[] = v
end

function set_vis!(block::Makie.Block, v::Bool)
set_vis!(block.blockscene, v)
return foreach(s -> set_vis!(s, v), block.blockscene.children)
end

function hoverbar(f, ax)
gl = GridLayout(f[:, :]; tellwidth=false, tellheight=false, halign=:center, valign=:top)
visible = Observable(false)
box = gl[1, 1:3] = Box(f; height=45, width=200, color=(:white, 0.7), cornerradius=5)
bstyle = (buttoncolor="gray", labelcolor=:white, font=:bold, fontsize=13)
bsave = gl[1, 1] = Button(f; label="save", bstyle...)
bcopy = gl[1, 2] = Button(f; label="copy", bstyle...)
breset = gl[1, 3] = Button(f; label="↻", width=50, bstyle...)
on(f.scene, visible; update=true) do v
set_vis!(box, v)
set_vis!(bsave, v)
set_vis!(bcopy, v)
return set_vis!(breset, v)
end
on(f.scene, breset.clicks) do _
visible[] = false
return reset_limits!(ax)
end
on(f.scene, bsave.clicks) do _
visible[] = false
file = save_file_dialogue()
if !isnothing(file)
save(file, f; update=false)
end
end
on(f.scene, bcopy.clicks) do _
visible[] = false
img = colorbuffer(f; update=false)
return ImageClipboard.clipboard_img(img)
end
on(f.scene, f.scene.events.mouseposition) do mp
vp = f.scene.viewport[]
rect = Rect2f(0, widths(vp)[2] - 70, widths(vp)[1], 70)
if mp in rect
visible[] = true
else
visible[] = false
end
end
return
end

"""
GUI(faxpl::Makie.FigureAxisPlot; legend=(;), colorbar=(;))

Automatically creates a legend and colorbar for the return value of `plot`.
Also adds a small UI to save/reset/copy the plot.
# Example

```julia
f, ax, pl = GUI(series(rand(7, 20)); legend=(position=:lt, title="legend"))
```
"""
function GUI(faxpl::Makie.FigureAxisPlot; legend=(;), colorbar=(;))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we also add a method which accepts a figure, so people can "opt-in" to displaying their figures (or maybe even Scenes) in this GUI by default, perhaps by setting a switch in activate!?

f, ax, plot = faxpl
hoverbar(f, ax)
if legend isa NamedTuple
plots, labels = Makie.get_labeled_plots(ax; unique=get(legend, :unique, false),
merge=get(legend, :merge, false))
if !isempty(plots)
title = get(legend, :title, nothing)
bbox = ax.scene.viewport
margin = get(legend, :margin, (6, 6, 6, 6))
position = get(legend, :position, :rt)
pos_kw = Makie.legend_position_to_aligns(position)
Legend(ax.parent, plots, labels, title; margin=margin, bbox=bbox, legend..., pos_kw...)
end
elseif !(legend isa Bool && legend == false)
error("legend must be a NamedTuple with attributes passed to `axislegend` or false to disable automatic legend creation")
end

if colorbar isa NamedTuple
try
cmap = Makie.extract_colormap_recursive(plot)
if !isnothing(cmap)
Colorbar(f[1, 2]; colormap=cmap, colorbar...)
end
catch e

end
elseif !(colorbar isa Bool && colorbar == false)
error("legend must be a NamedTuple with attributes passed to `axislegend` or false to disable automatic legend creation")
end
return faxpl
end
3 changes: 3 additions & 0 deletions src/Makie.jl
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,9 @@ include("display.jl")
include("ffmpeg-util.jl")
include("recording.jl")
include("event-recorder.jl")
include("GUI/gui.jl")

export GUI

# bezier paths
export BezierPath, MoveTo, LineTo, CurveTo, EllipticalArc, ClosePath
Expand Down
Loading