#ifndef WINDOW_H #define WINDOW_H #include "../pch.h" #include "../utils.h" using ImageID = uint32_t; using FontID = uint32_t; using TextID = uint32_t; struct Font { TTF_Font *font; bool pixel_art; }; struct Event { enum Type { NONE, QUIT, KEY_UP, KEY_DOWN, TEXT_INPUT, SCROLL, MOUSE_BUTTON_UP, MOUSE_BUTTON_DOWN, MOUSE_MOVE } type; union { struct { uint32_t key; } key; struct { char *text; uint32_t length; } text_input; struct { float x, y; } scroll; struct { uint8_t button; Vec2 position; } mouse_button; struct { Vec2 position; Vec2 delta; } mouse_move; }; }; struct Window { public: // title can be free'd by the caller after the window is created, as it's copied internally. Window(Vec2 size, const char *title); ~Window(); // Rendering functions ImageID load_image(const char *path, bool pixel_art = false); void unload_image(ImageID image_id); FontID load_font(const char *path, int font_size, bool bold = false, bool italic = false, bool underline = false, bool pixel_art = false); void unload_font(FontID font_id); // text is copied internally, so it can be free'd by the caller after the text is created. TextID create_text(FontID font_id, const char *text, uint32_t length, Color color); void unload_text(TextID text_id); bool write(TextID text_id, Vec2 position, float z, float angle = 0.0f, Vec2 scale = {1.0f, 1.0f}); bool draw(ImageID image_id, Vec2 position, float z, float angle = 0.0f, Vec2 scale = {1.0f, 1.0f}, float alpha = 1.0f); bool draw_rect(Rect rect, Color color, float z, float angle = 0.0f); void render(); // the rest of the calls only build the instruction list, this actually renders everything added to the screen (following z order) void clear(); // clears the instruction list // Event handling bool poll(Event &event); // returns true if an event was polled, false otherwise // consumes an event, (mostly for text input, to free the text input buffer) // but also so the user can decide when they're done with the event explicitly. void consume(Event &event); // Text input // Starts accepting Unicode text input events, and stops acceptong normal key down/up events for those keys. void start_text_input(); void stop_text_input(); // Clipboard get // To be free'd by the caller after use. const char *paste(); // Time uint64_t get_time(); // returns the time in milliseconds since the window was created uint64_t delta_time(); // returns the time in milliseconds since the last render call private: // internal data and functions SDL_Window *window; SDL_Renderer *renderer; Vec2 real_size; Vec2 virtual_size; Vec2 offset; float scale; // White pixel texture for drawing colored rectangles SDL_Texture *white_tex; // Image pool std::vector images; std::vector free_image_indices; // Font pool std::vector fonts; std::vector free_font_indices; // Text pool std::vector texts; std::vector free_text_indices; struct RenderInstruction { enum Type { DRAW_IMAGE, DRAW_TEXT, DRAW_RECT } type; float z; float angle; Vec2 scale; union { struct { ImageID image_id; Vec2 position; float alpha; } draw_image; struct { TextID text_id; Vec2 position; } draw_text; struct { Rect rect; Color color; } draw_rect; }; }; std::vector render_instructions; bool text_input_active; void compute_transform(); bool mouse_in_window(const Vec2 real_position, Vec2 &virtual_position); void draw_letterbox(); }; #endif