@@ -3810,6 +3810,9 @@ NK_API void nk_contextual_end(struct nk_context*);
38103810 * ============================================================================= */
38113811NK_API void nk_tooltip(struct nk_context*, const char*);
38123812NK_API void nk_tooltip_offset(struct nk_context *ctx, const char *text, enum nk_tooltip_pos position, struct nk_vec2 offset);
3813+ NK_API void nk_do_tooltip(struct nk_context*, const char*, struct nk_rect);
3814+ NK_API void nk_do_tooltip_delay(struct nk_context*, const char*, struct nk_rect, float*);
3815+ NK_API void nk_do_tooltip_delay_clicked(struct nk_context*, const char*, struct nk_rect, float* timer, nk_bool*);
38133816#ifdef NK_INCLUDE_STANDARD_VARARGS
38143817NK_API void nk_tooltipf(struct nk_context*, NK_PRINTF_FORMAT_STRING const char*, ...) NK_PRINTF_VARARG_FUNC(2);
38153818NK_API void nk_tooltipfv(struct nk_context*, NK_PRINTF_FORMAT_STRING const char*, va_list) NK_PRINTF_VALIST_FUNC(2);
@@ -4935,6 +4938,10 @@ NK_API nk_bool nk_input_is_mouse_click_down_in_rect(const struct nk_input *i, en
49354938NK_API nk_bool nk_input_any_mouse_click_in_rect(const struct nk_input*, struct nk_rect);
49364939NK_API nk_bool nk_input_is_mouse_prev_hovering_rect(const struct nk_input*, struct nk_rect);
49374940NK_API nk_bool nk_input_is_mouse_hovering_rect(const struct nk_input*, struct nk_rect);
4941+ NK_API nk_bool nk_input_is_mouse_hovering_still_rect(const struct nk_input*, struct nk_rect);
4942+ NK_API nk_bool nk_input_is_mouse_hovering_delay_rect(const struct nk_context*, struct nk_rect, float*, float);
4943+ NK_API nk_bool nk_input_is_mouse_hovering_still_delay_rect(const struct nk_context*, struct nk_rect, float*, float);
4944+ NK_API nk_bool nk_input_is_mouse_hovering_still_delay_clicked_rect(const struct nk_context*, struct nk_rect, float*, float, nk_bool*);
49384945NK_API nk_bool nk_input_is_mouse_moved(const struct nk_input*);
49394946NK_API nk_bool nk_input_mouse_clicked(const struct nk_input*, enum nk_buttons, struct nk_rect);
49404947NK_API nk_bool nk_input_is_mouse_down(const struct nk_input*, enum nk_buttons);
@@ -5570,6 +5577,7 @@ struct nk_style_window {
55705577
55715578 enum nk_tooltip_pos tooltip_origin;
55725579 struct nk_vec2 tooltip_offset;
5580+ float tooltip_delay;
55735581};
55745582
55755583struct nk_style {
@@ -18425,6 +18433,139 @@ nk_input_is_mouse_hovering_rect(const struct nk_input *i, struct nk_rect rect)
1842518433 if (!i) return nk_false;
1842618434 return NK_INBOX(i->mouse.pos.x, i->mouse.pos.y, rect.x, rect.y, rect.w, rect.h);
1842718435}
18436+
18437+ /**
18438+ * # nk_input_is_mouse_hovering_still_rect
18439+ * Returns true if the mouse is hovering over rect and hasn't moved since the last
18440+ * frame, false otherwise.
18441+ */
18442+ NK_API nk_bool
18443+ nk_input_is_mouse_hovering_still_rect(const struct nk_input *i, struct nk_rect rect)
18444+ {
18445+ if (!i) return nk_false;
18446+ return (NK_INBOX(i->mouse.pos.x, i->mouse.pos.y, rect.x, rect.y, rect.w, rect.h) &&
18447+ !nk_input_is_mouse_moved(i));
18448+ }
18449+
18450+ /**
18451+ * # nk_input_is_mouse_hovering_delay_rect
18452+ * Returns true if the mouse has been hovering over rect for `delay` seconds or more.
18453+ *
18454+ * Parameter | Description
18455+ * ------------|---------------------------------------------------------------
18456+ * \param[in] ctx | Must point to an either stack or heap allocated `nk_context` struct
18457+ * \param[in] rect | The rect area you're checking against
18458+ * \param[in|out] timer | Must point to a float used to track the total seconds hovered across frames
18459+ * \param[in] delay | The wait time in seconds
18460+ *
18461+ * \returns `true` if the the mouse has hovered long enough, `false otherwise`
18462+ */
18463+ NK_API nk_bool
18464+ nk_input_is_mouse_hovering_delay_rect(const struct nk_context *ctx, struct nk_rect rect, float* timer, float delay)
18465+ {
18466+ NK_ASSERT(ctx);
18467+ if (!ctx) {
18468+ return nk_false;
18469+ } else {
18470+ const struct nk_input* i = &ctx->input;
18471+ if (NK_INBOX(i->mouse.pos.x, i->mouse.pos.y, rect.x, rect.y, rect.w, rect.h)) {
18472+ *timer += ctx->delta_time_seconds;
18473+ return *timer >= delay;
18474+ } else if (NK_INBOX(i->mouse.prev.x, i->mouse.prev.y, rect.x, rect.y, rect.w, rect.h)) {
18475+ *timer = 0;
18476+ }
18477+ return nk_false;
18478+ }
18479+
18480+ }
18481+
18482+ /**
18483+ * # nk_input_is_mouse_hovering_still_delay_rect
18484+ * Returns true if the mouse has been hovering motionless over rect for `delay` seconds or more. The timer
18485+ * does not reset once the delay is reached as long as you are still hovering over the rect.
18486+ *
18487+ * Parameter | Description
18488+ * ------------|---------------------------------------------------------------
18489+ * \param[in] ctx | Must point to an either stack or heap allocated `nk_context` struct
18490+ * \param[in] rect | The rect area you're checking against
18491+ * \param[in|out] timer | Must point to a float used to track the total seconds hovered across frames
18492+ * \param[in] delay | The wait time in seconds
18493+ *
18494+ * \returns `true` if the the mouse has hovered without moving long enough, `false otherwise`
18495+ */
18496+ NK_API nk_bool
18497+ nk_input_is_mouse_hovering_still_delay_rect(const struct nk_context *ctx, struct nk_rect rect, float* timer, float delay)
18498+ {
18499+ NK_ASSERT(ctx);
18500+ if (!ctx) {
18501+ return nk_false;
18502+ } else {
18503+ const struct nk_input* i = &ctx->input;
18504+ if (NK_INBOX(i->mouse.pos.x, i->mouse.pos.y, rect.x, rect.y, rect.w, rect.h)) {
18505+ /* once it triggers, moving within the bounds should not make it disappear */
18506+ if (*timer >= delay) {
18507+ return nk_true;
18508+ }
18509+ if (!nk_input_is_mouse_moved(i)) {
18510+ *timer += ctx->delta_time_seconds;
18511+ return *timer >= delay;
18512+ }
18513+ *timer = 0;
18514+ } else if (NK_INBOX(i->mouse.prev.x, i->mouse.prev.y, rect.x, rect.y, rect.w, rect.h)) {
18515+ *timer = 0;
18516+ }
18517+ return nk_false;
18518+ }
18519+ }
18520+
18521+ /**
18522+ * # nk_input_is_mouse_hovering_still_delay_clicked_rect
18523+ * Works the same as `nk_input_is_mouse_hovering_still_delay_rect` unless clicked is set. If clicked is true,
18524+ * then it returns false regardless of the timer value as long as the mouse is motionless. It goes back to working
18525+ * as normal once the mouse has moved (clicked is set to false, timer to 0).
18526+ *
18527+ * Parameter | Description
18528+ * ------------|---------------------------------------------------------------
18529+ * \param[in] ctx | Must point to an either stack or heap allocated `nk_context` struct
18530+ * \param[in] rect | The rect area you're checking against
18531+ * \param[in|out] timer | Must point to a float used to track the total seconds hovered across frames
18532+ * \param[in] delay | The wait time in seconds
18533+ * \param[in|out] clicked | Must point to an nk_bool used to indicate whether the item in question has been clicked (reset to false internally on mouse motion)
18534+ *
18535+ * \returns `true` if the the mouse has hovered without moving long enough, `false otherwise`
18536+ */
18537+ NK_API nk_bool
18538+ nk_input_is_mouse_hovering_still_delay_clicked_rect(const struct nk_context *ctx, struct nk_rect rect, float* timer, float delay, nk_bool* clicked)
18539+ {
18540+ NK_ASSERT(ctx);
18541+ if (!ctx) {
18542+ return nk_false;
18543+ } else {
18544+ const struct nk_input* i = &ctx->input;
18545+ if (*clicked) {
18546+ /* could also be based on maintaining hover rather than motionless once clicked */
18547+ if (!nk_input_is_mouse_moved(i)) {
18548+ return nk_false;
18549+ }
18550+ *clicked = nk_false;
18551+ *timer = 0;
18552+ }
18553+ if (NK_INBOX(i->mouse.pos.x, i->mouse.pos.y, rect.x, rect.y, rect.w, rect.h)) {
18554+ /* once it triggers, moving within the bounds should not make it disappear */
18555+ if (*timer >= delay) {
18556+ return nk_true;
18557+ }
18558+ if (!nk_input_is_mouse_moved(i)) {
18559+ *timer += ctx->delta_time_seconds;
18560+ return *timer >= delay;
18561+ }
18562+ *timer = 0;
18563+ } else if (NK_INBOX(i->mouse.prev.x, i->mouse.prev.y, rect.x, rect.y, rect.w, rect.h)) {
18564+ *timer = 0;
18565+ }
18566+ return nk_false;
18567+ }
18568+ }
1842818569NK_API nk_bool
1842918570nk_input_is_mouse_prev_hovering_rect(const struct nk_input *i, struct nk_rect rect)
1843018571{
@@ -19221,13 +19362,14 @@ nk_style_from_table(struct nk_context *ctx, const struct nk_color *table)
1922119362 win->tooltip_padding = nk_vec2(4,4);
1922219363
1922319364 /* default tooltip just down and to the right of the cursor
19224- * so it doesn't cover the text
19365+ * so it doesn't cover the text and a default delay of 0.5 seconds
1922519366 *
1922619367 * TODO might be worth consolidating tooltip styling
1922719368 * into its own style structure, though it is a
1922819369 * type of window...*/
1922919370 win->tooltip_origin = NK_TOP_LEFT;
1923019371 win->tooltip_offset = nk_vec2(12, 12);
19372+ win->tooltip_delay = 0.5f;
1923119373}
1923219374NK_API void
1923319375nk_style_set_font(struct nk_context *ctx, const struct nk_user_font *font)
@@ -30740,6 +30882,45 @@ nk_tooltip_end(struct nk_context *ctx)
3074030882 nk_popup_end(ctx);
3074130883}
3074230884
30885+ /**
30886+ * Display a default tooltip if the mouse is hovering over the rect `bounds`
30887+ */
30888+ NK_API void
30889+ nk_do_tooltip(struct nk_context* ctx, const char* text, struct nk_rect bounds)
30890+ {
30891+ NK_ASSERT(ctx);
30892+ if (nk_input_is_mouse_hovering_rect(&ctx->input, bounds)) {
30893+ nk_tooltip_offset(ctx, text, ctx->style.window.tooltip_origin, ctx->style.window.tooltip_offset);
30894+ }
30895+ }
30896+
30897+ /**
30898+ * Display a default tooltip if the mouse hovers motionless for the default delay (ctx->style.window.tooltip_delay)
30899+ * `timer` is used to track the time across frames.
30900+ */
30901+ NK_API void
30902+ nk_do_tooltip_delay(struct nk_context* ctx, const char* text, struct nk_rect bounds, float* timer)
30903+ {
30904+ NK_ASSERT(ctx);
30905+ if (nk_input_is_mouse_hovering_still_delay_rect(ctx, bounds, timer, ctx->style.window.tooltip_delay)) {
30906+ nk_tooltip_offset(ctx, text, ctx->style.window.tooltip_origin, ctx->style.window.tooltip_offset);
30907+ }
30908+ }
30909+
30910+ /**
30911+ * Display a default tooltip if the mouse hovers motionless for the default delay (ctx->style.window.tooltip_delay) unless
30912+ * `clicked` is true. `clicked` will be reset to false (and `timer` to 0) when the mouse moves.
30913+ * `timer` is used to track the time across frames.
30914+ */
30915+ NK_API void
30916+ nk_do_tooltip_delay_clicked(struct nk_context* ctx, const char* text, struct nk_rect bounds, float* timer, nk_bool* clicked)
30917+ {
30918+ NK_ASSERT(ctx);
30919+ if (nk_input_is_mouse_hovering_still_delay_clicked_rect(ctx, bounds, timer, ctx->style.window.tooltip_delay, clicked)) {
30920+ nk_tooltip_offset(ctx, text, ctx->style.window.tooltip_origin, ctx->style.window.tooltip_offset);
30921+ }
30922+ }
30923+
3074330924NK_API void
3074430925nk_tooltip_offset(struct nk_context *ctx, const char *text, enum nk_tooltip_pos position, struct nk_vec2 offset)
3074530926{
0 commit comments