├── .github ├── FUNDING.yml └── workflows │ └── cmake-worker.yml ├── .gitignore ├── .hdoc.toml ├── CMakeLists.txt ├── CODE-OF-CONDUCT.md ├── LICENSE.md ├── README.md ├── cmake ├── io.cmake └── properties.cmake ├── ekg-ui-library.sublime-project ├── faq.txt ├── include └── ekg │ ├── core │ ├── context.hpp │ ├── pools.hpp │ └── runtime.hpp │ ├── draw │ ├── allocator.hpp │ ├── shape │ │ └── shape.hpp │ └── typography │ │ └── font.hpp │ ├── ekg.hpp │ ├── gpu │ ├── api.hpp │ ├── data.hpp │ ├── opengl │ │ ├── gl.hpp │ │ └── shaders.hpp │ └── sampler.hpp │ ├── handler │ ├── callback.hpp │ ├── callback │ │ └── handler.hpp │ ├── input.hpp │ ├── input │ │ └── handler.hpp │ ├── theme.hpp │ └── theme │ │ └── handler.hpp │ ├── io │ ├── descriptor.hpp │ ├── event.hpp │ ├── font.hpp │ ├── log.hpp │ ├── memory.hpp │ ├── timing.hpp │ └── utf.hpp │ ├── layout │ ├── docknize.hpp │ ├── extentnize.hpp │ └── scalenize.hpp │ ├── math │ ├── floating_point.hpp │ └── geometry.hpp │ ├── platform │ ├── base.hpp │ └── sdl │ │ └── sdl2.hpp │ └── ui │ ├── abstract.hpp │ ├── button │ ├── button.hpp │ └── widget.hpp │ ├── frame │ ├── frame.hpp │ └── widget.hpp │ ├── property.hpp │ └── stack.hpp ├── linux.sh ├── src ├── core │ ├── pools.cpp │ └── runtime.cpp ├── draw │ ├── allocator.cpp │ ├── shape │ │ └── shape.cpp │ └── typography │ │ └── font.cpp ├── ekg.cpp ├── gpu │ ├── data.cpp │ ├── opengl │ │ ├── gl.cpp │ │ └── shaders.cpp │ └── sampler.cpp ├── handler │ ├── callback.cpp │ ├── callback │ │ └── handler.cpp │ ├── input.cpp │ ├── input │ │ └── handler.cpp │ ├── theme.cpp │ └── theme │ │ └── handler.cpp ├── io │ ├── event.cpp │ ├── font.cpp │ ├── memory.cpp │ ├── timing.cpp │ └── utf.cpp ├── layout │ ├── docknize.cpp │ ├── extentnize.cpp │ └── scalenize.cpp ├── math │ └── geometry.cpp ├── platform │ └── sdl │ │ └── sdl2.cpp └── ui │ ├── abstract.cpp │ ├── button │ ├── button.cpp │ └── widget.cpp │ ├── frame │ ├── frame.cpp │ └── widget.cpp │ ├── property.cpp │ └── stack.cpp └── version ├── autorelease.py ├── commit.txt └── todo.txt /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: MrsRina 4 | -------------------------------------------------------------------------------- /.github/workflows/cmake-worker.yml: -------------------------------------------------------------------------------- 1 | name: CMake Worker 2 | 3 | on: 4 | push: 5 | branches: [ "version-core" ] 6 | pull_request: 7 | branches: [ "version-core" ] 8 | 9 | jobs: 10 | release: 11 | name: Release 12 | runs-on: ubuntu-latest 13 | 14 | strategy: 15 | fail-fast: false 16 | 17 | steps: 18 | - name: Checkout Repository 19 | uses: actions/checkout@v3 20 | 21 | - uses: fregante/setup-git-user@v2 22 | 23 | - name: Install Ninja 24 | uses: ashutoshvarma/setup-ninja@master 25 | 26 | - name: Linux Install Libraries 27 | run: | 28 | wget -qO- https://packages.lunarg.com/lunarg-signing-key-pub.asc | sudo tee /etc/apt/trusted.gpg.d/lunarg.asc 29 | sudo wget -qO /etc/apt/sources.list.d/lunarg-vulkan-noble.list http://packages.lunarg.com/vulkan/lunarg-vulkan-noble.list 30 | 31 | sudo apt update 32 | sudo apt install vulkan-sdk 33 | 34 | sudo apt-get install gcc-mingw-w64 g++-mingw-w64 mingw-w64-tools mingw-w64-x86-64-dev 35 | sudo apt-get install libfreetype6-dev libsdl2-dev libglew-dev libopengl-dev libglx-dev libgl1-mesa-dev libglfw3-dev 36 | 37 | wget https://github.com/libsdl-org/SDL/releases/download/release-2.30.2/SDL2-devel-2.30.2-mingw.zip 38 | unzip ./SDL2-devel-2.30.2-mingw.zip 39 | sudo cp -r ./SDL2-2.30.2/x86_64-w64-mingw32/* /usr/x86_64-w64-mingw32 40 | 41 | wget https://github.com/vokegpu/.github/releases/download/cross-platform-mingw/x86_64-w64-mingw32.zip 42 | unzip ./x86_64-w64-mingw32.zip 43 | yes | sudo cp -r ./x86_64-w64-mingw32/* /usr/x86_64-w64-mingw32/ 44 | 45 | wget https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-freetype-2.13.3-1-any.pkg.tar.zst 46 | tar --use-compress-program=unzstd -xvf ./mingw-w64-x86_64-freetype-2.13.3-1-any.pkg.tar.zst 47 | yes | sudo cp -r ./mingw64/* /usr/x86_64-w64-mingw32/ 48 | 49 | - name: Configure Linux-CMake 50 | run: > 51 | cmake -B ${{ github.workspace }}/cmake-build-debug 52 | -S ${{ github.workspace }} 53 | -G Ninja 54 | -DCMAKE_CXX_COMPILER=g++ 55 | -DEKG_ENABLE_TEST=0 56 | -DEKG_LINUX_NOT_FOUND_FREETYPE=1 57 | -DEKG_FORCE_LINUX=1 58 | 59 | - name: Build Linux-CMake 60 | run: | 61 | cmake --build ${{ github.workspace }}/cmake-build-debug 62 | sudo rm -r -f ${{ github.workspace }}/cmake-build-debug 63 | 64 | - name: Configure Windows-CMake 65 | run: > 66 | cmake -B ${{ github.workspace }}/cmake-build-debug 67 | -S ${{ github.workspace }} 68 | -G Ninja 69 | -DCMAKE_CXX_COMPILER=x86_64-w64-mingw32-g++ 70 | -DEKG_ENABLE_TEST=0 71 | -DEKG_LINUX_NOT_FOUND_FREETYPE=1 72 | -DEKG_FORCE_WINDOWS=1 73 | 74 | - name: Build Windows-CMake 75 | run: | 76 | cmake --build ${{ github.workspace }}/cmake-build-debug 77 | 78 | - name: Read Title 79 | id: commit_title 80 | run: echo ::set-output name=message::$(git log --format=%B -n 1 ${{ github.sha }}) 81 | 82 | - name: Read Description 83 | id: commit_description 84 | run: echo ::set-output name=message::$(git log --format=%B -n 1 ${{ github.sha }} | sed -n '2,$p') 85 | 86 | - name: Release if Needed 87 | if: startsWith(steps.commit_title.outputs.message, '[release]') 88 | env: 89 | GH_TOKEN: ${{ github.token }} 90 | run: | 91 | cd ${{ github.workspace }} 92 | python ./version/autorelease.py -m ${{ steps.commit_title.outputs.message }} -d ${{ steps.commit_description.outputs.message }} 93 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | test/cmake-build 2 | test/cmake-build-cache 3 | /cmake-build-debug 4 | /cmake-build 5 | .idea/ 6 | .vscode/ 7 | .sublimetext/ 8 | .obsidian/ 9 | lib/ 10 | .sublime-project.sublime-workspace 11 | *.sublime-workspace 12 | ekg-ui-library.sublime-workspace 13 | ekg-sandbox 14 | ekg-docs 15 | ekg-cmake-install 16 | a.out # idk wha damn is this 17 | -------------------------------------------------------------------------------- /.hdoc.toml: -------------------------------------------------------------------------------- 1 | [project] 2 | name = "ekg" 3 | version = "1.0.0" 4 | 5 | git_repo_url = "https://github.com/vokegpu/ekg-ui-library/" 6 | git_default_branch = "version-core" 7 | 8 | [paths] 9 | compile_commands = "cmake-build/compile_commands.json" 10 | 11 | [pages] 12 | 13 | homepage = "ekg-docs/readme.md" 14 | paths = [ 15 | "ekg-docs/model/*.md", 16 | "ekg-docs/tutorial/*.md" 17 | ] 18 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # MIT License 2 | # 3 | # Copyright (c) 2022-2025 Rina Wilk / vokegpu@gmail.com 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the "Software"), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be included in all 13 | # copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | # SOFTWARE. 22 | 23 | cmake_minimum_required(VERSION 3.15...3.31) 24 | 25 | include(cmake/io.cmake) 26 | include(cmake/properties.cmake) 27 | 28 | project( 29 | EKG 30 | VERSION ${EKG_VERSION} 31 | DESCRIPTION "Modern descriptor-based GPU-accelerated GUI library" 32 | LANGUAGES CXX 33 | ) 34 | 35 | message(STATUS "Found compiler ID: ${CMAKE_CXX_COMPILER_ID}") 36 | message(STATUS "Building EKG user interface library version ${EKG_VERSION}") 37 | message(STATUS "Generating EKG ${PLATFORM} native library") 38 | 39 | find_package(Freetype REQUIRED) 40 | 41 | file(GLOB_RECURSE HEADER_FILES "include/*.hpp") 42 | file(GLOB_RECURSE SOURCE_FILES "src/*.cpp") 43 | 44 | # exclude_files_by_regex(SOURCE_FILES /* regex */) 45 | 46 | add_library( 47 | ekg STATIC 48 | ${SOURCE_FILES} 49 | ) 50 | 51 | target_include_directories( 52 | ekg PUBLIC 53 | $ 54 | $ 55 | ${FREETYPE_INCLUDE_DIRS} 56 | ) 57 | 58 | target_compile_options( 59 | ekg PRIVATE 60 | ${COMPILE_OPTIMIZATION_NUMBER} 61 | #-Wall 62 | #-Wextra 63 | #-g 64 | ) 65 | 66 | set_target_properties( 67 | ekg PROPERTIES 68 | CXX_STANDARD 17 69 | ) 70 | 71 | message(STATUS "EKG native library building done") 72 | 73 | install( 74 | TARGETS ekg 75 | EXPORT ekg 76 | ARCHIVE DESTINATION lib 77 | LIBRARY DESTINATION lib 78 | RUNTIME DESTINATION bin 79 | ) 80 | 81 | install( 82 | DIRECTORY ./include/ekg 83 | DESTINATION include 84 | ) 85 | 86 | install( 87 | EXPORT ekg 88 | FILE EKGConfig.cmake 89 | NAMESPACE EKG:: 90 | DESTINATION lib/cmake/ekg 91 | ) 92 | 93 | message(STATUS "EKG installation config done!") 94 | -------------------------------------------------------------------------------- /CODE-OF-CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Code of Conduct 🐄 2 | 3 | ### Social 🐈 4 | 5 | EKG is an open-source project hosted by VokeGpu, EKG is `she/her`. 6 | 7 | Maintaing EKG is a voluntary work, BUT VokeGpu does not allow any of these things: 8 | - AI-generated codes ARE NOT allowed. 9 | - Racism, transphobia, hate towards any group of people, religious attack and politically motivated attacks ARE NOT allowed. 10 | - Off-topic discussions ARE NOT allowed. 11 | - Making PR(s) MUST follow the [coding-guide style](https://github.com/vokegpu/code-of-conduct-and-style-guide). 12 | 13 | ✨ 14 | 15 | ### Coding-Guide Style 🦭 16 | 17 | As mentioned PR(s) MUST follow the coding-guide style, it is very important to follow, so, the code-design fit as should be VokeGpu standard. 18 | 19 | Coding-guide style: 20 | https://github.com/vokegpu/code-of-conduct-and-style-guide 21 | 22 | 🐮 23 | 24 | # Thanks, I hope you enjoy programming here 🐈‍⬛ 25 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022-2025 Rina Wilk / vokegpu@gmail.com 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 🐄 EKG 🐈 2 | 3 | EKG is a descriptor-based low-latency memory-safety modular UI-toolkit for desktop-apps, mobile-apps, and high-performance apps. 4 | 5 | The purpose of EKG is to be an alternative way to create fancy and low-latency C++ memory-safety GUI-context. EKG is under an experimental-buildable-unstable version, which means no ready-prod release was made before. 6 | 7 | The complete article of EKG memory-safety model can be read [here](https://github.com/vokegpu/ekg-docs/blob/master/model/architecture-model.md#architecture-model). Ultimately, EKG does not use raw-ptr(s) or even smart-ptr(s), except for hardware interfaces (platform-base and rendering-api), the entire EKG use of a virtual memory with virtual address which is called `ekg::at_t`, `ekg::at_t` is a virtual-address reference pointer to EKG descriptors, you can read more about [here](https://github.com/vokegpu/ekg-docs/blob/master/model/ui-descriptor-based-model.md#ui-descriptor-based-model). 8 | 9 | ## GUIs with EKG 10 | 11 | ### Initializing 12 | 13 | This is an example for SDL2 and OpenGL 4.5, for a complete desired program [looks here](https://github.com/vokegpu/ekg-sandbox). 14 | 15 | ```cpp 16 | ekg::ft_library ft_library {}; 17 | FT_Init_FreeType(&ft_library); 18 | 19 | ekg::runtime_properties_info_t runtime_properties_info { 20 | .default_font_path_text = "./comic-mono.ttf", 21 | .default_font_path_emoji = "./twemoji.ttf", 22 | .p_platform_base = new ekg::sdl2(app.p_sdl_win), 23 | .p_gpu_api = new ekg::opengl(), 24 | .ft_library = ft_library 25 | }; 26 | 27 | ekg::runtime_t ekg_runtime {}; 28 | ekg::init( 29 | runtime_properties_info, 30 | &ekg_runtime 31 | ); 32 | 33 | while (true) { 34 | while (SDL_PollEvent(&sdl_event)) { 35 | ekg::sdl2_poll_event(sdl_event); 36 | } 37 | 38 | ekg::update(); 39 | 40 | // clear screen and previous buffers 41 | 42 | ekg::gui.ui.dt = 0.016f; 43 | ekg::render(); 44 | 45 | // swap buffers 46 | } 47 | ``` 48 | 49 | ### Widgets 50 | 51 | A simple frame using the basic of `ekg::make`! 52 | ```cpp 53 | ekg::make( 54 | ekg::stack_t meow { 55 | .tag = "moo" 56 | } 57 | ); 58 | 59 | ekg::frame_t frame_template { 60 | .tag = "meows", 61 | .rect = {20.0f, 20.0f, 200.0f, 200.0f}, 62 | .drag = ekg::dock::top, 63 | .resize = ekg::dock::left | ekg::dock::right | ekg::dock::bottom 64 | }; 65 | 66 | auto &my_frame = ekg::make(frame_template); 67 | ``` 68 | 69 | ## Building 70 | 71 | EKG is C++17-based and is supported by: 72 | | - | GNU-MinGW-w64 73 | | - | GNU-G++ 74 | | - | Clang++ 75 | 76 | Dependencies for building binary: 77 | | - | [FreeType](https://freetype.org/) 78 | | - | [GLEW](https://glew.sourceforge.net/) 79 | | - | [SDL2](https://www.libsdl.org/) 80 | | - | [Ninja](https://ninja-build.org/) 81 | | - | [CMake](https://cmake.org/) 82 | 83 | Note: EKG is not SDL2 or GLEW fixed, this is for compile the entire library, for using the library you will not need to compile SDL2 or even GLEW with EKG, you can choose soon Vulkan and GLFW. 84 | 85 | Run the following commands: 86 | ```cpp 87 | cmake -S . -B ./cmake-build -G Ninja -D CMAKE_BUILD_TYPE=Release 88 | cmake --build ./cmake-build 89 | ``` 90 | 91 | Supported video APIs: 92 | | - | OpenGL 3.1~4.6 93 | | - | OpenGL ES 3 94 | | - | Emscripten WebGL 2 (OpenGL ES 2) (require building EKG with flag `-D EKG_EMSCRIPTEN_BUILD_TYPE=1`) 95 | 96 | Supported platforms: 97 | | - | SDL2 98 | 99 | ## Contributing 100 | 101 | Contributing for EKG is nicely welcome, please confer [EKG docs and read the model architecture](https://github.com/vokegpu/ekg-docs?tab=readme-ov-file#ekg-technical-details) for prevent ~useless~ pull requests. 102 | -------------------------------------------------------------------------------- /cmake/io.cmake: -------------------------------------------------------------------------------- 1 | function( 2 | exclude_files_by_regex 3 | src_files 4 | regex 5 | ) 6 | foreach(PATH ${${src_files}}) 7 | if(${PATH} MATCHES ${regex}) 8 | message(STATUS "Removed: '${PATH}'") 9 | list(REMOVE_ITEM ${src_files} ${PATH}) 10 | else() 11 | message(STATUS "Keep: '${PATH}'") 12 | endif() 13 | endforeach() 14 | 15 | return( 16 | PROPAGATE 17 | ${src_files} 18 | ) 19 | endfunction() 20 | -------------------------------------------------------------------------------- /cmake/properties.cmake: -------------------------------------------------------------------------------- 1 | set(EKG_VERSION 2.0.0) 2 | set(EKG_INCLUDE_DIRS "${CMAKE_INSTALL_PREFIX}/include") 3 | 4 | if(CMAKE_TOOLCHAIN_FILE) 5 | string( 6 | REGEX MATCH 7 | "/Emscripten" 8 | compiler_filename 9 | ${CMAKE_TOOLCHAIN_FILE} 10 | ) 11 | 12 | if( 13 | EKG_EMSCRIPTEN_BUILD_TYPE 14 | OR 15 | ${compiler_filename} STREQUAL "/Emscripten" 16 | ) 17 | message(STATUS "Toolchain ID: ${compiler_filename}, WASM build-type") 18 | set(EKG_EMSCRIPTEN_BUILD_TYPE 1) 19 | elseif(EKG_EMSCRIPTEN_BUILD_TYPE) 20 | message(FATAL_ERROR "No specialized toolchain ID was found with '/Emscripten' for WASM build-type") 21 | endif() 22 | elseif(EKG_EMSCRIPTEN_BUILD_TYPE) 23 | message(FATAL_ERROR "No specialized toolchain ID was found with '/Emscripten' for WASM build-type") 24 | endif() 25 | 26 | if( 27 | CMAKE_BUILD_TYPE STREQUAL "Release" 28 | AND 29 | EKG_EMSCRIPTEN_BUILD_TYPE 30 | OR 31 | CMAKE_CXX_COMPILER_ID STREQUAL "GNU" 32 | OR 33 | CMAKE_CXX_COMPILER_ID STREQUAL "Clang" 34 | ) 35 | set(COMPILE_OPTIMIZATION_NUMBER -O3) 36 | endif() 37 | 38 | if(WIN32 OR EKG_FORCE_WINDOWS) 39 | set(LIBRARY_OUTPUT_PATH "../lib/windows/") 40 | set(PLATFORM "windows") 41 | elseif(ANDROID OR EKG_FORCE_ANDROID) 42 | set(LIBRARY_OUTPUT_PATH "${ANDROID_ABI}/") 43 | set(PLATFORM "${ANDROID_ABI}") 44 | elseif(EKG_EMSCRIPTEN_BUILD_TYPE) 45 | set(LIBRARY_OUTPUT_PATH "../lib/linux-wasm/") 46 | set(PLATFORM "linux-wasm") 47 | elseif(LINUX OR EKG_FORCE_LINUX) 48 | # WSL is not detected as Linux-based OS, same you use a Linux kernel-based distribution. 49 | set(LIBRARY_OUTPUT_PATH "../lib/linux/") 50 | set(PLATFORM "linux") 51 | endif() 52 | -------------------------------------------------------------------------------- /ekg-ui-library.sublime-project: -------------------------------------------------------------------------------- 1 | { 2 | "folders": 3 | [ 4 | { 5 | "path": ".", 6 | } 7 | ], 8 | "settings": 9 | { 10 | "tab_size": 2, 11 | "translate_tabs_to_spaces": true, 12 | "LSP": 13 | { 14 | "clangd": 15 | { 16 | "system_binary": "clangd", 17 | "initializationOptions": 18 | { 19 | "clangd.compile-commands-dir": "$folder/cmake-build" 20 | } 21 | }, 22 | }, 23 | }, 24 | "build_systems": 25 | [ 26 | { 27 | "name": "Build Linux GNU", 28 | "shell_cmd": 29 | "cd $folder && EKG_BUILD_MODE=build-only EKG_BUILD_COMPILER=/usr/bin/g++ sh ./linux.sh" 30 | }, 31 | { 32 | "name": "Build-&-Test Linux GNU", 33 | "shell_cmd": 34 | "cd $folder && EKG_BUILD_MODE=build-and-test EKG_BUILD_COMPILER=/usr/bin/g++ sh ./linux.sh" 35 | }, 36 | { 37 | "name": "Build Linux Clang", 38 | "shell_cmd": 39 | "cd $folder && EKG_BUILD_MODE=build-only EKG_BUILD_COMPILER=/usr/bin/g++ sh ./linux.sh" 40 | }, 41 | { 42 | "name": "Build-&-Test Linux Clang", 43 | "shell_cmd": 44 | "cd $folder && EKG_BUILD_MODE=build-and-test EKG_BUILD_COMPILER=/usr/bin/clang++ sh ./linux.sh" 45 | }, 46 | { 47 | "name": "Build Linux WASM/emscripten", 48 | "shell_cmd": 49 | "cd $folder && EKG_BUILD_MODE=build-only EKG_BUILD_COMPILER=emscripten sh ./linux.sh" 50 | }, 51 | { 52 | "name": "Build Windows GNU", 53 | "shell_cmd": 54 | "cd $folder && cmake -S . -B ./cmake-build/ -G Ninja -DCMAKE_BUILD_TYPE=Release -DCMAKE_EXPORT_COMPILE_COMMANDS=1 && cmake --build ./cmake-build/" 55 | }, 56 | { 57 | "name": "Build-&-Test Windows GNU", 58 | "shell_cmd": 59 | "cd $folder && cmake -S . -B ./cmake-build/ -G Ninja -DCMAKE_BUILD_TYPE=Release -DCMAKE_EXPORT_COMPILE_COMMANDS=1 && cmake --build ./cmake-build/ && cd ./ekg-sandbox && cmake -S . -B ./cmake-build -G Ninja -DEKG_DEVELOPER_MODE=1 && cmake --build ./cmake-build && cd ./bin && ./ekg-showcase", 60 | }, 61 | ], 62 | } 63 | -------------------------------------------------------------------------------- /faq.txt: -------------------------------------------------------------------------------- 1 | meow meow dim meow 2 | 3 | - Rina Wilk, 24/11/2024 at 22:38 4 | -------------------------------------------------------------------------------- /include/ekg/core/context.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License 3 | * 4 | * Copyright (c) 2022-2025 Rina Wilk / vokegpu@gmail.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | #ifndef EKG_CORE_CONTEXT_HPP 25 | #define EKG_CORE_CONTEXT_HPP 26 | 27 | #include "ekg/math/geometry.hpp" 28 | #include "ekg/io/descriptor.hpp" 29 | 30 | namespace ekg { 31 | extern struct metrics_t { 32 | public: 33 | size_t gpu_data_count {}; 34 | } metrics; 35 | 36 | extern struct dpi_t { 37 | public: 38 | ekg::rect_t viewport {}; 39 | ekg::rect_t scale {0.0f, 0.0f, 1080.0f, 1920.0f}; 40 | bool auto_scale {}; 41 | float scale_interval {25.0f}; 42 | float factor_scale {}; 43 | float font_scale {}; 44 | float min_sizes {10.0f}; 45 | ekg::vec2_t font_offset {4, 6}; 46 | } dpi; 47 | 48 | extern struct gui_t { 49 | public: 50 | struct bind_t { 51 | public: 52 | ekg::at_t stack_at {ekg::at_t::not_found}; 53 | ekg::at_t swap_at {ekg::at_t::not_found}; 54 | ekg::at_t parent_at {ekg::at_t::not_found}; 55 | }; 56 | 57 | // @TODO: add last for press, release and hover 58 | 59 | struct ui_t { 60 | public: 61 | ekg::at_t abs_widget_at {ekg::at_t::not_found}; 62 | ekg::type hovered_type {}; 63 | ekg::at_t hovered_at {ekg::at_t::not_found}; 64 | ekg::at_t last_hovered_at {ekg::at_t::not_found}; 65 | ekg::type pressed_type {}; 66 | ekg::at_t pressed_at {ekg::at_t::not_found}; 67 | ekg::type released_type {}; 68 | ekg::at_t released_at {ekg::at_t::not_found}; 69 | float dt {}; 70 | bool redraw {}; 71 | }; 72 | public: 73 | ekg::gui_t::bind_t bind {}; 74 | ekg::gui_t::ui_t ui {}; 75 | } gui; 76 | 77 | constexpr uint32_t minimum_small_font_height {4}; 78 | constexpr uint32_t minimum_font_height {8}; 79 | constexpr uint32_t minimum_big_font_height {12}; 80 | } 81 | 82 | #endif 83 | -------------------------------------------------------------------------------- /include/ekg/core/pools.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License 3 | * 4 | * Copyright (c) 2022-2025 Rina Wilk / vokegpu@gmail.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | #ifndef EKG_CORE_POOLS_HPP 25 | #define EKG_CORE_POOLS_HPP 26 | 27 | #include "ekg/io/memory.hpp" 28 | #include "ekg/handler/callback.hpp" 29 | #include "ekg/gpu/sampler.hpp" 30 | #include "ekg/ui/property.hpp" 31 | #include "ekg/ui/stack.hpp" 32 | #include "context.hpp" 33 | #include "ekg/handler/theme.hpp" 34 | 35 | #include "ekg/ui/button/button.hpp" 36 | #include "ekg/ui/button/widget.hpp" 37 | 38 | #include "ekg/ui/frame/frame.hpp" 39 | #include "ekg/ui/frame/widget.hpp" 40 | 41 | namespace ekg::core { 42 | void registry(ekg::property_t &property); 43 | } 44 | 45 | #define ekg_abstract_todo(ekg_abstract_todo_at_type, ekg_abstract_todo_at, ekg_abstract_todo_todo) \ 46 | switch (ekg_abstract_todo_at_type) { \ 47 | case ekg::type::button: { \ 48 | ekg::button_t &descriptor { \ 49 | ekg::query(ekg_abstract_todo_at) \ 50 | }; \ 51 | if (descriptor == ekg::button_t::not_found) { \ 52 | break; \ 53 | } \ 54 | ekg_abstract_todo_todo \ 55 | break; \ 56 | } \ 57 | case ekg::type::frame: { \ 58 | ekg::frame_t &descriptor { \ 59 | ekg::query(ekg_abstract_todo_at) \ 60 | }; \ 61 | if (descriptor == ekg::frame_t::not_found) { \ 62 | break; \ 63 | } \ 64 | ekg_abstract_todo_todo \ 65 | break; \ 66 | } \ 67 | } 68 | 69 | #define ekg_registry_widget(widget_descriptor_t, register_widget_pool, register_property_pool, is_container, register_settings) \ 70 | widget_descriptor_t &widget { \ 71 | register_widget_pool.push_back( \ 72 | ekg::io::any_static_cast(&descriptor) \ 73 | ) \ 74 | }; \ 75 | ekg::property_t &property { \ 76 | register_property_pool.push_back({}) \ 77 | }; \ 78 | \ 79 | widget.at.flags = widget_descriptor_t::type; \ 80 | property.descriptor_at = widget.at; \ 81 | \ 82 | property.at.flags = widget_descriptor_t::type; \ 83 | widget.property_at = property.at; \ 84 | \ 85 | ekg::theme_t &global_theme {ekg::theme()};\ 86 | \ 87 | register_settings; \ 88 | \ 89 | ekg::stack_t &stack {ekg::query(ekg::gui.bind.stack_at)}; \ 90 | if (stack != ekg::stack_t::not_found) { \ 91 | stack.widgets.push_back(widget.at); \ 92 | } \ 93 | \ 94 | ekg::property_t &parent {ekg::query(ekg::gui.bind.parent_at)}; \ 95 | if (parent != ekg::property_t::not_found && is_container) { \ 96 | if (widget.dock != ekg::dock::none) { \ 97 | parent.children.push_back(widget.at); \ 98 | } else { \ 99 | ekg::gui.bind.parent_at = widget.at; \ 100 | } \ 101 | } else if (parent != ekg::property_t::not_found) { \ 102 | parent.children.push_back(widget.at); \ 103 | } \ 104 | \ 105 | ekg::core::registry(property); \ 106 | return ekg::io::any_static_cast(&widget); 107 | 108 | namespace ekg { 109 | extern struct pools_t { 110 | public: 111 | ekg::pool stack {}; 112 | ekg::pool callback {}; 113 | ekg::pool sampler {}; 114 | 115 | ekg::pool button_property {}; 116 | ekg::pool button {}; 117 | 118 | ekg::pool frame_property {}; 119 | ekg::pool frame {}; 120 | } pools; 121 | 122 | template 123 | t &query( 124 | ekg::at_t &at 125 | ) { 126 | switch (t::type) { 127 | case ekg::type::stack: 128 | return ekg::io::any_static_cast( 129 | &ekg::pools.stack.query(at) 130 | ); 131 | case ekg::type::callback: 132 | return ekg::io::any_static_cast( 133 | &ekg::pools.callback.query(at) 134 | ); 135 | case ekg::type::sampler: 136 | return ekg::io::any_static_cast( 137 | &ekg::pools.sampler.query(at) 138 | ); 139 | case ekg::type::property: 140 | switch (at.flags) { 141 | case ekg::type::button: 142 | return ekg::io::any_static_cast( 143 | &ekg::pools.button_property.query(at) 144 | ); 145 | case ekg::type::frame: 146 | return ekg::io::any_static_cast( 147 | &ekg::pools.frame_property.query(at) 148 | ); 149 | } 150 | case ekg::type::button: 151 | return ekg::io::any_static_cast( 152 | &ekg::pools.button.query(at) 153 | ); 154 | case ekg::type::frame: 155 | return ekg::io::any_static_cast( 156 | &ekg::pools.frame.query(at) 157 | ); 158 | } 159 | 160 | return t::not_found; 161 | } 162 | 163 | template 164 | t &make( 165 | t descriptor 166 | ) { 167 | switch (t::type) { 168 | case ekg::type::stack: { 169 | ekg::stack_t &stack { 170 | ekg::pools.stack.push_back( 171 | ekg::io::any_static_cast(&descriptor) 172 | ) 173 | }; 174 | 175 | ekg::gui.bind.stack_at = stack.at; 176 | 177 | return ekg::io::any_static_cast( 178 | &stack 179 | ); 180 | } 181 | case ekg::type::callback: 182 | return ekg::io::any_static_cast( 183 | &ekg::pools.callback.push_back( 184 | ekg::io::any_static_cast(&descriptor) 185 | ) 186 | ); 187 | case ekg::type::sampler: 188 | return ekg::io::any_static_cast( 189 | &ekg::pools.sampler.push_back( 190 | ekg::io::any_static_cast(&descriptor) 191 | ) 192 | ); 193 | case ekg::type::button: { 194 | ekg_registry_widget( 195 | ekg::button_t, 196 | ekg::pools.button, 197 | ekg::pools.button_property, 198 | false, 199 | { 200 | property.widget.is_childnizate = false; 201 | property.widget.is_children_docknizable = false; 202 | widget.color_scheme = global_theme.button_color_scheme; 203 | } 204 | ); 205 | } 206 | case ekg::type::frame: { 207 | ekg_registry_widget( 208 | ekg::frame_t, 209 | ekg::pools.frame, 210 | ekg::pools.frame_property, 211 | true, 212 | { 213 | property.widget.is_childnizate = true; 214 | property.widget.is_children_docknizable = true; 215 | widget.color_scheme = global_theme.frame_color_scheme; 216 | } 217 | ); 218 | }} 219 | 220 | return t::not_found; 221 | } 222 | } 223 | 224 | #endif 225 | -------------------------------------------------------------------------------- /include/ekg/core/runtime.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License 3 | * 4 | * Copyright (c) 2022-2025 Rina Wilk / vokegpu@gmail.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | #ifndef EKG_CORE_RUNTIME_HPP 25 | #define EKG_CORE_RUNTIME_HPP 26 | 27 | #include "ekg/platform/base.hpp" 28 | #include "ekg/gpu/api.hpp" 29 | #include "ekg/draw/typography/font.hpp" 30 | #include "ekg/draw/allocator.hpp" 31 | #include "ekg/handler/theme/handler.hpp" 32 | #include "ekg/handler/callback/handler.hpp" 33 | #include "ekg/handler/callback.hpp" 34 | #include "ekg/handler/input/handler.hpp" 35 | #include "ekg/layout/docknize.hpp" 36 | 37 | namespace ekg { 38 | struct runtime_properties_info_t { 39 | public: 40 | std::string_view default_font_path_text {}; 41 | std::string_view default_font_path_emoji {}; 42 | ekg::platform::base *p_platform_base {}; 43 | ekg::gpu::api *p_gpu_api {}; 44 | ekg::ft_library ft_library {}; 45 | }; 46 | 47 | extern struct runtime_t { 48 | public: 49 | ekg::platform::base *p_platform_base {}; 50 | ekg::gpu::api *p_gpu_api {}; 51 | ekg::ft_library ft_library {}; 52 | public: 53 | ekg::handler::input handler_input {}; 54 | ekg::handler::callback handler_callback {}; 55 | ekg::handler::theme handler_theme {}; 56 | public: 57 | ekg::draw::allocator draw_allocator {}; 58 | ekg::draw::font draw_font_small {}; 59 | ekg::draw::font draw_font_medium {}; 60 | ekg::draw::font draw_font_big {}; 61 | public: 62 | std::vector collector {}; 63 | std::vector registry {}; 64 | std::vector stack {}; 65 | std::vector top_level_stack {}; 66 | std::vector reload {}; 67 | std::vector docknize {}; 68 | std::vector high_frequency {}; 69 | } *p_core; 70 | } 71 | 72 | namespace ekg::core { 73 | void swap_collector(bool &was_found, ekg::at_t &property_at); 74 | void swap(ekg::info_t &info); 75 | void reload(ekg::info_t &info); 76 | void docknize(ekg::info_t &info); 77 | void scalenize(ekg::info_t &info); 78 | void poll_event(); 79 | } 80 | 81 | #endif 82 | -------------------------------------------------------------------------------- /include/ekg/draw/allocator.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License 3 | * 4 | * Copyright (c) 2022-2025 Rina Wilk / vokegpu@gmail.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | #ifndef EKG_DRAW_ALLOCATOR_HPP 25 | #define EKG_DRAW_ALLOCATOR_HPP 26 | 27 | #include 28 | 29 | #include "ekg/math/geometry.hpp" 30 | #include "ekg/gpu/data.hpp" 31 | #include "ekg/gpu/sampler.hpp" 32 | 33 | /** 34 | * This macro prevent from dispatching any GPU-data under a render section 35 | * if the content is not visible to the parent rect_scissor. 36 | **/ 37 | #define ekg_assert_scissor(rect_scissor, rect_child, rect_parent, is_parented) \ 38 | if (!ekg::p_core->draw_allocator.sync_scissor(rect_scissor, rect_child, rect_parent, is_parented)) return; 39 | 40 | namespace ekg::draw { 41 | class allocator { 42 | public: 43 | static bool enable_high_priority; 44 | static bool is_simple_shape; 45 | protected: 46 | size_t data_instance {}; 47 | ekg::vec2_t stride_instance {}; 48 | size_t simple_shape_instance {}; 49 | size_t geometry_instance {}; 50 | size_t high_priority_data_instance {}; 51 | ekg::rect_t scissor_instance {}; 52 | 53 | std::vector gpu_data_buffer {}; 54 | std::vector high_priority_gpu_data_buffer {}; 55 | std::vector geometry_buffer {}; 56 | size_t last_geometry_buffer_size {}; 57 | 58 | bool was_hash_changed {}; 59 | int32_t previous_hash {}; 60 | public: 61 | void init(); 62 | void quit(); 63 | 64 | void invoke(); 65 | void revoke(); 66 | void to_gpu(); 67 | 68 | void bind_texture(ekg::sampler_t &sampler); 69 | ekg::gpu::data_t &bind_current_data(); 70 | size_t get_current_data_id(); 71 | ekg::gpu::data_t &get_data_by_index(size_t index); 72 | void clear_current_data(); 73 | void dispatch(); 74 | 75 | bool sync_scissor( 76 | ekg::rect_t &rect_scissor, 77 | ekg::rect_t &rect_child, 78 | ekg::rect_t &rect_parent_scissor, 79 | bool is_parented 80 | ); 81 | 82 | void unsafe_set_scissor_rect( 83 | float x, float y, float w, float h 84 | ); 85 | 86 | void push_back_geometry( 87 | float x, float y, 88 | float u, float v 89 | ); 90 | }; 91 | } 92 | 93 | #endif 94 | -------------------------------------------------------------------------------- /include/ekg/draw/shape/shape.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License 3 | * 4 | * Copyright (c) 2022-2025 Rina Wilk / vokegpu@gmail.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | #ifndef EKG_DRAW_SHAPE_HPP 25 | #define EKG_DRAW_SHAPE_HPP 26 | 27 | #include "ekg/math/geometry.hpp" 28 | #include "ekg/gpu/sampler.hpp" 29 | 30 | namespace ekg::draw { 31 | enum mode : int8_t { 32 | fill = 0, 33 | outline = 1 34 | }; 35 | 36 | void rect( 37 | const ekg::rect_t &rect, 38 | const ekg::rgba_t &color, 39 | ekg::pixel_thickness_t line_thicnkess, 40 | ekg::sampler_t &sampler 41 | ); 42 | 43 | void rect( 44 | float x, float y, float w, float h, 45 | const ekg::rgba_t &color, 46 | ekg::pixel_thickness_t line_thicnkess, 47 | ekg::sampler_t &sampler 48 | ); 49 | 50 | void scissor( 51 | const ekg::rect_t &rect 52 | ); 53 | 54 | void scissor( 55 | float x, float y, float w, float h 56 | ); 57 | } 58 | 59 | #endif 60 | -------------------------------------------------------------------------------- /include/ekg/draw/typography/font.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License 3 | * 4 | * Copyright (c) 2022-2025 Rina Wilk / vokegpu@gmail.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | #ifndef EKG_DRAW_TYPOGRAPHY_FONT_HPP 25 | #define EKG_DRAW_TYPOGRAPHY_FONT_HPP 26 | 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | 33 | #include "ekg/math/geometry.hpp" 34 | #include "ekg/io/font.hpp" 35 | #include "ekg/gpu/sampler.hpp" 36 | 37 | namespace ekg::draw { 38 | class font { 39 | public: 40 | std::vector new_glyphs_to_atlas {}; 41 | size_t last_sampler_generate_list_size {}; 42 | 43 | std::unordered_map mapped_glyph {}; 44 | std::array faces {}; 45 | 46 | ekg::at_t atlas_texture_sampler_at {ekg::at_t::not_found}; 47 | ekg::rect_t atlas_rect {}; 48 | float offset_text_height {}; 49 | 50 | uint32_t font_size {}; 51 | float text_height {}; 52 | float non_swizzlable_range {}; 53 | FT_Bool ft_bool_kerning {}; 54 | 55 | bool font_size_changed {}; 56 | bool was_initialized {}; 57 | bool is_any_functional_font_face_loaded {}; 58 | public: 59 | void init(); 60 | void quit(); 61 | void flush(); 62 | 63 | ekg::sampler_t &get_atlas_texture_sampler(); 64 | float get_text_width(const std::string_view &text); 65 | float get_text_width(const std::string_view &text, int32_t &lines); 66 | float get_text_height(); 67 | 68 | void set_font_emoji(const std::string_view &font_face_emoji_path); 69 | void set_font(const std::string_view &font_face_path); 70 | void set_size(uint32_t font_face_size); 71 | void reload(); 72 | 73 | void blit( 74 | const std::string_view &text, 75 | float x, float y, 76 | const ekg::rgba_t &color 77 | ); 78 | }; 79 | 80 | ekg::draw::font &get_font_renderer(ekg::font font); 81 | } 82 | 83 | #endif 84 | -------------------------------------------------------------------------------- /include/ekg/ekg.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License 3 | * 4 | * Copyright (c) 2022-2025 Rina Wilk / vokegpu@gmail.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | #ifndef EKG_HPP 25 | #define EKG_HPP 26 | 27 | #include "ekg/io/memory.hpp" 28 | #include "ekg/core/runtime.hpp" 29 | #include "ekg/core/context.hpp" 30 | #include "ekg/core/pools.hpp" 31 | #include "ekg/math/floating_point.hpp" 32 | #include "ekg/math/geometry.hpp" 33 | #include "ekg/io/log.hpp" 34 | 35 | namespace ekg { 36 | ekg::flags_t init( 37 | ekg::runtime_properties_info_t &runtime_properties_info, 38 | ekg::runtime_t *p_runtime 39 | ); 40 | 41 | void quit(); 42 | void update(); 43 | void render(); 44 | } 45 | 46 | #endif 47 | -------------------------------------------------------------------------------- /include/ekg/gpu/api.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License 3 | * 4 | * Copyright (c) 2022-2025 Rina Wilk / vokegpu@gmail.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | #ifndef EKG_GPU_API_HPP 25 | #define EKG_GPU_API_HPP 26 | 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | 33 | #include "sampler.hpp" 34 | #include "data.hpp" 35 | #include "ekg/math/geometry.hpp" 36 | #include "ekg/io/font.hpp" 37 | 38 | namespace ekg { 39 | enum class which_gpu_api { 40 | opengl, 41 | opengles, 42 | vulkan 43 | }; 44 | } 45 | 46 | namespace ekg::gpu { 47 | class api { 48 | protected: 49 | float mat4x4_proj_matrix[16] {}; 50 | public: 51 | ekg::which_gpu_api which_gpu_api {}; 52 | public: 53 | virtual void log_vendor_details() {}; 54 | virtual void init() {}; 55 | virtual void quit() {}; 56 | virtual void invoke_pipeline() {}; 57 | virtual void revoke_pipeline() {}; 58 | virtual void pre_re_alloc() {}; 59 | 60 | virtual void update_viewport( 61 | int32_t w, 62 | int32_t h 63 | ) {}; 64 | 65 | virtual void pass_geometry_buffer_to_gpu( 66 | const float *p_data, 67 | uint64_t size 68 | ) {}; 69 | 70 | virtual void pass_gpu_data_buffer_to_gpu( 71 | std::vector &gpu_data_buffer 72 | ) {}; 73 | 74 | virtual ekg::flags_t gen_font_atlas_and_map_glyph( 75 | ekg::sampler_t &sampler, 76 | ekg::io::font_face_t *p_font_face_text, 77 | ekg::io::font_face_t *p_font_face_emoji, 78 | ekg::io::font_face_t *p_font_face_kanjis, 79 | ekg::rect_t &atlas_rect, 80 | std::vector &char_to_gen_sampler_list, 81 | std::unordered_map &mapped_gpu_data_char_glyph, 82 | float &non_swizzlable_range 83 | ) { return ekg::result::failed_not_implemented; }; 84 | 85 | virtual ekg::flags_t allocate_sampler( 86 | ekg::sampler_allocate_info_t &sampler_allocate_info, 87 | ekg::sampler_t &sampler 88 | ) { return ekg::result::failed_not_implemented; } 89 | 90 | virtual ekg::flags_t fill_sampler( 91 | ekg::sampler_fill_info_t &sampler_fill_info, 92 | ekg::sampler_t &sampler 93 | ) { return ekg::result::failed_not_implemented; }; 94 | 95 | virtual ekg::at_t &bind_sampler( 96 | ekg::sampler_t &sampler 97 | ) { return ekg::at_t::not_found; }; 98 | }; 99 | } 100 | 101 | #endif 102 | -------------------------------------------------------------------------------- /include/ekg/gpu/data.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License 3 | * 4 | * Copyright (c) 2022-2025 Rina Wilk / vokegpu@gmail.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | #ifndef EKG_GPU_DATA_HPP 25 | #define EKG_GPU_DATA_HPP 26 | 27 | #include "ekg/io/memory.hpp" 28 | #include "ekg/io/descriptor.hpp" 29 | 30 | namespace ekg::gpu { 31 | struct data_t { 32 | public: 33 | static ekg::gpu::data_t not_found; 34 | public: 35 | float buffer[12] {}; 36 | ekg::at_t sampler_at {ekg::at_t::not_found}; 37 | int8_t line_thickness {}; 38 | int32_t begin_stride {}; 39 | int32_t end_stride {}; 40 | ekg::hash_t hash {}; 41 | int32_t scissor_id {-1}; 42 | public: 43 | ekg_descriptor(ekg::gpu::data_t); 44 | }; 45 | } 46 | 47 | #endif 48 | -------------------------------------------------------------------------------- /include/ekg/gpu/opengl/gl.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License 3 | * 4 | * Copyright (c) 2022-2025 Rina Wilk / vokegpu@gmail.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | #ifndef EKG_GPU_OPENGL_GL_HPP 25 | #define EKG_GPU_OPENGL_GL_HPP 26 | 27 | #if defined(__ANDROID__) 28 | #include 29 | #else 30 | #include 31 | #endif 32 | 33 | #include 34 | #include 35 | 36 | #include "ekg/gpu/api.hpp" 37 | 38 | #define EKG_DISABLE_TEXTURE 0 39 | #define EKG_ENABLE_TEXTURE_PROTECTED 1 40 | #define EKG_ENABLE_TEXTURE 2 41 | 42 | namespace ekg { 43 | class opengl : public ekg::gpu::api { 44 | protected: 45 | std::vector bound_sampler_list {}; 46 | std::string_view glsl_version {}; 47 | 48 | int32_t uniform_active_texture {}; 49 | int32_t uniform_active_tex_slot {}; 50 | int32_t uniform_content {}; 51 | int32_t uniform_rect {}; 52 | int32_t uniform_line_thickness {}; 53 | int32_t uniform_scissor {}; 54 | int32_t uniform_viewport_height {}; 55 | int32_t uniform_projection {}; 56 | 57 | uint32_t geometry_buffer {}; 58 | uint32_t vbo_array {}; 59 | uint32_t ebo_simple_shape {}; 60 | uint32_t pipeline_program {}; 61 | uint8_t protected_texture_active_index {}; 62 | public: 63 | bool create_pipeline_program( 64 | uint32_t &program, 65 | const std::unordered_map &resources 66 | ); 67 | public: 68 | /** 69 | * OpenGL API wrapper abstraction constructor; 70 | * `set_glsl_version` must be 330 higher, if not, the version is auto-initialized as `450`. 71 | * OpenGL ES 3 needs explicit set to the GLSL ES version. 72 | */ 73 | explicit opengl(std::string_view set_glsl_version = "#version 450"); 74 | public: 75 | void log_vendor_details() override; 76 | 77 | void init() override; 78 | void quit() override; 79 | void pre_re_alloc() override; 80 | void update_viewport(int32_t w, int32_t h) override; 81 | void pass_geometry_buffer_to_gpu(const float *p_data, uint64_t size) override; 82 | 83 | void pass_gpu_data_buffer_to_gpu( 84 | std::vector &gpu_data_buffer 85 | ) override; 86 | 87 | ekg::flags_t allocate_sampler( 88 | ekg::sampler_allocate_info_t &sampler_allocate_info, 89 | ekg::sampler_t &sampler 90 | ) override; 91 | 92 | ekg::flags_t fill_sampler( 93 | ekg::sampler_fill_info_t &sampler_fill_info, 94 | ekg::sampler_t &sampler 95 | ) override; 96 | 97 | ekg::flags_t gen_font_atlas_and_map_glyph( 98 | ekg::sampler_t &sampler, 99 | ekg::io::font_face_t *p_font_face_text, 100 | ekg::io::font_face_t *p_font_face_emoji, 101 | ekg::io::font_face_t *p_font_face_kanjis, 102 | ekg::rect_t &atlas_rect, 103 | std::vector &char_to_gen_sampler_list, 104 | std::unordered_map &mapped_gpu_data_char_glyph, 105 | float &non_swizzlable_range 106 | ) override; 107 | 108 | ekg::at_t &bind_sampler( 109 | ekg::sampler_t &sampler 110 | ) override; 111 | }; 112 | } 113 | 114 | #endif 115 | -------------------------------------------------------------------------------- /include/ekg/gpu/opengl/shaders.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License 3 | * 4 | * Copyright (c) 2022-2025 Rina Wilk / vokegpu@gmail.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | #ifndef EKG_GPU_OPENGL_SHADERS_HPP 25 | #define EKG_GPU_OPENGL_SHADERS_HPP 26 | 27 | #include "ekg/gpu/api.hpp" 28 | 29 | namespace ekg::gpu { 30 | void glsl_opengl_pipeline_vsh( 31 | const std::string &glsl_version, 32 | ekg::which_gpu_api which_gpu_api, 33 | std::string &out_shader 34 | ); 35 | 36 | void glsl_opengl_pipeline_fsh( 37 | const std::string &glsl_version, 38 | ekg::which_gpu_api which_gpu_api, 39 | std::string &out_shader 40 | ); 41 | } 42 | 43 | #endif 44 | -------------------------------------------------------------------------------- /include/ekg/gpu/sampler.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License 3 | * 4 | * Copyright (c) 2022-2025 Rina Wilk / vokegpu@gmail.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | #ifndef EKG_GPU_SAMPLER_HPP 25 | #define EKG_GPU_SAMPLER_HPP 26 | 27 | #include "ekg/io/memory.hpp" 28 | #include "ekg/io/descriptor.hpp" 29 | #include "ekg/math/geometry.hpp" 30 | 31 | namespace ekg { 32 | struct sampler_t { 33 | public: 34 | static constexpr ekg::type type {ekg::type::sampler}; 35 | static ekg::sampler_t not_found; 36 | public: 37 | const char *p_tag {}; 38 | uint32_t w {}; 39 | uint32_t h {}; 40 | uint32_t channel {}; 41 | uint32_t gl_id {}; 42 | int8_t gl_protected_active_index {-1}; 43 | bool is_protected {}; 44 | public: 45 | ekg_descriptor(ekg::sampler_t); 46 | }; 47 | 48 | struct sampler_info_t { 49 | public: 50 | const char *p_tag {}; 51 | int32_t offset[2] {}; 52 | int32_t w {}; 53 | int32_t h {}; 54 | int32_t gl_parameter_filter[2] {}; 55 | int32_t gl_wrap_modes[2] {}; 56 | int32_t gl_internal_format {}; 57 | uint32_t gl_format {}; 58 | uint32_t gl_type {}; 59 | bool gl_unpack_alignment {}; 60 | bool gl_generate_mipmap {}; 61 | void *pv_data {}; 62 | }; 63 | 64 | typedef sampler_info_t sampler_allocate_info_t; 65 | typedef sampler_info_t sampler_fill_info_t; 66 | 67 | ekg::flags_t sampler_src_r8_to_r8g8b8a8( 68 | const ekg::vec2_t &size, 69 | const unsigned char *p_src, 70 | std::vector &dst 71 | ); 72 | } 73 | 74 | #endif 75 | -------------------------------------------------------------------------------- /include/ekg/handler/callback.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License 3 | * 4 | * Copyright (c) 2022-2025 Rina Wilk / vokegpu@gmail.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | #ifndef EKG_HANDLER_CALLBACK_HPP 25 | #define EKG_HANDLER_CALLBACK_HPP 26 | 27 | #include "ekg/io/memory.hpp" 28 | #include "ekg/io/descriptor.hpp" 29 | #include 30 | #include 31 | 32 | namespace ekg { 33 | struct info_t { 34 | public: 35 | std::string tag {}; 36 | void *pv_data {nullptr}; 37 | }; 38 | 39 | using callback_function_t = void(*)(ekg::info_t&); 40 | 41 | struct callback_t { 42 | public: 43 | static constexpr ekg::type type {ekg::type::callback}; 44 | static ekg::callback_t not_found; 45 | public: 46 | ekg::info_t info {}; 47 | std::function lambda {}; 48 | ekg::callback_function_t function {nullptr}; 49 | public: 50 | ekg_descriptor(ekg::callback_t); 51 | }; 52 | } 53 | 54 | #endif 55 | -------------------------------------------------------------------------------- /include/ekg/handler/callback/handler.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License 3 | * 4 | * Copyright (c) 2022-2025 Rina Wilk / vokegpu@gmail.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | #ifndef EKG_HANDLER_CALLBACK_HANDLER_HPP 25 | #define EKG_HANDLER_CALLBACK_HANDLER_HPP 26 | 27 | #include 28 | #include 29 | 30 | #include "ekg/io/memory.hpp" 31 | #include "ekg/handler/callback.hpp" 32 | 33 | namespace ekg::handler { 34 | enum status { 35 | not_dispateched = 2 << 1, 36 | dispatched = 2 << 2 37 | }; 38 | 39 | class callback { 40 | protected: 41 | std::vector loaded {}; 42 | std::queue queue {}; 43 | public: 44 | void init(); 45 | ekg::callback_t &load(); 46 | void dispatch(size_t index); 47 | void dispatch(ekg::at_t &at); 48 | void update(); 49 | }; 50 | } 51 | 52 | #endif 53 | -------------------------------------------------------------------------------- /include/ekg/handler/input.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License 3 | * 4 | * Copyright (c) 2022-2025 Rina Wilk / vokegpu@gmail.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | #ifndef EKG_HANDLER_INPUT_HPP 25 | #define EKG_HANDLER_INPUT_HPP 26 | 27 | #include "ekg/io/timing.hpp" 28 | #include "ekg/math/geometry.hpp" 29 | 30 | #include 31 | #include 32 | #include 33 | 34 | namespace ekg { 35 | enum class system_cursor { 36 | arrow, 37 | ibeam, 38 | wait, 39 | crosshair, 40 | wait_arrow, 41 | size_nwse, 42 | size_nesw, 43 | size_we, 44 | size_ns, 45 | size_all, 46 | no, 47 | hand 48 | }; 49 | 50 | enum class special_key { 51 | left_shift, 52 | right_shift, 53 | left_ctrl, 54 | right_ctrl, 55 | left_alt, 56 | right_alt, 57 | tab, 58 | unknown 59 | }; 60 | 61 | struct input_info_t { 62 | public: 63 | float scroll_speed {0.4f}; 64 | ekg::timing_t ui_timeout_timing {}; 65 | ekg::timing_t ui_scrolling_timing {}; 66 | ekg::timing_t timing_last_interact {}; 67 | ekg::timing_t ui_timing {}; 68 | ekg::vec4_t interact {}; 69 | bool was_pressed {}; 70 | bool was_released {}; 71 | bool has_motion {}; 72 | bool was_wheel {}; 73 | bool was_typed {}; 74 | }; 75 | 76 | struct input_key_t { 77 | public: 78 | int32_t key {}; 79 | int32_t scancode {}; 80 | }; 81 | 82 | struct input_bind_t { 83 | public: 84 | std::vector registry {}; 85 | bool state {}; 86 | bool *p_address {}; 87 | }; 88 | } 89 | 90 | namespace ekg { 91 | ekg::input_info_t &input(); 92 | bool fire(std::string_view tag); 93 | bool input(std::string_view input); 94 | void bind(std::string_view tag, std::string_view input); 95 | void bind(std::string_view tag, std::vector inputs); 96 | } 97 | 98 | #endif 99 | -------------------------------------------------------------------------------- /include/ekg/handler/input/handler.hpp: -------------------------------------------------------------------------------- 1 | #ifndef EKG_HANDLER_INPUT_HANDLER_HPP 2 | #define EKG_HANDLER_INPUT_HANDLER_HPP 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include "ekg/handler/input.hpp" 9 | #include "ekg/io/timing.hpp" 10 | 11 | namespace ekg::handler { 12 | class input { 13 | protected: 14 | // @TODO: change from unordored map to linear query 15 | 16 | std::unordered_map> input_bindings_map {}; 17 | std::unordered_map input_bind_map {}; 18 | std::unordered_map input_map {}; 19 | std::array special_keys {}; 20 | 21 | std::vector special_keys_unit_pressed {}; 22 | std::vector double_click_mouse_buttons_pressed {}; 23 | std::vector input_released_list {}; 24 | std::vector just_fired_input_bind {}; 25 | 26 | bool finger_hold_event {}; 27 | bool finger_swipe_event {}; 28 | bool is_special_keys_released {}; 29 | 30 | ekg::timing_t double_interact {}; 31 | ekg::timing_t last_time_wheel_was_fired {}; 32 | public: 33 | ekg::input_info_t input {}; 34 | protected: 35 | void complete_with_units( 36 | std::string &string_builder, 37 | std::string_view key_name 38 | ); 39 | 40 | bool contains_unit( 41 | std::string_view label 42 | ); 43 | 44 | bool is_special_key( 45 | int32_t sdl_key_code 46 | ); 47 | public: 48 | void init(); 49 | void quit(); 50 | void poll_event(); 51 | void update(); 52 | 53 | void insert_input_bind( 54 | std::string_view tag, 55 | std::string_view input 56 | ); 57 | 58 | void erase_input_bind( 59 | std::string_view tag, 60 | std::string_view input_to_erase 61 | ); 62 | 63 | void erase_input_bind( 64 | std::string_view tag 65 | ); 66 | 67 | void set_input_bind_state( 68 | std::string_view tag, 69 | bool state 70 | ); 71 | 72 | bool get_input_bind_state( 73 | std::string_view tag 74 | ); 75 | 76 | void set_input_state( 77 | std::string_view input, 78 | bool state 79 | ); 80 | 81 | bool get_input_state( 82 | std::string_view tag 83 | ); 84 | }; 85 | } 86 | 87 | #endif 88 | -------------------------------------------------------------------------------- /include/ekg/handler/theme.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License 3 | * 4 | * Copyright (c) 2022-2025 Rina Wilk / vokegpu@gmail.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | #ifndef EKG_HANDLER_THEME_HPP 25 | #define EKG_HANDLER_THEME_HPP 26 | 27 | #include "ekg/ui/button/button.hpp" 28 | #include "ekg/ui/frame/frame.hpp" 29 | 30 | namespace ekg { 31 | struct theme_t { 32 | public: 33 | std::string tag {}; 34 | std::string author {}; 35 | std::string description {}; 36 | public: 37 | float layout_offset {}; 38 | ekg::pixel_t layout_margin_thickness {}; 39 | ekg::button_color_scheme_t button_color_scheme {}; 40 | ekg::frame_color_scheme_t frame_color_scheme {}; 41 | }; 42 | 43 | ekg::theme_t &theme(std::string_view tag = ""); 44 | ekg::theme_t &set_current_theme(std::string_view tag); 45 | } 46 | 47 | #endif 48 | -------------------------------------------------------------------------------- /include/ekg/handler/theme/handler.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License 3 | * 4 | * Copyright (c) 2022-2025 Rina Wilk / vokegpu@gmail.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | #ifndef EKG_HANDLER_THEME_HANDLER_HPP 25 | #define EKG_HANDLER_THEME_HANDLER_HPP 26 | 27 | #include "ekg/handler/theme.hpp" 28 | 29 | #include 30 | #include 31 | 32 | namespace ekg::handler { 33 | class theme { 34 | protected: 35 | std::string_view current_theme_tag {"dark-theme"}; 36 | std::map themes {}; 37 | public: 38 | void init(); 39 | void quit(); 40 | 41 | ekg::theme_t ®istry(const std::string_view &tag); 42 | ekg::theme_t &get_current_theme(); 43 | ekg::theme_t &set_current_theme(const std::string_view &tag); 44 | }; 45 | } 46 | 47 | #endif 48 | -------------------------------------------------------------------------------- /include/ekg/io/descriptor.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License 3 | * 4 | * Copyright (c) 2022-2025 Rina Wilk / vokegpu@gmail.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | #ifndef EKG_IO_DESCRIPTOR_HPP 25 | #define EKG_IO_DESCRIPTOR_HPP 26 | 27 | #include "ekg/io/memory.hpp" 28 | 29 | namespace ekg { 30 | enum type : ekg::flags_t { 31 | unknown = 0, 32 | callback = 1, 33 | property = 2, 34 | sampler = 3, 35 | stack = 4, 36 | button = 5, 37 | scrollbar = 6, 38 | frame = 7 39 | }; 40 | } 41 | 42 | #define ekg_descriptor(descriptor_t) \ 43 | public: \ 44 | ekg::at_t at { \ 45 | .unique_id = ekg::not_found, \ 46 | .index = ekg::not_found, \ 47 | .flags = ekg::not_found \ 48 | }; \ 49 | bool is_dead {}; \ 50 | public: \ 51 | bool operator == (descriptor_t &descriptor) { \ 52 | return ( \ 53 | (this->is_dead && descriptor.at == descriptor_t::not_found.at) \ 54 | || \ 55 | (!this->is_dead && this->at == descriptor.at) \ 56 | ); \ 57 | } \ 58 | \ 59 | bool operator != (descriptor_t &descriptor) { \ 60 | return !(*this == descriptor); \ 61 | } \ 62 | \ 63 | operator ekg::at_t() { \ 64 | return this->at; \ 65 | } 66 | 67 | #endif 68 | -------------------------------------------------------------------------------- /include/ekg/io/event.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License 3 | * 4 | * Copyright (c) 2022-2025 Rina Wilk / vokegpu@gmail.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | #ifndef EKG_IO_EVENT_HPP 25 | #define EKG_IO_EVENT_HPP 26 | 27 | #include "ekg/handler/input.hpp" 28 | 29 | namespace ekg { 30 | enum behavior : ekg::flags_t { 31 | no_auto_set_viewport_when_resize = 2 << 1 32 | }; 33 | } 34 | 35 | namespace ekg::io { 36 | enum class operation { 37 | swap, 38 | reload, 39 | docknize, 40 | scalenize, 41 | high_frequency 42 | }; 43 | 44 | void dispatch( 45 | ekg::io::operation op, 46 | ekg::at_t &property_at = ekg::at_t::not_found 47 | ); 48 | 49 | enum class stage { 50 | pre, 51 | process, 52 | post 53 | }; 54 | 55 | enum class event_type { 56 | none, 57 | text_input, 58 | mouse_button_up, 59 | mouse_button_down, 60 | mouse_motion, 61 | mouse_wheel, 62 | finger_up, 63 | finger_down, 64 | finger_motion, 65 | key_down, 66 | key_up 67 | }; 68 | 69 | struct event_t { 70 | public: 71 | ekg::io::event_type type {}; 72 | std::string_view text_input {}; 73 | uint8_t mouse_button {}; 74 | 75 | int32_t mouse_motion_x {}; 76 | int32_t mouse_motion_y {}; 77 | 78 | int32_t mouse_wheel_x {}; 79 | int32_t mouse_wheel_y {}; 80 | 81 | float mouse_wheel_precise_x {}; 82 | float mouse_wheel_precise_y {}; 83 | 84 | ekg::input_key_t key {}; 85 | 86 | float finger_x {}; 87 | float finger_y {}; 88 | 89 | float finger_dx {}; 90 | float finger_dy {}; 91 | }; 92 | } 93 | 94 | namespace ekg::io { 95 | 96 | } 97 | 98 | #endif 99 | -------------------------------------------------------------------------------- /include/ekg/io/font.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License 3 | * 4 | * Copyright (c) 2022-2025 Rina Wilk / vokegpu@gmail.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | #ifndef EKG_IO_FONT_HPP 25 | #define EKG_IO_FONT_HPP 26 | 27 | #include 28 | #include FT_FREETYPE_H 29 | #include 30 | #include 31 | 32 | #include "memory.hpp" 33 | 34 | namespace ekg { 35 | /** 36 | * @TODO: Add non-fixed size font-rendering 37 | **/ 38 | enum class font { 39 | small, 40 | medium, 41 | big 42 | }; 43 | 44 | typedef FT_Library ft_library; 45 | } 46 | 47 | namespace ekg::io { 48 | enum font_face_type { 49 | text, 50 | emojis, 51 | kanjis 52 | }; 53 | 54 | constexpr size_t enum_font_face_type_size {3}; 55 | 56 | struct font_face_t { 57 | public: 58 | FT_Face ft_face {}; 59 | FT_GlyphSlot ft_glyph_slot {}; 60 | FT_Vector highest_glyph_size {}; 61 | std::string path {}; 62 | uint32_t size {}; 63 | bool was_face_changed {}; 64 | bool was_size_changed {}; 65 | bool was_loaded {}; 66 | }; 67 | 68 | ekg::flags_t font( 69 | ekg::io::font_face_t &font_face 70 | ); 71 | 72 | struct glyph_t { 73 | public: 74 | float x {}; 75 | float wsize {}; 76 | float w {}; 77 | float h {}; 78 | float top {}; 79 | float left {}; 80 | float kerning {}; 81 | bool was_sampled {}; 82 | }; 83 | } 84 | 85 | #endif 86 | -------------------------------------------------------------------------------- /include/ekg/io/log.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License 3 | * 4 | * Copyright (c) 2022-2025 Rina Wilk / vokegpu@gmail.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | #ifndef EKG_IO_LOG_HPP 25 | #define EKG_IO_LOG_HPP 26 | 27 | #include 28 | #include 29 | #include 30 | 31 | //#define EKG_LOG_DEBUG 32 | //#define EKG_INPUT_DEBUG 33 | 34 | namespace ekg { 35 | class log { 36 | public: 37 | static std::ostringstream buffer; 38 | static bool buffered; 39 | static bool tracked; 40 | public: 41 | static void flush() { 42 | if (ekg::log::buffered) { 43 | #if defined(__ANDROID__) 44 | __android_log_print(ANDROID_LOG_VERBOSE, "EKG", "%s", ekg::log::buffer.str().c_str()); 45 | #else 46 | std::cout << ekg::log::buffer.str(); 47 | #endif 48 | 49 | ekg::log::buffer = std::ostringstream {}; 50 | ekg::log::buffered = false; 51 | } 52 | } 53 | public: 54 | template 55 | explicit log(t content) { 56 | std::cout << content << std::endl; 57 | } 58 | 59 | explicit log() { 60 | ekg::log::buffered = true; 61 | ekg::log::buffer << "[EKG] "; 62 | } 63 | 64 | ~log() { 65 | ekg::log::buffer << '\n'; 66 | 67 | #if defined(EKG_LOG_DEBUG) 68 | ekg::log::flush(); 69 | std::cout << std::endl; 70 | #endif 71 | } 72 | 73 | template 74 | log &operator<<(const t &value) { 75 | ekg::log::buffer << value; 76 | return *this; 77 | } 78 | }; 79 | } 80 | 81 | #endif 82 | -------------------------------------------------------------------------------- /include/ekg/io/memory.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License 3 | * 4 | * Copyright (c) 2022-2025 Rina Wilk / vokegpu@gmail.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | #ifndef EKG_IO_MEMORY_HPP 25 | #define EKG_IO_MEMORY_HPP 26 | 27 | #include 28 | #include 29 | #include 30 | 31 | /** 32 | * This is a macro because hash should enjoy of compile-time for generate valid hashes. 33 | * Not really an expensive job for CPU. 34 | **/ 35 | #define ekg_generate_hash(distance, c32, u) static_cast(distance + c32 + u * 100); 36 | 37 | /** 38 | * A low-level assert used in risks cases where virtual-address should be warned. 39 | **/ 40 | #define ekg_assert_low_level(state, alarm, end) if (state) alarm; end; 41 | 42 | /** 43 | * A dev-purpose log level untracked for EKG. 44 | **/ 45 | #define ekg_log_low_level(log_content) std::cout << log_content << std::endl; 46 | 47 | namespace ekg { 48 | typedef size_t flags_t; 49 | typedef size_t id_t; 50 | typedef int32_t hash_t; 51 | 52 | enum result { 53 | success, 54 | failed, 55 | failed_unknown, 56 | failed_not_implemented 57 | }; 58 | 59 | template 60 | constexpr bool has(ekg::flags_t bits, t bit) { 61 | return (bits & bit) == bit; 62 | } 63 | 64 | template 65 | constexpr bool strip(ekg::flags_t &bits, t bit) { 66 | bits = bits & ~(bit); 67 | return ekg::has(bits, bit); 68 | } 69 | 70 | template 71 | constexpr ekg::flags_t &put(ekg::flags_t &bits, t bit) { 72 | return (bits |= bit); 73 | } 74 | } 75 | 76 | /** 77 | * Memory-pool and virtual address. 78 | **/ 79 | namespace ekg { 80 | /** 81 | * Broken heart hash.......... 82 | **/ 83 | constexpr ekg::id_t not_found {2942656639}; 84 | 85 | struct at_t { 86 | public: 87 | static ekg::at_t not_found; 88 | public: 89 | ekg::id_t unique_id {ekg::not_found}; 90 | size_t index {ekg::not_found}; 91 | ekg::flags_t flags {ekg::not_found}; 92 | public: 93 | bool operator == (ekg::at_t &at) { 94 | return ( 95 | this->flags == at.flags 96 | && 97 | this->index == at.index 98 | && 99 | this->unique_id == at.unique_id 100 | ); 101 | } 102 | 103 | bool operator != (ekg::at_t &at) { 104 | return !(*this == at); 105 | } 106 | }; 107 | 108 | template 109 | class pool { 110 | protected: 111 | std::vector loaded {}; 112 | ekg::id_t highest_unique_id {}; 113 | size_t virtual_memory_capacity {256}; 114 | public: 115 | pool() { 116 | this->loaded.reserve(this->virtual_memory_capacity); 117 | }; 118 | 119 | t &push_back(t copy) { 120 | this->loaded.push_back(copy); 121 | 122 | size_t index {this->loaded.size() - 1}; 123 | t &descriptor {this->loaded.at(index)}; 124 | 125 | descriptor.at.unique_id = this->highest_unique_id++; 126 | descriptor.at.flags = t::type; 127 | descriptor.at.index = index; 128 | 129 | return descriptor; 130 | } 131 | 132 | t &query(ekg::at_t &at) { 133 | if (at.index == ekg::not_found) { 134 | return t::not_found; 135 | } 136 | 137 | if ( 138 | at.index >= this->loaded.size() 139 | || 140 | this->loaded.at(at.index).at.unique_id != at.unique_id 141 | ) { 142 | size_t size {this->loaded.size()}; 143 | for (size_t it {}; it < size; it++) { 144 | t &descriptor {this->loaded.at(it)}; 145 | descriptor.at.index = it; 146 | if (descriptor.at.unique_id == at.unique_id) { 147 | at.index = it; 148 | return descriptor; 149 | } 150 | } 151 | 152 | return t::not_found; 153 | } 154 | 155 | t &descriptor {this->loaded.at(at.index)}; 156 | return descriptor; 157 | } 158 | }; 159 | } 160 | 161 | /** 162 | * Value system. 163 | **/ 164 | namespace ekg { 165 | template 166 | class value { 167 | protected: 168 | t val {}; 169 | t *p {}; 170 | t previous {}; 171 | bool changed {}; 172 | public: 173 | value() { 174 | this->ownership(nullptr); 175 | }; 176 | 177 | value(t *p_address) { 178 | this->ownership(p_address); 179 | this->changed = true; 180 | } 181 | 182 | value(t val) { 183 | this->get() = val; 184 | this->changed = true; 185 | } 186 | 187 | value(const char *p_char) { 188 | this->get() = p_char; 189 | this->changed = true; 190 | } 191 | 192 | void set(const t &val) { 193 | this->get() = p; 194 | this->changed = true; 195 | } 196 | 197 | t &get() { 198 | return this->p ? *this->p : this->val; 199 | } 200 | 201 | void ownership(t *p_address) { 202 | if (p_address == nullptr) { 203 | return; 204 | } 205 | 206 | this->p = p_address; 207 | } 208 | 209 | bool was_changed() { 210 | if (this->changed) { 211 | this->changed = false; 212 | return true; 213 | } 214 | 215 | t &get {this->get()}; 216 | if (this->previous != get) { 217 | this->previous = get; 218 | return true; 219 | } 220 | 221 | return false; 222 | } 223 | }; 224 | 225 | struct mapped_address_sign_info_t { 226 | public: 227 | std::vector ats {}; 228 | void *pv_address {}; 229 | }; 230 | 231 | extern struct signed_address_info_t { 232 | public: 233 | std::vector list {}; 234 | size_t current {}; 235 | } sign; 236 | 237 | void map(void *pv_address); 238 | void unmap(void *pv_address); 239 | } 240 | 241 | namespace ekg::io { 242 | /** 243 | * @TODO: add a complete docs here please. 244 | **/ 245 | template 246 | constexpr t &any_static_cast(void *p_any) { 247 | return *static_cast(p_any); 248 | } 249 | } 250 | 251 | #endif 252 | -------------------------------------------------------------------------------- /include/ekg/io/timing.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License 3 | * 4 | * Copyright (c) 2022-2025 Rina Wilk / vokegpu@gmail.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | #ifndef EKG_IO_TIMING_HPP 25 | #define EKG_IO_TIMING_HPP 26 | 27 | #include 28 | 29 | namespace ekg { 30 | struct timing_t { 31 | public: 32 | /** 33 | * The 1 second counter in ms. 34 | **/ 35 | static int64_t second; 36 | 37 | /** 38 | * The total running ticks since the application was started. 39 | **/ 40 | static int64_t ticks; 41 | public: 42 | int64_t elapsed_ticks {}; 43 | int64_t current_ticks {}; 44 | int64_t ticks_going_on {}; 45 | }; 46 | 47 | bool reach( 48 | ekg::timing_t &timing, 49 | int64_t ms 50 | ); 51 | 52 | bool reset_if_reach( 53 | ekg::timing_t &timing, 54 | int64_t ms 55 | ); 56 | 57 | bool reset( 58 | ekg::timing_t &timing 59 | ); 60 | 61 | bool extend( 62 | ekg::timing_t &timing, 63 | int64_t ms 64 | ); 65 | 66 | int64_t interval( 67 | ekg::timing_t &timing 68 | ); 69 | } 70 | 71 | #endif 72 | -------------------------------------------------------------------------------- /include/ekg/io/utf.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License 3 | * 4 | * Copyright (c) 2022-2025 Rina Wilk / vokegpu@gmail.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | #ifndef EKG_IO_UTF_HPP 25 | #define EKG_IO_UTF_HPP 26 | 27 | #include "ekg/math/geometry.hpp" 28 | 29 | #include 30 | #include 31 | #include 32 | 33 | namespace ekg { 34 | /** 35 | * Returns a UTF string by `char32` converting 36 | * the UTF-32 unique char into a sequence of UTF-8 37 | * chars. 38 | */ 39 | std::string utf32_to_string( 40 | char32_t char32 41 | ); 42 | 43 | /** 44 | * Returns a string subtracted by stride begin `offset` 45 | * and end index `size`. If string is empty, return 46 | * empty. 47 | */ 48 | std::string utf8_substr( 49 | std::string_view string, 50 | uint64_t offset, 51 | uint64_t size 52 | ); 53 | 54 | /** 55 | * Returns the `string` length considering UTF chars. 56 | */ 57 | uint64_t utf8_length( 58 | std::string_view string 59 | ); 60 | 61 | /** 62 | * Returns index size that represent an UTF-8 char. 63 | * Possibles: 64 | * 3, 2, 1, and 0. 65 | */ 66 | uint64_t utf8_check_sequence( 67 | uint8_t &char8, 68 | char32_t &char32, 69 | std::string &utf_string, 70 | std::string_view string, 71 | uint64_t index 72 | ); 73 | 74 | /** 75 | * Returns a UTF-32 char32 based on UTF-8 sequence. 76 | */ 77 | char32_t utf8_to_utf32( 78 | std::string_view string 79 | ); 80 | 81 | /** 82 | * Fast splitter specialized in `\n` or `\r\n` (non OS unix-based). 83 | * UTF to sinalize the string unicode-like suggested by EKG. 84 | */ 85 | void utf8_split_new_line( 86 | std::string_view string, 87 | std::vector &utf8_split_new_lined 88 | ); 89 | 90 | /** 91 | * Return true if `string` contains `find_char`, 92 | * then it must allocate and insert elements to 93 | * `p_string_split_list` ptr. 94 | */ 95 | bool utf8_split( 96 | std::vector &string_split_list, 97 | const std::string &string, 98 | char find_char 99 | ); 100 | 101 | template 102 | void utf8_number_precision( 103 | std::string &number_to_string, 104 | t number, 105 | size_t precision 106 | ) { 107 | number_to_string = std::to_string(number); 108 | number_to_string = ( 109 | number_to_string.substr( 110 | 0, 111 | ekg::clamp_max( 112 | number_to_string.find('.') + precision + (1 * precision), 113 | number_to_string.size() 114 | ) 115 | ) 116 | ); 117 | } 118 | } 119 | 120 | #endif 121 | -------------------------------------------------------------------------------- /include/ekg/layout/docknize.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License 3 | * 4 | * Copyright (c) 2022-2025 Rina Wilk / vokegpu@gmail.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | #ifndef EKG_LAYOUR_DOCKNIZE_HPP 25 | #define EKG_LAYOUR_DOCKNIZE_HPP 26 | 27 | #include "ekg/ui/property.hpp" 28 | 29 | namespace ekg::layout { 30 | /** 31 | * Returns the dimensional extent based on count and the offset (space between rects). 32 | * 33 | * The pixel imperfect issue was solved here... 34 | * For a long time I did not know what was going on with the pixels, 35 | * some solutions I used did not work, then I discovered that all the time 36 | * was this dimension extent with float imprecision loss. 37 | * 38 | * Each pixels represent 1.0f, if the GPU receives pixels with 39 | * (n + f) `n` a non-floating point number and `f` a floating point; 40 | * the rasterizer will jump between pixels, resulting in pixel-imperfect. 41 | * 42 | * The following formula make you understand: 43 | * ( (g - d) - (c * o) ) / c 44 | * 45 | * g = group rect 46 | * d = dimensional extent 47 | * c = amount of widgets with fill property flag until any flag next 48 | * o = UI offset setting 49 | * 50 | * Float-only without the int32_t cast may results in pixel-imperfect 51 | * due the influence of dimensional size of parent rect, font height, font width etc. 52 | * 53 | * - Rina. 54 | **/ 55 | constexpr float transform_dimension_from_extent( 56 | float dimension, 57 | float extent, 58 | float offset, 59 | int32_t count 60 | ) { 61 | return static_cast( 62 | ( 63 | static_cast(dimension) 64 | - 65 | static_cast(extent) 66 | - 67 | static_cast(count * offset) 68 | ) 69 | / 70 | count 71 | ); 72 | } 73 | 74 | /** 75 | * Pixel imperfection is a problem for UI widget placements, this macro provides 76 | * correction position for right/bottom based on left/top position. 77 | * 78 | * It is important to understand that is impossible to remove all the pixel 79 | * imperfections, but there are ways to round it, as example, you can place widget 80 | * from a side (left or right, top or bottom) and align with an offset. That is how EKG fix it. 81 | * 82 | * This method calculate the minimum possible position based on left until the pixel 83 | * escape for two or more offsets distance. Instead you use the container width directly 84 | * to calculate right widgets positions, EKG must use the left consistency to get the 85 | * real container (width/height) from the side of left (when using the container width directly 86 | * the position is pixel imperfect). 87 | * 88 | * - Rina. 89 | **/ 90 | constexpr float transform_to_pixel_perfect_position( 91 | float side_a, 92 | float side_b, 93 | float container_dimension, 94 | float offset 95 | ) { 96 | return ekg::clamp_min( 97 | ( 98 | (side_a + (container_dimension - side_a) + offset) 99 | - 100 | (side_b) 101 | ), 102 | side_a 103 | ); 104 | } 105 | 106 | class mask { 107 | public: 108 | struct component_t { 109 | public: 110 | ekg::rect_t *p_rect {}; 111 | ekg::flags_t dock {}; 112 | }; 113 | protected: 114 | std::vector components {}; 115 | float respective_all {}; 116 | float respective_center {}; 117 | ekg::flags_t axis {}; 118 | ekg::vec3_t offset {}; 119 | ekg::rect_t mask {}; 120 | public: 121 | void preset( 122 | ekg::vec3_t offset, 123 | ekg::flags_t axis, 124 | float initial_respective_size = 0.0f 125 | ); 126 | 127 | void insert( 128 | const ekg::layout::mask::component_t &rect_descriptor 129 | ); 130 | 131 | void docknize(); 132 | ekg::rect_t &get_rect(); 133 | }; 134 | 135 | /** 136 | * A mid-functional feature to process dock position from widgets. 137 | * Note: Recursive. 138 | **/ 139 | void docknize_widget( 140 | ekg::property_t &property 141 | ); 142 | 143 | float get_widget_height_by_children( 144 | ekg::property_t &property 145 | ); 146 | } 147 | 148 | #endif 149 | -------------------------------------------------------------------------------- /include/ekg/layout/extentnize.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License 3 | * 4 | * Copyright (c) 2022-2025 Rina Wilk / vokegpu@gmail.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | #ifndef EKG_LAYOUT_EXTENTNIZE_HPP 25 | #define EKG_LAYOUT_EXTENTNIZE_HPP 26 | 27 | #include "docknize.hpp" 28 | 29 | namespace ekg::layout { 30 | struct extent_t { 31 | public: 32 | static ekg::layout::extent_t v_widget; 33 | static ekg::layout::extent_t h_widget; 34 | static ekg::layout::extent_t v_mask; 35 | static ekg::layout::extent_t h_mask; 36 | public: 37 | int32_t end_index {}; 38 | int32_t begin_index {}; 39 | int32_t count {}; 40 | float extent {}; 41 | }; 42 | 43 | /** 44 | * The extentize is a method to calculate split (between all elements with `ekg::dock::fill` flag) 45 | * data from a container dimension, extent is the amount of non `ekg::dock::fill` calculated dimension. 46 | * 47 | * Both functions `extentnize_*` works almost equals, but with 48 | * difference of specialization-level, rect descriptors are a 49 | * compact way to calculate extent, while widgets works with some additional 50 | * variables. For performance reasons EKG does not want to make generic 51 | * this way, but soon maybe we can change it. 52 | * 53 | * --- 54 | * 55 | * How it works: 56 | * 57 | * The last index does not check if contains a next flag, 58 | * so it is needed to brute-check to stop at end of index. 59 | * 60 | * The extent data store the previous bounding indices, 61 | * in simply words, prevent useless iteration. 62 | * 63 | * The min offset is added for extent, because we need count 64 | * the offset position when split the dimension width, but the 65 | * last extent space is not necessary, so we need to subtract. 66 | **/ 67 | 68 | /** 69 | * Obtain the remain extent size, from the latest rect descriptor index `in` 70 | * and return the new count `out`. 71 | **/ 72 | void extentnize_mask( 73 | std::vector &components, 74 | ekg::vec3_t offset, 75 | ekg::flags_t flag_ok, 76 | ekg::flags_t flag_stop, 77 | ekg::flags_t flag_axis, 78 | float &extent, 79 | int32_t &in_out_count 80 | ); 81 | 82 | /** 83 | * Obtain the remain extent size, from the latest widget index `in` 84 | * and return the new count `out`. 85 | **/ 86 | void extentnize_widget( 87 | ekg::property_t &property, 88 | ekg::flags_t flag_ok, 89 | ekg::flags_t flag_stop, 90 | ekg::flags_t flag_axis, 91 | float &extent, 92 | int32_t &in_out_count 93 | ); 94 | } 95 | 96 | #endif 97 | -------------------------------------------------------------------------------- /include/ekg/layout/scalenize.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License 3 | * 4 | * Copyright (c) 2022-2025 Rina Wilk / vokegpu@gmail.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | #ifndef EKG_LAYOUT_SCALENIZE_HPP 25 | #define EKG_LAYOUT_SCALENIZE_HPP 26 | 27 | namespace ekg::layout { 28 | void scalenize(); 29 | } 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /include/ekg/math/floating_point.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License 3 | * 4 | * Copyright (c) 2022-2025 Rina Wilk / vokegpu@gmail.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | #ifndef EKG_MATH_FLOATING_POINT_HPP 25 | #define EKG_MATH_FLOATING_POINT_HPP 26 | 27 | #include 28 | #include 29 | 30 | namespace ekg { 31 | constexpr float pi {3.1415927f}; 32 | 33 | constexpr bool fequalsf(float compare, float compared) { 34 | return ( 35 | fabsf(compare - compared) 36 | <= 37 | ( 38 | FLT_EPSILON 39 | * 40 | fmaxf(1.0f, fmaxf(fabsf(compare), fabsf(compared))) 41 | ) 42 | ); 43 | } 44 | } 45 | 46 | #endif 47 | -------------------------------------------------------------------------------- /include/ekg/platform/base.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License 3 | * 4 | * Copyright (c) 2022-2025 Rina Wilk / vokegpu@gmail.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | #ifndef EKG_PLATFORM_HPP 25 | #define EKG_PLATFORM_HPP 26 | 27 | #include "ekg/io/event.hpp" 28 | 29 | namespace ekg::platform { 30 | class base { 31 | public: 32 | ekg::rect_t display_size {}; 33 | ekg::system_cursor system_cursor {}; 34 | ekg::io::event_t event {}; 35 | ekg::flags_t modes {}; 36 | public: 37 | virtual void init() {}; 38 | virtual void quit() {}; 39 | virtual void update_display_size() {}; 40 | virtual void update() {}; 41 | virtual void get_key_name(ekg::input_key_t &key, std::string &name) {}; 42 | virtual void get_special_key(ekg::input_key_t &key, ekg::special_key &espcial_key) {}; 43 | virtual const char *get_clipboard_text() { return nullptr; }; 44 | virtual void set_clipboard_text(const char *p_text) {}; 45 | virtual bool has_clipboard_text() { return false; }; 46 | }; 47 | } 48 | 49 | #endif 50 | -------------------------------------------------------------------------------- /include/ekg/platform/sdl/sdl2.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License 3 | * 4 | * Copyright (c) 2022-2025 Rina Wilk / vokegpu@gmail.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | #ifndef EKG_PLATFORM_SDL_SDL2_HPP 25 | #define EKG_PLATFORM_SDL_SDL2_HPP 26 | 27 | #if defined(__ANDROID__) 28 | #include "SDL.h" 29 | #else 30 | #include 31 | #endif 32 | 33 | #include "ekg/platform/base.hpp" 34 | #include 35 | 36 | namespace ekg { 37 | class sdl2 : public ekg::platform::base { 38 | protected: 39 | std::array loaded_system_cursors {}; 40 | SDL_Window *p_sdl_win {}; 41 | public: 42 | explicit sdl2( 43 | SDL_Window *p_sdl_win, 44 | ekg::flags_t modes = static_cast(0) 45 | ); 46 | public: 47 | void init() override; 48 | void quit() override; 49 | void update_display_size() override; 50 | void update() override; 51 | void get_key_name(ekg::input_key_t &key, std::string &name) override; 52 | void get_special_key(ekg::input_key_t &key, ekg::special_key &special_key) override; 53 | const char *get_clipboard_text() override; 54 | void set_clipboard_text(const char *p_text) override; 55 | bool has_clipboard_text() override; 56 | }; 57 | 58 | void sdl2_poll_event(SDL_Event &sdl_event); 59 | } 60 | 61 | #endif 62 | -------------------------------------------------------------------------------- /include/ekg/ui/abstract.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License 3 | * 4 | * Copyright (c) 2022-2025 Rina Wilk / vokegpu@gmail.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | #ifndef EKG_UI_ABSTRACT_HPP 25 | #define EKG_UI_ABSTRACT_HPP 26 | 27 | #include "ekg/math/geometry.hpp" 28 | #include "ekg/ui/property.hpp" 29 | 30 | namespace ekg::ui { 31 | ekg::rect_t &get_abs_rect( 32 | ekg::property_t &property, 33 | ekg::rect_t &descriptor_rect 34 | ); 35 | 36 | void pre_event( 37 | ekg::property_t &property, 38 | ekg::rect_t &descriptor_rect, 39 | bool is_top_level 40 | ); 41 | 42 | void post_event( 43 | ekg::property_t &property 44 | ); 45 | } 46 | 47 | #endif 48 | -------------------------------------------------------------------------------- /include/ekg/ui/button/button.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License 3 | * 4 | * Copyright (c) 2022-2025 Rina Wilk / vokegpu@gmail.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | #ifndef EKG_UI_BUTTON_HPP 25 | #define EKG_UI_BUTTON_HPP 26 | 27 | #include "ekg/io/descriptor.hpp" 28 | #include "ekg/io/font.hpp" 29 | #include "ekg/math/geometry.hpp" 30 | 31 | namespace ekg { 32 | struct button_color_scheme_t { 33 | public: 34 | ekg::rgba_t text_foreground {}; 35 | 36 | ekg::rgba_t background {}; 37 | ekg::rgba_t outline {}; 38 | ekg::rgba_t highlight {}; 39 | 40 | ekg::rgba_t box_background {}; 41 | ekg::rgba_t box_outline {}; 42 | ekg::rgba_t box_highlight {}; 43 | ekg::rgba_t box_active {}; 44 | }; 45 | 46 | struct button_t { 47 | public: 48 | struct check_t { 49 | public: 50 | struct widget_t { 51 | public: 52 | ekg::rect_t rect_text {}; 53 | ekg::rect_t rect_box {}; 54 | }; 55 | public: 56 | ekg::value text {}; 57 | ekg::font font_size {ekg::font::medium}; 58 | bool is_check_box {}; 59 | ekg::flags_t dock {}; 60 | ekg::button_t::check_t::widget_t widget {}; 61 | }; 62 | 63 | static ekg::button_t not_found; 64 | static constexpr ekg::type type {ekg::type::button}; 65 | public: 66 | ekg::at_t property_at {}; 67 | public: 68 | std::string tag {}; 69 | ekg::flags_t dock {}; 70 | ekg::rect_t rect {}; 71 | std::vector checks {}; 72 | ekg::button_color_scheme_t color_scheme {}; 73 | public: 74 | ekg_descriptor(ekg::button_t); 75 | }; 76 | } 77 | 78 | #endif 79 | -------------------------------------------------------------------------------- /include/ekg/ui/button/widget.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License 3 | * 4 | * Copyright (c) 2022-2025 Rina Wilk / vokegpu@gmail.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | #ifndef EKG_UI_BUTTON_WIDGET_HPP 25 | #define EKG_UI_BUTTON_WIDGET_HPP 26 | 27 | #include "button.hpp" 28 | #include "ekg/ui/property.hpp" 29 | #include "ekg/io/event.hpp" 30 | 31 | namespace ekg::ui { 32 | void reload( 33 | ekg::property_t &property, 34 | ekg::button_t &button 35 | ); 36 | 37 | void event( 38 | ekg::property_t &property, 39 | ekg::button_t &button, 40 | const ekg::io::stage &stage 41 | ); 42 | 43 | void high_frequency( 44 | ekg::property_t &property, 45 | ekg::button_t &button 46 | ); 47 | 48 | void pass( 49 | ekg::property_t &property, 50 | ekg::button_t &button 51 | ); 52 | 53 | void buffering( 54 | ekg::property_t &property, 55 | ekg::button_t &button 56 | ); 57 | 58 | void unmap( 59 | ekg::button_t &button 60 | ); 61 | } 62 | 63 | #endif 64 | -------------------------------------------------------------------------------- /include/ekg/ui/frame/frame.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License 3 | * 4 | * Copyright (c) 2022-2025 Rina Wilk / vokegpu@gmail.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | #ifndef EKG_UI_FRAME_HPP 25 | #define EKG_UI_FRAME_HPP 26 | 27 | #include "ekg/io/descriptor.hpp" 28 | #include "ekg/math/geometry.hpp" 29 | 30 | namespace ekg { 31 | struct frame_color_scheme_t { 32 | public: 33 | ekg::pixel_thickness_t actions_margin_pixel_thickness {5}; 34 | ekg::rgba_t background {}; 35 | ekg::rgba_t highlight {}; 36 | ekg::rgba_t outline {}; 37 | ekg::rgba_t active {}; 38 | ekg::rgba_t focused_background {}; 39 | ekg::rgba_t focused_outline {}; 40 | ekg::rgba_t warning_outline {}; 41 | }; 42 | 43 | struct frame_t { 44 | public: 45 | struct widget_t { 46 | public: 47 | ekg::flags_t target_dock_drag {}; 48 | ekg::flags_t target_dock_resize {}; 49 | ekg::docker_t docker_drag {}; 50 | ekg::docker_t docker_resize {}; 51 | ekg::rect_t rect_delta {}; 52 | ekg::rect_t rect_cache {}; 53 | }; 54 | public: 55 | static ekg::frame_t not_found; 56 | static constexpr ekg::type type {ekg::type::frame}; 57 | public: 58 | ekg::at_t top_level_at {}; 59 | ekg::at_t property_at {}; 60 | public: 61 | std::string tag {}; 62 | ekg::dock dock {ekg::dock::none}; 63 | ekg::rect_t rect {}; 64 | ekg::flags_t drag {}; 65 | ekg::flags_t resize {}; 66 | bool set_top_level {}; 67 | ekg::frame_color_scheme_t color_scheme {}; 68 | ekg::frame_t::widget_t widget {}; 69 | public: 70 | ekg_descriptor(ekg::frame_t); 71 | }; 72 | } 73 | 74 | #endif 75 | -------------------------------------------------------------------------------- /include/ekg/ui/frame/widget.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License 3 | * 4 | * Copyright (c) 2022-2025 Rina Wilk / vokegpu@gmail.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | #ifndef EKG_UI_FRAME_WIDGET_HPP 25 | #define EKG_UI_FRAME_WIDGET_HPP 26 | 27 | #include "ekg/ui/property.hpp" 28 | #include "ekg/ui/frame/frame.hpp" 29 | #include "ekg/io/event.hpp" 30 | 31 | namespace ekg::ui { 32 | void reload( 33 | ekg::property_t &property, 34 | ekg::frame_t &frame 35 | ); 36 | 37 | void event( 38 | ekg::property_t &property, 39 | ekg::frame_t &frame, 40 | const ekg::io::stage &stage 41 | ); 42 | 43 | void high_frequency( 44 | ekg::property_t &property, 45 | ekg::frame_t &frame 46 | ); 47 | 48 | void pass( 49 | ekg::property_t &property, 50 | ekg::frame_t &frame 51 | ); 52 | 53 | void buffering( 54 | ekg::property_t &property, 55 | ekg::frame_t &frame 56 | ); 57 | 58 | void unmap( 59 | ekg::frame_t &frame 60 | ); 61 | } 62 | 63 | #endif 64 | -------------------------------------------------------------------------------- /include/ekg/ui/property.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License 3 | * 4 | * Copyright (c) 2022-2025 Rina Wilk / vokegpu@gmail.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | #ifndef EKG_UI_PROPERTY_HPP 25 | #define EKG_UI_PROPERTY_HPP 26 | 27 | #include "ekg/io/descriptor.hpp" 28 | #include "ekg/math/geometry.hpp" 29 | 30 | namespace ekg { 31 | struct property_t { 32 | public: 33 | struct operation_t { 34 | public: 35 | bool should_reload {}; 36 | bool should_docknize {}; 37 | bool should_enable_high_frequency {}; 38 | }; 39 | 40 | struct scroll_t { 41 | public: 42 | ekg::vec4_t position {}; 43 | ekg::vec2_t is_enabled {}; 44 | ekg::vec2_t is_scrolling {}; 45 | ekg::pixel_thickness_t nearest_scroll_bar_thickness {}; 46 | }; 47 | 48 | struct widget_t { 49 | public: 50 | ekg::rect_t rect_scissor {}; 51 | ekg::vec2_t min_size {}; 52 | ekg::rect_t rect {}; 53 | bool is_childnizate {}; 54 | bool is_children_docknizable {}; 55 | bool is_targeting_absolute_parent {}; 56 | bool is_absolute {}; 57 | bool is_active {}; 58 | bool is_hovering {}; 59 | bool is_visible {}; 60 | bool is_enabled {}; 61 | bool is_highlight {}; 62 | bool is_focused {}; 63 | bool is_warning {}; 64 | bool is_high_frequency {}; 65 | bool should_refresh_size {}; 66 | bool should_buffering {}; 67 | }; 68 | public: 69 | static ekg::property_t not_found; 70 | static constexpr ekg::type type {ekg::type::property}; 71 | public: 72 | ekg::at_t parent_at {ekg::at_t::not_found}; 73 | ekg::at_t abs_parent_at {ekg::at_t::not_found}; 74 | ekg::at_t descriptor_at {ekg::at_t::not_found}; 75 | std::vector children {}; 76 | public: 77 | ekg::property_t::widget_t widget {}; 78 | ekg::property_t::scroll_t scroll {}; 79 | ekg::property_t::operation_t operation {}; 80 | public: 81 | ekg_descriptor(ekg::property_t); 82 | }; 83 | } 84 | 85 | #endif 86 | -------------------------------------------------------------------------------- /include/ekg/ui/stack.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License 3 | * 4 | * Copyright (c) 2022-2025 Rina Wilk / vokegpu@gmail.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | #ifndef EKG_UI_STACK_HPP 25 | #define EKG_UI_STACK_HPP 26 | 27 | #include "ekg/io/memory.hpp" 28 | #include "ekg/io/descriptor.hpp" 29 | 30 | #include 31 | #include 32 | 33 | namespace ekg { 34 | struct stack_t { 35 | public: 36 | static constexpr ekg::type type {ekg::type::stack}; 37 | static ekg::stack_t not_found; 38 | public: 39 | std::string tag {}; 40 | std::vector widgets {}; 41 | public: 42 | ekg_descriptor(ekg::stack_t); 43 | }; 44 | } 45 | 46 | #endif 47 | -------------------------------------------------------------------------------- /linux.sh: -------------------------------------------------------------------------------- 1 | echo EKG building starting... 2 | 3 | MODE_BUILD_AND_TEST="build-and-test" 4 | MODE_BUILD_ONLY="build-only" 5 | MODE_COMPILER_EMSCRIPTEN="emscripten" 6 | 7 | echo "Building EKG in mode: $EKG_BUILD_MODE; with following compiler: $EKG_BUILD_COMPILER" 8 | 9 | if [[ "$EKG_BUILD_MODE" == "$MODE_BUILD_AND_TEST" ]]; then 10 | 11 | cmake \ 12 | -S . \ 13 | -B ./cmake-build \ 14 | -G Ninja \ 15 | -D CMAKE_EXPORT_COMPILE_COMMANDS=1 \ 16 | -D CMAKE_CXX_COMPILER=$EKG_BUILD_COMPILER \ 17 | -D CMAKE_BUILD_TYPE=Release \ 18 | -D CMAKE_INSTALL_PREFIX=./ekg-cmake-install 19 | 20 | cmake \ 21 | --build ./cmake-build \ 22 | \ 23 | && \ 24 | \ 25 | cmake \ 26 | --install ./cmake-build \ 27 | --prefix ./ekg-cmake-install \ 28 | \ 29 | && \ 30 | \ 31 | cd ./ekg-sandbox \ 32 | \ 33 | && \ 34 | \ 35 | cmake \ 36 | -S . \ 37 | -B ./cmake-build \ 38 | -G Ninja \ 39 | -D CMAKE_CXX_COMPILER=$EKG_BUILD_COMPILER \ 40 | -D CMAKE_BUILD_TYPE=Release \ 41 | -D EKG_DEVELOPER_MODE=1 \ 42 | \ 43 | && \ 44 | \ 45 | cmake \ 46 | --build ./cmake-build \ 47 | && cd ./bin && ./ekg-showcase 48 | fi 49 | 50 | if [[ "$EKG_BUILD_MODE" == "$MODE_BUILD_ONLY" ]]; then 51 | # # 52 | # Emscripten must be different compiled, due some specific flags 53 | # like 'EKG_EMSCRIPTEN_BUILD_TYPE'. 54 | # # 55 | if [[ "$EKG_BUILD_COMPILER" == "$MODE_COMPILER_EMSCRIPTEN" ]]; then 56 | emcmake cmake \ 57 | -S . \ 58 | -B ./cmake-build \ 59 | -G Ninja \ 60 | -D CMAKE_EXPORT_COMPILE_COMMANDS=1 \ 61 | -D EKG_EMSCRIPTEN_BUILD_TYPE=1 \ 62 | -D CMAKE_BUILD_TYPE=Release 63 | else 64 | cmake \ 65 | -S . \ 66 | -B ./cmake-build \ 67 | -G Ninja \ 68 | -D CMAKE_EXPORT_COMPILE_COMMANDS=1 \ 69 | -D CMAKE_CXX_COMPILER=$EKG_BUILD_COMPILER \ 70 | -D CMAKE_BUILD_TYPE=Release 71 | fi 72 | 73 | cmake \ 74 | --build ./cmake-build 75 | fi 76 | -------------------------------------------------------------------------------- /src/core/pools.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License 3 | * 4 | * Copyright (c) 2022-2025 Rina Wilk / vokegpu@gmail.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | #include "ekg/core/pools.hpp" 25 | #include "ekg/core/runtime.hpp" 26 | 27 | void ekg::core::registry(ekg::property_t &property) { 28 | ekg::p_core->registry.push_back(property.at); 29 | 30 | ekg::io::dispatch( 31 | ekg::io::operation::swap, 32 | property.at 33 | ); 34 | } 35 | -------------------------------------------------------------------------------- /src/draw/allocator.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License 3 | * 4 | * Copyright (c) 2022-2025 Rina Wilk / vokegpu@gmail.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #include "ekg/draw/allocator.hpp" 26 | #include "ekg/core/runtime.hpp" 27 | #include "ekg/io/log.hpp" 28 | #include "ekg/core/context.hpp" 29 | 30 | bool ekg::draw::allocator::enable_high_priority {}; 31 | bool ekg::draw::allocator::is_simple_shape {}; 32 | 33 | void ekg::draw::allocator::init() { 34 | ekg::log() << "Initializing GPU allocator"; 35 | } 36 | 37 | void ekg::draw::allocator::quit() { 38 | ekg::log() << "Quitting GPU allocator"; 39 | } 40 | 41 | void ekg::draw::allocator::invoke() { 42 | this->data_instance = 0; 43 | this->stride_instance.x = 0; 44 | this->stride_instance.y = 0; 45 | this->simple_shape_instance = 0; 46 | this->geometry_instance = 0; 47 | 48 | /** 49 | * inserting a simple triangle mesh, 50 | * is necessary to make work the simple-shape rendering. 51 | **/ 52 | this->push_back_geometry(0.0f, 0.0f, 0.0f, 0.0f); 53 | this->push_back_geometry(0.0f, 1.0f, 0.0f, 1.0f); 54 | this->push_back_geometry(1.0f, 0.0f, 1.0f, 0.0f); 55 | this->push_back_geometry(1.0f, 1.0f, 1.0f, 1.0f); 56 | 57 | if (this->data_instance >= this->gpu_data_buffer.size()) { 58 | this->gpu_data_buffer.emplace_back(); 59 | } 60 | 61 | this->stride_instance.x += this->stride_instance.y; 62 | this->stride_instance.y = 0; 63 | } 64 | 65 | void ekg::draw::allocator::bind_texture(ekg::sampler_t &sampler) { 66 | if (sampler == ekg::sampler_t::not_found) { 67 | return; 68 | } 69 | 70 | ekg::gpu::data_t &data {this->gpu_data_buffer.at(this->data_instance)}; 71 | data.sampler_at = ekg::p_core->p_gpu_api->bind_sampler(sampler); 72 | } 73 | 74 | void ekg::draw::allocator::dispatch() { 75 | ekg::gpu::data_t *p_data {/* stupid */}; 76 | 77 | if (ekg::draw::allocator::enable_high_priority) { 78 | this->high_priority_gpu_data_buffer.push_back(this->gpu_data_buffer.at(this->data_instance)); 79 | 80 | p_data = ( 81 | &this->high_priority_gpu_data_buffer.at(this->high_priority_data_instance) 82 | ); 83 | 84 | this->data_instance -= this->data_instance > 0; 85 | this->high_priority_data_instance++; 86 | } else { 87 | p_data = &this->gpu_data_buffer.at(this->data_instance); 88 | } 89 | 90 | /** 91 | * Scissor must be externally synchned. 92 | **/ 93 | p_data->buffer[8] = this->scissor_instance.x; 94 | p_data->buffer[9] = this->scissor_instance.y; 95 | p_data->buffer[10] = this->scissor_instance.w; 96 | p_data->buffer[11] = this->scissor_instance.h; 97 | 98 | /** 99 | * the point of re-using a simple shape stride makes performance a little better, 100 | * due the index rendering, with only one triangle for rectangles. 101 | **/ 102 | 103 | if (ekg::draw::allocator::is_simple_shape) { 104 | this->stride_instance.y = 0; 105 | 106 | /** 107 | * Simple shade contains only 4 vertices because it is indexed-rendered. 108 | **/ 109 | p_data->begin_stride = this->simple_shape_instance; 110 | p_data->end_stride = 4; 111 | } else { 112 | /** 113 | * Peek `ekg/gpu/gl/shaders.cpp`. 114 | * Any value less than -1.0 is considered a concave by the vertex shader. 115 | **/ 116 | p_data->buffer[3] = -1.1f; 117 | 118 | p_data->begin_stride = this->stride_instance.x; 119 | p_data->end_stride = this->stride_instance.y; 120 | } 121 | 122 | if (!this->was_hash_changed) { 123 | this->was_hash_changed = ( 124 | this->previous_hash != p_data->hash 125 | ); 126 | } 127 | 128 | this->stride_instance.x += this->stride_instance.y; 129 | this->stride_instance.y = 0; 130 | this->data_instance++; 131 | } 132 | 133 | void ekg::draw::allocator::revoke() { 134 | this->data_instance -= this->data_instance > 0; 135 | 136 | if (!this->high_priority_gpu_data_buffer.empty()) { 137 | uint64_t high_priority_gpu_data_buffer_size { 138 | this->high_priority_gpu_data_buffer.size() 139 | }; 140 | 141 | this->gpu_data_buffer.insert( 142 | this->gpu_data_buffer.begin() + this->data_instance + 1, 143 | this->high_priority_gpu_data_buffer.begin(), 144 | this->high_priority_gpu_data_buffer.end() 145 | ); 146 | 147 | this->data_instance += high_priority_gpu_data_buffer_size; 148 | this->high_priority_gpu_data_buffer.clear(); 149 | this->high_priority_data_instance = 0; 150 | } 151 | 152 | if ( 153 | this->last_geometry_buffer_size != this->geometry_instance 154 | || 155 | this->was_hash_changed 156 | ) { 157 | ekg::p_core->p_gpu_api->pass_geometry_buffer_to_gpu( 158 | this->geometry_buffer.data(), 159 | this->geometry_buffer.size() 160 | ); 161 | } 162 | 163 | this->last_geometry_buffer_size = this->geometry_instance; 164 | this->was_hash_changed = false; 165 | ekg::metrics.gpu_data_count = this->data_instance; 166 | } 167 | 168 | void ekg::draw::allocator::to_gpu() { 169 | ekg::p_core->p_gpu_api->pass_gpu_data_buffer_to_gpu( 170 | this->gpu_data_buffer 171 | ); 172 | } 173 | 174 | void ekg::draw::allocator::clear_current_data() { 175 | if (!ekg::draw::allocator::enable_high_priority && this->data_instance >= this->gpu_data_buffer.size()) { 176 | this->gpu_data_buffer.emplace_back(); 177 | } 178 | 179 | /* allocator handle automatically the size of data */ 180 | ekg::gpu::data_t &data {this->gpu_data_buffer.at(this->data_instance)}; 181 | data.line_thickness = 0; 182 | data.sampler_at = ekg::sampler_t::not_found; 183 | 184 | this->previous_hash = data.hash; 185 | } 186 | 187 | ekg::gpu::data_t &ekg::draw::allocator::bind_current_data() { 188 | this->clear_current_data(); 189 | return this->gpu_data_buffer.at(this->data_instance); 190 | } 191 | 192 | size_t ekg::draw::allocator::get_current_data_id() { 193 | return this->data_instance; 194 | } 195 | 196 | ekg::gpu::data_t &ekg::draw::allocator::get_data_by_index(size_t index) { 197 | if (index >= this->gpu_data_buffer.size()) { 198 | return ekg::gpu::data_t::not_found; 199 | } 200 | 201 | return this->gpu_data_buffer[index]; 202 | } 203 | 204 | bool ekg::draw::allocator::sync_scissor( 205 | ekg::rect_t &rect_scissor, 206 | ekg::rect_t &rect_child, 207 | ekg::rect_t &rect_parent_scissor, 208 | bool is_parented 209 | ) { 210 | rect_scissor.x = rect_child.x; 211 | rect_scissor.y = rect_child.y; 212 | rect_scissor.w = rect_child.w; 213 | rect_scissor.h = rect_child.h; 214 | 215 | if (is_parented) { 216 | bool only_if {}; 217 | 218 | only_if = rect_scissor.x < rect_parent_scissor.x; 219 | rect_scissor.w -= only_if * (rect_parent_scissor.x - rect_scissor.x); 220 | rect_scissor.x = ( 221 | (only_if * rect_parent_scissor.x) + (rect_scissor.x * !only_if) 222 | ); 223 | 224 | only_if = rect_scissor.y < rect_parent_scissor.y; 225 | rect_scissor.h -= only_if * (rect_parent_scissor.y - rect_scissor.y); 226 | rect_scissor.y = (only_if * rect_parent_scissor.y) + (rect_scissor.y * !only_if); 227 | 228 | only_if = rect_scissor.x + rect_scissor.w > rect_parent_scissor.x + rect_parent_scissor.w; 229 | rect_scissor.w -= only_if * ((rect_scissor.x + rect_scissor.w) - (rect_parent_scissor.x + rect_parent_scissor.w)); 230 | 231 | only_if = rect_scissor.y + rect_scissor.h > rect_parent_scissor.y + rect_parent_scissor.h; 232 | rect_scissor.h -= only_if * ((rect_scissor.y + rect_scissor.h) - (rect_parent_scissor.y + rect_parent_scissor.h)); 233 | 234 | this->scissor_instance.x = rect_scissor.x; 235 | this->scissor_instance.y = rect_scissor.y; 236 | this->scissor_instance.w = rect_scissor.w; 237 | this->scissor_instance.h = rect_scissor.h; 238 | 239 | return ( 240 | rect_scissor.x < rect_parent_scissor.x + rect_parent_scissor.w 241 | && 242 | rect_scissor.x + rect_scissor.w > rect_parent_scissor.x 243 | && 244 | rect_scissor.y < rect_parent_scissor.y + rect_parent_scissor.h 245 | && 246 | rect_scissor.y + rect_scissor.h > rect_parent_scissor.y 247 | ); 248 | } 249 | 250 | this->scissor_instance.x = rect_scissor.x; 251 | this->scissor_instance.y = rect_scissor.y; 252 | this->scissor_instance.w = rect_scissor.w; 253 | this->scissor_instance.h = rect_scissor.h; 254 | 255 | return true; 256 | } 257 | 258 | void ekg::draw::allocator::unsafe_set_scissor_rect( 259 | float x, 260 | float y, 261 | float w, 262 | float h 263 | ) { 264 | this->scissor_instance.x = x; 265 | this->scissor_instance.y = y; 266 | this->scissor_instance.w = w; 267 | this->scissor_instance.h = h; 268 | } 269 | 270 | void ekg::draw::allocator::push_back_geometry( 271 | float x, float y, 272 | float u, float v 273 | ) { 274 | this->stride_instance.y++; 275 | this->geometry_buffer.push_back(x); 276 | this->geometry_buffer.push_back(y); 277 | this->geometry_buffer.push_back(u); 278 | this->geometry_buffer.push_back(v); 279 | this->geometry_instance += 4; 280 | } 281 | -------------------------------------------------------------------------------- /src/draw/shape/shape.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License 3 | * 4 | * Copyright (c) 2022-2025 Rina Wilk / vokegpu@gmail.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #include "ekg/draw/shape/shape.hpp" 26 | #include "ekg/core/runtime.hpp" 27 | 28 | void ekg::draw::rect( 29 | const ekg::rect_t &rect, 30 | const ekg::rgba_t &color, 31 | ekg::pixel_thickness_t line_thickness, 32 | ekg::sampler_t &sampler 33 | ) { 34 | ekg::draw::rect( 35 | rect.x, rect.y, rect.w, rect.h, 36 | color, 37 | line_thickness, 38 | sampler 39 | ); 40 | } 41 | 42 | void ekg::draw::rect( 43 | float x, float y, float w, float h, 44 | const ekg::rgba_t &color, 45 | ekg::pixel_thickness_t line_thickness, 46 | ekg::sampler_t &sampler 47 | ) { 48 | if (color.w < 10) { 49 | return; 50 | } 51 | 52 | ekg::gpu::data_t &data { 53 | ekg::p_core->draw_allocator.bind_current_data() 54 | }; 55 | 56 | data.buffer[0] = x; 57 | data.buffer[1] = y; 58 | data.buffer[2] = w; 59 | data.buffer[3] = h; 60 | data.buffer[4] = static_cast(color.x) / 255; 61 | data.buffer[5] = static_cast(color.y) / 255; 62 | data.buffer[6] = static_cast(color.z) / 255; 63 | data.buffer[7] = static_cast(color.w) / 255; 64 | 65 | data.line_thickness = static_cast(line_thickness); 66 | data.hash = 1; 67 | 68 | ekg::draw::allocator::is_simple_shape = true; 69 | ekg::p_core->draw_allocator.bind_texture(sampler); 70 | ekg::p_core->draw_allocator.dispatch(); 71 | } 72 | 73 | void ekg::draw::scissor( 74 | const ekg::rect_t &rect 75 | ) { 76 | ekg::p_core->draw_allocator.unsafe_set_scissor_rect( 77 | rect.x, rect.y, rect.w, rect.h 78 | ); 79 | } 80 | 81 | void ekg::draw::scissor( 82 | float x, float y, float w, float h 83 | ) { 84 | ekg::p_core->draw_allocator.unsafe_set_scissor_rect( 85 | x, y, w, h 86 | ); 87 | } 88 | -------------------------------------------------------------------------------- /src/ekg.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License 3 | * 4 | * Copyright (c) 2022-2025 Rina Wilk / vokegpu@gmail.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | #include "ekg/ekg.hpp" 25 | #include "ekg/io/log.hpp" 26 | #include "ekg/core/context.hpp" 27 | #include "ekg/core/pools.hpp" 28 | 29 | #include "ekg/ui/button/widget.hpp" 30 | 31 | ekg::runtime_t *ekg::p_core {nullptr}; 32 | ekg::metrics_t ekg::metrics {}; 33 | ekg::dpi_t ekg::dpi {}; 34 | ekg::gui_t ekg::gui {}; 35 | ekg::pools_t ekg::pools {}; 36 | 37 | std::ostringstream ekg::log::buffer {}; 38 | bool ekg::log::buffered {}; 39 | 40 | ekg::flags_t ekg::init( 41 | ekg::runtime_properties_info_t &runtime_properties_info, 42 | ekg::runtime_t *p_runtime 43 | ) { 44 | if (p_runtime == nullptr) { 45 | ekg::log("~ERROR~ invalid (?) `ekg::runtime_t` pointer address: nullptr"); 46 | return ekg::result::failed; 47 | } 48 | 49 | ekg::log() << "Initializing..."; 50 | 51 | ekg::p_core = p_runtime; 52 | 53 | ekg::p_core->p_platform_base = runtime_properties_info.p_platform_base; 54 | ekg::p_core->p_gpu_api = runtime_properties_info.p_gpu_api; 55 | ekg::p_core->ft_library = runtime_properties_info.ft_library; 56 | 57 | ekg::p_core->p_platform_base->init(); 58 | ekg::p_core->p_gpu_api->init(); 59 | 60 | ekg::p_core->handler_callback.init(); 61 | ekg::p_core->handler_input.init(); 62 | ekg::p_core->handler_theme.init(); 63 | ekg::p_core->draw_allocator.init(); 64 | 65 | /* deprecated soon */ 66 | 67 | ekg::p_core->draw_font_small.init(); 68 | ekg::p_core->draw_font_small.set_font(runtime_properties_info.default_font_path_text); 69 | ekg::p_core->draw_font_small.set_font_emoji(runtime_properties_info.default_font_path_emoji); 70 | ekg::p_core->draw_font_small.get_atlas_texture_sampler().gl_protected_active_index = true;; 71 | 72 | ekg::p_core->draw_font_medium.init(); 73 | ekg::p_core->draw_font_medium.set_font(runtime_properties_info.default_font_path_text); 74 | ekg::p_core->draw_font_medium.set_font_emoji(runtime_properties_info.default_font_path_emoji); 75 | ekg::p_core->draw_font_medium.get_atlas_texture_sampler().gl_protected_active_index = true;; 76 | 77 | ekg::p_core->draw_font_big.init(); 78 | ekg::p_core->draw_font_big.set_font(runtime_properties_info.default_font_path_text); 79 | ekg::p_core->draw_font_big.set_font_emoji(runtime_properties_info.default_font_path_emoji); 80 | ekg::p_core->draw_font_big.get_atlas_texture_sampler().gl_protected_active_index = true; 81 | 82 | ekg::info_t info {}; 83 | ekg::core::scalenize(info); 84 | 85 | ekg::log() << "Successfully initialized"; 86 | 87 | return ekg::result::success; 88 | } 89 | 90 | void ekg::quit() { 91 | if (ekg::p_core == nullptr) { 92 | return; 93 | } 94 | } 95 | 96 | void ekg::update() { 97 | if (ekg::p_core == nullptr) { 98 | return; 99 | } 100 | 101 | ekg::p_core->handler_input.update(); 102 | 103 | size_t size {ekg::p_core->high_frequency.size()}; 104 | for (size_t it {}; it < size; it++) { 105 | ekg::property_t &property { 106 | ekg::query(ekg::p_core->high_frequency.at(it)) 107 | }; 108 | 109 | ekg_abstract_todo( 110 | property.descriptor_at.flags, 111 | property.descriptor_at, 112 | ekg::ui::high_frequency(property, descriptor); 113 | ); 114 | 115 | if ( 116 | // no not-found-check because `t::not_found` bool fields are always false 117 | !property.widget.is_high_frequency 118 | ) { 119 | property.operation.should_enable_high_frequency = false; // same here 120 | 121 | ekg::p_core->high_frequency.erase( 122 | ekg::p_core->high_frequency.begin() + it 123 | ); 124 | 125 | size = ekg::p_core->high_frequency.size(); 126 | } 127 | } 128 | 129 | ekg::p_core->handler_callback.update(); 130 | ekg::p_core->p_platform_base->update(); 131 | ekg::p_core->p_platform_base->event.type = ekg::io::event_type::none; 132 | 133 | ekg::log::flush(); 134 | } 135 | 136 | void ekg::render() { 137 | if (ekg::p_core == nullptr) { 138 | return; 139 | } 140 | 141 | if (ekg::gui.ui.redraw) { 142 | ekg::p_core->draw_allocator.invoke(); 143 | 144 | for (ekg::at_t &at : ekg::p_core->stack) { 145 | ekg::property_t &property { 146 | ekg::query(at) 147 | }; 148 | 149 | if (property == ekg::property_t::not_found) { 150 | continue; 151 | } 152 | 153 | ekg_abstract_todo( 154 | property.descriptor_at.flags, 155 | property.descriptor_at, 156 | 157 | ekg::ui::pass(property, descriptor); 158 | if (!property.widget.should_buffering) { 159 | continue; 160 | } 161 | 162 | ekg::ui::buffering(property, descriptor); 163 | ); 164 | } 165 | 166 | ekg::p_core->draw_allocator.revoke(); 167 | } 168 | 169 | ekg::gui.ui.redraw = false; 170 | ekg::p_core->draw_allocator.to_gpu(); 171 | } 172 | -------------------------------------------------------------------------------- /src/gpu/data.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License 3 | * 4 | * Copyright (c) 2022-2025 Rina Wilk / vokegpu@gmail.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | #include "ekg/gpu/data.hpp" 25 | 26 | ekg::gpu::data_t ekg::gpu::data_t::not_found {}; 27 | -------------------------------------------------------------------------------- /src/gpu/opengl/shaders.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License 3 | * 4 | * Copyright (c) 2022-2025 Rina Wilk / vokegpu@gmail.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | #include "ekg/gpu/opengl/shaders.hpp" 25 | 26 | void ekg::gpu::glsl_opengl_pipeline_vsh( 27 | const std::string &glsl_version, 28 | ekg::which_gpu_api which_gpu_api, 29 | std::string &out_shader 30 | ) { 31 | out_shader = glsl_version + R"( 32 | layout (location = 0) in vec2 aPos; 33 | layout (location = 1) in vec2 aTexCoord; 34 | 35 | uniform mat4 uProjection; 36 | uniform vec4 uRect; 37 | 38 | out vec2 vTexCoord; 39 | out vec2 vPos; 40 | out vec4 vRect; 41 | 42 | void main() { 43 | vec2 vertex = aPos; 44 | 45 | if (uRect.z > -1.0f && uRect.w > -1.0f) { 46 | vertex *= uRect.zw; 47 | } 48 | 49 | vertex += uRect.xy; 50 | 51 | gl_Position = uProjection * vec4(vertex, 0.0f, 1.0f); 52 | vTexCoord = aTexCoord; 53 | vRect = uRect; 54 | vPos = aPos; 55 | } 56 | )"; 57 | } 58 | 59 | void ekg::gpu::glsl_opengl_pipeline_fsh( 60 | const std::string &glsl_version, 61 | ekg::which_gpu_api which_gpu_api, 62 | std::string &out_shader 63 | ) { 64 | out_shader = glsl_version + R"( 65 | layout (location = 0) out vec4 aFragColor; 66 | uniform sampler2D uTextureSampler; 67 | 68 | in vec2 vTexCoord; 69 | in vec2 vPos; 70 | in vec4 vRect; 71 | 72 | uniform int uLineThickness; 73 | uniform int uActiveTexture; 74 | uniform float uViewportHeight; 75 | uniform float uContent[8]; 76 | 77 | void main() { 78 | aFragColor = vec4( 79 | uContent[0], 80 | uContent[1], 81 | uContent[2], 82 | uContent[3] 83 | ); 84 | 85 | vec2 fragPos = vec2(gl_FragCoord.x, uViewportHeight - gl_FragCoord.y); 86 | 87 | /** 88 | * The scissoring works like swapchain-one (does not stack), of course, 89 | * this scissor is a little different, the pixel-perfect precision makes 90 | * a better cut of fragments. And does not require any overhead from 91 | * calling command buffers to GPU rastarizer. 92 | **/ 93 | bool shouldDiscard = ( 94 | fragPos.x <= uContent[4] 95 | || 96 | fragPos.y <= uContent[5] 97 | || 98 | fragPos.x >= uContent[4] + uContent[6] 99 | || 100 | fragPos.y >= uContent[5] + uContent[7] 101 | ); 102 | 103 | float lineThicknessf = float(uLineThickness); 104 | 105 | /** 106 | * The pixel-perfect outline is possible on fragment shader, 107 | * due the precision of fragments position, and the 108 | * normalised-space. 109 | **/ 110 | if (uLineThickness > 0) { 111 | vec4 outline = vec4( 112 | vRect.x + lineThicknessf, 113 | vRect.y + lineThicknessf, 114 | vRect.z - (lineThicknessf * 2.0f), 115 | vRect.w - (lineThicknessf * 2.0f) 116 | ); 117 | 118 | shouldDiscard = ( 119 | shouldDiscard || ( 120 | fragPos.x > outline.x && 121 | fragPos.x < outline.x + outline.z && 122 | fragPos.y > outline.y && 123 | fragPos.y < outline.y + outline.w 124 | ) 125 | ); 126 | } else if (uLineThickness < 0) { 127 | float radius = vRect.z / 2.0f; 128 | 129 | vec2 diff = vec2( 130 | (vRect.x + radius) - fragPos.x, 131 | (vRect.y + radius) - fragPos.y 132 | ); 133 | 134 | float dist = (diff.x * diff.x + diff.y * diff.y); 135 | aFragColor.w = ( 136 | 1.0f - smoothstep(0.0, radius * radius, dot(dist, dist)) 137 | ); 138 | } 139 | 140 | /** 141 | * The discard must not call `discard` keyword, 142 | * discarding pixels using keyword is performanceless 143 | * comparated to alpha blending equals to zero. 144 | **/ 145 | if (shouldDiscard) { 146 | aFragColor.w = 0.0f; 147 | } else { 148 | vec4 textureColor; 149 | switch (uActiveTexture) { 150 | case 1: 151 | textureColor = texture(uTextureSampler, vTexCoord); 152 | 153 | /** 154 | * The sampler used here is the font, and this sampler needs swizzled mapped, 155 | * instead of doing swizzling on CPU-side, here is actually the best place. 156 | * Due the necessity of put swizzle for ttf text fonts, the emojis must not swizzle. 157 | * The non swizzable range masterfully fix it. 158 | * 159 | * vRect.z is negative, because any concave rendering shape does not have a fixed 160 | * dimension size. So the rendering engine re-uses the Rect width to calculate 161 | * when must stop the GPU-side swizzle. 162 | **/ 163 | float non_swizzlable_range = -vRect.z; 164 | 165 | if (vTexCoord.x < non_swizzlable_range) { 166 | textureColor = textureColor.aaar; 167 | textureColor = vec4( 168 | textureColor.rgb * aFragColor.rgb, 169 | textureColor.a 170 | ); 171 | } 172 | 173 | aFragColor = vec4( 174 | textureColor.rgb, 175 | textureColor.a - (1.0f - aFragColor.a) 176 | ); 177 | 178 | //aFragColor = vec4(aFragColor.a, 0.0f, 0.0f, 1.0f); 179 | break; 180 | case 2: 181 | textureColor = texture(uTextureSampler, vPos); 182 | 183 | aFragColor = vec4( 184 | textureColor.rgb, 185 | textureColor.a - (1.0f - aFragColor.a) 186 | ); 187 | break; 188 | } 189 | } 190 | } 191 | )"; 192 | } 193 | -------------------------------------------------------------------------------- /src/gpu/sampler.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License 3 | * 4 | * Copyright (c) 2022-2025 Rina Wilk / vokegpu@gmail.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | #include "ekg/gpu/sampler.hpp" 25 | 26 | ekg::sampler_t ekg::sampler_t::not_found {}; 27 | 28 | ekg::flags_t ekg::sampler_src_r8_to_r8g8b8a8( 29 | const ekg::vec2_t &size, 30 | const unsigned char *p_src, 31 | std::vector &dst 32 | ) { 33 | if ( 34 | p_src == nullptr 35 | || 36 | size.x == 0 37 | || 38 | size.y == 0 39 | || 40 | dst.size() != (size.x * size.y) 41 | ) { 42 | return ekg::result::failed; 43 | } 44 | 45 | size_t index {}; 46 | 47 | for (size_t it {}; it < size.x * size.y; it++) { 48 | const unsigned char &char8_red_color { 49 | p_src[it] 50 | }; 51 | 52 | index = it * 4; 53 | 54 | if (index == dst.size()) { 55 | break; 56 | } 57 | 58 | /** 59 | * may I be wrong? but the format is ARGB and not RGBA, 60 | * I do not know. 61 | **/ 62 | 63 | dst.at(index + 0) = char8_red_color; 64 | dst.at(index + 1) = 255; 65 | dst.at(index + 2) = 255; 66 | dst.at(index + 3) = 255; 67 | } 68 | 69 | return ekg::result::success; 70 | } 71 | -------------------------------------------------------------------------------- /src/handler/callback.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License 3 | * 4 | * Copyright (c) 2022-2025 Rina Wilk / vokegpu@gmail.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | #include "ekg/handler/callback.hpp" 25 | 26 | ekg::callback_t ekg::callback_t::not_found { 27 | .at = ekg::at_t::not_found 28 | }; 29 | -------------------------------------------------------------------------------- /src/handler/callback/handler.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License 3 | * 4 | * Copyright (c) 2022-2025 Rina Wilk / vokegpu@gmail.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | #include "ekg/handler/callback/handler.hpp" 25 | #include "ekg/io/log.hpp" 26 | #include "ekg/core/pools.hpp" 27 | #include "ekg/core/runtime.hpp" 28 | 29 | void ekg::handler::callback::init() { 30 | ekg::log() << "Initialising callback-handler"; 31 | 32 | ekg::callback_t &swap {this->load()}; 33 | swap.info.tag = "swap"; 34 | swap.function = &ekg::core::swap; 35 | 36 | ekg::callback_t &reload {this->load()}; 37 | reload.info.tag = "reload"; 38 | reload.function = &ekg::core::reload; 39 | 40 | ekg::callback_t &docknize {this->load()}; 41 | docknize.info.tag = "docknize"; 42 | docknize.function = &ekg::core::docknize; 43 | 44 | ekg::callback_t &scalenize {this->load()}; 45 | scalenize.info.tag = "scalenize"; 46 | scalenize.function = &ekg::core::scalenize; 47 | } 48 | 49 | ekg::callback_t &ekg::handler::callback::load() { 50 | ekg::callback_t &task {ekg::make({})}; 51 | this->loaded.emplace_back() = task.at; 52 | return task; 53 | } 54 | 55 | void ekg::handler::callback::dispatch(ekg::at_t &at) { 56 | ekg::callback_t &callback {ekg::query(at)}; 57 | if ( 58 | callback != ekg::callback_t::not_found 59 | && 60 | !ekg::has(callback.at.flags, ekg::handler::status::dispatched) 61 | ) { 62 | callback.at.flags |= ekg::handler::status::dispatched; 63 | this->queue.push(callback.at); 64 | } 65 | } 66 | 67 | void ekg::handler::callback::dispatch(uint64_t index) { 68 | ekg::at_t &at {this->loaded.at(index)}; 69 | ekg::callback_t &callback {ekg::query(at)}; 70 | 71 | if ( 72 | callback != ekg::callback_t::not_found 73 | && 74 | !ekg::has(callback.at.flags, ekg::handler::status::dispatched) 75 | ) { 76 | callback.at.flags |= ekg::handler::status::dispatched; 77 | this->queue.push(callback.at); 78 | } 79 | } 80 | 81 | void ekg::handler::callback::update() { 82 | while (!this->queue.empty()) { 83 | ekg::callback_t &callback {ekg::query(this->queue.front())}; 84 | this->queue.pop(); 85 | 86 | if (callback == ekg::callback_t::not_found) { 87 | continue; 88 | } 89 | 90 | if (callback.lambda) { 91 | callback.lambda(callback.info); 92 | } 93 | 94 | if (callback.function) { 95 | callback.function(callback.info); 96 | } 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /src/handler/input.cpp: -------------------------------------------------------------------------------- 1 | #include "ekg/handler/input.hpp" 2 | #include "ekg/core/runtime.hpp" 3 | 4 | ekg::input_info_t &ekg::input() { 5 | return ekg::p_core->handler_input.input; 6 | } 7 | 8 | bool ekg::fire(std::string_view tag) { 9 | return ekg::p_core->handler_input.get_input_bind_state(tag); 10 | } 11 | 12 | bool ekg::input(std::string_view input) { 13 | return ekg::p_core->handler_input.get_input_state(input); 14 | } 15 | 16 | void ekg::bind(std::string_view tag, std::string_view input) { 17 | ekg::p_core->handler_input.insert_input_bind(tag, input); 18 | } 19 | 20 | void ekg::bind(std::string_view tag, std::vector inputs) { 21 | for (std::string_view &input : inputs) { 22 | ekg::bind(tag, inputs); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/handler/theme.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License 3 | * 4 | * Copyright (c) 2022-2025 Rina Wilk / vokegpu@gmail.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | #include "ekg/handler/theme.hpp" 25 | #include "ekg/core/runtime.hpp" 26 | 27 | ekg::theme_t &ekg::theme( 28 | std::string_view tag 29 | ) { 30 | if (tag.empty()) { 31 | return ekg::p_core->handler_theme.get_current_theme(); 32 | } 33 | 34 | return ekg::p_core->handler_theme.registry(tag); 35 | } 36 | 37 | ekg::theme_t &ekg::set_current_theme( 38 | std::string_view tag 39 | ) { 40 | ekg::p_core->handler_theme.set_current_theme(tag); 41 | return ekg::theme(tag); 42 | } 43 | -------------------------------------------------------------------------------- /src/handler/theme/handler.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License 3 | * 4 | * Copyright (c) 2022-2025 Rina Wilk / vokegpu@gmail.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | #include "ekg/handler/theme/handler.hpp" 25 | #include "ekg/io/log.hpp" 26 | 27 | void ekg::handler::theme::init() { 28 | ekg::log() << "Initializing default themes"; 29 | 30 | ekg::theme_t light_pinky_theme { 31 | .tag = "light-pinky", 32 | .author = "Rina Wilk", 33 | .description = "Pasted light-theme... moow", 34 | }; 35 | 36 | light_pinky_theme.frame_color_scheme.background = {242, 242, 242, 255}; 37 | light_pinky_theme.frame_color_scheme.highlight = {242, 242, 242, 0}; 38 | light_pinky_theme.frame_color_scheme.outline = {190, 190, 190, 0}; 39 | light_pinky_theme.frame_color_scheme.active = {242, 242, 242, 0}; 40 | light_pinky_theme.frame_color_scheme.focused_background = {242, 242, 242, 0}; 41 | light_pinky_theme.frame_color_scheme.focused_outline = {242, 242, 242, 0}; 42 | light_pinky_theme.frame_color_scheme.warning_outline = {242, 242, 0, 100}; 43 | light_pinky_theme.frame_color_scheme.actions_margin_pixel_thickness = 18; 44 | 45 | this->registry(light_pinky_theme.tag) = light_pinky_theme; 46 | this->set_current_theme(light_pinky_theme.tag); 47 | } 48 | 49 | void ekg::handler::theme::quit() { 50 | } 51 | 52 | ekg::theme_t &ekg::handler::theme::registry(const std::string_view &tag) { 53 | return this->themes[tag]; 54 | } 55 | 56 | ekg::theme_t &ekg::handler::theme::set_current_theme(const std::string_view &tag) { 57 | this->current_theme_tag = tag; 58 | return this->themes[tag]; 59 | } 60 | 61 | ekg::theme_t &ekg::handler::theme::get_current_theme() { 62 | return this->themes[this->current_theme_tag]; 63 | } 64 | -------------------------------------------------------------------------------- /src/io/event.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License 3 | * 4 | * Copyright (c) 2022-2025 Rina Wilk / vokegpu@gmail.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | #include "ekg/io/event.hpp" 25 | #include "ekg/core/runtime.hpp" 26 | #include "ekg/core/pools.hpp" 27 | #include "ekg/core/context.hpp" 28 | 29 | void ekg::io::dispatch( 30 | ekg::io::operation op, 31 | ekg::at_t &property_at 32 | ) { 33 | ekg::property_t &property { 34 | ekg::query(property_at) 35 | }; 36 | 37 | if ( 38 | op != ekg::io::operation::swap 39 | && 40 | op != ekg::io::operation::scalenize 41 | && 42 | property == ekg::property_t::not_found 43 | ) { 44 | return; 45 | } 46 | 47 | switch (op) { 48 | case ekg::io::operation::swap: 49 | if (property != ekg::property_t::not_found) { 50 | ekg::gui.bind.swap_at = property_at; 51 | } 52 | 53 | ekg::p_core->handler_callback.dispatch( 54 | static_cast(op) 55 | ); 56 | break; 57 | case ekg::io::operation::reload: 58 | if (property.operation.should_docknize) return; 59 | property.operation.should_reload = true; 60 | ekg::p_core->reload.push_back(property_at); 61 | ekg::p_core->handler_callback.dispatch( 62 | static_cast(op) 63 | ); 64 | break; 65 | case ekg::io::operation::docknize: 66 | if (property.operation.should_docknize) return; 67 | property.operation.should_docknize = true; 68 | ekg::p_core->docknize.push_back(property_at); 69 | ekg::p_core->handler_callback.dispatch( 70 | static_cast(op) 71 | ); 72 | break; 73 | case ekg::io::operation::scalenize: 74 | ekg::p_core->handler_callback.dispatch( 75 | static_cast(op) 76 | ); 77 | break; 78 | case ekg::io::operation::high_frequency: 79 | property.widget.is_high_frequency = true; // make sure this tick is true 80 | if (property.operation.should_enable_high_frequency) return; 81 | property.operation.should_enable_high_frequency = true; 82 | ekg::p_core->high_frequency.push_back(property_at); 83 | break; 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /src/io/font.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License 3 | * 4 | * Copyright (c) 2022-2025 Rina Wilk / vokegpu@gmail.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #include "ekg/io/font.hpp" 26 | #include "ekg/core/runtime.hpp" 27 | #include "ekg/io/log.hpp" 28 | 29 | ekg::flags_t ekg::io::font( 30 | ekg::io::font_face_t &font_face 31 | ) { 32 | if (font_face.was_face_changed) { 33 | if (font_face.was_loaded) { 34 | FT_Done_Face(font_face.ft_face); 35 | font_face.was_loaded = false; 36 | } 37 | 38 | font_face.was_loaded = FT_New_Face( 39 | ekg::p_core->ft_library, 40 | font_face.path.data(), 41 | 0, 42 | &font_face.ft_face 43 | ); 44 | 45 | if (font_face.was_loaded) { 46 | ekg::log() << "Could not load font " << font_face.path; 47 | return ekg::result::failed; 48 | } 49 | 50 | ekg::log() << "Font '" << font_face.path << "' loaded!"; 51 | 52 | font_face.was_loaded = true; 53 | font_face.was_face_changed = false; 54 | } 55 | 56 | if (font_face.was_loaded && font_face.was_size_changed) { 57 | FT_Set_Pixel_Sizes(font_face.ft_face, 0, font_face.size); 58 | font_face.was_size_changed = false; 59 | } 60 | 61 | return ekg::result::success; 62 | } 63 | -------------------------------------------------------------------------------- /src/io/memory.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License 3 | 4 | * Copyright (c) 2022-2025 Rina Wilk / vokegpu@gmail.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | #include "ekg/io/memory.hpp" 25 | #include "ekg/core/context.hpp" 26 | #include "ekg/core/pools.hpp" 27 | 28 | ekg::at_t ekg::at_t::not_found {}; 29 | 30 | ekg::signed_address_info_t ekg::sign {}; 31 | 32 | void ekg::map(void *pv_address) { 33 | if (pv_address == nullptr) { 34 | ekg::sign.current = ekg::not_found; 35 | return; 36 | } 37 | 38 | ekg::stack_t ¤t_stack { 39 | ekg::query(ekg::gui.bind.stack_at) 40 | }; 41 | 42 | if (current_stack == ekg::stack_t::not_found) { 43 | ekg::sign.current = ekg::not_found; 44 | return; 45 | } 46 | size_t size {ekg::sign.list.size()}; 47 | for (size_t it {}; it < size; it++) { 48 | ekg::mapped_address_sign_info_t &info {ekg::sign.list.at(it)}; 49 | if (info.pv_address == pv_address) { 50 | ekg::sign.current = it; 51 | return; 52 | } 53 | } 54 | 55 | ekg::sign.current = ekg::sign.list.size(); 56 | ekg::sign.list.push_back({.ats = {}, .pv_address = pv_address}); 57 | } 58 | 59 | void ekg::unmap(void *pv_address) { 60 | if (pv_address) { 61 | return; 62 | } 63 | 64 | size_t size {ekg::sign.list.size()}; 65 | for (size_t it {}; it < size; it++) { 66 | ekg::mapped_address_sign_info_t &info {ekg::sign.list.at(it)}; 67 | if (info.pv_address == pv_address) { 68 | for (ekg::at_t &at : info.ats) { 69 | ekg_abstract_todo( 70 | at.flags, 71 | at, 72 | ekg::ui::unmap(descriptor); 73 | ); 74 | } 75 | 76 | ekg::sign.list.erase( 77 | ekg::sign.list.begin() + it 78 | ); 79 | break; 80 | } 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/io/timing.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License 3 | * 4 | * Copyright (c) 2022-2025 Rina Wilk / vokegpu@gmail.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | #include "ekg/io/timing.hpp" 25 | 26 | int64_t ekg::timing_t::second {}; 27 | int64_t ekg::timing_t::ticks {}; 28 | 29 | bool ekg::reach(ekg::timing_t &timing, int64_t ms) { 30 | timing.ticks_going_on = ekg::timing_t::ticks; 31 | timing.current_ticks = timing.ticks_going_on - timing.elapsed_ticks; 32 | return timing.current_ticks > ms; 33 | } 34 | 35 | bool ekg::reset(ekg::timing_t &timing) { 36 | timing.elapsed_ticks = timing.ticks_going_on; 37 | return true; 38 | } 39 | 40 | bool ekg::reset_if_reach(ekg::timing_t &timing, int64_t ms) { 41 | timing.ticks_going_on = ekg::timing_t::ticks; 42 | timing.current_ticks = timing.ticks_going_on - timing.elapsed_ticks; 43 | 44 | if (timing.current_ticks > ms) { 45 | timing.elapsed_ticks = timing.ticks_going_on; 46 | return true; 47 | } 48 | 49 | return false; 50 | } 51 | 52 | bool ekg::extend(ekg::timing_t &timing, int64_t ms) { 53 | timing.elapsed_ticks = timing.ticks_going_on - ms; 54 | return true; 55 | } 56 | 57 | int64_t ekg::interval(ekg::timing_t &timing) { 58 | timing.ticks_going_on = ekg::timing_t::ticks; 59 | return ( 60 | timing.current_ticks = timing.ticks_going_on - timing.elapsed_ticks 61 | ); 62 | } 63 | -------------------------------------------------------------------------------- /src/io/utf.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License 3 | * 4 | * Copyright (c) 2022-2025 Rina Wilk / vokegpu@gmail.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | #include "ekg/io/utf.hpp" 25 | 26 | #include 27 | #include 28 | #include 29 | 30 | uint64_t ekg::utf8_check_sequence( 31 | uint8_t &char8, 32 | char32_t &char32, 33 | std::string &utf_string, 34 | std::string_view string, 35 | uint64_t index 36 | ) { 37 | if (char8 <= 0x7F) { 38 | utf_string = char8; 39 | char32 = static_cast(char8); 40 | return 0; 41 | } else if ((char8 & 0xE0) == 0xC0) { 42 | utf_string = string.substr(index, 2); 43 | char32 = ekg::utf8_to_utf32(utf_string); 44 | return 1; 45 | } else if ((char8 & 0xF0) == 0xE0) { 46 | utf_string = string.substr(index, 3); 47 | char32 = ekg::utf8_to_utf32(utf_string); 48 | return 2; 49 | } else if ((char8 & 0xF8) == 0xF0) { 50 | utf_string = string.substr(index, 4); 51 | char32 = ekg::utf8_to_utf32(utf_string); 52 | return 3; 53 | } 54 | 55 | return 0; 56 | } 57 | 58 | std::string ekg::utf32_to_string(char32_t char32) { 59 | std::string result {}; 60 | 61 | if (char32 < 0x80) { 62 | result.reserve(1); 63 | result[0] = static_cast(char32); 64 | } else if (char32 < 0x800) { 65 | result.reserve(2); 66 | result[0] += static_cast(0xC0 | (char32 >> 6)); 67 | result[1] += static_cast(0x80 | (char32 & 0x3F)); 68 | } else if (char32 < 0x10000) { 69 | result.reserve(3); 70 | result[0] += static_cast(0xE0 | (char32 >> 12)); 71 | result[1] += static_cast(0x80 | ((char32 >> 6) & 0x3F)); 72 | result[2] += static_cast(0x80 | (char32 & 0x3F)); 73 | } else if (char32 < 0x110000) { 74 | result.reserve(4); 75 | result[0] = static_cast(0xF0 | (char32 >> 18)); 76 | result[1] = static_cast(0x80 | ((char32 >> 12) & 0x3F)); 77 | result[2] = static_cast(0x80 | ((char32 >> 6) & 0x3F)); 78 | result[3] = static_cast(0x80 | (char32 & 0x3F)); 79 | } 80 | 81 | return result; 82 | } 83 | 84 | char32_t ekg::utf8_to_utf32(std::string_view string) { 85 | char32_t char32 {}; 86 | 87 | uint64_t it {}; 88 | uint8_t char8 {static_cast(string.at(0))}; 89 | 90 | if (char8 <= 0x7F) { 91 | char32 = char8; 92 | } else if (char8 <= 0xDF) { 93 | char32 = char8 & 0x1F; 94 | char32 = (char32 << 6) | (string.at(++it) & 0x3F); 95 | } else if (char8 <= 0xEF) { 96 | char32 = char8 & 0x0F; 97 | char32 = (char32 << 6) | (string.at(++it) & 0x3F); 98 | char32 = (char32 << 6) | (string.at(++it) & 0x3F); 99 | } else { 100 | char32 = char8 & 0x07; 101 | char32 = (char32 << 6) | (string.at(++it) & 0x3F); 102 | char32 = (char32 << 6) | (string.at(++it) & 0x3F); 103 | char32 = (char32 << 6) | (string.at(++it) & 0x3F); 104 | } 105 | 106 | return char32; 107 | } 108 | 109 | uint64_t ekg::utf8_length(std::string_view utf_string) { 110 | if (utf_string.empty()) { 111 | return 0; 112 | } 113 | 114 | uint64_t string_size {}; 115 | uint8_t char8 {}; 116 | 117 | for (uint64_t it {}; it < utf_string.size(); it++) { 118 | char8 = static_cast(utf_string.at(it)); 119 | if (char8 == '\n' || char8 == '\r') { 120 | continue; 121 | } else if (char8 <= 0x7F) { 122 | string_size++; 123 | } else if ((char8 & 0xE0) == 0xC0) { 124 | string_size++; 125 | it++; 126 | } else if ((char8 & 0xF0) == 0xE0) { 127 | string_size++; 128 | it += 2; 129 | } else if ((char8 & 0xF8) == 0xF0) { 130 | string_size++; 131 | it += 3; 132 | } 133 | } 134 | 135 | return string_size; 136 | } 137 | 138 | std::string ekg::utf8_substr(std::string_view string, uint64_t offset, uint64_t size) { 139 | if (string.empty() || size == 0) { 140 | return ""; 141 | } 142 | 143 | uint64_t string_size {string.size()}; 144 | uint64_t utf_text_size {}; 145 | 146 | //offset = offset > string_size ? string_size : offset; 147 | size += offset; 148 | 149 | uint64_t index {}; 150 | uint64_t utf_sequence_size {}; 151 | uint64_t begin {UINT64_MAX}; 152 | uint8_t char8 {}; 153 | bool at_last_index {}; 154 | 155 | /* 156 | * This function implementation checks the amount of bytes per char for UTF-8. 157 | * There is no support for UTF-16 or directly UTF-32. 158 | */ 159 | 160 | while (index < string_size) { 161 | char8 = static_cast(string.at(index)); 162 | 163 | utf_sequence_size = 1; 164 | utf_sequence_size += ((char8 & 0xE0) == 0xC0); 165 | utf_sequence_size += 2 * ((char8 & 0xF0) == 0xE0); 166 | utf_sequence_size += 3 * ((char8 & 0xF8) == 0xF0); 167 | 168 | at_last_index = index + utf_sequence_size == string_size; 169 | 170 | if ((at_last_index || utf_text_size >= offset) && begin == UINT64_MAX) { 171 | begin = ekg::clamp_max(index, string_size); 172 | } 173 | 174 | index += utf_sequence_size; 175 | utf_text_size++; 176 | 177 | if ( 178 | /** 179 | * OBS: 180 | * If the `offset` parameter is equals to the last UTF-8 string size, 181 | * then it continue without substring process. 182 | **/ 183 | (at_last_index && begin != UINT64_MAX && offset != utf_text_size) || 184 | (utf_text_size >= size) 185 | ) { 186 | string = string.substr(begin, (index - begin)); 187 | return std::string {string.begin(), string.end()}; 188 | } 189 | } 190 | 191 | return ""; 192 | } 193 | 194 | void ekg::utf8_split_new_line(std::string_view string, std::vector &utf8_read) { 195 | if (string.empty()) { 196 | return; 197 | } 198 | 199 | /* if the first element is empty, then the decode must start from it */ 200 | if (utf8_read.size() == 1 && utf8_read.at(0).empty()) { 201 | utf8_read.clear(); 202 | } 203 | 204 | uint64_t index {}; 205 | uint64_t start_index {}; 206 | 207 | while ((index = string.find('\n', start_index)) != std::string_view::npos) { 208 | utf8_read.emplace_back( 209 | string.substr( 210 | start_index, 211 | (index - start_index) - (index > 0 && string.at(index - 1) == '\r') 212 | ) 213 | ); 214 | 215 | start_index = index + 1; 216 | } 217 | 218 | if (!string.empty() && 219 | !( 220 | string = string.substr(start_index, string.find('\0', start_index)) 221 | ).empty() 222 | ) { 223 | // `meow\n\0`, so the decode wont emplace a empty string. 224 | utf8_read.emplace_back(string); 225 | } 226 | } 227 | 228 | bool ekg::utf8_split( 229 | std::vector &splitted, 230 | const std::string &string, 231 | char find_char 232 | ) { 233 | std::stringstream ss(string); 234 | std::string find_string {}; 235 | 236 | bool found_flag {}; 237 | 238 | while (std::getline(ss, find_string, find_char)) { 239 | splitted.push_back(find_string); 240 | found_flag = true; 241 | } 242 | 243 | return found_flag; 244 | } 245 | -------------------------------------------------------------------------------- /src/layout/extentnize.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License 3 | * 4 | * Copyright (c) 2022-2025 Rina Wilk / vokegpu@gmail.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | #include "ekg/layout/extentnize.hpp" 25 | #include "ekg/core/runtime.hpp" 26 | #include "ekg/io/descriptor.hpp" 27 | #include "ekg/core/pools.hpp" 28 | 29 | ekg::layout::extent_t ekg::layout::extent_t::v_widget {}; 30 | ekg::layout::extent_t ekg::layout::extent_t::h_widget {}; 31 | ekg::layout::extent_t ekg::layout::extent_t::v_mask {}; 32 | ekg::layout::extent_t ekg::layout::extent_t::h_mask {}; 33 | 34 | void ekg::layout::extentnize_mask( 35 | std::vector &components, 36 | ekg::vec3_t offset, 37 | ekg::flags_t flag_ok, 38 | ekg::flags_t flag_stop, 39 | ekg::flags_t flag_axis, 40 | float &extent, 41 | int32_t &in_out_count 42 | ) { 43 | extent = 0.0f; 44 | switch (flag_axis & ekg::axis::horizontal) { 45 | case ekg::axis::horizontal: { 46 | int32_t it {in_out_count}; 47 | 48 | if ( 49 | it > ekg::layout::extent_t::h_mask.begin_index 50 | && 51 | it < ekg::layout::extent_t::h_mask.end_index 52 | ) { 53 | in_out_count = ekg::layout::extent_t::h_mask.count; 54 | extent = ekg::layout::extent_t::h_mask.extent; 55 | return; 56 | } 57 | 58 | ekg::layout::extent_t::h_mask.begin_index = static_cast(it); 59 | 60 | int32_t size {static_cast(components.size())}; 61 | int32_t latest_index {static_cast(size - (!components.empty()))}; 62 | int32_t should_skip_next {}; 63 | int32_t flag_ok_count {}; 64 | 65 | bool is_last_index {}; 66 | bool is_ok_flag {}; 67 | 68 | extent += offset.x; 69 | 70 | for (it = it; it < size; it++) { 71 | ekg::layout::mask::component_t &component {components.at(it)}; 72 | if (component.p_rect == nullptr) { 73 | continue; 74 | } 75 | 76 | is_last_index = it == latest_index; 77 | 78 | if ( 79 | (ekg::has(component.dock, flag_stop) && it != in_out_count) 80 | || 81 | is_last_index 82 | ) { 83 | extent -= offset.x; 84 | flag_ok_count += ( 85 | (is_ok_flag = (!ekg::has(component.dock, flag_stop) && (ekg::has(component.dock, flag_ok)) && is_last_index)) 86 | ); 87 | 88 | /** 89 | * Basically if the container/frame mother ends with any non flag ok (ekg::dock::fill) 90 | * it MUST add the width size to extend. 91 | * 92 | * :blush: 93 | **/ 94 | extent += ( 95 | (component.p_rect->w + offset.x) 96 | * 97 | (is_last_index && (!ekg::has(component.dock, flag_ok) && should_skip_next == 0)) 98 | ); 99 | 100 | ekg::layout::extent_t::h_mask.end_index = it + is_last_index; 101 | ekg::layout::extent_t::h_mask.extent = extent; 102 | ekg::layout::extent_t::h_mask.count = flag_ok_count + (flag_ok_count == 0); 103 | break; 104 | } 105 | 106 | should_skip_next += ekg::has(component.dock, ekg::dock::concat); 107 | 108 | if (should_skip_next > 0) { 109 | should_skip_next = (should_skip_next + 1) * (should_skip_next < 2); 110 | flag_ok_count += ekg::has(component.dock, flag_ok); 111 | continue; 112 | } 113 | 114 | if (ekg::has(component.dock, flag_ok)) { 115 | flag_ok_count++; 116 | continue; 117 | } 118 | 119 | extent += component.p_rect->w + offset.x; 120 | } 121 | 122 | in_out_count = flag_ok_count + (flag_ok_count == 0); 123 | break; 124 | } 125 | 126 | case ekg::axis::vertical: { 127 | break; 128 | } 129 | } 130 | } 131 | 132 | void ekg::layout::extentnize_widget( 133 | ekg::property_t &parent_property, 134 | ekg::flags_t flag_ok, 135 | ekg::flags_t flag_stop, 136 | ekg::flags_t flag_axis, 137 | float &extent, 138 | int32_t &in_out_count 139 | ) { 140 | extent = 0.0f; 141 | 142 | int32_t begin_index {in_out_count}; 143 | switch (flag_axis & ekg::axis::horizontal) { 144 | case ekg::axis::horizontal: { 145 | int32_t it {begin_index}; 146 | 147 | if ( 148 | it > ekg::layout::extent_t::h_widget.begin_index 149 | && 150 | it < ekg::layout::extent_t::h_widget.end_index 151 | ) { 152 | 153 | in_out_count = static_cast(ekg::layout::extent_t::h_widget.count); 154 | extent = ekg::layout::extent_t::h_widget.extent; 155 | break; 156 | } 157 | 158 | ekg::layout::extent_t::h_widget.begin_index = static_cast(it); 159 | ekg::theme_t ¤t_global_theme {ekg::p_core->handler_theme.get_current_theme()}; 160 | 161 | int32_t size {static_cast(parent_property.children.size())}; 162 | int32_t latest_index {size - (!parent_property.children.empty())}; 163 | int32_t flag_ok_count {}; 164 | 165 | ekg::flags_t dock {}; 166 | bool is_scrollbar {}; 167 | bool is_last_index {}; 168 | bool is_last_index_but {}; 169 | bool is_ok {}; 170 | bool is_stop {}; 171 | 172 | ekg::rect_t rect {}; 173 | for (; it < size; it++) { 174 | ekg::property_t &property { 175 | ekg::query(parent_property.children.at(it)) 176 | }; 177 | 178 | if (property == ekg::property_t::not_found) { 179 | continue; 180 | } 181 | 182 | is_scrollbar = property.descriptor_at.flags == ekg::type::scrollbar; 183 | is_last_index = it == latest_index; 184 | 185 | ekg_abstract_todo( 186 | property.descriptor_at.flags, 187 | property.descriptor_at, 188 | dock = descriptor.dock; 189 | rect = descriptor.rect; 190 | ); 191 | 192 | is_ok = ekg::has(dock, flag_ok); 193 | is_stop = ekg::has(dock, flag_stop); 194 | 195 | if ( 196 | (is_stop && it != in_out_count) 197 | || 198 | is_last_index 199 | || 200 | is_scrollbar 201 | ) { 202 | 203 | extent -= (current_global_theme.layout_offset) * (extent > 0.0f); 204 | 205 | is_last_index_but = ( 206 | is_ok && is_last_index 207 | ); 208 | 209 | flag_ok_count += ( 210 | !is_stop 211 | && 212 | is_last_index_but 213 | ); 214 | 215 | is_last_index_but = ( 216 | is_last_index 217 | && 218 | !is_ok 219 | && 220 | !is_stop 221 | && 222 | !is_scrollbar 223 | ); 224 | 225 | /** 226 | * Basically if the container/frame mother ends with any non flag ok (ekg::dock::fill) 227 | * it MUST add the width size to extend. 228 | * But the point is the scrollbar, he is not docknized here, then just bypass with `!is_scrollbar`. 229 | * 230 | * :blush: 231 | **/ 232 | extent += ( 233 | rect.w 234 | * 235 | is_last_index_but 236 | ); 237 | 238 | /** 239 | * There are two glitches fixed here. 240 | * 241 | * The first one happens when the widget contains `next | fill` flag but the previous row 242 | * count as one extra index, so the last widget does not fill with 1 but with the previous 243 | * amount of fill count. 244 | * 245 | * The second one happens when the widget contains `next | fill` and `fill`, making the 246 | * previous row do not count as 1, so the widget is complete filled. 247 | * 248 | * To fix this, we consider the two options: 249 | * NOT STOP or OK but NOT STOP. 250 | * 251 | * Both case must fix this, if soon happens, we can already now the context of issue. 252 | **/ 253 | is_last_index_but = ( 254 | is_last_index 255 | && 256 | (!is_stop || (is_ok && !is_stop)) 257 | && 258 | !is_scrollbar 259 | ); 260 | 261 | ekg::layout::extent_t::h_widget.end_index = it + (is_last_index * is_last_index_but); 262 | ekg::layout::extent_t::h_widget.extent = extent; 263 | ekg::layout::extent_t::h_widget.count = flag_ok_count + (flag_ok_count == 0);\ 264 | 265 | is_stop = true; 266 | 267 | break; 268 | } 269 | 270 | if (is_ok) { 271 | flag_ok_count++; 272 | continue; 273 | } 274 | 275 | extent += rect.w + current_global_theme.layout_offset; 276 | } 277 | 278 | in_out_count = flag_ok_count + (flag_ok_count == 0); 279 | break; 280 | } 281 | 282 | case ekg::axis::vertical: { 283 | break; 284 | } 285 | } 286 | } 287 | -------------------------------------------------------------------------------- /src/layout/scalenize.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License 3 | * 4 | * Copyright (c) 2022-2025 Rina Wilk / vokegpu@gmail.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | #include "ekg/core/runtime.hpp" 25 | #include "ekg/core/context.hpp" 26 | #include "ekg/layout/scalenize.hpp" 27 | #include "ekg/math/floating_point.hpp" 28 | 29 | void ekg::layout::scalenize() { 30 | ekg::vec2_t display_size {ekg::dpi.scale.w, ekg::dpi.scale.h}; 31 | ekg::vec2_t viewport {ekg::dpi.viewport.w, ekg::dpi.viewport.h}; 32 | 33 | if (ekg::dpi.auto_scale) { 34 | ekg::p_core->p_platform_base->update_display_size(); 35 | 36 | display_size.x = ekg::p_core->p_platform_base->display_size.w; 37 | display_size.y = ekg::p_core->p_platform_base->display_size.h; 38 | 39 | ekg::dpi.scale.w = 1920.0f; 40 | ekg::dpi.scale.h = 1080.0f; 41 | 42 | viewport = display_size; 43 | } 44 | 45 | /** 46 | * The scale is step-based, each step change the scale, e.g: 47 | * scale percent interval = 25 48 | * scale percent = 100 (scale GUI resolution == window size) 49 | * 50 | * scale percent in: 51 | * 0 == 0 52 | * 25 == 1 53 | * 50 == 2 54 | * 75 == 3 55 | * 100 == 4 56 | * 57 | * Then it is divided by 4 (4 is the maximum value) 58 | * e.g: 2/4 = 0.5f --> 3/4 = 0.75f 59 | **/ 60 | 61 | float base_scale { 62 | ekg::dpi.scale.w * ekg::dpi.scale.h 63 | }; 64 | 65 | float display_scale { 66 | display_size.x * display_size.y 67 | }; 68 | 69 | float display_factor { 70 | display_scale / base_scale 71 | }; 72 | 73 | float display_scale_percent { 74 | display_factor * 100.0f 75 | }; 76 | 77 | float factor { 78 | ( 79 | (viewport.x * viewport.y) 80 | / 81 | base_scale 82 | ) * 100.0f 83 | }; 84 | 85 | factor = ( 86 | roundf(factor / ekg::dpi.scale_interval) 87 | / 88 | (display_scale_percent / ekg::dpi.scale_interval) 89 | ); 90 | 91 | ekg::dpi.factor_scale = ekg::clamp(factor, 0.5f, 2.0f); 92 | } 93 | -------------------------------------------------------------------------------- /src/math/geometry.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License 3 | * 4 | * Copyright (c) 2022-2025 Rina Wilk / vokegpu@gmail.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | #include "ekg/math/geometry.hpp" 25 | 26 | void ekg::ortho( 27 | float *p_mat4x4, 28 | float left, 29 | float right, 30 | float bottom, 31 | float top 32 | ) { 33 | const float depth_near = -1.0f; 34 | const float depth_far = 1.0f; 35 | const float depth_inv = 1.0f / (depth_far - depth_near); 36 | const float y_inv = 1.0f / (top - bottom); 37 | const float x_inv = 1.0f / (right - left); 38 | 39 | p_mat4x4[0] = 2.0f * x_inv; 40 | p_mat4x4[1] = 0.0f; 41 | p_mat4x4[2] = 0.0f; 42 | p_mat4x4[3] = 0.0f; 43 | 44 | p_mat4x4[4] = 0.0f; 45 | p_mat4x4[5] = 2.0f * y_inv; 46 | p_mat4x4[6] = 0.0f; 47 | p_mat4x4[7] = 0.0f; 48 | 49 | p_mat4x4[8] = 0.0f; 50 | p_mat4x4[9] = 0.0f; 51 | p_mat4x4[10] = -2.0f * depth_inv; 52 | p_mat4x4[11] = 0.0f; 53 | 54 | p_mat4x4[12] = -(right + left) * x_inv; 55 | p_mat4x4[13] = -(top + bottom) * y_inv; 56 | p_mat4x4[14] = -(depth_far + depth_near) * depth_inv; 57 | p_mat4x4[15] = 1.0f; 58 | } 59 | -------------------------------------------------------------------------------- /src/ui/abstract.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License 3 | * 4 | * Copyright (c) 2022-2025 Rina Wilk / vokegpu@gmail.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | #include "ekg/ui/abstract.hpp" 25 | #include "ekg/core/pools.hpp" 26 | #include "ekg/core/runtime.hpp" 27 | 28 | ekg::rect_t &ekg::ui::get_abs_rect( 29 | ekg::property_t &property, 30 | ekg::rect_t &descriptor_rect 31 | ) { 32 | ekg::property_t &parent { 33 | ekg::query(property.parent_at) 34 | }; 35 | 36 | return ( 37 | property.widget.rect = ( 38 | descriptor_rect + parent.widget.rect + parent.scroll.position 39 | ) 40 | ); 41 | } 42 | 43 | 44 | void ekg::ui::pre_event( 45 | ekg::property_t &property, 46 | ekg::rect_t &descriptor_rect, 47 | bool is_top_level 48 | ) { 49 | ekg::input_info_t &input {ekg::p_core->handler_input.input}; 50 | if ( 51 | input.was_pressed || input.was_released || 52 | input.has_motion || input.was_wheel 53 | ) { 54 | ekg::rect_t &abs {ekg::ui::get_abs_rect(property, descriptor_rect)}; 55 | ekg::vec2_t interact {static_cast>(input.interact)}; 56 | 57 | property.widget.is_hovering = ( 58 | ekg::rect_collide_vec2(abs, interact) 59 | && 60 | ( 61 | is_top_level 62 | || 63 | property.parent_at == ekg::at_t::not_found 64 | || 65 | ekg::rect_collide_vec2(property.widget.rect_scissor, interact) 66 | ) 67 | ); 68 | } 69 | } 70 | 71 | void ekg::ui::post_event( 72 | ekg::property_t &property 73 | ) { 74 | property.widget.is_hovering = false; 75 | 76 | #if defined(__ANDROID__) 77 | property.widget.is_highlight = ( 78 | !(!property.widget.is_hovering && ekg::p_core->handler_input.input.was_released) 79 | && 80 | property.widget.is_highlight 81 | ); 82 | #endif 83 | } 84 | -------------------------------------------------------------------------------- /src/ui/button/button.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License 3 | * 4 | * Copyright (c) 2022-2025 Rina Wilk / vokegpu@gmail.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | #include "ekg/ui/button/button.hpp" 25 | 26 | ekg::button_t ekg::button_t::not_found { 27 | .at = ekg::at_t::not_found 28 | }; 29 | -------------------------------------------------------------------------------- /src/ui/button/widget.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License 3 | * 4 | * Copyright (c) 2022-2025 Rina Wilk / vokegpu@gmail.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | #include "ekg/ui/button/widget.hpp" 25 | #include "ekg/layout/docknize.hpp" 26 | #include "ekg/io/log.hpp" 27 | #include "ekg/ui/abstract.hpp" 28 | #include "ekg/draw/shape/shape.hpp" 29 | #include "ekg/draw/typography/font.hpp" 30 | #include "ekg/core/context.hpp" 31 | 32 | void ekg::ui::reload( 33 | ekg::property_t &property, 34 | ekg::button_t &button 35 | ) { 36 | ekg_assert_low_level( 37 | property == ekg::property_t::not_found, 38 | ekg::log() << "warn: invalid property on reload", 39 | return 40 | ); 41 | 42 | ekg_assert_low_level( 43 | button == ekg::button_t::not_found, 44 | ekg::log() << "warn: invalid button on reload", 45 | return 46 | ); 47 | 48 | ekg::ui::get_abs_rect( 49 | property, 50 | button.rect 51 | ); 52 | 53 | ekg::axis pick_axis { 54 | ekg::axis::horizontal 55 | }; 56 | 57 | ekg::aligned_t aligned_dimension {}; 58 | for (ekg::button_t::check_t &check : button.checks) { 59 | ekg::draw::font &draw_font { 60 | ekg::draw::get_font_renderer(check.font_size) 61 | }; 62 | 63 | check.widget.rect_text.w = draw_font.get_text_width(check.text.get()); 64 | check.widget.rect_text.h = draw_font.get_text_height(); 65 | 66 | aligned_dimension = {}; 67 | ekg::align_rect_dimension( 68 | pick_axis, 69 | check.widget.rect_text, 70 | ekg::dpi.min_sizes, 71 | aligned_dimension 72 | ); 73 | } 74 | 75 | button.rect.h = aligned_dimension.h * button.rect.scaled_height; 76 | 77 | ekg::layout::mask mask {}; 78 | mask.preset( 79 | { 80 | aligned_dimension.offset, 81 | aligned_dimension.offset, 82 | button.rect.h 83 | }, 84 | pick_axis, 85 | button.rect.w 86 | ); 87 | 88 | for (ekg::button_t::check_t &check : button.checks) { 89 | ekg::draw::font &draw_font { 90 | ekg::draw::get_font_renderer(check.font_size) 91 | }; 92 | 93 | if (check.is_check_box) { 94 | check.widget.rect_box.w = check.widget.rect_text.h; 95 | check.widget.rect_box.h = check.widget.rect_text.h; 96 | 97 | mask.insert( 98 | { 99 | .p_rect = &check.widget.rect_box, 100 | .dock = check.dock 101 | } 102 | ); 103 | } 104 | 105 | mask.insert( 106 | { 107 | .p_rect = &check.widget.rect_text, 108 | .dock = check.dock 109 | } 110 | ); 111 | } 112 | 113 | mask.docknize(); 114 | 115 | if (property.widget.should_refresh_size) { 116 | button.rect.w = ekg::max(ekg::dpi.min_sizes, mask.get_rect().w); 117 | property.widget.should_refresh_size = false; 118 | } 119 | } 120 | 121 | void ekg::ui::event( 122 | ekg::property_t &property, 123 | ekg::button_t &button, 124 | const ekg::io::stage &stage 125 | ) { 126 | 127 | } 128 | 129 | void ekg::ui::high_frequency( 130 | ekg::property_t &property, 131 | ekg::button_t &button 132 | ) { 133 | 134 | } 135 | 136 | void ekg::ui::pass( 137 | ekg::property_t &property, 138 | ekg::button_t &button 139 | ) { 140 | 141 | } 142 | 143 | void ekg::ui::buffering( 144 | ekg::property_t &property, 145 | ekg::button_t &button 146 | ) { 147 | 148 | } 149 | 150 | void ekg::ui::unmap( 151 | ekg::button_t &button 152 | ) { 153 | 154 | } 155 | -------------------------------------------------------------------------------- /src/ui/frame/frame.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License 3 | * 4 | * Copyright (c) 2022-2025 Rina Wilk / vokegpu@gmail.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | #include "ekg/ui/frame/frame.hpp" 25 | 26 | ekg::frame_t ekg::frame_t::not_found {}; 27 | -------------------------------------------------------------------------------- /src/ui/property.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License 3 | * 4 | * Copyright (c) 2022-2025 Rina Wilk / vokegpu@gmail.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | #include "ekg/ui/property.hpp" 25 | 26 | ekg::property_t ekg::property_t::not_found { 27 | .at = ekg::at_t::not_found 28 | }; 29 | 30 | -------------------------------------------------------------------------------- /src/ui/stack.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License 3 | * 4 | * Copyright (c) 2022-2025 Rina Wilk / vokegpu@gmail.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | #include "ekg/ui/stack.hpp" 25 | 26 | ekg::stack_t ekg::stack_t::not_found {}; 27 | -------------------------------------------------------------------------------- /version/autorelease.py: -------------------------------------------------------------------------------- 1 | from typing import List, Dict 2 | import sys, os, zipfile, shutil, shlex, subprocess 3 | 4 | 5 | def create_release_zip_file(zip_filename: str, lib_directory: str) -> str: 6 | zip_output: str = f"./{zip_filename}.zip" 7 | to_zip_directory: str = f"./{zip_filename}/" 8 | 9 | os.system(f"mkdir ./{zip_filename} && cd ./{zip_filename} && mkdir ./lib && cd ..") 10 | 11 | shutil.copytree("./include", f"./{zip_filename}/include/") 12 | shutil.copy("./faq.txt", f"./{zip_filename}/") 13 | shutil.copy("./LICENSE.md", f"./{zip_filename}/") 14 | shutil.copy(f"./lib/{lib_directory}/libekg.a", f"./{zip_filename}/lib/libekg.a") 15 | 16 | print("zipping: ", zip_filename) 17 | 18 | with zipfile.ZipFile(zip_output, "w") as zipf: 19 | for root, dirs, files in os.walk(to_zip_directory): 20 | for file in files: 21 | zipf.write( 22 | os.path.join(root, file), 23 | os.path.relpath(os.path.join(root, file), to_zip_directory), 24 | ) 25 | return zip_output 26 | 27 | 28 | if __name__ == "__main__": 29 | print("initialising the most meow meow of live :3") 30 | print("mumu mumu meow meow") 31 | 32 | metadata: Dict[str, str] = {"-m": "", "-d": ""} 33 | store: str = "" 34 | 35 | for it in range(1, len(sys.argv)): 36 | if sys.argv[it] == "-m": 37 | store = "-m" 38 | elif sys.argv[it] == "-d": 39 | store = "-d" 40 | elif store: 41 | metadata[store] += sys.argv[it] 42 | metadata[store] += " " 43 | 44 | if metadata["-d"].endswith(" "): 45 | metadata["-d"] = metadata["-d"][:-1] 46 | 47 | print("reading metadata:") 48 | print(metadata) 49 | 50 | file = open("./version/commit.txt", "r") 51 | content: List[str] = file.read().split("\n") 52 | file.close() 53 | 54 | news_descriptor: str = "" 55 | version_descriptor: str = "" 56 | 57 | for it, element in reversed(list(enumerate(content))): 58 | if element.startswith("-"): 59 | news_descriptor += element 60 | news_descriptor += "\n" 61 | elif element.find(".") > 0: 62 | version_descriptor = element 63 | break 64 | 65 | release: str = f""" 66 | # EKG {version_descriptor} 67 | 68 | {metadata["-d"]} 69 | 70 | News: 71 | {news_descriptor} 72 | 73 | --- 74 | 75 | For complete previously released logs, check [here](https://github.com/vokegpu/ekg-ui-library/blob/version-core/version/commit.txt). 76 | 77 | """ 78 | 79 | print("making a new release") 80 | print(release) 81 | 82 | # Create tag and release. 83 | # But before pack/zip the faq, license, lib, and the include headers file. 84 | 85 | tag: str = version_descriptor.split(" ")[0] 86 | windows: str = f"ekg-ui-library-{tag}-win32" 87 | linux: str = f"ekg-ui-library-{tag}" 88 | 89 | create_release_zip_file(windows, "windows") 90 | create_release_zip_file(linux, "linux") 91 | 92 | """ 93 | os.system(f'git tag -a "{tag}" -m "{metadata["-d"]}"') 94 | os.system(f"git push origin {tag}") 95 | os.system( 96 | f'gh release create {tag} ./{windows}.zip ./{linux}.zip --latest --title "EKG {version_descriptor}" --notes "{release}"' 97 | ) 98 | """ 99 | 100 | subprocess.run(["git", "tag", "-a", tag, "-m", metadata["-d"]], check=True) 101 | subprocess.run(["git", "push", "origin", tag], check=True) 102 | 103 | escaped_release_notes: str = shlex.quote(release) 104 | 105 | subprocess.run( 106 | [ 107 | "gh", 108 | "release", 109 | "create", 110 | tag, 111 | f"./{windows}.zip", 112 | f"./{linux}.zip", 113 | "--latest", 114 | "--title", 115 | f"EKG {version_descriptor}", 116 | "--notes", 117 | escaped_release_notes, 118 | ], 119 | check=True, 120 | ) 121 | 122 | print("ok done >< mumu! :blush: ") 123 | -------------------------------------------------------------------------------- /version/todo.txt: -------------------------------------------------------------------------------- 1 | /* DPI, UI, and Scale */ 2 | 3 | The current stupid system of EKG for scalling is actually useless; the scaled height factors at each widget, 4 | is not really scaled by the layout, so, I want to use scaled height factor but scale with the DPI/UI scale. 5 | 6 | So 800x600 will be the same as 1920x1080 indifferent of font-size. 7 | How? idk, i will use the mother/parent frame as base/factor and the height font too as base. 8 | So the layout service will get the perfect sized DPI and scale. 9 | Some day I do this. 10 | 11 | /* Slider must be rewrite the part of docking text value! */ 12 | 13 | Slider contains a glitch were you can drag with no maximum limit. 14 | 15 | /* Textbox is not updating newer text! */ 16 | 17 | stupid ticking glitch. 18 | 19 | /* stupid scorlling glitch */ 20 | 21 | rewrite slider 22 | fix listbox issue when scrolling and dragging? 23 | reduce ekg::slider verbose number setting. 24 | 25 | // Add checkbox 26 | 27 | ✔ 28 | 29 | // add `set_width` and `set_height` to all widgets setters dimension methods >< meowg --------------------------------------------------------------------------------