Nilorea Library
C utilities for networking, threading, graphics
Loading...
Searching...
No Matches
n_gui_popup.c File Reference

A popup menu with submenus for N_GUI, the kind a right click opens. More...

#include <stdlib.h>
#include <string.h>
#include <allegro5/allegro_primitives.h>
#include "nilorea/n_common.h"
#include "nilorea/n_log.h"
#include "nilorea/n_gui_popup.h"
Include dependency graph for n_gui_popup.c:

Go to the source code of this file.

Data Structures

struct  _N_GUI_POPUP_ENTRY
 one entry. More...
struct  _N_GUI_POPUP_LEVEL
 what a level's widget is handed: stable while the entries array moves More...
struct  N_GUI_POPUP
 the popup More...

Macros

#define _POPUP_KIND_ITEM   1
 an item, picked with a tag
#define _POPUP_KIND_ROOT   0
 the top level
#define _POPUP_KIND_SEP   3
 a separator
#define _POPUP_KIND_SUB   2
 a submenu, which is also a level
#define N_GUI_POPUP_ARROW_W   16.0f
 room kept at the right of a level for the submenu arrow, at scale 1
#define N_GUI_POPUP_MIN_W   120.0f
 narrowest a level is, at scale 1
#define N_GUI_POPUP_OVERLAP   2.0f
 how far a submenu overlaps its parent, at scale 1, so the pointer does not cross a gap on its way in
#define N_GUI_POPUP_PAD_X   10.0f
 padding left and right of a row's text, at scale 1
#define N_GUI_POPUP_PAD_Y   4.0f
 padding above and below a row's text, at scale 1
#define N_GUI_POPUP_SEP_H   7.0f
 height of a separator row, at scale 1

Functions

static int _popup_activate (N_GUI_POPUP *popup, int level, int row)
 helper: act on a row: pick an item, open a submenu.
static int _popup_append (N_GUI_POPUP *popup, int kind, int parent, const char *text, const char *tip, int tag)
 helper: append an entry, returning its id or -1
static void _popup_close_level (N_GUI_POPUP *popup, int level)
 helper: close a level and everything open beside it
static void _popup_draw (N_GUI_WIDGET *widget, float x, float y, ALLEGRO_FONT *font, void *user_data)
 custom draw callback: the rows of one level
static ALLEGRO_FONT * _popup_font (const N_GUI_POPUP *popup)
 helper: the font rows are measured with
static int _popup_has_rows (const N_GUI_POPUP *popup, int level)
 helper: does a level have at least one row that would be shown.
static int _popup_is_level (const N_GUI_POPUP *popup, int id)
 helper: is this id a level (the root or a submenu)
static int _popup_layout (N_GUI_POPUP *popup, int level)
 helper: the rows of a level, and its size.
static int _popup_make_window (N_GUI_POPUP *popup, int level)
 helper: make a level's window the first time it opens
static int _popup_mouse (int widget_id, const N_GUI_MOUSE_EVENT *ev, void *user_data)
 custom mouse callback: hover opens submenus, a press acts
static void _popup_open_child (N_GUI_POPUP *popup, int level, int row)
 helper: open a submenu beside its row.
static int _popup_row_at (const N_GUI_POPUP *popup, int level, float ly)
 helper: the row index at a level-local y, or -1
static float _popup_row_h (const N_GUI_POPUP *popup)
 helper: height of an item row
static int _popup_row_shows (const N_GUI_POPUP *popup, int id)
 helper: is an entry a row that shows, separators aside
static int _popup_show_level (N_GUI_POPUP *popup, int level, float x, float y)
 helper: lay a level out, place it with its corner at a point pulled back inside the display, and open it on top
static int _popup_valid (const N_GUI_POPUP *popup, int id)
 helper: is this id an entry
int n_gui_popup_add_item (N_GUI_POPUP *popup, int parent, const char *text, int tag, const char *tip)
 Add an item at the end of a level.
int n_gui_popup_add_separator (N_GUI_POPUP *popup, int parent)
 Add a separator at the end of a level.
int n_gui_popup_add_submenu (N_GUI_POPUP *popup, int parent, const char *text, const char *tip)
 Add a submenu at the end of a level.
void n_gui_popup_close (N_GUI_POPUP *popup)
 Close every level without picking anything.
void n_gui_popup_free (N_GUI_POPUP **popup)
 Close the popup and release the handle.
int n_gui_popup_hit (const N_GUI_POPUP *popup, float x, float y)
 Is a point on any of its open levels.
int n_gui_popup_is_open (const N_GUI_POPUP *popup)
 Is its top level on screen.
N_GUI_POPUP * n_gui_popup_new (N_GUI_CTX *ctx, float scale, N_GUI_POPUP_FN on_pick, void *user_data)
 Make an empty popup menu in ctx, closed.
int n_gui_popup_open (N_GUI_POPUP *popup, float x, float y)
 Open the top level with its corner at a point.
int n_gui_popup_press (N_GUI_POPUP *popup, int entry)
 Press the row of an entry, as a click on it would.
void n_gui_popup_set_enabled (N_GUI_POPUP *popup, int entry, int enabled)
 Enable or grey out an entry.
void n_gui_popup_set_shown (N_GUI_POPUP *popup, int entry, int shown)
 Show or hide an entry.
void n_gui_popup_set_title (N_GUI_POPUP *popup, const char *text)
 Set the heading line over the top level.
int n_gui_popup_window (const N_GUI_POPUP *popup, int level)
 The window of a level, for an application that wants to test it.

Detailed Description

A popup menu with submenus for N_GUI, the kind a right click opens.

Author
Castagnier Mickael
Version
1.0
Date
29/09/2026

Definition in file n_gui_popup.c.


Data Structure Documentation

◆ _N_GUI_POPUP_ENTRY

struct _N_GUI_POPUP_ENTRY

one entry.

A root or a submenu is also a level and uses the fields after enabled.

Definition at line 72 of file n_gui_popup.c.

Collaboration diagram for _N_GUI_POPUP_ENTRY:
Data Fields
int child the submenu open beside it, an entry id, or -1
int enabled enabled when non-zero
float h
_N_GUI_POPUP_LEVEL * hook what the widget is handed; owned
int hover the row under the pointer, an index into rows, or -1
int kind POPUP_KIND*
int nb_rows how many rows
int parent the level it is in; -1 for the root
float * row_y top of each row from the level's top; owned, nb_rows long
int * rows entry ids of the rows as laid out at its last opening; owned
int shown shown when non-zero
int tag handed to on_pick
char * text row text, or the heading for the root; owned, may be NULL
char * tip tooltip; owned, may be NULL
float w the level's size when last laid out
int widget the level's custom widget
int window the level's window, or -1 until first opened
float x the level's position when last opened
float y

◆ _N_GUI_POPUP_LEVEL

struct _N_GUI_POPUP_LEVEL

what a level's widget is handed: stable while the entries array moves

Definition at line 63 of file n_gui_popup.c.

Collaboration diagram for _N_GUI_POPUP_LEVEL:
Data Fields
int entry the entry that is this level
N_GUI_POPUP * popup the popup

◆ N_GUI_POPUP

struct N_GUI_POPUP

the popup

a popup menu.

Opaque: make it with n_gui_popup_new(), release it with n_gui_popup_free().

Examples
ex_gui_popup.c.

Definition at line 110 of file n_gui_popup.c.

Collaboration diagram for N_GUI_POPUP:
Data Fields
int capacity allocated
N_GUI_CTX * ctx the context
_N_GUI_POPUP_ENTRY * entries the entries; 0 is the root.

Appended to only while the tree is built, so pointers into it hold while a level is open.

int nb_entries how many
N_GUI_POPUP_FN on_pick called on a pick
float scale interface scale
void * user_data handed to on_pick

Macro Definition Documentation

◆ _POPUP_KIND_ITEM

#define _POPUP_KIND_ITEM   1

an item, picked with a tag

Definition at line 56 of file n_gui_popup.c.

Referenced by _popup_activate(), and n_gui_popup_add_item().

◆ _POPUP_KIND_ROOT

#define _POPUP_KIND_ROOT   0

the top level

Definition at line 54 of file n_gui_popup.c.

Referenced by _popup_is_level(), and n_gui_popup_new().

◆ _POPUP_KIND_SEP

#define _POPUP_KIND_SEP   3

◆ _POPUP_KIND_SUB

#define _POPUP_KIND_SUB   2

◆ N_GUI_POPUP_ARROW_W

#define N_GUI_POPUP_ARROW_W   16.0f

room kept at the right of a level for the submenu arrow, at scale 1

Definition at line 46 of file n_gui_popup.c.

Referenced by _popup_layout().

◆ N_GUI_POPUP_MIN_W

#define N_GUI_POPUP_MIN_W   120.0f

narrowest a level is, at scale 1

Definition at line 48 of file n_gui_popup.c.

Referenced by _popup_layout().

◆ N_GUI_POPUP_OVERLAP

#define N_GUI_POPUP_OVERLAP   2.0f

how far a submenu overlaps its parent, at scale 1, so the pointer does not cross a gap on its way in

Definition at line 51 of file n_gui_popup.c.

Referenced by _popup_open_child().

◆ N_GUI_POPUP_PAD_X

#define N_GUI_POPUP_PAD_X   10.0f

padding left and right of a row's text, at scale 1

Definition at line 40 of file n_gui_popup.c.

Referenced by _popup_draw(), and _popup_layout().

◆ N_GUI_POPUP_PAD_Y

#define N_GUI_POPUP_PAD_Y   4.0f

padding above and below a row's text, at scale 1

Definition at line 42 of file n_gui_popup.c.

Referenced by _popup_draw(), _popup_layout(), and _popup_row_h().

◆ N_GUI_POPUP_SEP_H

#define N_GUI_POPUP_SEP_H   7.0f

height of a separator row, at scale 1

Definition at line 44 of file n_gui_popup.c.

Referenced by _popup_draw(), _popup_layout(), and _popup_row_at().

Function Documentation

◆ _popup_activate()

int _popup_activate ( N_GUI_POPUP * popup,
int level,
int row )
static

helper: act on a row: pick an item, open a submenu.

1 when it did.

Definition at line 375 of file n_gui_popup.c.

References _POPUP_KIND_ITEM, _POPUP_KIND_SUB, _popup_open_child(), _N_GUI_POPUP_ENTRY::enabled, N_GUI_POPUP::entries, _N_GUI_POPUP_ENTRY::kind, n_gui_popup_close(), _N_GUI_POPUP_ENTRY::nb_rows, N_GUI_POPUP::on_pick, row(), _N_GUI_POPUP_ENTRY::rows, _N_GUI_POPUP_ENTRY::tag, and N_GUI_POPUP::user_data.

Referenced by _popup_mouse(), and n_gui_popup_press().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _popup_append()

◆ _popup_close_level()

void _popup_close_level ( N_GUI_POPUP * popup,
int level )
static

helper: close a level and everything open beside it

Definition at line 290 of file n_gui_popup.c.

References _popup_close_level(), _N_GUI_POPUP_ENTRY::child, N_GUI_POPUP::ctx, N_GUI_POPUP::entries, _N_GUI_POPUP_ENTRY::hover, n_gui_close_window(), and _N_GUI_POPUP_ENTRY::window.

Referenced by _popup_close_level(), _popup_mouse(), _popup_open_child(), and n_gui_popup_close().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _popup_draw()

◆ _popup_font()

ALLEGRO_FONT * _popup_font ( const N_GUI_POPUP * popup)
static

helper: the font rows are measured with

Definition at line 139 of file n_gui_popup.c.

References N_GUI_POPUP::ctx, and N_GUI_CTX::default_font.

Referenced by _popup_layout(), and _popup_row_h().

Here is the caller graph for this function:

◆ _popup_has_rows()

int _popup_has_rows ( const N_GUI_POPUP * popup,
int level )
static

helper: does a level have at least one row that would be shown.

A submenu without one is not shown either: an arrow to an empty panel is a row that does nothing.

Definition at line 194 of file n_gui_popup.c.

References _popup_has_rows(), _POPUP_KIND_SEP, _POPUP_KIND_SUB, N_GUI_POPUP::entries, _N_GUI_POPUP_ENTRY::kind, N_GUI_POPUP::nb_entries, _N_GUI_POPUP_ENTRY::parent, and _N_GUI_POPUP_ENTRY::shown.

Referenced by _popup_has_rows(), and _popup_row_shows().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _popup_is_level()

int _popup_is_level ( const N_GUI_POPUP * popup,
int id )
static

helper: is this id a level (the root or a submenu)

Definition at line 134 of file n_gui_popup.c.

References _POPUP_KIND_ROOT, _POPUP_KIND_SUB, _popup_valid(), N_GUI_POPUP::entries, and _N_GUI_POPUP_ENTRY::kind.

Referenced by n_gui_popup_add_item(), n_gui_popup_add_separator(), n_gui_popup_add_submenu(), and n_gui_popup_window().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _popup_layout()

int _popup_layout ( N_GUI_POPUP * popup,
int level )
static

helper: the rows of a level, and its size.

Separators are kept only between two shown rows, once, so that hiding entries never leaves a line at an end or two lines together.

Definition at line 219 of file n_gui_popup.c.

References _popup_font(), _POPUP_KIND_SEP, _POPUP_KIND_SUB, _popup_row_h(), _popup_row_shows(), N_GUI_POPUP::entries, font, FreeNoLog, _N_GUI_POPUP_ENTRY::h, _N_GUI_POPUP_ENTRY::kind, N_GUI_POPUP_ARROW_W, N_GUI_POPUP_MIN_W, N_GUI_POPUP_PAD_X, N_GUI_POPUP_PAD_Y, N_GUI_POPUP_ROOT, N_GUI_POPUP_SEP_H, N_GUI_POPUP::nb_entries, _N_GUI_POPUP_ENTRY::nb_rows, _N_GUI_POPUP_ENTRY::parent, _N_GUI_POPUP_ENTRY::row_y, _N_GUI_POPUP_ENTRY::rows, N_GUI_POPUP::scale, _N_GUI_POPUP_ENTRY::shown, _N_GUI_POPUP_ENTRY::text, and _N_GUI_POPUP_ENTRY::w.

Referenced by _popup_open_child(), and _popup_show_level().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _popup_make_window()

◆ _popup_mouse()

◆ _popup_open_child()

void _popup_open_child ( N_GUI_POPUP * popup,
int level,
int row )
static

helper: open a submenu beside its row.

To the right of the parent, unless it would leave the display there, then to the left: a submenu pulled back over its parent would hide the row it came from.

Definition at line 358 of file n_gui_popup.c.

References _popup_close_level(), _popup_layout(), _popup_show_level(), _N_GUI_POPUP_ENTRY::child, N_GUI_POPUP::ctx, N_GUI_CTX::display_w, N_GUI_POPUP::entries, N_GUI_POPUP_OVERLAP, row(), _N_GUI_POPUP_ENTRY::row_y, _N_GUI_POPUP_ENTRY::rows, N_GUI_POPUP::scale, _N_GUI_POPUP_ENTRY::w, _N_GUI_POPUP_ENTRY::x, and _N_GUI_POPUP_ENTRY::y.

Referenced by _popup_activate(), and _popup_mouse().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _popup_row_at()

int _popup_row_at ( const N_GUI_POPUP * popup,
int level,
float ly )
static

helper: the row index at a level-local y, or -1

Definition at line 276 of file n_gui_popup.c.

References _POPUP_KIND_SEP, _popup_row_h(), N_GUI_POPUP::entries, _N_GUI_POPUP_ENTRY::kind, N_GUI_POPUP_SEP_H, _N_GUI_POPUP_ENTRY::nb_rows, _N_GUI_POPUP_ENTRY::row_y, row_y(), _N_GUI_POPUP_ENTRY::rows, and N_GUI_POPUP::scale.

Referenced by _popup_mouse().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _popup_row_h()

float _popup_row_h ( const N_GUI_POPUP * popup)
static

helper: height of an item row

Definition at line 144 of file n_gui_popup.c.

References _popup_font(), font, line(), N_GUI_POPUP_PAD_Y, and N_GUI_POPUP::scale.

Referenced by _popup_draw(), _popup_layout(), and _popup_row_at().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _popup_row_shows()

int _popup_row_shows ( const N_GUI_POPUP * popup,
int id )
static

helper: is an entry a row that shows, separators aside

Definition at line 208 of file n_gui_popup.c.

References _popup_has_rows(), _POPUP_KIND_SUB, N_GUI_POPUP::entries, _N_GUI_POPUP_ENTRY::kind, and _N_GUI_POPUP_ENTRY::shown.

Referenced by _popup_layout().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _popup_show_level()

int _popup_show_level ( N_GUI_POPUP * popup,
int level,
float x,
float y )
static

◆ _popup_valid()

int _popup_valid ( const N_GUI_POPUP * popup,
int id )
static

helper: is this id an entry

Definition at line 129 of file n_gui_popup.c.

References N_GUI_POPUP::nb_entries.

Referenced by _popup_is_level(), n_gui_popup_press(), n_gui_popup_set_enabled(), and n_gui_popup_set_shown().

Here is the caller graph for this function: