@@ -3826,12 +3826,27 @@ NK_API void nk_contextual_end(struct nk_context*);
38263826 * TOOLTIP
38273827 *
38283828 * ============================================================================= */
3829+ enum nk_tooltip_flags {
3830+ /**!< tells where tooltip should appear relatively to the cursor, can be combined (e.g. BELOW|ON_RIGHT) */
3831+ NK_TOOLTIP_ABOVE = NK_FLAG(0),
3832+ NK_TOOLTIP_BELOW = NK_FLAG(1),
3833+ NK_TOOLTIP_ON_LEFT = NK_FLAG(2),
3834+ NK_TOOLTIP_ON_RIGHT = NK_FLAG(3),
3835+ /**!< if set, the offset will be absolute, instead of relative */
3836+ NK_TOOLTIP_ABS_OFFSET = NK_FLAG(4)
3837+ /* FIXME: https://github.com/Immediate-Mode-UI/Nuklear/issues/899 */
3838+ /*NK_TOOLTIP_CLAMP_IN_SCREEN = NK_FLAG(5),*/
3839+ };
38293840NK_API void nk_tooltip(struct nk_context*, const char*);
3841+ NK_API void nk_tooltip_offset(struct nk_context *ctx, const char *text, nk_flags tooltip, struct nk_vec2);
38303842#ifdef NK_INCLUDE_STANDARD_VARARGS
38313843NK_API void nk_tooltipf(struct nk_context*, NK_PRINTF_FORMAT_STRING const char*, ...) NK_PRINTF_VARARG_FUNC(2);
38323844NK_API void nk_tooltipfv(struct nk_context*, NK_PRINTF_FORMAT_STRING const char*, va_list) NK_PRINTF_VALIST_FUNC(2);
3845+ NK_API void nk_tooltipf_offset(struct nk_context*, nk_flags tooltip, struct nk_vec2, NK_PRINTF_FORMAT_STRING const char*, ...) NK_PRINTF_VARARG_FUNC(4);
3846+ NK_API void nk_tooltipfv_offset(struct nk_context*, nk_flags tooltip, struct nk_vec2, NK_PRINTF_FORMAT_STRING const char*, va_list) NK_PRINTF_VALIST_FUNC(4);
38333847#endif
38343848NK_API nk_bool nk_tooltip_begin(struct nk_context*, float width);
3849+ NK_API nk_bool nk_tooltip_begin_offset(struct nk_context*, float width, nk_flags tooltip, struct nk_vec2);
38353850NK_API void nk_tooltip_end(struct nk_context*);
38363851/* =============================================================================
38373852 *
@@ -30603,10 +30618,40 @@ nk_combobox_callback(struct nk_context *ctx,
3060330618 * TOOLTIP
3060430619 *
3060530620 * ===============================================================*/
30621+ NK_LIB struct nk_vec2
30622+ nk_tooltip_get_default_offset(const struct nk_context *ctx)
30623+ {
30624+ struct nk_vec2 offset = {0};
30625+ NK_ASSERT(ctx);
30626+ if (!ctx) return offset;
30627+ if (ctx->style.cursor_active) {
30628+ /* nuklear is drawing its own cursor so we can reuse its size (best case!) */
30629+ offset.x = ctx->style.window.padding.x + ctx->style.cursor_active->size.x;
30630+ offset.x = ctx->style.window.padding.y + ctx->style.cursor_active->size.y;
30631+ } else if (ctx->style.font) {
30632+ /* assume that cursor size is similar to font height (flawed but reasonable)*/
30633+ offset.y = ctx->style.window.padding.x + ctx->style.font->height;
30634+ offset.x = ctx->style.window.padding.y + ctx->style.font->height;
30635+ }
30636+ return offset;
30637+ }
30638+ NK_LIB nk_flags
30639+ nk_tooltip_get_default_flags(const struct nk_context *ctx)
30640+ {
30641+ NK_UNUSED(ctx);
30642+ return NK_TOOLTIP_BELOW|NK_TOOLTIP_ON_RIGHT;
30643+ }
3060630644NK_API nk_bool
3060730645nk_tooltip_begin(struct nk_context *ctx, float width)
3060830646{
30609- int x,y,w,h;
30647+ return nk_tooltip_begin_offset(ctx, width,
30648+ nk_tooltip_get_default_flags(ctx),
30649+ nk_tooltip_get_default_offset(ctx));
30650+ }
30651+ NK_API nk_bool
30652+ nk_tooltip_begin_offset(struct nk_context *ctx, float width, nk_flags tooltip, struct nk_vec2 offset)
30653+ {
30654+ int x,y,w,h,mul_x,mul_y;
3061030655 struct nk_window *win;
3061130656 const struct nk_input *in;
3061230657 struct nk_rect bounds;
@@ -30625,14 +30670,38 @@ nk_tooltip_begin(struct nk_context *ctx, float width)
3062530670 return 0;
3062630671
3062730672 w = nk_iceilf(width);
30628- h = nk_iceilf(nk_null_rect.h);
30629- x = nk_ifloorf(in->mouse.pos.x + 1) - (int)win->layout->clip.x;
30630- y = nk_ifloorf(in->mouse.pos.y + 1) - (int)win->layout->clip.y;
30673+ h = ctx->current->layout->row.min_height;
30674+
30675+ /* find axis multipliers based on bitmask state */
30676+ mul_x = 0;
30677+ mul_x -= !!(tooltip & NK_TOOLTIP_ON_LEFT );
30678+ mul_x += !!(tooltip & NK_TOOLTIP_ON_RIGHT);
30679+ NK_ASSERT(mul_x == -1 || mul_x == 0 || mul_x == 1);
30680+ mul_y = 0;
30681+ mul_y -= !!(tooltip & NK_TOOLTIP_ABOVE);
30682+ mul_y += !!(tooltip & NK_TOOLTIP_BELOW);
30683+ NK_ASSERT(mul_y == -1 || mul_y == 0 || mul_y == 1);
30684+
30685+ /* turn relative offset into absolute, unless it's already absolute
30686+ * notice that offset axis is ignored in cases where mul==0
30687+ * (if you don't like this behavior, make sure to use ABS_OFFSET flag)*/
30688+ if (!(tooltip & NK_TOOLTIP_ABS_OFFSET)) {
30689+ offset.x *= mul_x;
30690+ offset.y *= mul_y;
30691+ }
30692+
30693+ /* find origin */
30694+ x = -w/2 + (mul_x * w/2);
30695+ x += nk_ifloorf(in->mouse.pos.x + 1) - (int)win->layout->clip.x;
30696+ x += offset.x;
30697+ y = -h/2 + (mul_y * h/2);
30698+ y += nk_ifloorf(in->mouse.pos.y + 1) - (int)win->layout->clip.y;
30699+ y += offset.y;
3063130700
3063230701 bounds.x = (float)x;
3063330702 bounds.y = (float)y;
3063430703 bounds.w = (float)w;
30635- bounds.h = (float)h ;
30704+ bounds.h = (float)nk_iceilf(nk_null_rect.h) ;
3063630705
3063730706 ret = nk_popup_begin(ctx, NK_POPUP_DYNAMIC,
3063830707 "__##Tooltip##__", NK_WINDOW_NO_SCROLLBAR|NK_WINDOW_BORDER, bounds);
@@ -30641,7 +30710,6 @@ nk_tooltip_begin(struct nk_context *ctx, float width)
3064130710 ctx->current->layout->type = NK_PANEL_TOOLTIP;
3064230711 return ret;
3064330712}
30644-
3064530713NK_API void
3064630714nk_tooltip_end(struct nk_context *ctx)
3064730715{
@@ -30653,7 +30721,7 @@ nk_tooltip_end(struct nk_context *ctx)
3065330721 nk_popup_end(ctx);
3065430722}
3065530723NK_API void
30656- nk_tooltip (struct nk_context *ctx, const char *text)
30724+ nk_tooltip_offset (struct nk_context *ctx, const char *text, nk_flags tooltip, struct nk_vec2 offset )
3065730725{
3065830726 const struct nk_style *style;
3065930727 struct nk_vec2 padding;
@@ -30681,14 +30749,29 @@ nk_tooltip(struct nk_context *ctx, const char *text)
3068130749 text_height = (style->font->height + 2 * padding.y);
3068230750
3068330751 /* execute tooltip and fill with text */
30684- if (nk_tooltip_begin (ctx, (float)text_width)) {
30752+ if (nk_tooltip_begin_offset (ctx, (float)text_width, tooltip, offset )) {
3068530753 nk_layout_row_dynamic(ctx, (float)text_height, 1);
3068630754 nk_text(ctx, text, text_len, NK_TEXT_LEFT);
3068730755 nk_tooltip_end(ctx);
3068830756 }
3068930757}
30758+ NK_API void
30759+ nk_tooltip(struct nk_context *ctx, const char *text)
30760+ {
30761+ nk_tooltip_offset(ctx, text,
30762+ nk_tooltip_get_default_flags(ctx),
30763+ nk_tooltip_get_default_offset(ctx));
30764+ }
3069030765#ifdef NK_INCLUDE_STANDARD_VARARGS
3069130766NK_API void
30767+ nk_tooltipf_offset(struct nk_context *ctx, nk_flags tooltip, struct nk_vec2 offset, const char *fmt, ...)
30768+ {
30769+ va_list args;
30770+ va_start(args, fmt);
30771+ nk_tooltipfv_offset(ctx, tooltip, offset, fmt, args);
30772+ va_end(args);
30773+ }
30774+ NK_API void
3069230775nk_tooltipf(struct nk_context *ctx, const char *fmt, ...)
3069330776{
3069430777 va_list args;
@@ -30697,6 +30780,13 @@ nk_tooltipf(struct nk_context *ctx, const char *fmt, ...)
3069730780 va_end(args);
3069830781}
3069930782NK_API void
30783+ nk_tooltipfv_offset(struct nk_context *ctx, nk_flags tooltip, struct nk_vec2 offset, const char *fmt, va_list args)
30784+ {
30785+ char buf[256];
30786+ nk_strfmt(buf, NK_LEN(buf), fmt, args);
30787+ nk_tooltip_offset(ctx, buf, tooltip, offset);
30788+ }
30789+ NK_API void
3070030790nk_tooltipfv(struct nk_context *ctx, const char *fmt, va_list args)
3070130791{
3070230792 char buf[256];
@@ -30762,6 +30852,8 @@ nk_tooltipfv(struct nk_context *ctx, const char *fmt, va_list args)
3076230852/// - [y]: Minor version with non-breaking API and library changes
3076330853/// - [z]: Patch version with no direct changes to the API
3076430854///
30855+ /// - 2026/02/17 (4.13.3) - Fixed default tooltip from being covered by the cursor,
30856+ /// added new tooltip variation that allows to set the offset manually
3076530857/// - 2026/01/31 (4.13.2) - Fix: replace incorrect static asserts for size(nk_bool)
3076630858/// - 2026/01/26 (4.13.1) - Fix: nk_do_property now uses NK_STRTOD via macro
3076730859/// - Fix: failure to build from source, due to
0 commit comments