├── .gitignore ├── .gitmodules ├── .haxerc ├── LICENSE ├── README.md ├── completion.hxml ├── gen-cpp.hxml ├── gen-cpp ├── GenerateCPP.hx └── ImGuiJsonCPP.hx ├── gen-js.hxml ├── gen-js ├── GenerateJS.hx └── ImGuiJsonJS.hx ├── gen ├── ImGuiJsonTypes.hx └── StringBufChainer.hx ├── haxe_libraries ├── exception.hxml ├── hxcpp.hxml ├── hxjsonast.hxml ├── json2object.hxml └── safety.hxml ├── haxelib.json ├── korefile.js ├── package-lock.json ├── src ├── imgui │ ├── Helpers.hx │ ├── ImGui.hx │ └── Types.hx ├── imguicpp │ ├── BoolPointer.hx │ ├── CharPointer.hx │ ├── FloatPointer.hx │ ├── Helpers.hx │ ├── ImGui.hx │ ├── IntPointer.hx │ ├── TextBuffer.hx │ ├── VoidPointer.hx │ ├── linc │ │ ├── Linc.hx │ │ ├── linc_imgui.cpp │ │ ├── linc_imgui.h │ │ └── linc_imgui.xml │ └── utils │ │ ├── VarConstCharStar.hx │ │ └── VarPointer.hx └── imguijs │ ├── Helpers.hx │ └── ImGui.hx └── test ├── cli ├── Main.hx └── build.hxml └── kha ├── Assets └── hxlogo.png ├── Libraries └── .gitkeep ├── README.md ├── Sources ├── ImGuiDemo.hx ├── Main.hx └── Shaders │ ├── imgui.frag.glsl │ └── imgui.vert.glsl └── khafile.js /.gitignore: -------------------------------------------------------------------------------- 1 | cpp 2 | bin 3 | export 4 | build 5 | korefile.js 6 | .vscode 7 | node_modules -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "lib/cimgui"] 2 | path = lib/cimgui 3 | url = https://github.com/cimgui/cimgui 4 | [submodule "lib/imgui-js"] 5 | path = lib/imgui-js 6 | url = https://github.com/flyover/imgui-js.git 7 | -------------------------------------------------------------------------------- /.haxerc: -------------------------------------------------------------------------------- 1 | { 2 | "version": "4.0.5", 3 | "resolveLibs": "scoped" 4 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Aidan Lee 4 | Copyright (c) 2021 Jeremy Faivre 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Dear ImGui for Haxe 2 | 3 | Haxe bindings for [Dear ImGui](https://github.com/ocornut/imgui). 4 | 5 | This library is a continuation of the great work from @Aidan63 on [linc_imgui](https://github.com/Aidan63/linc_imgui). 6 | 7 | --- 8 | 9 | imgui-hx can currently be used with the following Haxe targets: 10 | - C++ 11 | - Javascript (using [imgui-js](https://github.com/flyover/imgui-js)) 12 | 13 | --- 14 | ### Install 15 | 16 | `haxelib git imgui-hx https://github.com/jeremyfa/imgui-hx` 17 | 18 | ### Usage (C++) 19 | 20 | The API follows the ImGui C++ API with most functions and attributes having a haxe equivalent with the same name. When the API wants a ImTextureID (c++ void*) you can use the cpp.Pointer class and rawCast() / reinterpret() to convert to and from whatever classes your framework uses. 21 | 22 | For functions which take and modify a float (e.g. colour edits, float inputs / sliders) the float must be a cpp.Float32 type, not a default Haxe float. When creating types such as Vec2 and Vec4 the floats passed to the create method do not need to be explicitly defined as a cpp.Float32 since it is not permanently modifying that variable. 23 | 24 | ### Usage (Javascript) 25 | 26 | Bindings are intended to be as close as possible to original C++ imgui implementation. 27 | 28 | That means it should be possible to write a single ImGui code that works seemlessly on both C++ and JS targets. 29 | 30 | Please note that javascript bindings are very recent and might not match exactly what is actually available from [imgui-js](https://github.com/flyover/imgui-js). That said, this should be iteratively improved in the future. 31 | 32 | ### Reporting errors 33 | 34 | This is a new binding so there's bound to be missing and / or non-working functions and features. If you find them please create a new issue so it can be fixed. Pull Requests are also welcome. 35 | 36 | ### Setup in project/engine 37 | 38 | There is no setup guide at the moment, but if you want to setup and use Dear ImGui into your own project/engine, you could take a look at the [imgui plugin](https://github.com/ceramic-engine/ceramic/tree/master/plugins/imgui/runtime/src/ceramic) for ceramic engine, which contain code to make Dear ImGui work with both C++ and JS targets. 39 | 40 | When targetting C++, it is using Dear ImGui's built-in backend (SDL + opengl) which should make integration easier on your own engine, if based on opengl as well. 41 | 42 | When targetting JS, it loads `imgui.umd.js` and `imgui_impl.umd.js` that you can find in [imgui-js dist directory](https://github.com/flyover/imgui-js/tree/08f05fb0f47e02978e4aa52e5a2b9b206e06998d/dist). These files are required as they contain Dear ImGui Web Assembly module. 43 | 44 | ImGui's Metal/DirectX backends are not handled in imgui-hx bindings yet, and when using SDL + opengl, it is expected that your project uses `linc_sdl` and `linc_opengl` libraries, but pull requests are welcome to make the bindings work with more various environments. 45 | 46 | Once everything is setup, you can, in any haxe file of your project: 47 | 48 | 1. Import Dear ImGui and additional haxe helpers 49 | 50 | ```haxe 51 | import imgui.ImGui; 52 | import imgui.Helpers.*; 53 | ``` 54 | 55 | 2. Start creating UI by adding code that is executed at every frame of your app 56 | 57 | ```haxe 58 | var someFloatValue:Float = 0.0; 59 | 60 | function someUpdateLoopMethod() { 61 | 62 | // Create a small ImGui window to edit a float value 63 | 64 | ImGui.begin('Hello'); 65 | 66 | ImGui.sliderFloat('Some slider', fromFloat(someFloatValue), 0.0, 1.0); 67 | 68 | if (someFloatValue == 1.0) { 69 | ImGui.text('Float value is at MAX (1.0)'); 70 | } 71 | 72 | ImGui.end(); 73 | 74 | } 75 | ``` 76 | -------------------------------------------------------------------------------- /completion.hxml: -------------------------------------------------------------------------------- 1 | -cp gen 2 | -cp src 3 | 4 | -lib safety 5 | -lib json2object 6 | 7 | -main Main 8 | 9 | -cpp out 10 | 11 | --no-output -------------------------------------------------------------------------------- /gen-cpp.hxml: -------------------------------------------------------------------------------- 1 | -cp gen 2 | -cp gen-cpp 3 | 4 | -lib safety 5 | -lib json2object 6 | 7 | --run GenerateCPP -------------------------------------------------------------------------------- /gen-cpp/GenerateCPP.hx: -------------------------------------------------------------------------------- 1 | 2 | import haxe.macro.Printer; 3 | import sys.io.File; 4 | import ImGuiJsonCPP; 5 | 6 | using StringBufChainer; 7 | using StringTools; 8 | 9 | class GenerateCPP 10 | { 11 | static function main() 12 | { 13 | final printer = new Printer(); 14 | final buffer = new StringBuf(); 15 | final reader = new ImGuiJsonCPP( 16 | File.getContent('lib/cimgui/generator/output/typedefs_dict.json'), 17 | File.getContent('lib/cimgui/generator/output/structs_and_enums.json'), 18 | File.getContent('lib/cimgui/generator/output/definitions.json')); 19 | 20 | buffer.append('package imguicpp;'); 21 | buffer.newline(); 22 | buffer.newline(); 23 | 24 | for (type in reader.generateTypedefs()) 25 | { 26 | buffer.append(printer.printTypeDefinition(type, false)); 27 | buffer.newline(); 28 | buffer.newline(); 29 | } 30 | 31 | for (type in reader.generateEnums()) 32 | { 33 | buffer.append(printer.printTypeDefinition(type, false)); 34 | buffer.newline(); 35 | buffer.newline(); 36 | } 37 | 38 | for (type in reader.generateStructs()) 39 | { 40 | buffer.append(printer.printTypeDefinition(type, false)); 41 | buffer.newline(); 42 | buffer.newline(); 43 | } 44 | 45 | buffer.append(printer.printTypeDefinition(reader.generateTopLevelFunctions(), false)); 46 | buffer.newline(); 47 | buffer.newline(); 48 | 49 | for (type in reader.generateImVectors()) 50 | { 51 | buffer.append(printer.printTypeDefinition(type, false)); 52 | buffer.newline(); 53 | buffer.newline(); 54 | } 55 | 56 | File.saveContent('src/imguicpp/ImGui.hx', buffer.toString()); 57 | 58 | var wrappedMethods = reader.retrieveTopLevelWrappedMethods(); 59 | var headerData = new StringBuf(); 60 | var implData = new StringBuf(); 61 | 62 | for (method in wrappedMethods) { 63 | 64 | headerData.tabSpaces(); 65 | headerData.add(method.ret); 66 | headerData.add(' linc_'); 67 | headerData.add(method.funcname); 68 | headerData.add(method.argsoriginal.replace('((void*)0)', 'NULL').replace(',', ', ')); 69 | headerData.add(';'); 70 | headerData.newline(); 71 | headerData.newline(); 72 | 73 | if (method.funcname == 'Selectable') { 74 | trace(haxe.Json.stringify(method, null, ' ')); 75 | } 76 | 77 | var argsImpl = []; 78 | var lastArgName = null; 79 | var isVaArgs = false; 80 | var argsOriginal = method.argsoriginal.split(','); 81 | var argN = 0; 82 | for (arg in method.argsT) { 83 | var argType = arg.type; 84 | if (argsOriginal[argN].startsWith(argType)) { 85 | var afterType = argsOriginal[argN].substring(argType.length); 86 | if (afterType.startsWith('&')) { 87 | argType += '&'; 88 | } 89 | } 90 | if (argType.endsWith(']')) { 91 | var index = argType.lastIndexOf('['); 92 | argsImpl.push(argType.substring(0, index) + ' ' + arg.name + argType.substring(index)); 93 | } 94 | else if (argType.contains('(*)')) { 95 | argsImpl.push(argType.replace('(*)', '(*${arg.name})')); 96 | } 97 | else if (argType == '...') { 98 | argsImpl.push('...'); 99 | isVaArgs = true; 100 | lastArgName = method.argsT[method.argsT.length - 2].name; 101 | } 102 | else { 103 | argsImpl.push(argType + ' ' + arg.name); 104 | } 105 | argN++; 106 | } 107 | 108 | implData.tabSpaces(); 109 | implData.add(method.ret); 110 | implData.add(' linc_'); 111 | implData.add(method.funcname); 112 | implData.add('('); 113 | implData.add(argsImpl.join(', ')); 114 | implData.add(')'); 115 | implData.add(' {'); 116 | if (isVaArgs) { 117 | implData.newline(); 118 | implData.tabSpaces(); 119 | implData.tabSpaces(); 120 | implData.add('va_list _args;'); 121 | implData.newline(); 122 | implData.tabSpaces(); 123 | implData.tabSpaces(); 124 | implData.add('va_start(_args, $lastArgName);'); 125 | } 126 | implData.newline(); 127 | implData.tabSpaces(); 128 | implData.tabSpaces(); 129 | if (method.ret != 'void') { 130 | implData.add(method.ret); 131 | implData.add(' _res = '); 132 | } 133 | implData.add('ImGui::'); 134 | implData.add(method.funcname); 135 | if (isVaArgs) { 136 | implData.add('V'); 137 | } 138 | implData.add(method.call_args.replace('...', '_args')); 139 | implData.add(';'); 140 | implData.newline(); 141 | implData.tabSpaces(); 142 | implData.tabSpaces(); 143 | implData.add('if (linc_Helpers_flushCallbacks != NULL) (*linc_Helpers_flushCallbacks)();'); 144 | if (method.ret != 'void') { 145 | implData.newline(); 146 | implData.tabSpaces(); 147 | implData.tabSpaces(); 148 | implData.add('return _res;'); 149 | } 150 | implData.newline(); 151 | implData.tabSpaces(); 152 | implData.add('}'); 153 | implData.newline(); 154 | implData.newline(); 155 | 156 | } 157 | 158 | var lincImguiH = '#pragma once 159 | 160 | #ifndef HXCPP_H 161 | #include 162 | #endif 163 | 164 | #include "imgui.h" 165 | 166 | namespace ImGui { 167 | 168 | extern void (*linc_Helpers_flushCallbacks)(void); 169 | 170 | ${headerData.toString()} 171 | 172 | } 173 | '; 174 | 175 | var lincImguiCPP = '//hxcpp include should be first 176 | #include 177 | #include "./linc_imgui.h" 178 | 179 | namespace ImGui { 180 | 181 | void (*linc_Helpers_flushCallbacks)(void) = NULL; 182 | 183 | ${implData.toString()} 184 | 185 | } 186 | '; 187 | 188 | File.saveContent('src/imguicpp/linc/linc_imgui.h', lincImguiH); 189 | File.saveContent('src/imguicpp/linc/linc_imgui.cpp', lincImguiCPP); 190 | 191 | var exposedTypes = []; 192 | for (fn in reader.retrieveAllConstructors()) { 193 | var type = fn.funcname; 194 | if (type == 'ImVector') 195 | type = 'ImVector'; 196 | if (!exposedTypes.contains(type)) { 197 | exposedTypes.push(type); 198 | } 199 | } 200 | 201 | for (type in reader.generateEnums()) { 202 | if (!exposedTypes.contains(type.name)) { 203 | exposedTypes.push(type.name); 204 | } 205 | } 206 | 207 | for (type in [ 208 | 'ImGuiWindowPtr', 'ImWchar32', 'ImWchar16', 'ImWchar', 'ImU8', 'ImU64', 'ImU32', 'ImU16', 'ImTextureID', 209 | 'ImS8', 'ImS64', 'ImS32', 'ImS16', 'ImPoolIdx', 'ImGuiTableDrawChannelIdx', 'ImGuiTableColumnIdx', 'ImGuiSizeCallback', 210 | 'ImGuiInputTextCallback', 'ImGuiID', 'ImGuiErrorLogCallback', 'ImGuiContextHookCallback', 'ImFileHandle', 211 | 'ImDrawIdx', 'ImDrawCallback' 212 | ]) { 213 | if (!exposedTypes.contains(type)) { 214 | exposedTypes.push(type); 215 | } 216 | } 217 | 218 | var rootImGuiHx = []; 219 | var inJsBlock = false; 220 | var didDumpTypedefs = false; 221 | for (line in File.getContent('src/imgui/ImGui.hx').replace('\r','').split('\n')) { 222 | if (!inJsBlock) { 223 | if (!didDumpTypedefs && line.trim() == '#if cpp') { 224 | rootImGuiHx.push(line); 225 | inJsBlock = true; 226 | didDumpTypedefs = true; 227 | 228 | rootImGuiHx.push('typedef ImGui = imguicpp.ImGui;'); 229 | for (type in exposedTypes) { 230 | rootImGuiHx.push('typedef ' + type + ' = imguicpp.ImGui.' + type + ';'); 231 | } 232 | } 233 | else { 234 | rootImGuiHx.push(line); 235 | } 236 | } 237 | else { 238 | if (line.trim() == '#end') { 239 | inJsBlock = false; 240 | rootImGuiHx.push(line); 241 | } 242 | } 243 | } 244 | var isWindows:Bool = (Sys.systemName() == 'Windows'); 245 | File.saveContent('src/imgui/ImGui.hx', rootImGuiHx.join(isWindows ? '\r\n' : '\n')); 246 | 247 | } 248 | 249 | } 250 | -------------------------------------------------------------------------------- /gen-cpp/ImGuiJsonCPP.hx: -------------------------------------------------------------------------------- 1 | 2 | import json2object.JsonParser; 3 | import haxe.macro.Expr; 4 | import haxe.macro.Context; 5 | import ImGuiJsonTypes; 6 | 7 | using StringTools; 8 | using Lambda; 9 | using Safety; 10 | 11 | class ImGuiJsonCPP 12 | { 13 | final typedefs : JsonTypedef; 14 | final enumStruct : JsonEnumStruct; 15 | final definitions : JsonDefinitions; 16 | 17 | var abstractPtrs = true; 18 | 19 | public function new(_typedefs : String, _enumStruct : String, _definitions : String) 20 | { 21 | typedefs = new JsonParser>().fromJson(_typedefs); 22 | enumStruct = new JsonParser().fromJson(_enumStruct); 23 | definitions = new JsonParser().fromJson(_definitions); 24 | } 25 | 26 | /** 27 | * Generate type definitions for all typedef aliases found in the json. 28 | * Ignores flags, structs, and iterators and they are generated else where. 29 | * @return Array 30 | */ 31 | public function generateTypedefs() : Array 32 | { 33 | final gen = [ 34 | { pack: [ 'imguicpp' ], name: 'FILE', pos: null, fields: [], kind: TDAlias(parseNativeString('void')) }, 35 | { pack: [ 'imguicpp' ], name: 'ImGuiWindowPtr', pos: null, fields: [], kind: TDAlias(parseNativeString('void')) } 36 | ]; 37 | 38 | abstractPtrs = false; 39 | 40 | for (name => value in typedefs) 41 | { 42 | if (name == 'iterator' || 43 | name == 'const_iterator' || 44 | name == 'value_type' || 45 | name.endsWith('Flags') || 46 | value.contains('struct ')) 47 | { 48 | continue; 49 | } 50 | 51 | if (enumStruct.enums.exists('${ name }_') || enumStruct.enums.exists(name)) 52 | { 53 | continue; 54 | } 55 | 56 | gen.push({ pack: [ 'imguicpp' ], name: name, pos: null, fields: [], kind: TDAlias(parseNativeString(value)) }); 57 | } 58 | 59 | abstractPtrs = true; 60 | 61 | return gen; 62 | } 63 | 64 | /** 65 | * Generate type definitions for all the enums found in the json. 66 | * Integer based abstract enums are generated with implicit to and from int conversions. 67 | * 68 | * The json definition enum names are post fixed with `_` so we substring the last character away. 69 | * Enum members are also prefixed with the enum struct they belong to, so we remove that from each enum members name. 70 | * @return Array 71 | */ 72 | public function generateEnums() : Array 73 | { 74 | return [ 75 | for (name => values in enumStruct.enums) 76 | { 77 | pack : [ 'imguicpp' ], 78 | kind : TDAbstract(macro : Int, [ macro : Int ], [ macro : Int ]), 79 | name : if (name.endsWith('_')) name.substr(0, name.length - 1) else name, 80 | pos : null, 81 | meta : [ { name: ':enum', pos : null } ], 82 | fields : [ for (value in values) { 83 | name : value.name.replace(name, ''), 84 | kind : FVar(macro : Int, { pos: null, expr: EConst(CInt('${value.calc_value}')) }), 85 | pos : null, 86 | } ] 87 | } 88 | ]; 89 | } 90 | 91 | /** 92 | * Generate externs for each struct in the enums and structs json. 93 | * Also searches the definitions json for functions which belong to each struct. 94 | * 95 | * Destructors are not current generated, stack based constructors only right now. 96 | * @return Array 97 | */ 98 | public function generateStructs() : Array 99 | { 100 | final structs = []; 101 | 102 | final tmp = macro class ImGuiDockRequest {}; 103 | tmp.isExtern = true; 104 | tmp.meta = [ 105 | { name: ':keep', pos : null }, 106 | { name: ':structAccess', pos : null }, 107 | { name: ':include', pos : null, params: [ macro $i{ '"imgui.h"' } ] }, 108 | { name: ':native', pos : null, params: [ macro $i{ '"ImGuiDockRequest"' } ] } 109 | ]; 110 | structs.push(tmp); 111 | 112 | final tmp = macro class ImGuiDockNodeSettings {}; 113 | tmp.isExtern = true; 114 | tmp.meta = [ 115 | { name: ':keep', pos : null }, 116 | { name: ':structAccess', pos : null }, 117 | { name: ':include', pos : null, params: [ macro $i{ '"imgui.h"' } ] }, 118 | { name: ':native', pos : null, params: [ macro $i{ '"ImGuiDockNodeSettings"' } ] } 119 | ]; 120 | structs.push(tmp); 121 | 122 | for (name => values in enumStruct.structs) 123 | { 124 | final struct = macro class $name {}; 125 | struct.isExtern = true; 126 | struct.meta = [ 127 | { name: ':keep', pos : null }, 128 | { name: ':structAccess', pos : null }, 129 | { name: ':include', pos : null, params: [ macro $i{ '"imgui.h"' } ] }, 130 | { name: ':native', pos : null, params: [ macro $i{ '"$name"' } ] } 131 | ]; 132 | 133 | // Generate fields 134 | for (value in values) 135 | { 136 | // Ignore union types for now 137 | if (value.type.contains('union {')) 138 | { 139 | continue; 140 | } 141 | 142 | if (value.type.startsWith('STB_')) 143 | { 144 | continue; 145 | } 146 | 147 | // Need to do proper cleanup on the final name 148 | // Quick hack works around it for now... 149 | var finalType; 150 | var finalName = value.name.replace('[2]', ''); 151 | 152 | if (value.template_type != '') 153 | { 154 | // TODO : Very lazy and should be improved. 155 | // Exactly one of the templated types is also a pointer, so do a quick check and manually wrap it. 156 | // Can't use parseNativeType as we need a user friendly string name, not the actual type 157 | if (value.template_type.contains('*') && !value.template_type.contains('*OrIndex')) 158 | { 159 | final ctInner = TPath({ pack : [ ], name : 'ImVector${value.template_type.replace('*', '')}Pointer' }); 160 | 161 | finalType = macro : cpp.Star<$ctInner>; 162 | } 163 | else 164 | { 165 | finalType = TPath({ pack : [ ], name : 'ImVector${value.template_type.replace(' ', '').replace('*', 'Ptr')}' }); 166 | } 167 | } 168 | else 169 | { 170 | // Get the corresponding (and potentially simplified) complex type. 171 | final ctType = parseNativeString(value.type); 172 | 173 | // If its an array type wrap it in a pointer. 174 | // cpp.Star doesn't allow array access so we need to use the old cpp.RawPointer. 175 | if (value.size > 0) 176 | { 177 | // Attempt to simplify again now that its wrapped in a raw pointer 178 | finalName = value.name.split('[')[0]; 179 | finalType = simplifyComplexType(macro : cpp.RawPointer<$ctType>); 180 | } 181 | else 182 | { 183 | finalType = ctType; 184 | } 185 | } 186 | 187 | struct.fields.push({ 188 | name : getHaxefriendlyName(finalName), 189 | kind : FVar(finalType), 190 | pos : null, 191 | meta : [ { name: ':native', pos : null, params: [ macro $i{ '"$finalName"' } ] } ] 192 | }); 193 | } 194 | 195 | for (field in generateFunctionFieldsArray( 196 | definitions.map(f -> f.filter(i -> i.stname == name && !i.destructor)), false)) 197 | { 198 | struct.fields.push(field); 199 | } 200 | 201 | structs.push(struct); 202 | } 203 | 204 | return structs; 205 | } 206 | 207 | /** 208 | * Generate an ImVector generic and sub classes for all found ImVectors. 209 | * Same as structs, no descructors and stack based constructors only. 210 | * @return Array 211 | */ 212 | public function generateImVectors() : Array 213 | { 214 | final generatedVectors = []; 215 | final imVectorClass = macro class ImVector { 216 | @:native('Data') var data : cpp.RawPointer; 217 | }; 218 | imVectorClass.isExtern = true; 219 | imVectorClass.meta = [ 220 | { name: ':keep', pos : null }, 221 | { name: ':structAccess', pos : null }, 222 | { name: ':include', pos : null, params: [ macro $i{ '"imgui.h"' } ] }, 223 | { name: ':native', pos : null, params: [ macro $i{ '"ImVector"' } ] } 224 | ]; 225 | imVectorClass.fields = imVectorClass.fields.concat(generateFunctionFieldsArray( 226 | definitions.map(f -> f.filter(i -> !i.constructor && !i.destructor && i.templated && i.stname == 'ImVector')), false)); 227 | 228 | generatedVectors.push(imVectorClass); 229 | 230 | // Compile a list of all known vector templates 231 | // Search the argument and variable types of all structs and functions. 232 | final templatedTypes = []; 233 | for (_ => fields in enumStruct.structs) 234 | { 235 | for (field in fields) 236 | { 237 | if (field.template_type != '') 238 | { 239 | if (!templatedTypes.has(field.template_type)) 240 | { 241 | templatedTypes.push(field.template_type); 242 | } 243 | } 244 | } 245 | } 246 | for (_ => overloads in definitions) 247 | { 248 | for (overloadFn in overloads) 249 | { 250 | if (overloadFn.constructor || overloadFn.destructor || overloadFn.templated) 251 | { 252 | continue; 253 | } 254 | 255 | if (overloadFn.ret.startsWith('ImVector_')) 256 | { 257 | final templatedType = overloadFn.ret.replace('ImVector_', ''); 258 | if (!templatedTypes.has(templatedType)) 259 | { 260 | templatedTypes.push(templatedType); 261 | } 262 | } 263 | 264 | for (arg in overloadFn.argsT) 265 | { 266 | if (arg.type.startsWith('ImVector_')) 267 | { 268 | final templatedType = arg.type.replace('ImVector_', ''); 269 | if (!templatedTypes.has(templatedType)) 270 | { 271 | templatedTypes.push(templatedType); 272 | } 273 | } 274 | } 275 | } 276 | } 277 | 278 | // Generate an extern for each templated type 279 | for (templatedType in templatedTypes) 280 | { 281 | templatedType = templatedType.replace('*OrIndex', 'PtrOrIndex'); 282 | templatedType = templatedType.replace('const_charPtr*', 'const char*'); 283 | 284 | final ct = parseNativeString(templatedType); 285 | var name = cleanNativeType(templatedType).replace(' ', ''); 286 | 287 | for (_ in 0...occurance(templatedType, '*')) 288 | { 289 | name += 'Pointer'; 290 | } 291 | 292 | final fullname = 'ImVector$name'; 293 | final templated = macro class $fullname extends ImVector<$ct> {}; 294 | templated.isExtern = true; 295 | templated.meta = [ 296 | { name: ':keep', pos : null }, 297 | { name: ':structAccess', pos : null }, 298 | { name: ':include', pos : null, params: [ macro $i{ '"imgui.h"' } ] }, 299 | { name: ':native', pos : null, params: [ macro $i{ '"ImVector<$templatedType>"' } ] } 300 | ]; 301 | 302 | // Add constructors for each imvector child 303 | // Has a standard constructor and one which copies from another vector of the same type. 304 | final constructor : Field = { 305 | name : 'create', 306 | pos : null, 307 | access : [ AStatic ], kind: FFun(generateFunctionAst(fullname, false, [], false)) 308 | }; 309 | constructor.meta = [ 310 | { name : ':native', pos : null, params : [ macro $i{ '"ImVector<$templatedType>"' } ] }, 311 | { 312 | name : ':overload', 313 | pos : null, 314 | params : [ 315 | { 316 | expr : EFunction(FAnonymous, generateFunctionAst(fullname, false, [ { 317 | name : 'src', 318 | type : fullname, 319 | signature : '' 320 | } ], true)), 321 | pos : null 322 | } 323 | ] 324 | } 325 | ]; 326 | 327 | templated.fields.push(constructor); 328 | 329 | generatedVectors.push(templated); 330 | } 331 | 332 | return generatedVectors; 333 | } 334 | 335 | /** 336 | * Generate an empty extern, needed to create context type. 337 | * @param _name Name of the extern to generate. 338 | * @return TypeDefinition 339 | */ 340 | public function generateEmptyExtern(_name : String) : TypeDefinition 341 | { 342 | final def = macro class $_name {}; 343 | def.isExtern = true; 344 | def.meta = [ 345 | { name: ':keep', pos : null }, 346 | { name: ':structAccess', pos : null }, 347 | { name: ':include', pos : null, params: [ macro $i{ '"imgui.h"' } ] }, 348 | { name: ':native', pos : null, params: [ macro $i{ '"$_name"' } ] } 349 | ]; 350 | 351 | return def; 352 | } 353 | 354 | /** 355 | * Generate the the type definition for the extern class which will contain all the top level static imgui functions. 356 | * @return TypeDefinition 357 | */ 358 | public function generateTopLevelFunctions() : TypeDefinition 359 | { 360 | final topLevelClass = macro class ImGui { }; 361 | topLevelClass.fields = generateFunctionFieldsArray(definitions.map(f -> f.filter(i -> i.stname == '' && (i.location != null && i.location.startsWith('imgui:')))), true); 362 | topLevelClass.isExtern = true; 363 | topLevelClass.meta = [ 364 | { name: ':keep', pos : null }, 365 | { name: ':structAccess', pos : null }, 366 | { name: ':include', pos : null, params: [ macro $i{ '"linc_imgui.h"' } ] }, 367 | { name: ':build', pos : null, params: [ macro imguicpp.linc.Linc.xml('imgui') ] }, 368 | { name: ':build', pos : null, params: [ macro imguicpp.linc.Linc.touch() ] } 369 | ]; 370 | 371 | return topLevelClass; 372 | } 373 | 374 | public function topLevelFunctionNeedsWrapping(fn : JsonFunction, ?list : Array):Bool { 375 | 376 | var needsWrapping = false; 377 | if (fn.argsT.length > 0 && fn.argsT[fn.argsT.length-1].type == '...') { 378 | if (!fn.funcname.startsWith('Log') || fn.funcname.charAt(3).toLowerCase() == fn.funcname.charAt(3)) { 379 | needsWrapping = true; 380 | } 381 | } 382 | else if (fn.funcname == 'End') { 383 | needsWrapping = true; 384 | } 385 | else { 386 | for (arg in fn.argsT) { 387 | var parsedType = parseNativeString(arg.type); 388 | switch parsedType { 389 | default: 390 | case TPath(p): 391 | if (p.pack.length == 1 && p.pack[0] == 'imguicpp') { 392 | if (p.name.endsWith('Pointer')) { 393 | needsWrapping = true; 394 | break; 395 | } 396 | } 397 | } 398 | } 399 | } 400 | 401 | if (!needsWrapping && list != null) { 402 | for (item in list) { 403 | if (item != fn && item.funcname == fn.funcname) { 404 | if (topLevelFunctionNeedsWrapping(item)) { 405 | needsWrapping = true; 406 | break; 407 | } 408 | } 409 | } 410 | } 411 | 412 | return needsWrapping; 413 | 414 | } 415 | 416 | public function retrieveTopLevelWrappedMethods() : Array { 417 | 418 | var topLevelDefinitions = definitions.map(f -> f.filter(i -> i.stname == '' && (i.location != null && i.location.startsWith('imgui:')))); 419 | var result = []; 420 | 421 | for (overloads in topLevelDefinitions.filter(a -> a.length > 0)) 422 | { 423 | // Check if we need to wrap this method 424 | var needsWrapping = false; 425 | for (overloadedFn in overloads) 426 | { 427 | if (topLevelFunctionNeedsWrapping(overloadedFn, overloads)) { 428 | result.push(overloadedFn); 429 | } 430 | } 431 | } 432 | 433 | return result; 434 | 435 | } 436 | 437 | public function retrieveAllConstructors() : Array { 438 | 439 | var filteredDefinitions = definitions.map(f -> f.filter(i -> i.stname != '' && (i.location != null && i.location.startsWith('imgui:')))); 440 | var result = []; 441 | 442 | for (overloads in filteredDefinitions.filter(a -> a.length > 0)) 443 | { 444 | for (overloadedFn in overloads) 445 | { 446 | if (overloadedFn.constructor) { 447 | result.push(overloadedFn); 448 | } 449 | } 450 | } 451 | 452 | return result; 453 | 454 | } 455 | 456 | /** 457 | * Generates a array of field function definitions. 458 | * Overloads are generated based on actual overloads and arguments with default values. 459 | * In haxe default values must be constant, so we use overloads for this. 460 | * @param _overloads Array of all pre-defined overloads for functions. 461 | * @param _isTopLevel If this function is to be generated as a static function. 462 | * @return Array field functions in the type definition format. 463 | */ 464 | function generateFunctionFieldsArray(_overloads : Array>, _isTopLevel : Bool) : Array 465 | { 466 | final fields = []; 467 | final wrappers = []; 468 | 469 | for (overloads in _overloads.filter(a -> a.length > 0)) 470 | { 471 | var baseFn = null; 472 | 473 | // Check if we need to wrap this method 474 | var needsWrapping = false; 475 | if (_isTopLevel) { 476 | for (overloadedFn in overloads) 477 | { 478 | needsWrapping = topLevelFunctionNeedsWrapping(overloadedFn); 479 | if (needsWrapping) 480 | break; 481 | } 482 | } 483 | 484 | for (overloadedFn in overloads) 485 | { 486 | // Needed to match actual bindings, which differ from cimgui 487 | if (_isTopLevel) { 488 | if (overloadedFn.funcname.startsWith('GetItemRect')) { 489 | if (overloadedFn.ret == 'void' && overloadedFn.argsT.length == 1) { 490 | overloadedFn.ret = overloadedFn.argsT[0].type.replace('*',''); 491 | overloadedFn.argsT = []; 492 | } 493 | } 494 | } 495 | 496 | var hasVaArgs = false; 497 | if (overloadedFn.argsT.length > 0 && overloadedFn.argsT[overloadedFn.argsT.length-1].type == '...') { 498 | hasVaArgs = true; 499 | } 500 | 501 | if (baseFn == null) 502 | { 503 | baseFn = generateFunction(overloadedFn, _isTopLevel, overloadedFn.constructor, needsWrapping, hasVaArgs); 504 | // if (needsWrapping) { 505 | // baseFn.name = '_' + baseFn.name; 506 | // } 507 | if (hasVaArgs) { 508 | baseFn.meta.push({ 509 | name : ':overload', 510 | pos : null, 511 | params : [ { pos: null, expr: EFunction(FAnonymous, generateFunctionAst( 512 | overloadedFn.constructor ? overloadedFn.stname : overloadedFn.retorig.or(overloadedFn.ret), 513 | overloadedFn.retref == '&', 514 | overloadedFn.argsT.copy(), 515 | true)) } ] 516 | }); 517 | } 518 | } 519 | else 520 | { 521 | if (hasVaArgs) { 522 | baseFn.meta.push({ 523 | name : ':overload', 524 | pos : null, 525 | params : [ { pos: null, expr: EFunction(FAnonymous, generateFunctionAst( 526 | overloadedFn.constructor ? overloadedFn.stname : overloadedFn.retorig.or(overloadedFn.ret), 527 | overloadedFn.retref == '&', 528 | overloadedFn.argsT.filter(i -> i.type != '...'), 529 | true)) } ] 530 | }); 531 | } 532 | 533 | baseFn.meta.push({ 534 | name : ':overload', 535 | pos : null, 536 | params : [ { pos: null, expr: EFunction(FAnonymous, generateFunctionAst( 537 | overloadedFn.constructor ? overloadedFn.stname : overloadedFn.retorig.or(overloadedFn.ret), 538 | overloadedFn.retref == '&', 539 | overloadedFn.argsT.copy(), 540 | true)) } ] 541 | }); 542 | } 543 | 544 | // if (needsWrapping) { 545 | // var wrapper = generateFunctionWrapper(overloadedFn, _isTopLevel, overloadedFn.constructor); 546 | // wrappers.push(wrapper); 547 | // } 548 | 549 | // For each overloaded function also look at the default values. 550 | // Generate additional overloads by filtering the aguments based on a growing list of arguments to remove. 551 | // We pop from the list as default arguments 552 | final defaults = [ for (k in overloadedFn.defaults.keys()) k ]; 553 | final filtered = []; 554 | 555 | while (defaults.length > 0) 556 | { 557 | filtered.push(defaults.pop()); 558 | 559 | baseFn.meta.push({ 560 | name : ':overload', 561 | pos : null, 562 | params : [ { pos: null, expr: EFunction(FAnonymous, generateFunctionAst( 563 | overloadedFn.constructor ? overloadedFn.stname : overloadedFn.retorig.or(overloadedFn.ret), 564 | overloadedFn.retref == '&', 565 | overloadedFn.argsT.filter(i -> !filtered.has(i.name)), 566 | true)) } ] 567 | }); 568 | } 569 | } 570 | 571 | fields.push(baseFn); 572 | 573 | if (wrappers.length > 1) { 574 | for (wrapper in wrappers) { 575 | wrapper.access.push(AExtern); 576 | wrapper.access.push(AOverload); 577 | } 578 | } 579 | while (wrappers.length > 0) { 580 | fields.push(wrappers.shift()); 581 | } 582 | } 583 | 584 | return fields; 585 | } 586 | 587 | /** 588 | * Generates a field function type definiton from a json definition. 589 | * @param _function Json definition to generate a function from. 590 | * @param _isTopLevel If the function doesn't belong to a struct. 591 | * If true the function is generated as static and the native type is prefixed with the `ImGui::` namespace. 592 | * @param _isConstructor if this function is a constructor. 593 | * @param _wrapped if this function is wrapped. 594 | * @param _filterVaArgs if we should remove ... arg. 595 | * @return Field 596 | */ 597 | function generateFunction(_function : JsonFunction, _isTopLevel : Bool, _isConstructor : Bool, _wrapped : Bool, _filterVaArgs : Bool = false) : Field 598 | { 599 | final nativeType = _isTopLevel ? 'ImGui::${(_wrapped ? 'linc_' : '') + _function.funcname}' : _function.funcname; 600 | final funcName = _isConstructor ? 'create' : getHaxefriendlyName(_function.funcname); 601 | final returnType = _isConstructor ? _function.stname : _function.retorig.or(_function.ret); 602 | 603 | final args = _filterVaArgs ? _function.argsT.filter(i -> i.type != '...') : _function.argsT.copy(); 604 | 605 | return { 606 | name : funcName, 607 | pos : null, 608 | access : _isTopLevel || _isConstructor ? [ AStatic ] : [], 609 | kind : FFun(generateFunctionAst(returnType, _function.retref == '&', args, false)), 610 | meta : [ 611 | { name: ':native', pos : null, params: [ macro $i{ '"$nativeType"' } ] } 612 | ] 613 | } 614 | } 615 | 616 | /** 617 | * Generates a field function wrapper from a json definition. 618 | * @param _function Json definition to generate a function from. 619 | * @param _isTopLevel If the function doesn't belong to a struct. 620 | * If true the function is generated as static and the native type is prefixed with the `ImGui::` namespace. 621 | * @param _isConstructor if this function is a constructor. 622 | * @return Field 623 | */ 624 | function generateFunctionWrapper(_function : JsonFunction, _isTopLevel : Bool, _isConstructor : Bool, ?filtered : Array) : Field 625 | { 626 | final funcName = _isConstructor ? 'create' : getHaxefriendlyName(_function.funcname); 627 | final returnType = _isConstructor ? _function.stname : _function.retorig.or(_function.ret); 628 | 629 | var funcArgs; 630 | if (filtered != null) { 631 | funcArgs = _function.argsT.filter(i -> !filtered.has(i.name)); 632 | } 633 | else { 634 | funcArgs = _function.argsT.copy(); 635 | } 636 | 637 | return { 638 | name : funcName, 639 | pos : null, 640 | access : _isTopLevel || _isConstructor ? [ AStatic, AInline ] : [ AInline ], 641 | kind : FFun(generateFunctionWrapperAst(_function, returnType, _function.retref == '&', funcArgs)), 642 | meta : [ 643 | ] 644 | } 645 | } 646 | 647 | /** 648 | * Generates an AST representation of a function. 649 | * AST representations do not contain a function name, this type is then wrapped in an anonymous and function expr or type definition. 650 | * @param _return String of the native return type. 651 | * @param _reference If the return type is a reference. 652 | * @param _args Array of arguments for this function. 653 | * @param _block If this function should be generated with an EBlock expr (needed for correct overload syntax). 654 | * @return Function 655 | */ 656 | function generateFunctionAst(_return : String, _reference : Bool, _args : Array, _block : Bool) : Function 657 | { 658 | // If the first argument is called 'self' then thats part of cimgui 659 | // we can safely remove it as we aren't using the c bindings code. 660 | if (_args.length > 0) 661 | { 662 | if (_args[0].name == 'self') 663 | { 664 | _args.shift(); 665 | } 666 | } 667 | 668 | return { 669 | expr : _block ? { expr: EBlock([]), pos : null } : null, 670 | ret : buildReturnType(parseNativeString(_return), _reference), 671 | args : [ for (arg in _args) generateFunctionArg(arg.name, arg.type) ] 672 | } 673 | } 674 | 675 | /** 676 | * Generates an AST representation of a function wrapper. 677 | * AST representations do not contain a function name, this type is then wrapped in an anonymous and function expr or type definition. 678 | * @param _function Json definition of the function being wrapped. 679 | * @param _return String of the native return type. 680 | * @param _reference If the return type is a reference. 681 | * @param _args Array of arguments for this function. 682 | * @return Function 683 | */ 684 | function generateFunctionWrapperAst(_function : JsonFunction, _return : String, _reference : Bool, _args : Array) : Function 685 | { 686 | // If the first argument is called 'self' then thats part of cimgui 687 | // we can safely remove it as we aren't using the c bindings code. 688 | if (_args.length > 0) 689 | { 690 | if (_args[0].name == 'self') 691 | { 692 | _args.shift(); 693 | } 694 | } 695 | 696 | final funcName = getHaxefriendlyName(_function.funcname); 697 | final retComplexType = parseNativeString(_return); 698 | 699 | var isVoid = false; 700 | switch retComplexType { 701 | default: 702 | case TPath(p): 703 | if (p.name == 'Void') { 704 | isVoid = true; 705 | } 706 | } 707 | 708 | final defaults = [ for (k in _function.defaults.keys()) k ]; 709 | final defaultsForCall = [ for (k in _function.defaults.keys()) k ]; 710 | final filtered = []; 711 | 712 | var exprStr = '{'; 713 | if (!isVoid) { 714 | exprStr += 'var _res = '; 715 | } 716 | if (defaultsForCall.length == 0) { 717 | exprStr += '_' + funcName + '('; 718 | for (i in 0..._args.length) { 719 | var arg = _args[i]; 720 | if (i > 0) { 721 | exprStr += ', '; 722 | } 723 | exprStr += getHaxefriendlyName(arg.name); 724 | } 725 | exprStr += ');'; 726 | } 727 | else { 728 | var n = 0; 729 | do { 730 | var i = 0; 731 | if (n > 0) { 732 | filtered.push(defaultsForCall.pop()); 733 | exprStr += 'else '; 734 | } 735 | if (defaultsForCall.length > 0) { 736 | exprStr += 'if ('; 737 | i = 0; 738 | for (argName in defaultsForCall) { 739 | if (i > 0) { 740 | exprStr += ' && '; 741 | } 742 | exprStr += getHaxefriendlyName(argName) + ' != null'; 743 | i++; 744 | } 745 | exprStr += ') {'; 746 | } 747 | else { 748 | exprStr += '{'; 749 | } 750 | exprStr += '_' + funcName + '('; 751 | i = 0; 752 | for (arg in _args) { 753 | if (filtered.indexOf(arg.name) == -1) { 754 | if (i > 0) { 755 | exprStr += ', '; 756 | } 757 | exprStr += getHaxefriendlyName(arg.name); 758 | i++; 759 | } 760 | } 761 | exprStr += ');'; 762 | exprStr += '}'; 763 | n++; 764 | } 765 | while (defaultsForCall.length > 0); 766 | 767 | } 768 | exprStr += 'imguicpp.Helpers.flushCallbacks();'; 769 | if (!isVoid) { 770 | exprStr += 'return _res;'; 771 | } 772 | exprStr += '}'; 773 | 774 | var funcExpr = Context.parse( 775 | exprStr, 776 | Context.currentPos() 777 | ); 778 | 779 | return { 780 | expr : funcExpr, 781 | ret : buildReturnType(isVoid ? macro :Void : retComplexType, _reference), 782 | args : [ for (arg in _args) { generateFunctionArg(arg.name, arg.type, defaults.indexOf(arg.name) != -1, true); } ] 783 | } 784 | } 785 | 786 | /** 787 | * Generate a function argument AST representation. 788 | * @param _name name of the argument. 789 | * Will prefix this with and _ to avoid collisions with haxe preserved keyworks and will force the first character to a lower case. 790 | * @param _type Native type of this argument. 791 | * @param _opt Whether the argument is optional or not. 792 | * @param _wrapper Whether the argument is generated for a function wrapper. 793 | * @return FunctionArg 794 | */ 795 | function generateFunctionArg(_name : String, _type : String, _opt : Bool = false, _wrapper : Bool = false) : FunctionArg 796 | { 797 | var argType = parseNativeString(_type); 798 | 799 | // switch argType { 800 | // default: 801 | // case TPath(p): 802 | // if (p.pack.length == 2 && p.pack[0] == 'imguicpp' && p.pack[1] == 'utils') { 803 | // if (p.name == 'VarConstCharStar') { 804 | // argType = macro :String; 805 | // } 806 | // } 807 | // } 808 | 809 | return { 810 | name : '${ getHaxefriendlyName(_name) }', 811 | type : argType, 812 | opt: _opt 813 | } 814 | } 815 | 816 | /** 817 | * Parse the provided string containing a native c type into the equivilent haxe type. 818 | * Currently parses pointer types and functions. 819 | * @param _in Native c type. 820 | * @return ComplexType 821 | */ 822 | function parseNativeString(_in : String) : ComplexType 823 | { 824 | if (_in.contains('(*)')) 825 | { 826 | return parseFunction(_in); 827 | } 828 | else 829 | { 830 | return parseType(_in); 831 | } 832 | } 833 | 834 | function parseType(_in : String, _nativeVoid = true) : ComplexType 835 | { 836 | // count how many pointer levels then strip any of that away 837 | final const = _in.contains('const'); 838 | final pointer = occurance(_in, '*'); 839 | final refType = occurance(_in, '&'); 840 | final cleaned = cleanNativeType(_in); 841 | var ct; 842 | 843 | if (_in.contains('ImVector_const_charPtr*')) 844 | { 845 | return macro : ImVectorcharPointer; 846 | } 847 | 848 | if (cleaned.startsWith('ImVector_')) 849 | { 850 | var hxType = cleaned.replace('ImVector_', ''); 851 | for (_ in 0...pointer) 852 | { 853 | hxType += 'Pointer'; 854 | } 855 | 856 | return TPath({ pack: [ ], name: 'ImVector$hxType' }); 857 | } 858 | 859 | if (cleaned.contains('[')) 860 | { 861 | // Array types use cpp.RawPointer instead of cpp.Star to allow array access 862 | // Also allows us to pattern match against it and generate abstracts to easy array <-> pointer interop. 863 | 864 | final arrayType = _in.split('[')[0]; 865 | final hxType = parseType(arrayType); 866 | 867 | ct = macro : cpp.RawPointer<$hxType>; 868 | } 869 | else 870 | { 871 | ct = getHaxeType(cleaned, _nativeVoid); 872 | 873 | // Get the base complex type, then wrap it in as many pointer as is required. 874 | for (_ in 0...pointer) 875 | { 876 | if (const) 877 | { 878 | ct = macro : cpp.RawConstPointer<$ct>; 879 | } 880 | else 881 | { 882 | ct = macro : cpp.Star<$ct>; 883 | } 884 | } 885 | for (_ in 0...refType) 886 | { 887 | ct = macro : cpp.Reference<$ct>; 888 | } 889 | 890 | ct = simplifyComplexType(ct); 891 | } 892 | 893 | return simplifyComplexType(ct); 894 | } 895 | 896 | function parseFunction(_in : String) : ComplexType 897 | { 898 | final returnType = _in.split('(*)')[0]; 899 | final bracketedArgs = _in.split('(*)')[1]; 900 | final splitArgs = bracketedArgs.substr(1, bracketedArgs.length - 2).split(','); 901 | 902 | final ctArgs = []; 903 | for (arg in splitArgs) 904 | { 905 | final split = arg.split(' '); 906 | 907 | final name = split.pop(); 908 | 909 | if (name.contains('...')) 910 | { 911 | ctArgs.push(macro : haxe.extern.Rest); 912 | } 913 | else 914 | { 915 | final type = split.join(' '); 916 | 917 | abstractPtrs = false; 918 | 919 | ctArgs.push(parseNativeString(type)); 920 | 921 | abstractPtrs = true; 922 | } 923 | } 924 | 925 | final ctParams = TFunction(ctArgs, parseType(returnType, false)); 926 | 927 | return macro : cpp.Callable<$ctParams>; 928 | } 929 | 930 | function buildReturnType(_ct : ComplexType, _reference : Bool) 931 | { 932 | if (_reference) 933 | { 934 | switch _ct 935 | { 936 | case TPath(p): 937 | // If the return type is a reference and the outer-most complex type is a pointer 938 | // Strip that pointer off and make it a reference instead. 939 | if (p.name == 'Star') 940 | { 941 | return TPath({ pack: [ 'cpp' ], name: 'Reference', params: p.params }); 942 | } 943 | case _: 944 | } 945 | } 946 | 947 | return _ct; 948 | } 949 | 950 | function getHaxeType(_in : String, _nativeVoid = true) : ComplexType 951 | { 952 | return switch _in.trim() 953 | { 954 | case 'int', 'signed int' : macro : Int; 955 | case 'unsigned int' : macro : UInt; 956 | case 'short', 'signed short' : macro : cpp.Int16; 957 | case 'unsigned short' : macro : cpp.UInt16; 958 | case 'float' : macro : cpp.Float32; 959 | case 'double' : macro : Float; 960 | case 'bool' : macro : Bool; 961 | case 'char', 'const char', '_charPtr' : macro : cpp.Char; 962 | case 'signed char' : macro : cpp.Int8; 963 | case 'unsigned char' : macro : cpp.UInt8; 964 | case 'int64_t' : macro : cpp.Int64; 965 | case 'uint64_t' : macro : cpp.UInt64; 966 | case 'va_list', '...' : macro : cpp.VarArg; 967 | case 'size_t' : macro : cpp.SizeT; 968 | case 'void' : _nativeVoid ? macro : cpp.Void : macro : Void; 969 | case 'T' : macro : T; 970 | case 'ImVector' : macro : ImVector; 971 | case _other: TPath({ pack: [ ], name : _other }); 972 | } 973 | } 974 | 975 | function simplifyComplexType(_ct : ComplexType) : ComplexType 976 | { 977 | switch _ct 978 | { 979 | case TPath(p): 980 | // If we have no type parameters there is no simplification we can make. 981 | if (p.params == null || p.params.length == 0) 982 | { 983 | return _ct; 984 | } 985 | 986 | // Attempt to simplify some base type pointers to a custom abstracts. 987 | // Makes common pointer types easier to deal with. 988 | if (p.name == 'Star' || p.name == 'RawPointer') 989 | { 990 | final inner = getInnerParameter(p.params); 991 | 992 | switch inner.name 993 | { 994 | case 'UInt8' if (abstractPtrs): return macro : imguicpp.CharPointer; 995 | case 'Void' if (abstractPtrs): return macro : imguicpp.VoidPointer; 996 | case 'Int' if (abstractPtrs): return macro : imguicpp.IntPointer; 997 | case 'Float32' if (abstractPtrs): return macro : imguicpp.FloatPointer; 998 | case 'Bool' if (abstractPtrs): return macro : imguicpp.BoolPointer; 999 | case 'Star': 1000 | final inner = getInnerParameter(inner.params); 1001 | 1002 | if (inner.name == 'ImDrawList') 1003 | { 1004 | return macro : cpp.RawPointer>; 1005 | } 1006 | case _: // Not other pointer simplifications at this point 1007 | } 1008 | } 1009 | 1010 | // If we have a RawConstPointer the re-type it as a ConstCharStar 1011 | // else, re-type it in a cpp.Star for easier use 1012 | if (p.name == 'RawConstPointer') 1013 | { 1014 | final inner = getInnerParameter(p.params); 1015 | 1016 | switch inner.name 1017 | { 1018 | case 'Int8', 'UInt8', 'Char': return macro : imguicpp.utils.VarConstCharStar; 1019 | case _: 1020 | final ct = TPath(inner); 1021 | 1022 | return macro : cpp.Star<$ct>; 1023 | } 1024 | } 1025 | case _: 1026 | } 1027 | 1028 | return _ct; 1029 | } 1030 | 1031 | function getInnerParameter(_params : Array) : TypePath 1032 | { 1033 | for (param in _params) 1034 | { 1035 | switch param 1036 | { 1037 | case TPType(t): 1038 | switch t 1039 | { 1040 | case TPath(p): return p; 1041 | case _: 1042 | } 1043 | case _: 1044 | } 1045 | } 1046 | 1047 | return null; 1048 | } 1049 | 1050 | function occurance(_in : String, _search : String) : Int 1051 | { 1052 | var pointer = 0; 1053 | for (i in 0..._in.length) 1054 | { 1055 | if (_in.charAt(i) == _search) 1056 | { 1057 | pointer++; 1058 | } 1059 | } 1060 | 1061 | return pointer; 1062 | } 1063 | 1064 | function getHaxefriendlyName(_in : String) 1065 | { 1066 | if (_in == '...') 1067 | { 1068 | return 'vargs'; 1069 | } 1070 | else if (_in == 'in') 1071 | { 1072 | return '_in'; 1073 | } 1074 | else 1075 | { 1076 | return '${ _in.charAt(0).toLowerCase() }${ _in.substr(1) }'; 1077 | } 1078 | } 1079 | 1080 | static function cleanNativeType(_in : String) : String 1081 | { 1082 | return _in.replace('*', '').replace('const', '').replace('&', '').trim(); 1083 | } 1084 | } 1085 | -------------------------------------------------------------------------------- /gen-js.hxml: -------------------------------------------------------------------------------- 1 | -cp gen 2 | -cp gen-js 3 | 4 | -lib safety 5 | -lib json2object 6 | 7 | --run GenerateJS -------------------------------------------------------------------------------- /gen-js/GenerateJS.hx: -------------------------------------------------------------------------------- 1 | 2 | import haxe.macro.Printer; 3 | import sys.io.File; 4 | import ImGuiJsonJS; 5 | 6 | using StringBufChainer; 7 | using StringTools; 8 | 9 | class GenerateJS 10 | { 11 | static function main() 12 | { 13 | final printer = new Printer(); 14 | final buffer = new StringBuf(); 15 | final reader = new ImGuiJsonJS( 16 | File.getContent('lib/cimgui/generator/output/typedefs_dict.json'), 17 | File.getContent('lib/cimgui/generator/output/structs_and_enums.json'), 18 | File.getContent('lib/cimgui/generator/output/definitions.json')); 19 | 20 | buffer.append('package imguijs;'); 21 | buffer.newline(); 22 | 23 | buffer.append(' 24 | typedef Int16 = Int; 25 | 26 | typedef UInt16 = UInt; 27 | 28 | typedef Float32 = Float; 29 | 30 | typedef Char = Dynamic; 31 | 32 | typedef Int8 = Int; 33 | 34 | typedef UInt8 = UInt; 35 | 36 | typedef Int64 = Int; 37 | 38 | typedef UInt64 = UInt; 39 | 40 | typedef VarArg = Dynamic; 41 | 42 | typedef SizeT = Int; 43 | 44 | typedef Star = Dynamic; 45 | 46 | typedef RawPointer = Dynamic; 47 | 48 | typedef RawConstPointer = Dynamic; 49 | 50 | typedef Reference = Dynamic; 51 | 52 | typedef Callable = Dynamic; 53 | 54 | typedef VoidPointer = Dynamic; 55 | 56 | typedef IntPointer = Dynamic; 57 | 58 | typedef TextPointer = Dynamic; 59 | 60 | typedef FloatPointer = Dynamic; 61 | 62 | typedef CharPointer = Dynamic; 63 | 64 | typedef BoolPointer = Dynamic; 65 | '); 66 | buffer.newline(); 67 | 68 | for (type in reader.generateTypedefs()) 69 | { 70 | buffer.append(printer.printTypeDefinition(type, false)); 71 | buffer.newline(); 72 | buffer.newline(); 73 | } 74 | 75 | for (type in reader.generateEnums()) 76 | { 77 | buffer.append(printer.printTypeDefinition(type, false)); 78 | buffer.newline(); 79 | buffer.newline(); 80 | } 81 | 82 | for (type in reader.generateStructs()) 83 | { 84 | buffer.append(printer.printTypeDefinition(type, false)); 85 | buffer.newline(); 86 | buffer.newline(); 87 | } 88 | 89 | buffer.append(printer.printTypeDefinition(reader.generateTopLevelFunctions(), false)); 90 | buffer.newline(); 91 | buffer.newline(); 92 | 93 | for (type in reader.generateImVectors()) 94 | { 95 | buffer.append(printer.printTypeDefinition(type, false)); 96 | buffer.newline(); 97 | buffer.newline(); 98 | } 99 | 100 | File.saveContent('src/imguijs/ImGui.hx', buffer.toString()); 101 | 102 | var exposedTypes = []; 103 | for (fn in reader.retrieveAllConstructors()) { 104 | var type = fn.funcname; 105 | if (type == 'ImVector') 106 | type = 'ImVector'; 107 | if (!exposedTypes.contains(type)) { 108 | exposedTypes.push(type); 109 | } 110 | } 111 | 112 | for (type in reader.generateEnums()) { 113 | if (!exposedTypes.contains(type.name)) { 114 | exposedTypes.push(type.name); 115 | } 116 | } 117 | 118 | for (type in [ 119 | 'ImGuiWindowPtr', 'ImWchar32', 'ImWchar16', 'ImWchar', 'ImU8', 'ImU64', 'ImU32', 'ImU16', 'ImTextureID', 120 | 'ImS8', 'ImS64', 'ImS32', 'ImS16', 'ImPoolIdx', 'ImGuiTableDrawChannelIdx', 'ImGuiTableColumnIdx', 'ImGuiSizeCallback', 121 | 'ImGuiInputTextCallback', 'ImGuiID', 'ImGuiErrorLogCallback', 'ImGuiContextHookCallback', 'ImFileHandle', 122 | 'ImDrawIdx', 'ImDrawCallback' 123 | ]) { 124 | if (!exposedTypes.contains(type)) { 125 | exposedTypes.push(type); 126 | } 127 | } 128 | 129 | var rootImGuiHx = []; 130 | var inJsBlock = false; 131 | var didDumpTypedefs = false; 132 | for (line in File.getContent('src/imgui/ImGui.hx').replace('\r','').split('\n')) { 133 | if (!inJsBlock) { 134 | if (!didDumpTypedefs && line.trim() == '#if js') { 135 | rootImGuiHx.push(line); 136 | inJsBlock = true; 137 | didDumpTypedefs = true; 138 | 139 | rootImGuiHx.push('typedef ImGui = imguijs.ImGui;'); 140 | for (type in exposedTypes) { 141 | rootImGuiHx.push('typedef ' + type + ' = imguijs.ImGui.' + type + ';'); 142 | } 143 | } 144 | else { 145 | rootImGuiHx.push(line); 146 | } 147 | } 148 | else { 149 | if (line.trim() == '#end') { 150 | inJsBlock = false; 151 | rootImGuiHx.push(line); 152 | } 153 | } 154 | } 155 | var isWindows:Bool = (Sys.systemName() == 'Windows'); 156 | File.saveContent('src/imgui/ImGui.hx', rootImGuiHx.join(isWindows ? '\r\n' : '\n')); 157 | 158 | } 159 | } 160 | -------------------------------------------------------------------------------- /gen-js/ImGuiJsonJS.hx: -------------------------------------------------------------------------------- 1 | 2 | import haxe.macro.Context; 3 | import json2object.JsonParser; 4 | import haxe.macro.Expr; 5 | import ImGuiJsonTypes; 6 | 7 | using StringTools; 8 | using Lambda; 9 | using Safety; 10 | 11 | class ImGuiJsonJS 12 | { 13 | final typedefs : JsonTypedef; 14 | final enumStruct : JsonEnumStruct; 15 | final definitions : JsonDefinitions; 16 | 17 | var abstractPtrs = true; 18 | 19 | public function new(_typedefs : String, _enumStruct : String, _definitions : String) 20 | { 21 | typedefs = new JsonParser>().fromJson(_typedefs); 22 | enumStruct = new JsonParser().fromJson(_enumStruct); 23 | definitions = new JsonParser().fromJson(_definitions); 24 | } 25 | 26 | /** 27 | * Generate type definitions for all typedef aliases found in the json. 28 | * Ignores flags, structs, and iterators and they are generated else where. 29 | * @return Array 30 | */ 31 | public function generateTypedefs() : Array 32 | { 33 | final gen = [ 34 | { pack: [ 'imguijs' ], name: 'FILE', pos: null, fields: [], kind: TDAlias(macro :Dynamic) }, 35 | { pack: [ 'imguijs' ], name: 'ImGuiWindowPtr', pos: null, fields: [], kind: TDAlias(parseNativeString('void')) } 36 | ]; 37 | 38 | abstractPtrs = false; 39 | 40 | for (name => value in typedefs) 41 | { 42 | if (name == 'iterator' || 43 | name == 'const_iterator' || 44 | name == 'value_type' || 45 | name.endsWith('Flags') || 46 | value.contains('struct ')) 47 | { 48 | continue; 49 | } 50 | 51 | if (enumStruct.enums.exists('${ name }_') || enumStruct.enums.exists(name)) 52 | { 53 | continue; 54 | } 55 | 56 | gen.push({ pack: [ 'imguijs' ], name: name, pos: null, fields: [], kind: TDAlias(parseNativeString(value)) }); 57 | } 58 | 59 | abstractPtrs = true; 60 | 61 | return gen; 62 | } 63 | 64 | /** 65 | * Generate type definitions for all the enums found in the json. 66 | * Integer based abstract enums are generated with implicit to and from int conversions. 67 | * 68 | * The json definition enum names are post fixed with `_` so we substring the last character away. 69 | * Enum members are also prefixed with the enum struct they belong to, so we remove that from each enum members name. 70 | * @return Array 71 | */ 72 | public function generateEnums() : Array 73 | { 74 | return [ 75 | for (name => values in enumStruct.enums) 76 | { 77 | pack : [ 'imguijs' ], 78 | kind : TDAbstract(macro : Int, [ macro : Int ], [ macro : Int ]), 79 | name : if (name.endsWith('_')) name.substr(0, name.length - 1) else name, 80 | pos : null, 81 | meta : [ { name: ':enum', pos : null } ], 82 | fields : [ for (value in values) { 83 | name : value.name.replace(name, ''), 84 | kind : FVar(macro : Int, { pos: null, expr: EConst(CInt('${value.calc_value}')) }), 85 | pos : null, 86 | } ] 87 | } 88 | ]; 89 | } 90 | 91 | /** 92 | * Generate externs for each struct in the enums and structs json. 93 | * Also searches the definitions json for functions which belong to each struct. 94 | * 95 | * Destructors are not current generated, stack based constructors only right now. 96 | * @return Array 97 | */ 98 | public function generateStructs() : Array 99 | { 100 | final structs = []; 101 | 102 | final tmp = macro class ImGuiDockRequest {}; 103 | tmp.isExtern = true; 104 | tmp.meta = [ 105 | { name: ':keep', pos : null }, 106 | //{ name: ':structAccess', pos : null }, 107 | //{ name: ':include', pos : null, params: [ macro $i{ '"imgui.h"' } ] }, 108 | { name: ':native', pos : null, params: [ macro $i{ '"ImGuiDockRequest"' } ] } 109 | ]; 110 | structs.push(tmp); 111 | 112 | final tmp = macro class ImGuiDockNodeSettings {}; 113 | tmp.isExtern = true; 114 | tmp.meta = [ 115 | { name: ':keep', pos : null }, 116 | //{ name: ':structAccess', pos : null }, 117 | //{ name: ':include', pos : null, params: [ macro $i{ '"imgui.h"' } ] }, 118 | { name: ':native', pos : null, params: [ macro $i{ '"ImGuiDockNodeSettings"' } ] } 119 | ]; 120 | structs.push(tmp); 121 | 122 | for (name => values in enumStruct.structs) 123 | { 124 | final struct = macro class $name {}; 125 | struct.isExtern = true; 126 | struct.meta = [ 127 | { name: ':keep', pos : null }, 128 | //{ name: ':structAccess', pos : null }, 129 | //{ name: ':include', pos : null, params: [ macro $i{ '"imgui.h"' } ] }, 130 | { name: ':native', pos : null, params: [ macro $i{ '"$name"' } ] } 131 | ]; 132 | 133 | // Generate fields 134 | for (value in values) 135 | { 136 | // Ignore union types for now 137 | if (value.type.contains('union {')) 138 | { 139 | continue; 140 | } 141 | 142 | if (value.type.startsWith('STB_')) 143 | { 144 | continue; 145 | } 146 | 147 | // Need to do proper cleanup on the final name 148 | // Quick hack works around it for now... 149 | var finalType; 150 | var finalName = value.name.replace('[2]', ''); 151 | 152 | if (value.template_type != '') 153 | { 154 | // TODO : Very lazy and should be improved. 155 | // Exactly one of the templated types is also a pointer, so do a quick check and manually wrap it. 156 | // Can't use parseNativeType as we need a user friendly string name, not the actual type 157 | if (value.template_type.contains('*') && !value.template_type.contains('*OrIndex')) 158 | { 159 | final ctInner = TPath({ pack : [ ], name : 'ImVector${value.template_type.replace('*', '')}Pointer' }); 160 | 161 | finalType = macro : imguijs.Star<$ctInner>; 162 | } 163 | else 164 | { 165 | finalType = TPath({ pack : [ ], name : 'ImVector${value.template_type.replace(' ', '').replace('*', 'Ptr')}' }); 166 | } 167 | } 168 | else 169 | { 170 | // Get the corresponding (and potentially simplified) complex type. 171 | final ctType = parseNativeString(value.type); 172 | 173 | // If its an array type wrap it in a pointer. 174 | // imguijs.Star doesn't allow array access so we need to use the old imguijs.RawPointer. 175 | if (value.size > 0) 176 | { 177 | // Attempt to simplify again now that its wrapped in a raw pointer 178 | finalName = value.name.split('[')[0]; 179 | finalType = simplifyComplexType(macro : imguijs.RawPointer<$ctType>); 180 | } 181 | else 182 | { 183 | finalType = ctType; 184 | } 185 | } 186 | 187 | struct.fields.push({ 188 | name : getHaxefriendlyName(finalName), 189 | kind : FVar(finalType), 190 | pos : null, 191 | meta : [ { name: ':native', pos : null, params: [ macro $i{ '"$finalName"' } ] } ] 192 | }); 193 | } 194 | 195 | for (field in generateFunctionFieldsArray( 196 | definitions.map(f -> f.filter(i -> i.stname == name && !i.destructor)), false)) 197 | { 198 | struct.fields.push(field); 199 | } 200 | 201 | structs.push(struct); 202 | } 203 | 204 | return structs; 205 | } 206 | 207 | /** 208 | * Generate an ImVector generic and sub classes for all found ImVectors. 209 | * Same as structs, no descructors and stack based constructors only. 210 | * @return Array 211 | */ 212 | public function generateImVectors() : Array 213 | { 214 | final generatedVectors = []; 215 | final imVectorClass = macro class ImVector { 216 | @:native('Data') var data : imguijs.RawPointer; 217 | }; 218 | imVectorClass.isExtern = true; 219 | imVectorClass.meta = [ 220 | { name: ':keep', pos : null }, 221 | //{ name: ':structAccess', pos : null }, 222 | //{ name: ':include', pos : null, params: [ macro $i{ '"imgui.h"' } ] }, 223 | { name: ':native', pos : null, params: [ macro $i{ '"ImVector"' } ] } 224 | ]; 225 | imVectorClass.fields = imVectorClass.fields.concat(generateFunctionFieldsArray( 226 | definitions.map(f -> f.filter(i -> !i.constructor && !i.destructor && i.templated && i.stname == 'ImVector')), false)); 227 | 228 | generatedVectors.push(imVectorClass); 229 | 230 | // Compile a list of all known vector templates 231 | // Search the argument and variable types of all structs and functions. 232 | final templatedTypes = []; 233 | for (_ => fields in enumStruct.structs) 234 | { 235 | for (field in fields) 236 | { 237 | if (field.template_type != '') 238 | { 239 | if (!templatedTypes.has(field.template_type)) 240 | { 241 | templatedTypes.push(field.template_type); 242 | } 243 | } 244 | } 245 | } 246 | for (_ => overloads in definitions) 247 | { 248 | for (overloadFn in overloads) 249 | { 250 | if (overloadFn.constructor || overloadFn.destructor || overloadFn.templated) 251 | { 252 | continue; 253 | } 254 | 255 | if (overloadFn.ret.startsWith('ImVector_')) 256 | { 257 | final templatedType = overloadFn.ret.replace('ImVector_', ''); 258 | if (!templatedTypes.has(templatedType)) 259 | { 260 | templatedTypes.push(templatedType); 261 | } 262 | } 263 | 264 | for (arg in overloadFn.argsT) 265 | { 266 | if (arg.type.startsWith('ImVector_')) 267 | { 268 | final templatedType = arg.type.replace('ImVector_', ''); 269 | if (!templatedTypes.has(templatedType)) 270 | { 271 | templatedTypes.push(templatedType); 272 | } 273 | } 274 | } 275 | } 276 | } 277 | 278 | // Generate an extern for each templated type 279 | for (templatedType in templatedTypes) 280 | { 281 | templatedType = templatedType.replace('*OrIndex', 'PtrOrIndex'); 282 | templatedType = templatedType.replace('const_charPtr*', 'const char*'); 283 | 284 | final ct = parseNativeString(templatedType); 285 | var name = cleanNativeType(templatedType).replace(' ', ''); 286 | 287 | for (_ in 0...occurance(templatedType, '*')) 288 | { 289 | name += 'Pointer'; 290 | } 291 | 292 | final fullname = 'ImVector$name'; 293 | final templated = macro class $fullname extends ImVector<$ct> {}; 294 | templated.isExtern = true; 295 | templated.meta = [ 296 | { name: ':keep', pos : null }, 297 | //{ name: ':structAccess', pos : null }, 298 | //{ name: ':include', pos : null, params: [ macro $i{ '"imgui.h"' } ] }, 299 | { name: ':native', pos : null, params: [ macro $i{ '"ImVector"' /*<$templatedType>"'*/ } ] } 300 | ]; 301 | 302 | // Add constructors for each imvector child 303 | // Has a standard constructor and one which copies from another vector of the same type. 304 | final constructor : Field = { 305 | name : 'new', 306 | pos : null, 307 | access : [ APublic ], kind: FFun(generateFunctionAst(null, null, false, [{ 308 | signature: null, 309 | name: 'args', 310 | type: '...' 311 | }], false, false)) 312 | }; 313 | constructor.meta = [ 314 | { name : ':native', pos : null, params : [ macro $i{ '"ImVector"' /*<$templatedType>"'*/ } ] }, 315 | // { 316 | // name : ':overload', 317 | // pos : null, 318 | // params : [ 319 | // { 320 | // expr : EFunction(FAnonymous, generateFunctionAst(null, false, [ { 321 | // name : 'src', 322 | // type : fullname, 323 | // signature : '' 324 | // } ], true)), 325 | // pos : null 326 | // } 327 | // ] 328 | // } 329 | ]; 330 | 331 | templated.fields.push(constructor); 332 | 333 | generatedVectors.push(templated); 334 | } 335 | 336 | return generatedVectors; 337 | } 338 | 339 | /** 340 | * Generate an empty extern, needed to create context type. 341 | * @param _name Name of the extern to generate. 342 | * @return TypeDefinition 343 | */ 344 | public function generateEmptyExtern(_name : String) : TypeDefinition 345 | { 346 | final def = macro class $_name {}; 347 | def.isExtern = true; 348 | def.meta = [ 349 | { name: ':keep', pos : null }, 350 | { name: ':structAccess', pos : null }, 351 | { name: ':include', pos : null, params: [ macro $i{ '"imgui.h"' } ] }, 352 | { name: ':native', pos : null, params: [ macro $i{ '"$_name"' } ] } 353 | ]; 354 | 355 | return def; 356 | } 357 | 358 | /** 359 | * Generate the the type definition for the extern class which will contain all the top level static imgui functions. 360 | * @return TypeDefinition 361 | */ 362 | public function generateTopLevelFunctions() : TypeDefinition 363 | { 364 | final topLevelClass = macro class ImGui { }; 365 | topLevelClass.fields = generateFunctionFieldsArray(definitions.map(f -> f.filter(i -> i.stname == '' && (i.location != null && i.location.startsWith('imgui:')))), true); 366 | topLevelClass.isExtern = true; 367 | topLevelClass.meta = [ 368 | { name: ':keep', pos : null }, 369 | { name: ':native', pos : null, params: [ macro $i{ '"ImGui"' } ] } 370 | //{ name: ':structAccess', pos : null }, 371 | //{ name: ':include', pos : null, params: [ macro $i{ '"imgui.h"' } ] }, 372 | //{ name: ':build', pos : null, params: [ macro imguijs.linc.Linc.xml('imgui') ] }, 373 | //{ name: ':build', pos : null, params: [ macro imguijs.linc.Linc.touch() ] } 374 | ]; 375 | 376 | return topLevelClass; 377 | } 378 | 379 | public function retrieveAllConstructors() : Array { 380 | 381 | var filteredDefinitions = definitions.map(f -> f.filter(i -> i.stname != '' && (i.location != null && i.location.startsWith('imgui:')))); 382 | var result = []; 383 | 384 | for (overloads in filteredDefinitions.filter(a -> a.length > 0)) 385 | { 386 | for (overloadedFn in overloads) 387 | { 388 | if (overloadedFn.constructor) { 389 | result.push(overloadedFn); 390 | } 391 | } 392 | } 393 | 394 | return result; 395 | 396 | } 397 | 398 | /** 399 | * Generates a array of field function definitions. 400 | * Overloads are generated based on actual overloads and arguments with default values. 401 | * In haxe default values must be constant, so we use overloads for this. 402 | * @param _overloads Array of all pre-defined overloads for functions. 403 | * @param _isTopLevel If this function is to be generated as a static function. 404 | * @return Array field functions in the type definition format. 405 | */ 406 | function generateFunctionFieldsArray(_overloads : Array>, _isTopLevel : Bool) : Array 407 | { 408 | final fields = []; 409 | 410 | for (overloads in _overloads.filter(a -> a.length > 0)) 411 | { 412 | var baseFn = null; 413 | 414 | for (overloadedFn in overloads) 415 | { 416 | // Needed to match actual bindings, which differ from cimgui 417 | if (_isTopLevel) { 418 | if (overloadedFn.funcname.startsWith('GetItemRect')) { 419 | if (overloadedFn.ret == 'void' && overloadedFn.argsT.length == 1) { 420 | overloadedFn.ret = overloadedFn.argsT[0].type.replace('*',''); 421 | overloadedFn.argsT = []; 422 | } 423 | } 424 | } 425 | 426 | if (baseFn == null) 427 | { 428 | baseFn = generateFunction(overloadedFn, _isTopLevel, overloadedFn.constructor); 429 | } 430 | else 431 | { 432 | if (overloadedFn.constructor) { 433 | fields.push(generateFunction(overloadedFn, _isTopLevel, overloadedFn.constructor)); 434 | } 435 | else { 436 | baseFn.meta.push({ 437 | name : ':overload', 438 | pos : null, 439 | params : [ { pos: null, expr: EFunction(FAnonymous, generateFunctionAst( 440 | overloadedFn, 441 | overloadedFn.constructor ? overloadedFn.stname : overloadedFn.retorig.or(overloadedFn.ret), 442 | overloadedFn.retref == '&', 443 | overloadedFn.argsT.copy(), 444 | true, overloadedFn.constructor)) } ] 445 | }); 446 | } 447 | } 448 | 449 | // For each overloaded function also look at the default values. 450 | // Generate additional overloads by filtering the aguments based on a growing list of arguments to remove. 451 | // We pop from the list as default arguments 452 | final defaults = [ for (k in overloadedFn.defaults.keys()) k ]; 453 | final filtered = []; 454 | 455 | while (defaults.length > 0) 456 | { 457 | filtered.push(defaults.pop()); 458 | 459 | if (overloadedFn.constructor) { 460 | // TODO? 461 | } 462 | else { 463 | baseFn.meta.push({ 464 | name : ':overload', 465 | pos : null, 466 | params : [ { pos: null, expr: EFunction(FAnonymous, generateFunctionAst( 467 | overloadedFn, 468 | overloadedFn.constructor ? overloadedFn.stname : overloadedFn.retorig.or(overloadedFn.ret), 469 | overloadedFn.retref == '&', 470 | overloadedFn.argsT.filter(i -> !filtered.has(i.name)), 471 | true, overloadedFn.constructor)) } ] 472 | }); 473 | } 474 | } 475 | } 476 | 477 | fields.push(baseFn); 478 | } 479 | 480 | return fields; 481 | } 482 | 483 | /** 484 | * Generates a field function type definiton from a json definition. 485 | * @param _function Json definition to generate a function from. 486 | * @param _isTopLevel If the function doesn't belong to a struct. 487 | * If true the function is generated as static and the native type is prefixed with the `ImGui::` namespace. 488 | * @param _isConstructor if this function is a constructor. 489 | * @return Field 490 | */ 491 | function generateFunction(_function : JsonFunction, _isTopLevel : Bool, _isConstructor : Bool) : Field 492 | { 493 | final nativeType = _isTopLevel ? '${_function.funcname}' : _function.funcname; 494 | final funcName = _isConstructor ? 'create' : getHaxefriendlyName(_function.funcname); 495 | final returnType = _isConstructor ? _function.stname : _function.retorig.or(_function.ret); 496 | 497 | return { 498 | name : funcName, 499 | pos : null, 500 | access : _isTopLevel ? [ AStatic ] : (_isConstructor ? [ AStatic, AInline, AExtern, AOverload ] : []), 501 | kind : FFun(generateFunctionAst(_function, returnType, _function.retref == '&', _function.argsT.copy(), _isConstructor, _isConstructor)), 502 | meta : [ 503 | { name: ':native', pos : null, params: [ macro $i{ '"$nativeType"' } ] } 504 | ] 505 | } 506 | } 507 | 508 | /** 509 | * Generates an AST representation of a function. 510 | * AST representations do not contain a function name, this type is then wrapped in an anonymous and function expr or type definition. 511 | * @param _function The related function. 512 | * @param _return String of the native return type. 513 | * @param _reference If the return type is a reference. 514 | * @param _args Array of arguments for this function. 515 | * @param _block If this function should be generated with an EBlock expr (needed for correct overload syntax). 516 | * @param _wrapConstructor If this function is a wrapped constructor. 517 | * @return Function 518 | */ 519 | function generateFunctionAst(_function : JsonFunction, _return : String, _reference : Bool, _args : Array, _block : Bool, _wrapConstructor : Bool) : Function 520 | { 521 | // If the first argument is called 'self' then thats part of cimgui 522 | // we can safely remove it as we aren't using the c bindings code. 523 | if (_args.length > 0) 524 | { 525 | if (_args[0].name == 'self') 526 | { 527 | _args.shift(); 528 | } 529 | } 530 | 531 | var funcExpr:Expr = { expr: EBlock([]), pos : null }; 532 | 533 | if (_wrapConstructor) { 534 | 535 | var exprStr = '{'; 536 | exprStr += 'return js.Syntax.code("new ImGui.' + _function.funcname + '('; 537 | for (i in 0..._args.length) { 538 | var arg = _args[i]; 539 | if (i > 0) { 540 | exprStr += ', '; 541 | } 542 | exprStr += "{" + i + "}"; 543 | } 544 | exprStr += ')"'; 545 | for (i in 0..._args.length) { 546 | var arg = _args[i]; 547 | exprStr += ', '; 548 | exprStr += getHaxefriendlyName(arg.name); 549 | } 550 | exprStr += ');'; 551 | exprStr += '}'; 552 | 553 | funcExpr = Context.parse(exprStr, Context.currentPos()); 554 | 555 | } 556 | 557 | return { 558 | expr : _block ? funcExpr : null, 559 | ret : _return != null ? buildReturnType(parseNativeString(_return), _reference) : null, 560 | args : [ for (arg in _args) generateFunctionArg(arg.name, arg.type) ] 561 | } 562 | } 563 | 564 | /** 565 | * Generate a function argument AST representation. 566 | * @param _name name of the argument. 567 | * Will prefix this with and _ to avoid collisions with haxe preserved keyworks and will force the first character to a lower case. 568 | * @param _type Native type of this argument. 569 | * @return FunctionArg 570 | */ 571 | function generateFunctionArg(_name : String, _type : String) : FunctionArg 572 | { 573 | var opt = false; 574 | if (_name.startsWith('?')) { 575 | _name = _name.substring(1); 576 | opt = true; 577 | } 578 | if (_name == 'in') 579 | _name = '_in'; 580 | return { 581 | name : '${ getHaxefriendlyName(_name) }', 582 | type : parseNativeString(_type), 583 | opt : opt 584 | } 585 | } 586 | 587 | /** 588 | * Parse the provided string containing a native c type into the equivilent haxe type. 589 | * Currently parses pointer types and functions. 590 | * @param _in Native c type. 591 | * @return ComplexType 592 | */ 593 | function parseNativeString(_in : String) : ComplexType 594 | { 595 | if (_in.contains('(*)')) 596 | { 597 | return parseFunction(_in); 598 | } 599 | else 600 | { 601 | return parseType(_in); 602 | } 603 | } 604 | 605 | function parseType(_in : String, _nativeVoid = true) : ComplexType 606 | { 607 | // count how many pointer levels then strip any of that away 608 | final const = _in.contains('const'); 609 | final pointer = occurance(_in, '*'); 610 | final refType = occurance(_in, '&'); 611 | final cleaned = cleanNativeType(_in); 612 | var ct; 613 | 614 | if (_in.contains('ImVector_const_charPtr*')) 615 | { 616 | return macro : ImVectorcharPointer; 617 | } 618 | 619 | if (cleaned.startsWith('ImVector_')) 620 | { 621 | var hxType = cleaned.replace('ImVector_', ''); 622 | for (_ in 0...pointer) 623 | { 624 | hxType += 'Pointer'; 625 | } 626 | 627 | return TPath({ pack: [ ], name: 'ImVector$hxType' }); 628 | } 629 | 630 | if (cleaned.contains('[')) 631 | { 632 | // Array types use imguijs.RawPointer instead of imguijs.Star to allow array access 633 | // Also allows us to pattern match against it and generate abstracts to easy array <-> pointer interop. 634 | 635 | final arrayType = _in.split('[')[0]; 636 | final hxType = parseType(arrayType); 637 | 638 | ct = macro : imguijs.RawPointer<$hxType>; 639 | } 640 | else 641 | { 642 | ct = getHaxeType(cleaned, _nativeVoid); 643 | 644 | // Get the base complex type, then wrap it in as many pointer as is required. 645 | for (_ in 0...pointer) 646 | { 647 | if (const) 648 | { 649 | ct = macro : imguijs.RawConstPointer<$ct>; 650 | } 651 | else 652 | { 653 | ct = macro : imguijs.Star<$ct>; 654 | } 655 | } 656 | for (_ in 0...refType) 657 | { 658 | ct = macro : imguijs.Reference<$ct>; 659 | } 660 | 661 | ct = simplifyComplexType(ct); 662 | } 663 | 664 | return simplifyComplexType(ct); 665 | } 666 | 667 | function parseFunction(_in : String) : ComplexType 668 | { 669 | final returnType = _in.split('(*)')[0]; 670 | final bracketedArgs = _in.split('(*)')[1]; 671 | final splitArgs = bracketedArgs.substr(1, bracketedArgs.length - 2).split(','); 672 | 673 | final ctArgs = []; 674 | for (arg in splitArgs) 675 | { 676 | final split = arg.split(' '); 677 | 678 | final name = split.pop(); 679 | 680 | if (name.contains('...')) 681 | { 682 | ctArgs.push(macro : haxe.extern.Rest); 683 | } 684 | else 685 | { 686 | final type = split.join(' '); 687 | 688 | abstractPtrs = false; 689 | 690 | ctArgs.push(parseNativeString(type)); 691 | 692 | abstractPtrs = true; 693 | } 694 | } 695 | 696 | final ctParams = TFunction(ctArgs, parseType(returnType, false)); 697 | 698 | return macro : imguijs.Callable<$ctParams>; 699 | } 700 | 701 | function buildReturnType(_ct : ComplexType, _reference : Bool) 702 | { 703 | if (_reference) 704 | { 705 | switch _ct 706 | { 707 | case TPath(p): 708 | // If the return type is a reference and the outer-most complex type is a pointer 709 | // Strip that pointer off and make it a reference instead. 710 | if (p.name == 'Star') 711 | { 712 | return TPath({ pack: [ 'imguijs' ], name: 'Reference', params: p.params }); 713 | } 714 | case _: 715 | } 716 | } 717 | 718 | return _ct; 719 | } 720 | 721 | function getHaxeType(_in : String, _nativeVoid = true) : ComplexType 722 | { 723 | return switch _in.trim() 724 | { 725 | case 'int', 'signed int' : macro : Int; 726 | case 'unsigned int' : macro : UInt; 727 | case 'short', 'signed short' : macro : imguijs.Int16; 728 | case 'unsigned short' : macro : imguijs.UInt16; 729 | case 'float' : macro : imguijs.Float32; 730 | case 'double' : macro : Float; 731 | case 'bool' : macro : Bool; 732 | case 'char', 'const char', '_charPtr' : macro : imguijs.Char; 733 | case 'signed char' : macro : imguijs.Int8; 734 | case 'unsigned char' : macro : imguijs.UInt8; 735 | case 'int64_t' : macro : imguijs.Int64; 736 | case 'uint64_t' : macro : imguijs.UInt64; 737 | case 'va_list', '...' : macro : haxe.extern.Rest; 738 | case 'size_t' : macro : imguijs.SizeT; 739 | case 'void' : macro : Void; 740 | case 'T' : macro : T; 741 | case 'ImVector' : macro : ImVector; 742 | case _other: TPath({ pack: [ ], name : _other }); 743 | } 744 | } 745 | 746 | function simplifyComplexType(_ct : ComplexType) : ComplexType 747 | { 748 | switch _ct 749 | { 750 | case TPath(p): 751 | // If we have no type parameters there is no simplification we can make. 752 | if (p.params == null || p.params.length == 0) 753 | { 754 | return _ct; 755 | } 756 | 757 | // Attempt to simplify some base type pointers to a custom abstracts. 758 | // Makes common pointer types easier to deal with. 759 | if (p.name == 'Star' || p.name == 'RawPointer') 760 | { 761 | final inner = getInnerParameter(p.params); 762 | 763 | switch inner.name 764 | { 765 | case 'UInt8' if (abstractPtrs): return macro : imguijs.CharPointer; 766 | case 'Void' if (abstractPtrs): return macro : imguijs.VoidPointer; 767 | case 'Int' if (abstractPtrs): return macro : imguijs.IntPointer; 768 | case 'Float32' if (abstractPtrs): return macro : imguijs.FloatPointer; 769 | case 'Bool' if (abstractPtrs): return macro : imguijs.BoolPointer; 770 | case 'Void': return macro : Dynamic; // void* -> dynamic 771 | case 'Star': 772 | final inner = getInnerParameter(inner.params); 773 | 774 | if (inner.name == 'ImDrawList') 775 | { 776 | return macro : imguijs.RawPointer>; 777 | } 778 | case _: 779 | // Not other pointer simplifications at this point, unwrap 780 | return TPath(inner); 781 | } 782 | } 783 | 784 | // If we have a RawConstPointer the re-type it as a ConstCharStar 785 | // else, re-type it in a imguijs.Star for easier use 786 | if (p.name == 'RawConstPointer') 787 | { 788 | final inner = getInnerParameter(p.params); 789 | 790 | switch inner.name 791 | { 792 | case 'Int8', 'UInt8', 'Char': return macro : String; 793 | case _: 794 | final ct = TPath(inner); 795 | 796 | return macro : imguijs.Star<$ct>; 797 | } 798 | } 799 | case _: 800 | } 801 | 802 | return _ct; 803 | } 804 | 805 | function getInnerParameter(_params : Array) : TypePath 806 | { 807 | for (param in _params) 808 | { 809 | switch param 810 | { 811 | case TPType(t): 812 | switch t 813 | { 814 | case TPath(p): return p; 815 | case _: 816 | } 817 | case _: 818 | } 819 | } 820 | 821 | return null; 822 | } 823 | 824 | function occurance(_in : String, _search : String) : Int 825 | { 826 | var pointer = 0; 827 | for (i in 0..._in.length) 828 | { 829 | if (_in.charAt(i) == _search) 830 | { 831 | pointer++; 832 | } 833 | } 834 | 835 | return pointer; 836 | } 837 | 838 | function getHaxefriendlyName(_in : String) 839 | { 840 | if (_in == '...') 841 | { 842 | return 'vargs'; 843 | } 844 | else 845 | { 846 | return '${ _in.charAt(0).toLowerCase() }${ _in.substr(1) }'; 847 | } 848 | } 849 | 850 | static function cleanNativeType(_in : String) : String 851 | { 852 | return _in.replace('*', '').replace('const', '').replace('&', '').trim(); 853 | } 854 | } 855 | -------------------------------------------------------------------------------- /gen/ImGuiJsonTypes.hx: -------------------------------------------------------------------------------- 1 | 2 | typedef JsonEnum = { 3 | calc_value : Int, 4 | name : String, 5 | value : String 6 | } 7 | 8 | typedef JsonStruct = { 9 | var name : String; 10 | var type : String; 11 | @:default(0) 12 | var size : Int; 13 | @:default('') 14 | var template_type : String; 15 | } 16 | 17 | typedef JsonEnumStruct = { 18 | var enums : Map>; 19 | var structs : Map>; 20 | } 21 | 22 | typedef JsonFunctionArg = { 23 | var name : String; 24 | var type : String; 25 | @:default('') 26 | var signature : String; 27 | } 28 | 29 | typedef JsonFunction = { 30 | var args : String; 31 | var argsT : Array; 32 | var argsoriginal : String; 33 | var call_args : String; 34 | var cimguiname : String; 35 | var ov_cimguiname : String; 36 | var funcname : String; 37 | var stname : String; 38 | var signature : String; 39 | 40 | @:default([]) 41 | var defaults : Map; 42 | 43 | @:default(false) 44 | var constructor : Bool; 45 | 46 | @:default(false) 47 | var destructor : Bool; 48 | 49 | @:default(false) 50 | var templatedgen : Bool; 51 | @:default(false) 52 | var templated : Bool; 53 | var ?isvararg : String; 54 | var ?retref : String; 55 | var ?namespace : String; 56 | var ?ret : String; 57 | var ?retorig : String; 58 | var ?location : String; 59 | } 60 | 61 | typedef JsonDefinitions = Map>; 62 | 63 | typedef JsonTypedef = Map; 64 | -------------------------------------------------------------------------------- /gen/StringBufChainer.hx: -------------------------------------------------------------------------------- 1 | 2 | class StringBufChainer 3 | { 4 | static var isWindows:Bool = (Sys.systemName() == 'Windows'); 5 | 6 | public static function append(_buffer : StringBuf, _text : String) : StringBuf 7 | { 8 | _buffer.add(_text); 9 | 10 | return _buffer; 11 | } 12 | 13 | public static function newline(_buffer : StringBuf) : StringBuf 14 | { 15 | if (isWindows) { 16 | _buffer.add('\r\n'); 17 | } 18 | else { 19 | _buffer.add('\n'); 20 | } 21 | 22 | return _buffer; 23 | } 24 | 25 | public static function tab(_buffer : StringBuf) : StringBuf 26 | { 27 | _buffer.add('\t'); 28 | 29 | return _buffer; 30 | } 31 | 32 | public static function tabSpaces(_buffer : StringBuf) : StringBuf 33 | { 34 | _buffer.add(' '); 35 | 36 | return _buffer; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /haxe_libraries/exception.hxml: -------------------------------------------------------------------------------- 1 | -D exception=1.0.2 2 | # @install: lix --silent download "haxelib:/exception#1.0.2" into exception/1.0.2/haxelib 3 | -cp ${HAXE_LIBCACHE}/exception/1.0.2/haxelib/src 4 | -------------------------------------------------------------------------------- /haxe_libraries/hxcpp.hxml: -------------------------------------------------------------------------------- 1 | # @install: lix --silent download "gh://github.com/HaxeFoundation/hxcpp#30287243987c8189e2ae26175ae23076f0ce88d9" into hxcpp/4.0.0/github/30287243987c8189e2ae26175ae23076f0ce88d9 2 | # @run: haxelib run-dir hxcpp ${HAXE_LIBCACHE}/hxcpp/4.0.0/github/30287243987c8189e2ae26175ae23076f0ce88d9 3 | -cp ${HAXE_LIBCACHE}/hxcpp/4.0.0/github/30287243987c8189e2ae26175ae23076f0ce88d9/ 4 | -D hxcpp=4.0.0 5 | -------------------------------------------------------------------------------- /haxe_libraries/hxjsonast.hxml: -------------------------------------------------------------------------------- 1 | -D hxjsonast=1.0.1 2 | # @install: lix --silent download "haxelib:/hxjsonast#1.0.1" into hxjsonast/1.0.1/haxelib 3 | -cp ${HAXE_LIBCACHE}/hxjsonast/1.0.1/haxelib/src 4 | -------------------------------------------------------------------------------- /haxe_libraries/json2object.hxml: -------------------------------------------------------------------------------- 1 | -D json2object=3.6.3 2 | # @install: lix --silent download "haxelib:/json2object#3.6.3" into json2object/3.6.3/haxelib 3 | -lib hxjsonast 4 | -cp ${HAXE_LIBCACHE}/json2object/3.6.3/haxelib/src 5 | -------------------------------------------------------------------------------- /haxe_libraries/safety.hxml: -------------------------------------------------------------------------------- 1 | -D safety=1.1.0 2 | # @install: lix --silent download "haxelib:/safety#1.1.0" into safety/1.1.0/haxelib 3 | -lib exception 4 | -cp ${HAXE_LIBCACHE}/safety/1.1.0/haxelib/src 5 | -------------------------------------------------------------------------------- /haxelib.json: -------------------------------------------------------------------------------- 1 | 2 | { 3 | "name" : "imgui-hx", 4 | "license": "MIT", 5 | "description": "Haxe externs for ImGui", 6 | "version" : "0.0.1", 7 | "releasenote": "Working on unified bindings to C++ and JS builds of ImGui", 8 | "contributors": [ 9 | "Aidan", 10 | "jeremyfa" 11 | ], 12 | "classPath": "src" 13 | } 14 | -------------------------------------------------------------------------------- /korefile.js: -------------------------------------------------------------------------------- 1 | // korefile.js is used by Kha SDK, see test/kha 2 | 3 | var project = new Project('linc_imgui', __dirname); 4 | 5 | project.addFile('linc/**'); 6 | project.addIncludeDir('linc'); 7 | project.addFile('lib/imgui/*.cpp'); 8 | project.addIncludeDir('lib/imgui'); 9 | 10 | resolve(project); 11 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "requires": true, 3 | "lockfileVersion": 1, 4 | "dependencies": { 5 | "lix": { 6 | "version": "15.10.1", 7 | "resolved": "https://registry.npmjs.org/lix/-/lix-15.10.1.tgz", 8 | "integrity": "sha512-UZX+p4i+2ZSEyI6p2Yu1sfC0pRRFnFHDpNQ2+FqhxmBG8cCiHZkj+I8FqCK4AUuQ/VOPE/bK69JbWez+OG3zaA==" 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/imgui/Helpers.hx: -------------------------------------------------------------------------------- 1 | package imgui; 2 | 3 | #if js 4 | 5 | typedef Helpers = imguijs.Helpers; 6 | 7 | #end 8 | 9 | #if cpp 10 | 11 | typedef Helpers = imguicpp.Helpers; 12 | 13 | #end 14 | -------------------------------------------------------------------------------- /src/imgui/ImGui.hx: -------------------------------------------------------------------------------- 1 | package imgui; 2 | 3 | #if js 4 | typedef ImGui = imguijs.ImGui; 5 | typedef ImVector = imguijs.ImGui.ImVector; 6 | typedef ImVec4 = imguijs.ImGui.ImVec4; 7 | typedef ImVec2 = imguijs.ImGui.ImVec2; 8 | typedef ImGuiTextRange = imguijs.ImGui.ImGuiTextRange; 9 | typedef ImGuiTextFilter = imguijs.ImGui.ImGuiTextFilter; 10 | typedef ImGuiTextBuffer = imguijs.ImGui.ImGuiTextBuffer; 11 | typedef ImGuiTableSortSpecs = imguijs.ImGui.ImGuiTableSortSpecs; 12 | typedef ImGuiTableColumnSortSpecs = imguijs.ImGui.ImGuiTableColumnSortSpecs; 13 | typedef ImGuiStyle = imguijs.ImGui.ImGuiStyle; 14 | typedef ImGuiStoragePair = imguijs.ImGui.ImGuiStoragePair; 15 | typedef ImGuiPayload = imguijs.ImGui.ImGuiPayload; 16 | typedef ImGuiOnceUponAFrame = imguijs.ImGui.ImGuiOnceUponAFrame; 17 | typedef ImGuiListClipper = imguijs.ImGui.ImGuiListClipper; 18 | typedef ImGuiInputTextCallbackData = imguijs.ImGui.ImGuiInputTextCallbackData; 19 | typedef ImGuiIO = imguijs.ImGui.ImGuiIO; 20 | typedef ImFont = imguijs.ImGui.ImFont; 21 | typedef ImFontGlyphRangesBuilder = imguijs.ImGui.ImFontGlyphRangesBuilder; 22 | typedef ImFontConfig = imguijs.ImGui.ImFontConfig; 23 | typedef ImFontAtlas = imguijs.ImGui.ImFontAtlas; 24 | typedef ImFontAtlasCustomRect = imguijs.ImGui.ImFontAtlasCustomRect; 25 | typedef ImDrawList = imguijs.ImGui.ImDrawList; 26 | typedef ImDrawListSplitter = imguijs.ImGui.ImDrawListSplitter; 27 | typedef ImDrawData = imguijs.ImGui.ImDrawData; 28 | typedef ImDrawCmd = imguijs.ImGui.ImDrawCmd; 29 | typedef ImColor = imguijs.ImGui.ImColor; 30 | typedef ImGuiWindowFlags = imguijs.ImGui.ImGuiWindowFlags; 31 | typedef ImGuiTreeNodeFlags = imguijs.ImGui.ImGuiTreeNodeFlags; 32 | typedef ImGuiTreeNodeFlagsPrivate = imguijs.ImGui.ImGuiTreeNodeFlagsPrivate; 33 | typedef ImGuiTooltipFlags = imguijs.ImGui.ImGuiTooltipFlags; 34 | typedef ImGuiTextFlags = imguijs.ImGui.ImGuiTextFlags; 35 | typedef ImGuiTableRowFlags = imguijs.ImGui.ImGuiTableRowFlags; 36 | typedef ImGuiTableFlags = imguijs.ImGui.ImGuiTableFlags; 37 | typedef ImGuiTableColumnFlags = imguijs.ImGui.ImGuiTableColumnFlags; 38 | typedef ImGuiTableBgTarget = imguijs.ImGui.ImGuiTableBgTarget; 39 | typedef ImGuiTabItemFlags = imguijs.ImGui.ImGuiTabItemFlags; 40 | typedef ImGuiTabItemFlagsPrivate = imguijs.ImGui.ImGuiTabItemFlagsPrivate; 41 | typedef ImGuiTabBarFlags = imguijs.ImGui.ImGuiTabBarFlags; 42 | typedef ImGuiTabBarFlagsPrivate = imguijs.ImGui.ImGuiTabBarFlagsPrivate; 43 | typedef ImGuiStyleVar = imguijs.ImGui.ImGuiStyleVar; 44 | typedef ImGuiSortDirection = imguijs.ImGui.ImGuiSortDirection; 45 | typedef ImGuiSliderFlags = imguijs.ImGui.ImGuiSliderFlags; 46 | typedef ImGuiSliderFlagsPrivate = imguijs.ImGui.ImGuiSliderFlagsPrivate; 47 | typedef ImGuiSeparatorFlags = imguijs.ImGui.ImGuiSeparatorFlags; 48 | typedef ImGuiSelectableFlags = imguijs.ImGui.ImGuiSelectableFlags; 49 | typedef ImGuiSelectableFlagsPrivate = imguijs.ImGui.ImGuiSelectableFlagsPrivate; 50 | typedef ImGuiPopupPositionPolicy = imguijs.ImGui.ImGuiPopupPositionPolicy; 51 | typedef ImGuiPopupFlags = imguijs.ImGui.ImGuiPopupFlags; 52 | typedef ImGuiPlotType = imguijs.ImGui.ImGuiPlotType; 53 | typedef ImGuiOldColumnFlags = imguijs.ImGui.ImGuiOldColumnFlags; 54 | typedef ImGuiNextWindowDataFlags = imguijs.ImGui.ImGuiNextWindowDataFlags; 55 | typedef ImGuiNextItemDataFlags = imguijs.ImGui.ImGuiNextItemDataFlags; 56 | typedef ImGuiNavMoveFlags = imguijs.ImGui.ImGuiNavMoveFlags; 57 | typedef ImGuiNavLayer = imguijs.ImGui.ImGuiNavLayer; 58 | typedef ImGuiNavInput = imguijs.ImGui.ImGuiNavInput; 59 | typedef ImGuiNavHighlightFlags = imguijs.ImGui.ImGuiNavHighlightFlags; 60 | typedef ImGuiNavForward = imguijs.ImGui.ImGuiNavForward; 61 | typedef ImGuiNavDirSourceFlags = imguijs.ImGui.ImGuiNavDirSourceFlags; 62 | typedef ImGuiMouseCursor = imguijs.ImGui.ImGuiMouseCursor; 63 | typedef ImGuiMouseButton = imguijs.ImGui.ImGuiMouseButton; 64 | typedef ImGuiLogType = imguijs.ImGui.ImGuiLogType; 65 | typedef ImGuiLayoutType = imguijs.ImGui.ImGuiLayoutType; 66 | typedef ImGuiKey = imguijs.ImGui.ImGuiKey; 67 | typedef ImGuiKeyModFlags = imguijs.ImGui.ImGuiKeyModFlags; 68 | typedef ImGuiItemStatusFlags = imguijs.ImGui.ImGuiItemStatusFlags; 69 | typedef ImGuiItemFlags = imguijs.ImGui.ImGuiItemFlags; 70 | typedef ImGuiInputTextFlags = imguijs.ImGui.ImGuiInputTextFlags; 71 | typedef ImGuiInputSource = imguijs.ImGui.ImGuiInputSource; 72 | typedef ImGuiInputReadMode = imguijs.ImGui.ImGuiInputReadMode; 73 | typedef ImGuiHoveredFlags = imguijs.ImGui.ImGuiHoveredFlags; 74 | typedef ImGuiFocusedFlags = imguijs.ImGui.ImGuiFocusedFlags; 75 | typedef ImGuiDragDropFlags = imguijs.ImGui.ImGuiDragDropFlags; 76 | typedef ImGuiDir = imguijs.ImGui.ImGuiDir; 77 | typedef ImGuiDataType = imguijs.ImGui.ImGuiDataType; 78 | typedef ImGuiDataTypePrivate = imguijs.ImGui.ImGuiDataTypePrivate; 79 | typedef ImGuiContextHookType = imguijs.ImGui.ImGuiContextHookType; 80 | typedef ImGuiConfigFlags = imguijs.ImGui.ImGuiConfigFlags; 81 | typedef ImGuiCond = imguijs.ImGui.ImGuiCond; 82 | typedef ImGuiComboFlags = imguijs.ImGui.ImGuiComboFlags; 83 | typedef ImGuiColorEditFlags = imguijs.ImGui.ImGuiColorEditFlags; 84 | typedef ImGuiCol = imguijs.ImGui.ImGuiCol; 85 | typedef ImGuiButtonFlags = imguijs.ImGui.ImGuiButtonFlags; 86 | typedef ImGuiButtonFlagsPrivate = imguijs.ImGui.ImGuiButtonFlagsPrivate; 87 | typedef ImGuiBackendFlags = imguijs.ImGui.ImGuiBackendFlags; 88 | typedef ImGuiAxis = imguijs.ImGui.ImGuiAxis; 89 | typedef ImFontAtlasFlags = imguijs.ImGui.ImFontAtlasFlags; 90 | typedef ImDrawListFlags = imguijs.ImGui.ImDrawListFlags; 91 | typedef ImDrawCornerFlags = imguijs.ImGui.ImDrawCornerFlags; 92 | typedef ImGuiWindowPtr = imguijs.ImGui.ImGuiWindowPtr; 93 | typedef ImWchar32 = imguijs.ImGui.ImWchar32; 94 | typedef ImWchar16 = imguijs.ImGui.ImWchar16; 95 | typedef ImWchar = imguijs.ImGui.ImWchar; 96 | typedef ImU8 = imguijs.ImGui.ImU8; 97 | typedef ImU64 = imguijs.ImGui.ImU64; 98 | typedef ImU32 = imguijs.ImGui.ImU32; 99 | typedef ImU16 = imguijs.ImGui.ImU16; 100 | typedef ImTextureID = imguijs.ImGui.ImTextureID; 101 | typedef ImS8 = imguijs.ImGui.ImS8; 102 | typedef ImS64 = imguijs.ImGui.ImS64; 103 | typedef ImS32 = imguijs.ImGui.ImS32; 104 | typedef ImS16 = imguijs.ImGui.ImS16; 105 | typedef ImPoolIdx = imguijs.ImGui.ImPoolIdx; 106 | typedef ImGuiTableDrawChannelIdx = imguijs.ImGui.ImGuiTableDrawChannelIdx; 107 | typedef ImGuiTableColumnIdx = imguijs.ImGui.ImGuiTableColumnIdx; 108 | typedef ImGuiSizeCallback = imguijs.ImGui.ImGuiSizeCallback; 109 | typedef ImGuiInputTextCallback = imguijs.ImGui.ImGuiInputTextCallback; 110 | typedef ImGuiID = imguijs.ImGui.ImGuiID; 111 | typedef ImGuiErrorLogCallback = imguijs.ImGui.ImGuiErrorLogCallback; 112 | typedef ImGuiContextHookCallback = imguijs.ImGui.ImGuiContextHookCallback; 113 | typedef ImFileHandle = imguijs.ImGui.ImFileHandle; 114 | typedef ImDrawIdx = imguijs.ImGui.ImDrawIdx; 115 | typedef ImDrawCallback = imguijs.ImGui.ImDrawCallback; 116 | #end 117 | 118 | #if cpp 119 | typedef ImGui = imguicpp.ImGui; 120 | typedef ImVector = imguicpp.ImGui.ImVector; 121 | typedef ImVec4 = imguicpp.ImGui.ImVec4; 122 | typedef ImVec2 = imguicpp.ImGui.ImVec2; 123 | typedef ImGuiTextRange = imguicpp.ImGui.ImGuiTextRange; 124 | typedef ImGuiTextFilter = imguicpp.ImGui.ImGuiTextFilter; 125 | typedef ImGuiTextBuffer = imguicpp.ImGui.ImGuiTextBuffer; 126 | typedef ImGuiTableSortSpecs = imguicpp.ImGui.ImGuiTableSortSpecs; 127 | typedef ImGuiTableColumnSortSpecs = imguicpp.ImGui.ImGuiTableColumnSortSpecs; 128 | typedef ImGuiStyle = imguicpp.ImGui.ImGuiStyle; 129 | typedef ImGuiStoragePair = imguicpp.ImGui.ImGuiStoragePair; 130 | typedef ImGuiPayload = imguicpp.ImGui.ImGuiPayload; 131 | typedef ImGuiOnceUponAFrame = imguicpp.ImGui.ImGuiOnceUponAFrame; 132 | typedef ImGuiListClipper = imguicpp.ImGui.ImGuiListClipper; 133 | typedef ImGuiInputTextCallbackData = imguicpp.ImGui.ImGuiInputTextCallbackData; 134 | typedef ImGuiIO = imguicpp.ImGui.ImGuiIO; 135 | typedef ImFont = imguicpp.ImGui.ImFont; 136 | typedef ImFontGlyphRangesBuilder = imguicpp.ImGui.ImFontGlyphRangesBuilder; 137 | typedef ImFontConfig = imguicpp.ImGui.ImFontConfig; 138 | typedef ImFontAtlas = imguicpp.ImGui.ImFontAtlas; 139 | typedef ImFontAtlasCustomRect = imguicpp.ImGui.ImFontAtlasCustomRect; 140 | typedef ImDrawList = imguicpp.ImGui.ImDrawList; 141 | typedef ImDrawListSplitter = imguicpp.ImGui.ImDrawListSplitter; 142 | typedef ImDrawData = imguicpp.ImGui.ImDrawData; 143 | typedef ImDrawCmd = imguicpp.ImGui.ImDrawCmd; 144 | typedef ImColor = imguicpp.ImGui.ImColor; 145 | typedef ImGuiWindowFlags = imguicpp.ImGui.ImGuiWindowFlags; 146 | typedef ImGuiTreeNodeFlags = imguicpp.ImGui.ImGuiTreeNodeFlags; 147 | typedef ImGuiTreeNodeFlagsPrivate = imguicpp.ImGui.ImGuiTreeNodeFlagsPrivate; 148 | typedef ImGuiTooltipFlags = imguicpp.ImGui.ImGuiTooltipFlags; 149 | typedef ImGuiTextFlags = imguicpp.ImGui.ImGuiTextFlags; 150 | typedef ImGuiTableRowFlags = imguicpp.ImGui.ImGuiTableRowFlags; 151 | typedef ImGuiTableFlags = imguicpp.ImGui.ImGuiTableFlags; 152 | typedef ImGuiTableColumnFlags = imguicpp.ImGui.ImGuiTableColumnFlags; 153 | typedef ImGuiTableBgTarget = imguicpp.ImGui.ImGuiTableBgTarget; 154 | typedef ImGuiTabItemFlags = imguicpp.ImGui.ImGuiTabItemFlags; 155 | typedef ImGuiTabItemFlagsPrivate = imguicpp.ImGui.ImGuiTabItemFlagsPrivate; 156 | typedef ImGuiTabBarFlags = imguicpp.ImGui.ImGuiTabBarFlags; 157 | typedef ImGuiTabBarFlagsPrivate = imguicpp.ImGui.ImGuiTabBarFlagsPrivate; 158 | typedef ImGuiStyleVar = imguicpp.ImGui.ImGuiStyleVar; 159 | typedef ImGuiSortDirection = imguicpp.ImGui.ImGuiSortDirection; 160 | typedef ImGuiSliderFlags = imguicpp.ImGui.ImGuiSliderFlags; 161 | typedef ImGuiSliderFlagsPrivate = imguicpp.ImGui.ImGuiSliderFlagsPrivate; 162 | typedef ImGuiSeparatorFlags = imguicpp.ImGui.ImGuiSeparatorFlags; 163 | typedef ImGuiSelectableFlags = imguicpp.ImGui.ImGuiSelectableFlags; 164 | typedef ImGuiSelectableFlagsPrivate = imguicpp.ImGui.ImGuiSelectableFlagsPrivate; 165 | typedef ImGuiPopupPositionPolicy = imguicpp.ImGui.ImGuiPopupPositionPolicy; 166 | typedef ImGuiPopupFlags = imguicpp.ImGui.ImGuiPopupFlags; 167 | typedef ImGuiPlotType = imguicpp.ImGui.ImGuiPlotType; 168 | typedef ImGuiOldColumnFlags = imguicpp.ImGui.ImGuiOldColumnFlags; 169 | typedef ImGuiNextWindowDataFlags = imguicpp.ImGui.ImGuiNextWindowDataFlags; 170 | typedef ImGuiNextItemDataFlags = imguicpp.ImGui.ImGuiNextItemDataFlags; 171 | typedef ImGuiNavMoveFlags = imguicpp.ImGui.ImGuiNavMoveFlags; 172 | typedef ImGuiNavLayer = imguicpp.ImGui.ImGuiNavLayer; 173 | typedef ImGuiNavInput = imguicpp.ImGui.ImGuiNavInput; 174 | typedef ImGuiNavHighlightFlags = imguicpp.ImGui.ImGuiNavHighlightFlags; 175 | typedef ImGuiNavForward = imguicpp.ImGui.ImGuiNavForward; 176 | typedef ImGuiNavDirSourceFlags = imguicpp.ImGui.ImGuiNavDirSourceFlags; 177 | typedef ImGuiMouseCursor = imguicpp.ImGui.ImGuiMouseCursor; 178 | typedef ImGuiMouseButton = imguicpp.ImGui.ImGuiMouseButton; 179 | typedef ImGuiLogType = imguicpp.ImGui.ImGuiLogType; 180 | typedef ImGuiLayoutType = imguicpp.ImGui.ImGuiLayoutType; 181 | typedef ImGuiKey = imguicpp.ImGui.ImGuiKey; 182 | typedef ImGuiKeyModFlags = imguicpp.ImGui.ImGuiKeyModFlags; 183 | typedef ImGuiItemStatusFlags = imguicpp.ImGui.ImGuiItemStatusFlags; 184 | typedef ImGuiItemFlags = imguicpp.ImGui.ImGuiItemFlags; 185 | typedef ImGuiInputTextFlags = imguicpp.ImGui.ImGuiInputTextFlags; 186 | typedef ImGuiInputSource = imguicpp.ImGui.ImGuiInputSource; 187 | typedef ImGuiInputReadMode = imguicpp.ImGui.ImGuiInputReadMode; 188 | typedef ImGuiHoveredFlags = imguicpp.ImGui.ImGuiHoveredFlags; 189 | typedef ImGuiFocusedFlags = imguicpp.ImGui.ImGuiFocusedFlags; 190 | typedef ImGuiDragDropFlags = imguicpp.ImGui.ImGuiDragDropFlags; 191 | typedef ImGuiDir = imguicpp.ImGui.ImGuiDir; 192 | typedef ImGuiDataType = imguicpp.ImGui.ImGuiDataType; 193 | typedef ImGuiDataTypePrivate = imguicpp.ImGui.ImGuiDataTypePrivate; 194 | typedef ImGuiContextHookType = imguicpp.ImGui.ImGuiContextHookType; 195 | typedef ImGuiConfigFlags = imguicpp.ImGui.ImGuiConfigFlags; 196 | typedef ImGuiCond = imguicpp.ImGui.ImGuiCond; 197 | typedef ImGuiComboFlags = imguicpp.ImGui.ImGuiComboFlags; 198 | typedef ImGuiColorEditFlags = imguicpp.ImGui.ImGuiColorEditFlags; 199 | typedef ImGuiCol = imguicpp.ImGui.ImGuiCol; 200 | typedef ImGuiButtonFlags = imguicpp.ImGui.ImGuiButtonFlags; 201 | typedef ImGuiButtonFlagsPrivate = imguicpp.ImGui.ImGuiButtonFlagsPrivate; 202 | typedef ImGuiBackendFlags = imguicpp.ImGui.ImGuiBackendFlags; 203 | typedef ImGuiAxis = imguicpp.ImGui.ImGuiAxis; 204 | typedef ImFontAtlasFlags = imguicpp.ImGui.ImFontAtlasFlags; 205 | typedef ImDrawListFlags = imguicpp.ImGui.ImDrawListFlags; 206 | typedef ImDrawCornerFlags = imguicpp.ImGui.ImDrawCornerFlags; 207 | typedef ImGuiWindowPtr = imguicpp.ImGui.ImGuiWindowPtr; 208 | typedef ImWchar32 = imguicpp.ImGui.ImWchar32; 209 | typedef ImWchar16 = imguicpp.ImGui.ImWchar16; 210 | typedef ImWchar = imguicpp.ImGui.ImWchar; 211 | typedef ImU8 = imguicpp.ImGui.ImU8; 212 | typedef ImU64 = imguicpp.ImGui.ImU64; 213 | typedef ImU32 = imguicpp.ImGui.ImU32; 214 | typedef ImU16 = imguicpp.ImGui.ImU16; 215 | typedef ImTextureID = imguicpp.ImGui.ImTextureID; 216 | typedef ImS8 = imguicpp.ImGui.ImS8; 217 | typedef ImS64 = imguicpp.ImGui.ImS64; 218 | typedef ImS32 = imguicpp.ImGui.ImS32; 219 | typedef ImS16 = imguicpp.ImGui.ImS16; 220 | typedef ImPoolIdx = imguicpp.ImGui.ImPoolIdx; 221 | typedef ImGuiTableDrawChannelIdx = imguicpp.ImGui.ImGuiTableDrawChannelIdx; 222 | typedef ImGuiTableColumnIdx = imguicpp.ImGui.ImGuiTableColumnIdx; 223 | typedef ImGuiSizeCallback = imguicpp.ImGui.ImGuiSizeCallback; 224 | typedef ImGuiInputTextCallback = imguicpp.ImGui.ImGuiInputTextCallback; 225 | typedef ImGuiID = imguicpp.ImGui.ImGuiID; 226 | typedef ImGuiErrorLogCallback = imguicpp.ImGui.ImGuiErrorLogCallback; 227 | typedef ImGuiContextHookCallback = imguicpp.ImGui.ImGuiContextHookCallback; 228 | typedef ImFileHandle = imguicpp.ImGui.ImFileHandle; 229 | typedef ImDrawIdx = imguicpp.ImGui.ImDrawIdx; 230 | typedef ImDrawCallback = imguicpp.ImGui.ImDrawCallback; 231 | #end 232 | -------------------------------------------------------------------------------- /src/imgui/Types.hx: -------------------------------------------------------------------------------- 1 | package imgui; 2 | 3 | typedef Int16 = Int; 4 | 5 | typedef UInt16 = UInt; 6 | 7 | typedef Float32 = Float; 8 | 9 | typedef Char = Dynamic; 10 | 11 | typedef Int8 = Int; 12 | 13 | typedef UInt8 = UInt; 14 | 15 | typedef Int64 = Int; 16 | 17 | typedef UInt64 = UInt; 18 | 19 | typedef VarArg = Dynamic; 20 | 21 | typedef SizeT = Int; 22 | 23 | typedef Star = Array; 24 | 25 | typedef RawPointer = Array; 26 | 27 | typedef RawConstPointer = Array; 28 | 29 | typedef Reference = T; 30 | 31 | typedef Callable = Dynamic; 32 | 33 | typedef VoidPointer = Dynamic; 34 | 35 | typedef IntPointer = Dynamic; 36 | 37 | typedef TextPointer = Dynamic; 38 | 39 | typedef FloatPointer = Dynamic; 40 | 41 | typedef CharPointer = Dynamic; 42 | 43 | typedef BoolPointer = Dynamic; 44 | -------------------------------------------------------------------------------- /src/imguicpp/BoolPointer.hx: -------------------------------------------------------------------------------- 1 | package imguicpp; 2 | 3 | import imguicpp.utils.VarPointer; 4 | 5 | abstract BoolPointer(cpp.Pointer) from cpp.Pointer to cpp.Pointer 6 | { 7 | inline function new(_ptr : cpp.Pointer) 8 | { 9 | this = _ptr; 10 | } 11 | 12 | @:from public static inline function fromBool(_bool : Bool) 13 | { 14 | return new BoolPointer(VarPointer.addressOf(_bool)); 15 | } 16 | 17 | @:from public static inline function fromBoolArray(_array : Array) 18 | { 19 | return new BoolPointer(VarPointer.arrayElem(_array, 0)); 20 | } 21 | 22 | @:to public inline function toBool() : Bool 23 | { 24 | return this.value; 25 | } 26 | 27 | @:to public inline function toPtr() : cpp.Star 28 | { 29 | return this.ptr; 30 | } 31 | 32 | @:to public inline function toRaw() : cpp.RawPointer 33 | { 34 | return this.raw; 35 | } 36 | 37 | @:arrayAccess public inline function get(_idx : Int) : Bool 38 | { 39 | return this[_idx]; 40 | } 41 | 42 | @:arrayAccess public inline function set(_idx : Int, _val : Bool) 43 | { 44 | this[_idx] = _val; 45 | } 46 | } -------------------------------------------------------------------------------- /src/imguicpp/CharPointer.hx: -------------------------------------------------------------------------------- 1 | package imguicpp; 2 | 3 | import haxe.io.Bytes; 4 | import haxe.io.BytesData; 5 | 6 | using cpp.NativeArray; 7 | 8 | abstract CharPointer(cpp.Pointer) from cpp.Pointer to cpp.Pointer 9 | { 10 | inline function new(_ptr : cpp.Pointer) 11 | { 12 | this = _ptr; 13 | } 14 | 15 | @:from public static inline function fromBytes(_bytes : Bytes) 16 | { 17 | return new CharPointer(_bytes.getData().address(0)); 18 | } 19 | 20 | @:from public static inline function fromBytesData(_bytes : BytesData) 21 | { 22 | return new CharPointer(_bytes.address(0)); 23 | } 24 | 25 | @:to public inline function toPtr() : cpp.Star 26 | { 27 | return this.ptr; 28 | } 29 | 30 | @:to public inline function toRaw() : cpp.RawPointer 31 | { 32 | return this.raw; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/imguicpp/FloatPointer.hx: -------------------------------------------------------------------------------- 1 | package imguicpp; 2 | 3 | import imguicpp.utils.VarPointer; 4 | 5 | abstract FloatPointer(cpp.Pointer) from cpp.Pointer to cpp.Pointer 6 | { 7 | inline function new(_ptr : cpp.Pointer) 8 | { 9 | this = _ptr; 10 | } 11 | 12 | @:from public static inline function fromFloat(_float : cpp.Float32) 13 | { 14 | return new FloatPointer(VarPointer.addressOf(_float)); 15 | } 16 | 17 | @:from public static inline function fromFloatArray(_array : Array) 18 | { 19 | return new FloatPointer(VarPointer.arrayElem(_array, 0)); 20 | } 21 | 22 | @:to public inline function toFloat32() : cpp.Float32 23 | { 24 | return this.value; 25 | } 26 | 27 | @:to public inline function toPtr() : cpp.Star 28 | { 29 | return cast this; 30 | } 31 | 32 | @:to public inline function toRaw() : cpp.RawPointer 33 | { 34 | return cast this; 35 | } 36 | } -------------------------------------------------------------------------------- /src/imguicpp/Helpers.hx: -------------------------------------------------------------------------------- 1 | package imguicpp; 2 | 3 | import haxe.io.Bytes; 4 | import haxe.io.BytesData; 5 | 6 | import haxe.macro.Context; 7 | import haxe.macro.Expr; 8 | 9 | #if !macro 10 | import cpp.Float32; 11 | #end 12 | 13 | #if !macro 14 | @:structInit 15 | class BoolHolder { 16 | public var value:Bool = false; 17 | } 18 | 19 | @:structInit 20 | class Float32Holder { 21 | public var value:Float32 = 0; 22 | } 23 | 24 | class Float32ArrayHolder { 25 | public var original:Array = null; 26 | public var value:Array = null; 27 | public function new(original:Array) { 28 | this.original = original; 29 | this.value = @:privateAccess Helpers._readFloatArray(original); 30 | } 31 | } 32 | 33 | @:structInit 34 | class IntHolder { 35 | public var value:Int = 0; 36 | } 37 | #end 38 | 39 | @:headerInclude("linc_imgui.h") 40 | class Helpers { 41 | 42 | macro public static function fromBool(value:ExprOf):Expr { 43 | 44 | return macro { 45 | var _val:imguicpp.Helpers.BoolHolder = { 46 | value: $value 47 | }; 48 | imguicpp.Helpers.pushCallback(function() { 49 | $value = _val.value; 50 | }); 51 | imguicpp.utils.VarPointer.addressOf(_val.value); 52 | }; 53 | 54 | } 55 | 56 | macro public static function fromBoolArray(value:ExprOf>):Expr { 57 | 58 | return macro imguicpp.utils.VarPointer.arrayElem($value, 0); 59 | 60 | } 61 | 62 | macro public static function fromInt(value:ExprOf):Expr { 63 | 64 | return macro { 65 | var _val:imguicpp.Helpers.IntHolder = { 66 | value: $value 67 | }; 68 | imguicpp.Helpers.pushCallback(function() { 69 | $value = _val.value; 70 | }); 71 | imguicpp.utils.VarPointer.addressOf(_val.value); 72 | }; 73 | 74 | } 75 | 76 | macro public static function fromIntArray(value:ExprOf>):Expr { 77 | 78 | return macro imguicpp.utils.VarPointer.arrayElem($value, 0); 79 | 80 | } 81 | 82 | macro public static function fromFloat(value:ExprOf):Expr { 83 | 84 | return macro { 85 | var _val:imguicpp.Helpers.Float32Holder = { 86 | value: $value 87 | }; 88 | imguicpp.Helpers.pushCallback(function() { 89 | $value = _val.value; 90 | }); 91 | imguicpp.utils.VarPointer.addressOf(_val.value); 92 | }; 93 | 94 | } 95 | 96 | macro public static function fromFloatArray(value:ExprOf>):Expr { 97 | 98 | // Convert the original array into Float32 array, then update original array if it has changed. 99 | return macro { 100 | var _val = new imguicpp.Helpers.Float32ArrayHolder($value); 101 | imguicpp.Helpers.pushCallback(function() { 102 | @:privateAccess imguicpp.Helpers._updateFloatArray(_val.original, _val.value); 103 | }); 104 | imguicpp.utils.VarPointer.arrayElem(_val.value, 0); 105 | }; 106 | 107 | } 108 | 109 | macro public static function fromBytes(value:ExprOf):Expr { 110 | 111 | return macro $value.getData().address(0); 112 | 113 | } 114 | 115 | macro public static function fromBytesData(value:ExprOf):Expr { 116 | 117 | return macro $value.address(0); 118 | 119 | } 120 | 121 | /// Internal 122 | 123 | #if !macro 124 | 125 | static function _readFloatArray(value:Array):Array { 126 | 127 | var array:Array = []; 128 | for (i in 0...value.length) { 129 | array[i] = value[i]; 130 | } 131 | return array; 132 | 133 | } 134 | 135 | static function _updateFloatArray(original:Array, array:Array):Bool { 136 | 137 | var changed = false; 138 | for (i in 0...array.length) { 139 | var originalVal:Float = original[i]; 140 | var newVal:Float = array[i]; 141 | if (originalVal != newVal) { 142 | changed = true; 143 | original[i] = newVal; 144 | } 145 | } 146 | return changed; 147 | 148 | } 149 | 150 | static var _pendingCallbacks:ArrayVoid> = null; 151 | 152 | @:noCompletion public static function pushCallback(cb:Void->Void):Void { 153 | 154 | if (untyped __cpp__('ImGui::linc_Helpers_flushCallbacks == NULL')) { 155 | var func = cpp.Callable.fromStaticFunction(Helpers.flushCallbacks); 156 | untyped __cpp__('ImGui::linc_Helpers_flushCallbacks = {0}', func); 157 | } 158 | 159 | if (_pendingCallbacks == null) 160 | _pendingCallbacks = []; 161 | _pendingCallbacks.push(cb); 162 | 163 | } 164 | 165 | @:noCompletion public static function flushCallbacks():Void { 166 | 167 | if (_pendingCallbacks != null) { 168 | while (_pendingCallbacks.length > 0) { 169 | var cb = _pendingCallbacks.shift(); 170 | cb(); 171 | } 172 | } 173 | 174 | } 175 | #end 176 | 177 | } 178 | -------------------------------------------------------------------------------- /src/imguicpp/IntPointer.hx: -------------------------------------------------------------------------------- 1 | package imguicpp; 2 | 3 | import imguicpp.utils.VarPointer; 4 | 5 | abstract IntPointer(cpp.Pointer) from cpp.Pointer to cpp.Pointer 6 | { 7 | inline function new(_ptr : cpp.Pointer) 8 | { 9 | this = _ptr; 10 | } 11 | 12 | @:from public static inline function fromInt(_int : Int) 13 | { 14 | return new IntPointer(VarPointer.addressOf(_int)); 15 | } 16 | 17 | @:from public static inline function fromIntArray(_array : Array) 18 | { 19 | return new IntPointer(VarPointer.arrayElem(_array, 0)); 20 | } 21 | 22 | @:to public inline function toInt() : Int 23 | { 24 | return this.value; 25 | } 26 | 27 | @:to public inline function toRaw() : cpp.RawPointer 28 | { 29 | return this.raw; 30 | } 31 | 32 | @:to public inline function toPtr() : cpp.Star 33 | { 34 | return this.ptr; 35 | } 36 | 37 | @:arrayAccess public inline function get(_idx : Int) : Int 38 | { 39 | return this[_idx]; 40 | } 41 | 42 | @:arrayAccess public inline function set(_idx : Int, _val : Int) 43 | { 44 | this[_idx] = _val; 45 | } 46 | } -------------------------------------------------------------------------------- /src/imguicpp/TextBuffer.hx: -------------------------------------------------------------------------------- 1 | package imguicpp; 2 | 3 | import cpp.Char; 4 | 5 | abstract TextBuffer(Array) { 6 | public function new(_size : Int) { 7 | this = [ for (_ in 0..._size) 0x0 ]; 8 | } 9 | 10 | public function set(_text : String) { 11 | for (i in 0..._text.length) { 12 | this[i] = _text.charCodeAt(i); 13 | } 14 | } 15 | 16 | public function length() { 17 | return this.length; 18 | } 19 | 20 | @:to public function toStar() { 21 | return cpp.Pointer.arrayElem(this, 0).ptr; 22 | } 23 | 24 | @:to public function toString() { 25 | return cpp.NativeString.fromGcPointer(cpp.Pointer.arrayElem(this, 0), this.length); 26 | } 27 | } -------------------------------------------------------------------------------- /src/imguicpp/VoidPointer.hx: -------------------------------------------------------------------------------- 1 | package imguicpp; 2 | 3 | import imguicpp.utils.VarPointer; 4 | 5 | abstract VoidPointer(cpp.Pointer) from cpp.Pointer to cpp.Pointer 6 | { 7 | inline function new(_ptr : cpp.Pointer) 8 | { 9 | this = _ptr; 10 | } 11 | 12 | @:from public static inline function fromInt(_int : Int) 13 | { 14 | return new VoidPointer(VarPointer.addressOf(_int).reinterpret()); 15 | } 16 | 17 | @:from public static inline function fromFloat(_float : Float) 18 | { 19 | return new VoidPointer(VarPointer.addressOf(_float).reinterpret()); 20 | } 21 | 22 | @:from public static inline function fromBool(_bool : Bool) 23 | { 24 | return new VoidPointer(VarPointer.addressOf(_bool).reinterpret()); 25 | } 26 | 27 | @:from public static inline function fromPointer(_pointer : cpp.Pointer) 28 | { 29 | return new VoidPointer(untyped __cpp__('(void*){0}', _pointer)); 30 | } 31 | 32 | @:from public static inline function fromBytes(_bytes : haxe.io.Bytes) 33 | { 34 | return new VoidPointer(fromPointer(VarPointer.arrayElem(_bytes.getData(), 0))); 35 | } 36 | 37 | @:from public static inline function fromArray(_array : Array) 38 | { 39 | return new VoidPointer(fromPointer(VarPointer.arrayElem(_array, 0))); 40 | } 41 | 42 | @:to public inline function toRaw() : cpp.RawPointer 43 | { 44 | return this.raw; 45 | } 46 | 47 | @:to public inline function toPtr() : cpp.Star 48 | { 49 | return this.ptr; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/imguicpp/linc/Linc.hx: -------------------------------------------------------------------------------- 1 | package imguicpp.linc; 2 | 3 | import haxe.io.Path; 4 | import haxe.macro.Expr; 5 | import haxe.macro.Context; 6 | 7 | using haxe.macro.PositionTools; 8 | 9 | 10 | class Linc { 11 | 12 | /** Adds a private internal inline static variable called __touch, 13 | which sets the value to the current time so that builds are always 14 | updated by the code, and native changes are dragged in automatically (except for header only changes) */ 15 | macro public static function touch() : Array { 16 | 17 | var _fields = Context.getBuildFields(); 18 | 19 | _fields.push({ 20 | name: '__touch', pos: Context.currentPos(), 21 | doc: null, meta: [], access: [APrivate, AStatic, AInline], 22 | kind: FVar(macro : String, macro $v{ Std.string(Date.now().getTime()) }), 23 | }); 24 | 25 | return _fields; 26 | 27 | } //touch 28 | 29 | /** Adds a @:buildXml meta node with a linc and an tag. 30 | The set is named LINC_${_lib}_PATH, and points to the root folder of the library. 31 | That path is calculated from the calling file using the optional _relative_root, default ../ 32 | This means that somelib/ is the root. 33 | somelib/somelib/Somelib.hx is the calling file. 34 | LINC_SOMELIB_PATH is set to somelib/ 35 | ${LINC_SOMELIB_PATH}/linc/linc_${_lib}.xml is added directly. */ 36 | macro public static function xml(_lib:String, _relative_root:String='../../'):Array { 37 | 38 | var _pos = Context.currentPos(); 39 | var _pos_info = _pos.getInfos(); 40 | var _class = Context.getLocalClass(); 41 | 42 | var _source_path = Path.directory(_pos_info.file); 43 | if( !Path.isAbsolute(_source_path) ) { 44 | _source_path = Path.join([Sys.getCwd(), _source_path]); 45 | } 46 | 47 | _source_path = Path.normalize(_source_path); 48 | 49 | var _linc_lib_path = Path.normalize(Path.join([_source_path, _relative_root])); 50 | var _linc_include_path = Path.normalize(Path.join([ _linc_lib_path, './linc/linc_${_lib}.xml' ])); 51 | var _linc_lib_var = 'LINC_${_lib.toUpperCase()}_PATH'; 52 | 53 | var _define = ''; 54 | var _import_path = '$${$_linc_lib_var}src/imguicpp/linc/linc_${_lib}.xml'; 55 | var _import = ''; 56 | 57 | _class.get().meta.add(":buildXml", [{ expr:EConst( CString( '$_define\n$_import' ) ), pos:_pos }], _pos ); 58 | 59 | return Context.getBuildFields(); 60 | 61 | } //xml 62 | 63 | } //Linc 64 | -------------------------------------------------------------------------------- /src/imguicpp/linc/linc_imgui.cpp: -------------------------------------------------------------------------------- 1 | //hxcpp include should be first 2 | #include 3 | #include "./linc_imgui.h" 4 | 5 | namespace ImGui { 6 | 7 | void (*linc_Helpers_flushCallbacks)(void) = NULL; 8 | 9 | bool linc_VSliderScalar(const char* label, const ImVec2& size, ImGuiDataType data_type, void* p_data, const void* p_min, const void* p_max, const char* format, ImGuiSliderFlags flags) { 10 | bool _res = ImGui::VSliderScalar(label,size,data_type,p_data,p_min,p_max,format,flags); 11 | if (linc_Helpers_flushCallbacks != NULL) (*linc_Helpers_flushCallbacks)(); 12 | return _res; 13 | } 14 | 15 | bool linc_VSliderInt(const char* label, const ImVec2& size, int* v, int v_min, int v_max, const char* format, ImGuiSliderFlags flags) { 16 | bool _res = ImGui::VSliderInt(label,size,v,v_min,v_max,format,flags); 17 | if (linc_Helpers_flushCallbacks != NULL) (*linc_Helpers_flushCallbacks)(); 18 | return _res; 19 | } 20 | 21 | bool linc_VSliderFloat(const char* label, const ImVec2& size, float* v, float v_min, float v_max, const char* format, ImGuiSliderFlags flags) { 22 | bool _res = ImGui::VSliderFloat(label,size,v,v_min,v_max,format,flags); 23 | if (linc_Helpers_flushCallbacks != NULL) (*linc_Helpers_flushCallbacks)(); 24 | return _res; 25 | } 26 | 27 | void linc_TreePush(const char* str_id) { 28 | ImGui::TreePush(str_id); 29 | if (linc_Helpers_flushCallbacks != NULL) (*linc_Helpers_flushCallbacks)(); 30 | } 31 | 32 | void linc_TreePush(const void* ptr_id) { 33 | ImGui::TreePush(ptr_id); 34 | if (linc_Helpers_flushCallbacks != NULL) (*linc_Helpers_flushCallbacks)(); 35 | } 36 | 37 | bool linc_TreeNodeV(const char* str_id, const char* fmt, va_list args) { 38 | bool _res = ImGui::TreeNodeV(str_id,fmt,args); 39 | if (linc_Helpers_flushCallbacks != NULL) (*linc_Helpers_flushCallbacks)(); 40 | return _res; 41 | } 42 | 43 | bool linc_TreeNodeV(const void* ptr_id, const char* fmt, va_list args) { 44 | bool _res = ImGui::TreeNodeV(ptr_id,fmt,args); 45 | if (linc_Helpers_flushCallbacks != NULL) (*linc_Helpers_flushCallbacks)(); 46 | return _res; 47 | } 48 | 49 | bool linc_TreeNodeExV(const char* str_id, ImGuiTreeNodeFlags flags, const char* fmt, va_list args) { 50 | bool _res = ImGui::TreeNodeExV(str_id,flags,fmt,args); 51 | if (linc_Helpers_flushCallbacks != NULL) (*linc_Helpers_flushCallbacks)(); 52 | return _res; 53 | } 54 | 55 | bool linc_TreeNodeExV(const void* ptr_id, ImGuiTreeNodeFlags flags, const char* fmt, va_list args) { 56 | bool _res = ImGui::TreeNodeExV(ptr_id,flags,fmt,args); 57 | if (linc_Helpers_flushCallbacks != NULL) (*linc_Helpers_flushCallbacks)(); 58 | return _res; 59 | } 60 | 61 | bool linc_TreeNodeEx(const char* label, ImGuiTreeNodeFlags flags) { 62 | bool _res = ImGui::TreeNodeEx(label,flags); 63 | if (linc_Helpers_flushCallbacks != NULL) (*linc_Helpers_flushCallbacks)(); 64 | return _res; 65 | } 66 | 67 | bool linc_TreeNodeEx(const char* str_id, ImGuiTreeNodeFlags flags, const char* fmt, ...) { 68 | va_list _args; 69 | va_start(_args, fmt); 70 | bool _res = ImGui::TreeNodeExV(str_id,flags,fmt,_args); 71 | if (linc_Helpers_flushCallbacks != NULL) (*linc_Helpers_flushCallbacks)(); 72 | return _res; 73 | } 74 | 75 | bool linc_TreeNodeEx(const void* ptr_id, ImGuiTreeNodeFlags flags, const char* fmt, ...) { 76 | va_list _args; 77 | va_start(_args, fmt); 78 | bool _res = ImGui::TreeNodeExV(ptr_id,flags,fmt,_args); 79 | if (linc_Helpers_flushCallbacks != NULL) (*linc_Helpers_flushCallbacks)(); 80 | return _res; 81 | } 82 | 83 | bool linc_TreeNode(const char* label) { 84 | bool _res = ImGui::TreeNode(label); 85 | if (linc_Helpers_flushCallbacks != NULL) (*linc_Helpers_flushCallbacks)(); 86 | return _res; 87 | } 88 | 89 | bool linc_TreeNode(const char* str_id, const char* fmt, ...) { 90 | va_list _args; 91 | va_start(_args, fmt); 92 | bool _res = ImGui::TreeNodeV(str_id,fmt,_args); 93 | if (linc_Helpers_flushCallbacks != NULL) (*linc_Helpers_flushCallbacks)(); 94 | return _res; 95 | } 96 | 97 | bool linc_TreeNode(const void* ptr_id, const char* fmt, ...) { 98 | va_list _args; 99 | va_start(_args, fmt); 100 | bool _res = ImGui::TreeNodeV(ptr_id,fmt,_args); 101 | if (linc_Helpers_flushCallbacks != NULL) (*linc_Helpers_flushCallbacks)(); 102 | return _res; 103 | } 104 | 105 | void linc_TextWrapped(const char* fmt, ...) { 106 | va_list _args; 107 | va_start(_args, fmt); 108 | ImGui::TextWrappedV(fmt,_args); 109 | if (linc_Helpers_flushCallbacks != NULL) (*linc_Helpers_flushCallbacks)(); 110 | } 111 | 112 | void linc_TextDisabled(const char* fmt, ...) { 113 | va_list _args; 114 | va_start(_args, fmt); 115 | ImGui::TextDisabledV(fmt,_args); 116 | if (linc_Helpers_flushCallbacks != NULL) (*linc_Helpers_flushCallbacks)(); 117 | } 118 | 119 | void linc_TextColored(const ImVec4 col, const char* fmt, ...) { 120 | va_list _args; 121 | va_start(_args, fmt); 122 | ImGui::TextColoredV(col,fmt,_args); 123 | if (linc_Helpers_flushCallbacks != NULL) (*linc_Helpers_flushCallbacks)(); 124 | } 125 | 126 | void linc_Text(const char* fmt, ...) { 127 | va_list _args; 128 | va_start(_args, fmt); 129 | ImGui::TextV(fmt,_args); 130 | if (linc_Helpers_flushCallbacks != NULL) (*linc_Helpers_flushCallbacks)(); 131 | } 132 | 133 | bool linc_SliderScalarN(const char* label, ImGuiDataType data_type, void* p_data, int components, const void* p_min, const void* p_max, const char* format, ImGuiSliderFlags flags) { 134 | bool _res = ImGui::SliderScalarN(label,data_type,p_data,components,p_min,p_max,format,flags); 135 | if (linc_Helpers_flushCallbacks != NULL) (*linc_Helpers_flushCallbacks)(); 136 | return _res; 137 | } 138 | 139 | bool linc_SliderScalar(const char* label, ImGuiDataType data_type, void* p_data, const void* p_min, const void* p_max, const char* format, ImGuiSliderFlags flags) { 140 | bool _res = ImGui::SliderScalar(label,data_type,p_data,p_min,p_max,format,flags); 141 | if (linc_Helpers_flushCallbacks != NULL) (*linc_Helpers_flushCallbacks)(); 142 | return _res; 143 | } 144 | 145 | bool linc_SliderInt4(const char* label, int v[4], int v_min, int v_max, const char* format, ImGuiSliderFlags flags) { 146 | bool _res = ImGui::SliderInt4(label,v,v_min,v_max,format,flags); 147 | if (linc_Helpers_flushCallbacks != NULL) (*linc_Helpers_flushCallbacks)(); 148 | return _res; 149 | } 150 | 151 | bool linc_SliderInt3(const char* label, int v[3], int v_min, int v_max, const char* format, ImGuiSliderFlags flags) { 152 | bool _res = ImGui::SliderInt3(label,v,v_min,v_max,format,flags); 153 | if (linc_Helpers_flushCallbacks != NULL) (*linc_Helpers_flushCallbacks)(); 154 | return _res; 155 | } 156 | 157 | bool linc_SliderInt2(const char* label, int v[2], int v_min, int v_max, const char* format, ImGuiSliderFlags flags) { 158 | bool _res = ImGui::SliderInt2(label,v,v_min,v_max,format,flags); 159 | if (linc_Helpers_flushCallbacks != NULL) (*linc_Helpers_flushCallbacks)(); 160 | return _res; 161 | } 162 | 163 | bool linc_SliderInt(const char* label, int* v, int v_min, int v_max, const char* format, ImGuiSliderFlags flags) { 164 | bool _res = ImGui::SliderInt(label,v,v_min,v_max,format,flags); 165 | if (linc_Helpers_flushCallbacks != NULL) (*linc_Helpers_flushCallbacks)(); 166 | return _res; 167 | } 168 | 169 | bool linc_SliderFloat4(const char* label, float v[4], float v_min, float v_max, const char* format, ImGuiSliderFlags flags) { 170 | bool _res = ImGui::SliderFloat4(label,v,v_min,v_max,format,flags); 171 | if (linc_Helpers_flushCallbacks != NULL) (*linc_Helpers_flushCallbacks)(); 172 | return _res; 173 | } 174 | 175 | bool linc_SliderFloat3(const char* label, float v[3], float v_min, float v_max, const char* format, ImGuiSliderFlags flags) { 176 | bool _res = ImGui::SliderFloat3(label,v,v_min,v_max,format,flags); 177 | if (linc_Helpers_flushCallbacks != NULL) (*linc_Helpers_flushCallbacks)(); 178 | return _res; 179 | } 180 | 181 | bool linc_SliderFloat2(const char* label, float v[2], float v_min, float v_max, const char* format, ImGuiSliderFlags flags) { 182 | bool _res = ImGui::SliderFloat2(label,v,v_min,v_max,format,flags); 183 | if (linc_Helpers_flushCallbacks != NULL) (*linc_Helpers_flushCallbacks)(); 184 | return _res; 185 | } 186 | 187 | bool linc_SliderFloat(const char* label, float* v, float v_min, float v_max, const char* format, ImGuiSliderFlags flags) { 188 | bool _res = ImGui::SliderFloat(label,v,v_min,v_max,format,flags); 189 | if (linc_Helpers_flushCallbacks != NULL) (*linc_Helpers_flushCallbacks)(); 190 | return _res; 191 | } 192 | 193 | bool linc_SliderAngle(const char* label, float* v_rad, float v_degrees_min, float v_degrees_max, const char* format, ImGuiSliderFlags flags) { 194 | bool _res = ImGui::SliderAngle(label,v_rad,v_degrees_min,v_degrees_max,format,flags); 195 | if (linc_Helpers_flushCallbacks != NULL) (*linc_Helpers_flushCallbacks)(); 196 | return _res; 197 | } 198 | 199 | void linc_ShowMetricsWindow(bool* p_open) { 200 | ImGui::ShowMetricsWindow(p_open); 201 | if (linc_Helpers_flushCallbacks != NULL) (*linc_Helpers_flushCallbacks)(); 202 | } 203 | 204 | void linc_ShowDemoWindow(bool* p_open) { 205 | ImGui::ShowDemoWindow(p_open); 206 | if (linc_Helpers_flushCallbacks != NULL) (*linc_Helpers_flushCallbacks)(); 207 | } 208 | 209 | void linc_ShowAboutWindow(bool* p_open) { 210 | ImGui::ShowAboutWindow(p_open); 211 | if (linc_Helpers_flushCallbacks != NULL) (*linc_Helpers_flushCallbacks)(); 212 | } 213 | 214 | void linc_SetTooltip(const char* fmt, ...) { 215 | va_list _args; 216 | va_start(_args, fmt); 217 | ImGui::SetTooltipV(fmt,_args); 218 | if (linc_Helpers_flushCallbacks != NULL) (*linc_Helpers_flushCallbacks)(); 219 | } 220 | 221 | void linc_SetNextWindowSizeConstraints(const ImVec2 size_min, const ImVec2& size_max, ImGuiSizeCallback custom_callback, void* custom_callback_data) { 222 | ImGui::SetNextWindowSizeConstraints(size_min,size_max,custom_callback,custom_callback_data); 223 | if (linc_Helpers_flushCallbacks != NULL) (*linc_Helpers_flushCallbacks)(); 224 | } 225 | 226 | bool linc_SetDragDropPayload(const char* type, const void* data, size_t sz, ImGuiCond cond) { 227 | bool _res = ImGui::SetDragDropPayload(type,data,sz,cond); 228 | if (linc_Helpers_flushCallbacks != NULL) (*linc_Helpers_flushCallbacks)(); 229 | return _res; 230 | } 231 | 232 | void linc_SetAllocatorFunctions(void*(*alloc_func)(size_t sz,void* user_data), void(*free_func)(void* ptr,void* user_data), void* user_data) { 233 | ImGui::SetAllocatorFunctions(alloc_func,free_func,user_data); 234 | if (linc_Helpers_flushCallbacks != NULL) (*linc_Helpers_flushCallbacks)(); 235 | } 236 | 237 | bool linc_Selectable(const char* label, bool selected, ImGuiSelectableFlags flags, const ImVec2& size) { 238 | bool _res = ImGui::Selectable(label,selected,flags,size); 239 | if (linc_Helpers_flushCallbacks != NULL) (*linc_Helpers_flushCallbacks)(); 240 | return _res; 241 | } 242 | 243 | bool linc_Selectable(const char* label, bool* p_selected, ImGuiSelectableFlags flags, const ImVec2& size) { 244 | bool _res = ImGui::Selectable(label,p_selected,flags,size); 245 | if (linc_Helpers_flushCallbacks != NULL) (*linc_Helpers_flushCallbacks)(); 246 | return _res; 247 | } 248 | 249 | bool linc_RadioButton(const char* label, bool active) { 250 | bool _res = ImGui::RadioButton(label,active); 251 | if (linc_Helpers_flushCallbacks != NULL) (*linc_Helpers_flushCallbacks)(); 252 | return _res; 253 | } 254 | 255 | bool linc_RadioButton(const char* label, int* v, int v_button) { 256 | bool _res = ImGui::RadioButton(label,v,v_button); 257 | if (linc_Helpers_flushCallbacks != NULL) (*linc_Helpers_flushCallbacks)(); 258 | return _res; 259 | } 260 | 261 | void linc_PushID(const char* str_id) { 262 | ImGui::PushID(str_id); 263 | if (linc_Helpers_flushCallbacks != NULL) (*linc_Helpers_flushCallbacks)(); 264 | } 265 | 266 | void linc_PushID(const char* str_id_begin, const char* str_id_end) { 267 | ImGui::PushID(str_id_begin,str_id_end); 268 | if (linc_Helpers_flushCallbacks != NULL) (*linc_Helpers_flushCallbacks)(); 269 | } 270 | 271 | void linc_PushID(const void* ptr_id) { 272 | ImGui::PushID(ptr_id); 273 | if (linc_Helpers_flushCallbacks != NULL) (*linc_Helpers_flushCallbacks)(); 274 | } 275 | 276 | void linc_PushID(int int_id) { 277 | ImGui::PushID(int_id); 278 | if (linc_Helpers_flushCallbacks != NULL) (*linc_Helpers_flushCallbacks)(); 279 | } 280 | 281 | void linc_PlotLines(const char* label, const float* values, int values_count, int values_offset, const char* overlay_text, float scale_min, float scale_max, ImVec2 graph_size, int stride) { 282 | ImGui::PlotLines(label,values,values_count,values_offset,overlay_text,scale_min,scale_max,graph_size,stride); 283 | if (linc_Helpers_flushCallbacks != NULL) (*linc_Helpers_flushCallbacks)(); 284 | } 285 | 286 | void linc_PlotLines(const char* label, float(*values_getter)(void* data,int idx), void* data, int values_count, int values_offset, const char* overlay_text, float scale_min, float scale_max, ImVec2 graph_size) { 287 | ImGui::PlotLines(label,values_getter,data,values_count,values_offset,overlay_text,scale_min,scale_max,graph_size); 288 | if (linc_Helpers_flushCallbacks != NULL) (*linc_Helpers_flushCallbacks)(); 289 | } 290 | 291 | void linc_PlotHistogram(const char* label, const float* values, int values_count, int values_offset, const char* overlay_text, float scale_min, float scale_max, ImVec2 graph_size, int stride) { 292 | ImGui::PlotHistogram(label,values,values_count,values_offset,overlay_text,scale_min,scale_max,graph_size,stride); 293 | if (linc_Helpers_flushCallbacks != NULL) (*linc_Helpers_flushCallbacks)(); 294 | } 295 | 296 | void linc_PlotHistogram(const char* label, float(*values_getter)(void* data,int idx), void* data, int values_count, int values_offset, const char* overlay_text, float scale_min, float scale_max, ImVec2 graph_size) { 297 | ImGui::PlotHistogram(label,values_getter,data,values_count,values_offset,overlay_text,scale_min,scale_max,graph_size); 298 | if (linc_Helpers_flushCallbacks != NULL) (*linc_Helpers_flushCallbacks)(); 299 | } 300 | 301 | bool linc_MenuItem(const char* label, const char* shortcut, bool selected, bool enabled) { 302 | bool _res = ImGui::MenuItem(label,shortcut,selected,enabled); 303 | if (linc_Helpers_flushCallbacks != NULL) (*linc_Helpers_flushCallbacks)(); 304 | return _res; 305 | } 306 | 307 | bool linc_MenuItem(const char* label, const char* shortcut, bool* p_selected, bool enabled) { 308 | bool _res = ImGui::MenuItem(label,shortcut,p_selected,enabled); 309 | if (linc_Helpers_flushCallbacks != NULL) (*linc_Helpers_flushCallbacks)(); 310 | return _res; 311 | } 312 | 313 | void linc_MemFree(void* ptr) { 314 | ImGui::MemFree(ptr); 315 | if (linc_Helpers_flushCallbacks != NULL) (*linc_Helpers_flushCallbacks)(); 316 | } 317 | 318 | bool linc_ListBox(const char* label, int* current_item, const char* const items[], int items_count, int height_in_items) { 319 | bool _res = ImGui::ListBox(label,current_item,items,items_count,height_in_items); 320 | if (linc_Helpers_flushCallbacks != NULL) (*linc_Helpers_flushCallbacks)(); 321 | return _res; 322 | } 323 | 324 | bool linc_ListBox(const char* label, int* current_item, bool(*items_getter)(void* data,int idx,const char** out_text), void* data, int items_count, int height_in_items) { 325 | bool _res = ImGui::ListBox(label,current_item,items_getter,data,items_count,height_in_items); 326 | if (linc_Helpers_flushCallbacks != NULL) (*linc_Helpers_flushCallbacks)(); 327 | return _res; 328 | } 329 | 330 | void linc_LabelText(const char* label, const char* fmt, ...) { 331 | va_list _args; 332 | va_start(_args, fmt); 333 | ImGui::LabelTextV(label,fmt,_args); 334 | if (linc_Helpers_flushCallbacks != NULL) (*linc_Helpers_flushCallbacks)(); 335 | } 336 | 337 | bool linc_InputTextWithHint(const char* label, const char* hint, char* buf, size_t buf_size, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback, void* user_data) { 338 | bool _res = ImGui::InputTextWithHint(label,hint,buf,buf_size,flags,callback,user_data); 339 | if (linc_Helpers_flushCallbacks != NULL) (*linc_Helpers_flushCallbacks)(); 340 | return _res; 341 | } 342 | 343 | bool linc_InputTextMultiline(const char* label, char* buf, size_t buf_size, const ImVec2& size, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback, void* user_data) { 344 | bool _res = ImGui::InputTextMultiline(label,buf,buf_size,size,flags,callback,user_data); 345 | if (linc_Helpers_flushCallbacks != NULL) (*linc_Helpers_flushCallbacks)(); 346 | return _res; 347 | } 348 | 349 | bool linc_InputText(const char* label, char* buf, size_t buf_size, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback, void* user_data) { 350 | bool _res = ImGui::InputText(label,buf,buf_size,flags,callback,user_data); 351 | if (linc_Helpers_flushCallbacks != NULL) (*linc_Helpers_flushCallbacks)(); 352 | return _res; 353 | } 354 | 355 | bool linc_InputScalarN(const char* label, ImGuiDataType data_type, void* p_data, int components, const void* p_step, const void* p_step_fast, const char* format, ImGuiInputTextFlags flags) { 356 | bool _res = ImGui::InputScalarN(label,data_type,p_data,components,p_step,p_step_fast,format,flags); 357 | if (linc_Helpers_flushCallbacks != NULL) (*linc_Helpers_flushCallbacks)(); 358 | return _res; 359 | } 360 | 361 | bool linc_InputScalar(const char* label, ImGuiDataType data_type, void* p_data, const void* p_step, const void* p_step_fast, const char* format, ImGuiInputTextFlags flags) { 362 | bool _res = ImGui::InputScalar(label,data_type,p_data,p_step,p_step_fast,format,flags); 363 | if (linc_Helpers_flushCallbacks != NULL) (*linc_Helpers_flushCallbacks)(); 364 | return _res; 365 | } 366 | 367 | bool linc_InputInt4(const char* label, int v[4], ImGuiInputTextFlags flags) { 368 | bool _res = ImGui::InputInt4(label,v,flags); 369 | if (linc_Helpers_flushCallbacks != NULL) (*linc_Helpers_flushCallbacks)(); 370 | return _res; 371 | } 372 | 373 | bool linc_InputInt3(const char* label, int v[3], ImGuiInputTextFlags flags) { 374 | bool _res = ImGui::InputInt3(label,v,flags); 375 | if (linc_Helpers_flushCallbacks != NULL) (*linc_Helpers_flushCallbacks)(); 376 | return _res; 377 | } 378 | 379 | bool linc_InputInt2(const char* label, int v[2], ImGuiInputTextFlags flags) { 380 | bool _res = ImGui::InputInt2(label,v,flags); 381 | if (linc_Helpers_flushCallbacks != NULL) (*linc_Helpers_flushCallbacks)(); 382 | return _res; 383 | } 384 | 385 | bool linc_InputInt(const char* label, int* v, int step, int step_fast, ImGuiInputTextFlags flags) { 386 | bool _res = ImGui::InputInt(label,v,step,step_fast,flags); 387 | if (linc_Helpers_flushCallbacks != NULL) (*linc_Helpers_flushCallbacks)(); 388 | return _res; 389 | } 390 | 391 | bool linc_InputFloat4(const char* label, float v[4], const char* format, ImGuiInputTextFlags flags) { 392 | bool _res = ImGui::InputFloat4(label,v,format,flags); 393 | if (linc_Helpers_flushCallbacks != NULL) (*linc_Helpers_flushCallbacks)(); 394 | return _res; 395 | } 396 | 397 | bool linc_InputFloat3(const char* label, float v[3], const char* format, ImGuiInputTextFlags flags) { 398 | bool _res = ImGui::InputFloat3(label,v,format,flags); 399 | if (linc_Helpers_flushCallbacks != NULL) (*linc_Helpers_flushCallbacks)(); 400 | return _res; 401 | } 402 | 403 | bool linc_InputFloat2(const char* label, float v[2], const char* format, ImGuiInputTextFlags flags) { 404 | bool _res = ImGui::InputFloat2(label,v,format,flags); 405 | if (linc_Helpers_flushCallbacks != NULL) (*linc_Helpers_flushCallbacks)(); 406 | return _res; 407 | } 408 | 409 | bool linc_InputFloat(const char* label, float* v, float step, float step_fast, const char* format, ImGuiInputTextFlags flags) { 410 | bool _res = ImGui::InputFloat(label,v,step,step_fast,format,flags); 411 | if (linc_Helpers_flushCallbacks != NULL) (*linc_Helpers_flushCallbacks)(); 412 | return _res; 413 | } 414 | 415 | ImGuiID linc_GetID(const char* str_id) { 416 | ImGuiID _res = ImGui::GetID(str_id); 417 | if (linc_Helpers_flushCallbacks != NULL) (*linc_Helpers_flushCallbacks)(); 418 | return _res; 419 | } 420 | 421 | ImGuiID linc_GetID(const char* str_id_begin, const char* str_id_end) { 422 | ImGuiID _res = ImGui::GetID(str_id_begin,str_id_end); 423 | if (linc_Helpers_flushCallbacks != NULL) (*linc_Helpers_flushCallbacks)(); 424 | return _res; 425 | } 426 | 427 | ImGuiID linc_GetID(const void* ptr_id) { 428 | ImGuiID _res = ImGui::GetID(ptr_id); 429 | if (linc_Helpers_flushCallbacks != NULL) (*linc_Helpers_flushCallbacks)(); 430 | return _res; 431 | } 432 | 433 | void linc_End() { 434 | ImGui::End(); 435 | if (linc_Helpers_flushCallbacks != NULL) (*linc_Helpers_flushCallbacks)(); 436 | } 437 | 438 | bool linc_DragScalarN(const char* label, ImGuiDataType data_type, void* p_data, int components, float v_speed, const void* p_min, const void* p_max, const char* format, ImGuiSliderFlags flags) { 439 | bool _res = ImGui::DragScalarN(label,data_type,p_data,components,v_speed,p_min,p_max,format,flags); 440 | if (linc_Helpers_flushCallbacks != NULL) (*linc_Helpers_flushCallbacks)(); 441 | return _res; 442 | } 443 | 444 | bool linc_DragScalar(const char* label, ImGuiDataType data_type, void* p_data, float v_speed, const void* p_min, const void* p_max, const char* format, ImGuiSliderFlags flags) { 445 | bool _res = ImGui::DragScalar(label,data_type,p_data,v_speed,p_min,p_max,format,flags); 446 | if (linc_Helpers_flushCallbacks != NULL) (*linc_Helpers_flushCallbacks)(); 447 | return _res; 448 | } 449 | 450 | bool linc_DragIntRange2(const char* label, int* v_current_min, int* v_current_max, float v_speed, int v_min, int v_max, const char* format, const char* format_max, ImGuiSliderFlags flags) { 451 | bool _res = ImGui::DragIntRange2(label,v_current_min,v_current_max,v_speed,v_min,v_max,format,format_max,flags); 452 | if (linc_Helpers_flushCallbacks != NULL) (*linc_Helpers_flushCallbacks)(); 453 | return _res; 454 | } 455 | 456 | bool linc_DragInt4(const char* label, int v[4], float v_speed, int v_min, int v_max, const char* format, ImGuiSliderFlags flags) { 457 | bool _res = ImGui::DragInt4(label,v,v_speed,v_min,v_max,format,flags); 458 | if (linc_Helpers_flushCallbacks != NULL) (*linc_Helpers_flushCallbacks)(); 459 | return _res; 460 | } 461 | 462 | bool linc_DragInt3(const char* label, int v[3], float v_speed, int v_min, int v_max, const char* format, ImGuiSliderFlags flags) { 463 | bool _res = ImGui::DragInt3(label,v,v_speed,v_min,v_max,format,flags); 464 | if (linc_Helpers_flushCallbacks != NULL) (*linc_Helpers_flushCallbacks)(); 465 | return _res; 466 | } 467 | 468 | bool linc_DragInt2(const char* label, int v[2], float v_speed, int v_min, int v_max, const char* format, ImGuiSliderFlags flags) { 469 | bool _res = ImGui::DragInt2(label,v,v_speed,v_min,v_max,format,flags); 470 | if (linc_Helpers_flushCallbacks != NULL) (*linc_Helpers_flushCallbacks)(); 471 | return _res; 472 | } 473 | 474 | bool linc_DragInt(const char* label, int* v, float v_speed, int v_min, int v_max, const char* format, ImGuiSliderFlags flags) { 475 | bool _res = ImGui::DragInt(label,v,v_speed,v_min,v_max,format,flags); 476 | if (linc_Helpers_flushCallbacks != NULL) (*linc_Helpers_flushCallbacks)(); 477 | return _res; 478 | } 479 | 480 | bool linc_DragFloatRange2(const char* label, float* v_current_min, float* v_current_max, float v_speed, float v_min, float v_max, const char* format, const char* format_max, ImGuiSliderFlags flags) { 481 | bool _res = ImGui::DragFloatRange2(label,v_current_min,v_current_max,v_speed,v_min,v_max,format,format_max,flags); 482 | if (linc_Helpers_flushCallbacks != NULL) (*linc_Helpers_flushCallbacks)(); 483 | return _res; 484 | } 485 | 486 | bool linc_DragFloat4(const char* label, float v[4], float v_speed, float v_min, float v_max, const char* format, ImGuiSliderFlags flags) { 487 | bool _res = ImGui::DragFloat4(label,v,v_speed,v_min,v_max,format,flags); 488 | if (linc_Helpers_flushCallbacks != NULL) (*linc_Helpers_flushCallbacks)(); 489 | return _res; 490 | } 491 | 492 | bool linc_DragFloat3(const char* label, float v[3], float v_speed, float v_min, float v_max, const char* format, ImGuiSliderFlags flags) { 493 | bool _res = ImGui::DragFloat3(label,v,v_speed,v_min,v_max,format,flags); 494 | if (linc_Helpers_flushCallbacks != NULL) (*linc_Helpers_flushCallbacks)(); 495 | return _res; 496 | } 497 | 498 | bool linc_DragFloat2(const char* label, float v[2], float v_speed, float v_min, float v_max, const char* format, ImGuiSliderFlags flags) { 499 | bool _res = ImGui::DragFloat2(label,v,v_speed,v_min,v_max,format,flags); 500 | if (linc_Helpers_flushCallbacks != NULL) (*linc_Helpers_flushCallbacks)(); 501 | return _res; 502 | } 503 | 504 | bool linc_DragFloat(const char* label, float* v, float v_speed, float v_min, float v_max, const char* format, ImGuiSliderFlags flags) { 505 | bool _res = ImGui::DragFloat(label,v,v_speed,v_min,v_max,format,flags); 506 | if (linc_Helpers_flushCallbacks != NULL) (*linc_Helpers_flushCallbacks)(); 507 | return _res; 508 | } 509 | 510 | bool linc_Combo(const char* label, int* current_item, const char* const items[], int items_count, int popup_max_height_in_items) { 511 | bool _res = ImGui::Combo(label,current_item,items,items_count,popup_max_height_in_items); 512 | if (linc_Helpers_flushCallbacks != NULL) (*linc_Helpers_flushCallbacks)(); 513 | return _res; 514 | } 515 | 516 | bool linc_Combo(const char* label, int* current_item, const char* items_separated_by_zeros, int popup_max_height_in_items) { 517 | bool _res = ImGui::Combo(label,current_item,items_separated_by_zeros,popup_max_height_in_items); 518 | if (linc_Helpers_flushCallbacks != NULL) (*linc_Helpers_flushCallbacks)(); 519 | return _res; 520 | } 521 | 522 | bool linc_Combo(const char* label, int* current_item, bool(*items_getter)(void* data,int idx,const char** out_text), void* data, int items_count, int popup_max_height_in_items) { 523 | bool _res = ImGui::Combo(label,current_item,items_getter,data,items_count,popup_max_height_in_items); 524 | if (linc_Helpers_flushCallbacks != NULL) (*linc_Helpers_flushCallbacks)(); 525 | return _res; 526 | } 527 | 528 | bool linc_ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags flags, const float* ref_col) { 529 | bool _res = ImGui::ColorPicker4(label,col,flags,ref_col); 530 | if (linc_Helpers_flushCallbacks != NULL) (*linc_Helpers_flushCallbacks)(); 531 | return _res; 532 | } 533 | 534 | bool linc_ColorPicker3(const char* label, float col[3], ImGuiColorEditFlags flags) { 535 | bool _res = ImGui::ColorPicker3(label,col,flags); 536 | if (linc_Helpers_flushCallbacks != NULL) (*linc_Helpers_flushCallbacks)(); 537 | return _res; 538 | } 539 | 540 | bool linc_ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flags) { 541 | bool _res = ImGui::ColorEdit4(label,col,flags); 542 | if (linc_Helpers_flushCallbacks != NULL) (*linc_Helpers_flushCallbacks)(); 543 | return _res; 544 | } 545 | 546 | bool linc_ColorEdit3(const char* label, float col[3], ImGuiColorEditFlags flags) { 547 | bool _res = ImGui::ColorEdit3(label,col,flags); 548 | if (linc_Helpers_flushCallbacks != NULL) (*linc_Helpers_flushCallbacks)(); 549 | return _res; 550 | } 551 | 552 | void linc_ColorConvertRGBtoHSV(float r, float g, float b, float* out_h, float* out_s, float* out_v) { 553 | ImGui::ColorConvertRGBtoHSV(r,g,b,*out_h,*out_s,*out_v); 554 | if (linc_Helpers_flushCallbacks != NULL) (*linc_Helpers_flushCallbacks)(); 555 | } 556 | 557 | void linc_ColorConvertHSVtoRGB(float h, float s, float v, float* out_r, float* out_g, float* out_b) { 558 | ImGui::ColorConvertHSVtoRGB(h,s,v,*out_r,*out_g,*out_b); 559 | if (linc_Helpers_flushCallbacks != NULL) (*linc_Helpers_flushCallbacks)(); 560 | } 561 | 562 | bool linc_CollapsingHeader(const char* label, ImGuiTreeNodeFlags flags) { 563 | bool _res = ImGui::CollapsingHeader(label,flags); 564 | if (linc_Helpers_flushCallbacks != NULL) (*linc_Helpers_flushCallbacks)(); 565 | return _res; 566 | } 567 | 568 | bool linc_CollapsingHeader(const char* label, bool* p_visible, ImGuiTreeNodeFlags flags) { 569 | bool _res = ImGui::CollapsingHeader(label,p_visible,flags); 570 | if (linc_Helpers_flushCallbacks != NULL) (*linc_Helpers_flushCallbacks)(); 571 | return _res; 572 | } 573 | 574 | bool linc_CheckboxFlags(const char* label, int* flags, int flags_value) { 575 | bool _res = ImGui::CheckboxFlags(label,flags,flags_value); 576 | if (linc_Helpers_flushCallbacks != NULL) (*linc_Helpers_flushCallbacks)(); 577 | return _res; 578 | } 579 | 580 | bool linc_CheckboxFlags(const char* label, unsigned int* flags, unsigned int flags_value) { 581 | bool _res = ImGui::CheckboxFlags(label,flags,flags_value); 582 | if (linc_Helpers_flushCallbacks != NULL) (*linc_Helpers_flushCallbacks)(); 583 | return _res; 584 | } 585 | 586 | bool linc_Checkbox(const char* label, bool* v) { 587 | bool _res = ImGui::Checkbox(label,v); 588 | if (linc_Helpers_flushCallbacks != NULL) (*linc_Helpers_flushCallbacks)(); 589 | return _res; 590 | } 591 | 592 | void linc_CalcListClipping(int items_count, float items_height, int* out_items_display_start, int* out_items_display_end) { 593 | ImGui::CalcListClipping(items_count,items_height,out_items_display_start,out_items_display_end); 594 | if (linc_Helpers_flushCallbacks != NULL) (*linc_Helpers_flushCallbacks)(); 595 | } 596 | 597 | void linc_BulletText(const char* fmt, ...) { 598 | va_list _args; 599 | va_start(_args, fmt); 600 | ImGui::BulletTextV(fmt,_args); 601 | if (linc_Helpers_flushCallbacks != NULL) (*linc_Helpers_flushCallbacks)(); 602 | } 603 | 604 | bool linc_BeginTabItem(const char* label, bool* p_open, ImGuiTabItemFlags flags) { 605 | bool _res = ImGui::BeginTabItem(label,p_open,flags); 606 | if (linc_Helpers_flushCallbacks != NULL) (*linc_Helpers_flushCallbacks)(); 607 | return _res; 608 | } 609 | 610 | bool linc_BeginPopupModal(const char* name, bool* p_open, ImGuiWindowFlags flags) { 611 | bool _res = ImGui::BeginPopupModal(name,p_open,flags); 612 | if (linc_Helpers_flushCallbacks != NULL) (*linc_Helpers_flushCallbacks)(); 613 | return _res; 614 | } 615 | 616 | bool linc_Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) { 617 | bool _res = ImGui::Begin(name,p_open,flags); 618 | if (linc_Helpers_flushCallbacks != NULL) (*linc_Helpers_flushCallbacks)(); 619 | return _res; 620 | } 621 | 622 | 623 | 624 | } 625 | -------------------------------------------------------------------------------- /src/imguicpp/linc/linc_imgui.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifndef HXCPP_H 4 | #include 5 | #endif 6 | 7 | #include "imgui.h" 8 | 9 | namespace ImGui { 10 | 11 | extern void (*linc_Helpers_flushCallbacks)(void); 12 | 13 | bool linc_VSliderScalar(const char* label, const ImVec2& size, ImGuiDataType data_type, void* p_data, const void* p_min, const void* p_max, const char* format=NULL, ImGuiSliderFlags flags=0); 14 | 15 | bool linc_VSliderInt(const char* label, const ImVec2& size, int* v, int v_min, int v_max, const char* format="%d", ImGuiSliderFlags flags=0); 16 | 17 | bool linc_VSliderFloat(const char* label, const ImVec2& size, float* v, float v_min, float v_max, const char* format="%.3f", ImGuiSliderFlags flags=0); 18 | 19 | void linc_TreePush(const char* str_id); 20 | 21 | void linc_TreePush(const void* ptr_id=NULL); 22 | 23 | bool linc_TreeNodeV(const char* str_id, const char* fmt, va_list args); 24 | 25 | bool linc_TreeNodeV(const void* ptr_id, const char* fmt, va_list args); 26 | 27 | bool linc_TreeNodeExV(const char* str_id, ImGuiTreeNodeFlags flags, const char* fmt, va_list args); 28 | 29 | bool linc_TreeNodeExV(const void* ptr_id, ImGuiTreeNodeFlags flags, const char* fmt, va_list args); 30 | 31 | bool linc_TreeNodeEx(const char* label, ImGuiTreeNodeFlags flags=0); 32 | 33 | bool linc_TreeNodeEx(const char* str_id, ImGuiTreeNodeFlags flags, const char* fmt, ...); 34 | 35 | bool linc_TreeNodeEx(const void* ptr_id, ImGuiTreeNodeFlags flags, const char* fmt, ...); 36 | 37 | bool linc_TreeNode(const char* label); 38 | 39 | bool linc_TreeNode(const char* str_id, const char* fmt, ...); 40 | 41 | bool linc_TreeNode(const void* ptr_id, const char* fmt, ...); 42 | 43 | void linc_TextWrapped(const char* fmt, ...); 44 | 45 | void linc_TextDisabled(const char* fmt, ...); 46 | 47 | void linc_TextColored(const ImVec4& col, const char* fmt, ...); 48 | 49 | void linc_Text(const char* fmt, ...); 50 | 51 | bool linc_SliderScalarN(const char* label, ImGuiDataType data_type, void* p_data, int components, const void* p_min, const void* p_max, const char* format=NULL, ImGuiSliderFlags flags=0); 52 | 53 | bool linc_SliderScalar(const char* label, ImGuiDataType data_type, void* p_data, const void* p_min, const void* p_max, const char* format=NULL, ImGuiSliderFlags flags=0); 54 | 55 | bool linc_SliderInt4(const char* label, int v[4], int v_min, int v_max, const char* format="%d", ImGuiSliderFlags flags=0); 56 | 57 | bool linc_SliderInt3(const char* label, int v[3], int v_min, int v_max, const char* format="%d", ImGuiSliderFlags flags=0); 58 | 59 | bool linc_SliderInt2(const char* label, int v[2], int v_min, int v_max, const char* format="%d", ImGuiSliderFlags flags=0); 60 | 61 | bool linc_SliderInt(const char* label, int* v, int v_min, int v_max, const char* format="%d", ImGuiSliderFlags flags=0); 62 | 63 | bool linc_SliderFloat4(const char* label, float v[4], float v_min, float v_max, const char* format="%.3f", ImGuiSliderFlags flags=0); 64 | 65 | bool linc_SliderFloat3(const char* label, float v[3], float v_min, float v_max, const char* format="%.3f", ImGuiSliderFlags flags=0); 66 | 67 | bool linc_SliderFloat2(const char* label, float v[2], float v_min, float v_max, const char* format="%.3f", ImGuiSliderFlags flags=0); 68 | 69 | bool linc_SliderFloat(const char* label, float* v, float v_min, float v_max, const char* format="%.3f", ImGuiSliderFlags flags=0); 70 | 71 | bool linc_SliderAngle(const char* label, float* v_rad, float v_degrees_min=-360.0f, float v_degrees_max=+360.0f, const char* format="%.0f deg", ImGuiSliderFlags flags=0); 72 | 73 | void linc_ShowMetricsWindow(bool* p_open=NULL); 74 | 75 | void linc_ShowDemoWindow(bool* p_open=NULL); 76 | 77 | void linc_ShowAboutWindow(bool* p_open=NULL); 78 | 79 | void linc_SetTooltip(const char* fmt, ...); 80 | 81 | void linc_SetNextWindowSizeConstraints(const ImVec2& size_min, const ImVec2& size_max, ImGuiSizeCallback custom_callback=NULL, void* custom_callback_data=NULL); 82 | 83 | bool linc_SetDragDropPayload(const char* type, const void* data, size_t sz, ImGuiCond cond=0); 84 | 85 | void linc_SetAllocatorFunctions(void*(*alloc_func)(size_t sz, void* user_data), void(*free_func)(void* ptr, void* user_data), void* user_data=NULL); 86 | 87 | bool linc_Selectable(const char* label, bool selected=false, ImGuiSelectableFlags flags=0, const ImVec2& size=ImVec2(0, 0)); 88 | 89 | bool linc_Selectable(const char* label, bool* p_selected, ImGuiSelectableFlags flags=0, const ImVec2& size=ImVec2(0, 0)); 90 | 91 | bool linc_RadioButton(const char* label, bool active); 92 | 93 | bool linc_RadioButton(const char* label, int* v, int v_button); 94 | 95 | void linc_PushID(const char* str_id); 96 | 97 | void linc_PushID(const char* str_id_begin, const char* str_id_end); 98 | 99 | void linc_PushID(const void* ptr_id); 100 | 101 | void linc_PushID(int int_id); 102 | 103 | void linc_PlotLines(const char* label, const float* values, int values_count, int values_offset=0, const char* overlay_text=NULL, float scale_min=3.40282346638528859811704183484516925e+38F, float scale_max=3.40282346638528859811704183484516925e+38F, ImVec2 graph_size=ImVec2(0, 0), int stride=sizeof(float)); 104 | 105 | void linc_PlotLines(const char* label, float(*values_getter)(void* data, int idx), void* data, int values_count, int values_offset=0, const char* overlay_text=NULL, float scale_min=3.40282346638528859811704183484516925e+38F, float scale_max=3.40282346638528859811704183484516925e+38F, ImVec2 graph_size=ImVec2(0, 0)); 106 | 107 | void linc_PlotHistogram(const char* label, const float* values, int values_count, int values_offset=0, const char* overlay_text=NULL, float scale_min=3.40282346638528859811704183484516925e+38F, float scale_max=3.40282346638528859811704183484516925e+38F, ImVec2 graph_size=ImVec2(0, 0), int stride=sizeof(float)); 108 | 109 | void linc_PlotHistogram(const char* label, float(*values_getter)(void* data, int idx), void* data, int values_count, int values_offset=0, const char* overlay_text=NULL, float scale_min=3.40282346638528859811704183484516925e+38F, float scale_max=3.40282346638528859811704183484516925e+38F, ImVec2 graph_size=ImVec2(0, 0)); 110 | 111 | bool linc_MenuItem(const char* label, const char* shortcut=NULL, bool selected=false, bool enabled=true); 112 | 113 | bool linc_MenuItem(const char* label, const char* shortcut, bool* p_selected, bool enabled=true); 114 | 115 | void linc_MemFree(void* ptr); 116 | 117 | bool linc_ListBox(const char* label, int* current_item, const char* const items[], int items_count, int height_in_items=-1); 118 | 119 | bool linc_ListBox(const char* label, int* current_item, bool(*items_getter)(void* data, int idx, const char** out_text), void* data, int items_count, int height_in_items=-1); 120 | 121 | void linc_LabelText(const char* label, const char* fmt, ...); 122 | 123 | bool linc_InputTextWithHint(const char* label, const char* hint, char* buf, size_t buf_size, ImGuiInputTextFlags flags=0, ImGuiInputTextCallback callback=NULL, void* user_data=NULL); 124 | 125 | bool linc_InputTextMultiline(const char* label, char* buf, size_t buf_size, const ImVec2& size=ImVec2(0, 0), ImGuiInputTextFlags flags=0, ImGuiInputTextCallback callback=NULL, void* user_data=NULL); 126 | 127 | bool linc_InputText(const char* label, char* buf, size_t buf_size, ImGuiInputTextFlags flags=0, ImGuiInputTextCallback callback=NULL, void* user_data=NULL); 128 | 129 | bool linc_InputScalarN(const char* label, ImGuiDataType data_type, void* p_data, int components, const void* p_step=NULL, const void* p_step_fast=NULL, const char* format=NULL, ImGuiInputTextFlags flags=0); 130 | 131 | bool linc_InputScalar(const char* label, ImGuiDataType data_type, void* p_data, const void* p_step=NULL, const void* p_step_fast=NULL, const char* format=NULL, ImGuiInputTextFlags flags=0); 132 | 133 | bool linc_InputInt4(const char* label, int v[4], ImGuiInputTextFlags flags=0); 134 | 135 | bool linc_InputInt3(const char* label, int v[3], ImGuiInputTextFlags flags=0); 136 | 137 | bool linc_InputInt2(const char* label, int v[2], ImGuiInputTextFlags flags=0); 138 | 139 | bool linc_InputInt(const char* label, int* v, int step=1, int step_fast=100, ImGuiInputTextFlags flags=0); 140 | 141 | bool linc_InputFloat4(const char* label, float v[4], const char* format="%.3f", ImGuiInputTextFlags flags=0); 142 | 143 | bool linc_InputFloat3(const char* label, float v[3], const char* format="%.3f", ImGuiInputTextFlags flags=0); 144 | 145 | bool linc_InputFloat2(const char* label, float v[2], const char* format="%.3f", ImGuiInputTextFlags flags=0); 146 | 147 | bool linc_InputFloat(const char* label, float* v, float step=0.0f, float step_fast=0.0f, const char* format="%.3f", ImGuiInputTextFlags flags=0); 148 | 149 | ImGuiID linc_GetID(const char* str_id); 150 | 151 | ImGuiID linc_GetID(const char* str_id_begin, const char* str_id_end); 152 | 153 | ImGuiID linc_GetID(const void* ptr_id); 154 | 155 | void linc_End(); 156 | 157 | bool linc_DragScalarN(const char* label, ImGuiDataType data_type, void* p_data, int components, float v_speed, const void* p_min=NULL, const void* p_max=NULL, const char* format=NULL, ImGuiSliderFlags flags=0); 158 | 159 | bool linc_DragScalar(const char* label, ImGuiDataType data_type, void* p_data, float v_speed, const void* p_min=NULL, const void* p_max=NULL, const char* format=NULL, ImGuiSliderFlags flags=0); 160 | 161 | bool linc_DragIntRange2(const char* label, int* v_current_min, int* v_current_max, float v_speed=1.0f, int v_min=0, int v_max=0, const char* format="%d", const char* format_max=NULL, ImGuiSliderFlags flags=0); 162 | 163 | bool linc_DragInt4(const char* label, int v[4], float v_speed=1.0f, int v_min=0, int v_max=0, const char* format="%d", ImGuiSliderFlags flags=0); 164 | 165 | bool linc_DragInt3(const char* label, int v[3], float v_speed=1.0f, int v_min=0, int v_max=0, const char* format="%d", ImGuiSliderFlags flags=0); 166 | 167 | bool linc_DragInt2(const char* label, int v[2], float v_speed=1.0f, int v_min=0, int v_max=0, const char* format="%d", ImGuiSliderFlags flags=0); 168 | 169 | bool linc_DragInt(const char* label, int* v, float v_speed=1.0f, int v_min=0, int v_max=0, const char* format="%d", ImGuiSliderFlags flags=0); 170 | 171 | bool linc_DragFloatRange2(const char* label, float* v_current_min, float* v_current_max, float v_speed=1.0f, float v_min=0.0f, float v_max=0.0f, const char* format="%.3f", const char* format_max=NULL, ImGuiSliderFlags flags=0); 172 | 173 | bool linc_DragFloat4(const char* label, float v[4], float v_speed=1.0f, float v_min=0.0f, float v_max=0.0f, const char* format="%.3f", ImGuiSliderFlags flags=0); 174 | 175 | bool linc_DragFloat3(const char* label, float v[3], float v_speed=1.0f, float v_min=0.0f, float v_max=0.0f, const char* format="%.3f", ImGuiSliderFlags flags=0); 176 | 177 | bool linc_DragFloat2(const char* label, float v[2], float v_speed=1.0f, float v_min=0.0f, float v_max=0.0f, const char* format="%.3f", ImGuiSliderFlags flags=0); 178 | 179 | bool linc_DragFloat(const char* label, float* v, float v_speed=1.0f, float v_min=0.0f, float v_max=0.0f, const char* format="%.3f", ImGuiSliderFlags flags=0); 180 | 181 | bool linc_Combo(const char* label, int* current_item, const char* const items[], int items_count, int popup_max_height_in_items=-1); 182 | 183 | bool linc_Combo(const char* label, int* current_item, const char* items_separated_by_zeros, int popup_max_height_in_items=-1); 184 | 185 | bool linc_Combo(const char* label, int* current_item, bool(*items_getter)(void* data, int idx, const char** out_text), void* data, int items_count, int popup_max_height_in_items=-1); 186 | 187 | bool linc_ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags flags=0, const float* ref_col=NULL); 188 | 189 | bool linc_ColorPicker3(const char* label, float col[3], ImGuiColorEditFlags flags=0); 190 | 191 | bool linc_ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flags=0); 192 | 193 | bool linc_ColorEdit3(const char* label, float col[3], ImGuiColorEditFlags flags=0); 194 | 195 | void linc_ColorConvertRGBtoHSV(float r, float g, float b, float& out_h, float& out_s, float& out_v); 196 | 197 | void linc_ColorConvertHSVtoRGB(float h, float s, float v, float& out_r, float& out_g, float& out_b); 198 | 199 | bool linc_CollapsingHeader(const char* label, ImGuiTreeNodeFlags flags=0); 200 | 201 | bool linc_CollapsingHeader(const char* label, bool* p_visible, ImGuiTreeNodeFlags flags=0); 202 | 203 | bool linc_CheckboxFlags(const char* label, int* flags, int flags_value); 204 | 205 | bool linc_CheckboxFlags(const char* label, unsigned int* flags, unsigned int flags_value); 206 | 207 | bool linc_Checkbox(const char* label, bool* v); 208 | 209 | void linc_CalcListClipping(int items_count, float items_height, int* out_items_display_start, int* out_items_display_end); 210 | 211 | void linc_BulletText(const char* fmt, ...); 212 | 213 | bool linc_BeginTabItem(const char* label, bool* p_open=NULL, ImGuiTabItemFlags flags=0); 214 | 215 | bool linc_BeginPopupModal(const char* name, bool* p_open=NULL, ImGuiWindowFlags flags=0); 216 | 217 | bool linc_Begin(const char* name, bool* p_open=NULL, ImGuiWindowFlags flags=0); 218 | 219 | 220 | 221 | } 222 | -------------------------------------------------------------------------------- /src/imguicpp/linc/linc_imgui.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 |
32 | 33 | 34 |
35 | 36 |
37 | 38 | 39 |
40 | 41 |
42 |
43 | 44 | 45 |
46 | 47 |
48 | 49 | 50 |
51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 |
-------------------------------------------------------------------------------- /src/imguicpp/utils/VarConstCharStar.hx: -------------------------------------------------------------------------------- 1 | package imguicpp.utils; 2 | 3 | import cpp.Char; 4 | import cpp.RawConstPointer; 5 | import haxe.extern.AsVar; 6 | 7 | extern abstract VarConstCharStar(RawConstPointer) to(RawConstPointer) { 8 | inline function new(s:AsVar) 9 | this = cpp.NativeString.raw(s); 10 | 11 | @:from 12 | static public inline function fromString(s:String):VarConstCharStar 13 | return new VarConstCharStar(s); 14 | 15 | @:to extern public inline function toString():String 16 | return new String(untyped this); 17 | 18 | @:to extern public inline function toPointer():RawConstPointer 19 | return this; 20 | } -------------------------------------------------------------------------------- /src/imguicpp/utils/VarPointer.hx: -------------------------------------------------------------------------------- 1 | package imguicpp.utils; 2 | 3 | import cpp.Star; 4 | import cpp.Pointer; 5 | import cpp.AutoCast; 6 | import cpp.Reference; 7 | import cpp.RawPointer; 8 | import cpp.NativeArray; 9 | import cpp.ConstPointer; 10 | import haxe.extern.AsVar; 11 | 12 | @:coreType 13 | @:native("cpp.Pointer") 14 | @:include("cpp/Pointer.h") 15 | @:semantics(variable) 16 | extern class VarPointer extends ConstPointer implements ArrayAccess { 17 | var ref(get, set):Reference; 18 | 19 | function get_ref():Reference; 20 | function set_ref(t:T):Reference; 21 | 22 | function setAt(inIndex:Int, value:T):Void; 23 | 24 | static function fromRaw(ptr:RawPointer):Pointer; 25 | 26 | @:native("::cpp::Pointer_obj::fromRaw") 27 | static function fromStar(star:Star):Pointer; 28 | 29 | @:native("::cpp::Pointer_obj::fromHandle") 30 | static function nativeFromHandle(inHandle:Dynamic, ?inKind:String):AutoCast; 31 | inline static function fromHandle(inHandle:Dynamic, ?inKind:String):Pointer { 32 | return cast nativeFromHandle(inHandle, inKind); 33 | } 34 | 35 | static function fromPointer(inNativePointer:Dynamic):Pointer; 36 | 37 | static function addressOf(inVariable:AsVar>):Pointer; 38 | 39 | static function endOf(inVariable:T):Pointer; 40 | 41 | @:native("::cpp::Pointer_obj::arrayElem") 42 | static function nativeArrayElem(array:AsVar>, inElem:Int):AutoCast; 43 | inline static function arrayElem(array:AsVar>, inElem:Int):Pointer { 44 | return cast nativeArrayElem(array, inElem); 45 | } 46 | 47 | @:native("::cpp::Pointer_obj::ofArray") 48 | static function nativeOfArray(array:AsVar>):AutoCast; 49 | inline static function ofArray(array:AsVar>):Pointer { 50 | return cast nativeOfArray(array); 51 | } 52 | 53 | inline function toUnmanagedArray(elementCount:Int):Array { 54 | var result = new Array(); 55 | NativeArray.setUnmanagedData(result, this, elementCount); 56 | return result; 57 | } 58 | 59 | inline function toUnmanagedVector(elementCount:Int):haxe.ds.Vector 60 | return cast toUnmanagedArray(elementCount); 61 | 62 | override function inc():Pointer; 63 | override function dec():Pointer; 64 | override function incBy(inT:Int):Pointer; 65 | override function decBy(inT:Int):Pointer; 66 | override function add(inT:Int):Pointer; 67 | override function sub(inT:Int):Pointer; 68 | 69 | function postIncRef():Reference; 70 | 71 | function destroy():Void; 72 | function destroyArray():Void; 73 | } -------------------------------------------------------------------------------- /src/imguijs/Helpers.hx: -------------------------------------------------------------------------------- 1 | package imguijs; 2 | 3 | import haxe.io.Bytes; 4 | import haxe.io.BytesData; 5 | 6 | import haxe.macro.Context; 7 | import haxe.macro.Expr; 8 | 9 | class Helpers { 10 | 11 | macro public static function fromBool(value:ExprOf):Expr { 12 | 13 | return macro function(?_val:Bool):Bool { 14 | return _val != null ? $value = _val : $value; 15 | }; 16 | 17 | } 18 | 19 | macro public static function fromBoolArray(value:ExprOf>):Expr { 20 | 21 | return macro $value; 22 | 23 | } 24 | 25 | macro public static function fromInt(value:ExprOf):Expr { 26 | 27 | return macro function(?_val:Int):Int { 28 | return _val != null ? $value = _val : $value; 29 | }; 30 | 31 | } 32 | 33 | macro public static function fromIntArray(value:ExprOf>):Expr { 34 | 35 | return macro $value; 36 | 37 | } 38 | 39 | macro public static function fromFloat(value:ExprOf):Expr { 40 | 41 | return macro function(?_val:Float):Float { 42 | return _val != null ? $value = _val : $value; 43 | }; 44 | 45 | } 46 | 47 | macro public static function fromFloatArray(value:ExprOf>):Expr { 48 | 49 | return macro $value; 50 | 51 | } 52 | 53 | macro public static function fromBytes(value:ExprOf):Expr { 54 | 55 | return macro $value.getData(); 56 | 57 | } 58 | 59 | macro public static function fromBytesData(value:ExprOf):Expr { 60 | 61 | return macro $value; 62 | 63 | } 64 | 65 | } 66 | -------------------------------------------------------------------------------- /test/cli/Main.hx: -------------------------------------------------------------------------------- 1 | 2 | import cpp.Pointer; 3 | import imgui.ImGui; 4 | 5 | using cpp.Native; 6 | 7 | class Main 8 | { 9 | public static function main() 10 | { 11 | new Main(); 12 | } 13 | 14 | public function new() 15 | { 16 | final ctx = ImGui.createContext(); 17 | final io = ImGui.getIO(); 18 | io.displaySize = ImVec2.create(640, 480); 19 | 20 | final id = "Some ID"; 21 | 22 | var width = [ 0 ]; 23 | var height = [ 0 ]; 24 | var pixels : cpp.Star = null; 25 | var pixelPtr : cpp.Star> = pixels.addressOf(); 26 | 27 | io.fonts.getTexDataAsRGBA32(pixelPtr, width, height); 28 | io.fonts.texID = Pointer.addressOf(id).raw; 29 | io.backendRendererName = 'my renderer'; 30 | 31 | trace(width[0], height[0]); 32 | 33 | // Update 34 | ImGui.newFrame(); 35 | 36 | ImGui.showDemoWindow(); 37 | 38 | if (ImGui.begin('window')) 39 | { 40 | final ints = [ 1, 2, 3, 4 ]; 41 | 42 | ImGui.sliderInt4('multi ints', ints, 0, 10); 43 | } 44 | ImGui.end(); 45 | 46 | ImGui.render(); 47 | 48 | ImGui.destroyContext(ctx); 49 | 50 | trace('done'); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /test/cli/build.hxml: -------------------------------------------------------------------------------- 1 | -main Main 2 | -cpp cpp 3 | -cp ../../src -------------------------------------------------------------------------------- /test/kha/Assets/hxlogo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jeremyfa/imgui-hx/1f11d8fb2cf3a9b11c87a6852948c7cf937fda0d/test/kha/Assets/hxlogo.png -------------------------------------------------------------------------------- /test/kha/Libraries/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jeremyfa/imgui-hx/1f11d8fb2cf3a9b11c87a6852948c7cf937fda0d/test/kha/Libraries/.gitkeep -------------------------------------------------------------------------------- /test/kha/README.md: -------------------------------------------------------------------------------- 1 | # Build instruction example 2 | node /your/Kha/make --compile windows -------------------------------------------------------------------------------- /test/kha/Sources/ImGuiDemo.hx: -------------------------------------------------------------------------------- 1 | package; 2 | 3 | import kha.System; 4 | import kha.Framebuffer; 5 | import kha.Image; 6 | import kha.Shaders; 7 | import kha.Assets; 8 | import kha.Color; 9 | import kha.input.KeyCode; 10 | import kha.arrays.Float32Array; 11 | import kha.graphics4.Graphics; 12 | import kha.graphics4.TextureUnit; 13 | import kha.graphics4.PipelineState; 14 | import kha.graphics4.VertexStructure; 15 | import kha.graphics4.VertexData; 16 | import kha.graphics4.BlendingFactor; 17 | import kha.graphics4.TextureFormat; 18 | import kha.graphics4.VertexBuffer; 19 | import kha.graphics4.IndexBuffer; 20 | import kha.graphics4.Usage; 21 | import cpp.Callable; 22 | import cpp.Pointer; 23 | import cpp.RawPointer; 24 | import imgui.ImGui; 25 | import imgui.util.ImVec2; 26 | import imgui.draw.ImDrawData; 27 | 28 | class ImGuiDemo { 29 | private static var maxBufferSize:Int = 10000; 30 | private static var pipeline:PipelineState; 31 | private static var texunit:TextureUnit; 32 | private static var imguiTexture:Image; 33 | private static var structure:VertexStructure; 34 | private static var vtx:VertexBuffer; 35 | private static var idx:IndexBuffer; 36 | 37 | // --Mouse and keyboard input-- 38 | private static var inputX:Float; 39 | private static var inputY:Float; 40 | private static var inputDownL:Bool; 41 | private static var inputDownR:Bool; 42 | private static var inputWheelDelta:Int; 43 | private static var isKeyDown:Array; 44 | private static var inputChars:String; 45 | 46 | private static var hxLogo:Image; 47 | 48 | public function new() { 49 | structure = new VertexStructure(); 50 | structure.add("pos", VertexData.Float3); 51 | structure.add("col", VertexData.Float4); 52 | structure.add("tex", VertexData.Float2); 53 | 54 | inputChars = ""; 55 | 56 | isKeyDown = new Array(); 57 | for(i in 0...255) isKeyDown.push(false); 58 | 59 | pipeline = new PipelineState(); 60 | pipeline.inputLayout = [structure]; 61 | pipeline.vertexShader = Shaders.imgui_vert; 62 | pipeline.fragmentShader = Shaders.imgui_frag; 63 | 64 | // --Use transparent blending mode, instead of opaque-- 65 | pipeline.blendSource = BlendingFactor.SourceAlpha; 66 | pipeline.blendDestination = BlendingFactor.InverseSourceAlpha; 67 | pipeline.compile(); 68 | 69 | vtx = new VertexBuffer(maxBufferSize, structure, Usage.StaticUsage); 70 | idx = new IndexBuffer(maxBufferSize, Usage.StaticUsage); 71 | 72 | texunit = pipeline.getTextureUnit("texsampler"); 73 | 74 | ImGui.createContext(); 75 | 76 | var imguiIo = ImGui.getIO(); 77 | imguiIo.displaySize = ImVec2.create(1024, 768); 78 | // --App crashes on attemt to copy if we don't register copy/paste callbacks-- 79 | kha.System.notifyOnCutCopyPaste(khaCut, khaCopy, khaPaste); 80 | 81 | var atlas = Pointer.fromRaw(imguiIo.fonts).ref; 82 | var width : Int = 0; 83 | var height : Int = 0; 84 | var pixels : Array = null; 85 | 86 | atlas.getTexDataAsRGBA32(pixels, width, height); 87 | 88 | var buff:haxe.io.Bytes = haxe.io.Bytes.alloc(pixels.length); 89 | for(i in 0...pixels.length) buff.set(i, pixels[i]); 90 | 91 | // --Seems like whole texture is white, but alpha channel changes-- 92 | // --Multiplication of alpha channel moved to fragment shader-- 93 | imguiTexture = Image.fromBytes(buff, width, height, TextureFormat.RGBA32, Usage.StaticUsage); 94 | 95 | atlas.texID = Pointer.addressOf(imguiTexture).rawCast(); 96 | 97 | kha.input.Mouse.get().notifyWindowed(0, onMouseDown, onMouseUp, onMouseMove, onMouseWheel); 98 | kha.input.Keyboard.get().notify(onKeyDown, onKeyUp, onKeyPress); 99 | 100 | imguiIo.keyMap[ImGuiKey.Tab ] = KeyCode.Tab; 101 | imguiIo.keyMap[ImGuiKey.LeftArrow ] = KeyCode.Left; 102 | imguiIo.keyMap[ImGuiKey.RightArrow] = KeyCode.Right; 103 | imguiIo.keyMap[ImGuiKey.UpArrow ] = KeyCode.Up; 104 | imguiIo.keyMap[ImGuiKey.DownArrow ] = KeyCode.Down; 105 | imguiIo.keyMap[ImGuiKey.PageUp ] = KeyCode.PageUp; 106 | imguiIo.keyMap[ImGuiKey.PageDown ] = KeyCode.PageDown; 107 | imguiIo.keyMap[ImGuiKey.Home ] = KeyCode.Home; 108 | imguiIo.keyMap[ImGuiKey.End ] = KeyCode.End; 109 | imguiIo.keyMap[ImGuiKey.Delete ] = KeyCode.Delete; 110 | imguiIo.keyMap[ImGuiKey.Backspace ] = KeyCode.Backspace; 111 | imguiIo.keyMap[ImGuiKey.Enter ] = KeyCode.Return; 112 | imguiIo.keyMap[ImGuiKey.Escape ] = KeyCode.Escape; 113 | imguiIo.keyMap[ImGuiKey.A ] = KeyCode.A; 114 | imguiIo.keyMap[ImGuiKey.C ] = KeyCode.C; 115 | imguiIo.keyMap[ImGuiKey.V ] = KeyCode.V; 116 | imguiIo.keyMap[ImGuiKey.X ] = KeyCode.X; 117 | imguiIo.keyMap[ImGuiKey.Y ] = KeyCode.Y; 118 | imguiIo.keyMap[ImGuiKey.Z ] = KeyCode.Z; 119 | 120 | Assets.loadEverything(function() { 121 | hxLogo = Assets.images.hxlogo; 122 | System.notifyOnRender(render); 123 | }); 124 | } 125 | 126 | public function onKeyDown(code: kha.input.KeyCode) { 127 | isKeyDown[code] = true; 128 | } 129 | 130 | public function onKeyUp(code: kha.input.KeyCode) { 131 | isKeyDown[code] = false; 132 | } 133 | 134 | public function onKeyPress(char: String) { 135 | inputChars += char; 136 | } 137 | 138 | public static function onMouseDown(button: Int, x: Int, y: Int) { 139 | button == 0 ? inputDownL = true : inputDownR = true; 140 | setInputPosition(Std.int(x), Std.int(y)); 141 | } 142 | 143 | public static function onMouseUp(button: Int, x: Int, y: Int) { 144 | button == 0 ? inputDownL = false : inputDownR = false; 145 | setInputPosition(Std.int(x), Std.int(y)); 146 | } 147 | 148 | public static function onMouseMove(x: Int, y: Int, movementX: Int, movementY: Int) { 149 | // --movementX and movementY may be useful as well-- 150 | setInputPosition(Std.int(x), Std.int(y)); 151 | } 152 | 153 | public static function onMouseWheel(delta: Int) { 154 | inputWheelDelta = delta; 155 | } 156 | 157 | public static function setInputPosition(iX: Int, iY: Int) { 158 | inputX = iX; 159 | inputY = iY; 160 | } 161 | 162 | function render(fb:Framebuffer): Void { 163 | 164 | newFrame(); 165 | 166 | ImGui.begin('logo'); 167 | ImGui.image(Pointer.addressOf(hxLogo).rawCast(), ImVec2.create(128, 128)); 168 | ImGui.end(); 169 | 170 | ImGui.showDemoWindow(); 171 | 172 | ImGui.endFrame(); 173 | 174 | var g4 = fb.g4; 175 | 176 | g4.begin(); 177 | g4.clear(Color.Orange); 178 | // --Turn off rectangle clipping, that was enabled in onRender()-- 179 | // --So it would't affect any other draws-- 180 | 181 | ImGui.render(); 182 | onRender(g4, ImGui.getDrawData()); 183 | 184 | g4.disableScissor(); 185 | g4.end(); 186 | } 187 | 188 | private static function newFrame() { 189 | var io = ImGui.getIO(); 190 | io.displaySize = ImVec2.create(kha.System.windowWidth(), kha.System.windowHeight()); 191 | io.mousePos.x = inputX; 192 | io.mousePos.y = inputY; 193 | io.mouseDown[0] = inputDownL; 194 | io.mouseDown[1] = inputDownR; 195 | io.mouseWheel -= inputWheelDelta; 196 | inputWheelDelta = 0; 197 | 198 | io.keyCtrl = isKeyDown[KeyCode.Control]; 199 | io.keyAlt = isKeyDown[KeyCode.Alt]; 200 | io.keyShift = isKeyDown[KeyCode.Shift]; 201 | io.keySuper = isKeyDown[KeyCode.Win]; 202 | 203 | io.keysDown[KeyCode.Tab ] = isKeyDown[KeyCode.Tab]; 204 | io.keysDown[KeyCode.Left ] = isKeyDown[KeyCode.Left]; 205 | io.keysDown[KeyCode.Right ] = isKeyDown[KeyCode.Right]; 206 | io.keysDown[KeyCode.Up ] = isKeyDown[KeyCode.Up]; 207 | io.keysDown[KeyCode.Down ] = isKeyDown[KeyCode.Down]; 208 | io.keysDown[KeyCode.PageUp ] = isKeyDown[KeyCode.PageUp]; 209 | io.keysDown[KeyCode.PageDown ] = isKeyDown[KeyCode.PageDown]; 210 | io.keysDown[KeyCode.Home ] = isKeyDown[KeyCode.Home]; 211 | io.keysDown[KeyCode.End ] = isKeyDown[KeyCode.End]; 212 | io.keysDown[KeyCode.Return ] = isKeyDown[KeyCode.Return]; 213 | io.keysDown[KeyCode.Backspace] = isKeyDown[KeyCode.Backspace]; 214 | io.keysDown[KeyCode.Escape ] = isKeyDown[KeyCode.Escape]; 215 | io.keysDown[KeyCode.Delete ] = isKeyDown[KeyCode.Delete]; 216 | io.keysDown[KeyCode.A ] = isKeyDown[KeyCode.A]; 217 | io.keysDown[KeyCode.C ] = isKeyDown[KeyCode.C]; 218 | io.keysDown[KeyCode.V ] = isKeyDown[KeyCode.V]; 219 | io.keysDown[KeyCode.X ] = isKeyDown[KeyCode.X]; 220 | io.keysDown[KeyCode.Y ] = isKeyDown[KeyCode.Y]; 221 | io.keysDown[KeyCode.Z ] = isKeyDown[KeyCode.Z]; 222 | 223 | io.addInputCharactersUTF8(inputChars); 224 | inputChars = ""; 225 | 226 | ImGui.newFrame(); 227 | } 228 | 229 | private static function setVertexColor(vBuf:Float32Array, col:Int, startIdx:Int) : Void { 230 | vBuf.set(startIdx + 0, ((col >> 0) & 0xFF) / 255); 231 | vBuf.set(startIdx + 1, ((col >> 8) & 0xFF) / 255); 232 | vBuf.set(startIdx + 2, ((col >> 16) & 0xFF) / 255); 233 | vBuf.set(startIdx + 3, ((col >> 24) & 0xFF) / 255); 234 | } 235 | 236 | private static function onRender(_g4 : Graphics, _dataRawPtr : cpp.RawPointer) : Void { 237 | // --There are probably some mem leaks in this function-- 238 | 239 | var drawData = Pointer.fromRaw(_dataRawPtr).ref; 240 | 241 | var invHalfWW = 1.0 / (kha.System.windowWidth() * .5); 242 | var invHalfWH = 1.0 / (kha.System.windowHeight() * .5); 243 | 244 | for(i in 0...drawData.cmdListsCount) { 245 | var idxOffset = 0; 246 | var cmdList = Pointer.fromRaw(drawData.cmdLists[i]).ref; 247 | var cmdBuffer = cmdList.cmdBuffer.data; 248 | var vtxBuffer = cmdList.vtxBuffer.data; 249 | var idxBuffer = cmdList.idxBuffer.data; 250 | 251 | for (j in 0...cmdList.cmdBuffer.size) { 252 | var cmd = cmdBuffer[j]; 253 | var it : Int = cast cmd.elemCount / 3; 254 | 255 | if (cmd.elemCount > maxBufferSize) { 256 | vtx.delete(); 257 | idx.delete(); 258 | vtx = new VertexBuffer(cmd.elemCount, structure, Usage.StaticUsage); 259 | idx = new IndexBuffer(cmd.elemCount, Usage.StaticUsage); 260 | maxBufferSize = cmd.elemCount; 261 | } 262 | 263 | var v = vtx.lock(); 264 | var ii = idx.lock(); 265 | 266 | for (tri in 0...it) { 267 | var baseIdx = idxOffset + (tri * 3); 268 | var idx1 = idxBuffer[baseIdx + 0]; 269 | var idx2 = idxBuffer[baseIdx + 1]; 270 | var idx3 = idxBuffer[baseIdx + 2]; 271 | var vtx1 = vtxBuffer[idx1]; 272 | var vtx2 = vtxBuffer[idx2]; 273 | var vtx3 = vtxBuffer[idx3]; 274 | var tmul = tri * 27; 275 | 276 | v.set(tmul+0, vtx1.pos.x * invHalfWW - 1); v.set(tmul+1, -(vtx1.pos.y * invHalfWH - 1.0)); v.set(tmul+2, 0.5); // Vertex coord 277 | setVertexColor(v, vtx1.col, tmul + 3); // Vertex color 278 | v.set(tmul+7, vtx1.uv.x); v.set(tmul+8, vtx1.uv.y); // Texture UV coord 279 | v.set(tmul+9, vtx2.pos.x * invHalfWW - 1); v.set(tmul+10, -(vtx2.pos.y * invHalfWH - 1.0)); v.set(tmul+11, 0.5); 280 | setVertexColor(v, vtx2.col, tmul + 12); 281 | v.set(tmul+16, vtx2.uv.x); v.set(tmul+17, vtx2.uv.y); 282 | v.set(tmul+18, vtx3.pos.x * invHalfWW - 1); v.set(tmul+19, -(vtx3.pos.y * invHalfWH - 1.0)); v.set(tmul+20, 0.5); 283 | setVertexColor(v, vtx3.col, tmul + 21); 284 | v.set(tmul+25, vtx3.uv.x); v.set(tmul+26, vtx3.uv.y); 285 | 286 | ii[tri*3+0] = tri*3+0; ii[tri*3+1] = tri*3+1; ii[tri*3+2] = tri*3+2; 287 | } 288 | 289 | vtx.unlock(); 290 | idx.unlock(); 291 | 292 | var tex : Pointer = Pointer.fromRaw(cmd.textureID).reinterpret(); 293 | 294 | _g4.begin(); 295 | _g4.setPipeline(pipeline); 296 | _g4.setTexture(texunit, tex.ref); 297 | _g4.setVertexBuffer(vtx); 298 | _g4.setIndexBuffer(idx); 299 | _g4.scissor(Std.int(cmd.clipRect.x), Std.int(cmd.clipRect.y), Std.int(cmd.clipRect.z - cmd.clipRect.x), Std.int(cmd.clipRect.w - cmd.clipRect.y)); 300 | _g4.drawIndexedVertices(0, cmd.elemCount); 301 | _g4.end(); 302 | 303 | idxOffset += cmd.elemCount; 304 | } 305 | } 306 | } 307 | 308 | private static function khaCut() : String { 309 | return ""; 310 | } 311 | 312 | private static function khaCopy() : String { 313 | return ""; 314 | } 315 | 316 | private static function khaPaste(s:String) : Void { 317 | 318 | } 319 | } 320 | -------------------------------------------------------------------------------- /test/kha/Sources/Main.hx: -------------------------------------------------------------------------------- 1 | package; 2 | 3 | import kha.System; 4 | 5 | class Main { 6 | public static function main() { 7 | System.init({title: "ImGuiDemo", width: 1024, height: 768}, function () { 8 | new ImGuiDemo(); 9 | }); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /test/kha/Sources/Shaders/imgui.frag.glsl: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | in vec4 fragmentColor; 4 | in vec2 texcoord; 5 | out vec4 FragColor; 6 | uniform sampler2D texsampler; 7 | 8 | void main() { 9 | vec4 color = texture(texsampler, texcoord); 10 | FragColor = vec4(fragmentColor.r, fragmentColor.g, fragmentColor.b, fragmentColor.a * color.a); 11 | } 12 | -------------------------------------------------------------------------------- /test/kha/Sources/Shaders/imgui.vert.glsl: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | in vec3 pos; 4 | in vec4 col; 5 | in vec2 tex; 6 | out vec4 fragmentColor; 7 | out vec2 texcoord; 8 | 9 | void main() { 10 | gl_Position = vec4(pos.x, pos.y, 0.5, 1.0); 11 | fragmentColor = col; 12 | texcoord = tex; 13 | } 14 | -------------------------------------------------------------------------------- /test/kha/khafile.js: -------------------------------------------------------------------------------- 1 | let project = new Project('ImGuiDemo'); 2 | project.addSources('Sources'); 3 | project.addShaders('Sources/Shaders/**'); 4 | project.addAssets('Assets/**'); 5 | 6 | // Relative path used only to avoid circular dependencies, like 7 | // linc_imgui/test/kha/Libraries/linc_imgui 8 | // So, feel free to copy linc_imgui into Libraries directory and use 9 | // project.addLibrary('linc_imgui'); 10 | project.addLibrary('../../../../linc_imgui'); 11 | 12 | resolve(project); 13 | --------------------------------------------------------------------------------