From 4ff461e07db9f891d424211a00adb6d44dd0a0e4 Mon Sep 17 00:00:00 2001 From: Eddie Groshev Date: Tue, 5 Nov 2024 11:15:33 -0600 Subject: [PATCH] fix: correctly render the tooltip triangle (#4560) * fix: correctly render the tooltip triangle * update changelog * smaller offset * adjust the z value instead * translate outline up by 1 * switch to string_boundingbox * reduce translation and fix render order * extend refimg test * avoid overlap in refimg --------- Co-authored-by: ffreyer --- CHANGELOG.md | 1 + ReferenceTests/src/tests/examples2d.jl | 6 +++ src/basic_recipes/tooltip.jl | 70 +++++++++++++++----------- 3 files changed, 47 insertions(+), 30 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 207f05f34a1..00102a6c500 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## [Unreleased] +- Correctly render the tooltip triangle [#4560](https://github.com/MakieOrg/Makie.jl/pull/4560). - Introduce `isclosed(scene)`, conditionally use `Bonito.LargeUpdate` [#4569](https://github.com/MakieOrg/Makie.jl/pull/4569). - Allow plots to move between scenes in SpecApi [#4132](https://github.com/MakieOrg/Makie.jl/pull/4132). - Added empty constructor to all backends for `Screen` allowing `display(Makie.current_backend().Screen(), fig)` [#4561](https://github.com/MakieOrg/Makie.jl/pull/4561). diff --git a/ReferenceTests/src/tests/examples2d.jl b/ReferenceTests/src/tests/examples2d.jl index 89ef03ce26a..8154d08f9be 100644 --- a/ReferenceTests/src/tests/examples2d.jl +++ b/ReferenceTests/src/tests/examples2d.jl @@ -706,6 +706,12 @@ end outline_linewidth = 5, offset = 30, triangle_size = 15, strokewidth = 2f0, strokecolor = :cyan ) + # Test depth (this part is expected to fail in CairoMakie) + p = tooltip!(ax, -5, -4, "test line\ntest line", backgroundcolor = :lightblue) + translate!(p, 0, 0, 100) + mesh!(ax, + Point3f.([-7, -7, -3, -3], [-4, -2, -4, -2], [99, 99, 101, 101]), [1 2 3; 2 3 4], + shading = NoShading, color = :orange) fig end diff --git a/src/basic_recipes/tooltip.jl b/src/basic_recipes/tooltip.jl index 624073b54ab..c833908be12 100644 --- a/src/basic_recipes/tooltip.jl +++ b/src/basic_recipes/tooltip.jl @@ -133,13 +133,13 @@ function plot!(p::Tooltip{<:Tuple{<:VecTypes}}) overdraw = p.overdraw, depth_shift = p.depth_shift, inspectable = p.inspectable, space = :pixel, transformation = Transformation() ) - translate!(tp, 0, 0, 1) + translate!(tp, 0, 0, 0.01) # must be larger than eps(1f4) to prevent float precision issues # TODO react to glyphcollection instead bbox = map( p, px_pos, p.text, text_align, text_offset, textpadding, p.align ) do p, s, _, o, pad, align - bb = boundingbox(tp, :pixel) + to_ndim(Vec3f, o, 0) + bb = string_boundingbox(tp) + to_ndim(Vec3f, o, 0) l, r, b, t = pad return Rect3f(origin(bb) .- (l, b, 0), widths(bb) .+ (l+r, b+t, 0)) end @@ -156,42 +156,51 @@ function plot!(p::Tooltip{<:Tuple{<:VecTypes}}) # Triangle mesh - triangle = GeometryBasics.Mesh( - Point2f[(-0.5, 0), (0.5, 0), (0, -1)], - GLTriangleFace[(1,2,3)] - ) - - mp = mesh!( - p, triangle, shading = NoShading, space = :pixel, - color = p.backgroundcolor, - transparency = p.transparency, visible = p.visible, - overdraw = p.overdraw, depth_shift = p.depth_shift, - inspectable = p.inspectable, transformation = Transformation() - ) - onany(p, bbox, p.triangle_size, p.placement, p.align) do bb, s, placement, align - o = origin(bb); w = widths(bb) - scale!(mp, s, s, s) - + tri_points = map(p, bbox, p.triangle_size, p.placement, p.align) do bb, s, placement, align + l, b, z = origin(bb); w, h, _ = widths(bb) + r, t = (l, b) .+ (w, h) if placement === :left - translate!(mp, Vec3f(o[1] + w[1], o[2] + align * w[2], o[3])) - rotate!(mp, qrotation(Vec3f(0,0,1), 0.5pi)) + return Point3f[ + (r, b + align * h + 0.5s, z), + (r + s, b + align * h, z), + (r, b + align * h - 0.5s, z), + ] elseif placement === :right - translate!(mp, Vec3f(o[1], o[2] + align * w[2], o[3])) - rotate!(mp, qrotation(Vec3f(0,0,1), -0.5pi)) + return Point3f[ + (l, b + align * h - 0.5s, z), + (l-s, b + align * h, z), + (l, b + align * h + 0.5s, z), + ] elseif placement in (:below, :down, :bottom) - translate!(mp, Vec3f(o[1] + align * w[1], o[2] + w[2], o[3])) - rotate!(mp, Quaternionf(0,0,1,0)) # pi + return Point3f[ + (l + align * w - 0.5s, t, z), + (l + align * w, t+s, z), + (l + align * w + 0.5s, t, z), + ] elseif placement in (:above, :up, :top) - translate!(mp, Vec3f(o[1] + align * w[1], o[2], o[3])) - rotate!(mp, Quaternionf(0,0,0,1)) # 0 + return Point3f[ + (l + align * w + 0.5s, b, z), + (l + align * w, b-s, z), + (l + align * w - 0.5s, b, z), + ] else @error "Tooltip placement $placement invalid. Assuming :above" - translate!(mp, Vec3f(o[1] + align * w[1], o[2], o[3])) - rotate!(mp, Quaternionf(0,0,0,1)) + return Point3f[ + (l + align * w + 0.5s, b, z), + (l + align * w, b-s, z), + (l + align * w - 0.5s, b, z), + ] end - return end + mesh!( + p, tri_points, [1 2 3], shading = NoShading, space = :pixel, + color = p.backgroundcolor, fxaa = false, + transparency = p.transparency, visible = p.visible, + overdraw = p.overdraw, depth_shift = p.depth_shift, + inspectable = p.inspectable, transformation = Transformation() + ) + # Outline outline = map(p, bbox, p.triangle_size, p.placement, p.align) do bb, s, placement, align @@ -250,7 +259,7 @@ function plot!(p::Tooltip{<:Tuple{<:VecTypes}}) return to_ndim.(Vec3f, shift, z) end - lines!( + lp = lines!( p, outline, color = p.outline_color, space = :pixel, miter_limit = pi/18, linewidth = p.outline_linewidth, linestyle = p.outline_linestyle, @@ -258,6 +267,7 @@ function plot!(p::Tooltip{<:Tuple{<:VecTypes}}) overdraw = p.overdraw, depth_shift = p.depth_shift, inspectable = p.inspectable, transformation = Transformation() ) + translate!(lp, 0, 0, 0.01) notify(p[1])