view infinite_canvas/canvas.h @ 278:8d560f50ed4c

Improve infinite canvas interactions and browser chrome Render Lucide icons directly with Raylib, add searchable icon browsing, robust text editing, entity lifecycle animations, z-order-safe input, semantic themes, and animated editable browser controls. Document rendering, pinning, context, and component extension for future agents. Co-authored-by: Copilot <[email protected]> Copilot-Session: f68442b1-fa8f-46a0-9689-81710613bbd4
author MrJuneJune <me@mrjunejune.com>
date Mon, 17 Aug 2026 22:16:14 -0700
parents b55c22cff335
children 49e9e591c9bb
line wrap: on
line source

#ifndef INFINITE_CANVAS_CANVAS_H
#define INFINITE_CANVAS_CANVAS_H

#include "dowa/dowa.h"
#include "infinite_canvas/theme.h"
#include "third_party/raylib/include/raylib.h"

#define CANVAS_MAX_ENTITIES 1024
#define CANVAS_WEB_FRAME_INSET 8.0f
#define CANVAS_WEB_TOOLBAR_HEIGHT 42.0f
#define CANVAS_WEB_RESIZE_HANDLE 18.0f
#define CANVAS_WEB_MIN_WIDTH 160.0f
#define CANVAS_WEB_MIN_HEIGHT 120.0f
#define CANVAS_CONTEXT_MAX_LENGTH (64 * 1024)
#define CANVAS_ENTITY_TEXT_CAPACITY 2048

typedef enum {
    CANVAS_ENTITY_RECTANGLE = 0,
    CANVAS_ENTITY_CIRCLE,
    CANVAS_ENTITY_LINE,
    CANVAS_ENTITY_TEXT,
    CANVAS_ENTITY_BUTTON,
    CANVAS_ENTITY_TEXT_AREA,
    CANVAS_ENTITY_DROPDOWN,
    CANVAS_ENTITY_ACCORDION,
    CANVAS_ENTITY_CARD,
    CANVAS_ENTITY_CALENDAR,
    CANVAS_ENTITY_SWITCH,
    CANVAS_ENTITY_TABLE,
    CANVAS_ENTITY_NOTIFICATION,
    CANVAS_ENTITY_SCROLL_AREA,
    CANVAS_ENTITY_IMAGE,
    CANVAS_ENTITY_WEB_CONTENT,
    CANVAS_ENTITY_LUCIDE_GALLERY,
    CANVAS_ENTITY_TYPE_COUNT,
} Canvas_Entity_Type;

typedef struct {
    uint32 id;
    Canvas_Entity_Type type;
    Vector2 position;
    Vector2 size;
    Color color;
    char text[CANVAS_ENTITY_TEXT_CAPACITY];
    int32 value;
    int32 text_cursor;
    int32 text_selection_anchor;
    float text_scroll_y;
    float visibility_amount;
    boolean active;
    boolean pinned;
    boolean removing;
    boolean screen_space_initialized;
    float hover_amount;
    float animation_amount;
    float web_chrome_amount;
    Vector2 pinned_screen_position;
    Vector2 pinned_screen_size;
} Canvas_Entity;

typedef struct {
    Vector2 target;
    float zoom;
    int32 viewport_width;
    int32 viewport_height;
    float min_zoom;
    float max_zoom;
} Canvas_Camera;

typedef struct {
    Dowa_Arena *p_arena;
    Canvas_Entity *p_entities;
    uint32 next_entity;
    uint32 next_entity_id;
    int32 selected_index;
    int32 pressed_index;
    int32 hover_index;
    boolean dragging;
    boolean resizing;
    boolean selecting_text;
    boolean editing_web_url;
    boolean show_grid;
    float notification_stack_amount;
    uint32 web_url_entity_id;
    int32 web_url_cursor;
    int32 web_url_selection_anchor;
    float web_url_scroll_x;
    char web_url_draft[CANVAS_ENTITY_TEXT_CAPACITY];
    Vector2 pointer_start;
    Vector2 entity_start;
    Vector2 entity_size_start;
} Canvas_Scene;

typedef struct {
    size_t visible_count;
    size_t bytes_written;
    boolean truncated;
} Canvas_Context_Snapshot;

typedef enum {
    CANVAS_WEB_CHROME_NONE = 0,
    CANVAS_WEB_CHROME_CAPTURE,
    CANVAS_WEB_CHROME_BACK,
    CANVAS_WEB_CHROME_FORWARD,
    CANVAS_WEB_CHROME_NAVIGATE,
} Canvas_Web_Chrome_Action;

void Canvas_Camera_Init(Canvas_Camera *p_camera, int32 width, int32 height);
void Canvas_Camera_Set_Viewport(Canvas_Camera *p_camera, int32 width, int32 height);
Vector2 Canvas_Camera_Screen_To_World(const Canvas_Camera *p_camera, Vector2 screen);
Vector2 Canvas_Camera_World_To_Screen(const Canvas_Camera *p_camera, Vector2 world);
void Canvas_Camera_Pan(Canvas_Camera *p_camera, Vector2 screen_delta);
void Canvas_Camera_Zoom_At(
    Canvas_Camera *p_camera,
    Vector2 screen_anchor,
    float zoom_multiplier);
Rectangle Canvas_Camera_Viewport_Bounds(const Canvas_Camera *p_camera);
void Canvas_Camera_Fit_Bounds(
    Canvas_Camera *p_camera,
    Rectangle bounds,
    float padding_left,
    float padding_top,
    float padding_right,
    float padding_bottom);
float Canvas_Grid_Spacing(float zoom);
int32 Canvas_Lucide_Count_Matches(const char *p_query);
Canvas_Web_Chrome_Action Canvas_Web_Chrome_Update_Input(
    const Canvas_Camera *p_camera,
    Canvas_Scene *p_scene,
    Font font,
    const char *p_current_url);
boolean Canvas_Web_Chrome_Is_Editing(const Canvas_Scene *p_scene);

void Canvas_Scene_Init(Canvas_Scene *p_scene, Dowa_Arena *p_arena);
boolean Canvas_Scene_Add(Canvas_Scene *p_scene, Canvas_Entity_Type type, Vector2 position);
void Canvas_Scene_Clear(Canvas_Scene *p_scene);
void Canvas_Scene_Fade_Out_All(Canvas_Scene *p_scene);
void Canvas_Scene_Fade_Out_Selected(Canvas_Scene *p_scene);
void Canvas_Scene_Add_Demo(Canvas_Scene *p_scene);
void Canvas_Scene_Add_Browser_Grid(Canvas_Scene *p_scene);
boolean Canvas_Scene_Show_Lucide_Gallery(
    Canvas_Scene *p_scene,
    Canvas_Camera *p_camera);
int32 Canvas_Scene_Pick(
    const Canvas_Scene *p_scene,
    Vector2 world_pointer,
    float zoom);
int32 Canvas_Scene_Topmost_Visual(
    const Canvas_Scene *p_scene,
    Vector2 world_pointer,
    float zoom);
boolean Canvas_Scene_Update_Interaction(
    Canvas_Scene *p_scene,
    const Canvas_Camera *p_camera,
    Font font,
    boolean block_pointer_input);
boolean Canvas_Scene_Is_Text_Editing(const Canvas_Scene *p_scene);
void Canvas_Scene_Toggle_Selected_Pin(
    Canvas_Scene *p_scene,
    const Canvas_Camera *p_camera);
void Canvas_Scene_Sync_Pinned(
    Canvas_Scene *p_scene,
    const Canvas_Camera *p_camera);
void Canvas_Scene_Update_Notification_Stack(
    Canvas_Scene *p_scene,
    const Canvas_Camera *p_camera);
Canvas_Context_Snapshot Canvas_Scene_Build_Visible_Context(
    const Canvas_Scene *p_scene,
    const Canvas_Camera *p_camera,
    char *p_buffer,
    size_t buffer_size);

void Canvas_Update_Camera_Input(
    Canvas_Camera *p_camera,
    boolean block_pointer_input,
    boolean block_keyboard_input);
void Canvas_Draw_World(
    const Canvas_Camera *p_camera,
    const Canvas_Scene *p_scene,
    Font font,
    const Canvas_Theme *p_theme);
void Canvas_Draw_World_Background(
    const Canvas_Camera *p_camera,
    const Canvas_Scene *p_scene,
    const Canvas_Theme *p_theme);
void Canvas_Draw_World_Entity(
    const Canvas_Camera *p_camera,
    const Canvas_Scene *p_scene,
    size_t entity_index,
    Font font,
    const Canvas_Theme *p_theme);
void Canvas_Draw_Web_Chrome_Entity(
    const Canvas_Camera *p_camera,
    const Canvas_Scene *p_scene,
    size_t entity_index,
    Font font,
    const Canvas_Theme *p_theme,
    const char *p_url,
    boolean can_go_back,
    boolean can_go_forward);
void Canvas_Draw_World_Overlays(
    const Canvas_Camera *p_camera,
    const Canvas_Scene *p_scene,
    Font font,
    const Canvas_Theme *p_theme);

const char *Canvas_Entity_Type_Name(Canvas_Entity_Type type);

#endif