Texture displacement: no tooltip while a control is being used, and a wait

that finishes on its own

The hover delay only finished while the mouse was moving: a pointer resting
on a control produces no events, so nothing redrew the canvas and the wait
never reached its end - the tooltip appeared on the next pixel of movement
instead. It asked for its frames with schedule_extra_frame(), which only
arranges a timer whose event an idle event is assumed to follow, and
on_idle renders nothing unless the canvas was already dirty when it ran.
The wait and the animations now both use request_extra_frame(), which ends
on_idle with evt.RequestMore() and so obliges wx to deliver the next idle;
it is what 3DBed's fade uses. Asking for frames as fast as they come is
safe now that which frame is drawn comes from the clock rather than from
the frame count - a redraw that arrives early draws the same frame again.

Nothing explains a control while the control is being used, so no tooltip
appears while a slider is being dragged, a value typed into one, a combo
open or a layer card dragged. The pointer sits on the very thing being
edited, so a tooltip there covered the model exactly while the user was
watching it change. The full wait comes back afterwards rather than the
short one: having just let go of a slider is not a reason to be shown a
picture of it.

AnimatedTexture::texture_id() loses its time-to-next-frame out-parameter,
which nothing asks for any more.
This commit is contained in:
ExPikaPaka
2026-10-13 14:21:55 +02:00
parent db0e788d35
commit 5cfd91a309
4 changed files with 47 additions and 44 deletions
+3 -11
View File
@@ -207,26 +207,18 @@ void AnimatedTexture::reset()
m_duration = 0.;
}
unsigned int AnimatedTexture::texture_id(double time, double *time_to_next) const
unsigned int AnimatedTexture::texture_id(double time) const
{
if (m_frames.empty()) {
if (time_to_next != nullptr)
*time_to_next = 0.;
if (m_frames.empty())
return 0;
}
if (m_frames.size() == 1 || m_duration <= 0.) {
if (time_to_next != nullptr)
*time_to_next = 0.;
if (m_frames.size() == 1 || m_duration <= 0.)
return m_frames.front().texture->get_id();
}
const double t = time - m_duration * std::floor(time / m_duration);
// Frames are few; a linear walk beats keeping an index around and getting it stale.
size_t i = 0;
while (i + 1 < m_frames.size() && t >= m_frames[i].start + m_frames[i].delay)
++i;
if (time_to_next != nullptr)
*time_to_next = std::max(0., m_frames[i].start + m_frames[i].delay - t);
return m_frames[i].texture->get_id();
}