├── rustfmt.toml ├── .gitignore ├── gen.bash ├── package.json ├── imgui-raw ├── build.rs ├── Cargo.toml └── third-party │ ├── LICENSE │ └── imgui │ ├── LICENSE.txt │ ├── imconfig.h │ ├── imstb_rectpack.h │ └── imstb_textedit.h ├── imgui ├── Cargo.toml └── imgui.rs ├── LICENSE ├── data ├── typedefs_dict.json ├── impl_definitions.json └── structs_and_enums.json ├── README.md └── generate.js /rustfmt.toml: -------------------------------------------------------------------------------- 1 | max_width = 120 -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules 2 | target 3 | Cargo.lock -------------------------------------------------------------------------------- /gen.bash: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | node generate.js raw | rustfmt > imgui-raw/imguiraw.rs 3 | node generate.js safe | rustfmt > imgui/auto.rs 4 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "devDependencies": { 4 | "change-case": "^3.0.2", 5 | "commander": "^2.19.0", 6 | "lodash": "^4.17.11", 7 | "nunjucks": "^3.1.6" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /imgui-raw/build.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | cc::Build::new() 3 | .cpp(true) 4 | .file("third-party/cimgui.cpp") 5 | .file("third-party/imgui/imgui.cpp") 6 | .file("third-party/imgui/imgui_demo.cpp") 7 | .file("third-party/imgui/imgui_draw.cpp") 8 | .file("third-party/imgui/imgui_widgets.cpp") 9 | .compile("libcimgui.a") 10 | } 11 | -------------------------------------------------------------------------------- /imgui/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "nsf-imgui" 3 | version = "0.1.3" 4 | authors = ["nsf "] 5 | edition = "2018" 6 | description = "Alternative (personal) imgui rust bindings" 7 | repository = "https://github.com/nsf/imgui-rust" 8 | categories = ["gui", "api-bindings"] 9 | license = "MIT" 10 | keywords = ["imgui"] 11 | 12 | [profile.release] 13 | lto = true 14 | codegen-units = 1 15 | 16 | [profile.dev] 17 | opt-level = 2 18 | 19 | [lib] 20 | path = "imgui.rs" 21 | 22 | [dependencies] 23 | nsf-imgui-raw = { path = "../imgui-raw", version = "0.1.0" } 24 | lazy_static = "1.2.0" 25 | -------------------------------------------------------------------------------- /imgui-raw/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "nsf-imgui-raw" 3 | version = "0.1.0" 4 | authors = ["nsf "] 5 | edition = "2018" 6 | description = "Alternative (personal) imgui rust bindings, unsafe ffi part" 7 | repository = "https://github.com/nsf/imgui-rust" 8 | categories = ["gui", "external-ffi-bindings"] 9 | license = "MIT" 10 | maintenance = { status = "experimental" } 11 | keywords = ["imgui"] 12 | 13 | [profile.release] 14 | lto = true 15 | codegen-units = 1 16 | 17 | [profile.dev] 18 | opt-level = 2 19 | 20 | [lib] 21 | path = "imguiraw.rs" 22 | 23 | [dependencies] 24 | bitflags = "1.0.4" 25 | libc = "0.2.45" 26 | 27 | [build-dependencies] 28 | cc = "1.0" -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2019 nsf 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. 20 | -------------------------------------------------------------------------------- /imgui-raw/third-party/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Stephan Dilly 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 | -------------------------------------------------------------------------------- /imgui-raw/third-party/imgui/LICENSE.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014-2018 Omar Cornut 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 | -------------------------------------------------------------------------------- /data/typedefs_dict.json: -------------------------------------------------------------------------------- 1 | { 2 | "CustomRect": "struct CustomRect", 3 | "GlyphRangesBuilder": "struct GlyphRangesBuilder", 4 | "ImColor": "struct ImColor", 5 | "ImDrawCallback": "void(*)(const ImDrawList* parent_list,const ImDrawCmd* cmd);", 6 | "ImDrawChannel": "struct ImDrawChannel", 7 | "ImDrawCmd": "struct ImDrawCmd", 8 | "ImDrawCornerFlags": "int", 9 | "ImDrawData": "struct ImDrawData", 10 | "ImDrawIdx": "unsigned short", 11 | "ImDrawList": "struct ImDrawList", 12 | "ImDrawListFlags": "int", 13 | "ImDrawListSharedData": "struct ImDrawListSharedData", 14 | "ImDrawVert": "struct ImDrawVert", 15 | "ImFont": "struct ImFont", 16 | "ImFontAtlas": "struct ImFontAtlas", 17 | "ImFontAtlasFlags": "int", 18 | "ImFontConfig": "struct ImFontConfig", 19 | "ImFontGlyph": "struct ImFontGlyph", 20 | "ImGuiBackendFlags": "int", 21 | "ImGuiCol": "int", 22 | "ImGuiColorEditFlags": "int", 23 | "ImGuiColumnsFlags": "int", 24 | "ImGuiComboFlags": "int", 25 | "ImGuiCond": "int", 26 | "ImGuiConfigFlags": "int", 27 | "ImGuiContext": "struct ImGuiContext", 28 | "ImGuiDataType": "int", 29 | "ImGuiDir": "int", 30 | "ImGuiDragDropFlags": "int", 31 | "ImGuiFocusedFlags": "int", 32 | "ImGuiHoveredFlags": "int", 33 | "ImGuiID": "unsigned int", 34 | "ImGuiIO": "struct ImGuiIO", 35 | "ImGuiInputTextCallback": "int(*)(ImGuiInputTextCallbackData *data);", 36 | "ImGuiInputTextCallbackData": "struct ImGuiInputTextCallbackData", 37 | "ImGuiInputTextFlags": "int", 38 | "ImGuiKey": "int", 39 | "ImGuiListClipper": "struct ImGuiListClipper", 40 | "ImGuiMouseCursor": "int", 41 | "ImGuiNavInput": "int", 42 | "ImGuiOnceUponAFrame": "struct ImGuiOnceUponAFrame", 43 | "ImGuiPayload": "struct ImGuiPayload", 44 | "ImGuiSelectableFlags": "int", 45 | "ImGuiSizeCallback": "void(*)(ImGuiSizeCallbackData* data);", 46 | "ImGuiSizeCallbackData": "struct ImGuiSizeCallbackData", 47 | "ImGuiStorage": "struct ImGuiStorage", 48 | "ImGuiStyle": "struct ImGuiStyle", 49 | "ImGuiStyleVar": "int", 50 | "ImGuiTextBuffer": "struct ImGuiTextBuffer", 51 | "ImGuiTextFilter": "struct ImGuiTextFilter", 52 | "ImGuiTreeNodeFlags": "int", 53 | "ImGuiWindowFlags": "int", 54 | "ImS32": "signed int", 55 | "ImS64": "int64_t", 56 | "ImTextureID": "void*", 57 | "ImU32": "unsigned int", 58 | "ImU64": "uint64_t", 59 | "ImVec2": "struct ImVec2", 60 | "ImVec4": "struct ImVec4", 61 | "ImWchar": "unsigned short", 62 | "Pair": "struct Pair", 63 | "TextRange": "struct TextRange", 64 | "const_iterator": "const value_type*", 65 | "iterator": "value_type*", 66 | "value_type": "T" 67 | } -------------------------------------------------------------------------------- /imgui/imgui.rs: -------------------------------------------------------------------------------- 1 | mod auto; 2 | 3 | pub use crate::auto::types_used::*; 4 | pub use crate::auto::*; 5 | use lazy_static::lazy_static; 6 | use nsf_imgui_raw::*; 7 | use std::ffi::CStr; 8 | use std::os::raw::{c_char, c_int, c_void}; 9 | use std::rc::Rc; 10 | use std::sync::Mutex; 11 | 12 | lazy_static! { 13 | static ref IMGUI_INSTANCE_ALIVE: Mutex = Mutex::new(false); 14 | } 15 | 16 | pub struct ImGuiOwner; 17 | 18 | impl Drop for ImGuiOwner { 19 | fn drop(&mut self) { 20 | let mut is_alive = IMGUI_INSTANCE_ALIVE.lock().unwrap(); 21 | unsafe { 22 | igDestroyContext(igGetCurrentContext()); 23 | } 24 | *is_alive = false; 25 | } 26 | } 27 | 28 | #[derive(Clone)] 29 | pub struct ImGui { 30 | imgui_owner: Rc, 31 | } 32 | 33 | impl ImGui { 34 | pub fn new() -> Result { 35 | let mut is_alive = IMGUI_INSTANCE_ALIVE.lock().unwrap(); 36 | if *is_alive { 37 | Err("Cannot initialize `ImGui` more than once at a time.".to_owned()) 38 | } else { 39 | unsafe { igCreateContext(std::ptr::null_mut()) }; 40 | *is_alive = true; 41 | Ok(ImGui { 42 | imgui_owner: Rc::new(ImGuiOwner), 43 | }) 44 | } 45 | } 46 | 47 | extern "C" fn input_text_callback(data: *mut ImGuiInputTextCallbackData) -> c_int { 48 | unsafe { 49 | let s = (*data).user_data as *mut String; 50 | if (*data).event_flag == ImGuiInputTextFlags::CallbackResize { 51 | while (*s).len() < (*data).buf_size as usize { 52 | (*s).push('\0'); 53 | } 54 | if (*s).len() > (*data).buf_size as usize { 55 | (*s).truncate((*data).buf_size as usize); 56 | } 57 | (*data).buf = (*s).as_ptr() as *mut c_char; 58 | } 59 | } 60 | 0 61 | } 62 | 63 | #[inline] 64 | pub fn input_text(&self, label: &CStr, s: &mut String, extra_flags: impl Into>) { 65 | s.push('\0'); 66 | unsafe { 67 | igInputText( 68 | label.as_ptr(), 69 | s.as_ptr() as *mut c_char, 70 | s.len(), 71 | match extra_flags.into() { 72 | Some(v) => v | ImGuiInputTextFlags::CallbackResize, 73 | None => ImGuiInputTextFlags::CallbackResize, 74 | }, 75 | Some(Self::input_text_callback), 76 | s as *mut String as *mut c_void, 77 | ); 78 | } 79 | s.pop(); 80 | } 81 | } 82 | 83 | #[macro_export] 84 | macro_rules! cstr_ptr { 85 | ($s:expr) => { 86 | concat!($s, "\0") as *const str as *const [::std::os::raw::c_char] as *const ::std::os::raw::c_char 87 | }; 88 | } 89 | 90 | #[macro_export] 91 | macro_rules! cstr { 92 | ($s:expr) => ( 93 | unsafe { ::std::ffi::CStr::from_ptr(cstr_ptr!($s)) } 94 | ); 95 | ($s:expr, $($arg:expr),*) => ( 96 | unsafe { ::std::ffi::CStr::from_bytes_with_nul_unchecked(&format!(concat!($s, "\0"), $($arg),*).into_bytes()) } 97 | ); 98 | } 99 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # nsf-imgui 2 | 3 | Rust bindings for Dear ImGui 1.66b. Experimental personal project, created due to the following reasons: 4 | 5 | 1. Wanted to learn rust. 6 | 1. Mildly interested in game development. 7 | 1. Wasn't entirely happy with existing bindings. 8 | 9 | ## Goals 10 | 11 | 1. Generate most of FFI bindings automatically (helps with maintenance) using cimgui data files. 12 | 1. Generate most of native wrappers automatically as well. 13 | 1. Native wrappers should not be focused too much on safety, instead provide some level of convenience when it comes to types (refs to pointers, string management, etc.). 14 | 1. Closely follow original C++ API, hence avoid being paranoid about safety. E.g. as long as original lib allows you to break things with mismatched begin()/end() calls, allow that as well. 15 | 16 | ## Implementation details 17 | 18 | 1. A lot of code is generated using `generate.js` script. Generation is triggered manually, the repository includes generated files. To run this script you will need to install npm packages via `npm install`. In addition to `generate.js` script, see `gen.bash` script to understand how files are being generated. 19 | 1. Unsafe part uses "bitflags" crate to implement enums which act as bit flags. 20 | 1. Safe part is currently very limited. Only functions that are considered safe are being wrapped. E.g. ones which don't contain function pointers or `void*` or things like that. 21 | 1. `const char*` arguments become `&CStr`, there is also custom `cstr!` macro to help building those at compile-time. `const char*` return values are converted into `String`. Other types are propagated as-is, `*mut` becomes `&mut`, `*const` becomes `&`. 22 | 1. "Format" portion of the function arguments that normally consists of a format string and arguments is converted to a single string argument. Which is then passed in as `"%s"`. 23 | 1. Custom `cstr!` macro supports formatting, e.g. `cstr!("{}", myint)`. This variant uses `format!` macro underneath, which allocates a String. 24 | 1. All imgui functions are methods of `ImGui` struct. You can create one with `ImGui::new()`. Only one instance of this struct is allowed (protected via static mutex). Although the struct is Clone, Rc inside. `ImGui::new()` function will call `igCreateContext()`. When last `ImGui` instance is dropped, it will call `igDestroyContext(igGetCurrentContext())`. 25 | 1. Original library uses C types, such as int, unsigned int, float, double, size_t. I assume those are i32, u32, f32, f64, usize and so on. Basically implying they have fixed sizes. While it's not true in theory, in many cases it's true in practice. It will work for typical 64 bit desktop setups, it might not work for some esoteric embedded scenarios in case if you want to use imgui there. 26 | 1. Original library is written in C++, which allows specifying default values for trailing function arguments. It's implemented using generic `impl Into>` types. Sadly, references within those types require explicit lifetimes for some reason, hence I have to generate explicit lifetimes for all ref types in a function signature. 27 | 28 | ## Q & A 29 | 30 | Q: Where are the examples? 31 | 32 | A: There are none. The goal for this lib is to stay as close as possible to C++ API, you can refer to original C++ examples. There are no safe wrappers around structs yet, hence if you want to integrate this lib into your renderer, you'll just fetch ImDrawData using FFI API and do it in a fully "unsafe" manner, just like you would do it in C++. 33 | 34 | Q: Do you plan to maintain this library? 35 | 36 | A: It depends. Currently I'm using it in my personal hobby gamedevy project. As long as I keep working on it, this library probably will be maintained to some degree. Then - who knows. Don't expect it to be well maintained. 37 | 38 | ## Changelog 39 | 40 | ### nsf-imgui 41 | 42 | * **0.1.3** 43 | - Implement `input_text` using `String`. 44 | - Fix `cstr!` macro again, now for sure. 45 | - Fix snake case conversion on `color_convert_hsv_to_rgb` and `color_convert_rgb_to_hsv` functions. 46 | - Blacklist `igTextUnformatted`. 47 | * **0.1.2** Implement default function values using `impl Into>` generic parameters. 48 | * **0.1.1** Fix `cstr!` macro variant with arguments. 49 | * **0.1.0** Initial release. 50 | 51 | ### nsf-imgui-raw 52 | 53 | * **0.1.0** Initial release. -------------------------------------------------------------------------------- /imgui-raw/third-party/imgui/imconfig.h: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------------------------------- 2 | // COMPILE-TIME OPTIONS FOR DEAR IMGUI 3 | // Runtime options (clipboard callbacks, enabling various features, etc.) can generally be set via the ImGuiIO structure. 4 | // You can use ImGui::SetAllocatorFunctions() before calling ImGui::CreateContext() to rewire memory allocation functions. 5 | //----------------------------------------------------------------------------- 6 | // A) You may edit imconfig.h (and not overwrite it when updating imgui, or maintain a patch/branch with your modifications to imconfig.h) 7 | // B) or add configuration directives in your own file and compile with #define IMGUI_USER_CONFIG "myfilename.h" 8 | // If you do so you need to make sure that configuration settings are defined consistently _everywhere_ dear imgui is used, which include 9 | // the imgui*.cpp files but also _any_ of your code that uses imgui. This is because some compile-time options have an affect on data structures. 10 | // Defining those options in imconfig.h will ensure every compilation unit gets to see the same data structure layouts. 11 | // Call IMGUI_CHECKVERSION() from your .cpp files to verify that the data structures your files are using are matching the ones imgui.cpp is using. 12 | //----------------------------------------------------------------------------- 13 | 14 | #pragma once 15 | 16 | //---- Define assertion handler. Defaults to calling assert(). 17 | //#define IM_ASSERT(_EXPR) MyAssert(_EXPR) 18 | //#define IM_ASSERT(_EXPR) ((void)(_EXPR)) // Disable asserts 19 | 20 | //---- Define attributes of all API symbols declarations, e.g. for DLL under Windows. 21 | //#define IMGUI_API __declspec( dllexport ) 22 | //#define IMGUI_API __declspec( dllimport ) 23 | 24 | //---- Don't define obsolete functions/enums names. Consider enabling from time to time after updating to avoid using soon-to-be obsolete function/names. 25 | //#define IMGUI_DISABLE_OBSOLETE_FUNCTIONS 26 | 27 | //---- Don't implement demo windows functionality (ShowDemoWindow()/ShowStyleEditor()/ShowUserGuide() methods will be empty) 28 | //---- It is very strongly recommended to NOT disable the demo windows during development. Please read the comments in imgui_demo.cpp. 29 | //#define IMGUI_DISABLE_DEMO_WINDOWS 30 | 31 | //---- Don't implement some functions to reduce linkage requirements. 32 | //#define IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCTIONS // [Win32] Don't implement default clipboard handler. Won't use and link with OpenClipboard/GetClipboardData/CloseClipboard etc. 33 | //#define IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS // [Win32] Don't implement default IME handler. Won't use and link with ImmGetContext/ImmSetCompositionWindow. 34 | //#define IMGUI_DISABLE_WIN32_FUNCTIONS // [Win32] Won't use and link with any Win32 function. 35 | //#define IMGUI_DISABLE_FORMAT_STRING_FUNCTIONS // Don't implement ImFormatString/ImFormatStringV so you can implement them yourself if you don't want to link with vsnprintf. 36 | //#define IMGUI_DISABLE_MATH_FUNCTIONS // Don't implement ImFabs/ImSqrt/ImPow/ImFmod/ImCos/ImSin/ImAcos/ImAtan2 wrapper so you can implement them yourself. Declare your prototypes in imconfig.h. 37 | //#define IMGUI_DISABLE_DEFAULT_ALLOCATORS // Don't implement default allocators calling malloc()/free() to avoid linking with them. You will need to call ImGui::SetAllocatorFunctions(). 38 | 39 | //---- Include imgui_user.h at the end of imgui.h as a convenience 40 | //#define IMGUI_INCLUDE_IMGUI_USER_H 41 | 42 | //---- Pack colors to BGRA8 instead of RGBA8 (to avoid converting from one to another) 43 | //#define IMGUI_USE_BGRA_PACKED_COLOR 44 | 45 | //---- Avoid multiple STB libraries implementations, or redefine path/filenames to prioritize another version 46 | // By default the embedded implementations are declared static and not available outside of imgui cpp files. 47 | //#define IMGUI_STB_TRUETYPE_FILENAME "my_folder/stb_truetype.h" 48 | //#define IMGUI_STB_RECT_PACK_FILENAME "my_folder/stb_rect_pack.h" 49 | //#define IMGUI_DISABLE_STB_TRUETYPE_IMPLEMENTATION 50 | //#define IMGUI_DISABLE_STB_RECT_PACK_IMPLEMENTATION 51 | 52 | //---- Define constructor and implicit cast operators to convert back<>forth between your math types and ImVec2/ImVec4. 53 | // This will be inlined as part of ImVec2 and ImVec4 class declarations. 54 | /* 55 | #define IM_VEC2_CLASS_EXTRA \ 56 | ImVec2(const MyVec2& f) { x = f.x; y = f.y; } \ 57 | operator MyVec2() const { return MyVec2(x,y); } 58 | 59 | #define IM_VEC4_CLASS_EXTRA \ 60 | ImVec4(const MyVec4& f) { x = f.x; y = f.y; z = f.z; w = f.w; } \ 61 | operator MyVec4() const { return MyVec4(x,y,z,w); } 62 | */ 63 | 64 | //---- Use 32-bit vertex indices (default is 16-bit) to allow meshes with more than 64K vertices. Render function needs to support it. 65 | //#define ImDrawIdx unsigned int 66 | 67 | //---- Tip: You can add extra functions within the ImGui:: namespace, here or in your own headers files. 68 | /* 69 | namespace ImGui 70 | { 71 | void MyFunction(const char* name, const MyMatrix44& v); 72 | } 73 | */ 74 | -------------------------------------------------------------------------------- /data/impl_definitions.json: -------------------------------------------------------------------------------- 1 | { 2 | "ImGui_ImplGlfw_CharCallback": [ 3 | { 4 | "args": "(GLFWwindow* window,unsigned int c)", 5 | "argsT": [ 6 | { 7 | "name": "window", 8 | "type": "GLFWwindow*" 9 | }, 10 | { 11 | "name": "c", 12 | "type": "unsigned int" 13 | } 14 | ], 15 | "argsoriginal": "(GLFWwindow* window,unsigned int c)", 16 | "call_args": "(window,c)", 17 | "cimguiname": "ImGui_ImplGlfw_CharCallback", 18 | "comment": "", 19 | "defaults": [], 20 | "funcname": "ImGui_ImplGlfw_CharCallback", 21 | "location": "imgui_impl_glfw", 22 | "ret": "void", 23 | "signature": "(GLFWwindow*,unsigned int)", 24 | "stname": "" 25 | } 26 | ], 27 | "ImGui_ImplGlfw_InitForOpenGL": [ 28 | { 29 | "args": "(GLFWwindow* window,bool install_callbacks)", 30 | "argsT": [ 31 | { 32 | "name": "window", 33 | "type": "GLFWwindow*" 34 | }, 35 | { 36 | "name": "install_callbacks", 37 | "type": "bool" 38 | } 39 | ], 40 | "argsoriginal": "(GLFWwindow* window,bool install_callbacks)", 41 | "call_args": "(window,install_callbacks)", 42 | "cimguiname": "ImGui_ImplGlfw_InitForOpenGL", 43 | "comment": "", 44 | "defaults": [], 45 | "funcname": "ImGui_ImplGlfw_InitForOpenGL", 46 | "location": "imgui_impl_glfw", 47 | "ret": "bool", 48 | "signature": "(GLFWwindow*,bool)", 49 | "stname": "" 50 | } 51 | ], 52 | "ImGui_ImplGlfw_InitForVulkan": [ 53 | { 54 | "args": "(GLFWwindow* window,bool install_callbacks)", 55 | "argsT": [ 56 | { 57 | "name": "window", 58 | "type": "GLFWwindow*" 59 | }, 60 | { 61 | "name": "install_callbacks", 62 | "type": "bool" 63 | } 64 | ], 65 | "argsoriginal": "(GLFWwindow* window,bool install_callbacks)", 66 | "call_args": "(window,install_callbacks)", 67 | "cimguiname": "ImGui_ImplGlfw_InitForVulkan", 68 | "comment": "", 69 | "defaults": [], 70 | "funcname": "ImGui_ImplGlfw_InitForVulkan", 71 | "location": "imgui_impl_glfw", 72 | "ret": "bool", 73 | "signature": "(GLFWwindow*,bool)", 74 | "stname": "" 75 | } 76 | ], 77 | "ImGui_ImplGlfw_KeyCallback": [ 78 | { 79 | "args": "(GLFWwindow* window,int key,int scancode,int action,int mods)", 80 | "argsT": [ 81 | { 82 | "name": "window", 83 | "type": "GLFWwindow*" 84 | }, 85 | { 86 | "name": "key", 87 | "type": "int" 88 | }, 89 | { 90 | "name": "scancode", 91 | "type": "int" 92 | }, 93 | { 94 | "name": "action", 95 | "type": "int" 96 | }, 97 | { 98 | "name": "mods", 99 | "type": "int" 100 | } 101 | ], 102 | "argsoriginal": "(GLFWwindow* window,int key,int scancode,int action,int mods)", 103 | "call_args": "(window,key,scancode,action,mods)", 104 | "cimguiname": "ImGui_ImplGlfw_KeyCallback", 105 | "comment": "", 106 | "defaults": [], 107 | "funcname": "ImGui_ImplGlfw_KeyCallback", 108 | "location": "imgui_impl_glfw", 109 | "ret": "void", 110 | "signature": "(GLFWwindow*,int,int,int,int)", 111 | "stname": "" 112 | } 113 | ], 114 | "ImGui_ImplGlfw_MouseButtonCallback": [ 115 | { 116 | "args": "(GLFWwindow* window,int button,int action,int mods)", 117 | "argsT": [ 118 | { 119 | "name": "window", 120 | "type": "GLFWwindow*" 121 | }, 122 | { 123 | "name": "button", 124 | "type": "int" 125 | }, 126 | { 127 | "name": "action", 128 | "type": "int" 129 | }, 130 | { 131 | "name": "mods", 132 | "type": "int" 133 | } 134 | ], 135 | "argsoriginal": "(GLFWwindow* window,int button,int action,int mods)", 136 | "call_args": "(window,button,action,mods)", 137 | "cimguiname": "ImGui_ImplGlfw_MouseButtonCallback", 138 | "comment": "", 139 | "defaults": [], 140 | "funcname": "ImGui_ImplGlfw_MouseButtonCallback", 141 | "location": "imgui_impl_glfw", 142 | "ret": "void", 143 | "signature": "(GLFWwindow*,int,int,int)", 144 | "stname": "" 145 | } 146 | ], 147 | "ImGui_ImplGlfw_NewFrame": [ 148 | { 149 | "args": "()", 150 | "argsT": [], 151 | "argsoriginal": "()", 152 | "call_args": "()", 153 | "cimguiname": "ImGui_ImplGlfw_NewFrame", 154 | "comment": "", 155 | "defaults": [], 156 | "funcname": "ImGui_ImplGlfw_NewFrame", 157 | "location": "imgui_impl_glfw", 158 | "ret": "void", 159 | "signature": "()", 160 | "stname": "" 161 | } 162 | ], 163 | "ImGui_ImplGlfw_ScrollCallback": [ 164 | { 165 | "args": "(GLFWwindow* window,double xoffset,double yoffset)", 166 | "argsT": [ 167 | { 168 | "name": "window", 169 | "type": "GLFWwindow*" 170 | }, 171 | { 172 | "name": "xoffset", 173 | "type": "double" 174 | }, 175 | { 176 | "name": "yoffset", 177 | "type": "double" 178 | } 179 | ], 180 | "argsoriginal": "(GLFWwindow* window,double xoffset,double yoffset)", 181 | "call_args": "(window,xoffset,yoffset)", 182 | "cimguiname": "ImGui_ImplGlfw_ScrollCallback", 183 | "comment": "", 184 | "defaults": [], 185 | "funcname": "ImGui_ImplGlfw_ScrollCallback", 186 | "location": "imgui_impl_glfw", 187 | "ret": "void", 188 | "signature": "(GLFWwindow*,double,double)", 189 | "stname": "" 190 | } 191 | ], 192 | "ImGui_ImplGlfw_Shutdown": [ 193 | { 194 | "args": "()", 195 | "argsT": [], 196 | "argsoriginal": "()", 197 | "call_args": "()", 198 | "cimguiname": "ImGui_ImplGlfw_Shutdown", 199 | "comment": "", 200 | "defaults": [], 201 | "funcname": "ImGui_ImplGlfw_Shutdown", 202 | "location": "imgui_impl_glfw", 203 | "ret": "void", 204 | "signature": "()", 205 | "stname": "" 206 | } 207 | ], 208 | "ImGui_ImplOpenGL2_CreateDeviceObjects": [ 209 | { 210 | "args": "()", 211 | "argsT": [], 212 | "argsoriginal": "()", 213 | "call_args": "()", 214 | "cimguiname": "ImGui_ImplOpenGL2_CreateDeviceObjects", 215 | "comment": "", 216 | "defaults": [], 217 | "funcname": "ImGui_ImplOpenGL2_CreateDeviceObjects", 218 | "location": "imgui_impl_opengl2", 219 | "ret": "bool", 220 | "signature": "()", 221 | "stname": "" 222 | } 223 | ], 224 | "ImGui_ImplOpenGL2_CreateFontsTexture": [ 225 | { 226 | "args": "()", 227 | "argsT": [], 228 | "argsoriginal": "()", 229 | "call_args": "()", 230 | "cimguiname": "ImGui_ImplOpenGL2_CreateFontsTexture", 231 | "comment": "", 232 | "defaults": [], 233 | "funcname": "ImGui_ImplOpenGL2_CreateFontsTexture", 234 | "location": "imgui_impl_opengl2", 235 | "ret": "bool", 236 | "signature": "()", 237 | "stname": "" 238 | } 239 | ], 240 | "ImGui_ImplOpenGL2_DestroyDeviceObjects": [ 241 | { 242 | "args": "()", 243 | "argsT": [], 244 | "argsoriginal": "()", 245 | "call_args": "()", 246 | "cimguiname": "ImGui_ImplOpenGL2_DestroyDeviceObjects", 247 | "comment": "", 248 | "defaults": [], 249 | "funcname": "ImGui_ImplOpenGL2_DestroyDeviceObjects", 250 | "location": "imgui_impl_opengl2", 251 | "ret": "void", 252 | "signature": "()", 253 | "stname": "" 254 | } 255 | ], 256 | "ImGui_ImplOpenGL2_DestroyFontsTexture": [ 257 | { 258 | "args": "()", 259 | "argsT": [], 260 | "argsoriginal": "()", 261 | "call_args": "()", 262 | "cimguiname": "ImGui_ImplOpenGL2_DestroyFontsTexture", 263 | "comment": "", 264 | "defaults": [], 265 | "funcname": "ImGui_ImplOpenGL2_DestroyFontsTexture", 266 | "location": "imgui_impl_opengl2", 267 | "ret": "void", 268 | "signature": "()", 269 | "stname": "" 270 | } 271 | ], 272 | "ImGui_ImplOpenGL2_Init": [ 273 | { 274 | "args": "()", 275 | "argsT": [], 276 | "argsoriginal": "()", 277 | "call_args": "()", 278 | "cimguiname": "ImGui_ImplOpenGL2_Init", 279 | "comment": "", 280 | "defaults": [], 281 | "funcname": "ImGui_ImplOpenGL2_Init", 282 | "location": "imgui_impl_opengl2", 283 | "ret": "bool", 284 | "signature": "()", 285 | "stname": "" 286 | } 287 | ], 288 | "ImGui_ImplOpenGL2_NewFrame": [ 289 | { 290 | "args": "()", 291 | "argsT": [], 292 | "argsoriginal": "()", 293 | "call_args": "()", 294 | "cimguiname": "ImGui_ImplOpenGL2_NewFrame", 295 | "comment": "", 296 | "defaults": [], 297 | "funcname": "ImGui_ImplOpenGL2_NewFrame", 298 | "location": "imgui_impl_opengl2", 299 | "ret": "void", 300 | "signature": "()", 301 | "stname": "" 302 | } 303 | ], 304 | "ImGui_ImplOpenGL2_RenderDrawData": [ 305 | { 306 | "args": "(ImDrawData* draw_data)", 307 | "argsT": [ 308 | { 309 | "name": "draw_data", 310 | "type": "ImDrawData*" 311 | } 312 | ], 313 | "argsoriginal": "(ImDrawData* draw_data)", 314 | "call_args": "(draw_data)", 315 | "cimguiname": "ImGui_ImplOpenGL2_RenderDrawData", 316 | "comment": "", 317 | "defaults": [], 318 | "funcname": "ImGui_ImplOpenGL2_RenderDrawData", 319 | "location": "imgui_impl_opengl2", 320 | "ret": "void", 321 | "signature": "(ImDrawData*)", 322 | "stname": "" 323 | } 324 | ], 325 | "ImGui_ImplOpenGL2_Shutdown": [ 326 | { 327 | "args": "()", 328 | "argsT": [], 329 | "argsoriginal": "()", 330 | "call_args": "()", 331 | "cimguiname": "ImGui_ImplOpenGL2_Shutdown", 332 | "comment": "", 333 | "defaults": [], 334 | "funcname": "ImGui_ImplOpenGL2_Shutdown", 335 | "location": "imgui_impl_opengl2", 336 | "ret": "void", 337 | "signature": "()", 338 | "stname": "" 339 | } 340 | ], 341 | "ImGui_ImplOpenGL3_CreateDeviceObjects": [ 342 | { 343 | "args": "()", 344 | "argsT": [], 345 | "argsoriginal": "()", 346 | "call_args": "()", 347 | "cimguiname": "ImGui_ImplOpenGL3_CreateDeviceObjects", 348 | "comment": "", 349 | "defaults": [], 350 | "funcname": "ImGui_ImplOpenGL3_CreateDeviceObjects", 351 | "location": "imgui_impl_opengl3", 352 | "ret": "bool", 353 | "signature": "()", 354 | "stname": "" 355 | } 356 | ], 357 | "ImGui_ImplOpenGL3_CreateFontsTexture": [ 358 | { 359 | "args": "()", 360 | "argsT": [], 361 | "argsoriginal": "()", 362 | "call_args": "()", 363 | "cimguiname": "ImGui_ImplOpenGL3_CreateFontsTexture", 364 | "comment": "", 365 | "defaults": [], 366 | "funcname": "ImGui_ImplOpenGL3_CreateFontsTexture", 367 | "location": "imgui_impl_opengl3", 368 | "ret": "bool", 369 | "signature": "()", 370 | "stname": "" 371 | } 372 | ], 373 | "ImGui_ImplOpenGL3_DestroyDeviceObjects": [ 374 | { 375 | "args": "()", 376 | "argsT": [], 377 | "argsoriginal": "()", 378 | "call_args": "()", 379 | "cimguiname": "ImGui_ImplOpenGL3_DestroyDeviceObjects", 380 | "comment": "", 381 | "defaults": [], 382 | "funcname": "ImGui_ImplOpenGL3_DestroyDeviceObjects", 383 | "location": "imgui_impl_opengl3", 384 | "ret": "void", 385 | "signature": "()", 386 | "stname": "" 387 | } 388 | ], 389 | "ImGui_ImplOpenGL3_DestroyFontsTexture": [ 390 | { 391 | "args": "()", 392 | "argsT": [], 393 | "argsoriginal": "()", 394 | "call_args": "()", 395 | "cimguiname": "ImGui_ImplOpenGL3_DestroyFontsTexture", 396 | "comment": "", 397 | "defaults": [], 398 | "funcname": "ImGui_ImplOpenGL3_DestroyFontsTexture", 399 | "location": "imgui_impl_opengl3", 400 | "ret": "void", 401 | "signature": "()", 402 | "stname": "" 403 | } 404 | ], 405 | "ImGui_ImplOpenGL3_Init": [ 406 | { 407 | "args": "(const char* glsl_version)", 408 | "argsT": [ 409 | { 410 | "name": "glsl_version", 411 | "type": "const char*" 412 | } 413 | ], 414 | "argsoriginal": "(const char* glsl_version=NULL)", 415 | "call_args": "(glsl_version)", 416 | "cimguiname": "ImGui_ImplOpenGL3_Init", 417 | "comment": "", 418 | "defaults": { 419 | "glsl_version": "NULL" 420 | }, 421 | "funcname": "ImGui_ImplOpenGL3_Init", 422 | "location": "imgui_impl_opengl3", 423 | "ret": "bool", 424 | "signature": "(const char*)", 425 | "stname": "" 426 | } 427 | ], 428 | "ImGui_ImplOpenGL3_NewFrame": [ 429 | { 430 | "args": "()", 431 | "argsT": [], 432 | "argsoriginal": "()", 433 | "call_args": "()", 434 | "cimguiname": "ImGui_ImplOpenGL3_NewFrame", 435 | "comment": "", 436 | "defaults": [], 437 | "funcname": "ImGui_ImplOpenGL3_NewFrame", 438 | "location": "imgui_impl_opengl3", 439 | "ret": "void", 440 | "signature": "()", 441 | "stname": "" 442 | } 443 | ], 444 | "ImGui_ImplOpenGL3_RenderDrawData": [ 445 | { 446 | "args": "(ImDrawData* draw_data)", 447 | "argsT": [ 448 | { 449 | "name": "draw_data", 450 | "type": "ImDrawData*" 451 | } 452 | ], 453 | "argsoriginal": "(ImDrawData* draw_data)", 454 | "call_args": "(draw_data)", 455 | "cimguiname": "ImGui_ImplOpenGL3_RenderDrawData", 456 | "comment": "", 457 | "defaults": [], 458 | "funcname": "ImGui_ImplOpenGL3_RenderDrawData", 459 | "location": "imgui_impl_opengl3", 460 | "ret": "void", 461 | "signature": "(ImDrawData*)", 462 | "stname": "" 463 | } 464 | ], 465 | "ImGui_ImplOpenGL3_Shutdown": [ 466 | { 467 | "args": "()", 468 | "argsT": [], 469 | "argsoriginal": "()", 470 | "call_args": "()", 471 | "cimguiname": "ImGui_ImplOpenGL3_Shutdown", 472 | "comment": "", 473 | "defaults": [], 474 | "funcname": "ImGui_ImplOpenGL3_Shutdown", 475 | "location": "imgui_impl_opengl3", 476 | "ret": "void", 477 | "signature": "()", 478 | "stname": "" 479 | } 480 | ], 481 | "ImGui_ImplSDL2_InitForOpenGL": [ 482 | { 483 | "args": "(SDL_Window* window,void* sdl_gl_context)", 484 | "argsT": [ 485 | { 486 | "name": "window", 487 | "type": "SDL_Window*" 488 | }, 489 | { 490 | "name": "sdl_gl_context", 491 | "type": "void*" 492 | } 493 | ], 494 | "argsoriginal": "(SDL_Window* window,void* sdl_gl_context)", 495 | "call_args": "(window,sdl_gl_context)", 496 | "cimguiname": "ImGui_ImplSDL2_InitForOpenGL", 497 | "comment": "", 498 | "defaults": [], 499 | "funcname": "ImGui_ImplSDL2_InitForOpenGL", 500 | "location": "imgui_impl_sdl", 501 | "ret": "bool", 502 | "signature": "(SDL_Window*,void*)", 503 | "stname": "" 504 | } 505 | ], 506 | "ImGui_ImplSDL2_InitForVulkan": [ 507 | { 508 | "args": "(SDL_Window* window)", 509 | "argsT": [ 510 | { 511 | "name": "window", 512 | "type": "SDL_Window*" 513 | } 514 | ], 515 | "argsoriginal": "(SDL_Window* window)", 516 | "call_args": "(window)", 517 | "cimguiname": "ImGui_ImplSDL2_InitForVulkan", 518 | "comment": "", 519 | "defaults": [], 520 | "funcname": "ImGui_ImplSDL2_InitForVulkan", 521 | "location": "imgui_impl_sdl", 522 | "ret": "bool", 523 | "signature": "(SDL_Window*)", 524 | "stname": "" 525 | } 526 | ], 527 | "ImGui_ImplSDL2_NewFrame": [ 528 | { 529 | "args": "(SDL_Window* window)", 530 | "argsT": [ 531 | { 532 | "name": "window", 533 | "type": "SDL_Window*" 534 | } 535 | ], 536 | "argsoriginal": "(SDL_Window* window)", 537 | "call_args": "(window)", 538 | "cimguiname": "ImGui_ImplSDL2_NewFrame", 539 | "comment": "", 540 | "defaults": [], 541 | "funcname": "ImGui_ImplSDL2_NewFrame", 542 | "location": "imgui_impl_sdl", 543 | "ret": "void", 544 | "signature": "(SDL_Window*)", 545 | "stname": "" 546 | } 547 | ], 548 | "ImGui_ImplSDL2_ProcessEvent": [ 549 | { 550 | "args": "(const SDL_Event* event)", 551 | "argsT": [ 552 | { 553 | "name": "event", 554 | "type": "const SDL_Event*" 555 | } 556 | ], 557 | "argsoriginal": "(const SDL_Event* event)", 558 | "call_args": "(event)", 559 | "cimguiname": "ImGui_ImplSDL2_ProcessEvent", 560 | "comment": "", 561 | "defaults": [], 562 | "funcname": "ImGui_ImplSDL2_ProcessEvent", 563 | "location": "imgui_impl_sdl", 564 | "ret": "bool", 565 | "signature": "(const SDL_Event*)", 566 | "stname": "" 567 | } 568 | ], 569 | "ImGui_ImplSDL2_Shutdown": [ 570 | { 571 | "args": "()", 572 | "argsT": [], 573 | "argsoriginal": "()", 574 | "call_args": "()", 575 | "cimguiname": "ImGui_ImplSDL2_Shutdown", 576 | "comment": "", 577 | "defaults": [], 578 | "funcname": "ImGui_ImplSDL2_Shutdown", 579 | "location": "imgui_impl_sdl", 580 | "ret": "void", 581 | "signature": "()", 582 | "stname": "" 583 | } 584 | ] 585 | } -------------------------------------------------------------------------------- /imgui-raw/third-party/imgui/imstb_rectpack.h: -------------------------------------------------------------------------------- 1 | // stb_rect_pack.h - v0.11 - public domain - rectangle packing 2 | // Sean Barrett 2014 3 | // 4 | // Useful for e.g. packing rectangular textures into an atlas. 5 | // Does not do rotation. 6 | // 7 | // Not necessarily the awesomest packing method, but better than 8 | // the totally naive one in stb_truetype (which is primarily what 9 | // this is meant to replace). 10 | // 11 | // Has only had a few tests run, may have issues. 12 | // 13 | // More docs to come. 14 | // 15 | // No memory allocations; uses qsort() and assert() from stdlib. 16 | // Can override those by defining STBRP_SORT and STBRP_ASSERT. 17 | // 18 | // This library currently uses the Skyline Bottom-Left algorithm. 19 | // 20 | // Please note: better rectangle packers are welcome! Please 21 | // implement them to the same API, but with a different init 22 | // function. 23 | // 24 | // Credits 25 | // 26 | // Library 27 | // Sean Barrett 28 | // Minor features 29 | // Martins Mozeiko 30 | // github:IntellectualKitty 31 | // 32 | // Bugfixes / warning fixes 33 | // Jeremy Jaussaud 34 | // 35 | // Version history: 36 | // 37 | // 0.11 (2017-03-03) return packing success/fail result 38 | // 0.10 (2016-10-25) remove cast-away-const to avoid warnings 39 | // 0.09 (2016-08-27) fix compiler warnings 40 | // 0.08 (2015-09-13) really fix bug with empty rects (w=0 or h=0) 41 | // 0.07 (2015-09-13) fix bug with empty rects (w=0 or h=0) 42 | // 0.06 (2015-04-15) added STBRP_SORT to allow replacing qsort 43 | // 0.05: added STBRP_ASSERT to allow replacing assert 44 | // 0.04: fixed minor bug in STBRP_LARGE_RECTS support 45 | // 0.01: initial release 46 | // 47 | // LICENSE 48 | // 49 | // See end of file for license information. 50 | 51 | ////////////////////////////////////////////////////////////////////////////// 52 | // 53 | // INCLUDE SECTION 54 | // 55 | 56 | #ifndef STB_INCLUDE_STB_RECT_PACK_H 57 | #define STB_INCLUDE_STB_RECT_PACK_H 58 | 59 | #define STB_RECT_PACK_VERSION 1 60 | 61 | #ifdef STBRP_STATIC 62 | #define STBRP_DEF static 63 | #else 64 | #define STBRP_DEF extern 65 | #endif 66 | 67 | #ifdef __cplusplus 68 | extern "C" { 69 | #endif 70 | 71 | typedef struct stbrp_context stbrp_context; 72 | typedef struct stbrp_node stbrp_node; 73 | typedef struct stbrp_rect stbrp_rect; 74 | 75 | #ifdef STBRP_LARGE_RECTS 76 | typedef int stbrp_coord; 77 | #else 78 | typedef unsigned short stbrp_coord; 79 | #endif 80 | 81 | STBRP_DEF int stbrp_pack_rects (stbrp_context *context, stbrp_rect *rects, int num_rects); 82 | // Assign packed locations to rectangles. The rectangles are of type 83 | // 'stbrp_rect' defined below, stored in the array 'rects', and there 84 | // are 'num_rects' many of them. 85 | // 86 | // Rectangles which are successfully packed have the 'was_packed' flag 87 | // set to a non-zero value and 'x' and 'y' store the minimum location 88 | // on each axis (i.e. bottom-left in cartesian coordinates, top-left 89 | // if you imagine y increasing downwards). Rectangles which do not fit 90 | // have the 'was_packed' flag set to 0. 91 | // 92 | // You should not try to access the 'rects' array from another thread 93 | // while this function is running, as the function temporarily reorders 94 | // the array while it executes. 95 | // 96 | // To pack into another rectangle, you need to call stbrp_init_target 97 | // again. To continue packing into the same rectangle, you can call 98 | // this function again. Calling this multiple times with multiple rect 99 | // arrays will probably produce worse packing results than calling it 100 | // a single time with the full rectangle array, but the option is 101 | // available. 102 | // 103 | // The function returns 1 if all of the rectangles were successfully 104 | // packed and 0 otherwise. 105 | 106 | struct stbrp_rect 107 | { 108 | // reserved for your use: 109 | int id; 110 | 111 | // input: 112 | stbrp_coord w, h; 113 | 114 | // output: 115 | stbrp_coord x, y; 116 | int was_packed; // non-zero if valid packing 117 | 118 | }; // 16 bytes, nominally 119 | 120 | 121 | STBRP_DEF void stbrp_init_target (stbrp_context *context, int width, int height, stbrp_node *nodes, int num_nodes); 122 | // Initialize a rectangle packer to: 123 | // pack a rectangle that is 'width' by 'height' in dimensions 124 | // using temporary storage provided by the array 'nodes', which is 'num_nodes' long 125 | // 126 | // You must call this function every time you start packing into a new target. 127 | // 128 | // There is no "shutdown" function. The 'nodes' memory must stay valid for 129 | // the following stbrp_pack_rects() call (or calls), but can be freed after 130 | // the call (or calls) finish. 131 | // 132 | // Note: to guarantee best results, either: 133 | // 1. make sure 'num_nodes' >= 'width' 134 | // or 2. call stbrp_allow_out_of_mem() defined below with 'allow_out_of_mem = 1' 135 | // 136 | // If you don't do either of the above things, widths will be quantized to multiples 137 | // of small integers to guarantee the algorithm doesn't run out of temporary storage. 138 | // 139 | // If you do #2, then the non-quantized algorithm will be used, but the algorithm 140 | // may run out of temporary storage and be unable to pack some rectangles. 141 | 142 | STBRP_DEF void stbrp_setup_allow_out_of_mem (stbrp_context *context, int allow_out_of_mem); 143 | // Optionally call this function after init but before doing any packing to 144 | // change the handling of the out-of-temp-memory scenario, described above. 145 | // If you call init again, this will be reset to the default (false). 146 | 147 | 148 | STBRP_DEF void stbrp_setup_heuristic (stbrp_context *context, int heuristic); 149 | // Optionally select which packing heuristic the library should use. Different 150 | // heuristics will produce better/worse results for different data sets. 151 | // If you call init again, this will be reset to the default. 152 | 153 | enum 154 | { 155 | STBRP_HEURISTIC_Skyline_default=0, 156 | STBRP_HEURISTIC_Skyline_BL_sortHeight = STBRP_HEURISTIC_Skyline_default, 157 | STBRP_HEURISTIC_Skyline_BF_sortHeight 158 | }; 159 | 160 | 161 | ////////////////////////////////////////////////////////////////////////////// 162 | // 163 | // the details of the following structures don't matter to you, but they must 164 | // be visible so you can handle the memory allocations for them 165 | 166 | struct stbrp_node 167 | { 168 | stbrp_coord x,y; 169 | stbrp_node *next; 170 | }; 171 | 172 | struct stbrp_context 173 | { 174 | int width; 175 | int height; 176 | int align; 177 | int init_mode; 178 | int heuristic; 179 | int num_nodes; 180 | stbrp_node *active_head; 181 | stbrp_node *free_head; 182 | stbrp_node extra[2]; // we allocate two extra nodes so optimal user-node-count is 'width' not 'width+2' 183 | }; 184 | 185 | #ifdef __cplusplus 186 | } 187 | #endif 188 | 189 | #endif 190 | 191 | ////////////////////////////////////////////////////////////////////////////// 192 | // 193 | // IMPLEMENTATION SECTION 194 | // 195 | 196 | #ifdef STB_RECT_PACK_IMPLEMENTATION 197 | #ifndef STBRP_SORT 198 | #include 199 | #define STBRP_SORT qsort 200 | #endif 201 | 202 | #ifndef STBRP_ASSERT 203 | #include 204 | #define STBRP_ASSERT assert 205 | #endif 206 | 207 | #ifdef _MSC_VER 208 | #define STBRP__NOTUSED(v) (void)(v) 209 | #define STBRP__CDECL __cdecl 210 | #else 211 | #define STBRP__NOTUSED(v) (void)sizeof(v) 212 | #define STBRP__CDECL 213 | #endif 214 | 215 | enum 216 | { 217 | STBRP__INIT_skyline = 1 218 | }; 219 | 220 | STBRP_DEF void stbrp_setup_heuristic(stbrp_context *context, int heuristic) 221 | { 222 | switch (context->init_mode) { 223 | case STBRP__INIT_skyline: 224 | STBRP_ASSERT(heuristic == STBRP_HEURISTIC_Skyline_BL_sortHeight || heuristic == STBRP_HEURISTIC_Skyline_BF_sortHeight); 225 | context->heuristic = heuristic; 226 | break; 227 | default: 228 | STBRP_ASSERT(0); 229 | } 230 | } 231 | 232 | STBRP_DEF void stbrp_setup_allow_out_of_mem(stbrp_context *context, int allow_out_of_mem) 233 | { 234 | if (allow_out_of_mem) 235 | // if it's ok to run out of memory, then don't bother aligning them; 236 | // this gives better packing, but may fail due to OOM (even though 237 | // the rectangles easily fit). @TODO a smarter approach would be to only 238 | // quantize once we've hit OOM, then we could get rid of this parameter. 239 | context->align = 1; 240 | else { 241 | // if it's not ok to run out of memory, then quantize the widths 242 | // so that num_nodes is always enough nodes. 243 | // 244 | // I.e. num_nodes * align >= width 245 | // align >= width / num_nodes 246 | // align = ceil(width/num_nodes) 247 | 248 | context->align = (context->width + context->num_nodes-1) / context->num_nodes; 249 | } 250 | } 251 | 252 | STBRP_DEF void stbrp_init_target(stbrp_context *context, int width, int height, stbrp_node *nodes, int num_nodes) 253 | { 254 | int i; 255 | #ifndef STBRP_LARGE_RECTS 256 | STBRP_ASSERT(width <= 0xffff && height <= 0xffff); 257 | #endif 258 | 259 | for (i=0; i < num_nodes-1; ++i) 260 | nodes[i].next = &nodes[i+1]; 261 | nodes[i].next = NULL; 262 | context->init_mode = STBRP__INIT_skyline; 263 | context->heuristic = STBRP_HEURISTIC_Skyline_default; 264 | context->free_head = &nodes[0]; 265 | context->active_head = &context->extra[0]; 266 | context->width = width; 267 | context->height = height; 268 | context->num_nodes = num_nodes; 269 | stbrp_setup_allow_out_of_mem(context, 0); 270 | 271 | // node 0 is the full width, node 1 is the sentinel (lets us not store width explicitly) 272 | context->extra[0].x = 0; 273 | context->extra[0].y = 0; 274 | context->extra[0].next = &context->extra[1]; 275 | context->extra[1].x = (stbrp_coord) width; 276 | #ifdef STBRP_LARGE_RECTS 277 | context->extra[1].y = (1<<30); 278 | #else 279 | context->extra[1].y = 65535; 280 | #endif 281 | context->extra[1].next = NULL; 282 | } 283 | 284 | // find minimum y position if it starts at x1 285 | static int stbrp__skyline_find_min_y(stbrp_context *c, stbrp_node *first, int x0, int width, int *pwaste) 286 | { 287 | stbrp_node *node = first; 288 | int x1 = x0 + width; 289 | int min_y, visited_width, waste_area; 290 | 291 | STBRP__NOTUSED(c); 292 | 293 | STBRP_ASSERT(first->x <= x0); 294 | 295 | #if 0 296 | // skip in case we're past the node 297 | while (node->next->x <= x0) 298 | ++node; 299 | #else 300 | STBRP_ASSERT(node->next->x > x0); // we ended up handling this in the caller for efficiency 301 | #endif 302 | 303 | STBRP_ASSERT(node->x <= x0); 304 | 305 | min_y = 0; 306 | waste_area = 0; 307 | visited_width = 0; 308 | while (node->x < x1) { 309 | if (node->y > min_y) { 310 | // raise min_y higher. 311 | // we've accounted for all waste up to min_y, 312 | // but we'll now add more waste for everything we've visted 313 | waste_area += visited_width * (node->y - min_y); 314 | min_y = node->y; 315 | // the first time through, visited_width might be reduced 316 | if (node->x < x0) 317 | visited_width += node->next->x - x0; 318 | else 319 | visited_width += node->next->x - node->x; 320 | } else { 321 | // add waste area 322 | int under_width = node->next->x - node->x; 323 | if (under_width + visited_width > width) 324 | under_width = width - visited_width; 325 | waste_area += under_width * (min_y - node->y); 326 | visited_width += under_width; 327 | } 328 | node = node->next; 329 | } 330 | 331 | *pwaste = waste_area; 332 | return min_y; 333 | } 334 | 335 | typedef struct 336 | { 337 | int x,y; 338 | stbrp_node **prev_link; 339 | } stbrp__findresult; 340 | 341 | static stbrp__findresult stbrp__skyline_find_best_pos(stbrp_context *c, int width, int height) 342 | { 343 | int best_waste = (1<<30), best_x, best_y = (1 << 30); 344 | stbrp__findresult fr; 345 | stbrp_node **prev, *node, *tail, **best = NULL; 346 | 347 | // align to multiple of c->align 348 | width = (width + c->align - 1); 349 | width -= width % c->align; 350 | STBRP_ASSERT(width % c->align == 0); 351 | 352 | node = c->active_head; 353 | prev = &c->active_head; 354 | while (node->x + width <= c->width) { 355 | int y,waste; 356 | y = stbrp__skyline_find_min_y(c, node, node->x, width, &waste); 357 | if (c->heuristic == STBRP_HEURISTIC_Skyline_BL_sortHeight) { // actually just want to test BL 358 | // bottom left 359 | if (y < best_y) { 360 | best_y = y; 361 | best = prev; 362 | } 363 | } else { 364 | // best-fit 365 | if (y + height <= c->height) { 366 | // can only use it if it first vertically 367 | if (y < best_y || (y == best_y && waste < best_waste)) { 368 | best_y = y; 369 | best_waste = waste; 370 | best = prev; 371 | } 372 | } 373 | } 374 | prev = &node->next; 375 | node = node->next; 376 | } 377 | 378 | best_x = (best == NULL) ? 0 : (*best)->x; 379 | 380 | // if doing best-fit (BF), we also have to try aligning right edge to each node position 381 | // 382 | // e.g, if fitting 383 | // 384 | // ____________________ 385 | // |____________________| 386 | // 387 | // into 388 | // 389 | // | | 390 | // | ____________| 391 | // |____________| 392 | // 393 | // then right-aligned reduces waste, but bottom-left BL is always chooses left-aligned 394 | // 395 | // This makes BF take about 2x the time 396 | 397 | if (c->heuristic == STBRP_HEURISTIC_Skyline_BF_sortHeight) { 398 | tail = c->active_head; 399 | node = c->active_head; 400 | prev = &c->active_head; 401 | // find first node that's admissible 402 | while (tail->x < width) 403 | tail = tail->next; 404 | while (tail) { 405 | int xpos = tail->x - width; 406 | int y,waste; 407 | STBRP_ASSERT(xpos >= 0); 408 | // find the left position that matches this 409 | while (node->next->x <= xpos) { 410 | prev = &node->next; 411 | node = node->next; 412 | } 413 | STBRP_ASSERT(node->next->x > xpos && node->x <= xpos); 414 | y = stbrp__skyline_find_min_y(c, node, xpos, width, &waste); 415 | if (y + height < c->height) { 416 | if (y <= best_y) { 417 | if (y < best_y || waste < best_waste || (waste==best_waste && xpos < best_x)) { 418 | best_x = xpos; 419 | STBRP_ASSERT(y <= best_y); 420 | best_y = y; 421 | best_waste = waste; 422 | best = prev; 423 | } 424 | } 425 | } 426 | tail = tail->next; 427 | } 428 | } 429 | 430 | fr.prev_link = best; 431 | fr.x = best_x; 432 | fr.y = best_y; 433 | return fr; 434 | } 435 | 436 | static stbrp__findresult stbrp__skyline_pack_rectangle(stbrp_context *context, int width, int height) 437 | { 438 | // find best position according to heuristic 439 | stbrp__findresult res = stbrp__skyline_find_best_pos(context, width, height); 440 | stbrp_node *node, *cur; 441 | 442 | // bail if: 443 | // 1. it failed 444 | // 2. the best node doesn't fit (we don't always check this) 445 | // 3. we're out of memory 446 | if (res.prev_link == NULL || res.y + height > context->height || context->free_head == NULL) { 447 | res.prev_link = NULL; 448 | return res; 449 | } 450 | 451 | // on success, create new node 452 | node = context->free_head; 453 | node->x = (stbrp_coord) res.x; 454 | node->y = (stbrp_coord) (res.y + height); 455 | 456 | context->free_head = node->next; 457 | 458 | // insert the new node into the right starting point, and 459 | // let 'cur' point to the remaining nodes needing to be 460 | // stiched back in 461 | 462 | cur = *res.prev_link; 463 | if (cur->x < res.x) { 464 | // preserve the existing one, so start testing with the next one 465 | stbrp_node *next = cur->next; 466 | cur->next = node; 467 | cur = next; 468 | } else { 469 | *res.prev_link = node; 470 | } 471 | 472 | // from here, traverse cur and free the nodes, until we get to one 473 | // that shouldn't be freed 474 | while (cur->next && cur->next->x <= res.x + width) { 475 | stbrp_node *next = cur->next; 476 | // move the current node to the free list 477 | cur->next = context->free_head; 478 | context->free_head = cur; 479 | cur = next; 480 | } 481 | 482 | // stitch the list back in 483 | node->next = cur; 484 | 485 | if (cur->x < res.x + width) 486 | cur->x = (stbrp_coord) (res.x + width); 487 | 488 | #ifdef _DEBUG 489 | cur = context->active_head; 490 | while (cur->x < context->width) { 491 | STBRP_ASSERT(cur->x < cur->next->x); 492 | cur = cur->next; 493 | } 494 | STBRP_ASSERT(cur->next == NULL); 495 | 496 | { 497 | int count=0; 498 | cur = context->active_head; 499 | while (cur) { 500 | cur = cur->next; 501 | ++count; 502 | } 503 | cur = context->free_head; 504 | while (cur) { 505 | cur = cur->next; 506 | ++count; 507 | } 508 | STBRP_ASSERT(count == context->num_nodes+2); 509 | } 510 | #endif 511 | 512 | return res; 513 | } 514 | 515 | static int STBRP__CDECL rect_height_compare(const void *a, const void *b) 516 | { 517 | const stbrp_rect *p = (const stbrp_rect *) a; 518 | const stbrp_rect *q = (const stbrp_rect *) b; 519 | if (p->h > q->h) 520 | return -1; 521 | if (p->h < q->h) 522 | return 1; 523 | return (p->w > q->w) ? -1 : (p->w < q->w); 524 | } 525 | 526 | static int STBRP__CDECL rect_original_order(const void *a, const void *b) 527 | { 528 | const stbrp_rect *p = (const stbrp_rect *) a; 529 | const stbrp_rect *q = (const stbrp_rect *) b; 530 | return (p->was_packed < q->was_packed) ? -1 : (p->was_packed > q->was_packed); 531 | } 532 | 533 | #ifdef STBRP_LARGE_RECTS 534 | #define STBRP__MAXVAL 0xffffffff 535 | #else 536 | #define STBRP__MAXVAL 0xffff 537 | #endif 538 | 539 | STBRP_DEF int stbrp_pack_rects(stbrp_context *context, stbrp_rect *rects, int num_rects) 540 | { 541 | int i, all_rects_packed = 1; 542 | 543 | // we use the 'was_packed' field internally to allow sorting/unsorting 544 | for (i=0; i < num_rects; ++i) { 545 | rects[i].was_packed = i; 546 | #ifndef STBRP_LARGE_RECTS 547 | STBRP_ASSERT(rects[i].w <= 0xffff && rects[i].h <= 0xffff); 548 | #endif 549 | } 550 | 551 | // sort according to heuristic 552 | STBRP_SORT(rects, num_rects, sizeof(rects[0]), rect_height_compare); 553 | 554 | for (i=0; i < num_rects; ++i) { 555 | if (rects[i].w == 0 || rects[i].h == 0) { 556 | rects[i].x = rects[i].y = 0; // empty rect needs no space 557 | } else { 558 | stbrp__findresult fr = stbrp__skyline_pack_rectangle(context, rects[i].w, rects[i].h); 559 | if (fr.prev_link) { 560 | rects[i].x = (stbrp_coord) fr.x; 561 | rects[i].y = (stbrp_coord) fr.y; 562 | } else { 563 | rects[i].x = rects[i].y = STBRP__MAXVAL; 564 | } 565 | } 566 | } 567 | 568 | // unsort 569 | STBRP_SORT(rects, num_rects, sizeof(rects[0]), rect_original_order); 570 | 571 | // set was_packed flags and all_rects_packed status 572 | for (i=0; i < num_rects; ++i) { 573 | rects[i].was_packed = !(rects[i].x == STBRP__MAXVAL && rects[i].y == STBRP__MAXVAL); 574 | if (!rects[i].was_packed) 575 | all_rects_packed = 0; 576 | } 577 | 578 | // return the all_rects_packed status 579 | return all_rects_packed; 580 | } 581 | #endif 582 | 583 | /* 584 | ------------------------------------------------------------------------------ 585 | This software is available under 2 licenses -- choose whichever you prefer. 586 | ------------------------------------------------------------------------------ 587 | ALTERNATIVE A - MIT License 588 | Copyright (c) 2017 Sean Barrett 589 | Permission is hereby granted, free of charge, to any person obtaining a copy of 590 | this software and associated documentation files (the "Software"), to deal in 591 | the Software without restriction, including without limitation the rights to 592 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 593 | of the Software, and to permit persons to whom the Software is furnished to do 594 | so, subject to the following conditions: 595 | The above copyright notice and this permission notice shall be included in all 596 | copies or substantial portions of the Software. 597 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 598 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 599 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 600 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 601 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 602 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 603 | SOFTWARE. 604 | ------------------------------------------------------------------------------ 605 | ALTERNATIVE B - Public Domain (www.unlicense.org) 606 | This is free and unencumbered software released into the public domain. 607 | Anyone is free to copy, modify, publish, use, compile, sell, or distribute this 608 | software, either in source code form or as a compiled binary, for any purpose, 609 | commercial or non-commercial, and by any means. 610 | In jurisdictions that recognize copyright laws, the author or authors of this 611 | software dedicate any and all copyright interest in the software to the public 612 | domain. We make this dedication for the benefit of the public at large and to 613 | the detriment of our heirs and successors. We intend this dedication to be an 614 | overt act of relinquishment in perpetuity of all present and future rights to 615 | this software under copyright law. 616 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 617 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 618 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 619 | AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 620 | ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 621 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 622 | ------------------------------------------------------------------------------ 623 | */ 624 | -------------------------------------------------------------------------------- /generate.js: -------------------------------------------------------------------------------- 1 | const _ = require("lodash"); 2 | const changeCase = require('change-case'); 3 | const nunjucks = require("nunjucks"); 4 | const fs = require("fs"); 5 | const program = require("commander"); 6 | 7 | nunjucks.configure({ 8 | autoescape: false 9 | }); 10 | 11 | const definitions = JSON.parse(fs.readFileSync("data/definitions.json", "utf-8")); 12 | const structsAndEnums = JSON.parse(fs.readFileSync("data/structs_and_enums.json", "utf-8")); 13 | const typedefs = JSON.parse(fs.readFileSync("data/typedefs_dict.json", "utf-8")); 14 | 15 | const blacklistedTypedefs = { 16 | // some C++ artifacts from templates 17 | 'const_iterator': true, 18 | 'iterator': true, 19 | 'value_type': true, 20 | } 21 | 22 | const blacklistedStructs = { 23 | 'Pair': true, // has a union inside, let's implement it manually 24 | 'ImVector': true, // template type, let's implement it manually 25 | } 26 | 27 | const typedefsSorted = _.keys(typedefs).sort(); 28 | 29 | const typeMap = { 30 | 'bool': 'bool', 31 | 'char': 'c_char', 32 | 'double': 'c_double', 33 | 'float': 'c_float', 34 | 'int': 'c_int', 35 | 'int64_t': 'i64', 36 | 'Pair': 'Pair', 37 | 'short': 'c_short', 38 | 'signed int': 'c_int', // iirc, "int == signed int" in C, "char != signed char" though 39 | 'uint64_t': 'u64', 40 | 'unsigned char': 'c_uchar', 41 | 'unsigned int': 'c_uint', 42 | 'unsigned short': 'c_ushort', 43 | 'unsigned_char': 'c_uchar', 44 | 'void': 'c_void', 45 | 46 | 'bool(*)(void* data,int idx,const char** out_text)': 'extern "C" fn(data: *mut c_void, idx: c_int, out_text: *mut *const c_char) -> bool', 47 | 'const char*(*)(void* user_data)': 'Option *const c_char>', 48 | 'float(*)(void* data,int idx)': 'extern "C" fn(data: *mut c_void, idx: c_int) -> c_float', 49 | 'void(*)(int x,int y)': 'Option', 50 | 'void(*)(void* ptr,void* user_data)': 'Option', 51 | 'void(*)(void* user_data,const char* text)': 'Option', 52 | 'void*(*)(size_t sz,void* user_data)': 'Option *mut c_void>', 53 | 54 | 'ImColor_Simple': 'ImColor_Simple', 55 | 'ImDrawCallback': 'ImDrawCallback', 56 | 'ImDrawListSharedData': 'ImDrawListSharedData', 57 | 'ImFontPtr': 'ImFontPtr', 58 | 'ImGuiContext': 'ImGuiContext', 59 | 'ImGuiInputTextCallback': 'ImGuiInputTextCallback', 60 | 'ImGuiSizeCallback': 'ImGuiSizeCallback', 61 | 'ImVec2_Simple': 'ImVec2_Simple', 62 | 'ImVec4_Simple': 'ImVec4_Simple', 63 | 'size_t': 'size_t', 64 | } 65 | 66 | const snakeCaseManualCases = { 67 | 'ColorConvertRGBtoHSV': 'color_convert_rgb_to_hsv', 68 | 'ColorConvertHSVtoRGB': 'color_convert_hsv_to_rgb', 69 | } 70 | 71 | function snakeCase(s) { 72 | const v = snakeCaseManualCases[s]; 73 | return v || changeCase.snakeCase(s); 74 | } 75 | 76 | function addKnownTypes() { 77 | const alreadyAdded = []; 78 | const addFrom = (collection, name) => { 79 | for (const v of collection) { 80 | if (typeMap[v]) { 81 | alreadyAdded.push({key: v, collection: name}); 82 | } else { 83 | typeMap[v] = v; 84 | } 85 | } 86 | } 87 | addFrom(allEnumNames(), 'Enum'); 88 | addFrom(allStructNames(), 'Struct'); 89 | addFrom(allTypedefNames(), 'Typedef'); 90 | if (alreadyAdded.length > 0) { 91 | throw new Error(`already added: ${_.join(_.map(alreadyAdded, JSON.stringify), ', ')}`); 92 | } 93 | } 94 | 95 | addKnownTypes(); 96 | 97 | function extractArity(name) { 98 | const re = /\[([^\]]+)\]/g; 99 | const m = re.exec(name); 100 | if (m) { 101 | const mm = /([^_]+)_(.+)/.exec(m[1]); 102 | if (mm) { 103 | return `${mm[1]}::${mm[2]} as usize`; 104 | } 105 | return m[1]; 106 | } 107 | return ''; 108 | } 109 | 110 | function stripArity(name) { 111 | return name.replace(/\[[^\]]+\]/g, '') 112 | } 113 | 114 | function mapType(t, opts) { 115 | const prefix = (opts && opts.prefix) || ''; 116 | const arity = (opts && opts.arity) || ''; 117 | 118 | // some manual overrides 119 | if (t === 'const char* const[]') { 120 | return '*const *const c_char'; 121 | } 122 | 123 | if (t.indexOf("(*)") === -1) { 124 | // we mess with types, but only if they are not a function pointer, those are special 125 | 126 | if (_.startsWith(t, 'const ') && _.endsWith(t, '*')) { 127 | // it's not exactly a C syntax parser here, but for given cases it works, 128 | // converts "const Foo*" to "*const Foo" 129 | const nt = t.substr(0, t.length-1).substr('const '.length); 130 | return mapType(nt, { ...opts, prefix: `*const ${prefix}` }); 131 | } else if (_.startsWith(t, 'const ')) { 132 | const nt = t.substr('const '.length); 133 | return mapType(nt, opts); 134 | } 135 | if (_.endsWith(t, '*') || _.endsWith(t, '&')) { 136 | // it's not exactly a C syntax parser here, but for given cases it works, 137 | // converts "Foo*" to "*mut Foo" 138 | return mapType(t.substr(0, t.length-1), { ...opts, prefix: `*mut ${prefix}` }); 139 | } 140 | if (_.endsWith(t, ']')) { 141 | // arity in a type, happens in functions, in that case we need to convert it to a pointer to an array 142 | // C array types are just pointers 143 | const arity = extractArity(t); 144 | const nt = stripArity(t) + '*'; 145 | return mapType(nt, { ...opts, arity }); 146 | } 147 | if (_.startsWith(t, "ImVector_")) { 148 | return `${prefix}ImVector<${mapType(t.substr("ImVector_".length))}>`; 149 | } 150 | } 151 | const result = typeMap[t]; 152 | if (!result) { 153 | throw new Error(`unknown type: ${prefix}${t}`); 154 | } 155 | if (arity) { 156 | return `${prefix}[${result}; ${arity}]`; 157 | } else { 158 | return `${prefix}${result}`; 159 | } 160 | } 161 | 162 | //========================================================================================= 163 | // HEADER AND MANUALLY IMPLEMENTED THINGS 164 | //========================================================================================= 165 | 166 | function generateHeader() { 167 | console.log(` 168 | use bitflags::bitflags; 169 | use std::os::raw::{c_char, c_double, c_float, c_int, c_short, c_uchar, c_uint, c_ushort, c_void}; 170 | use libc::size_t; 171 | use std::slice; 172 | 173 | #[repr(C)] 174 | pub struct ImVector { 175 | size: c_int, 176 | capacity: c_int, 177 | data: *mut T, 178 | } 179 | 180 | impl ImVector { 181 | pub unsafe fn as_slice(&self) -> &[T] { 182 | slice::from_raw_parts(self.data, self.size as usize) 183 | } 184 | } 185 | 186 | #[repr(C)] 187 | pub struct Pair { 188 | pub key: ImGuiID, 189 | pub value: PairValue, 190 | } 191 | 192 | #[repr(C)] 193 | pub union PairValue { 194 | pub val_i: c_int, 195 | pub val_f: c_float, 196 | pub val_p: *mut c_void, 197 | } 198 | 199 | // opaque types 200 | pub enum ImDrawListSharedData {} 201 | pub enum ImGuiContext {} 202 | 203 | pub type ImFontPtr = *mut ImFont; 204 | pub type ImDrawCallback = Option; 205 | pub type ImGuiInputTextCallback = Option c_int>; 206 | pub type ImGuiSizeCallback = Option; 207 | `.substr(1)); 208 | } 209 | 210 | //========================================================================================= 211 | // TYPEDEFS 212 | //========================================================================================= 213 | 214 | function allTypedefNames() { 215 | return _.filter(typedefsSorted, typedef => !isTypedefBlacklisted(typedef, typedefs[typedef])); 216 | } 217 | 218 | function isTypedefBlacklisted(typedef, val) { 219 | if (_.startsWith(val, "struct ")) { // not interested in struct typedefs 220 | return true; 221 | } 222 | if (val.indexOf("(*)") !== -1) { // function pointer typedefs are done manually 223 | return true; 224 | } 225 | if (blacklistedTypedefs[typedef]) { 226 | return true; 227 | } 228 | if (structsAndEnums.enums[typedef+"_"]) { // not interested in enums either 229 | return true; 230 | } 231 | return false; 232 | } 233 | 234 | function generateTypedefs() { 235 | for (const typedef of typedefsSorted) { 236 | const val = typedefs[typedef]; 237 | if (isTypedefBlacklisted(typedef, val)) { 238 | continue; 239 | } 240 | 241 | console.log(`pub type ${typedef} = ${mapType(val)};`); 242 | } 243 | } 244 | 245 | //========================================================================================= 246 | // ENUMS 247 | //========================================================================================= 248 | 249 | const bitflagsTemplate = ` 250 | bitflags! { 251 | #[repr(C)] 252 | pub struct {{ name }}: {{ type }} { 253 | {%- for f in fields %} 254 | const {{ f.name }} = {{ f.value }}; 255 | {%- endfor %} 256 | } 257 | } 258 | `; 259 | 260 | const enumTemplate = ` 261 | #[repr(C)] 262 | #[derive(Copy, Clone, Debug, PartialEq, Eq)] 263 | pub enum {{ name }} { 264 | {%- for f in fields %} 265 | {{ f.name }} = {{ f.value }}, 266 | {%- endfor %} 267 | } 268 | `; 269 | 270 | function isBitFlags(fields) { 271 | return _.some(fields, f => _.isString(f.value) && f.value.indexOf("<<") !== -1); 272 | } 273 | 274 | function processBitFlagsValue(v, nameRaw) { 275 | if (!_.isString(v)) { 276 | return v; 277 | } 278 | const re = new RegExp(nameRaw+`([A-Za-z0-9_]+)`, 'g'); 279 | return v.replace(re, (m, name) => { 280 | return `Self::${name}.bits`; 281 | }); 282 | } 283 | 284 | function allEnumNames() { 285 | return _.map(_.keys(structsAndEnums.enums), e => _.trimEnd(e, '_')); 286 | } 287 | 288 | function generateEnums() { 289 | for (const nameRaw of _.keys(structsAndEnums.enums)) { 290 | const fields = structsAndEnums.enums[nameRaw]; 291 | const name = _.trimEnd(nameRaw, '_'); 292 | const data = { 293 | name, 294 | type: mapType(typedefs[name]), 295 | fields: _.map(fields, f => ({ 296 | ...f, 297 | name: _.startsWith(f.name, nameRaw) ? f.name.substr(nameRaw.length) : f.name, 298 | value: processBitFlagsValue(f.value, nameRaw), 299 | })), 300 | }; 301 | if (isBitFlags(fields)) { 302 | const result = nunjucks.renderString(bitflagsTemplate, data); 303 | console.log(result); 304 | } else { 305 | const valsMap = {}; 306 | data.fields = _.filter(data.fields, f => { 307 | if (valsMap[f.calc_value]) { 308 | return false; 309 | } else { 310 | valsMap[f.calc_value] = true; 311 | return true; 312 | } 313 | }); 314 | const result = nunjucks.renderString(enumTemplate, data); 315 | console.log(result); 316 | } 317 | } 318 | } 319 | 320 | //========================================================================================= 321 | // STRUCTS 322 | //========================================================================================= 323 | 324 | const structTemplate = ` 325 | #[repr(C)] 326 | {%- if simple %} 327 | #[derive(Copy, Clone)]{% endif %} 328 | pub struct {{ name }} { 329 | {%- for f in fields %} 330 | pub {{ f.name }}: {{ f.type }}, 331 | {%- endfor %} 332 | } 333 | `; 334 | 335 | const simpleStructs = { 336 | 'ImVec2': true, 337 | 'ImVec4': true, 338 | } 339 | 340 | function allStructNames() { 341 | return _.filter(_.keys(structsAndEnums.structs), s => !blacklistedStructs[s]); 342 | } 343 | 344 | function generateStructs() { 345 | for (const name of _.keys(structsAndEnums.structs)) { 346 | if (blacklistedStructs[name]) { 347 | continue; 348 | } 349 | 350 | const fields = structsAndEnums.structs[name]; 351 | const result = nunjucks.renderString(structTemplate, { 352 | name, 353 | simple: !!simpleStructs[name], 354 | fields: _.map(fields, f => ({ 355 | type: mapType(f.type, { arity: extractArity(f.name) }), 356 | name: snakeCase(stripArity(f.name)), 357 | })), 358 | }); 359 | console.log(result); 360 | } 361 | } 362 | 363 | //========================================================================================= 364 | // FUNCTIONS 365 | //========================================================================================= 366 | 367 | const funcTemplate = ` 368 | pub fn {{name}}( 369 | {%- for a in args -%} 370 | {%- if not loop.first %}, {% endif %}{{ a.name }}{% if a.type %}: {% endif %}{{ a.type -}} 371 | {% endfor -%} 372 | ) 373 | {%- if ret %} -> {{ ret }}{% endif %}; 374 | `; 375 | 376 | const safeArgNameMap = { 377 | 'type': '_type', 378 | 'ref': '_ref', 379 | 'self': '_self', 380 | 'in': '_in', 381 | } 382 | 383 | function safeArgName(v) { 384 | return safeArgNameMap[v] || v; 385 | } 386 | 387 | function generateFuncs() { 388 | console.log(`extern "C" {`); 389 | for (const name of _.keys(definitions)) { 390 | const funcs = definitions[name]; 391 | for (const func of funcs) { 392 | if (func.nonUDT) { // rust works just fine here 393 | continue; 394 | } 395 | if (_.some(func.argsT, a => a.type === 'va_list')) { 396 | // skip va_list variants, we're fine with "..." notation, in most cases it's about string formatting 397 | // and we'll just use ("%s", str) 398 | continue; 399 | } 400 | const name = func.ov_cimguiname || func.cimguiname; 401 | const ret = func.ret && func.ret !== 'void' ? mapType(func.ret) : undefined; 402 | const args = _.map(func.argsT, a => ({ 403 | name: safeArgName(a.name), 404 | type: a.name === '...' ? undefined : mapType(a.type), 405 | })); 406 | const result = nunjucks.renderString(funcTemplate, { 407 | name, 408 | ret, 409 | args, 410 | }); 411 | console.log(_.trim(result)); 412 | } 413 | } 414 | console.log(`} // extern "C"`); 415 | } 416 | 417 | //========================================================================================= 418 | // SAFE WRAPPERS 419 | //========================================================================================= 420 | 421 | const blacklistedSafeFuncs = { 422 | 'igCreateContext': true, // calls to it are made by ImGui object 423 | 'igDestroyContext': true, // calls to it are made by ImGui object 424 | 'igMemAlloc': true, // raw memory 425 | 'igMemFree': true, // raw memory 426 | 'igSetAllocatorFunctions': true, // use unsafe interface if you want to override those 427 | 'igSetCurrentContext': true, // currently we assume only one context per lib usage 428 | 'igTextUnformatted': true, // has "end" pointer, TODO: we could make &str interface for it 429 | } 430 | 431 | const safeArgTypeConv = { 432 | '*const c_char': v => `${v}.as_ptr()`, 433 | }; 434 | 435 | const safeRetTypeConv = { 436 | '*const c_char': v => `CStr::from_ptr(${v}).to_string_lossy().into_owned()`, 437 | }; 438 | 439 | const safeTypeMap = { 440 | '*const ImVec2': (g) => `&'${g.next()} ImVec2`, 441 | '*const c_char': (g) => `&'${g.next()} CStr`, 442 | '*const c_float': (g) => `&'${g.next()} f32`, 443 | '*mut [c_float; 2]': (g) => `&'${g.next()} mut [f32; 2]`, 444 | '*mut [c_float; 3]': (g) => `&'${g.next()} mut [f32; 3]`, 445 | '*mut [c_float; 4]': (g) => `&'${g.next()} mut [f32; 4]`, 446 | '*mut [c_int; 2]': (g) => `&'${g.next()} mut [i32; 2]`, 447 | '*mut [c_int; 3]': (g) => `&'${g.next()} mut [i32; 3]`, 448 | '*mut [c_int; 4]': (g) => `&'${g.next()} mut [i32; 4]`, 449 | '*mut bool': (g) => `&'${g.next()} mut bool`, 450 | '*mut c_double': (g) => `&'${g.next()} mut f64`, 451 | '*mut c_float': (g) => `&'${g.next()} mut f32`, 452 | '*mut c_int': (g) => `&'${g.next()} mut i32`, 453 | '*mut c_uint': (g) => `&'${g.next()} mut u32`, 454 | '*mut size_t': (g) => `&'${g.next()} mut usize`, 455 | 'ImGuiCol': () => 'ImGuiCol', 456 | 'ImGuiColorEditFlags': () => 'ImGuiColorEditFlags', 457 | 'ImGuiComboFlags': () => 'ImGuiComboFlags', 458 | 'ImGuiCond': () => 'ImGuiCond', 459 | 'ImGuiDataType': () => 'ImGuiDataType', 460 | 'ImGuiDir': () => 'ImGuiDir', 461 | 'ImGuiDragDropFlags': () => 'ImGuiDragDropFlags', 462 | 'ImGuiFocusedFlags': () => 'ImGuiFocusedFlags', 463 | 'ImGuiHoveredFlags': () => 'ImGuiHoveredFlags', 464 | 'ImGuiID': () => 'ImGuiID', 465 | 'ImGuiInputTextCallback': () => 'ImGuiInputTextCallback', 466 | 'ImGuiInputTextFlags': () => 'ImGuiInputTextFlags', 467 | 'ImGuiKey': () => 'ImGuiKey', 468 | 'ImGuiMouseCursor': () => 'ImGuiMouseCursor', 469 | 'ImGuiSelectableFlags': () => 'ImGuiSelectableFlags', 470 | 'ImGuiSizeCallback': () => 'ImGuiSizeCallback', 471 | 'ImGuiStyleVar': () => 'ImGuiStyleVar', 472 | 'ImGuiTreeNodeFlags': () => 'ImGuiTreeNodeFlags', 473 | 'ImGuiWindowFlags': () => 'ImGuiWindowFlags', 474 | 'ImTextureID': () => 'ImTextureID', 475 | 'ImU32': () => 'u32', 476 | 'ImVec2': () => 'ImVec2', 477 | 'ImVec4': () => 'ImVec4', 478 | 'bool': () => 'bool', 479 | 'c_double': () => 'f64', 480 | 'c_float': () => 'f32', 481 | 'c_int': () => 'i32', 482 | 'c_uint': () => 'u32', 483 | 'size_t': () => 'usize', 484 | }; 485 | 486 | const safeRetTypeMap = { 487 | ...safeTypeMap, 488 | '*const c_char': () => 'String', 489 | }; 490 | 491 | const safeTemplate = ` 492 | #[inline] 493 | pub fn {{ sname }}<{{ lifetimes }}>(&'a self 494 | {%- for a in args -%} 495 | , {{ a.name }}{% if a.stype %}: {% endif %}{{ a.stype -}} 496 | {% endfor -%} 497 | ) 498 | {%- if sret %} -> {{ sret }}{% endif %} { 499 | {% set funccall %} 500 | {{- name }}( 501 | {%- for a in args -%} 502 | {%- if not loop.first %}, {% endif %}{{ a.aconv -}} 503 | {% endfor -%} 504 | ) 505 | {%- endset -%} 506 | unsafe { {{ retconv(funccall) }} }{% if not sret %};{% endif %} 507 | } 508 | `; 509 | 510 | const defaultValueMap = { 511 | '"%.0f deg"': t => 'cstr_ptr!("%.0f deg")', 512 | '"%.3f"': t => 'cstr_ptr!("%.3f")', 513 | '"%.6f"': t => 'cstr_ptr!("%.6f")', 514 | '"%d"': t => 'cstr_ptr!("%d")', 515 | '((void *)0)': t => _.startsWith(t, '*mut') ? '::std::ptr::null_mut()' : '::std::ptr::null()', 516 | '+360.0f': t => '360.0', 517 | '-1': t => '-1', 518 | '-1.0f': t => '-1.0', 519 | '-360.0f': t => '-360.0', 520 | '0': t => _.endsWith(t, 'Flags') || t === 'ImGuiCond' ? `${t}::empty()` : '0', 521 | '0.0f': t => '0.0', 522 | '0.5f': t => '0.5', 523 | '1': t => '1', 524 | '1.0f': t => '1.0', 525 | '100': t => '100', 526 | 'FLT_MAX': t => '::std::f32::MAX', 527 | 'ImVec2(-1,0)': t => 'ImVec2{x:-1.0,y:0.0}', 528 | 'ImVec2(0,0)': t => 'ImVec2{x:0.0,y:0.0}', 529 | 'ImVec2(1,1)': t => 'ImVec2{x:1.0,y:1.0}', 530 | 'ImVec4(0,0,0,0)': t => 'ImVec4{x:0.0,y:0.0,z:0.0,w:0.0}', 531 | 'ImVec4(1,1,1,1)': t => 'ImVec4{x:1.0,y:1.0,z:1.0,w:1.0}', 532 | 'false': t => 'false', 533 | 'sizeof(float)': t => '::std::mem::size_of::() as i32', 534 | 'true': t => 'true', 535 | }; 536 | 537 | function indentMultilineString(indent, str) { 538 | return _.join(_.map(_.split(str, '\n'), li => `${indent}${li}`), '\n'); 539 | } 540 | 541 | function convertVarargs(args) { 542 | const n = args.length; 543 | if (n >= 2 && args[n-1].type === undefined && args[n-2].name === 'fmt') { 544 | args.splice(n-2, 2, { 545 | ...args[n-2], 546 | aconv: `cstr_ptr!("%s"), ${args[n-2].name}.as_ptr()`, 547 | }); 548 | } 549 | return args; 550 | } 551 | 552 | const lifetimeNames = 'abcdefghijklmnopqrstuvwxyz'; 553 | 554 | class LifetimeGen { 555 | constructor() { 556 | this.i = 1; 557 | } 558 | next() { 559 | return lifetimeNames[this.i++]; 560 | } 561 | } 562 | 563 | function generateSafe() { 564 | console.log("use super::{cstr_ptr, ImGui};"); 565 | console.log("use nsf_imgui_raw::*;"); 566 | console.log("use std::ffi::CStr;"); 567 | console.log("impl ImGui {"); 568 | const defaultConv = v => v; 569 | const indent = " "; 570 | const typesUsedInAPI = {}; 571 | for (const name of _.keys(definitions)) { 572 | const funcs = definitions[name]; 573 | for (const func of funcs) { 574 | if (func.nonUDT) { // rust works fine with UDTs 575 | continue; 576 | } 577 | if (_.some(func.argsT, a => a.type === 'va_list')) { // not interesting in va_list funcs 578 | continue; 579 | } 580 | const rawName = func.ov_cimguiname || func.cimguiname; 581 | if (!_.startsWith(rawName, 'ig')) { // TODO: not interested in methods just yet 582 | continue; 583 | } 584 | if (blacklistedSafeFuncs[rawName]) { // these are not safe 585 | continue; 586 | } 587 | 588 | const name = snakeCase(rawName.substr(2)); // remove 'ig' prefix and convert_to_snake_case 589 | const ret = func.ret && func.ret !== 'void' ? mapType(func.ret) : undefined; 590 | const args = _.map(func.argsT, a => ({ 591 | name: safeArgName(a.name), 592 | type: a.name === '...' ? undefined : mapType(a.type), 593 | def: func.defaults[a.name], 594 | })); 595 | if (_.every(args, a => a.type === undefined || !!safeTypeMap[a.type]) && (!ret || !!safeRetTypeMap[ret])) { 596 | const lifetimeGen = new LifetimeGen(); 597 | const data = { 598 | name: rawName, 599 | sname: name, 600 | ret, 601 | retconv: safeRetTypeConv[ret] || defaultConv, 602 | sret: safeRetTypeMap[ret] ? safeRetTypeMap[ret]() : undefined, 603 | args: convertVarargs(_.map(args, a => { 604 | const stypef = safeTypeMap[a.type]; 605 | const stype = stypef ? (a.def !== undefined ? `impl Into>` : stypef(lifetimeGen)) : undefined; 606 | const convf = safeArgTypeConv[a.type] || defaultConv; 607 | return { 608 | ...a, 609 | stype, 610 | aconv: a.def ? 611 | `match ${a.name}.into() { Some(v) => ${convf("v")}, None => ${defaultValueMap[a.def](a.type)} }` : 612 | convf(a.name), 613 | }; 614 | })), 615 | }; 616 | data.lifetimes = _.join(_.map(_.range(lifetimeGen.i), i => `'${lifetimeNames[i]}`), ', '); 617 | for (const a of data.args) { 618 | const t = _.startsWith(a.stype, "impl Into a.type), ', ')}) -> ${ret}`); 629 | } 630 | } 631 | } 632 | console.log("} // impl ImGui"); 633 | console.log("pub mod types_used {"); 634 | for (const t of _.keys(typesUsedInAPI).sort()) { 635 | console.log(indent + `pub use nsf_imgui_raw::${t};`); 636 | } 637 | console.log("} // mod types_used"); 638 | } 639 | 640 | //========================================================================================= 641 | //========================================================================================= 642 | //========================================================================================= 643 | 644 | program 645 | .command("raw") 646 | .action(() => { 647 | generateHeader(); 648 | generateTypedefs(); 649 | generateEnums(); 650 | generateStructs(); 651 | generateFuncs(); 652 | }); 653 | 654 | program 655 | .command("safe") 656 | .action(() => { 657 | generateSafe(); 658 | }); 659 | 660 | program.parse(process.argv); -------------------------------------------------------------------------------- /imgui-raw/third-party/imgui/imstb_textedit.h: -------------------------------------------------------------------------------- 1 | // [ImGui] this is a slightly modified version of stb_textedit.h 1.12. Those changes would need to be pushed into nothings/stb 2 | // [ImGui] - 2018-06: fixed undo/redo after pasting large amount of text (over 32 kb). Redo will still fail when undo buffers are exhausted, but text won't be corrupted (see nothings/stb issue #620) 3 | // [ImGui] - 2018-06: fix in stb_textedit_discard_redo (see https://github.com/nothings/stb/issues/321) 4 | // [ImGui] - fixed some minor warnings 5 | 6 | // stb_textedit.h - v1.12 - public domain - Sean Barrett 7 | // Development of this library was sponsored by RAD Game Tools 8 | // 9 | // This C header file implements the guts of a multi-line text-editing 10 | // widget; you implement display, word-wrapping, and low-level string 11 | // insertion/deletion, and stb_textedit will map user inputs into 12 | // insertions & deletions, plus updates to the cursor position, 13 | // selection state, and undo state. 14 | // 15 | // It is intended for use in games and other systems that need to build 16 | // their own custom widgets and which do not have heavy text-editing 17 | // requirements (this library is not recommended for use for editing large 18 | // texts, as its performance does not scale and it has limited undo). 19 | // 20 | // Non-trivial behaviors are modelled after Windows text controls. 21 | // 22 | // 23 | // LICENSE 24 | // 25 | // See end of file for license information. 26 | // 27 | // 28 | // DEPENDENCIES 29 | // 30 | // Uses the C runtime function 'memmove', which you can override 31 | // by defining STB_TEXTEDIT_memmove before the implementation. 32 | // Uses no other functions. Performs no runtime allocations. 33 | // 34 | // 35 | // VERSION HISTORY 36 | // 37 | // 1.12 (2018-01-29) user can change STB_TEXTEDIT_KEYTYPE, fix redo to avoid crash 38 | // 1.11 (2017-03-03) fix HOME on last line, dragging off single-line textfield 39 | // 1.10 (2016-10-25) supress warnings about casting away const with -Wcast-qual 40 | // 1.9 (2016-08-27) customizable move-by-word 41 | // 1.8 (2016-04-02) better keyboard handling when mouse button is down 42 | // 1.7 (2015-09-13) change y range handling in case baseline is non-0 43 | // 1.6 (2015-04-15) allow STB_TEXTEDIT_memmove 44 | // 1.5 (2014-09-10) add support for secondary keys for OS X 45 | // 1.4 (2014-08-17) fix signed/unsigned warnings 46 | // 1.3 (2014-06-19) fix mouse clicking to round to nearest char boundary 47 | // 1.2 (2014-05-27) fix some RAD types that had crept into the new code 48 | // 1.1 (2013-12-15) move-by-word (requires STB_TEXTEDIT_IS_SPACE ) 49 | // 1.0 (2012-07-26) improve documentation, initial public release 50 | // 0.3 (2012-02-24) bugfixes, single-line mode; insert mode 51 | // 0.2 (2011-11-28) fixes to undo/redo 52 | // 0.1 (2010-07-08) initial version 53 | // 54 | // ADDITIONAL CONTRIBUTORS 55 | // 56 | // Ulf Winklemann: move-by-word in 1.1 57 | // Fabian Giesen: secondary key inputs in 1.5 58 | // Martins Mozeiko: STB_TEXTEDIT_memmove in 1.6 59 | // 60 | // Bugfixes: 61 | // Scott Graham 62 | // Daniel Keller 63 | // Omar Cornut 64 | // Dan Thompson 65 | // 66 | // USAGE 67 | // 68 | // This file behaves differently depending on what symbols you define 69 | // before including it. 70 | // 71 | // 72 | // Header-file mode: 73 | // 74 | // If you do not define STB_TEXTEDIT_IMPLEMENTATION before including this, 75 | // it will operate in "header file" mode. In this mode, it declares a 76 | // single public symbol, STB_TexteditState, which encapsulates the current 77 | // state of a text widget (except for the string, which you will store 78 | // separately). 79 | // 80 | // To compile in this mode, you must define STB_TEXTEDIT_CHARTYPE to a 81 | // primitive type that defines a single character (e.g. char, wchar_t, etc). 82 | // 83 | // To save space or increase undo-ability, you can optionally define the 84 | // following things that are used by the undo system: 85 | // 86 | // STB_TEXTEDIT_POSITIONTYPE small int type encoding a valid cursor position 87 | // STB_TEXTEDIT_UNDOSTATECOUNT the number of undo states to allow 88 | // STB_TEXTEDIT_UNDOCHARCOUNT the number of characters to store in the undo buffer 89 | // 90 | // If you don't define these, they are set to permissive types and 91 | // moderate sizes. The undo system does no memory allocations, so 92 | // it grows STB_TexteditState by the worst-case storage which is (in bytes): 93 | // 94 | // [4 + 3 * sizeof(STB_TEXTEDIT_POSITIONTYPE)] * STB_TEXTEDIT_UNDOSTATE_COUNT 95 | // + sizeof(STB_TEXTEDIT_CHARTYPE) * STB_TEXTEDIT_UNDOCHAR_COUNT 96 | // 97 | // 98 | // Implementation mode: 99 | // 100 | // If you define STB_TEXTEDIT_IMPLEMENTATION before including this, it 101 | // will compile the implementation of the text edit widget, depending 102 | // on a large number of symbols which must be defined before the include. 103 | // 104 | // The implementation is defined only as static functions. You will then 105 | // need to provide your own APIs in the same file which will access the 106 | // static functions. 107 | // 108 | // The basic concept is that you provide a "string" object which 109 | // behaves like an array of characters. stb_textedit uses indices to 110 | // refer to positions in the string, implicitly representing positions 111 | // in the displayed textedit. This is true for both plain text and 112 | // rich text; even with rich text stb_truetype interacts with your 113 | // code as if there was an array of all the displayed characters. 114 | // 115 | // Symbols that must be the same in header-file and implementation mode: 116 | // 117 | // STB_TEXTEDIT_CHARTYPE the character type 118 | // STB_TEXTEDIT_POSITIONTYPE small type that is a valid cursor position 119 | // STB_TEXTEDIT_UNDOSTATECOUNT the number of undo states to allow 120 | // STB_TEXTEDIT_UNDOCHARCOUNT the number of characters to store in the undo buffer 121 | // 122 | // Symbols you must define for implementation mode: 123 | // 124 | // STB_TEXTEDIT_STRING the type of object representing a string being edited, 125 | // typically this is a wrapper object with other data you need 126 | // 127 | // STB_TEXTEDIT_STRINGLEN(obj) the length of the string (ideally O(1)) 128 | // STB_TEXTEDIT_LAYOUTROW(&r,obj,n) returns the results of laying out a line of characters 129 | // starting from character #n (see discussion below) 130 | // STB_TEXTEDIT_GETWIDTH(obj,n,i) returns the pixel delta from the xpos of the i'th character 131 | // to the xpos of the i+1'th char for a line of characters 132 | // starting at character #n (i.e. accounts for kerning 133 | // with previous char) 134 | // STB_TEXTEDIT_KEYTOTEXT(k) maps a keyboard input to an insertable character 135 | // (return type is int, -1 means not valid to insert) 136 | // STB_TEXTEDIT_GETCHAR(obj,i) returns the i'th character of obj, 0-based 137 | // STB_TEXTEDIT_NEWLINE the character returned by _GETCHAR() we recognize 138 | // as manually wordwrapping for end-of-line positioning 139 | // 140 | // STB_TEXTEDIT_DELETECHARS(obj,i,n) delete n characters starting at i 141 | // STB_TEXTEDIT_INSERTCHARS(obj,i,c*,n) insert n characters at i (pointed to by STB_TEXTEDIT_CHARTYPE*) 142 | // 143 | // STB_TEXTEDIT_K_SHIFT a power of two that is or'd in to a keyboard input to represent the shift key 144 | // 145 | // STB_TEXTEDIT_K_LEFT keyboard input to move cursor left 146 | // STB_TEXTEDIT_K_RIGHT keyboard input to move cursor right 147 | // STB_TEXTEDIT_K_UP keyboard input to move cursor up 148 | // STB_TEXTEDIT_K_DOWN keyboard input to move cursor down 149 | // STB_TEXTEDIT_K_LINESTART keyboard input to move cursor to start of line // e.g. HOME 150 | // STB_TEXTEDIT_K_LINEEND keyboard input to move cursor to end of line // e.g. END 151 | // STB_TEXTEDIT_K_TEXTSTART keyboard input to move cursor to start of text // e.g. ctrl-HOME 152 | // STB_TEXTEDIT_K_TEXTEND keyboard input to move cursor to end of text // e.g. ctrl-END 153 | // STB_TEXTEDIT_K_DELETE keyboard input to delete selection or character under cursor 154 | // STB_TEXTEDIT_K_BACKSPACE keyboard input to delete selection or character left of cursor 155 | // STB_TEXTEDIT_K_UNDO keyboard input to perform undo 156 | // STB_TEXTEDIT_K_REDO keyboard input to perform redo 157 | // 158 | // Optional: 159 | // STB_TEXTEDIT_K_INSERT keyboard input to toggle insert mode 160 | // STB_TEXTEDIT_IS_SPACE(ch) true if character is whitespace (e.g. 'isspace'), 161 | // required for default WORDLEFT/WORDRIGHT handlers 162 | // STB_TEXTEDIT_MOVEWORDLEFT(obj,i) custom handler for WORDLEFT, returns index to move cursor to 163 | // STB_TEXTEDIT_MOVEWORDRIGHT(obj,i) custom handler for WORDRIGHT, returns index to move cursor to 164 | // STB_TEXTEDIT_K_WORDLEFT keyboard input to move cursor left one word // e.g. ctrl-LEFT 165 | // STB_TEXTEDIT_K_WORDRIGHT keyboard input to move cursor right one word // e.g. ctrl-RIGHT 166 | // STB_TEXTEDIT_K_LINESTART2 secondary keyboard input to move cursor to start of line 167 | // STB_TEXTEDIT_K_LINEEND2 secondary keyboard input to move cursor to end of line 168 | // STB_TEXTEDIT_K_TEXTSTART2 secondary keyboard input to move cursor to start of text 169 | // STB_TEXTEDIT_K_TEXTEND2 secondary keyboard input to move cursor to end of text 170 | // 171 | // Todo: 172 | // STB_TEXTEDIT_K_PGUP keyboard input to move cursor up a page 173 | // STB_TEXTEDIT_K_PGDOWN keyboard input to move cursor down a page 174 | // 175 | // Keyboard input must be encoded as a single integer value; e.g. a character code 176 | // and some bitflags that represent shift states. to simplify the interface, SHIFT must 177 | // be a bitflag, so we can test the shifted state of cursor movements to allow selection, 178 | // i.e. (STB_TEXTED_K_RIGHT|STB_TEXTEDIT_K_SHIFT) should be shifted right-arrow. 179 | // 180 | // You can encode other things, such as CONTROL or ALT, in additional bits, and 181 | // then test for their presence in e.g. STB_TEXTEDIT_K_WORDLEFT. For example, 182 | // my Windows implementations add an additional CONTROL bit, and an additional KEYDOWN 183 | // bit. Then all of the STB_TEXTEDIT_K_ values bitwise-or in the KEYDOWN bit, 184 | // and I pass both WM_KEYDOWN and WM_CHAR events to the "key" function in the 185 | // API below. The control keys will only match WM_KEYDOWN events because of the 186 | // keydown bit I add, and STB_TEXTEDIT_KEYTOTEXT only tests for the KEYDOWN 187 | // bit so it only decodes WM_CHAR events. 188 | // 189 | // STB_TEXTEDIT_LAYOUTROW returns information about the shape of one displayed 190 | // row of characters assuming they start on the i'th character--the width and 191 | // the height and the number of characters consumed. This allows this library 192 | // to traverse the entire layout incrementally. You need to compute word-wrapping 193 | // here. 194 | // 195 | // Each textfield keeps its own insert mode state, which is not how normal 196 | // applications work. To keep an app-wide insert mode, update/copy the 197 | // "insert_mode" field of STB_TexteditState before/after calling API functions. 198 | // 199 | // API 200 | // 201 | // void stb_textedit_initialize_state(STB_TexteditState *state, int is_single_line) 202 | // 203 | // void stb_textedit_click(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, float x, float y) 204 | // void stb_textedit_drag(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, float x, float y) 205 | // int stb_textedit_cut(STB_TEXTEDIT_STRING *str, STB_TexteditState *state) 206 | // int stb_textedit_paste(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, STB_TEXTEDIT_CHARTYPE *text, int len) 207 | // void stb_textedit_key(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, STB_TEXEDIT_KEYTYPE key) 208 | // 209 | // Each of these functions potentially updates the string and updates the 210 | // state. 211 | // 212 | // initialize_state: 213 | // set the textedit state to a known good default state when initially 214 | // constructing the textedit. 215 | // 216 | // click: 217 | // call this with the mouse x,y on a mouse down; it will update the cursor 218 | // and reset the selection start/end to the cursor point. the x,y must 219 | // be relative to the text widget, with (0,0) being the top left. 220 | // 221 | // drag: 222 | // call this with the mouse x,y on a mouse drag/up; it will update the 223 | // cursor and the selection end point 224 | // 225 | // cut: 226 | // call this to delete the current selection; returns true if there was 227 | // one. you should FIRST copy the current selection to the system paste buffer. 228 | // (To copy, just copy the current selection out of the string yourself.) 229 | // 230 | // paste: 231 | // call this to paste text at the current cursor point or over the current 232 | // selection if there is one. 233 | // 234 | // key: 235 | // call this for keyboard inputs sent to the textfield. you can use it 236 | // for "key down" events or for "translated" key events. if you need to 237 | // do both (as in Win32), or distinguish Unicode characters from control 238 | // inputs, set a high bit to distinguish the two; then you can define the 239 | // various definitions like STB_TEXTEDIT_K_LEFT have the is-key-event bit 240 | // set, and make STB_TEXTEDIT_KEYTOCHAR check that the is-key-event bit is 241 | // clear. STB_TEXTEDIT_KEYTYPE defaults to int, but you can #define it to 242 | // anything other type you wante before including. 243 | // 244 | // 245 | // When rendering, you can read the cursor position and selection state from 246 | // the STB_TexteditState. 247 | // 248 | // 249 | // Notes: 250 | // 251 | // This is designed to be usable in IMGUI, so it allows for the possibility of 252 | // running in an IMGUI that has NOT cached the multi-line layout. For this 253 | // reason, it provides an interface that is compatible with computing the 254 | // layout incrementally--we try to make sure we make as few passes through 255 | // as possible. (For example, to locate the mouse pointer in the text, we 256 | // could define functions that return the X and Y positions of characters 257 | // and binary search Y and then X, but if we're doing dynamic layout this 258 | // will run the layout algorithm many times, so instead we manually search 259 | // forward in one pass. Similar logic applies to e.g. up-arrow and 260 | // down-arrow movement.) 261 | // 262 | // If it's run in a widget that *has* cached the layout, then this is less 263 | // efficient, but it's not horrible on modern computers. But you wouldn't 264 | // want to edit million-line files with it. 265 | 266 | 267 | //////////////////////////////////////////////////////////////////////////// 268 | //////////////////////////////////////////////////////////////////////////// 269 | //// 270 | //// Header-file mode 271 | //// 272 | //// 273 | 274 | #ifndef INCLUDE_STB_TEXTEDIT_H 275 | #define INCLUDE_STB_TEXTEDIT_H 276 | 277 | //////////////////////////////////////////////////////////////////////// 278 | // 279 | // STB_TexteditState 280 | // 281 | // Definition of STB_TexteditState which you should store 282 | // per-textfield; it includes cursor position, selection state, 283 | // and undo state. 284 | // 285 | 286 | #ifndef STB_TEXTEDIT_UNDOSTATECOUNT 287 | #define STB_TEXTEDIT_UNDOSTATECOUNT 99 288 | #endif 289 | #ifndef STB_TEXTEDIT_UNDOCHARCOUNT 290 | #define STB_TEXTEDIT_UNDOCHARCOUNT 999 291 | #endif 292 | #ifndef STB_TEXTEDIT_CHARTYPE 293 | #define STB_TEXTEDIT_CHARTYPE int 294 | #endif 295 | #ifndef STB_TEXTEDIT_POSITIONTYPE 296 | #define STB_TEXTEDIT_POSITIONTYPE int 297 | #endif 298 | 299 | typedef struct 300 | { 301 | // private data 302 | STB_TEXTEDIT_POSITIONTYPE where; 303 | STB_TEXTEDIT_POSITIONTYPE insert_length; 304 | STB_TEXTEDIT_POSITIONTYPE delete_length; 305 | int char_storage; 306 | } StbUndoRecord; 307 | 308 | typedef struct 309 | { 310 | // private data 311 | StbUndoRecord undo_rec [STB_TEXTEDIT_UNDOSTATECOUNT]; 312 | STB_TEXTEDIT_CHARTYPE undo_char[STB_TEXTEDIT_UNDOCHARCOUNT]; 313 | short undo_point, redo_point; 314 | int undo_char_point, redo_char_point; 315 | } StbUndoState; 316 | 317 | typedef struct 318 | { 319 | ///////////////////// 320 | // 321 | // public data 322 | // 323 | 324 | int cursor; 325 | // position of the text cursor within the string 326 | 327 | int select_start; // selection start point 328 | int select_end; 329 | // selection start and end point in characters; if equal, no selection. 330 | // note that start may be less than or greater than end (e.g. when 331 | // dragging the mouse, start is where the initial click was, and you 332 | // can drag in either direction) 333 | 334 | unsigned char insert_mode; 335 | // each textfield keeps its own insert mode state. to keep an app-wide 336 | // insert mode, copy this value in/out of the app state 337 | 338 | ///////////////////// 339 | // 340 | // private data 341 | // 342 | unsigned char cursor_at_end_of_line; // not implemented yet 343 | unsigned char initialized; 344 | unsigned char has_preferred_x; 345 | unsigned char single_line; 346 | unsigned char padding1, padding2, padding3; 347 | float preferred_x; // this determines where the cursor up/down tries to seek to along x 348 | StbUndoState undostate; 349 | } STB_TexteditState; 350 | 351 | 352 | //////////////////////////////////////////////////////////////////////// 353 | // 354 | // StbTexteditRow 355 | // 356 | // Result of layout query, used by stb_textedit to determine where 357 | // the text in each row is. 358 | 359 | // result of layout query 360 | typedef struct 361 | { 362 | float x0,x1; // starting x location, end x location (allows for align=right, etc) 363 | float baseline_y_delta; // position of baseline relative to previous row's baseline 364 | float ymin,ymax; // height of row above and below baseline 365 | int num_chars; 366 | } StbTexteditRow; 367 | #endif //INCLUDE_STB_TEXTEDIT_H 368 | 369 | 370 | //////////////////////////////////////////////////////////////////////////// 371 | //////////////////////////////////////////////////////////////////////////// 372 | //// 373 | //// Implementation mode 374 | //// 375 | //// 376 | 377 | 378 | // implementation isn't include-guarded, since it might have indirectly 379 | // included just the "header" portion 380 | #ifdef STB_TEXTEDIT_IMPLEMENTATION 381 | 382 | #ifndef STB_TEXTEDIT_memmove 383 | #include 384 | #define STB_TEXTEDIT_memmove memmove 385 | #endif 386 | 387 | 388 | ///////////////////////////////////////////////////////////////////////////// 389 | // 390 | // Mouse input handling 391 | // 392 | 393 | // traverse the layout to locate the nearest character to a display position 394 | static int stb_text_locate_coord(STB_TEXTEDIT_STRING *str, float x, float y) 395 | { 396 | StbTexteditRow r; 397 | int n = STB_TEXTEDIT_STRINGLEN(str); 398 | float base_y = 0, prev_x; 399 | int i=0, k; 400 | 401 | r.x0 = r.x1 = 0; 402 | r.ymin = r.ymax = 0; 403 | r.num_chars = 0; 404 | 405 | // search rows to find one that straddles 'y' 406 | while (i < n) { 407 | STB_TEXTEDIT_LAYOUTROW(&r, str, i); 408 | if (r.num_chars <= 0) 409 | return n; 410 | 411 | if (i==0 && y < base_y + r.ymin) 412 | return 0; 413 | 414 | if (y < base_y + r.ymax) 415 | break; 416 | 417 | i += r.num_chars; 418 | base_y += r.baseline_y_delta; 419 | } 420 | 421 | // below all text, return 'after' last character 422 | if (i >= n) 423 | return n; 424 | 425 | // check if it's before the beginning of the line 426 | if (x < r.x0) 427 | return i; 428 | 429 | // check if it's before the end of the line 430 | if (x < r.x1) { 431 | // search characters in row for one that straddles 'x' 432 | prev_x = r.x0; 433 | for (k=0; k < r.num_chars; ++k) { 434 | float w = STB_TEXTEDIT_GETWIDTH(str, i, k); 435 | if (x < prev_x+w) { 436 | if (x < prev_x+w/2) 437 | return k+i; 438 | else 439 | return k+i+1; 440 | } 441 | prev_x += w; 442 | } 443 | // shouldn't happen, but if it does, fall through to end-of-line case 444 | } 445 | 446 | // if the last character is a newline, return that. otherwise return 'after' the last character 447 | if (STB_TEXTEDIT_GETCHAR(str, i+r.num_chars-1) == STB_TEXTEDIT_NEWLINE) 448 | return i+r.num_chars-1; 449 | else 450 | return i+r.num_chars; 451 | } 452 | 453 | // API click: on mouse down, move the cursor to the clicked location, and reset the selection 454 | static void stb_textedit_click(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, float x, float y) 455 | { 456 | // In single-line mode, just always make y = 0. This lets the drag keep working if the mouse 457 | // goes off the top or bottom of the text 458 | if( state->single_line ) 459 | { 460 | StbTexteditRow r; 461 | STB_TEXTEDIT_LAYOUTROW(&r, str, 0); 462 | y = r.ymin; 463 | } 464 | 465 | state->cursor = stb_text_locate_coord(str, x, y); 466 | state->select_start = state->cursor; 467 | state->select_end = state->cursor; 468 | state->has_preferred_x = 0; 469 | } 470 | 471 | // API drag: on mouse drag, move the cursor and selection endpoint to the clicked location 472 | static void stb_textedit_drag(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, float x, float y) 473 | { 474 | int p = 0; 475 | 476 | // In single-line mode, just always make y = 0. This lets the drag keep working if the mouse 477 | // goes off the top or bottom of the text 478 | if( state->single_line ) 479 | { 480 | StbTexteditRow r; 481 | STB_TEXTEDIT_LAYOUTROW(&r, str, 0); 482 | y = r.ymin; 483 | } 484 | 485 | if (state->select_start == state->select_end) 486 | state->select_start = state->cursor; 487 | 488 | p = stb_text_locate_coord(str, x, y); 489 | state->cursor = state->select_end = p; 490 | } 491 | 492 | ///////////////////////////////////////////////////////////////////////////// 493 | // 494 | // Keyboard input handling 495 | // 496 | 497 | // forward declarations 498 | static void stb_text_undo(STB_TEXTEDIT_STRING *str, STB_TexteditState *state); 499 | static void stb_text_redo(STB_TEXTEDIT_STRING *str, STB_TexteditState *state); 500 | static void stb_text_makeundo_delete(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int length); 501 | static void stb_text_makeundo_insert(STB_TexteditState *state, int where, int length); 502 | static void stb_text_makeundo_replace(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int old_length, int new_length); 503 | 504 | typedef struct 505 | { 506 | float x,y; // position of n'th character 507 | float height; // height of line 508 | int first_char, length; // first char of row, and length 509 | int prev_first; // first char of previous row 510 | } StbFindState; 511 | 512 | // find the x/y location of a character, and remember info about the previous row in 513 | // case we get a move-up event (for page up, we'll have to rescan) 514 | static void stb_textedit_find_charpos(StbFindState *find, STB_TEXTEDIT_STRING *str, int n, int single_line) 515 | { 516 | StbTexteditRow r; 517 | int prev_start = 0; 518 | int z = STB_TEXTEDIT_STRINGLEN(str); 519 | int i=0, first; 520 | 521 | if (n == z) { 522 | // if it's at the end, then find the last line -- simpler than trying to 523 | // explicitly handle this case in the regular code 524 | if (single_line) { 525 | STB_TEXTEDIT_LAYOUTROW(&r, str, 0); 526 | find->y = 0; 527 | find->first_char = 0; 528 | find->length = z; 529 | find->height = r.ymax - r.ymin; 530 | find->x = r.x1; 531 | } else { 532 | find->y = 0; 533 | find->x = 0; 534 | find->height = 1; 535 | while (i < z) { 536 | STB_TEXTEDIT_LAYOUTROW(&r, str, i); 537 | prev_start = i; 538 | i += r.num_chars; 539 | } 540 | find->first_char = i; 541 | find->length = 0; 542 | find->prev_first = prev_start; 543 | } 544 | return; 545 | } 546 | 547 | // search rows to find the one that straddles character n 548 | find->y = 0; 549 | 550 | for(;;) { 551 | STB_TEXTEDIT_LAYOUTROW(&r, str, i); 552 | if (n < i + r.num_chars) 553 | break; 554 | prev_start = i; 555 | i += r.num_chars; 556 | find->y += r.baseline_y_delta; 557 | } 558 | 559 | find->first_char = first = i; 560 | find->length = r.num_chars; 561 | find->height = r.ymax - r.ymin; 562 | find->prev_first = prev_start; 563 | 564 | // now scan to find xpos 565 | find->x = r.x0; 566 | i = 0; 567 | for (i=0; first+i < n; ++i) 568 | find->x += STB_TEXTEDIT_GETWIDTH(str, first, i); 569 | } 570 | 571 | #define STB_TEXT_HAS_SELECTION(s) ((s)->select_start != (s)->select_end) 572 | 573 | // make the selection/cursor state valid if client altered the string 574 | static void stb_textedit_clamp(STB_TEXTEDIT_STRING *str, STB_TexteditState *state) 575 | { 576 | int n = STB_TEXTEDIT_STRINGLEN(str); 577 | if (STB_TEXT_HAS_SELECTION(state)) { 578 | if (state->select_start > n) state->select_start = n; 579 | if (state->select_end > n) state->select_end = n; 580 | // if clamping forced them to be equal, move the cursor to match 581 | if (state->select_start == state->select_end) 582 | state->cursor = state->select_start; 583 | } 584 | if (state->cursor > n) state->cursor = n; 585 | } 586 | 587 | // delete characters while updating undo 588 | static void stb_textedit_delete(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int len) 589 | { 590 | stb_text_makeundo_delete(str, state, where, len); 591 | STB_TEXTEDIT_DELETECHARS(str, where, len); 592 | state->has_preferred_x = 0; 593 | } 594 | 595 | // delete the section 596 | static void stb_textedit_delete_selection(STB_TEXTEDIT_STRING *str, STB_TexteditState *state) 597 | { 598 | stb_textedit_clamp(str, state); 599 | if (STB_TEXT_HAS_SELECTION(state)) { 600 | if (state->select_start < state->select_end) { 601 | stb_textedit_delete(str, state, state->select_start, state->select_end - state->select_start); 602 | state->select_end = state->cursor = state->select_start; 603 | } else { 604 | stb_textedit_delete(str, state, state->select_end, state->select_start - state->select_end); 605 | state->select_start = state->cursor = state->select_end; 606 | } 607 | state->has_preferred_x = 0; 608 | } 609 | } 610 | 611 | // canoncialize the selection so start <= end 612 | static void stb_textedit_sortselection(STB_TexteditState *state) 613 | { 614 | if (state->select_end < state->select_start) { 615 | int temp = state->select_end; 616 | state->select_end = state->select_start; 617 | state->select_start = temp; 618 | } 619 | } 620 | 621 | // move cursor to first character of selection 622 | static void stb_textedit_move_to_first(STB_TexteditState *state) 623 | { 624 | if (STB_TEXT_HAS_SELECTION(state)) { 625 | stb_textedit_sortselection(state); 626 | state->cursor = state->select_start; 627 | state->select_end = state->select_start; 628 | state->has_preferred_x = 0; 629 | } 630 | } 631 | 632 | // move cursor to last character of selection 633 | static void stb_textedit_move_to_last(STB_TEXTEDIT_STRING *str, STB_TexteditState *state) 634 | { 635 | if (STB_TEXT_HAS_SELECTION(state)) { 636 | stb_textedit_sortselection(state); 637 | stb_textedit_clamp(str, state); 638 | state->cursor = state->select_end; 639 | state->select_start = state->select_end; 640 | state->has_preferred_x = 0; 641 | } 642 | } 643 | 644 | #ifdef STB_TEXTEDIT_IS_SPACE 645 | static int is_word_boundary( STB_TEXTEDIT_STRING *str, int idx ) 646 | { 647 | return idx > 0 ? (STB_TEXTEDIT_IS_SPACE( STB_TEXTEDIT_GETCHAR(str,idx-1) ) && !STB_TEXTEDIT_IS_SPACE( STB_TEXTEDIT_GETCHAR(str, idx) ) ) : 1; 648 | } 649 | 650 | #ifndef STB_TEXTEDIT_MOVEWORDLEFT 651 | static int stb_textedit_move_to_word_previous( STB_TEXTEDIT_STRING *str, int c ) 652 | { 653 | --c; // always move at least one character 654 | while( c >= 0 && !is_word_boundary( str, c ) ) 655 | --c; 656 | 657 | if( c < 0 ) 658 | c = 0; 659 | 660 | return c; 661 | } 662 | #define STB_TEXTEDIT_MOVEWORDLEFT stb_textedit_move_to_word_previous 663 | #endif 664 | 665 | #ifndef STB_TEXTEDIT_MOVEWORDRIGHT 666 | static int stb_textedit_move_to_word_next( STB_TEXTEDIT_STRING *str, int c ) 667 | { 668 | const int len = STB_TEXTEDIT_STRINGLEN(str); 669 | ++c; // always move at least one character 670 | while( c < len && !is_word_boundary( str, c ) ) 671 | ++c; 672 | 673 | if( c > len ) 674 | c = len; 675 | 676 | return c; 677 | } 678 | #define STB_TEXTEDIT_MOVEWORDRIGHT stb_textedit_move_to_word_next 679 | #endif 680 | 681 | #endif 682 | 683 | // update selection and cursor to match each other 684 | static void stb_textedit_prep_selection_at_cursor(STB_TexteditState *state) 685 | { 686 | if (!STB_TEXT_HAS_SELECTION(state)) 687 | state->select_start = state->select_end = state->cursor; 688 | else 689 | state->cursor = state->select_end; 690 | } 691 | 692 | // API cut: delete selection 693 | static int stb_textedit_cut(STB_TEXTEDIT_STRING *str, STB_TexteditState *state) 694 | { 695 | if (STB_TEXT_HAS_SELECTION(state)) { 696 | stb_textedit_delete_selection(str,state); // implicity clamps 697 | state->has_preferred_x = 0; 698 | return 1; 699 | } 700 | return 0; 701 | } 702 | 703 | // API paste: replace existing selection with passed-in text 704 | static int stb_textedit_paste_internal(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, STB_TEXTEDIT_CHARTYPE *text, int len) 705 | { 706 | // if there's a selection, the paste should delete it 707 | stb_textedit_clamp(str, state); 708 | stb_textedit_delete_selection(str,state); 709 | // try to insert the characters 710 | if (STB_TEXTEDIT_INSERTCHARS(str, state->cursor, text, len)) { 711 | stb_text_makeundo_insert(state, state->cursor, len); 712 | state->cursor += len; 713 | state->has_preferred_x = 0; 714 | return 1; 715 | } 716 | // remove the undo since we didn't actually insert the characters 717 | if (state->undostate.undo_point) 718 | --state->undostate.undo_point; 719 | return 0; 720 | } 721 | 722 | #ifndef STB_TEXTEDIT_KEYTYPE 723 | #define STB_TEXTEDIT_KEYTYPE int 724 | #endif 725 | 726 | // API key: process a keyboard input 727 | static void stb_textedit_key(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, STB_TEXTEDIT_KEYTYPE key) 728 | { 729 | retry: 730 | switch (key) { 731 | default: { 732 | int c = STB_TEXTEDIT_KEYTOTEXT(key); 733 | if (c > 0) { 734 | STB_TEXTEDIT_CHARTYPE ch = (STB_TEXTEDIT_CHARTYPE) c; 735 | 736 | // can't add newline in single-line mode 737 | if (c == '\n' && state->single_line) 738 | break; 739 | 740 | if (state->insert_mode && !STB_TEXT_HAS_SELECTION(state) && state->cursor < STB_TEXTEDIT_STRINGLEN(str)) { 741 | stb_text_makeundo_replace(str, state, state->cursor, 1, 1); 742 | STB_TEXTEDIT_DELETECHARS(str, state->cursor, 1); 743 | if (STB_TEXTEDIT_INSERTCHARS(str, state->cursor, &ch, 1)) { 744 | ++state->cursor; 745 | state->has_preferred_x = 0; 746 | } 747 | } else { 748 | stb_textedit_delete_selection(str,state); // implicity clamps 749 | if (STB_TEXTEDIT_INSERTCHARS(str, state->cursor, &ch, 1)) { 750 | stb_text_makeundo_insert(state, state->cursor, 1); 751 | ++state->cursor; 752 | state->has_preferred_x = 0; 753 | } 754 | } 755 | } 756 | break; 757 | } 758 | 759 | #ifdef STB_TEXTEDIT_K_INSERT 760 | case STB_TEXTEDIT_K_INSERT: 761 | state->insert_mode = !state->insert_mode; 762 | break; 763 | #endif 764 | 765 | case STB_TEXTEDIT_K_UNDO: 766 | stb_text_undo(str, state); 767 | state->has_preferred_x = 0; 768 | break; 769 | 770 | case STB_TEXTEDIT_K_REDO: 771 | stb_text_redo(str, state); 772 | state->has_preferred_x = 0; 773 | break; 774 | 775 | case STB_TEXTEDIT_K_LEFT: 776 | // if currently there's a selection, move cursor to start of selection 777 | if (STB_TEXT_HAS_SELECTION(state)) 778 | stb_textedit_move_to_first(state); 779 | else 780 | if (state->cursor > 0) 781 | --state->cursor; 782 | state->has_preferred_x = 0; 783 | break; 784 | 785 | case STB_TEXTEDIT_K_RIGHT: 786 | // if currently there's a selection, move cursor to end of selection 787 | if (STB_TEXT_HAS_SELECTION(state)) 788 | stb_textedit_move_to_last(str, state); 789 | else 790 | ++state->cursor; 791 | stb_textedit_clamp(str, state); 792 | state->has_preferred_x = 0; 793 | break; 794 | 795 | case STB_TEXTEDIT_K_LEFT | STB_TEXTEDIT_K_SHIFT: 796 | stb_textedit_clamp(str, state); 797 | stb_textedit_prep_selection_at_cursor(state); 798 | // move selection left 799 | if (state->select_end > 0) 800 | --state->select_end; 801 | state->cursor = state->select_end; 802 | state->has_preferred_x = 0; 803 | break; 804 | 805 | #ifdef STB_TEXTEDIT_MOVEWORDLEFT 806 | case STB_TEXTEDIT_K_WORDLEFT: 807 | if (STB_TEXT_HAS_SELECTION(state)) 808 | stb_textedit_move_to_first(state); 809 | else { 810 | state->cursor = STB_TEXTEDIT_MOVEWORDLEFT(str, state->cursor); 811 | stb_textedit_clamp( str, state ); 812 | } 813 | break; 814 | 815 | case STB_TEXTEDIT_K_WORDLEFT | STB_TEXTEDIT_K_SHIFT: 816 | if( !STB_TEXT_HAS_SELECTION( state ) ) 817 | stb_textedit_prep_selection_at_cursor(state); 818 | 819 | state->cursor = STB_TEXTEDIT_MOVEWORDLEFT(str, state->cursor); 820 | state->select_end = state->cursor; 821 | 822 | stb_textedit_clamp( str, state ); 823 | break; 824 | #endif 825 | 826 | #ifdef STB_TEXTEDIT_MOVEWORDRIGHT 827 | case STB_TEXTEDIT_K_WORDRIGHT: 828 | if (STB_TEXT_HAS_SELECTION(state)) 829 | stb_textedit_move_to_last(str, state); 830 | else { 831 | state->cursor = STB_TEXTEDIT_MOVEWORDRIGHT(str, state->cursor); 832 | stb_textedit_clamp( str, state ); 833 | } 834 | break; 835 | 836 | case STB_TEXTEDIT_K_WORDRIGHT | STB_TEXTEDIT_K_SHIFT: 837 | if( !STB_TEXT_HAS_SELECTION( state ) ) 838 | stb_textedit_prep_selection_at_cursor(state); 839 | 840 | state->cursor = STB_TEXTEDIT_MOVEWORDRIGHT(str, state->cursor); 841 | state->select_end = state->cursor; 842 | 843 | stb_textedit_clamp( str, state ); 844 | break; 845 | #endif 846 | 847 | case STB_TEXTEDIT_K_RIGHT | STB_TEXTEDIT_K_SHIFT: 848 | stb_textedit_prep_selection_at_cursor(state); 849 | // move selection right 850 | ++state->select_end; 851 | stb_textedit_clamp(str, state); 852 | state->cursor = state->select_end; 853 | state->has_preferred_x = 0; 854 | break; 855 | 856 | case STB_TEXTEDIT_K_DOWN: 857 | case STB_TEXTEDIT_K_DOWN | STB_TEXTEDIT_K_SHIFT: { 858 | StbFindState find; 859 | StbTexteditRow row; 860 | int i, sel = (key & STB_TEXTEDIT_K_SHIFT) != 0; 861 | 862 | if (state->single_line) { 863 | // on windows, up&down in single-line behave like left&right 864 | key = STB_TEXTEDIT_K_RIGHT | (key & STB_TEXTEDIT_K_SHIFT); 865 | goto retry; 866 | } 867 | 868 | if (sel) 869 | stb_textedit_prep_selection_at_cursor(state); 870 | else if (STB_TEXT_HAS_SELECTION(state)) 871 | stb_textedit_move_to_last(str,state); 872 | 873 | // compute current position of cursor point 874 | stb_textedit_clamp(str, state); 875 | stb_textedit_find_charpos(&find, str, state->cursor, state->single_line); 876 | 877 | // now find character position down a row 878 | if (find.length) { 879 | float goal_x = state->has_preferred_x ? state->preferred_x : find.x; 880 | float x; 881 | int start = find.first_char + find.length; 882 | state->cursor = start; 883 | STB_TEXTEDIT_LAYOUTROW(&row, str, state->cursor); 884 | x = row.x0; 885 | for (i=0; i < row.num_chars; ++i) { 886 | float dx = STB_TEXTEDIT_GETWIDTH(str, start, i); 887 | #ifdef STB_TEXTEDIT_GETWIDTH_NEWLINE 888 | if (dx == STB_TEXTEDIT_GETWIDTH_NEWLINE) 889 | break; 890 | #endif 891 | x += dx; 892 | if (x > goal_x) 893 | break; 894 | ++state->cursor; 895 | } 896 | stb_textedit_clamp(str, state); 897 | 898 | state->has_preferred_x = 1; 899 | state->preferred_x = goal_x; 900 | 901 | if (sel) 902 | state->select_end = state->cursor; 903 | } 904 | break; 905 | } 906 | 907 | case STB_TEXTEDIT_K_UP: 908 | case STB_TEXTEDIT_K_UP | STB_TEXTEDIT_K_SHIFT: { 909 | StbFindState find; 910 | StbTexteditRow row; 911 | int i, sel = (key & STB_TEXTEDIT_K_SHIFT) != 0; 912 | 913 | if (state->single_line) { 914 | // on windows, up&down become left&right 915 | key = STB_TEXTEDIT_K_LEFT | (key & STB_TEXTEDIT_K_SHIFT); 916 | goto retry; 917 | } 918 | 919 | if (sel) 920 | stb_textedit_prep_selection_at_cursor(state); 921 | else if (STB_TEXT_HAS_SELECTION(state)) 922 | stb_textedit_move_to_first(state); 923 | 924 | // compute current position of cursor point 925 | stb_textedit_clamp(str, state); 926 | stb_textedit_find_charpos(&find, str, state->cursor, state->single_line); 927 | 928 | // can only go up if there's a previous row 929 | if (find.prev_first != find.first_char) { 930 | // now find character position up a row 931 | float goal_x = state->has_preferred_x ? state->preferred_x : find.x; 932 | float x; 933 | state->cursor = find.prev_first; 934 | STB_TEXTEDIT_LAYOUTROW(&row, str, state->cursor); 935 | x = row.x0; 936 | for (i=0; i < row.num_chars; ++i) { 937 | float dx = STB_TEXTEDIT_GETWIDTH(str, find.prev_first, i); 938 | #ifdef STB_TEXTEDIT_GETWIDTH_NEWLINE 939 | if (dx == STB_TEXTEDIT_GETWIDTH_NEWLINE) 940 | break; 941 | #endif 942 | x += dx; 943 | if (x > goal_x) 944 | break; 945 | ++state->cursor; 946 | } 947 | stb_textedit_clamp(str, state); 948 | 949 | state->has_preferred_x = 1; 950 | state->preferred_x = goal_x; 951 | 952 | if (sel) 953 | state->select_end = state->cursor; 954 | } 955 | break; 956 | } 957 | 958 | case STB_TEXTEDIT_K_DELETE: 959 | case STB_TEXTEDIT_K_DELETE | STB_TEXTEDIT_K_SHIFT: 960 | if (STB_TEXT_HAS_SELECTION(state)) 961 | stb_textedit_delete_selection(str, state); 962 | else { 963 | int n = STB_TEXTEDIT_STRINGLEN(str); 964 | if (state->cursor < n) 965 | stb_textedit_delete(str, state, state->cursor, 1); 966 | } 967 | state->has_preferred_x = 0; 968 | break; 969 | 970 | case STB_TEXTEDIT_K_BACKSPACE: 971 | case STB_TEXTEDIT_K_BACKSPACE | STB_TEXTEDIT_K_SHIFT: 972 | if (STB_TEXT_HAS_SELECTION(state)) 973 | stb_textedit_delete_selection(str, state); 974 | else { 975 | stb_textedit_clamp(str, state); 976 | if (state->cursor > 0) { 977 | stb_textedit_delete(str, state, state->cursor-1, 1); 978 | --state->cursor; 979 | } 980 | } 981 | state->has_preferred_x = 0; 982 | break; 983 | 984 | #ifdef STB_TEXTEDIT_K_TEXTSTART2 985 | case STB_TEXTEDIT_K_TEXTSTART2: 986 | #endif 987 | case STB_TEXTEDIT_K_TEXTSTART: 988 | state->cursor = state->select_start = state->select_end = 0; 989 | state->has_preferred_x = 0; 990 | break; 991 | 992 | #ifdef STB_TEXTEDIT_K_TEXTEND2 993 | case STB_TEXTEDIT_K_TEXTEND2: 994 | #endif 995 | case STB_TEXTEDIT_K_TEXTEND: 996 | state->cursor = STB_TEXTEDIT_STRINGLEN(str); 997 | state->select_start = state->select_end = 0; 998 | state->has_preferred_x = 0; 999 | break; 1000 | 1001 | #ifdef STB_TEXTEDIT_K_TEXTSTART2 1002 | case STB_TEXTEDIT_K_TEXTSTART2 | STB_TEXTEDIT_K_SHIFT: 1003 | #endif 1004 | case STB_TEXTEDIT_K_TEXTSTART | STB_TEXTEDIT_K_SHIFT: 1005 | stb_textedit_prep_selection_at_cursor(state); 1006 | state->cursor = state->select_end = 0; 1007 | state->has_preferred_x = 0; 1008 | break; 1009 | 1010 | #ifdef STB_TEXTEDIT_K_TEXTEND2 1011 | case STB_TEXTEDIT_K_TEXTEND2 | STB_TEXTEDIT_K_SHIFT: 1012 | #endif 1013 | case STB_TEXTEDIT_K_TEXTEND | STB_TEXTEDIT_K_SHIFT: 1014 | stb_textedit_prep_selection_at_cursor(state); 1015 | state->cursor = state->select_end = STB_TEXTEDIT_STRINGLEN(str); 1016 | state->has_preferred_x = 0; 1017 | break; 1018 | 1019 | 1020 | #ifdef STB_TEXTEDIT_K_LINESTART2 1021 | case STB_TEXTEDIT_K_LINESTART2: 1022 | #endif 1023 | case STB_TEXTEDIT_K_LINESTART: 1024 | stb_textedit_clamp(str, state); 1025 | stb_textedit_move_to_first(state); 1026 | if (state->single_line) 1027 | state->cursor = 0; 1028 | else while (state->cursor > 0 && STB_TEXTEDIT_GETCHAR(str, state->cursor-1) != STB_TEXTEDIT_NEWLINE) 1029 | --state->cursor; 1030 | state->has_preferred_x = 0; 1031 | break; 1032 | 1033 | #ifdef STB_TEXTEDIT_K_LINEEND2 1034 | case STB_TEXTEDIT_K_LINEEND2: 1035 | #endif 1036 | case STB_TEXTEDIT_K_LINEEND: { 1037 | int n = STB_TEXTEDIT_STRINGLEN(str); 1038 | stb_textedit_clamp(str, state); 1039 | stb_textedit_move_to_first(state); 1040 | if (state->single_line) 1041 | state->cursor = n; 1042 | else while (state->cursor < n && STB_TEXTEDIT_GETCHAR(str, state->cursor) != STB_TEXTEDIT_NEWLINE) 1043 | ++state->cursor; 1044 | state->has_preferred_x = 0; 1045 | break; 1046 | } 1047 | 1048 | #ifdef STB_TEXTEDIT_K_LINESTART2 1049 | case STB_TEXTEDIT_K_LINESTART2 | STB_TEXTEDIT_K_SHIFT: 1050 | #endif 1051 | case STB_TEXTEDIT_K_LINESTART | STB_TEXTEDIT_K_SHIFT: 1052 | stb_textedit_clamp(str, state); 1053 | stb_textedit_prep_selection_at_cursor(state); 1054 | if (state->single_line) 1055 | state->cursor = 0; 1056 | else while (state->cursor > 0 && STB_TEXTEDIT_GETCHAR(str, state->cursor-1) != STB_TEXTEDIT_NEWLINE) 1057 | --state->cursor; 1058 | state->select_end = state->cursor; 1059 | state->has_preferred_x = 0; 1060 | break; 1061 | 1062 | #ifdef STB_TEXTEDIT_K_LINEEND2 1063 | case STB_TEXTEDIT_K_LINEEND2 | STB_TEXTEDIT_K_SHIFT: 1064 | #endif 1065 | case STB_TEXTEDIT_K_LINEEND | STB_TEXTEDIT_K_SHIFT: { 1066 | int n = STB_TEXTEDIT_STRINGLEN(str); 1067 | stb_textedit_clamp(str, state); 1068 | stb_textedit_prep_selection_at_cursor(state); 1069 | if (state->single_line) 1070 | state->cursor = n; 1071 | else while (state->cursor < n && STB_TEXTEDIT_GETCHAR(str, state->cursor) != STB_TEXTEDIT_NEWLINE) 1072 | ++state->cursor; 1073 | state->select_end = state->cursor; 1074 | state->has_preferred_x = 0; 1075 | break; 1076 | } 1077 | 1078 | // @TODO: 1079 | // STB_TEXTEDIT_K_PGUP - move cursor up a page 1080 | // STB_TEXTEDIT_K_PGDOWN - move cursor down a page 1081 | } 1082 | } 1083 | 1084 | ///////////////////////////////////////////////////////////////////////////// 1085 | // 1086 | // Undo processing 1087 | // 1088 | // @OPTIMIZE: the undo/redo buffer should be circular 1089 | 1090 | static void stb_textedit_flush_redo(StbUndoState *state) 1091 | { 1092 | state->redo_point = STB_TEXTEDIT_UNDOSTATECOUNT; 1093 | state->redo_char_point = STB_TEXTEDIT_UNDOCHARCOUNT; 1094 | } 1095 | 1096 | // discard the oldest entry in the undo list 1097 | static void stb_textedit_discard_undo(StbUndoState *state) 1098 | { 1099 | if (state->undo_point > 0) { 1100 | // if the 0th undo state has characters, clean those up 1101 | if (state->undo_rec[0].char_storage >= 0) { 1102 | int n = state->undo_rec[0].insert_length, i; 1103 | // delete n characters from all other records 1104 | state->undo_char_point -= n; 1105 | STB_TEXTEDIT_memmove(state->undo_char, state->undo_char + n, (size_t) (state->undo_char_point*sizeof(STB_TEXTEDIT_CHARTYPE))); 1106 | for (i=0; i < state->undo_point; ++i) 1107 | if (state->undo_rec[i].char_storage >= 0) 1108 | state->undo_rec[i].char_storage -= n; // @OPTIMIZE: get rid of char_storage and infer it 1109 | } 1110 | --state->undo_point; 1111 | STB_TEXTEDIT_memmove(state->undo_rec, state->undo_rec+1, (size_t) (state->undo_point*sizeof(state->undo_rec[0]))); 1112 | } 1113 | } 1114 | 1115 | // discard the oldest entry in the redo list--it's bad if this 1116 | // ever happens, but because undo & redo have to store the actual 1117 | // characters in different cases, the redo character buffer can 1118 | // fill up even though the undo buffer didn't 1119 | static void stb_textedit_discard_redo(StbUndoState *state) 1120 | { 1121 | int k = STB_TEXTEDIT_UNDOSTATECOUNT-1; 1122 | 1123 | if (state->redo_point <= k) { 1124 | // if the k'th undo state has characters, clean those up 1125 | if (state->undo_rec[k].char_storage >= 0) { 1126 | int n = state->undo_rec[k].insert_length, i; 1127 | // move the remaining redo character data to the end of the buffer 1128 | state->redo_char_point += n; 1129 | STB_TEXTEDIT_memmove(state->undo_char + state->redo_char_point, state->undo_char + state->redo_char_point-n, (size_t) ((STB_TEXTEDIT_UNDOCHARCOUNT - state->redo_char_point)*sizeof(STB_TEXTEDIT_CHARTYPE))); 1130 | // adjust the position of all the other records to account for above memmove 1131 | for (i=state->redo_point; i < k; ++i) 1132 | if (state->undo_rec[i].char_storage >= 0) 1133 | state->undo_rec[i].char_storage += n; 1134 | } 1135 | // now move all the redo records towards the end of the buffer; the first one is at 'redo_point' 1136 | STB_TEXTEDIT_memmove(state->undo_rec + state->redo_point+1, state->undo_rec + state->redo_point, (size_t) ((STB_TEXTEDIT_UNDOSTATECOUNT - state->redo_point)*sizeof(state->undo_rec[0]))); 1137 | // now move redo_point to point to the new one 1138 | ++state->redo_point; 1139 | } 1140 | } 1141 | 1142 | static StbUndoRecord *stb_text_create_undo_record(StbUndoState *state, int numchars) 1143 | { 1144 | // any time we create a new undo record, we discard redo 1145 | stb_textedit_flush_redo(state); 1146 | 1147 | // if we have no free records, we have to make room, by sliding the 1148 | // existing records down 1149 | if (state->undo_point == STB_TEXTEDIT_UNDOSTATECOUNT) 1150 | stb_textedit_discard_undo(state); 1151 | 1152 | // if the characters to store won't possibly fit in the buffer, we can't undo 1153 | if (numchars > STB_TEXTEDIT_UNDOCHARCOUNT) { 1154 | state->undo_point = 0; 1155 | state->undo_char_point = 0; 1156 | return NULL; 1157 | } 1158 | 1159 | // if we don't have enough free characters in the buffer, we have to make room 1160 | while (state->undo_char_point + numchars > STB_TEXTEDIT_UNDOCHARCOUNT) 1161 | stb_textedit_discard_undo(state); 1162 | 1163 | return &state->undo_rec[state->undo_point++]; 1164 | } 1165 | 1166 | static STB_TEXTEDIT_CHARTYPE *stb_text_createundo(StbUndoState *state, int pos, int insert_len, int delete_len) 1167 | { 1168 | StbUndoRecord *r = stb_text_create_undo_record(state, insert_len); 1169 | if (r == NULL) 1170 | return NULL; 1171 | 1172 | r->where = pos; 1173 | r->insert_length = (STB_TEXTEDIT_POSITIONTYPE) insert_len; 1174 | r->delete_length = (STB_TEXTEDIT_POSITIONTYPE) delete_len; 1175 | 1176 | if (insert_len == 0) { 1177 | r->char_storage = -1; 1178 | return NULL; 1179 | } else { 1180 | r->char_storage = state->undo_char_point; 1181 | state->undo_char_point += insert_len; 1182 | return &state->undo_char[r->char_storage]; 1183 | } 1184 | } 1185 | 1186 | static void stb_text_undo(STB_TEXTEDIT_STRING *str, STB_TexteditState *state) 1187 | { 1188 | StbUndoState *s = &state->undostate; 1189 | StbUndoRecord u, *r; 1190 | if (s->undo_point == 0) 1191 | return; 1192 | 1193 | // we need to do two things: apply the undo record, and create a redo record 1194 | u = s->undo_rec[s->undo_point-1]; 1195 | r = &s->undo_rec[s->redo_point-1]; 1196 | r->char_storage = -1; 1197 | 1198 | r->insert_length = u.delete_length; 1199 | r->delete_length = u.insert_length; 1200 | r->where = u.where; 1201 | 1202 | if (u.delete_length) { 1203 | // if the undo record says to delete characters, then the redo record will 1204 | // need to re-insert the characters that get deleted, so we need to store 1205 | // them. 1206 | 1207 | // there are three cases: 1208 | // there's enough room to store the characters 1209 | // characters stored for *redoing* don't leave room for redo 1210 | // characters stored for *undoing* don't leave room for redo 1211 | // if the last is true, we have to bail 1212 | 1213 | if (s->undo_char_point + u.delete_length >= STB_TEXTEDIT_UNDOCHARCOUNT) { 1214 | // the undo records take up too much character space; there's no space to store the redo characters 1215 | r->insert_length = 0; 1216 | } else { 1217 | int i; 1218 | 1219 | // there's definitely room to store the characters eventually 1220 | while (s->undo_char_point + u.delete_length > s->redo_char_point) { 1221 | // should never happen: 1222 | if (s->redo_point == STB_TEXTEDIT_UNDOSTATECOUNT) 1223 | return; 1224 | // there's currently not enough room, so discard a redo record 1225 | stb_textedit_discard_redo(s); 1226 | } 1227 | r = &s->undo_rec[s->redo_point-1]; 1228 | 1229 | r->char_storage = s->redo_char_point - u.delete_length; 1230 | s->redo_char_point = s->redo_char_point - u.delete_length; 1231 | 1232 | // now save the characters 1233 | for (i=0; i < u.delete_length; ++i) 1234 | s->undo_char[r->char_storage + i] = STB_TEXTEDIT_GETCHAR(str, u.where + i); 1235 | } 1236 | 1237 | // now we can carry out the deletion 1238 | STB_TEXTEDIT_DELETECHARS(str, u.where, u.delete_length); 1239 | } 1240 | 1241 | // check type of recorded action: 1242 | if (u.insert_length) { 1243 | // easy case: was a deletion, so we need to insert n characters 1244 | STB_TEXTEDIT_INSERTCHARS(str, u.where, &s->undo_char[u.char_storage], u.insert_length); 1245 | s->undo_char_point -= u.insert_length; 1246 | } 1247 | 1248 | state->cursor = u.where + u.insert_length; 1249 | 1250 | s->undo_point--; 1251 | s->redo_point--; 1252 | } 1253 | 1254 | static void stb_text_redo(STB_TEXTEDIT_STRING *str, STB_TexteditState *state) 1255 | { 1256 | StbUndoState *s = &state->undostate; 1257 | StbUndoRecord *u, r; 1258 | if (s->redo_point == STB_TEXTEDIT_UNDOSTATECOUNT) 1259 | return; 1260 | 1261 | // we need to do two things: apply the redo record, and create an undo record 1262 | u = &s->undo_rec[s->undo_point]; 1263 | r = s->undo_rec[s->redo_point]; 1264 | 1265 | // we KNOW there must be room for the undo record, because the redo record 1266 | // was derived from an undo record 1267 | 1268 | u->delete_length = r.insert_length; 1269 | u->insert_length = r.delete_length; 1270 | u->where = r.where; 1271 | u->char_storage = -1; 1272 | 1273 | if (r.delete_length) { 1274 | // the redo record requires us to delete characters, so the undo record 1275 | // needs to store the characters 1276 | 1277 | if (s->undo_char_point + u->insert_length > s->redo_char_point) { 1278 | u->insert_length = 0; 1279 | u->delete_length = 0; 1280 | } else { 1281 | int i; 1282 | u->char_storage = s->undo_char_point; 1283 | s->undo_char_point = s->undo_char_point + u->insert_length; 1284 | 1285 | // now save the characters 1286 | for (i=0; i < u->insert_length; ++i) 1287 | s->undo_char[u->char_storage + i] = STB_TEXTEDIT_GETCHAR(str, u->where + i); 1288 | } 1289 | 1290 | STB_TEXTEDIT_DELETECHARS(str, r.where, r.delete_length); 1291 | } 1292 | 1293 | if (r.insert_length) { 1294 | // easy case: need to insert n characters 1295 | STB_TEXTEDIT_INSERTCHARS(str, r.where, &s->undo_char[r.char_storage], r.insert_length); 1296 | s->redo_char_point += r.insert_length; 1297 | } 1298 | 1299 | state->cursor = r.where + r.insert_length; 1300 | 1301 | s->undo_point++; 1302 | s->redo_point++; 1303 | } 1304 | 1305 | static void stb_text_makeundo_insert(STB_TexteditState *state, int where, int length) 1306 | { 1307 | stb_text_createundo(&state->undostate, where, 0, length); 1308 | } 1309 | 1310 | static void stb_text_makeundo_delete(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int length) 1311 | { 1312 | int i; 1313 | STB_TEXTEDIT_CHARTYPE *p = stb_text_createundo(&state->undostate, where, length, 0); 1314 | if (p) { 1315 | for (i=0; i < length; ++i) 1316 | p[i] = STB_TEXTEDIT_GETCHAR(str, where+i); 1317 | } 1318 | } 1319 | 1320 | static void stb_text_makeundo_replace(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int old_length, int new_length) 1321 | { 1322 | int i; 1323 | STB_TEXTEDIT_CHARTYPE *p = stb_text_createundo(&state->undostate, where, old_length, new_length); 1324 | if (p) { 1325 | for (i=0; i < old_length; ++i) 1326 | p[i] = STB_TEXTEDIT_GETCHAR(str, where+i); 1327 | } 1328 | } 1329 | 1330 | // reset the state to default 1331 | static void stb_textedit_clear_state(STB_TexteditState *state, int is_single_line) 1332 | { 1333 | state->undostate.undo_point = 0; 1334 | state->undostate.undo_char_point = 0; 1335 | state->undostate.redo_point = STB_TEXTEDIT_UNDOSTATECOUNT; 1336 | state->undostate.redo_char_point = STB_TEXTEDIT_UNDOCHARCOUNT; 1337 | state->select_end = state->select_start = 0; 1338 | state->cursor = 0; 1339 | state->has_preferred_x = 0; 1340 | state->preferred_x = 0; 1341 | state->cursor_at_end_of_line = 0; 1342 | state->initialized = 1; 1343 | state->single_line = (unsigned char) is_single_line; 1344 | state->insert_mode = 0; 1345 | } 1346 | 1347 | // API initialize 1348 | static void stb_textedit_initialize_state(STB_TexteditState *state, int is_single_line) 1349 | { 1350 | stb_textedit_clear_state(state, is_single_line); 1351 | } 1352 | 1353 | #if defined(__GNUC__) || defined(__clang__) 1354 | #pragma GCC diagnostic push 1355 | #pragma GCC diagnostic ignored "-Wcast-qual" 1356 | #endif 1357 | 1358 | static int stb_textedit_paste(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, STB_TEXTEDIT_CHARTYPE const *ctext, int len) 1359 | { 1360 | return stb_textedit_paste_internal(str, state, (STB_TEXTEDIT_CHARTYPE *) ctext, len); 1361 | } 1362 | 1363 | #if defined(__GNUC__) || defined(__clang__) 1364 | #pragma GCC diagnostic pop 1365 | #endif 1366 | 1367 | #endif//STB_TEXTEDIT_IMPLEMENTATION 1368 | 1369 | /* 1370 | ------------------------------------------------------------------------------ 1371 | This software is available under 2 licenses -- choose whichever you prefer. 1372 | ------------------------------------------------------------------------------ 1373 | ALTERNATIVE A - MIT License 1374 | Copyright (c) 2017 Sean Barrett 1375 | Permission is hereby granted, free of charge, to any person obtaining a copy of 1376 | this software and associated documentation files (the "Software"), to deal in 1377 | the Software without restriction, including without limitation the rights to 1378 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 1379 | of the Software, and to permit persons to whom the Software is furnished to do 1380 | so, subject to the following conditions: 1381 | The above copyright notice and this permission notice shall be included in all 1382 | copies or substantial portions of the Software. 1383 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1384 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1385 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 1386 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 1387 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 1388 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 1389 | SOFTWARE. 1390 | ------------------------------------------------------------------------------ 1391 | ALTERNATIVE B - Public Domain (www.unlicense.org) 1392 | This is free and unencumbered software released into the public domain. 1393 | Anyone is free to copy, modify, publish, use, compile, sell, or distribute this 1394 | software, either in source code form or as a compiled binary, for any purpose, 1395 | commercial or non-commercial, and by any means. 1396 | In jurisdictions that recognize copyright laws, the author or authors of this 1397 | software dedicate any and all copyright interest in the software to the public 1398 | domain. We make this dedication for the benefit of the public at large and to 1399 | the detriment of our heirs and successors. We intend this dedication to be an 1400 | overt act of relinquishment in perpetuity of all present and future rights to 1401 | this software under copyright law. 1402 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1403 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1404 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 1405 | AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 1406 | ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 1407 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 1408 | ------------------------------------------------------------------------------ 1409 | */ 1410 | -------------------------------------------------------------------------------- /data/structs_and_enums.json: -------------------------------------------------------------------------------- 1 | { 2 | "enums": { 3 | "ImDrawCornerFlags_": [ 4 | { 5 | "calc_value": 1, 6 | "name": "ImDrawCornerFlags_TopLeft", 7 | "value": "1 << 0" 8 | }, 9 | { 10 | "calc_value": 2, 11 | "name": "ImDrawCornerFlags_TopRight", 12 | "value": "1 << 1" 13 | }, 14 | { 15 | "calc_value": 4, 16 | "name": "ImDrawCornerFlags_BotLeft", 17 | "value": "1 << 2" 18 | }, 19 | { 20 | "calc_value": 8, 21 | "name": "ImDrawCornerFlags_BotRight", 22 | "value": "1 << 3" 23 | }, 24 | { 25 | "calc_value": 3, 26 | "name": "ImDrawCornerFlags_Top", 27 | "value": "ImDrawCornerFlags_TopLeft | ImDrawCornerFlags_TopRight" 28 | }, 29 | { 30 | "calc_value": 12, 31 | "name": "ImDrawCornerFlags_Bot", 32 | "value": "ImDrawCornerFlags_BotLeft | ImDrawCornerFlags_BotRight" 33 | }, 34 | { 35 | "calc_value": 5, 36 | "name": "ImDrawCornerFlags_Left", 37 | "value": "ImDrawCornerFlags_TopLeft | ImDrawCornerFlags_BotLeft" 38 | }, 39 | { 40 | "calc_value": 10, 41 | "name": "ImDrawCornerFlags_Right", 42 | "value": "ImDrawCornerFlags_TopRight | ImDrawCornerFlags_BotRight" 43 | }, 44 | { 45 | "calc_value": 15, 46 | "name": "ImDrawCornerFlags_All", 47 | "value": "0xF" 48 | } 49 | ], 50 | "ImDrawListFlags_": [ 51 | { 52 | "calc_value": 0, 53 | "name": "ImDrawListFlags_None", 54 | "value": "0" 55 | }, 56 | { 57 | "calc_value": 1, 58 | "name": "ImDrawListFlags_AntiAliasedLines", 59 | "value": "1 << 0" 60 | }, 61 | { 62 | "calc_value": 2, 63 | "name": "ImDrawListFlags_AntiAliasedFill", 64 | "value": "1 << 1" 65 | } 66 | ], 67 | "ImFontAtlasFlags_": [ 68 | { 69 | "calc_value": 0, 70 | "name": "ImFontAtlasFlags_None", 71 | "value": "0" 72 | }, 73 | { 74 | "calc_value": 1, 75 | "name": "ImFontAtlasFlags_NoPowerOfTwoHeight", 76 | "value": "1 << 0" 77 | }, 78 | { 79 | "calc_value": 2, 80 | "name": "ImFontAtlasFlags_NoMouseCursors", 81 | "value": "1 << 1" 82 | } 83 | ], 84 | "ImGuiBackendFlags_": [ 85 | { 86 | "calc_value": 0, 87 | "name": "ImGuiBackendFlags_None", 88 | "value": "0" 89 | }, 90 | { 91 | "calc_value": 1, 92 | "name": "ImGuiBackendFlags_HasGamepad", 93 | "value": "1 << 0" 94 | }, 95 | { 96 | "calc_value": 2, 97 | "name": "ImGuiBackendFlags_HasMouseCursors", 98 | "value": "1 << 1" 99 | }, 100 | { 101 | "calc_value": 4, 102 | "name": "ImGuiBackendFlags_HasSetMousePos", 103 | "value": "1 << 2" 104 | } 105 | ], 106 | "ImGuiCol_": [ 107 | { 108 | "calc_value": 0, 109 | "name": "ImGuiCol_Text", 110 | "value": 0 111 | }, 112 | { 113 | "calc_value": 1, 114 | "name": "ImGuiCol_TextDisabled", 115 | "value": 1 116 | }, 117 | { 118 | "calc_value": 2, 119 | "name": "ImGuiCol_WindowBg", 120 | "value": 2 121 | }, 122 | { 123 | "calc_value": 3, 124 | "name": "ImGuiCol_ChildBg", 125 | "value": 3 126 | }, 127 | { 128 | "calc_value": 4, 129 | "name": "ImGuiCol_PopupBg", 130 | "value": 4 131 | }, 132 | { 133 | "calc_value": 5, 134 | "name": "ImGuiCol_Border", 135 | "value": 5 136 | }, 137 | { 138 | "calc_value": 6, 139 | "name": "ImGuiCol_BorderShadow", 140 | "value": 6 141 | }, 142 | { 143 | "calc_value": 7, 144 | "name": "ImGuiCol_FrameBg", 145 | "value": 7 146 | }, 147 | { 148 | "calc_value": 8, 149 | "name": "ImGuiCol_FrameBgHovered", 150 | "value": 8 151 | }, 152 | { 153 | "calc_value": 9, 154 | "name": "ImGuiCol_FrameBgActive", 155 | "value": 9 156 | }, 157 | { 158 | "calc_value": 10, 159 | "name": "ImGuiCol_TitleBg", 160 | "value": 10 161 | }, 162 | { 163 | "calc_value": 11, 164 | "name": "ImGuiCol_TitleBgActive", 165 | "value": 11 166 | }, 167 | { 168 | "calc_value": 12, 169 | "name": "ImGuiCol_TitleBgCollapsed", 170 | "value": 12 171 | }, 172 | { 173 | "calc_value": 13, 174 | "name": "ImGuiCol_MenuBarBg", 175 | "value": 13 176 | }, 177 | { 178 | "calc_value": 14, 179 | "name": "ImGuiCol_ScrollbarBg", 180 | "value": 14 181 | }, 182 | { 183 | "calc_value": 15, 184 | "name": "ImGuiCol_ScrollbarGrab", 185 | "value": 15 186 | }, 187 | { 188 | "calc_value": 16, 189 | "name": "ImGuiCol_ScrollbarGrabHovered", 190 | "value": 16 191 | }, 192 | { 193 | "calc_value": 17, 194 | "name": "ImGuiCol_ScrollbarGrabActive", 195 | "value": 17 196 | }, 197 | { 198 | "calc_value": 18, 199 | "name": "ImGuiCol_CheckMark", 200 | "value": 18 201 | }, 202 | { 203 | "calc_value": 19, 204 | "name": "ImGuiCol_SliderGrab", 205 | "value": 19 206 | }, 207 | { 208 | "calc_value": 20, 209 | "name": "ImGuiCol_SliderGrabActive", 210 | "value": 20 211 | }, 212 | { 213 | "calc_value": 21, 214 | "name": "ImGuiCol_Button", 215 | "value": 21 216 | }, 217 | { 218 | "calc_value": 22, 219 | "name": "ImGuiCol_ButtonHovered", 220 | "value": 22 221 | }, 222 | { 223 | "calc_value": 23, 224 | "name": "ImGuiCol_ButtonActive", 225 | "value": 23 226 | }, 227 | { 228 | "calc_value": 24, 229 | "name": "ImGuiCol_Header", 230 | "value": 24 231 | }, 232 | { 233 | "calc_value": 25, 234 | "name": "ImGuiCol_HeaderHovered", 235 | "value": 25 236 | }, 237 | { 238 | "calc_value": 26, 239 | "name": "ImGuiCol_HeaderActive", 240 | "value": 26 241 | }, 242 | { 243 | "calc_value": 27, 244 | "name": "ImGuiCol_Separator", 245 | "value": 27 246 | }, 247 | { 248 | "calc_value": 28, 249 | "name": "ImGuiCol_SeparatorHovered", 250 | "value": 28 251 | }, 252 | { 253 | "calc_value": 29, 254 | "name": "ImGuiCol_SeparatorActive", 255 | "value": 29 256 | }, 257 | { 258 | "calc_value": 30, 259 | "name": "ImGuiCol_ResizeGrip", 260 | "value": 30 261 | }, 262 | { 263 | "calc_value": 31, 264 | "name": "ImGuiCol_ResizeGripHovered", 265 | "value": 31 266 | }, 267 | { 268 | "calc_value": 32, 269 | "name": "ImGuiCol_ResizeGripActive", 270 | "value": 32 271 | }, 272 | { 273 | "calc_value": 33, 274 | "name": "ImGuiCol_PlotLines", 275 | "value": 33 276 | }, 277 | { 278 | "calc_value": 34, 279 | "name": "ImGuiCol_PlotLinesHovered", 280 | "value": 34 281 | }, 282 | { 283 | "calc_value": 35, 284 | "name": "ImGuiCol_PlotHistogram", 285 | "value": 35 286 | }, 287 | { 288 | "calc_value": 36, 289 | "name": "ImGuiCol_PlotHistogramHovered", 290 | "value": 36 291 | }, 292 | { 293 | "calc_value": 37, 294 | "name": "ImGuiCol_TextSelectedBg", 295 | "value": 37 296 | }, 297 | { 298 | "calc_value": 38, 299 | "name": "ImGuiCol_DragDropTarget", 300 | "value": 38 301 | }, 302 | { 303 | "calc_value": 39, 304 | "name": "ImGuiCol_NavHighlight", 305 | "value": 39 306 | }, 307 | { 308 | "calc_value": 40, 309 | "name": "ImGuiCol_NavWindowingHighlight", 310 | "value": 40 311 | }, 312 | { 313 | "calc_value": 41, 314 | "name": "ImGuiCol_NavWindowingDimBg", 315 | "value": 41 316 | }, 317 | { 318 | "calc_value": 42, 319 | "name": "ImGuiCol_ModalWindowDimBg", 320 | "value": 42 321 | }, 322 | { 323 | "calc_value": 43, 324 | "name": "ImGuiCol_COUNT", 325 | "value": 43 326 | } 327 | ], 328 | "ImGuiColorEditFlags_": [ 329 | { 330 | "calc_value": 0, 331 | "name": "ImGuiColorEditFlags_None", 332 | "value": "0" 333 | }, 334 | { 335 | "calc_value": 2, 336 | "name": "ImGuiColorEditFlags_NoAlpha", 337 | "value": "1 << 1" 338 | }, 339 | { 340 | "calc_value": 4, 341 | "name": "ImGuiColorEditFlags_NoPicker", 342 | "value": "1 << 2" 343 | }, 344 | { 345 | "calc_value": 8, 346 | "name": "ImGuiColorEditFlags_NoOptions", 347 | "value": "1 << 3" 348 | }, 349 | { 350 | "calc_value": 16, 351 | "name": "ImGuiColorEditFlags_NoSmallPreview", 352 | "value": "1 << 4" 353 | }, 354 | { 355 | "calc_value": 32, 356 | "name": "ImGuiColorEditFlags_NoInputs", 357 | "value": "1 << 5" 358 | }, 359 | { 360 | "calc_value": 64, 361 | "name": "ImGuiColorEditFlags_NoTooltip", 362 | "value": "1 << 6" 363 | }, 364 | { 365 | "calc_value": 128, 366 | "name": "ImGuiColorEditFlags_NoLabel", 367 | "value": "1 << 7" 368 | }, 369 | { 370 | "calc_value": 256, 371 | "name": "ImGuiColorEditFlags_NoSidePreview", 372 | "value": "1 << 8" 373 | }, 374 | { 375 | "calc_value": 512, 376 | "name": "ImGuiColorEditFlags_NoDragDrop", 377 | "value": "1 << 9" 378 | }, 379 | { 380 | "calc_value": 65536, 381 | "name": "ImGuiColorEditFlags_AlphaBar", 382 | "value": "1 << 16" 383 | }, 384 | { 385 | "calc_value": 131072, 386 | "name": "ImGuiColorEditFlags_AlphaPreview", 387 | "value": "1 << 17" 388 | }, 389 | { 390 | "calc_value": 262144, 391 | "name": "ImGuiColorEditFlags_AlphaPreviewHalf", 392 | "value": "1 << 18" 393 | }, 394 | { 395 | "calc_value": 524288, 396 | "name": "ImGuiColorEditFlags_HDR", 397 | "value": "1 << 19" 398 | }, 399 | { 400 | "calc_value": 1048576, 401 | "name": "ImGuiColorEditFlags_RGB", 402 | "value": "1 << 20" 403 | }, 404 | { 405 | "calc_value": 2097152, 406 | "name": "ImGuiColorEditFlags_HSV", 407 | "value": "1 << 21" 408 | }, 409 | { 410 | "calc_value": 4194304, 411 | "name": "ImGuiColorEditFlags_HEX", 412 | "value": "1 << 22" 413 | }, 414 | { 415 | "calc_value": 8388608, 416 | "name": "ImGuiColorEditFlags_Uint8", 417 | "value": "1 << 23" 418 | }, 419 | { 420 | "calc_value": 16777216, 421 | "name": "ImGuiColorEditFlags_Float", 422 | "value": "1 << 24" 423 | }, 424 | { 425 | "calc_value": 33554432, 426 | "name": "ImGuiColorEditFlags_PickerHueBar", 427 | "value": "1 << 25" 428 | }, 429 | { 430 | "calc_value": 67108864, 431 | "name": "ImGuiColorEditFlags_PickerHueWheel", 432 | "value": "1 << 26" 433 | }, 434 | { 435 | "calc_value": 7340032, 436 | "name": "ImGuiColorEditFlags__InputsMask", 437 | "value": "ImGuiColorEditFlags_RGB|ImGuiColorEditFlags_HSV|ImGuiColorEditFlags_HEX" 438 | }, 439 | { 440 | "calc_value": 25165824, 441 | "name": "ImGuiColorEditFlags__DataTypeMask", 442 | "value": "ImGuiColorEditFlags_Uint8|ImGuiColorEditFlags_Float" 443 | }, 444 | { 445 | "calc_value": 100663296, 446 | "name": "ImGuiColorEditFlags__PickerMask", 447 | "value": "ImGuiColorEditFlags_PickerHueWheel|ImGuiColorEditFlags_PickerHueBar" 448 | }, 449 | { 450 | "calc_value": 42991616, 451 | "name": "ImGuiColorEditFlags__OptionsDefault", 452 | "value": "ImGuiColorEditFlags_Uint8|ImGuiColorEditFlags_RGB|ImGuiColorEditFlags_PickerHueBar" 453 | } 454 | ], 455 | "ImGuiComboFlags_": [ 456 | { 457 | "calc_value": 0, 458 | "name": "ImGuiComboFlags_None", 459 | "value": "0" 460 | }, 461 | { 462 | "calc_value": 1, 463 | "name": "ImGuiComboFlags_PopupAlignLeft", 464 | "value": "1 << 0" 465 | }, 466 | { 467 | "calc_value": 2, 468 | "name": "ImGuiComboFlags_HeightSmall", 469 | "value": "1 << 1" 470 | }, 471 | { 472 | "calc_value": 4, 473 | "name": "ImGuiComboFlags_HeightRegular", 474 | "value": "1 << 2" 475 | }, 476 | { 477 | "calc_value": 8, 478 | "name": "ImGuiComboFlags_HeightLarge", 479 | "value": "1 << 3" 480 | }, 481 | { 482 | "calc_value": 16, 483 | "name": "ImGuiComboFlags_HeightLargest", 484 | "value": "1 << 4" 485 | }, 486 | { 487 | "calc_value": 32, 488 | "name": "ImGuiComboFlags_NoArrowButton", 489 | "value": "1 << 5" 490 | }, 491 | { 492 | "calc_value": 64, 493 | "name": "ImGuiComboFlags_NoPreview", 494 | "value": "1 << 6" 495 | }, 496 | { 497 | "calc_value": 30, 498 | "name": "ImGuiComboFlags_HeightMask_", 499 | "value": "ImGuiComboFlags_HeightSmall | ImGuiComboFlags_HeightRegular | ImGuiComboFlags_HeightLarge | ImGuiComboFlags_HeightLargest" 500 | } 501 | ], 502 | "ImGuiCond_": [ 503 | { 504 | "calc_value": 1, 505 | "name": "ImGuiCond_Always", 506 | "value": "1 << 0" 507 | }, 508 | { 509 | "calc_value": 2, 510 | "name": "ImGuiCond_Once", 511 | "value": "1 << 1" 512 | }, 513 | { 514 | "calc_value": 4, 515 | "name": "ImGuiCond_FirstUseEver", 516 | "value": "1 << 2" 517 | }, 518 | { 519 | "calc_value": 8, 520 | "name": "ImGuiCond_Appearing", 521 | "value": "1 << 3" 522 | } 523 | ], 524 | "ImGuiConfigFlags_": [ 525 | { 526 | "calc_value": 0, 527 | "name": "ImGuiConfigFlags_None", 528 | "value": "0" 529 | }, 530 | { 531 | "calc_value": 1, 532 | "name": "ImGuiConfigFlags_NavEnableKeyboard", 533 | "value": "1 << 0" 534 | }, 535 | { 536 | "calc_value": 2, 537 | "name": "ImGuiConfigFlags_NavEnableGamepad", 538 | "value": "1 << 1" 539 | }, 540 | { 541 | "calc_value": 4, 542 | "name": "ImGuiConfigFlags_NavEnableSetMousePos", 543 | "value": "1 << 2" 544 | }, 545 | { 546 | "calc_value": 8, 547 | "name": "ImGuiConfigFlags_NavNoCaptureKeyboard", 548 | "value": "1 << 3" 549 | }, 550 | { 551 | "calc_value": 16, 552 | "name": "ImGuiConfigFlags_NoMouse", 553 | "value": "1 << 4" 554 | }, 555 | { 556 | "calc_value": 32, 557 | "name": "ImGuiConfigFlags_NoMouseCursorChange", 558 | "value": "1 << 5" 559 | }, 560 | { 561 | "calc_value": 1048576, 562 | "name": "ImGuiConfigFlags_IsSRGB", 563 | "value": "1 << 20" 564 | }, 565 | { 566 | "calc_value": 2097152, 567 | "name": "ImGuiConfigFlags_IsTouchScreen", 568 | "value": "1 << 21" 569 | } 570 | ], 571 | "ImGuiDataType_": [ 572 | { 573 | "calc_value": 0, 574 | "name": "ImGuiDataType_S32", 575 | "value": 0 576 | }, 577 | { 578 | "calc_value": 1, 579 | "name": "ImGuiDataType_U32", 580 | "value": 1 581 | }, 582 | { 583 | "calc_value": 2, 584 | "name": "ImGuiDataType_S64", 585 | "value": 2 586 | }, 587 | { 588 | "calc_value": 3, 589 | "name": "ImGuiDataType_U64", 590 | "value": 3 591 | }, 592 | { 593 | "calc_value": 4, 594 | "name": "ImGuiDataType_Float", 595 | "value": 4 596 | }, 597 | { 598 | "calc_value": 5, 599 | "name": "ImGuiDataType_Double", 600 | "value": 5 601 | }, 602 | { 603 | "calc_value": 6, 604 | "name": "ImGuiDataType_COUNT", 605 | "value": 6 606 | } 607 | ], 608 | "ImGuiDir_": [ 609 | { 610 | "calc_value": -1, 611 | "name": "ImGuiDir_None", 612 | "value": "-1" 613 | }, 614 | { 615 | "calc_value": 0, 616 | "name": "ImGuiDir_Left", 617 | "value": "0" 618 | }, 619 | { 620 | "calc_value": 1, 621 | "name": "ImGuiDir_Right", 622 | "value": "1" 623 | }, 624 | { 625 | "calc_value": 2, 626 | "name": "ImGuiDir_Up", 627 | "value": "2" 628 | }, 629 | { 630 | "calc_value": 3, 631 | "name": "ImGuiDir_Down", 632 | "value": "3" 633 | }, 634 | { 635 | "calc_value": 4, 636 | "name": "ImGuiDir_COUNT", 637 | "value": 4 638 | } 639 | ], 640 | "ImGuiDragDropFlags_": [ 641 | { 642 | "calc_value": 0, 643 | "name": "ImGuiDragDropFlags_None", 644 | "value": "0" 645 | }, 646 | { 647 | "calc_value": 1, 648 | "name": "ImGuiDragDropFlags_SourceNoPreviewTooltip", 649 | "value": "1 << 0" 650 | }, 651 | { 652 | "calc_value": 2, 653 | "name": "ImGuiDragDropFlags_SourceNoDisableHover", 654 | "value": "1 << 1" 655 | }, 656 | { 657 | "calc_value": 4, 658 | "name": "ImGuiDragDropFlags_SourceNoHoldToOpenOthers", 659 | "value": "1 << 2" 660 | }, 661 | { 662 | "calc_value": 8, 663 | "name": "ImGuiDragDropFlags_SourceAllowNullID", 664 | "value": "1 << 3" 665 | }, 666 | { 667 | "calc_value": 16, 668 | "name": "ImGuiDragDropFlags_SourceExtern", 669 | "value": "1 << 4" 670 | }, 671 | { 672 | "calc_value": 32, 673 | "name": "ImGuiDragDropFlags_SourceAutoExpirePayload", 674 | "value": "1 << 5" 675 | }, 676 | { 677 | "calc_value": 1024, 678 | "name": "ImGuiDragDropFlags_AcceptBeforeDelivery", 679 | "value": "1 << 10" 680 | }, 681 | { 682 | "calc_value": 2048, 683 | "name": "ImGuiDragDropFlags_AcceptNoDrawDefaultRect", 684 | "value": "1 << 11" 685 | }, 686 | { 687 | "calc_value": 4096, 688 | "name": "ImGuiDragDropFlags_AcceptNoPreviewTooltip", 689 | "value": "1 << 12" 690 | }, 691 | { 692 | "calc_value": 3072, 693 | "name": "ImGuiDragDropFlags_AcceptPeekOnly", 694 | "value": "ImGuiDragDropFlags_AcceptBeforeDelivery | ImGuiDragDropFlags_AcceptNoDrawDefaultRect" 695 | } 696 | ], 697 | "ImGuiFocusedFlags_": [ 698 | { 699 | "calc_value": 0, 700 | "name": "ImGuiFocusedFlags_None", 701 | "value": "0" 702 | }, 703 | { 704 | "calc_value": 1, 705 | "name": "ImGuiFocusedFlags_ChildWindows", 706 | "value": "1 << 0" 707 | }, 708 | { 709 | "calc_value": 2, 710 | "name": "ImGuiFocusedFlags_RootWindow", 711 | "value": "1 << 1" 712 | }, 713 | { 714 | "calc_value": 4, 715 | "name": "ImGuiFocusedFlags_AnyWindow", 716 | "value": "1 << 2" 717 | }, 718 | { 719 | "calc_value": 3, 720 | "name": "ImGuiFocusedFlags_RootAndChildWindows", 721 | "value": "ImGuiFocusedFlags_RootWindow | ImGuiFocusedFlags_ChildWindows" 722 | } 723 | ], 724 | "ImGuiHoveredFlags_": [ 725 | { 726 | "calc_value": 0, 727 | "name": "ImGuiHoveredFlags_None", 728 | "value": "0" 729 | }, 730 | { 731 | "calc_value": 1, 732 | "name": "ImGuiHoveredFlags_ChildWindows", 733 | "value": "1 << 0" 734 | }, 735 | { 736 | "calc_value": 2, 737 | "name": "ImGuiHoveredFlags_RootWindow", 738 | "value": "1 << 1" 739 | }, 740 | { 741 | "calc_value": 4, 742 | "name": "ImGuiHoveredFlags_AnyWindow", 743 | "value": "1 << 2" 744 | }, 745 | { 746 | "calc_value": 8, 747 | "name": "ImGuiHoveredFlags_AllowWhenBlockedByPopup", 748 | "value": "1 << 3" 749 | }, 750 | { 751 | "calc_value": 32, 752 | "name": "ImGuiHoveredFlags_AllowWhenBlockedByActiveItem", 753 | "value": "1 << 5" 754 | }, 755 | { 756 | "calc_value": 64, 757 | "name": "ImGuiHoveredFlags_AllowWhenOverlapped", 758 | "value": "1 << 6" 759 | }, 760 | { 761 | "calc_value": 128, 762 | "name": "ImGuiHoveredFlags_AllowWhenDisabled", 763 | "value": "1 << 7" 764 | }, 765 | { 766 | "calc_value": 104, 767 | "name": "ImGuiHoveredFlags_RectOnly", 768 | "value": "ImGuiHoveredFlags_AllowWhenBlockedByPopup | ImGuiHoveredFlags_AllowWhenBlockedByActiveItem | ImGuiHoveredFlags_AllowWhenOverlapped" 769 | }, 770 | { 771 | "calc_value": 3, 772 | "name": "ImGuiHoveredFlags_RootAndChildWindows", 773 | "value": "ImGuiHoveredFlags_RootWindow | ImGuiHoveredFlags_ChildWindows" 774 | } 775 | ], 776 | "ImGuiInputTextFlags_": [ 777 | { 778 | "calc_value": 0, 779 | "name": "ImGuiInputTextFlags_None", 780 | "value": "0" 781 | }, 782 | { 783 | "calc_value": 1, 784 | "name": "ImGuiInputTextFlags_CharsDecimal", 785 | "value": "1 << 0" 786 | }, 787 | { 788 | "calc_value": 2, 789 | "name": "ImGuiInputTextFlags_CharsHexadecimal", 790 | "value": "1 << 1" 791 | }, 792 | { 793 | "calc_value": 4, 794 | "name": "ImGuiInputTextFlags_CharsUppercase", 795 | "value": "1 << 2" 796 | }, 797 | { 798 | "calc_value": 8, 799 | "name": "ImGuiInputTextFlags_CharsNoBlank", 800 | "value": "1 << 3" 801 | }, 802 | { 803 | "calc_value": 16, 804 | "name": "ImGuiInputTextFlags_AutoSelectAll", 805 | "value": "1 << 4" 806 | }, 807 | { 808 | "calc_value": 32, 809 | "name": "ImGuiInputTextFlags_EnterReturnsTrue", 810 | "value": "1 << 5" 811 | }, 812 | { 813 | "calc_value": 64, 814 | "name": "ImGuiInputTextFlags_CallbackCompletion", 815 | "value": "1 << 6" 816 | }, 817 | { 818 | "calc_value": 128, 819 | "name": "ImGuiInputTextFlags_CallbackHistory", 820 | "value": "1 << 7" 821 | }, 822 | { 823 | "calc_value": 256, 824 | "name": "ImGuiInputTextFlags_CallbackAlways", 825 | "value": "1 << 8" 826 | }, 827 | { 828 | "calc_value": 512, 829 | "name": "ImGuiInputTextFlags_CallbackCharFilter", 830 | "value": "1 << 9" 831 | }, 832 | { 833 | "calc_value": 1024, 834 | "name": "ImGuiInputTextFlags_AllowTabInput", 835 | "value": "1 << 10" 836 | }, 837 | { 838 | "calc_value": 2048, 839 | "name": "ImGuiInputTextFlags_CtrlEnterForNewLine", 840 | "value": "1 << 11" 841 | }, 842 | { 843 | "calc_value": 4096, 844 | "name": "ImGuiInputTextFlags_NoHorizontalScroll", 845 | "value": "1 << 12" 846 | }, 847 | { 848 | "calc_value": 8192, 849 | "name": "ImGuiInputTextFlags_AlwaysInsertMode", 850 | "value": "1 << 13" 851 | }, 852 | { 853 | "calc_value": 16384, 854 | "name": "ImGuiInputTextFlags_ReadOnly", 855 | "value": "1 << 14" 856 | }, 857 | { 858 | "calc_value": 32768, 859 | "name": "ImGuiInputTextFlags_Password", 860 | "value": "1 << 15" 861 | }, 862 | { 863 | "calc_value": 65536, 864 | "name": "ImGuiInputTextFlags_NoUndoRedo", 865 | "value": "1 << 16" 866 | }, 867 | { 868 | "calc_value": 131072, 869 | "name": "ImGuiInputTextFlags_CharsScientific", 870 | "value": "1 << 17" 871 | }, 872 | { 873 | "calc_value": 262144, 874 | "name": "ImGuiInputTextFlags_CallbackResize", 875 | "value": "1 << 18" 876 | }, 877 | { 878 | "calc_value": 1048576, 879 | "name": "ImGuiInputTextFlags_Multiline", 880 | "value": "1 << 20" 881 | } 882 | ], 883 | "ImGuiKey_": [ 884 | { 885 | "calc_value": 0, 886 | "name": "ImGuiKey_Tab", 887 | "value": 0 888 | }, 889 | { 890 | "calc_value": 1, 891 | "name": "ImGuiKey_LeftArrow", 892 | "value": 1 893 | }, 894 | { 895 | "calc_value": 2, 896 | "name": "ImGuiKey_RightArrow", 897 | "value": 2 898 | }, 899 | { 900 | "calc_value": 3, 901 | "name": "ImGuiKey_UpArrow", 902 | "value": 3 903 | }, 904 | { 905 | "calc_value": 4, 906 | "name": "ImGuiKey_DownArrow", 907 | "value": 4 908 | }, 909 | { 910 | "calc_value": 5, 911 | "name": "ImGuiKey_PageUp", 912 | "value": 5 913 | }, 914 | { 915 | "calc_value": 6, 916 | "name": "ImGuiKey_PageDown", 917 | "value": 6 918 | }, 919 | { 920 | "calc_value": 7, 921 | "name": "ImGuiKey_Home", 922 | "value": 7 923 | }, 924 | { 925 | "calc_value": 8, 926 | "name": "ImGuiKey_End", 927 | "value": 8 928 | }, 929 | { 930 | "calc_value": 9, 931 | "name": "ImGuiKey_Insert", 932 | "value": 9 933 | }, 934 | { 935 | "calc_value": 10, 936 | "name": "ImGuiKey_Delete", 937 | "value": 10 938 | }, 939 | { 940 | "calc_value": 11, 941 | "name": "ImGuiKey_Backspace", 942 | "value": 11 943 | }, 944 | { 945 | "calc_value": 12, 946 | "name": "ImGuiKey_Space", 947 | "value": 12 948 | }, 949 | { 950 | "calc_value": 13, 951 | "name": "ImGuiKey_Enter", 952 | "value": 13 953 | }, 954 | { 955 | "calc_value": 14, 956 | "name": "ImGuiKey_Escape", 957 | "value": 14 958 | }, 959 | { 960 | "calc_value": 15, 961 | "name": "ImGuiKey_A", 962 | "value": 15 963 | }, 964 | { 965 | "calc_value": 16, 966 | "name": "ImGuiKey_C", 967 | "value": 16 968 | }, 969 | { 970 | "calc_value": 17, 971 | "name": "ImGuiKey_V", 972 | "value": 17 973 | }, 974 | { 975 | "calc_value": 18, 976 | "name": "ImGuiKey_X", 977 | "value": 18 978 | }, 979 | { 980 | "calc_value": 19, 981 | "name": "ImGuiKey_Y", 982 | "value": 19 983 | }, 984 | { 985 | "calc_value": 20, 986 | "name": "ImGuiKey_Z", 987 | "value": 20 988 | }, 989 | { 990 | "calc_value": 21, 991 | "name": "ImGuiKey_COUNT", 992 | "value": 21 993 | } 994 | ], 995 | "ImGuiMouseCursor_": [ 996 | { 997 | "calc_value": -1, 998 | "name": "ImGuiMouseCursor_None", 999 | "value": "-1" 1000 | }, 1001 | { 1002 | "calc_value": 0, 1003 | "name": "ImGuiMouseCursor_Arrow", 1004 | "value": "0" 1005 | }, 1006 | { 1007 | "calc_value": 1, 1008 | "name": "ImGuiMouseCursor_TextInput", 1009 | "value": 1 1010 | }, 1011 | { 1012 | "calc_value": 2, 1013 | "name": "ImGuiMouseCursor_ResizeAll", 1014 | "value": 2 1015 | }, 1016 | { 1017 | "calc_value": 3, 1018 | "name": "ImGuiMouseCursor_ResizeNS", 1019 | "value": 3 1020 | }, 1021 | { 1022 | "calc_value": 4, 1023 | "name": "ImGuiMouseCursor_ResizeEW", 1024 | "value": 4 1025 | }, 1026 | { 1027 | "calc_value": 5, 1028 | "name": "ImGuiMouseCursor_ResizeNESW", 1029 | "value": 5 1030 | }, 1031 | { 1032 | "calc_value": 6, 1033 | "name": "ImGuiMouseCursor_ResizeNWSE", 1034 | "value": 6 1035 | }, 1036 | { 1037 | "calc_value": 7, 1038 | "name": "ImGuiMouseCursor_Hand", 1039 | "value": 7 1040 | }, 1041 | { 1042 | "calc_value": 8, 1043 | "name": "ImGuiMouseCursor_COUNT", 1044 | "value": 8 1045 | } 1046 | ], 1047 | "ImGuiNavInput_": [ 1048 | { 1049 | "calc_value": 0, 1050 | "name": "ImGuiNavInput_Activate", 1051 | "value": 0 1052 | }, 1053 | { 1054 | "calc_value": 1, 1055 | "name": "ImGuiNavInput_Cancel", 1056 | "value": 1 1057 | }, 1058 | { 1059 | "calc_value": 2, 1060 | "name": "ImGuiNavInput_Input", 1061 | "value": 2 1062 | }, 1063 | { 1064 | "calc_value": 3, 1065 | "name": "ImGuiNavInput_Menu", 1066 | "value": 3 1067 | }, 1068 | { 1069 | "calc_value": 4, 1070 | "name": "ImGuiNavInput_DpadLeft", 1071 | "value": 4 1072 | }, 1073 | { 1074 | "calc_value": 5, 1075 | "name": "ImGuiNavInput_DpadRight", 1076 | "value": 5 1077 | }, 1078 | { 1079 | "calc_value": 6, 1080 | "name": "ImGuiNavInput_DpadUp", 1081 | "value": 6 1082 | }, 1083 | { 1084 | "calc_value": 7, 1085 | "name": "ImGuiNavInput_DpadDown", 1086 | "value": 7 1087 | }, 1088 | { 1089 | "calc_value": 8, 1090 | "name": "ImGuiNavInput_LStickLeft", 1091 | "value": 8 1092 | }, 1093 | { 1094 | "calc_value": 9, 1095 | "name": "ImGuiNavInput_LStickRight", 1096 | "value": 9 1097 | }, 1098 | { 1099 | "calc_value": 10, 1100 | "name": "ImGuiNavInput_LStickUp", 1101 | "value": 10 1102 | }, 1103 | { 1104 | "calc_value": 11, 1105 | "name": "ImGuiNavInput_LStickDown", 1106 | "value": 11 1107 | }, 1108 | { 1109 | "calc_value": 12, 1110 | "name": "ImGuiNavInput_FocusPrev", 1111 | "value": 12 1112 | }, 1113 | { 1114 | "calc_value": 13, 1115 | "name": "ImGuiNavInput_FocusNext", 1116 | "value": 13 1117 | }, 1118 | { 1119 | "calc_value": 14, 1120 | "name": "ImGuiNavInput_TweakSlow", 1121 | "value": 14 1122 | }, 1123 | { 1124 | "calc_value": 15, 1125 | "name": "ImGuiNavInput_TweakFast", 1126 | "value": 15 1127 | }, 1128 | { 1129 | "calc_value": 16, 1130 | "name": "ImGuiNavInput_KeyMenu_", 1131 | "value": 16 1132 | }, 1133 | { 1134 | "calc_value": 17, 1135 | "name": "ImGuiNavInput_KeyLeft_", 1136 | "value": 17 1137 | }, 1138 | { 1139 | "calc_value": 18, 1140 | "name": "ImGuiNavInput_KeyRight_", 1141 | "value": 18 1142 | }, 1143 | { 1144 | "calc_value": 19, 1145 | "name": "ImGuiNavInput_KeyUp_", 1146 | "value": 19 1147 | }, 1148 | { 1149 | "calc_value": 20, 1150 | "name": "ImGuiNavInput_KeyDown_", 1151 | "value": 20 1152 | }, 1153 | { 1154 | "calc_value": 21, 1155 | "name": "ImGuiNavInput_COUNT", 1156 | "value": 21 1157 | }, 1158 | { 1159 | "calc_value": 16, 1160 | "name": "ImGuiNavInput_InternalStart_", 1161 | "value": "ImGuiNavInput_KeyMenu_" 1162 | } 1163 | ], 1164 | "ImGuiSelectableFlags_": [ 1165 | { 1166 | "calc_value": 0, 1167 | "name": "ImGuiSelectableFlags_None", 1168 | "value": "0" 1169 | }, 1170 | { 1171 | "calc_value": 1, 1172 | "name": "ImGuiSelectableFlags_DontClosePopups", 1173 | "value": "1 << 0" 1174 | }, 1175 | { 1176 | "calc_value": 2, 1177 | "name": "ImGuiSelectableFlags_SpanAllColumns", 1178 | "value": "1 << 1" 1179 | }, 1180 | { 1181 | "calc_value": 4, 1182 | "name": "ImGuiSelectableFlags_AllowDoubleClick", 1183 | "value": "1 << 2" 1184 | }, 1185 | { 1186 | "calc_value": 8, 1187 | "name": "ImGuiSelectableFlags_Disabled", 1188 | "value": "1 << 3" 1189 | } 1190 | ], 1191 | "ImGuiStyleVar_": [ 1192 | { 1193 | "calc_value": 0, 1194 | "name": "ImGuiStyleVar_Alpha", 1195 | "value": 0 1196 | }, 1197 | { 1198 | "calc_value": 1, 1199 | "name": "ImGuiStyleVar_WindowPadding", 1200 | "value": 1 1201 | }, 1202 | { 1203 | "calc_value": 2, 1204 | "name": "ImGuiStyleVar_WindowRounding", 1205 | "value": 2 1206 | }, 1207 | { 1208 | "calc_value": 3, 1209 | "name": "ImGuiStyleVar_WindowBorderSize", 1210 | "value": 3 1211 | }, 1212 | { 1213 | "calc_value": 4, 1214 | "name": "ImGuiStyleVar_WindowMinSize", 1215 | "value": 4 1216 | }, 1217 | { 1218 | "calc_value": 5, 1219 | "name": "ImGuiStyleVar_WindowTitleAlign", 1220 | "value": 5 1221 | }, 1222 | { 1223 | "calc_value": 6, 1224 | "name": "ImGuiStyleVar_ChildRounding", 1225 | "value": 6 1226 | }, 1227 | { 1228 | "calc_value": 7, 1229 | "name": "ImGuiStyleVar_ChildBorderSize", 1230 | "value": 7 1231 | }, 1232 | { 1233 | "calc_value": 8, 1234 | "name": "ImGuiStyleVar_PopupRounding", 1235 | "value": 8 1236 | }, 1237 | { 1238 | "calc_value": 9, 1239 | "name": "ImGuiStyleVar_PopupBorderSize", 1240 | "value": 9 1241 | }, 1242 | { 1243 | "calc_value": 10, 1244 | "name": "ImGuiStyleVar_FramePadding", 1245 | "value": 10 1246 | }, 1247 | { 1248 | "calc_value": 11, 1249 | "name": "ImGuiStyleVar_FrameRounding", 1250 | "value": 11 1251 | }, 1252 | { 1253 | "calc_value": 12, 1254 | "name": "ImGuiStyleVar_FrameBorderSize", 1255 | "value": 12 1256 | }, 1257 | { 1258 | "calc_value": 13, 1259 | "name": "ImGuiStyleVar_ItemSpacing", 1260 | "value": 13 1261 | }, 1262 | { 1263 | "calc_value": 14, 1264 | "name": "ImGuiStyleVar_ItemInnerSpacing", 1265 | "value": 14 1266 | }, 1267 | { 1268 | "calc_value": 15, 1269 | "name": "ImGuiStyleVar_IndentSpacing", 1270 | "value": 15 1271 | }, 1272 | { 1273 | "calc_value": 16, 1274 | "name": "ImGuiStyleVar_ScrollbarSize", 1275 | "value": 16 1276 | }, 1277 | { 1278 | "calc_value": 17, 1279 | "name": "ImGuiStyleVar_ScrollbarRounding", 1280 | "value": 17 1281 | }, 1282 | { 1283 | "calc_value": 18, 1284 | "name": "ImGuiStyleVar_GrabMinSize", 1285 | "value": 18 1286 | }, 1287 | { 1288 | "calc_value": 19, 1289 | "name": "ImGuiStyleVar_GrabRounding", 1290 | "value": 19 1291 | }, 1292 | { 1293 | "calc_value": 20, 1294 | "name": "ImGuiStyleVar_ButtonTextAlign", 1295 | "value": 20 1296 | }, 1297 | { 1298 | "calc_value": 21, 1299 | "name": "ImGuiStyleVar_COUNT", 1300 | "value": 21 1301 | } 1302 | ], 1303 | "ImGuiTreeNodeFlags_": [ 1304 | { 1305 | "calc_value": 0, 1306 | "name": "ImGuiTreeNodeFlags_None", 1307 | "value": "0" 1308 | }, 1309 | { 1310 | "calc_value": 1, 1311 | "name": "ImGuiTreeNodeFlags_Selected", 1312 | "value": "1 << 0" 1313 | }, 1314 | { 1315 | "calc_value": 2, 1316 | "name": "ImGuiTreeNodeFlags_Framed", 1317 | "value": "1 << 1" 1318 | }, 1319 | { 1320 | "calc_value": 4, 1321 | "name": "ImGuiTreeNodeFlags_AllowItemOverlap", 1322 | "value": "1 << 2" 1323 | }, 1324 | { 1325 | "calc_value": 8, 1326 | "name": "ImGuiTreeNodeFlags_NoTreePushOnOpen", 1327 | "value": "1 << 3" 1328 | }, 1329 | { 1330 | "calc_value": 16, 1331 | "name": "ImGuiTreeNodeFlags_NoAutoOpenOnLog", 1332 | "value": "1 << 4" 1333 | }, 1334 | { 1335 | "calc_value": 32, 1336 | "name": "ImGuiTreeNodeFlags_DefaultOpen", 1337 | "value": "1 << 5" 1338 | }, 1339 | { 1340 | "calc_value": 64, 1341 | "name": "ImGuiTreeNodeFlags_OpenOnDoubleClick", 1342 | "value": "1 << 6" 1343 | }, 1344 | { 1345 | "calc_value": 128, 1346 | "name": "ImGuiTreeNodeFlags_OpenOnArrow", 1347 | "value": "1 << 7" 1348 | }, 1349 | { 1350 | "calc_value": 256, 1351 | "name": "ImGuiTreeNodeFlags_Leaf", 1352 | "value": "1 << 8" 1353 | }, 1354 | { 1355 | "calc_value": 512, 1356 | "name": "ImGuiTreeNodeFlags_Bullet", 1357 | "value": "1 << 9" 1358 | }, 1359 | { 1360 | "calc_value": 1024, 1361 | "name": "ImGuiTreeNodeFlags_FramePadding", 1362 | "value": "1 << 10" 1363 | }, 1364 | { 1365 | "calc_value": 8192, 1366 | "name": "ImGuiTreeNodeFlags_NavLeftJumpsBackHere", 1367 | "value": "1 << 13" 1368 | }, 1369 | { 1370 | "calc_value": 26, 1371 | "name": "ImGuiTreeNodeFlags_CollapsingHeader", 1372 | "value": "ImGuiTreeNodeFlags_Framed | ImGuiTreeNodeFlags_NoTreePushOnOpen | ImGuiTreeNodeFlags_NoAutoOpenOnLog" 1373 | } 1374 | ], 1375 | "ImGuiWindowFlags_": [ 1376 | { 1377 | "calc_value": 0, 1378 | "name": "ImGuiWindowFlags_None", 1379 | "value": "0" 1380 | }, 1381 | { 1382 | "calc_value": 1, 1383 | "name": "ImGuiWindowFlags_NoTitleBar", 1384 | "value": "1 << 0" 1385 | }, 1386 | { 1387 | "calc_value": 2, 1388 | "name": "ImGuiWindowFlags_NoResize", 1389 | "value": "1 << 1" 1390 | }, 1391 | { 1392 | "calc_value": 4, 1393 | "name": "ImGuiWindowFlags_NoMove", 1394 | "value": "1 << 2" 1395 | }, 1396 | { 1397 | "calc_value": 8, 1398 | "name": "ImGuiWindowFlags_NoScrollbar", 1399 | "value": "1 << 3" 1400 | }, 1401 | { 1402 | "calc_value": 16, 1403 | "name": "ImGuiWindowFlags_NoScrollWithMouse", 1404 | "value": "1 << 4" 1405 | }, 1406 | { 1407 | "calc_value": 32, 1408 | "name": "ImGuiWindowFlags_NoCollapse", 1409 | "value": "1 << 5" 1410 | }, 1411 | { 1412 | "calc_value": 64, 1413 | "name": "ImGuiWindowFlags_AlwaysAutoResize", 1414 | "value": "1 << 6" 1415 | }, 1416 | { 1417 | "calc_value": 128, 1418 | "name": "ImGuiWindowFlags_NoBackground", 1419 | "value": "1 << 7" 1420 | }, 1421 | { 1422 | "calc_value": 256, 1423 | "name": "ImGuiWindowFlags_NoSavedSettings", 1424 | "value": "1 << 8" 1425 | }, 1426 | { 1427 | "calc_value": 512, 1428 | "name": "ImGuiWindowFlags_NoMouseInputs", 1429 | "value": "1 << 9" 1430 | }, 1431 | { 1432 | "calc_value": 1024, 1433 | "name": "ImGuiWindowFlags_MenuBar", 1434 | "value": "1 << 10" 1435 | }, 1436 | { 1437 | "calc_value": 2048, 1438 | "name": "ImGuiWindowFlags_HorizontalScrollbar", 1439 | "value": "1 << 11" 1440 | }, 1441 | { 1442 | "calc_value": 4096, 1443 | "name": "ImGuiWindowFlags_NoFocusOnAppearing", 1444 | "value": "1 << 12" 1445 | }, 1446 | { 1447 | "calc_value": 8192, 1448 | "name": "ImGuiWindowFlags_NoBringToFrontOnFocus", 1449 | "value": "1 << 13" 1450 | }, 1451 | { 1452 | "calc_value": 16384, 1453 | "name": "ImGuiWindowFlags_AlwaysVerticalScrollbar", 1454 | "value": "1 << 14" 1455 | }, 1456 | { 1457 | "calc_value": 32768, 1458 | "name": "ImGuiWindowFlags_AlwaysHorizontalScrollbar", 1459 | "value": "1<< 15" 1460 | }, 1461 | { 1462 | "calc_value": 65536, 1463 | "name": "ImGuiWindowFlags_AlwaysUseWindowPadding", 1464 | "value": "1 << 16" 1465 | }, 1466 | { 1467 | "calc_value": 262144, 1468 | "name": "ImGuiWindowFlags_NoNavInputs", 1469 | "value": "1 << 18" 1470 | }, 1471 | { 1472 | "calc_value": 524288, 1473 | "name": "ImGuiWindowFlags_NoNavFocus", 1474 | "value": "1 << 19" 1475 | }, 1476 | { 1477 | "calc_value": 786432, 1478 | "name": "ImGuiWindowFlags_NoNav", 1479 | "value": "ImGuiWindowFlags_NoNavInputs | ImGuiWindowFlags_NoNavFocus" 1480 | }, 1481 | { 1482 | "calc_value": 43, 1483 | "name": "ImGuiWindowFlags_NoDecoration", 1484 | "value": "ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoCollapse" 1485 | }, 1486 | { 1487 | "calc_value": 786944, 1488 | "name": "ImGuiWindowFlags_NoInputs", 1489 | "value": "ImGuiWindowFlags_NoMouseInputs | ImGuiWindowFlags_NoNavInputs | ImGuiWindowFlags_NoNavFocus" 1490 | }, 1491 | { 1492 | "calc_value": 8388608, 1493 | "name": "ImGuiWindowFlags_NavFlattened", 1494 | "value": "1 << 23" 1495 | }, 1496 | { 1497 | "calc_value": 16777216, 1498 | "name": "ImGuiWindowFlags_ChildWindow", 1499 | "value": "1 << 24" 1500 | }, 1501 | { 1502 | "calc_value": 33554432, 1503 | "name": "ImGuiWindowFlags_Tooltip", 1504 | "value": "1 << 25" 1505 | }, 1506 | { 1507 | "calc_value": 67108864, 1508 | "name": "ImGuiWindowFlags_Popup", 1509 | "value": "1 << 26" 1510 | }, 1511 | { 1512 | "calc_value": 134217728, 1513 | "name": "ImGuiWindowFlags_Modal", 1514 | "value": "1 << 27" 1515 | }, 1516 | { 1517 | "calc_value": 268435456, 1518 | "name": "ImGuiWindowFlags_ChildMenu", 1519 | "value": "1 << 28" 1520 | } 1521 | ] 1522 | }, 1523 | "structs": { 1524 | "CustomRect": [ 1525 | { 1526 | "name": "ID", 1527 | "type": "unsigned int" 1528 | }, 1529 | { 1530 | "name": "Width", 1531 | "type": "unsigned short" 1532 | }, 1533 | { 1534 | "name": "Height", 1535 | "type": "unsigned short" 1536 | }, 1537 | { 1538 | "name": "X", 1539 | "type": "unsigned short" 1540 | }, 1541 | { 1542 | "name": "Y", 1543 | "type": "unsigned short" 1544 | }, 1545 | { 1546 | "name": "GlyphAdvanceX", 1547 | "type": "float" 1548 | }, 1549 | { 1550 | "name": "GlyphOffset", 1551 | "type": "ImVec2" 1552 | }, 1553 | { 1554 | "name": "Font", 1555 | "type": "ImFont*" 1556 | } 1557 | ], 1558 | "GlyphRangesBuilder": [ 1559 | { 1560 | "name": "UsedChars", 1561 | "template_type": "unsigned char", 1562 | "type": "ImVector_unsigned_char" 1563 | } 1564 | ], 1565 | "ImColor": [ 1566 | { 1567 | "name": "Value", 1568 | "type": "ImVec4" 1569 | } 1570 | ], 1571 | "ImDrawChannel": [ 1572 | { 1573 | "name": "CmdBuffer", 1574 | "template_type": "ImDrawCmd", 1575 | "type": "ImVector_ImDrawCmd" 1576 | }, 1577 | { 1578 | "name": "IdxBuffer", 1579 | "template_type": "ImDrawIdx", 1580 | "type": "ImVector_ImDrawIdx" 1581 | } 1582 | ], 1583 | "ImDrawCmd": [ 1584 | { 1585 | "name": "ElemCount", 1586 | "type": "unsigned int" 1587 | }, 1588 | { 1589 | "name": "ClipRect", 1590 | "type": "ImVec4" 1591 | }, 1592 | { 1593 | "name": "TextureId", 1594 | "type": "ImTextureID" 1595 | }, 1596 | { 1597 | "name": "UserCallback", 1598 | "type": "ImDrawCallback" 1599 | }, 1600 | { 1601 | "name": "UserCallbackData", 1602 | "type": "void*" 1603 | } 1604 | ], 1605 | "ImDrawData": [ 1606 | { 1607 | "name": "Valid", 1608 | "type": "bool" 1609 | }, 1610 | { 1611 | "name": "CmdLists", 1612 | "type": "ImDrawList**" 1613 | }, 1614 | { 1615 | "name": "CmdListsCount", 1616 | "type": "int" 1617 | }, 1618 | { 1619 | "name": "TotalIdxCount", 1620 | "type": "int" 1621 | }, 1622 | { 1623 | "name": "TotalVtxCount", 1624 | "type": "int" 1625 | }, 1626 | { 1627 | "name": "DisplayPos", 1628 | "type": "ImVec2" 1629 | }, 1630 | { 1631 | "name": "DisplaySize", 1632 | "type": "ImVec2" 1633 | } 1634 | ], 1635 | "ImDrawList": [ 1636 | { 1637 | "name": "CmdBuffer", 1638 | "template_type": "ImDrawCmd", 1639 | "type": "ImVector_ImDrawCmd" 1640 | }, 1641 | { 1642 | "name": "IdxBuffer", 1643 | "template_type": "ImDrawIdx", 1644 | "type": "ImVector_ImDrawIdx" 1645 | }, 1646 | { 1647 | "name": "VtxBuffer", 1648 | "template_type": "ImDrawVert", 1649 | "type": "ImVector_ImDrawVert" 1650 | }, 1651 | { 1652 | "name": "Flags", 1653 | "type": "ImDrawListFlags" 1654 | }, 1655 | { 1656 | "name": "_Data", 1657 | "type": "const ImDrawListSharedData*" 1658 | }, 1659 | { 1660 | "name": "_OwnerName", 1661 | "type": "const char*" 1662 | }, 1663 | { 1664 | "name": "_VtxCurrentIdx", 1665 | "type": "unsigned int" 1666 | }, 1667 | { 1668 | "name": "_VtxWritePtr", 1669 | "type": "ImDrawVert*" 1670 | }, 1671 | { 1672 | "name": "_IdxWritePtr", 1673 | "type": "ImDrawIdx*" 1674 | }, 1675 | { 1676 | "name": "_ClipRectStack", 1677 | "template_type": "ImVec4", 1678 | "type": "ImVector_ImVec4" 1679 | }, 1680 | { 1681 | "name": "_TextureIdStack", 1682 | "template_type": "ImTextureID", 1683 | "type": "ImVector_ImTextureID" 1684 | }, 1685 | { 1686 | "name": "_Path", 1687 | "template_type": "ImVec2", 1688 | "type": "ImVector_ImVec2" 1689 | }, 1690 | { 1691 | "name": "_ChannelsCurrent", 1692 | "type": "int" 1693 | }, 1694 | { 1695 | "name": "_ChannelsCount", 1696 | "type": "int" 1697 | }, 1698 | { 1699 | "name": "_Channels", 1700 | "template_type": "ImDrawChannel", 1701 | "type": "ImVector_ImDrawChannel" 1702 | } 1703 | ], 1704 | "ImDrawVert": [ 1705 | { 1706 | "name": "pos", 1707 | "type": "ImVec2" 1708 | }, 1709 | { 1710 | "name": "uv", 1711 | "type": "ImVec2" 1712 | }, 1713 | { 1714 | "name": "col", 1715 | "type": "ImU32" 1716 | } 1717 | ], 1718 | "ImFont": [ 1719 | { 1720 | "name": "FontSize", 1721 | "type": "float" 1722 | }, 1723 | { 1724 | "name": "Scale", 1725 | "type": "float" 1726 | }, 1727 | { 1728 | "name": "DisplayOffset", 1729 | "type": "ImVec2" 1730 | }, 1731 | { 1732 | "name": "Glyphs", 1733 | "template_type": "ImFontGlyph", 1734 | "type": "ImVector_ImFontGlyph" 1735 | }, 1736 | { 1737 | "name": "IndexAdvanceX", 1738 | "template_type": "float", 1739 | "type": "ImVector_float" 1740 | }, 1741 | { 1742 | "name": "IndexLookup", 1743 | "template_type": "ImWchar", 1744 | "type": "ImVector_ImWchar" 1745 | }, 1746 | { 1747 | "name": "FallbackGlyph", 1748 | "type": "const ImFontGlyph*" 1749 | }, 1750 | { 1751 | "name": "FallbackAdvanceX", 1752 | "type": "float" 1753 | }, 1754 | { 1755 | "name": "FallbackChar", 1756 | "type": "ImWchar" 1757 | }, 1758 | { 1759 | "name": "ConfigDataCount", 1760 | "type": "short" 1761 | }, 1762 | { 1763 | "name": "ConfigData", 1764 | "type": "ImFontConfig*" 1765 | }, 1766 | { 1767 | "name": "ContainerAtlas", 1768 | "type": "ImFontAtlas*" 1769 | }, 1770 | { 1771 | "name": "Ascent", 1772 | "type": "float" 1773 | }, 1774 | { 1775 | "name": "Descent", 1776 | "type": "float" 1777 | }, 1778 | { 1779 | "name": "DirtyLookupTables", 1780 | "type": "bool" 1781 | }, 1782 | { 1783 | "name": "MetricsTotalSurface", 1784 | "type": "int" 1785 | } 1786 | ], 1787 | "ImFontAtlas": [ 1788 | { 1789 | "name": "Locked", 1790 | "type": "bool" 1791 | }, 1792 | { 1793 | "name": "Flags", 1794 | "type": "ImFontAtlasFlags" 1795 | }, 1796 | { 1797 | "name": "TexID", 1798 | "type": "ImTextureID" 1799 | }, 1800 | { 1801 | "name": "TexDesiredWidth", 1802 | "type": "int" 1803 | }, 1804 | { 1805 | "name": "TexGlyphPadding", 1806 | "type": "int" 1807 | }, 1808 | { 1809 | "name": "TexPixelsAlpha8", 1810 | "type": "unsigned char*" 1811 | }, 1812 | { 1813 | "name": "TexPixelsRGBA32", 1814 | "type": "unsigned int*" 1815 | }, 1816 | { 1817 | "name": "TexWidth", 1818 | "type": "int" 1819 | }, 1820 | { 1821 | "name": "TexHeight", 1822 | "type": "int" 1823 | }, 1824 | { 1825 | "name": "TexUvScale", 1826 | "type": "ImVec2" 1827 | }, 1828 | { 1829 | "name": "TexUvWhitePixel", 1830 | "type": "ImVec2" 1831 | }, 1832 | { 1833 | "name": "Fonts", 1834 | "template_type": "ImFont*", 1835 | "type": "ImVector_ImFontPtr" 1836 | }, 1837 | { 1838 | "name": "CustomRects", 1839 | "template_type": "CustomRect", 1840 | "type": "ImVector_CustomRect" 1841 | }, 1842 | { 1843 | "name": "ConfigData", 1844 | "template_type": "ImFontConfig", 1845 | "type": "ImVector_ImFontConfig" 1846 | }, 1847 | { 1848 | "name": "CustomRectIds[1]", 1849 | "size": 1, 1850 | "type": "int" 1851 | } 1852 | ], 1853 | "ImFontConfig": [ 1854 | { 1855 | "name": "FontData", 1856 | "type": "void*" 1857 | }, 1858 | { 1859 | "name": "FontDataSize", 1860 | "type": "int" 1861 | }, 1862 | { 1863 | "name": "FontDataOwnedByAtlas", 1864 | "type": "bool" 1865 | }, 1866 | { 1867 | "name": "FontNo", 1868 | "type": "int" 1869 | }, 1870 | { 1871 | "name": "SizePixels", 1872 | "type": "float" 1873 | }, 1874 | { 1875 | "name": "OversampleH", 1876 | "type": "int" 1877 | }, 1878 | { 1879 | "name": "OversampleV", 1880 | "type": "int" 1881 | }, 1882 | { 1883 | "name": "PixelSnapH", 1884 | "type": "bool" 1885 | }, 1886 | { 1887 | "name": "GlyphExtraSpacing", 1888 | "type": "ImVec2" 1889 | }, 1890 | { 1891 | "name": "GlyphOffset", 1892 | "type": "ImVec2" 1893 | }, 1894 | { 1895 | "name": "GlyphRanges", 1896 | "type": "const ImWchar*" 1897 | }, 1898 | { 1899 | "name": "GlyphMinAdvanceX", 1900 | "type": "float" 1901 | }, 1902 | { 1903 | "name": "GlyphMaxAdvanceX", 1904 | "type": "float" 1905 | }, 1906 | { 1907 | "name": "MergeMode", 1908 | "type": "bool" 1909 | }, 1910 | { 1911 | "name": "RasterizerFlags", 1912 | "type": "unsigned int" 1913 | }, 1914 | { 1915 | "name": "RasterizerMultiply", 1916 | "type": "float" 1917 | }, 1918 | { 1919 | "name": "Name[40]", 1920 | "size": 40, 1921 | "type": "char" 1922 | }, 1923 | { 1924 | "name": "DstFont", 1925 | "type": "ImFont*" 1926 | } 1927 | ], 1928 | "ImFontGlyph": [ 1929 | { 1930 | "name": "Codepoint", 1931 | "type": "ImWchar" 1932 | }, 1933 | { 1934 | "name": "AdvanceX", 1935 | "type": "float" 1936 | }, 1937 | { 1938 | "name": "X0", 1939 | "type": "float" 1940 | }, 1941 | { 1942 | "name": "Y0", 1943 | "type": "float" 1944 | }, 1945 | { 1946 | "name": "X1", 1947 | "type": "float" 1948 | }, 1949 | { 1950 | "name": "Y1", 1951 | "type": "float" 1952 | }, 1953 | { 1954 | "name": "U0", 1955 | "type": "float" 1956 | }, 1957 | { 1958 | "name": "V0", 1959 | "type": "float" 1960 | }, 1961 | { 1962 | "name": "U1", 1963 | "type": "float" 1964 | }, 1965 | { 1966 | "name": "V1", 1967 | "type": "float" 1968 | } 1969 | ], 1970 | "ImGuiIO": [ 1971 | { 1972 | "name": "ConfigFlags", 1973 | "type": "ImGuiConfigFlags" 1974 | }, 1975 | { 1976 | "name": "BackendFlags", 1977 | "type": "ImGuiBackendFlags" 1978 | }, 1979 | { 1980 | "name": "DisplaySize", 1981 | "type": "ImVec2" 1982 | }, 1983 | { 1984 | "name": "DeltaTime", 1985 | "type": "float" 1986 | }, 1987 | { 1988 | "name": "IniSavingRate", 1989 | "type": "float" 1990 | }, 1991 | { 1992 | "name": "IniFilename", 1993 | "type": "const char*" 1994 | }, 1995 | { 1996 | "name": "LogFilename", 1997 | "type": "const char*" 1998 | }, 1999 | { 2000 | "name": "MouseDoubleClickTime", 2001 | "type": "float" 2002 | }, 2003 | { 2004 | "name": "MouseDoubleClickMaxDist", 2005 | "type": "float" 2006 | }, 2007 | { 2008 | "name": "MouseDragThreshold", 2009 | "type": "float" 2010 | }, 2011 | { 2012 | "name": "KeyMap[ImGuiKey_COUNT]", 2013 | "size": 21, 2014 | "type": "int" 2015 | }, 2016 | { 2017 | "name": "KeyRepeatDelay", 2018 | "type": "float" 2019 | }, 2020 | { 2021 | "name": "KeyRepeatRate", 2022 | "type": "float" 2023 | }, 2024 | { 2025 | "name": "UserData", 2026 | "type": "void*" 2027 | }, 2028 | { 2029 | "name": "Fonts", 2030 | "type": "ImFontAtlas*" 2031 | }, 2032 | { 2033 | "name": "FontGlobalScale", 2034 | "type": "float" 2035 | }, 2036 | { 2037 | "name": "FontAllowUserScaling", 2038 | "type": "bool" 2039 | }, 2040 | { 2041 | "name": "FontDefault", 2042 | "type": "ImFont*" 2043 | }, 2044 | { 2045 | "name": "DisplayFramebufferScale", 2046 | "type": "ImVec2" 2047 | }, 2048 | { 2049 | "name": "DisplayVisibleMin", 2050 | "type": "ImVec2" 2051 | }, 2052 | { 2053 | "name": "DisplayVisibleMax", 2054 | "type": "ImVec2" 2055 | }, 2056 | { 2057 | "name": "MouseDrawCursor", 2058 | "type": "bool" 2059 | }, 2060 | { 2061 | "name": "ConfigMacOSXBehaviors", 2062 | "type": "bool" 2063 | }, 2064 | { 2065 | "name": "ConfigInputTextCursorBlink", 2066 | "type": "bool" 2067 | }, 2068 | { 2069 | "name": "ConfigResizeWindowsFromEdges", 2070 | "type": "bool" 2071 | }, 2072 | { 2073 | "name": "BackendPlatformName", 2074 | "type": "const char*" 2075 | }, 2076 | { 2077 | "name": "BackendRendererName", 2078 | "type": "const char*" 2079 | }, 2080 | { 2081 | "name": "GetClipboardTextFn", 2082 | "type": "const char*(*)(void* user_data)" 2083 | }, 2084 | { 2085 | "name": "SetClipboardTextFn", 2086 | "type": "void(*)(void* user_data,const char* text)" 2087 | }, 2088 | { 2089 | "name": "ClipboardUserData", 2090 | "type": "void*" 2091 | }, 2092 | { 2093 | "name": "ImeSetInputScreenPosFn", 2094 | "type": "void(*)(int x,int y)" 2095 | }, 2096 | { 2097 | "name": "ImeWindowHandle", 2098 | "type": "void*" 2099 | }, 2100 | { 2101 | "name": "RenderDrawListsFnUnused", 2102 | "type": "void*" 2103 | }, 2104 | { 2105 | "name": "MousePos", 2106 | "type": "ImVec2" 2107 | }, 2108 | { 2109 | "name": "MouseDown[5]", 2110 | "size": 5, 2111 | "type": "bool" 2112 | }, 2113 | { 2114 | "name": "MouseWheel", 2115 | "type": "float" 2116 | }, 2117 | { 2118 | "name": "MouseWheelH", 2119 | "type": "float" 2120 | }, 2121 | { 2122 | "name": "KeyCtrl", 2123 | "type": "bool" 2124 | }, 2125 | { 2126 | "name": "KeyShift", 2127 | "type": "bool" 2128 | }, 2129 | { 2130 | "name": "KeyAlt", 2131 | "type": "bool" 2132 | }, 2133 | { 2134 | "name": "KeySuper", 2135 | "type": "bool" 2136 | }, 2137 | { 2138 | "name": "KeysDown[512]", 2139 | "size": 512, 2140 | "type": "bool" 2141 | }, 2142 | { 2143 | "name": "InputCharacters[16+1]", 2144 | "size": 17, 2145 | "type": "ImWchar" 2146 | }, 2147 | { 2148 | "name": "NavInputs[ImGuiNavInput_COUNT]", 2149 | "size": 21, 2150 | "type": "float" 2151 | }, 2152 | { 2153 | "name": "WantCaptureMouse", 2154 | "type": "bool" 2155 | }, 2156 | { 2157 | "name": "WantCaptureKeyboard", 2158 | "type": "bool" 2159 | }, 2160 | { 2161 | "name": "WantTextInput", 2162 | "type": "bool" 2163 | }, 2164 | { 2165 | "name": "WantSetMousePos", 2166 | "type": "bool" 2167 | }, 2168 | { 2169 | "name": "WantSaveIniSettings", 2170 | "type": "bool" 2171 | }, 2172 | { 2173 | "name": "NavActive", 2174 | "type": "bool" 2175 | }, 2176 | { 2177 | "name": "NavVisible", 2178 | "type": "bool" 2179 | }, 2180 | { 2181 | "name": "Framerate", 2182 | "type": "float" 2183 | }, 2184 | { 2185 | "name": "MetricsRenderVertices", 2186 | "type": "int" 2187 | }, 2188 | { 2189 | "name": "MetricsRenderIndices", 2190 | "type": "int" 2191 | }, 2192 | { 2193 | "name": "MetricsRenderWindows", 2194 | "type": "int" 2195 | }, 2196 | { 2197 | "name": "MetricsActiveWindows", 2198 | "type": "int" 2199 | }, 2200 | { 2201 | "name": "MetricsActiveAllocations", 2202 | "type": "int" 2203 | }, 2204 | { 2205 | "name": "MouseDelta", 2206 | "type": "ImVec2" 2207 | }, 2208 | { 2209 | "name": "MousePosPrev", 2210 | "type": "ImVec2" 2211 | }, 2212 | { 2213 | "name": "MouseClickedPos[5]", 2214 | "size": 5, 2215 | "type": "ImVec2" 2216 | }, 2217 | { 2218 | "name": "MouseClickedTime[5]", 2219 | "size": 5, 2220 | "type": "double" 2221 | }, 2222 | { 2223 | "name": "MouseClicked[5]", 2224 | "size": 5, 2225 | "type": "bool" 2226 | }, 2227 | { 2228 | "name": "MouseDoubleClicked[5]", 2229 | "size": 5, 2230 | "type": "bool" 2231 | }, 2232 | { 2233 | "name": "MouseReleased[5]", 2234 | "size": 5, 2235 | "type": "bool" 2236 | }, 2237 | { 2238 | "name": "MouseDownOwned[5]", 2239 | "size": 5, 2240 | "type": "bool" 2241 | }, 2242 | { 2243 | "name": "MouseDownDuration[5]", 2244 | "size": 5, 2245 | "type": "float" 2246 | }, 2247 | { 2248 | "name": "MouseDownDurationPrev[5]", 2249 | "size": 5, 2250 | "type": "float" 2251 | }, 2252 | { 2253 | "name": "MouseDragMaxDistanceAbs[5]", 2254 | "size": 5, 2255 | "type": "ImVec2" 2256 | }, 2257 | { 2258 | "name": "MouseDragMaxDistanceSqr[5]", 2259 | "size": 5, 2260 | "type": "float" 2261 | }, 2262 | { 2263 | "name": "KeysDownDuration[512]", 2264 | "size": 512, 2265 | "type": "float" 2266 | }, 2267 | { 2268 | "name": "KeysDownDurationPrev[512]", 2269 | "size": 512, 2270 | "type": "float" 2271 | }, 2272 | { 2273 | "name": "NavInputsDownDuration[ImGuiNavInput_COUNT]", 2274 | "size": 21, 2275 | "type": "float" 2276 | }, 2277 | { 2278 | "name": "NavInputsDownDurationPrev[ImGuiNavInput_COUNT]", 2279 | "size": 21, 2280 | "type": "float" 2281 | } 2282 | ], 2283 | "ImGuiInputTextCallbackData": [ 2284 | { 2285 | "name": "EventFlag", 2286 | "type": "ImGuiInputTextFlags" 2287 | }, 2288 | { 2289 | "name": "Flags", 2290 | "type": "ImGuiInputTextFlags" 2291 | }, 2292 | { 2293 | "name": "UserData", 2294 | "type": "void*" 2295 | }, 2296 | { 2297 | "name": "EventChar", 2298 | "type": "ImWchar" 2299 | }, 2300 | { 2301 | "name": "EventKey", 2302 | "type": "ImGuiKey" 2303 | }, 2304 | { 2305 | "name": "Buf", 2306 | "type": "char*" 2307 | }, 2308 | { 2309 | "name": "BufTextLen", 2310 | "type": "int" 2311 | }, 2312 | { 2313 | "name": "BufSize", 2314 | "type": "int" 2315 | }, 2316 | { 2317 | "name": "BufDirty", 2318 | "type": "bool" 2319 | }, 2320 | { 2321 | "name": "CursorPos", 2322 | "type": "int" 2323 | }, 2324 | { 2325 | "name": "SelectionStart", 2326 | "type": "int" 2327 | }, 2328 | { 2329 | "name": "SelectionEnd", 2330 | "type": "int" 2331 | } 2332 | ], 2333 | "ImGuiListClipper": [ 2334 | { 2335 | "name": "StartPosY", 2336 | "type": "float" 2337 | }, 2338 | { 2339 | "name": "ItemsHeight", 2340 | "type": "float" 2341 | }, 2342 | { 2343 | "name": "ItemsCount", 2344 | "type": "int" 2345 | }, 2346 | { 2347 | "name": "StepNo", 2348 | "type": "int" 2349 | }, 2350 | { 2351 | "name": "DisplayStart", 2352 | "type": "int" 2353 | }, 2354 | { 2355 | "name": "DisplayEnd", 2356 | "type": "int" 2357 | } 2358 | ], 2359 | "ImGuiOnceUponAFrame": [ 2360 | { 2361 | "name": "RefFrame", 2362 | "type": "int" 2363 | } 2364 | ], 2365 | "ImGuiPayload": [ 2366 | { 2367 | "name": "Data", 2368 | "type": "void*" 2369 | }, 2370 | { 2371 | "name": "DataSize", 2372 | "type": "int" 2373 | }, 2374 | { 2375 | "name": "SourceId", 2376 | "type": "ImGuiID" 2377 | }, 2378 | { 2379 | "name": "SourceParentId", 2380 | "type": "ImGuiID" 2381 | }, 2382 | { 2383 | "name": "DataFrameCount", 2384 | "type": "int" 2385 | }, 2386 | { 2387 | "name": "DataType[32+1]", 2388 | "size": 33, 2389 | "type": "char" 2390 | }, 2391 | { 2392 | "name": "Preview", 2393 | "type": "bool" 2394 | }, 2395 | { 2396 | "name": "Delivery", 2397 | "type": "bool" 2398 | } 2399 | ], 2400 | "ImGuiSizeCallbackData": [ 2401 | { 2402 | "name": "UserData", 2403 | "type": "void*" 2404 | }, 2405 | { 2406 | "name": "Pos", 2407 | "type": "ImVec2" 2408 | }, 2409 | { 2410 | "name": "CurrentSize", 2411 | "type": "ImVec2" 2412 | }, 2413 | { 2414 | "name": "DesiredSize", 2415 | "type": "ImVec2" 2416 | } 2417 | ], 2418 | "ImGuiStorage": [ 2419 | { 2420 | "name": "Data", 2421 | "template_type": "Pair", 2422 | "type": "ImVector_Pair" 2423 | } 2424 | ], 2425 | "ImGuiStyle": [ 2426 | { 2427 | "name": "Alpha", 2428 | "type": "float" 2429 | }, 2430 | { 2431 | "name": "WindowPadding", 2432 | "type": "ImVec2" 2433 | }, 2434 | { 2435 | "name": "WindowRounding", 2436 | "type": "float" 2437 | }, 2438 | { 2439 | "name": "WindowBorderSize", 2440 | "type": "float" 2441 | }, 2442 | { 2443 | "name": "WindowMinSize", 2444 | "type": "ImVec2" 2445 | }, 2446 | { 2447 | "name": "WindowTitleAlign", 2448 | "type": "ImVec2" 2449 | }, 2450 | { 2451 | "name": "ChildRounding", 2452 | "type": "float" 2453 | }, 2454 | { 2455 | "name": "ChildBorderSize", 2456 | "type": "float" 2457 | }, 2458 | { 2459 | "name": "PopupRounding", 2460 | "type": "float" 2461 | }, 2462 | { 2463 | "name": "PopupBorderSize", 2464 | "type": "float" 2465 | }, 2466 | { 2467 | "name": "FramePadding", 2468 | "type": "ImVec2" 2469 | }, 2470 | { 2471 | "name": "FrameRounding", 2472 | "type": "float" 2473 | }, 2474 | { 2475 | "name": "FrameBorderSize", 2476 | "type": "float" 2477 | }, 2478 | { 2479 | "name": "ItemSpacing", 2480 | "type": "ImVec2" 2481 | }, 2482 | { 2483 | "name": "ItemInnerSpacing", 2484 | "type": "ImVec2" 2485 | }, 2486 | { 2487 | "name": "TouchExtraPadding", 2488 | "type": "ImVec2" 2489 | }, 2490 | { 2491 | "name": "IndentSpacing", 2492 | "type": "float" 2493 | }, 2494 | { 2495 | "name": "ColumnsMinSpacing", 2496 | "type": "float" 2497 | }, 2498 | { 2499 | "name": "ScrollbarSize", 2500 | "type": "float" 2501 | }, 2502 | { 2503 | "name": "ScrollbarRounding", 2504 | "type": "float" 2505 | }, 2506 | { 2507 | "name": "GrabMinSize", 2508 | "type": "float" 2509 | }, 2510 | { 2511 | "name": "GrabRounding", 2512 | "type": "float" 2513 | }, 2514 | { 2515 | "name": "ButtonTextAlign", 2516 | "type": "ImVec2" 2517 | }, 2518 | { 2519 | "name": "DisplayWindowPadding", 2520 | "type": "ImVec2" 2521 | }, 2522 | { 2523 | "name": "DisplaySafeAreaPadding", 2524 | "type": "ImVec2" 2525 | }, 2526 | { 2527 | "name": "MouseCursorScale", 2528 | "type": "float" 2529 | }, 2530 | { 2531 | "name": "AntiAliasedLines", 2532 | "type": "bool" 2533 | }, 2534 | { 2535 | "name": "AntiAliasedFill", 2536 | "type": "bool" 2537 | }, 2538 | { 2539 | "name": "CurveTessellationTol", 2540 | "type": "float" 2541 | }, 2542 | { 2543 | "name": "Colors[ImGuiCol_COUNT]", 2544 | "size": 43, 2545 | "type": "ImVec4" 2546 | } 2547 | ], 2548 | "ImGuiTextBuffer": [ 2549 | { 2550 | "name": "Buf", 2551 | "template_type": "char", 2552 | "type": "ImVector_char" 2553 | } 2554 | ], 2555 | "ImGuiTextFilter": [ 2556 | { 2557 | "name": "InputBuf[256]", 2558 | "size": 256, 2559 | "type": "char" 2560 | }, 2561 | { 2562 | "name": "Filters", 2563 | "template_type": "TextRange", 2564 | "type": "ImVector_TextRange" 2565 | }, 2566 | { 2567 | "name": "CountGrep", 2568 | "type": "int" 2569 | } 2570 | ], 2571 | "ImVec2": [ 2572 | { 2573 | "name": "x", 2574 | "type": "float" 2575 | }, 2576 | { 2577 | "name": "y", 2578 | "type": "float" 2579 | } 2580 | ], 2581 | "ImVec4": [ 2582 | { 2583 | "name": "x", 2584 | "type": "float" 2585 | }, 2586 | { 2587 | "name": "y", 2588 | "type": "float" 2589 | }, 2590 | { 2591 | "name": "z", 2592 | "type": "float" 2593 | }, 2594 | { 2595 | "name": "w", 2596 | "type": "float" 2597 | } 2598 | ], 2599 | "ImVector": [], 2600 | "Pair": [ 2601 | { 2602 | "name": "key", 2603 | "type": "ImGuiID" 2604 | }, 2605 | { 2606 | "name": "}", 2607 | "type": "union { int val_i; float val_f; void* val_p;" 2608 | } 2609 | ], 2610 | "TextRange": [ 2611 | { 2612 | "name": "b", 2613 | "type": "const char*" 2614 | }, 2615 | { 2616 | "name": "e", 2617 | "type": "const char*" 2618 | } 2619 | ] 2620 | } 2621 | } --------------------------------------------------------------------------------