Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Window API doesn´t provide a way to get a private pointer from within the on_draw callback #8

Open
lugu opened this issue Feb 20, 2025 · 2 comments
Labels
enhancement New feature or request

Comments

@lugu
Copy link
Contributor

lugu commented Feb 20, 2025

Hi, thank you for taking the time to write Cassette!

The on_draw callback (and other callbacks like on_close or on_focus) of the window API takes a cgui_window argument and a delay. Is there a way to access a private pointer that could linked to the program state from within the callback?

Here is an example to illustrate the problem where cairo is used to draw an animation on the window:

static void on_draw(cgui_window *window, unsigned long delay) {
  // TODO: find a way to access the animation state from within the callback
  update_animation(animation, delay);
  draw_animation(animation);
  cgui_window_redraw_delayed(window, 20 /* milliseconds */);
}

One option could be to add an extra parameter to the callback (like what was done for #4). Another approach could be to store a private pointer in cgui_window (similar to what cgui_cell_set_data/cgui_cell_get_data does).

@lugu
Copy link
Contributor Author

lugu commented Feb 21, 2025

Happy to contribute if this issue is worth addressing.

@fraawlen
Copy link
Owner

fraawlen commented Feb 22, 2025

I've now added cgui_window_set_data() modeled after Glib's GObject.Object.set_data().
You can now throw in as many arbitrary pointers as you want with different identifying keys. And retrieve them with that same key:

void cgui_window_set_data(cgui_window *window, const char *key, void *data);
void *cgui_window_data(const cgui_window *window, const char *key);

To stay consistent (and avoid macros for every single callback) I decided to roll back the changes from the previous issue with button callbacks (sry about that), and adopted the same kind of setter and getters:

void cgui_cell_set_data(cgui_cell *cell, const char *key, void *data);
void *cgui_cell_data(const cgui_cell *cell, const char *key);

With a reserved key value for cell internals: CGUI_CELL_IMPLEMENTATION (defined as "_IMPL"). You're free to use any other string values for your own keys.

Therefore, the button callback is back to just:

void on_click(cgui_cell *cell);

The last few commits address all of that.


In your linked code you can now do that:

static void
on_draw(...)
{
    animation_t *anim = (animation_t *)cgui_window_data(window, "ctx");

    update_animation(anim, delay);
    draw_animation(anim);
    ...
}
static void
init_animation(...)
{
    ...
    cgui_window_set_data(animation->window, "ctx", animation);
    ...
}

Same thing for the buttons:

...
cgui_button_on_click(button, on_click);
cgui_button_set_data(button, "game", game);
...
void
on_click(cgui_cell *c)
{
    game_t *game = (game_t *)cgui_cell_data(c, "game");
}

@fraawlen fraawlen added the enhancement New feature or request label Feb 22, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants