From 78f55971e6369db9f695479e286081cbc780d6e7 Mon Sep 17 00:00:00 2001 From: Simon Date: Thu, 12 Dec 2024 12:18:30 +0100 Subject: [PATCH 1/2] Allow for user defined recipes to be used in SpecApi (#4655) * Allow for user defined recipes to be used in SpecApi * Update CHANGELOG.md * allow external blocks as well * add basic tests for specapi with external recipes * fix test --------- Co-authored-by: Anshul Singhvi --- CHANGELOG.md | 2 ++ MakieCore/src/recipes.jl | 9 +++++++++ src/makielayout/blocks.jl | 17 ++++++++++------- src/specapi.jl | 18 ++++++++---------- test/specapi.jl | 11 ++++++++++- 5 files changed, 39 insertions(+), 18 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f883599a4ac..57e6db7cfad 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## [Unreleased] +- Allow for user defined recipes to be used in SpecApi [#4655](https://github.com/MakieOrg/Makie.jl/pull/4655). + ## [0.21.17] - 2024-12-05 - Added `backend` and `update` kwargs to `show` [#4558](https://github.com/MakieOrg/Makie.jl/pull/4558) diff --git a/MakieCore/src/recipes.jl b/MakieCore/src/recipes.jl index d20636519d4..8f396c12538 100644 --- a/MakieCore/src/recipes.jl +++ b/MakieCore/src/recipes.jl @@ -21,6 +21,12 @@ function plotfunc(f::Function) end end +symbol_to_plot(x::Symbol) = symbol_to_plot(Val(x)) +function symbol_to_plot(::Val{Sym}) where {Sym} + return nothing +end + + function plotfunc!(x) F = plotfunc(x)::Function name = Symbol(nameof(F), :!) @@ -188,6 +194,7 @@ macro recipe(theme_func, Tsym::Symbol, args::Symbol...) Core.@__doc__ ($funcname)(args...; kw...) = _create_plot($funcname, Dict{Symbol, Any}(kw), args...) ($funcname!)(args...; kw...) = _create_plot!($funcname, Dict{Symbol, Any}(kw), args...) $(MakieCore).default_theme(scene, ::Type{<:$PlotType}) = $(esc(theme_func))(scene) + $(MakieCore).symbol_to_plot(::Val{$(QuoteNode(Tsym))}) = $PlotType export $PlotType, $funcname, $funcname! end if !isempty(args) @@ -496,6 +503,8 @@ function create_recipe_expr(Tsym, args, attrblock) $(MakieCore).documented_attributes(::Type{<:$(PlotType)}) = $attr_placeholder $(MakieCore).plotsym(::Type{<:$(PlotType)}) = $(QuoteNode(Tsym)) + $(MakieCore).symbol_to_plot(::Val{$(QuoteNode(Tsym))}) = $PlotType + function ($funcname)(args...; kw...) kwdict = Dict{Symbol, Any}(kw) _create_plot($funcname, kwdict, args...) diff --git a/src/makielayout/blocks.jl b/src/makielayout/blocks.jl index d90f2921731..b37780777e8 100644 --- a/src/makielayout/blocks.jl +++ b/src/makielayout/blocks.jl @@ -6,6 +6,9 @@ function attribute_default_expressions end function _attribute_docs end function has_forwarded_layout end +symbol_to_block(symbol::Symbol) = symbol_to_block(Val(symbol)) +symbol_to_block(::Val) = nothing + macro Block(_name::Union{Expr, Symbol}, body::Expr = Expr(:block)) body.head === :block || error("A Block needs to be defined within a `begin end` block") @@ -78,18 +81,18 @@ macro Block(_name::Union{Expr, Symbol}, body::Expr = Expr(:block)) $structdef export $name - - function Makie.is_attribute(::Type{$(name)}, sym::Symbol) + $(Makie).symbol_to_block(::Val{$(QuoteNode(name))}) = $name + function $(Makie).is_attribute(::Type{$(name)}, sym::Symbol) sym in ($((attrs !== nothing ? [QuoteNode(a.symbol) for a in attrs] : [])...),) end - function Makie.default_attribute_values(::Type{$(name)}, scene::Union{Scene, Nothing}) + function $(Makie).default_attribute_values(::Type{$(name)}, scene::Union{Scene, Nothing}) sceneattrs = scene === nothing ? Attributes() : theme(scene) - curdeftheme = Makie.fast_deepcopy($(Makie).CURRENT_DEFAULT_THEME) + curdeftheme = $(Makie).fast_deepcopy($(Makie).CURRENT_DEFAULT_THEME) $(make_attr_dict_expr(attrs, :sceneattrs, :curdeftheme)) end - function Makie.attribute_default_expressions(::Type{$name}) + function $(Makie).attribute_default_expressions(::Type{$name}) $( if attrs === nothing Dict{Symbol, String}() @@ -99,7 +102,7 @@ macro Block(_name::Union{Expr, Symbol}, body::Expr = Expr(:block)) ) end - function Makie._attribute_docs(::Type{$(name)}) + function $(Makie)._attribute_docs(::Type{$(name)}) Dict( $( (attrs !== nothing ? @@ -109,7 +112,7 @@ macro Block(_name::Union{Expr, Symbol}, body::Expr = Expr(:block)) ) end - Makie.has_forwarded_layout(::Type{$name}) = $has_forwarded_layout + $(Makie).has_forwarded_layout(::Type{$name}) = $has_forwarded_layout docstring_modified = make_block_docstring($name, user_docstring) @doc docstring_modified $name diff --git a/src/specapi.jl b/src/specapi.jl index 45e81923489..1a334abad17 100644 --- a/src/specapi.jl +++ b/src/specapi.jl @@ -3,12 +3,10 @@ using GridLayoutBase: GridLayoutBase import GridLayoutBase: GridPosition, Side, ContentSize, GapSize, AlignMode, Inner, GridLayout, GridSubposition -function get_recipe_function(name::Symbol) - if hasproperty(Makie, name) - return getfield(Makie, name) - else - return nothing - end +function symbol_to_specable(sym::Symbol) + block = symbol_to_block(sym) + isnothing(block) || return block + return MakieCore.symbol_to_plot(sym) end """ @@ -27,7 +25,7 @@ struct PlotSpec error("PlotSpec objects are supposed to be used without !, unless when using `S.$(type)(axis::P.Axis, args...; kwargs...)`") end if !isuppercase(type_str[1]) - func = get_recipe_function(type) + func = hasproperty(Makie, type) ? getproperty(Makie, type) : nothing func === nothing && error("PlotSpec need to be existing recipes or Makie plot objects. Found: $(type_str)") plot_type = Plot{func} type = plotsym(plot_type) @@ -169,7 +167,7 @@ function to_plotspec(::Type{P}, p::PlotSpec; kwargs...) where {P} return PlotSpec(plotsym(plottype(P, S)), p.args...; p.kwargs..., kwargs...) end -plottype(p::PlotSpec) = getfield(Makie, p.type) +plottype(p::PlotSpec) = MakieCore.symbol_to_plot(p.type) function Base.show(io::IO, ::MIME"text/plain", spec::PlotSpec) args = join(map(x -> string("::", typeof(x)), spec.args), ", ") @@ -403,7 +401,7 @@ function Base.getproperty(::_SpecApi, field::Symbol) # Since precompilation will cache only MakieCore's state # And once everything is compiled, and MakieCore is loaded into a package # The names are loaded from cache and dont contain anything after MakieCore. - func = get_recipe_function(field) + func = symbol_to_specable(field) if isnothing(func) error("$(field) neither a recipe, Makie plotting object or a Block (like Axis, Legend, etc).") elseif func isa Function @@ -744,7 +742,7 @@ function extract_colorbar_kw(legend::BlockSpec, scene::Scene) end function to_layoutable(parent, position::GridLayoutPosition, spec::BlockSpec) - BType = getfield(Makie, spec.type) + BType = symbol_to_block(spec.type) fig = get_top_parent(parent) block = if spec.type === :Colorbar diff --git a/test/specapi.jl b/test/specapi.jl index 9c0a6f23ac4..7f1393756fb 100644 --- a/test/specapi.jl +++ b/test/specapi.jl @@ -181,9 +181,18 @@ end # This is too internal and fragile, so we won't actually test this # @test leg.scene.plots[2].marker[] == :circle # @test leg.scene.plots[3].marker[] == :rect - + # Test that the legend has the correct labels. # Again, I consider this too fragile to work with! # @test contents(contents(leg.grid)[1])[2].text[] == "A" # @test contents(contents(leg.grid)[2])[4].text[] == "B" end + +@recipe(TestRecipeForSpecApi) do scene + return Attributes() +end + +@testset "External Recipe compatibility (#4295)" begin + @test_nowarn S.TestRecipeForSpecApi + @test_nowarn S.TestRecipeForSpecApi(1, 2, 3; a = 4, b = 5) +end From d9e786fa9eb0c491dd40f3005afb01ba63525d00 Mon Sep 17 00:00:00 2001 From: Simon Date: Thu, 12 Dec 2024 15:55:58 +0100 Subject: [PATCH 2/2] tag v0.21.18 (#4659) * tag v0.21.18 * update changelog --- CHANGELOG.md | 5 ++++- CairoMakie/Project.toml | 4 ++-- GLMakie/Project.toml | 4 ++-- MakieCore/Project.toml | 2 +- Project.toml | 4 ++-- RPRMakie/Project.toml | 4 ++-- WGLMakie/Project.toml | 4 ++-- 7 files changed, 15 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 57e6db7cfad..23ef8ff1b13 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## [Unreleased] +## [0.21.18] - 2024-12-12 + - Allow for user defined recipes to be used in SpecApi [#4655](https://github.com/MakieOrg/Makie.jl/pull/4655). ## [0.21.17] - 2024-12-05 @@ -685,7 +687,8 @@ All other changes are collected [in this PR](https://github.com/MakieOrg/Makie.j - Fixed rendering of `heatmap`s with one or more reversed ranges in CairoMakie, as in `heatmap(1:10, 10:-1:1, rand(10, 10))` [#1100](https://github.com/MakieOrg/Makie.jl/pull/1100). - Fixed volume slice recipe and added docs for it [#1123](https://github.com/MakieOrg/Makie.jl/pull/1123). -[Unreleased]: https://github.com/MakieOrg/Makie.jl/compare/v0.21.17...HEAD +[Unreleased]: https://github.com/MakieOrg/Makie.jl/compare/v0.21.18...HEAD +[0.21.18]: https://github.com/MakieOrg/Makie.jl/compare/v0.21.17...v0.21.18 [0.21.17]: https://github.com/MakieOrg/Makie.jl/compare/v0.21.16...v0.21.17 [0.21.16]: https://github.com/MakieOrg/Makie.jl/compare/v0.21.15...v0.21.16 [0.21.15]: https://github.com/MakieOrg/Makie.jl/compare/v0.21.14...v0.21.15 diff --git a/CairoMakie/Project.toml b/CairoMakie/Project.toml index 3fecb9283be..b4613bd481d 100644 --- a/CairoMakie/Project.toml +++ b/CairoMakie/Project.toml @@ -1,7 +1,7 @@ name = "CairoMakie" uuid = "13f3f980-e62b-5c42-98c6-ff1f3baf88f0" author = ["Simon Danisch "] -version = "0.12.17" +version = "0.12.18" [deps] CRC32c = "8bf52ea8-c179-5cab-976a-9e18b702a9bc" @@ -24,7 +24,7 @@ FileIO = "1.1" FreeType = "3, 4.0" GeometryBasics = "0.4.11" LinearAlgebra = "1.0, 1.6" -Makie = "=0.21.17" +Makie = "=0.21.18" PrecompileTools = "1.0" julia = "1.3" diff --git a/GLMakie/Project.toml b/GLMakie/Project.toml index 65bcde4d964..d293f1b06fb 100644 --- a/GLMakie/Project.toml +++ b/GLMakie/Project.toml @@ -1,6 +1,6 @@ name = "GLMakie" uuid = "e9467ef8-e4e7-5192-8a1a-b1aee30e663a" -version = "0.10.17" +version = "0.10.18" [deps] ColorTypes = "3da002f7-5984-5a60-b8a6-cbb66c0b333f" @@ -30,7 +30,7 @@ FreeTypeAbstraction = "0.10" GLFW = "3.4.3" GeometryBasics = "0.4.11" LinearAlgebra = "1.0, 1.6" -Makie = "=0.21.17" +Makie = "=0.21.18" Markdown = "1.0, 1.6" MeshIO = "0.4" ModernGL = "1" diff --git a/MakieCore/Project.toml b/MakieCore/Project.toml index fb36ccae750..0ec7e4936da 100644 --- a/MakieCore/Project.toml +++ b/MakieCore/Project.toml @@ -1,7 +1,7 @@ name = "MakieCore" uuid = "20f20a25-4f0e-4fdf-b5d1-57303727442b" authors = ["Simon Danisch"] -version = "0.8.11" +version = "0.8.12" [deps] ColorTypes = "3da002f7-5984-5a60-b8a6-cbb66c0b333f" diff --git a/Project.toml b/Project.toml index caefb4ff759..5628baf218b 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "Makie" uuid = "ee78f7c6-11fb-53f2-987a-cfe4a2b5a57a" authors = ["Simon Danisch", "Julius Krumbiegel"] -version = "0.21.17" +version = "0.21.18" [deps] Animations = "27a7e980-b3e6-11e9-2bcd-0b925532e340" @@ -96,7 +96,7 @@ KernelDensity = "0.5, 0.6" LaTeXStrings = "1.2" LinearAlgebra = "1.0, 1.6" MacroTools = "0.5" -MakieCore = "=0.8.11" +MakieCore = "=0.8.12" Markdown = "1.0, 1.6" MathTeXEngine = "0.5, 0.6" Observables = "0.5.5" diff --git a/RPRMakie/Project.toml b/RPRMakie/Project.toml index 4d759d4dc57..1a897c6d9ea 100644 --- a/RPRMakie/Project.toml +++ b/RPRMakie/Project.toml @@ -1,7 +1,7 @@ name = "RPRMakie" uuid = "22d9f318-5e34-4b44-b769-6e3734a732a6" authors = ["Simon Danisch"] -version = "0.7.17" +version = "0.7.18" [deps] Colors = "5ae59095-9a9b-59fe-a467-6f913c188581" @@ -17,7 +17,7 @@ Colors = "0.9, 0.10, 0.11, 0.12, 0.13" FileIO = "1.6" GeometryBasics = "0.4.11" LinearAlgebra = "1.0, 1.6" -Makie = "=0.21.17" +Makie = "=0.21.18" Printf = "1.0, 1.6" RadeonProRender = "0.3.0" julia = "1.3" diff --git a/WGLMakie/Project.toml b/WGLMakie/Project.toml index b9208a8152d..0d8893e94c7 100644 --- a/WGLMakie/Project.toml +++ b/WGLMakie/Project.toml @@ -1,7 +1,7 @@ name = "WGLMakie" uuid = "276b4fcb-3e11-5398-bf8b-a0c2d153d008" authors = ["SimonDanisch "] -version = "0.10.17" +version = "0.10.18" [deps] Bonito = "824d6782-a2ef-11e9-3a09-e5662e0c26f8" @@ -27,7 +27,7 @@ FreeTypeAbstraction = "0.10" GeometryBasics = "0.4.11" Hyperscript = "0.0.3, 0.0.4, 0.0.5" LinearAlgebra = "1.0, 1.6" -Makie = "=0.21.17" +Makie = "=0.21.18" Observables = "0.5.1" PNGFiles = "0.3, 0.4" PrecompileTools = "1.0"