Page:
ex__gui__tooltip_8c
Pages
Examples
Files
Home
Module AABB3D
Module ACCEPT_POOL
Module ALLEGRO4
Module ALLEGRO5
Module ANIM_LIB
Module ASTAR
Module ATLAS_LIB
Module AVRO
Module CLOCK_SYNC
Module COMMONS
Module CONFIGFILE
Module CYPHER_BASE64
Module CYPHER_VIGENERE
Module DEAD_RECKONING
Module ENUMS
Module EXCEPTIONS
Module GAME_ENV
Module GIT
Module GUI
Module HASH_TABLE
Module ISOMETRIC_ENGINE
Module LIST
Module LOG
Module LOGNODUP
Module LZ4
Module NETWORKING
Module NETWORK_MSG
Module N_COOKIES
Module N_DIFF
Module N_DIGEST
Module N_DISK_CACHE
Module N_DNS
Module N_ECC
Module N_ENTROPY
Module N_FILES
Module N_FLUIDS
Module N_GUI_COLOR
Module N_GUI_COLORWHEEL
Module N_GUI_CURVE
Module N_GUI_GRID
Module N_GUI_POPUP
Module N_HEX
Module N_HTTP3
Module N_HTTP_COOKIE
Module N_HTTP_FORM
Module N_HTTP_MIME
Module N_HTTP_REQ
Module N_HTTP_RESP
Module N_HTTP_ROUTER
Module N_HTTP_SERVER
Module N_ICC
Module N_JSON
Module N_KAFKA
Module N_LINALG
Module N_MODULE
Module N_OPENSSL_COMPAT
Module N_PRETTY
Module N_PTH
Module N_QUERY
Module N_RANDOM
Module N_SHA256
Module N_STR
Module N_TIFF
Module N_TIME
Module N_USER
Module N_X509
Module N_ZIP
Module PARTICLES
Module PCRE
Module PHYSICS
Module SIGNALS
Module STACK
Module THREADS
Module TRAJECTORY
Module TREE
Module ZLIB
Modules
Pages
Struct A4_BMP
Struct A4_TIMER
Struct AABB3D
Struct ANIM_DATA
Struct ANIM_FRAME
Struct ANIM_GFX
Struct ANIM_LIB
Struct ASTAR_BOX
Struct ASTAR_CELL
Struct ASTAR_GRID
Struct ASTAR_HEAP
Struct ASTAR_HEAP_NODE
Struct ASTAR_NODE
Struct ASTAR_PATH
Struct AVRO_FIELD
Struct AVRO_READER
Struct AVRO_SCHEMA
Struct BITMAP
Struct CALLBACK_DATA
Struct CA_CTX
Struct CLIENT_JOB
Struct CLIENT_STATE
Struct CONFIG_FILE
Struct CONFIG_FILE_SECTION
Struct CYPHER_PARAM
Struct DATA
Struct DEMO_PANEL
Struct DICTIONARY_DEFINITION
Struct DICTIONARY_ENTRY
Struct DIFF_OUT
Struct DIFF_TEXT
Struct DRAW_STATE
Struct DR_ENTITY
Struct DR_STATE
Struct DR_VEC3
Struct ExceptionContextList
Struct FONT
Struct GAME_ENV
Struct H2BUF
Struct H2_DYN_ENTRY
Struct H2_STREAM
Struct HASH_NODE
Struct HASH_TABLE
Struct ISO_DRAW_ENTRY
Struct ISO_MAP
Struct ISO_PROJECTION
Struct ISO_TILE_SEGMENT
Struct ISO_TILE_SEGMENTS
Struct ISO_VISIBLE_EDGES
Struct JS_STATE
Struct LEX_ITEM
Struct LIST
Struct LIST_NODE
Struct LOG_LEVELS
Struct LexMenu
Struct MEMBER
Struct MIDI
Struct NESTED
Struct NETWORK
Struct NETWORK_HTTP_INFO
Struct NETWORK_POOL
Struct NETWORK_SSL_THREAD_PARAMS
Struct NETW_ACCEPT_POOL
Struct NETW_ACCEPT_POOL_STATS
Struct NETW_MSG
Struct NETW_SNI_ARG
Struct NODE_DATA
Struct N_ATLAS
Struct N_ATLAS_PAGE
Struct N_CLOCK_SYNC
Struct N_COOKIE
Struct N_COOKIE_JAR
Struct N_DIFF_LINE
Struct N_DIFF_RESULT
Struct N_DISK_CACHE
Struct N_ENTROPY_BIT
Struct N_ENTROPY_POS
Struct N_FILE_INFO
Struct N_FLUID
Struct N_FLUID_THREAD_PARAMS
Struct N_FORM_FIELD
Struct N_GIT_COMMIT_INFO
Struct N_GIT_REMOTE_AUTH
Struct N_GIT_REPO
Struct N_GIT_STATUS_ENTRY
Struct N_GUI_BUTTON_DATA
Struct N_GUI_CHECKBOX_DATA
Struct N_GUI_COLOR_PICKER
Struct N_GUI_COMBOBOX_DATA
Struct N_GUI_CTX
Struct N_GUI_CUSTOM_DATA
Struct N_GUI_DATAGRID_COL
Struct N_GUI_DATAGRID_DATA
Struct N_GUI_DROPMENU_DATA
Struct N_GUI_DROPMENU_ENTRY
Struct N_GUI_GRID_CALLBACKS
Struct N_GUI_HEXVIEW_DATA
Struct N_GUI_IMAGE_DATA
Struct N_GUI_KVTABLE
Struct N_GUI_KV_CONTENT
Struct N_GUI_KV_ROW
Struct N_GUI_LABEL_DATA
Struct N_GUI_LISTBOX_DATA
Struct N_GUI_LISTITEM
Struct N_GUI_MARKDOWNVIEW_DATA
Struct N_GUI_MD_FONTS
Struct N_GUI_MD_STYLE
Struct N_GUI_MEAS_ENTRY
Struct N_GUI_MOUSE_EVENT
Struct N_GUI_PENDING_GEOM
Struct N_GUI_PENDING_WIDGET
Struct N_GUI_POPUP
Struct N_GUI_PROGRESSBAR_DATA
Struct N_GUI_RADIOLIST_DATA
Struct N_GUI_SB_TRACK
Struct N_GUI_SCROLLBAR_DATA
Struct N_GUI_SECTION
Struct N_GUI_SECTIONLIST
Struct N_GUI_SLIDER_DATA
Struct N_GUI_SPLITPANE_DATA
Struct N_GUI_STYLE
Struct N_GUI_SUGGEST_SINK
Struct N_GUI_SYNTAXVIEW_DATA
Struct N_GUI_TAB_PANEL
Struct N_GUI_TB_BUTTONS
Struct N_GUI_TEXTAREA_DATA
Struct N_GUI_TEXT_DIMS
Struct N_GUI_THEME
Struct N_GUI_TREE
Struct N_GUI_TREE_NODE
Struct N_GUI_TREE_STATE
Struct N_GUI_WIDGET
Struct N_GUI_WINDOW
Struct N_H2_FRAME
Struct N_H2_HEADER
Struct N_H2_HPACK
Struct N_H2_REQUEST
Struct N_H2_SERVER
Struct N_H2_SETTING
Struct N_HTML_ATTR_
Struct N_HTML_FORM
Struct N_HTML_TAG_
Struct N_HTTP3_RESPONSE
Struct N_HTTP_FIELD
Struct N_HTTP_FORM
Struct N_HTTP_FORM_MULTIPART
Struct N_HTTP_FORM_PART
Struct N_HTTP_MULTIPART_PART
Struct N_HTTP_REQUEST
Struct N_HTTP_RESP
Struct N_HTTP_RESPONSE
Struct N_HTTP_SERVER
Struct N_HTTP_SERVER_CONFIG
Struct N_HTTP_SERVER_REQUEST
Struct N_HTTP_SERVER_STATS
Struct N_HTTP_SET_COOKIE
Struct N_HTTP_STREAM
Struct N_ISO_CAMERA
Struct N_ISO_OBJECT
Struct N_KAFKA
Struct N_KAFKA_EVENT
Struct N_MOCK_SERVER
Struct N_MODULE
Struct N_PARALLEL_SLICE
Struct N_PARALLEL_TEAM
Struct N_PARALLEL_WORKER
Struct N_PCRE
Struct N_PROXY_CFG
Struct N_PTH
Struct N_PTH_TENSOR
Struct N_QUERY
Struct N_ROUTE
Struct N_ROUTER
Struct N_ROUTE_MATCH
Struct N_SHA256
Struct N_SOCKET
Struct N_SPAWN_PIPE
Struct N_SSE_CONN
Struct N_SSE_EVENT
Struct N_STR
Struct N_TIFF
Struct N_TIFF_ENTRY
Struct N_TIME
Struct N_URL
Struct N_URL_PARAM
Struct N_USER
Struct N_USERLIST
Struct N_WS_CONN
Struct N_WS_FRAME
Struct N_WS_MESSAGE
Struct N_ZIP_MEMBER
Struct OCTREE
Struct OCTREE_NODE
Struct PARSER
Struct PARTICLE
Struct PARTICLE_EMITTER
Struct PARTICLE_SYSTEM
Struct PEER
Struct PHYSICS
Struct PK_OBJ
Struct PK_VM
Struct POINT2D
Struct POINT3D
Struct PRETTY_OUT
Struct QNODE
Struct QUADTREE
Struct QUADTREE_NODE
Struct REC
Struct RGB
Struct SAMPLE
Struct SEEN
Struct SHARER
Struct SRV
Struct SRV_ARG
Struct STACK
Struct STACK_ITEM
Struct SYNTAX_RUN
Struct THREAD_POOL
Struct THREAD_POOL_NODE
Struct THREAD_WAITING_PROC
Struct TRAJECTORY
Struct TRAJECTORY_POINT
Struct TREE
Struct TREE_NODE
Struct TS_LOG
Struct WAYPOINT3D
Struct WORKER_ARG
Struct ZIP_SINK
Struct _N_DC_ENTRY
Struct _N_DC_GROUP_ENTRY
Struct _N_GUI_COLORWHEEL
Struct _N_GUI_COLORWHEEL_BLOCK
Struct _N_GUI_COLORWHEEL_MOUSE
Struct _N_GUI_CURVE
Struct _N_GUI_CURVE_BLOCK
Struct _N_GUI_CURVE_MOUSE
Struct _N_GUI_GRID
Struct _N_GUI_POPUP_ENTRY
Struct _N_GUI_POPUP_LEVEL
Struct _N_GUI_SB_SKIN
Struct _N_GUI_TA_STEP
Struct _N_GUI_THUMB
Struct _N_GUI_WRAP_ACC
Struct _compiled
Struct _conn
Struct _ip_slot
Struct _mp_param
Struct _n_civil
Struct _seg
Struct client
Struct collector
Struct date_vector
Struct md_atom
Struct md_cells
Struct md_hit
Struct md_line_ctx
Struct mline
Struct n_http_req_header
Struct n_http_req_limits
Struct n_http_request
Struct n_markdown_block
Struct n_markdown_doc
Struct n_markdown_inline
Struct n_markdown_span
Struct n_reactor_stats
Struct n_url_safe
Struct n_url_safe_head
Struct n_wrap_item
Struct producer_state
Struct rects
Struct reply
Struct runner
Struct sink
Struct tbuf
Struct wrap_hit
Struct wrap_span
Structures
Union COORD_VALUE
Union HASH_DATA
Union NODE_DATA_TYPES
Union STACK_DATA
dir_310dcdd4703e877a6b99d5dc3fc54d27
dir_68267d1309a1af8e8297ef4c3efbcdba
dir_d28a4824dc47e487b107a5db32ef43c4
dir_d44c64559bbebec7f509842c48db8b23
ex__accept__pool__client_8c
ex__accept__pool__server_8c
ex__allegro__4_8c
ex__atlas_8c
ex__avro_8c
ex__base64_8c
ex__bind__exclusive_8c
ex__clipboard_8c
ex__clock__sync_8c
ex__common_8c
ex__configfile_8c
ex__cookies_8c
ex__crypto_8c
ex__diff_8c
ex__digest_8c
ex__disk__cache_8c
ex__dns_8c
ex__ecc_8c
ex__entropy_8c
ex__exceptions_8c
ex__file_8c
ex__file__copy_8c
ex__fluid_8c
ex__fluid__config_8c
ex__fluid__config_8h
ex__git_8c
ex__gui_8c
ex__gui__bench_8c
ex__gui__button__keys_8c
ex__gui__checkbox__label_8c
ex__gui__checkbox__release_8c
ex__gui__color__picker_8c
ex__gui__colorwheel_8c
ex__gui__combobox__items_8c
ex__gui__combobox__wheel_8c
ex__gui__cursor_8c
ex__gui__curve_8c
ex__gui__custom_8c
ex__gui__custom__mouse_8c
ex__gui__datagrid_8c
ex__gui__datagrid__keys_8c
ex__gui__datagrid__sort_8c
ex__gui__detach_8c
ex__gui__dictionary_8c
ex__gui__display__fallback_8c
ex__gui__double__click_8c
ex__gui__dropmenu_8c
ex__gui__frameless__drag_8c
ex__gui__global__scroll_8c
ex__gui__glyph_8c
ex__gui__grid_8c
ex__gui__hexview_8c
ex__gui__hover_8c
ex__gui__isometric_8c
ex__gui__kvtable_8c
ex__gui__label__fits_8c
ex__gui__label__lines_8c
ex__gui__layout__persist_8c
ex__gui__listbox_8c
ex__gui__md_8c
ex__gui__multiwin_8c
ex__gui__network_8c
ex__gui__particles_8c
ex__gui__placeholder_8c
ex__gui__popup_8c
ex__gui__progressbar_8c
ex__gui__reentrant_8c
ex__gui__round_8c
ex__gui__sectionlist_8c
ex__gui__slider__default_8c
ex__gui__slider__handle_8c
ex__gui__slider__step_8c
ex__gui__splitpane_8c
ex__gui__suggest_8c
ex__gui__syntaxview_8c
ex__gui__text__shorten_8c
ex__gui__textarea__selection_8c
ex__gui__tooltip_8c
ex__gui__tree__lazy_8c
ex__gui__tree__order_8c
ex__gui__tree__state_8c
ex__gui__window__rect_8c
ex__gui__zorder_8c
ex__hash_8c
ex__hex_8c
ex__html_8c
ex__http2_8c
ex__http2__server_8c
ex__http3_8c
ex__http__cookie_8c
ex__http__form_8c
ex__http__mime_8c
ex__http__req_8c
ex__http__response_8c
ex__http__router_8c
ex__http__server_8c
ex__icc_8c
ex__iso__astar_8c
ex__json_8c
ex__kafka_8c
ex__linalg_8c
ex__list_8c
ex__log_8c
ex__markdown_8c
ex__module_8c
ex__monolith_8c
ex__network_8c
ex__network_8h
ex__network__accept_8c
ex__network__alpn_8c
ex__network__connect__abort_8c
ex__network__mock_8c
ex__network__proxy_8c
ex__network__reactor_8c
ex__network__sni_8c
ex__network__sse_8c
ex__network__ssl_8c
ex__network__ssl__hardened_8c
ex__network__ssl__hostname_8c
ex__network__ssl__nonblock_8c
ex__network__tls__defaults_8c
ex__network__ws_8c
ex__network__ws__limits_8c
ex__nstr_8c
ex__parallel__for_8c
ex__parallel__team_8c
ex__pcre_8c
ex__pretty_8c
ex__pth_8c
ex__query_8c
ex__random_8c
ex__sha256_8c
ex__signals_8c
ex__spawn_8c
ex__ssrf_8c
ex__stack_8c
ex__thread__pool__discard_8c
ex__thread__pool__wait_8c
ex__threads_8c
ex__tiff_8c
ex__time__formats_8c
ex__trajectory_8c
ex__trees_8c
ex__url_8c
ex__url__safe_8c
ex__wrap_8c
ex__x509_8c
ex__zip_8c
ex__zlib_8c
ex_accept_pool_client_8c example
ex_accept_pool_server_8c example
ex_allegro_4_8c example
ex_atlas_8c example
ex_base64_8c example
ex_clock_sync_8c example
ex_common_8c example
ex_configfile_8c example
ex_cookies_8c example
ex_crypto_8c example
ex_diff_8c example
ex_digest_8c example
ex_disk_cache_8c example
ex_dns_8c example
ex_ecc_8c example
ex_entropy_8c example
ex_exceptions_8c example
ex_file_8c example
ex_file_copy_8c example
ex_fluid_8c example
ex_fluid_config_8c example
ex_fluid_config_8h example
ex_git_8c example
ex_gui_8c example
ex_gui_bench_8c example
ex_gui_button_keys_8c example
ex_gui_checkbox_label_8c example
ex_gui_checkbox_release_8c example
ex_gui_color_picker_8c example
ex_gui_colorwheel_8c example
ex_gui_combobox_items_8c example
ex_gui_combobox_wheel_8c example
ex_gui_cursor_8c example
ex_gui_curve_8c example
ex_gui_custom_8c example
ex_gui_custom_mouse_8c example
ex_gui_datagrid_8c example
ex_gui_datagrid_keys_8c example
ex_gui_datagrid_sort_8c example
ex_gui_detach_8c example
ex_gui_dictionary_8c example
ex_gui_display_fallback_8c example
ex_gui_double_click_8c example
ex_gui_dropmenu_8c example
ex_gui_frameless_drag_8c example
ex_gui_global_scroll_8c example
ex_gui_glyph_8c example
ex_gui_grid_8c example
ex_gui_hexview_8c example
ex_gui_hover_8c example
ex_gui_isometric_8c example
ex_gui_kvtable_8c example
ex_gui_label_fits_8c example
ex_gui_label_lines_8c example
ex_gui_layout_persist_8c example
ex_gui_listbox_8c example
ex_gui_md_8c example
ex_gui_multiwin_8c example
ex_gui_network_8c example
ex_gui_particles_8c example
ex_gui_placeholder_8c example
ex_gui_popup_8c example
ex_gui_progressbar_8c example
ex_gui_reentrant_8c example
ex_gui_round_8c example
ex_gui_sectionlist_8c example
ex_gui_slider_default_8c example
ex_gui_slider_handle_8c example
ex_gui_slider_step_8c example
ex_gui_splitpane_8c example
ex_gui_suggest_8c example
ex_gui_syntaxview_8c example
ex_gui_text_shorten_8c example
ex_gui_textarea_selection_8c example
ex_gui_tooltip_8c example
ex_gui_tree_lazy_8c example
ex_gui_tree_order_8c example
ex_gui_tree_state_8c example
ex_gui_window_rect_8c example
ex_gui_zorder_8c example
ex_hash_8c example
ex_hex_8c example
ex_html_8c example
ex_http2_8c example
ex_http2_server_8c example
ex_http_cookie_8c example
ex_http_form_8c example
ex_http_mime_8c example
ex_http_req_8c example
ex_http_response_8c example
ex_http_router_8c example
ex_http_server_8c example
ex_icc_8c example
ex_iso_astar_8c example
ex_json_8c example
ex_kafka_8c example
ex_linalg_8c example
ex_list_8c example
ex_log_8c example
ex_markdown_8c example
ex_module_8c example
ex_monolith_8c example
ex_network_8c example
ex_network_8h example
ex_network_accept_8c example
ex_network_alpn_8c example
ex_network_connect_abort_8c example
ex_network_mock_8c example
ex_network_proxy_8c example
ex_network_reactor_8c example
ex_network_sni_8c example
ex_network_sse_8c example
ex_network_ssl_8c example
ex_network_ssl_hardened_8c example
ex_network_ssl_hostname_8c example
ex_network_ssl_nonblock_8c example
ex_network_tls_defaults_8c example
ex_network_ws_8c example
ex_network_ws_limits_8c example
ex_nstr_8c example
ex_parallel_for_8c example
ex_parallel_team_8c example
ex_pcre_8c example
ex_pretty_8c example
ex_pth_8c example
ex_query_8c example
ex_random_8c example
ex_sha256_8c example
ex_signals_8c example
ex_spawn_8c example
ex_ssrf_8c example
ex_stack_8c example
ex_threads_8c example
ex_tiff_8c example
ex_time_formats_8c example
ex_trajectory_8c example
ex_trees_8c example
ex_url_8c example
ex_url_safe_8c example
ex_wrap_8c example
ex_x509_8c example
ex_zip_8c example
ex_zlib_8c example
mainpage_8dox
n__3d_8c
n__3d_8h
n__aabb_8c
n__aabb_8h
n__allegro5_8c
n__allegro5_8h
n__allegro__4_8c
n__allegro__4_8h
n__anim_8c
n__anim_8h
n__astar_8c
n__astar_8h
n__atlas_8c
n__atlas_8h
n__avro_8c
n__avro_8h
n__base64_8c
n__base64_8h
n__clipboard_8c
n__clipboard_8h
n__clock__sync_8c
n__clock__sync_8h
n__common_8c
n__common_8h
n__config__file_8c
n__config__file_8h
n__cookies_8c
n__cookies_8h
n__crypto_8c
n__crypto_8h
n__dead__reckoning_8c
n__dead__reckoning_8h
n__diff_8c
n__diff_8h
n__digest_8c
n__digest_8h
n__disk__cache_8c
n__disk__cache_8h
n__dns_8c
n__dns_8h
n__ecc_8c
n__ecc_8h
n__entropy_8c
n__entropy_8h
n__enum_8h
n__exceptions_8c
n__exceptions_8h
n__files_8c
n__files_8h
n__fluids_8c
n__fluids_8h
n__games_8c
n__games_8h
n__git_8c
n__git_8h
n__gui_8c
n__gui_8h
n__gui__color_8c
n__gui__color_8h
n__gui__colorwheel_8c
n__gui__colorwheel_8h
n__gui__curve_8c
n__gui__curve_8h
n__gui__grid_8c
n__gui__grid_8h
n__gui__md_8c
n__gui__md_8h
n__gui__popup_8c
n__gui__popup_8h
n__hash_8c
n__hash_8h
n__hex_8c
n__hex_8h
n__html_8c
n__html_8h
n__http2_8c
n__http2_8h
n__http2__server_8c
n__http2__server_8h
n__http3_8c
n__http3_8h
n__http__cookie_8c
n__http__cookie_8h
n__http__form_8c
n__http__form_8h
n__http__mime_8c
n__http__mime_8h
n__http__req_8c
n__http__req_8h
n__http__response_8c
n__http__response_8h
n__http__router_8c
n__http__router_8h
n__http__server_8c
n__http__server_8h
n__icc_8c
n__icc_8h
n__iso__engine_8c
n__iso__engine_8h
n__json_8c
n__json_8h
n__kafka_8c
n__kafka_8h
n__linalg_8c
n__linalg_8h
n__list_8c
n__list_8h
n__log_8c
n__log_8h
n__lz4_8c
n__lz4_8h
n__markdown_8c
n__markdown_8h
n__module_8c
n__module_8h
n__network_8c
n__network_8h
n__network__accept__pool_8c
n__network__accept__pool_8h
n__network__msg_8c
n__network__msg_8h
n__nodup__log_8c
n__nodup__log_8h
n__openssl__compat_8h
n__particles_8c
n__particles_8h
n__pcre_8c
n__pcre_8h
n__pretty_8c
n__pretty_8h
n__pth_8c
n__pth_8h
n__query_8c
n__query_8h
n__random_8c
n__random_8h
n__reactor_8c
n__reactor_8h
n__sha256_8c
n__sha256_8h
n__signals_8c
n__signals_8h
n__ssrf_8c
n__ssrf_8h
n__stack_8c
n__stack_8h
n__str_8c
n__str_8h
n__thread__pool_8c
n__thread__pool_8h
n__tiff_8c
n__tiff_8h
n__time_8c
n__time_8h
n__trajectory_8c
n__trajectory_8h
n__trees_8c
n__trees_8h
n__url__safe_8c
n__url__safe_8h
n__user_8c
n__user_8h
n__windows_8h
n__wrap_8c
n__wrap_8h
n__x509_8c
n__x509_8h
n__zip_8c
n__zip_8h
n__zlib_8c
n__zlib_8h
nilorea_8h
No results
6
ex__gui__tooltip_8c
gullradriel edited this page 2026-10-09 00:55:18 +02:00
Table of Contents
- examples/ex_gui_tooltip.c
- Functions
- Attributes
- Defines
- Functions Documentation
- function usage
- function render
- function process_args
- function main
- function hover_tooltip_at
- function expect_true
- function bubble_width
- Attributes Documentation
- Macros Documentation
- define TT_W
- define TT_H
- define SPLIT_Y
- define SPLIT_X
- define SPLIT_W
- define SPLIT_H
- define PANEL_X
- define PANEL_W
- define ALLEGRO_UNSTABLE
- Source code
examples/ex_gui_tooltip.c
Functions
| Name | |
|---|---|
| void | usage(void ) |
| void | render(N_GUI_CTX * gui, ALLEGRO_BITMAP * target, int armed, int widget_id) |
| void | process_args(int argc, char ** argv) |
| int | main(int argc, char ** argv) |
| int | hover_tooltip_at(N_GUI_CTX * gui, int x, int y) |
| void | expect_true(const char * label, int cond) |
| int | bubble_width(ALLEGRO_BITMAP * a, ALLEGRO_BITMAP * b) |
Attributes
| Name | |
|---|---|
| int | failures |
Defines
| Name | |
|---|---|
| TT_W | |
| TT_H | |
| SPLIT_Y | |
| SPLIT_X | |
| SPLIT_W | |
| SPLIT_H | |
| PANEL_X | |
| PANEL_W | |
| ALLEGRO_UNSTABLE |
Functions Documentation
function usage
static void usage(
void
)
function render
static void render(
N_GUI_CTX * gui,
ALLEGRO_BITMAP * target,
int armed,
int widget_id
)
function process_args
static void process_args(
int argc,
char ** argv
)
function main
int main(
int argc,
char ** argv
)
function hover_tooltip_at
static int hover_tooltip_at(
N_GUI_CTX * gui,
int x,
int y
)
function expect_true
static void expect_true(
const char * label,
int cond
)
function bubble_width
static int bubble_width(
ALLEGRO_BITMAP * a,
ALLEGRO_BITMAP * b
)
Attributes Documentation
variable failures
static int failures = 0;
Macros Documentation
define TT_W
#define TT_W 1200
define TT_H
#define TT_H 400
define SPLIT_Y
#define SPLIT_Y 100.0f
define SPLIT_X
#define SPLIT_X 400.0f
define SPLIT_W
#define SPLIT_W 200.0f
define SPLIT_H
#define SPLIT_H 120.0f
define PANEL_X
#define PANEL_X 10.0f
define PANEL_W
#define PANEL_W 80.0f
define ALLEGRO_UNSTABLE
#define ALLEGRO_UNSTABLE 1
Source code
/*
* Nilorea Library
* Copyright (C) 2005-2026 Castagnier Mickael
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
* implied. See the License for the specific language governing
* permissions and limitations under the License.
*
* SPDX-License-Identifier: Apache-2.0
*/
#define ALLEGRO_UNSTABLE 1
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "nilorea/n_common.h"
#include "nilorea/n_log.h"
#include "nilorea/n_gui.h"
/* wide enough that an uncapped bubble can outrun style.tooltip_max_w */
#define TT_W 1200
#define TT_H 400
/* the panel is deliberately tiny: it is the "70 px HUD gauge" shape that used to
squeeze the bubble down to a few characters per line */
#define PANEL_X 10.0f
#define PANEL_W 80.0f
/* window holding the split pane whose divider band is the only tooltip target */
#define SPLIT_X 400.0f
#define SPLIT_Y 100.0f
#define SPLIT_W 200.0f
#define SPLIT_H 120.0f
static int failures = 0;
static void expect_true(const char* label, int cond) {
if (!cond) {
n_log(LOG_ERR, "%s: condition false", label);
failures++;
}
}
static void usage(void) {
fprintf(stderr,
" -v version\n"
" -V log level: LOG_NULL, LOG_NOTICE, LOG_INFO, LOG_ERR, LOG_DEBUG\n"
" -h help\n");
}
/* the example is quiet by default (LOG_ERR); -V raises it, which is what
run_tests.sh passes. */
static void process_args(int argc, char** argv) {
int getoptret = 0;
int log_level = LOG_ERR;
while ((getoptret = getopt(argc, argv, "hvV:")) != EOF) {
switch (getoptret) {
case 'v':
fprintf(stderr, "build date: %s %s\n", __DATE__, __TIME__);
exit(0);
case 'V':
if (!strcmp("LOG_NULL", optarg))
log_level = LOG_NULL;
else if (!strcmp("LOG_NOTICE", optarg))
log_level = LOG_NOTICE;
else if (!strcmp("LOG_INFO", optarg))
log_level = LOG_INFO;
else if (!strcmp("LOG_ERR", optarg))
log_level = LOG_ERR;
else if (!strcmp("LOG_DEBUG", optarg))
log_level = LOG_DEBUG;
else {
fprintf(stderr, "%s is not a valid log level\n", optarg);
exit(1);
}
break;
case 'h':
usage();
exit(0);
default:
case '?':
if (optopt == 'V') fprintf(stderr, "\n Missing log level\n");
usage();
exit(1);
}
}
set_log_level(log_level);
}
/* Render the whole GUI into target, with the tooltip either armed or not. The
bubble is found by differencing the two renders, so nothing here depends on
the bubble's colours or on how its corners are rasterized. */
static void render(N_GUI_CTX* gui, ALLEGRO_BITMAP* target, int armed, int widget_id) {
al_set_target_bitmap(target);
al_clear_to_color(al_map_rgb(0, 0, 0));
gui->tooltip_widget_id = armed ? widget_id : -1;
if (armed) {
/* pretend the hover happened long enough ago that the delay has elapsed */
gui->tooltip_armed_at = al_get_time() - (double)gui->style.tooltip_delay - 1.0;
}
n_gui_draw(gui);
}
/* Width in pixels of the region that appears only when the tooltip is armed,
i.e. the bubble. Returns 0 when the two renders are identical. */
static int bubble_width(ALLEGRO_BITMAP* a, ALLEGRO_BITMAP* b) {
ALLEGRO_LOCKED_REGION* la = al_lock_bitmap(a, ALLEGRO_PIXEL_FORMAT_ABGR_8888_LE, ALLEGRO_LOCK_READONLY);
ALLEGRO_LOCKED_REGION* lb = al_lock_bitmap(b, ALLEGRO_PIXEL_FORMAT_ABGR_8888_LE, ALLEGRO_LOCK_READONLY);
int min_x = TT_W, max_x = -1;
if (la && lb) {
for (int y = 0; y < TT_H; y++) {
const unsigned char* ra = (const unsigned char*)la->data + (ptrdiff_t)y * la->pitch;
const unsigned char* rb = (const unsigned char*)lb->data + (ptrdiff_t)y * lb->pitch;
for (int x = 0; x < TT_W; x++) {
if (memcmp(ra + (ptrdiff_t)x * 4, rb + (ptrdiff_t)x * 4, 4) != 0) {
if (x < min_x) min_x = x;
if (x > max_x) max_x = x;
}
}
}
}
if (la) al_unlock_bitmap(a);
if (lb) al_unlock_bitmap(b);
return (max_x < 0) ? 0 : (max_x - min_x + 1);
}
/* Move the pointer to (x,y) through a real mouse event and report which widget
the arming scan picked, so the test exercises n_gui_process_event rather than
the tooltip_widget_id field it maintains. */
static int hover_tooltip_at(N_GUI_CTX* gui, int x, int y) {
ALLEGRO_EVENT ev;
memset(&ev, 0, sizeof(ev));
ev.type = ALLEGRO_EVENT_MOUSE_AXES;
ev.mouse.x = x;
ev.mouse.y = y;
n_gui_process_event(gui, ev);
return gui->tooltip_widget_id;
}
int main(int argc, char** argv) {
process_args(argc, argv);
if (!al_init() || !al_init_font_addon()) {
n_log(LOG_ERR, "allegro init failed");
return 1;
}
al_init_primitives_addon();
/* memory bitmaps: the whole test runs without a display, like ex_gui_kvtable */
al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP);
ALLEGRO_BITMAP* plain = al_create_bitmap(TT_W, TT_H);
ALLEGRO_BITMAP* tipped = al_create_bitmap(TT_W, TT_H);
ALLEGRO_FONT* font = al_create_builtin_font();
if (!plain || !tipped || !font) {
n_log(LOG_ERR, "bitmap or font creation failed");
return 1;
}
N_GUI_CTX* gui = n_gui_new_ctx(font);
if (!gui) {
n_log(LOG_ERR, "n_gui_new_ctx failed");
return 1;
}
n_gui_set_display_size(gui, (float)TT_W, (float)TT_H);
int win = n_gui_add_window(gui, "HUD", PANEL_X, 10.0f, PANEL_W, 60.0f);
int btn = n_gui_add_button(gui, win, "?", 5.0f, 5.0f, 30.0f, 20.0f, N_GUI_SHAPE_RECT, NULL, NULL);
expect_true("window created", win >= 0);
expect_true("button created", btn >= 0);
/* long enough that its natural width outruns both the panel and the cap */
n_gui_set_widget_tooltip(gui, btn,
"Promote this panel to a real OS window, and back again, "
"which is the sort of sentence a tooltip has to hold when it "
"explains something instead of restating the label beside it.");
/* The middle of that button, in display coordinates: the client area of a
titled window starts below its title bar, so 30,40 is the title bar and
not the button. The blocks that drive the arming scan through real mouse
motion need the real thing. */
const int btn_x = (int)(PANEL_X + 5.0f + 15.0f);
const int btn_y = (int)(10.0f + gui->style.titlebar_h + 5.0f + 10.0f);
/* cursor inside the tiny panel, with room to the right for the bubble */
gui->mouse_x = 30;
gui->mouse_y = 40;
/* An in-app window must not narrow the bubble. Before the fix the bubble was
clamped to the widget's window rect, so it came out no wider than the 80px
panel and the sentence wrapped to a few characters per line. */
{
render(gui, plain, 0, btn);
render(gui, tipped, 1, btn);
int w = bubble_width(plain, tipped);
expect_true("tooltip is drawn at all", w > 0);
expect_true("bubble is not narrowed to the in-app window", (float)w > PANEL_W);
n_log(LOG_INFO, "in-app bubble width: %d px (panel is %.0f px)", w, (double)PANEL_W);
}
/* style.tooltip_max_w caps it: the bubble stays near the cap, not the display */
{
gui->style.tooltip_max_w = 480.0f;
render(gui, plain, 0, btn);
render(gui, tipped, 1, btn);
int capped = bubble_width(plain, tipped);
/* text width + the bubble's 8px horizontal padding each side, plus a pixel
of slack for the rounded border */
expect_true("bubble honours tooltip_max_w", capped <= 480 + 16 + 2);
expect_true("bubble still uses the width it is allowed", capped > 480 / 2);
/* 0 disables the cap, and the same tooltip then runs far wider */
gui->style.tooltip_max_w = 0.0f;
render(gui, plain, 0, btn);
render(gui, tipped, 1, btn);
int uncapped = bubble_width(plain, tipped);
expect_true("tooltip_max_w = 0 restores wrap-at-the-clamp-edge", uncapped > capped);
n_log(LOG_INFO, "capped %d px, uncapped %d px", capped, uncapped);
gui->style.tooltip_max_w = 480.0f;
}
/* a widget with no tooltip draws nothing extra */
{
int bare = n_gui_add_button(gui, win, "x", 40.0f, 5.0f, 20.0f, 20.0f, N_GUI_SHAPE_RECT, NULL, NULL);
render(gui, plain, 0, bare);
render(gui, tipped, 1, bare);
expect_true("no tooltip text means no bubble", bubble_width(plain, tipped) == 0);
}
/* A split pane spans the whole region it divides, so only its divider band
arms its tooltip: taking the whole rect would answer for every
widget-free pixel of both panes. This drives the arming scan through
real mouse motion rather than poking tooltip_widget_id. */
{
int spwin = n_gui_add_window(gui, "Split", SPLIT_X, SPLIT_Y, SPLIT_W, SPLIT_H);
int sp = n_gui_add_splitpane(gui, spwin, 0.0f, 0.0f, SPLIT_W, SPLIT_H,
N_GUI_SPLIT_VERTICAL, 0.5f, NULL, NULL);
expect_true("split pane created", sp >= 0);
n_gui_set_widget_tooltip(gui, sp, "Drag to resize");
/* client-area origin of a titled window: y is below the title bar */
float ox = SPLIT_X;
float oy = SPLIT_Y + gui->style.titlebar_h;
int divider_x = (int)(ox + SPLIT_W * 0.5f);
expect_true("pointer on the divider arms the split pane",
hover_tooltip_at(gui, divider_x, (int)(oy + SPLIT_H * 0.5f)) == sp);
expect_true("pointer well left of the divider arms nothing",
hover_tooltip_at(gui, (int)(ox + 10.0f), (int)(oy + SPLIT_H * 0.5f)) == -1);
expect_true("pointer well right of the divider arms nothing",
hover_tooltip_at(gui, (int)(ox + SPLIT_W - 10.0f), (int)(oy + SPLIT_H * 0.5f)) == -1);
/* a widget sitting over a pane still gets its own tooltip */
int over = n_gui_add_button(gui, spwin, "b", 10.0f, 10.0f, 30.0f, 20.0f, N_GUI_SHAPE_RECT, NULL, NULL);
n_gui_set_widget_tooltip(gui, over, "on top of the pane");
expect_true("a widget above the pane still arms its own tooltip",
hover_tooltip_at(gui, (int)(ox + 20.0f), (int)(oy + 20.0f)) == over);
n_gui_close_window(gui, spwin);
}
/* A window opened over the armed widget hides the bubble. The bubble is
drawn last and over everything, and nothing re-runs the arming scan when
a window opens without the pointer moving, so it used to be painted over
the window that had just appeared - a context menu on a right click, with
its first entries covered until the pointer moved. */
{
int menu = 0;
gui->mouse_x = btn_x;
gui->mouse_y = btn_y;
render(gui, plain, 0, btn);
render(gui, tipped, 1, btn);
expect_true("the bubble shows with nothing over it", bubble_width(plain, tipped) > 0);
/* over the pointer, and above the panel: a pop-up sorts in front */
menu = n_gui_add_window(gui, "Menu", 20.0f, 30.0f, 120.0f, 90.0f);
expect_true("menu window created", menu >= 0);
n_gui_window_set_flags(gui, menu, N_GUI_WIN_FRAMELESS);
n_gui_window_set_zorder(gui, menu, N_GUI_ZORDER_POPUP, 0);
expect_true("nothing is pending while a window covers the pointer",
n_gui_tooltip_pending(gui) == 0);
render(gui, plain, 0, btn);
render(gui, tipped, 1, btn);
expect_true("and no bubble is drawn over it", bubble_width(plain, tipped) == 0);
/* the same window somewhere else leaves the bubble alone */
n_gui_window_set_rect(gui, menu, 600.0f, 200.0f, 120.0f, 90.0f);
render(gui, plain, 0, btn);
render(gui, tipped, 1, btn);
expect_true("a window that does not cover the pointer changes nothing",
bubble_width(plain, tipped) > 0);
/* and closing it brings the bubble back where it was */
n_gui_window_set_rect(gui, menu, 20.0f, 30.0f, 120.0f, 90.0f);
n_gui_close_window(gui, menu);
render(gui, plain, 0, btn);
render(gui, tipped, 1, btn);
expect_true("a closed window covers nothing", bubble_width(plain, tipped) > 0);
}
/* Any button dismisses an armed tooltip, not only the first. A right click
is what opens a context menu, and it used to leave the bubble armed. */
{
ALLEGRO_EVENT ev;
int button = 0;
for (button = 1; button <= 3; button++) {
expect_true("the pointer arms the button's tooltip",
hover_tooltip_at(gui, btn_x, btn_y) == btn);
memset(&ev, 0, sizeof(ev));
ev.type = ALLEGRO_EVENT_MOUSE_BUTTON_DOWN;
ev.mouse.button = (unsigned)button;
ev.mouse.x = btn_x;
ev.mouse.y = btn_y;
n_gui_process_event(gui, ev);
expect_true("and a press on any button dismisses it", gui->tooltip_widget_id == -1);
memset(&ev, 0, sizeof(ev));
ev.type = ALLEGRO_EVENT_MOUSE_BUTTON_UP;
ev.mouse.button = (unsigned)button;
ev.mouse.x = btn_x;
ev.mouse.y = btn_y;
n_gui_process_event(gui, ev);
}
}
n_gui_destroy_ctx(&gui);
al_destroy_font(font);
al_destroy_bitmap(plain);
al_destroy_bitmap(tipped);
if (failures) {
n_log(LOG_ERR, "ex_gui_tooltip: %d failure(s)", failures);
return 1;
}
n_log(LOG_NOTICE, "ex_gui_tooltip: all checks passed");
return 0;
}
Modules
- AABB3D
- ACCEPT_POOL
- ALLEGRO4
- ALLEGRO5
- ANIM_LIB
- ASTAR
- ATLAS_LIB
- AVRO
- CLOCK_SYNC
- COMMONS
- CONFIGFILE
- CYPHER_BASE64
- CYPHER_VIGENERE
- DEAD_RECKONING
- ENUMS
- EXCEPTIONS
- GAME_ENV
- GIT
- GUI
- HASH_TABLE
- ISOMETRIC_ENGINE
- LIST
- LOG
- LOGNODUP
- LZ4
- NETWORKING
- NETWORK_MSG
- N_COOKIES
- N_DIFF
- N_DIGEST
- N_DISK_CACHE
- N_DNS
- N_ECC
- N_ENTROPY
- N_FILES
- N_FLUIDS
- N_GUI_COLOR
- N_GUI_COLORWHEEL
- N_GUI_CURVE
- N_GUI_GRID
- N_GUI_POPUP
- N_HEX
- N_HTTP3
- N_HTTP_COOKIE
- N_HTTP_FORM
- N_HTTP_MIME
- N_HTTP_REQ
- N_HTTP_RESP
- N_HTTP_ROUTER
- N_HTTP_SERVER
- N_ICC
- N_JSON
- N_KAFKA
- N_LINALG
- N_MODULE
- N_OPENSSL_COMPAT
- N_PRETTY
- N_PTH
- N_QUERY
- N_RANDOM
- N_SHA256
- N_STR
- N_TIFF
- N_TIME
- N_USER
- N_X509
- N_ZIP
- PARTICLES
- PCRE
- PHYSICS
- SIGNALS
- STACK
- THREADS
- TRAJECTORY
- TREE
- ZLIB