├── .circleci └── config.yml ├── .editorconfig ├── .github └── FUNDING.yml ├── .gitignore ├── .gitmodules ├── CHANGELOG.md ├── LICENSE ├── README.md ├── appveyor.yml ├── build.gradle.kts ├── buildSrc ├── build.gradle.kts └── src │ ├── GenDrawListTask.kt │ ├── GenFDTask.kt │ ├── GenFontAtlasTask.kt │ ├── GenFontConfigTask.kt │ ├── GenFontTask.kt │ ├── GenGenTask.kt │ ├── GenIOTask.kt │ ├── GenJavaTask.kt │ ├── GenNativeTypesTask.kt │ ├── GenStyleTask.kt │ ├── GenTask.kt │ ├── ImGuiHeaderParser.kt │ ├── enum-generators.kt │ ├── flag-generators.kt │ ├── generation-utilities.kt │ ├── naitve-build.kt │ └── sort-specs.kt ├── core ├── build.gradle.kts ├── jni │ ├── .gitignore │ ├── CMakeLists.txt │ ├── cmake-modules │ │ ├── FindDirectX.cmake │ │ └── FindWindowsSDK.cmake │ ├── config │ │ ├── fd_customization.h │ │ └── imconfig.h │ ├── project │ │ ├── basics.hpp │ │ ├── cpp_interop.cpp │ │ ├── dx11_impl.cpp │ │ ├── dx9_impl.cpp │ │ ├── fd_wrapper.cpp │ │ ├── glfw_impl.cpp │ │ ├── hand_written_bindings.cpp │ │ ├── imgui_ext.cpp │ │ ├── imgui_ext.h │ │ ├── impl_header.cpp │ │ ├── impl_header.h │ │ ├── overloads_helper.cpp │ │ ├── overloads_helper.hpp │ │ ├── win32_impl.cpp │ │ └── win32_impl.h │ └── win32-glfw │ │ ├── .gitignore │ │ ├── CMakeLists.txt │ │ ├── build.pl │ │ └── main-test.cpp ├── module-info.java ├── src │ └── org │ │ └── ice1000 │ │ └── jimgui │ │ ├── JImDrawList.java │ │ ├── JImFileDialog.java │ │ ├── JImFont.java │ │ ├── JImFontAtlas.java │ │ ├── JImFontConfig.java │ │ ├── JImGui.java │ │ ├── JImGuiIO.java │ │ ├── JImSortSpecs.java │ │ ├── JImStr.java │ │ ├── JImStyle.java │ │ ├── JImStyleVar.java │ │ ├── JImTextureID.java │ │ ├── JImVec4.java │ │ ├── JImWidgets.java │ │ ├── MutableJImVec4.java │ │ ├── NativeBool.java │ │ ├── NativeString.java │ │ ├── NativeStrings.java │ │ ├── NativeTime.java │ │ ├── cpp │ │ ├── DeallocatableObject.java │ │ └── DeallocatableObjectManager.java │ │ ├── flag │ │ ├── Flag.java │ │ ├── JImDirection.java │ │ ├── JImDrawCornerFlags.java │ │ ├── JImDrawListFlags.java │ │ └── package-info.java │ │ ├── glfw │ │ └── GlfwUtil.java │ │ └── util │ │ ├── ColorUtil.java │ │ ├── JImGuiUtil.java │ │ ├── JniLoader.java │ │ ├── NativeUtil.java │ │ └── SharedState.java └── test │ └── org │ └── ice1000 │ └── jimgui │ ├── features │ ├── ComboTest.java │ ├── DateChooserTest.java │ ├── FileDialogTest.java │ ├── InputNativeString.java │ ├── InputTextTest.java │ ├── NativeStringTest.java │ ├── ProgressBarTest.java │ ├── SetWindowTitle.java │ ├── Tables.java │ └── ToggleButtonTest.java │ ├── flag │ ├── FlagTest.java │ └── JImFlagsTest.java │ └── tests │ ├── Demo.java │ ├── EditorTest.java │ ├── Issue14.java │ ├── Issue52.java │ ├── Issue66.java │ ├── JImDrawListTest.java │ ├── JImFontTest.java │ ├── JImGuiTest.java │ ├── JImStyleVarTest.java │ ├── JImTextureTest.java │ ├── JImVec4Test.java │ ├── MultiWindowTest.java │ ├── MutableJImVec4Test.java │ ├── PlatformWindowTest.java │ ├── Sandbox.java │ └── package-info.java ├── extension ├── build.gradle.kts ├── src │ └── org │ │ └── ice1000 │ │ └── jimgui │ │ └── util │ │ └── JniLoaderEx.java └── test │ └── org │ └── ice1000 │ └── jimgui │ └── util │ └── JniLoaderExTest.java ├── fun ├── build.gradle.kts ├── module-info.java └── src │ └── dlparty │ ├── AbstractFireworks.java │ ├── BigCollection.java │ ├── Blobs.java │ ├── BouncingBalls.java │ ├── Circles.java │ ├── Curves.java │ ├── DoomFire.java │ ├── DrivingGame.java │ ├── Guitar.java │ ├── InterwebBlogosphere.java │ ├── MatrixEffect.java │ ├── Mosaic.java │ ├── Plasma.java │ ├── PossiblyAShrub.java │ ├── QuickSortVisualization.java │ ├── RaceTrack.java │ ├── Squares.java │ ├── TestBed.java │ ├── ThreeDCube.java │ ├── ThunderStorm.java │ ├── TinyLoadingScreen.java │ ├── TixyLand.java │ └── package-info.java ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── kotlin-dsl ├── build.gradle.kts ├── module-info.java ├── src │ ├── JImGuiContext.kt │ ├── jimgui.kt │ ├── primitives.kt │ ├── types.kt │ └── util.kt ├── test │ ├── lice-test.kt │ ├── psi-viewer.kt │ ├── tabs.kt │ ├── test.kt │ └── texture.kt └── testRes │ └── bizarre.lice └── settings.gradle.kts /.circleci/config.yml: -------------------------------------------------------------------------------- 1 | # Java Gradle CircleCI 2.0 configuration file 2 | # 3 | # Check https://circleci.com/docs/2.0/language-java/ for more details 4 | # 5 | version: 2 6 | jobs: 7 | build: 8 | docker: 9 | - image: circleci/openjdk:8-jdk 10 | 11 | working_directory: ~/repo 12 | 13 | environment: 14 | # Customize the JVM maximum heap limit 15 | JVM_OPTS: -Xmx3200m 16 | TERM: dumb 17 | PATH: "~/.yarn/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" 18 | 19 | steps: 20 | - checkout 21 | 22 | - run: 23 | name: Install clang, make, glfw3, pkg-config 24 | command: | 25 | sudo apt-get update 26 | sudo apt-get install -y make libglfw3-dev libglfw3-dev pkg-config gcc g++ 27 | gcc -v 28 | 29 | - run: 30 | name: Install cmake 31 | command: | 32 | mkdir -p cmake-3.14 33 | wget -qO- "https://cmake.org/files/v3.14/cmake-3.14.3-Linux-x86_64.tar.gz" | tar --strip-components=1 -xz -C cmake-3.14 34 | 35 | # Download and cache dependencies 36 | - restore_cache: 37 | keys: 38 | - v1-dependencies-{{ checksum "build.gradle.kts" }} 39 | # fallback to using the latest cache if no exact match is found 40 | - v1-dependencies- 41 | 42 | - run: bash gradlew dependencies --no-daemon 43 | 44 | - save_cache: 45 | paths: 46 | - ~/.gradle 47 | key: v1- 48 | 49 | - run: 50 | name: Build all projects 51 | command: PATH=`pwd`/cmake-3.14/bin:$PATH bash gradlew jar --info --stacktrace --no-daemon 52 | 53 | - store_artifacts: 54 | path: core/build/libs 55 | 56 | - store_artifacts: 57 | path: kotlin-dsl/build/libs 58 | 59 | - store_artifacts: 60 | path: extension/build/libs 61 | 62 | - run: 63 | name: Run tests 64 | command: PATH=`pwd`/cmake-3.14/bin:$PATH bash gradlew test --info --stacktrace --no-daemon 65 | 66 | - run: 67 | name: Save test results 68 | command: | 69 | mkdir -p ~/junit/ 70 | find . -type f -regex ".*/build/test-results/.*xml" -exec cp {} ~/junit/ \; 71 | when: always 72 | 73 | - store_test_results: 74 | path: ~/junit 75 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: ice1000 4 | patreon: # Replace with a single Patreon username 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: # Replace with a single Ko-fi username 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | otechie: # Replace with a single Otechie username 12 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] 13 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by .ignore support plugin (hsz.mobi) 2 | 3 | gradle.properties 4 | 5 | ### Java template 6 | # Compiled class file 7 | *.class 8 | 9 | # Log file 10 | *.log 11 | 12 | # BlueJ files 13 | *.ctxt 14 | 15 | # Mobile Tools for Java (J2ME) 16 | .mtj.tmp/ 17 | 18 | # Package Files # 19 | *.jar 20 | *.war 21 | *.nar 22 | *.ear 23 | *.zip 24 | *.tar.gz 25 | *.rar 26 | 27 | testRes 28 | 29 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 30 | hs_err_pid* 31 | ### JetBrains template 32 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm 33 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 34 | 35 | # User-specific stuff 36 | .idea/**/workspace.xml 37 | .idea/**/tasks.xml 38 | .idea/**/dictionaries 39 | .idea/**/shelf 40 | 41 | # Sensitive or high-churn files 42 | .idea/**/dataSources/ 43 | .idea/**/dataSources.ids 44 | .idea/**/dataSources.local.xml 45 | .idea/**/sqlDataSources.xml 46 | .idea/**/dynamic.xml 47 | .idea/**/uiDesigner.xml 48 | 49 | # Gradle 50 | .idea/**/gradle.xml 51 | .idea/**/libraries 52 | 53 | # CMake 54 | cmake-build-debug/ 55 | cmake-build-release/ 56 | cmake-build/ 57 | cmake-build-win64/ 58 | CMakeCache.txt 59 | CMakeFiles 60 | 61 | # Mongo Explorer plugin 62 | .idea/**/mongoSettings.xml 63 | 64 | # File-based project format 65 | *.iws 66 | 67 | # IntelliJ 68 | out/ 69 | 70 | # mpeltonen/sbt-idea plugin 71 | .idea_modules/ 72 | 73 | # JIRA plugin 74 | atlassian-ide-plugin.xml 75 | 76 | # Cursive Clojure plugin 77 | .idea/replstate.xml 78 | 79 | # Crashlytics plugin (for Android Studio and IntelliJ) 80 | com_crashlytics_export_strings.xml 81 | crashlytics.properties 82 | crashlytics-build.properties 83 | fabric.properties 84 | 85 | # Editor-based Rest Client 86 | .idea/httpRequests 87 | ### Gradle template 88 | .gradle 89 | build/ 90 | 91 | # Ignore Gradle GUI config 92 | gradle-app.setting 93 | 94 | # Cache of project 95 | .gradletasknamecache 96 | 97 | !gradle/wrapper/gradle-wrapper.* 98 | 99 | # # Work around https://youtrack.jetbrains.com/issue/IDEA-116898 100 | # gradle/wrapper/gradle-wrapper.properties 101 | 102 | *.iml 103 | .idea 104 | *.so 105 | *.dll 106 | *.dylib 107 | 108 | *.ini 109 | gen 110 | pinpoint_piggy -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "core/jni/glfw"] 2 | path = core/jni/glfw 3 | url = https://github.com/glfw/glfw 4 | -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | image: Visual Studio 2019 2 | 3 | environment: 4 | JAVA_TOOL_OPTIONS: -Dfile.encoding=UTF-8 5 | 6 | build_script: 7 | - set JAVA_HOME="C:\Program Files (x86)\Java\jdk1.8.0" 8 | - gradlew :core:cmake --info --stacktrace --no-daemon 9 | - set JAVA_HOME="C:\Program Files\Java\jdk1.8.0" 10 | - gradlew :core:cmakeWin64 --info --stacktrace --no-daemon 11 | - gradlew jar 12 | 13 | cache: 14 | - C:\Users\appveyor\.gradle 15 | 16 | test_script: 17 | - set JAVA_HOME="C:\Program Files\Java\jdk1.8.0" 18 | - gradlew test --info --stacktrace --no-daemon 19 | - set JAVA_HOME="C:\Program Files (x86)\Java\jdk1.8.0" 20 | - gradlew test --info --stacktrace --no-daemon 21 | 22 | artifacts: 23 | - path: 'core\build\libs\*.jar' 24 | name: jimgui-core 25 | - path: 'kotlin-dsl\build\libs\*.jar' 26 | name: jimgui-dsl 27 | - path: 'fun\build\libs\*.jar' 28 | name: jimgui-fun 29 | # 30 | -------------------------------------------------------------------------------- /build.gradle.kts: -------------------------------------------------------------------------------- 1 | buildscript { 2 | repositories { 3 | mavenCentral() 4 | } 5 | 6 | dependencies { 7 | classpath("org.glavo:module-info-compiler:1.5") 8 | } 9 | } 10 | 11 | plugins { 12 | java 13 | `maven-publish` 14 | signing 15 | kotlin("jvm") version "1.6.21" apply false 16 | id("de.undercouch.download") version "5.0.5" apply false 17 | } 18 | 19 | val isCI = !System.getenv("CI").isNullOrBlank() 20 | 21 | subprojects { 22 | group = "org.ice1000.jimgui" 23 | version = "v0.22.0" 24 | 25 | apply { 26 | plugin("java") 27 | plugin("signing") 28 | plugin("maven-publish") 29 | } 30 | 31 | repositories { 32 | mavenCentral() 33 | jcenter() 34 | } 35 | 36 | tasks.withType().configureEach { 37 | options.apply { 38 | isDeprecation = true 39 | isWarnings = true 40 | isDebug = !isCI 41 | options.encoding = "UTF-8" 42 | compilerArgs.add("-Xlint:unchecked") 43 | } 44 | } 45 | 46 | if (org.ice1000.gradle.isMac) tasks.withType().configureEach { 47 | jvmArgs("-XstartOnFirstThread") 48 | } 49 | 50 | java { 51 | withSourcesJar() 52 | withJavadocJar() 53 | sourceCompatibility = JavaVersion.VERSION_1_8 54 | targetCompatibility = JavaVersion.VERSION_1_8 55 | } 56 | 57 | tasks.withType().configureEach { 58 | (options as StandardJavadocDocletOptions).tags( 59 | "apiNote:a:API Note:", 60 | "implSpec:a:Implementation Requirements:", 61 | "implNote:a:Implementation Note:") 62 | } 63 | 64 | if (file("module-info.java").exists()) { 65 | val compileModuleInfo = tasks.register("compileModuleInfo") { 66 | sourceFile.set(file("module-info.java")) 67 | targetFile.set(buildDir.resolve("classes/java/module-info/module-info.class")) 68 | } 69 | 70 | tasks.jar { 71 | dependsOn(compileModuleInfo) 72 | from(compileModuleInfo.get().targetFile) 73 | } 74 | } 75 | 76 | artifacts { 77 | add("archives", tasks["sourcesJar"]) 78 | add("archives", tasks["javadocJar"]) 79 | } 80 | 81 | if (hasProperty("ossrhUsername")) publishing.repositories { 82 | maven("https://oss.sonatype.org/service/local/staging/deploy/maven2") { 83 | name = "MavenCentral" 84 | credentials { 85 | username = property("ossrhUsername").toString() 86 | password = property("ossrhPassword").toString() 87 | } 88 | } 89 | } 90 | 91 | publishing.publications { 92 | create("maven") { 93 | val githubUrl = "https://github.com/ice1000/jimgui" 94 | from(components["java"]) 95 | groupId = "${project.group}" 96 | artifactId = "${project.name}" 97 | version = "${project.version}" 98 | pom { 99 | description.set("Pure Java binding for dear-imgui") 100 | name.set(project.name) 101 | url.set(githubUrl) 102 | licenses { 103 | license { 104 | name.set("The Apache License, Version 2.0") 105 | url.set("https://www.apache.org/licenses/LICENSE-2.0.txt") 106 | } 107 | } 108 | developers { 109 | developer { 110 | id.set("ice1000") 111 | name.set("Tesla Ice Zhang") 112 | email.set("ice1000kotlin@foxmail.com") 113 | } 114 | } 115 | scm { 116 | connection.set("scm:git:$githubUrl") 117 | url.set(githubUrl) 118 | } 119 | } 120 | } 121 | } 122 | 123 | signing { 124 | sign(publishing.publications["maven"]) 125 | } 126 | } 127 | -------------------------------------------------------------------------------- /buildSrc/build.gradle.kts: -------------------------------------------------------------------------------- 1 | group = "org.ice1000.gradle" 2 | version = "114514" 3 | 4 | plugins { kotlin("jvm") version "1.6.21" } 5 | 6 | kotlin.sourceSets["main"].kotlin.srcDir("src") 7 | sourceSets.main { 8 | java.srcDir("src") 9 | } 10 | 11 | repositories { mavenCentral() } 12 | dependencies { implementation(kotlin("stdlib-jdk8")) } 13 | -------------------------------------------------------------------------------- /buildSrc/src/GenFDTask.kt: -------------------------------------------------------------------------------- 1 | package org.ice1000.gradle 2 | 3 | import org.intellij.lang.annotations.Language 4 | 5 | open class GenFDTask : GenTask("JImFileDialogGen", "imgui_file_dialog", since = "v0.13") { 6 | override val `c++Expr` = "PTR_J2C(IGFD::FileDialog, nativeObjectPtr)->" 7 | override val `prefixC++`: String 8 | get() = "#include \n${super.`prefixC++`}" 9 | 10 | @Language("JAVA") 11 | override val userCode = """ /** package-private by design */ 12 | $className(long nativeObjectPtr) { 13 | this.nativeObjectPtr = nativeObjectPtr; 14 | } 15 | 16 | protected long nativeObjectPtr; 17 | """ 18 | 19 | override fun `c++`(cppCode: StringBuilder) { 20 | functions.forEach { (name, type, params) -> `genC++Fun`(params.dropLast(1), name, type, cppCode, "jlong nativeObjectPtr") } 21 | } 22 | 23 | override fun java(javaCode: StringBuilder) { 24 | functions.forEach { genJavaFun(javaCode, it) } 25 | } 26 | 27 | private val filters = string("filters") 28 | private val key = string("key") 29 | private val functions = listOf( 30 | Fun("display", "boolean", key, 31 | windowFlags, size("Min", default = "0, 0"), size("Max", default = "FLT_MAX, FLT_MAX"), 32 | nativeObjectPtr), 33 | Fun("openDialog", key, string("title"), 34 | filters, string("basePath"), 35 | int("maxSelection", default = 1), nativeObjectPtr), 36 | Fun("openModal", key, string("title"), 37 | filters, string("basePath"), 38 | int("maxSelection", default = 1), nativeObjectPtr), 39 | Fun("close", nativeObjectPtr), 40 | Fun("isOk", "boolean", nativeObjectPtr), 41 | Fun("wasOpenedThisFrame", "boolean", key, nativeObjectPtr), 42 | Fun("isOpened", "boolean", string("text"), nativeObjectPtr), 43 | Fun("setFileStyle", flags(from = "FDStyle"), string("criteria"), vec4("color"), string("icon"), nativeObjectPtr), 44 | Fun("getFileStyle", flags(from = "FDStyle"), 45 | string("criteria"), vec4Ptr("color"), stringPtr("icon"), 46 | nativeObjectPtr), 47 | Fun("clearFilesStyle", nativeObjectPtr), 48 | ) 49 | } 50 | -------------------------------------------------------------------------------- /buildSrc/src/GenFontAtlasTask.kt: -------------------------------------------------------------------------------- 1 | @file:Suppress("unused") 2 | 3 | package org.ice1000.gradle 4 | 5 | import org.intellij.lang.annotations.Language 6 | 7 | /** 8 | * @author ice1000 9 | */ 10 | open class GenFontAtlasTask : GenTask("JImGuiFontAtlasGen", "imgui_font_atlas") { 11 | init { 12 | description = "Generate binding for ImGui::GetFont()->ContainerAtlas" 13 | } 14 | 15 | @Language("JAVA", prefix = "class A{", suffix = "}") 16 | override val userCode = """protected long nativeObjectPtr; 17 | 18 | /** package-private by design */ 19 | $className(long nativeObjectPtr) { 20 | this.nativeObjectPtr = nativeObjectPtr; 21 | } 22 | """ 23 | 24 | override fun java(javaCode: StringBuilder) { 25 | imVec2Members.forEach { genJavaObjectiveXYAccessor(javaCode, it, "float") } 26 | primitiveMembers.forEach { (type, name, annotation) -> 27 | genSimpleJavaObjectivePrimitiveMembers(javaCode, name, type, annotation) 28 | } 29 | functions.forEach { genJavaFun(javaCode, it) } 30 | } 31 | 32 | override fun `c++`(cppCode: StringBuilder) { 33 | imVec2Members.joinLinesTo(cppCode) { `c++XYAccessor`(it, "float", "jlong nativeObjectPtr") } 34 | primitiveMembers.joinLinesTo(cppCode) { (type, name) -> `c++PrimitiveAccessor`(type, name, "jlong nativeObjectPtr") } 35 | functions.forEach { (name, type, params) -> `genC++Fun`(params.dropLast(1), name, type, cppCode, "jlong nativeObjectPtr") } 36 | } 37 | 38 | override val `c++Expr` = "PTR_J2C(ImFontAtlas, nativeObjectPtr)->" 39 | private val imVec2Members = listOf("TexUvScale", "TexUvWhitePixel") 40 | private val functions = listOf( 41 | Fun.protected("addFont", "long", configPtr("fontConfig"), nativeObjectPtr), 42 | Fun.protected("addFontDefault", "long", configPtr("fontConfig", nullable = true), nativeObjectPtr), 43 | Fun.protected("addFontFromMemoryCompressedBase85TTF", "long", 44 | string("compressedFontDataBase85"), float("sizePixels"), nativeObjectPtr), 45 | Fun.private("build", "boolean", nativeObjectPtr), 46 | Fun.private("isBuilt", "boolean", nativeObjectPtr), 47 | Fun.private("clearInputData", nativeObjectPtr), 48 | Fun.private("clearTexData", nativeObjectPtr), 49 | Fun.private("clearFonts", nativeObjectPtr), 50 | Fun.private("clear", nativeObjectPtr), 51 | Fun.private("setTexID", texture("id"), nativeObjectPtr), 52 | Fun.protected("getGlyphRangesDefault", "long", nativeObjectPtr), 53 | Fun.protected("getGlyphRangesKorean", "long", nativeObjectPtr), 54 | Fun.protected("getGlyphRangesJapanese", "long", nativeObjectPtr), 55 | Fun.protected("getGlyphRangesChineseFull", "long", nativeObjectPtr), 56 | Fun.protected("getGlyphRangesChineseSimplifiedCommon", "long", nativeObjectPtr), 57 | Fun.protected("getGlyphRangesCyrillic", "long", nativeObjectPtr), 58 | Fun.protected("getGlyphRangesVietnamese", "long", nativeObjectPtr), 59 | Fun.protected("getGlyphRangesThai", "long", nativeObjectPtr), 60 | Fun.private("addCustomRectRegular", int("width"), int("height"), nativeObjectPtr), 61 | Fun.protected("addCustomRectFontGlyph", 62 | font(), p("id", "short"), int("width"), int("height"), 63 | float("advanceX"), pos("offset", default = "0,0"), nativeObjectPtr)) 64 | 65 | private val primitiveMembers = listOf( 66 | PPT("int", "Flags", annotation = "@MagicConstant(flagsFromClass = JImFontAtlasFlags.class)"), 67 | PPT("int", "TexWidth"), 68 | PPT("int", "TexHeight"), 69 | PPT("int", "TexDesiredWidth"), 70 | PPT("int", "TexGlyphPadding") 71 | ) 72 | } 73 | -------------------------------------------------------------------------------- /buildSrc/src/GenFontConfigTask.kt: -------------------------------------------------------------------------------- 1 | @file:Suppress("unused") 2 | 3 | package org.ice1000.gradle 4 | 5 | import org.intellij.lang.annotations.Language 6 | 7 | /** 8 | * @author ice1000 9 | */ 10 | open class GenFontConfigTask : GenTask("JImGuiFontConfigGen", "imgui_font_config", since = "v0.4") { 11 | init { 12 | description = "Generate binding for ImGui::GetFont()->ConfigData" 13 | } 14 | 15 | @Language("JAVA", prefix = "class A{", suffix = "}") 16 | override val userCode = """protected long nativeObjectPtr; 17 | 18 | /** package-private by design */ 19 | $className(long nativeObjectPtr) { 20 | this.nativeObjectPtr = nativeObjectPtr; 21 | } 22 | """ 23 | 24 | override fun java(javaCode: StringBuilder) { 25 | imVec2Members.forEach { genJavaObjectiveXYAccessor(javaCode, it, "float") } 26 | primitiveMembers.forEach { (type, name) -> genSimpleJavaObjectivePrimitiveMembers(javaCode, name, type) } 27 | booleanMembers.forEach { genSimpleJavaObjectiveBooleanMember(javaCode, it) } 28 | } 29 | 30 | override fun `c++`(cppCode: StringBuilder) { 31 | imVec2Members.joinLinesTo(cppCode) { `c++XYAccessor`(it, "float", "jlong nativeObjectPtr") } 32 | primitiveMembers.joinLinesTo(cppCode) { (type, name) -> `c++PrimitiveAccessor`(type, name, "jlong nativeObjectPtr") } 33 | booleanMembers.joinLinesTo(cppCode) { `c++BooleanAccessor`(it, "jlong nativeObjectPtr") } 34 | } 35 | 36 | override val `c++Expr` = "PTR_J2C(ImFontConfig, nativeObjectPtr)->" 37 | private val booleanMembers = listOf("FontDataOwnedByAtlas", "PixelSnapH", "MergeMode") 38 | private val imVec2Members = listOf("GlyphExtraSpacing", "GlyphOffset") 39 | private val primitiveMembers = listOf( 40 | "int" to "FontDataSize", 41 | "int" to "FontNo", 42 | "int" to "OversampleH", 43 | "int" to "OversampleV", 44 | "int" to "FontBuilderFlags", 45 | "float" to "SizePixels", 46 | "float" to "RasterizerMultiply", 47 | "float" to "GlyphMinAdvanceX", 48 | "float" to "GlyphMaxAdvanceX" 49 | ) 50 | } 51 | -------------------------------------------------------------------------------- /buildSrc/src/GenFontTask.kt: -------------------------------------------------------------------------------- 1 | @file:Suppress("unused") 2 | 3 | package org.ice1000.gradle 4 | 5 | import org.intellij.lang.annotations.Language 6 | 7 | /** 8 | * @author ice1000 9 | */ 10 | open class GenFontTask : GenTask("JImGuiFontGen", "imgui_font") { 11 | init { 12 | description = "Generate binding for ImGui::GetFont" 13 | } 14 | 15 | @Language("JAVA", prefix = "class A{", suffix = "}") 16 | override val userCode = """ @Contract(pure = true) 17 | public static @NotNull JImFont getInstance(@NotNull JImGui owner) { 18 | return owner.getFont(); 19 | } 20 | 21 | /** package-private by design */ 22 | protected long nativeObjectPtr; 23 | 24 | /** package-private by design */ 25 | $className(long nativeObjectPtr) { 26 | this.nativeObjectPtr = nativeObjectPtr; 27 | } 28 | """ 29 | 30 | override fun java(javaCode: StringBuilder) { 31 | GenGenTask.checkParserInitialized(project) 32 | // imVec2Members.forEach { genJavaObjectiveXYAccessor(javaCode, it, "float") } 33 | primitiveMembers.forEach { (type, name) -> genSimpleJavaObjectivePrimitiveMembers(javaCode, name, type) } 34 | booleanMembers.forEach { genSimpleJavaObjectiveBooleanMember(javaCode, it) } 35 | functions.forEach { genJavaFun(javaCode, it) } 36 | } 37 | 38 | override fun `c++`(cppCode: StringBuilder) { 39 | // imVec2Members.joinLinesTo(cppCode) { `c++XYAccessor`(it, "float", "jlong nativeObjectPtr") } 40 | booleanMembers.joinLinesTo(cppCode) { `c++BooleanAccessor`(it, "jlong nativeObjectPtr") } 41 | primitiveMembers.joinLinesTo(cppCode) { (type, name) -> `c++PrimitiveAccessor`(type, name, "jlong nativeObjectPtr") } 42 | functions.forEach { (name, type, params) -> `genC++Fun`(params.dropLast(1), name, type, cppCode, "jlong nativeObjectPtr") } 43 | } 44 | 45 | override val `c++Expr` = "PTR_J2C(ImFont, nativeObjectPtr)->" 46 | private val booleanMembers = listOf("DirtyLookupTables") 47 | 48 | // private val imVec2Members = listOf("DisplayOffset") 49 | private val functions = listOf( 50 | Fun.private("clearOutputData", nativeObjectPtr), 51 | Fun.private("isLoaded", "boolean", nativeObjectPtr), 52 | Fun.private("getDebugName", "long", nativeObjectPtr), 53 | Fun.private("growIndex", int("newSize"), nativeObjectPtr), 54 | Fun.private("addRemapChar", int("dst"), int("src"), bool("overwriteDst", default = true), nativeObjectPtr), 55 | // TODO: add this back 56 | // Fun.private("addGlyph", p("wChar", "int"), float("x0"), float("y0"), float("x1"), float("y1"), 57 | // float("u0"), float("v0"), float("u1"), float("v1"), float("advanceX"), nativeObjectPtr), 58 | Fun.private("buildLookupTable", nativeObjectPtr), 59 | Fun.private("renderChar", drawListPtr("drawList"), float("size"), pos(), u32, p("c", "short"), nativeObjectPtr)) 60 | 61 | private val primitiveMembers = listOf( 62 | "float" to "FontSize", 63 | "float" to "Scale", 64 | "float" to "FallbackAdvanceX", 65 | // "int" to "FallbackChar", 66 | "short" to "ConfigDataCount", 67 | "float" to "Ascent", 68 | "float" to "Descent", 69 | "int" to "MetricsTotalSurface", 70 | ) 71 | } 72 | -------------------------------------------------------------------------------- /buildSrc/src/GenJavaTask.kt: -------------------------------------------------------------------------------- 1 | package org.ice1000.gradle 2 | 3 | import org.gradle.api.DefaultTask 4 | import org.gradle.api.tasks.Input 5 | import org.gradle.api.tasks.Internal 6 | import org.gradle.api.tasks.OutputFile 7 | import org.intellij.lang.annotations.Language 8 | 9 | open class GenJavaTask( 10 | @Input val className: String, 11 | @Input val since: String = "v0.1", 12 | @Input private val packageName: String = "org.ice1000.jimgui", 13 | relativePath: String = packageName.replace('.', '/'), 14 | ) : DefaultTask() { 15 | @OutputFile val targetJavaFile = project 16 | .projectDir 17 | .resolve("gen") 18 | .resolve(relativePath) 19 | .resolve("$className.java") 20 | .absoluteFile 21 | 22 | init { 23 | group = "code generation" 24 | targetJavaFile.parentFile.mkdirs() 25 | } 26 | 27 | @Language("Text") @Internal 28 | open val userCode = """/** package-private by design */ 29 | $className() { } 30 | """ 31 | 32 | @get:Internal protected val prefixJava 33 | @Language("JAVA", suffix = "}") 34 | get() = """package $packageName; 35 | 36 | import org.ice1000.jimgui.*; 37 | import org.ice1000.jimgui.flag.*; 38 | import org.ice1000.jimgui.cpp.*; 39 | import org.intellij.lang.annotations.*; 40 | import org.jetbrains.annotations.*; 41 | import java.nio.charset.StandardCharsets; 42 | 43 | import static org.ice1000.jimgui.util.JImGuiUtil.*; 44 | 45 | /** 46 | * @author ice1000 47 | * @since $since 48 | */ 49 | @SuppressWarnings("ALL") 50 | 51 | public class $className { 52 | $userCode 53 | """ 54 | 55 | @get:Internal protected val prefixInterfacedJava 56 | @Language("JAVA", suffix = "}") 57 | get() = """package $packageName; 58 | 59 | import org.ice1000.jimgui.*; 60 | import org.ice1000.jimgui.flag.*; 61 | import org.ice1000.jimgui.cpp.*; 62 | import org.intellij.lang.annotations.*; 63 | import org.jetbrains.annotations.*; 64 | import java.nio.charset.StandardCharsets; 65 | 66 | import static org.ice1000.jimgui.util.JImGuiUtil.*; 67 | 68 | /** 69 | * @author ice1000 70 | * @since $since 71 | */ 72 | @SuppressWarnings("ALL") 73 | 74 | public interface $className { 75 | """ 76 | 77 | @Internal val eol: String = System.lineSeparator() 78 | } 79 | -------------------------------------------------------------------------------- /buildSrc/src/GenNativeTypesTask.kt: -------------------------------------------------------------------------------- 1 | package org.ice1000.gradle 2 | 3 | import org.gradle.api.tasks.OutputFiles 4 | import org.gradle.api.tasks.TaskAction 5 | 6 | open class GenNativeTypesTask : GenJavaTask(""), Runnable { 7 | private val types = listOf( 8 | "Int" to "int", 9 | "Float" to "float", 10 | "Double" to "double", 11 | "Short" to "short", 12 | // "Byte" to "byte", 13 | // "Char" to "char", 14 | "Long" to "long" 15 | ) 16 | 17 | @OutputFiles 18 | val outputFiles = types.map { (it, _) -> targetJavaFile.parentFile.resolve("Native$it.java")} 19 | 20 | @TaskAction 21 | override fun run() { 22 | val cppPackage = targetJavaFile.parentFile 23 | cppPackage.mkdirs() 24 | types.forEach { (it, java) -> 25 | cppPackage 26 | .resolve("Native$it.java") 27 | .apply { if (!exists()) createNewFile() } 28 | //language=JAVA 29 | .writeText(""" 30 | package org.ice1000.jimgui; 31 | import org.ice1000.jimgui.cpp.*; 32 | import org.jetbrains.annotations.*; 33 | 34 | /** 35 | * @author ice1000 36 | * @since v0.1 37 | */ 38 | @SuppressWarnings("ALL") 39 | public final class Native$it extends Number implements DeallocatableObject, Cloneable { 40 | /** package-private by design */ 41 | long nativeObjectPtr; 42 | @Contract public Native$it() { nativeObjectPtr = allocateNativeObject(); } 43 | @Contract(pure = true) public Native$it(long nativeObjectPtr) { this.nativeObjectPtr = nativeObjectPtr; } 44 | 45 | @Override @Contract 46 | public void deallocateNativeObject() { deallocateNativeObject0(nativeObjectPtr); nativeObjectPtr = 0; } 47 | @Contract(pure = true) public $java accessValue() { return accessValue(nativeObjectPtr); } 48 | @Contract public void increaseValue($java increment) { increaseValue(nativeObjectPtr, increment); } 49 | @Contract public void modifyValue($java newValue) { modifyValue(nativeObjectPtr, newValue); } 50 | 51 | @Override @Contract(pure = true) public int intValue() { return (int) accessValue(); } 52 | @Override @Contract(pure = true) public long longValue() { return (long) accessValue(); } 53 | @Override @Contract(pure = true) public float floatValue() { return (float) accessValue(); } 54 | @Override @Contract(pure = true) public double doubleValue() { return (double) accessValue(); } 55 | 56 | private static native $java accessValue(long nativeObjectPtr); 57 | private static native void modifyValue(long nativeObjectPtr, $java newValue); 58 | private static native void increaseValue(long nativeObjectPtr, $java increment); 59 | private static native long allocateNativeObject(); 60 | private static native void deallocateNativeObject0(long nativeObjectPtr); 61 | 62 | @Override @Contract(value = "null -> false", pure = true) 63 | public boolean equals(@Nullable Object o) { 64 | return this == o || o instanceof Native$it && nativeObjectPtr == ((Native$it) o).nativeObjectPtr; 65 | } 66 | @Override @Contract(pure = true) 67 | public int hashCode() { return Long.hashCode(nativeObjectPtr); } 68 | @Override public @NotNull String toString() { return String.valueOf(accessValue()); } 69 | @Override @Contract public @NotNull Native$it clone() { 70 | Native$it newInstance = new Native$it(); 71 | newInstance.modifyValue(accessValue()); 72 | return newInstance; 73 | } 74 | } 75 | """) 76 | } 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /buildSrc/src/GenStyleTask.kt: -------------------------------------------------------------------------------- 1 | @file:Suppress("unused") 2 | 3 | package org.ice1000.gradle 4 | 5 | import org.intellij.lang.annotations.Language 6 | 7 | /** 8 | * @author ice1000 9 | */ 10 | open class GenStyleTask : GenTask("JImGuiStyleGen", "imgui_style") { 11 | init { 12 | description = "Generate binding for ImGui::GetStyle" 13 | } 14 | 15 | @Language("JAVA") 16 | override val userCode = """ @Contract(pure = true) 17 | public static @NotNull $className getInstance(@NotNull JImGui owner) { return owner.getStyle(); } 18 | 19 | /** package-private by design */ 20 | $className(long nativeObjectPtr) { 21 | this.nativeObjectPtr = nativeObjectPtr; 22 | } 23 | 24 | protected long nativeObjectPtr; 25 | """ 26 | 27 | override fun java(javaCode: StringBuilder) { 28 | GenGenTask.checkParserInitialized(project) 29 | imVec2Members.forEach { genJavaObjectiveXYAccessor(javaCode, it, "float") } 30 | primitiveMembers.forEach { (type, name) -> genSimpleJavaObjectivePrimitiveMembers(javaCode, name, type) } 31 | booleanMembers.forEach { genSimpleJavaObjectiveBooleanMember(javaCode, it) } 32 | functions.forEach { genJavaFun(javaCode, it) } 33 | } 34 | 35 | override fun `c++`(cppCode: StringBuilder) { 36 | imVec2Members.joinLinesTo(cppCode) { `c++XYAccessor`(it, "float", "jlong nativeObjectPtr") } 37 | booleanMembers.joinLinesTo(cppCode) { `c++BooleanAccessor`(it, "jlong nativeObjectPtr") } 38 | primitiveMembers.joinLinesTo(cppCode) { (type, name) -> `c++PrimitiveAccessor`(type, name, "jlong nativeObjectPtr") } 39 | functions.forEach { (name, type, params) -> `genC++Fun`(params.dropLast(1), name, type, cppCode, "jlong nativeObjectPtr") } 40 | } 41 | 42 | override val `c++Expr` = "PTR_J2C(ImGuiStyle, nativeObjectPtr)->" 43 | private val booleanMembers = listOf("AntiAliasedLines", "AntiAliasedFill") 44 | private val functions = listOf(Fun("scaleAllSizes", float("scaleFactor"), nativeObjectPtr)) 45 | private val primitiveMembers = listOf( 46 | "int" to "WindowMenuButtonPosition", 47 | "int" to "ColorButtonPosition", 48 | "float" to "Alpha", 49 | "float" to "WindowRounding", 50 | "float" to "WindowBorderSize", 51 | "float" to "ChildRounding", 52 | "float" to "ChildBorderSize", 53 | "float" to "PopupRounding", 54 | "float" to "PopupBorderSize", 55 | "float" to "FrameRounding", 56 | "float" to "FrameBorderSize", 57 | "float" to "IndentSpacing", 58 | "float" to "ColumnsMinSpacing", 59 | "float" to "ScrollbarSize", 60 | "float" to "ScrollbarRounding", 61 | "float" to "GrabMinSize", 62 | "float" to "GrabRounding", 63 | "float" to "LogSliderDeadzone", 64 | "float" to "TabRounding", 65 | "float" to "TabBorderSize", 66 | "float" to "TabMinWidthForCloseButton", 67 | "float" to "MouseCursorScale", 68 | "float" to "CurveTessellationTol", 69 | "float" to "CircleTessellationMaxError", 70 | ) 71 | 72 | private val imVec2Members = listOf( 73 | "WindowPadding", 74 | "WindowMinSize", 75 | "WindowTitleAlign", 76 | "FramePadding", 77 | "ItemSpacing", 78 | "CellPadding", 79 | "ItemInnerSpacing", 80 | "TouchExtraPadding", 81 | "ButtonTextAlign", 82 | "SelectableTextAlign", 83 | "DisplayWindowPadding", 84 | "DisplaySafeAreaPadding", 85 | ) 86 | } 87 | -------------------------------------------------------------------------------- /buildSrc/src/ImGuiHeaderParser.kt: -------------------------------------------------------------------------------- 1 | package org.ice1000.gradle 2 | 3 | import java.io.File 4 | 5 | /** 6 | * @author ice1000 7 | */ 8 | class ImGuiHeaderParser { 9 | val map: MutableMap = hashMapOf() 10 | 11 | fun parseHeader(imguiHeader: File) { 12 | if (!imguiHeader.exists()) return 13 | imguiHeader.bufferedReader().use { reader -> 14 | reader.lineSequence() 15 | .dropWhile { it != "#pragma once" } 16 | .map { it.trimStart() } 17 | .map { it.removePrefix("IMGUI_API ") } 18 | .filter { it.indexOf(';') > 0 || it.indexOf('=') > 0 } 19 | .filter { it.indexOf("//") > 0 } 20 | .mapNotNull { 21 | val docStartIndex = it.indexOf("//") 22 | val parenthesesStartIndex = it.indexOf('(') 23 | val bracketsStartIndex = it.indexOf('[') 24 | val assignStartIndex = it.indexOf('=') 25 | val name = when { 26 | bracketsStartIndex in 0..docStartIndex -> it.substring(0, bracketsStartIndex) 27 | parenthesesStartIndex in 0..docStartIndex -> it.substring(0, parenthesesStartIndex) 28 | assignStartIndex > 0 -> { 29 | if (assignStartIndex in 0..docStartIndex) it.substring(0, assignStartIndex) 30 | else return@mapNotNull null 31 | } 32 | else -> it.substring(0, it.indexOf(';')) 33 | }.trimEnd() 34 | val javadoc = it.substring(docStartIndex).trim(' ', '/', '\n', '\r', '\t') 35 | .replace('/', '|') 36 | if (' ' in name) 37 | name.substring(name.lastIndexOf(' ')).trimStart() to javadoc 38 | else 39 | name.decapitalize() to javadoc 40 | } 41 | .filter { (name, _) -> name.isNotEmpty() } 42 | .filter { (name, _) -> !name[0].isDigit() } 43 | .forEach { (name, javadoc) -> 44 | val original = map[name] 45 | if (original != null) map[name] = "$original\n $javadoc" 46 | else map[name] = javadoc 47 | } 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /buildSrc/src/enum-generators.kt: -------------------------------------------------------------------------------- 1 | package org.ice1000.gradle 2 | 3 | import org.gradle.api.tasks.Input 4 | import org.gradle.api.tasks.TaskAction 5 | 6 | abstract class GenEnumTask(className: String) : GenJavaTask(className), Runnable { 7 | @get:Input abstract val list: List 8 | 9 | @TaskAction 10 | override fun run() = buildString { 11 | append(prefixInterfacedJava) 12 | list.forEachIndexed { index, element -> 13 | append(" ") 14 | genStatement(index, element) 15 | appendLine(";") 16 | } 17 | appendLine('}') 18 | }.let { targetJavaFile.writeText(it) } 19 | 20 | open fun StringBuilder.genStatement(index: Int, element: T) { 21 | append("int ") 22 | append(element) 23 | append(" = ") 24 | append(index) 25 | } 26 | } 27 | 28 | open class GenStyleVarsTask : GenEnumTask>("JImStyleVars") { 29 | override val list = listOf( 30 | "Alpha" to "Float", 31 | "WindowPadding" to "Void", 32 | "WindowRounding" to "Float", 33 | "WindowBorderSize" to "Float", 34 | "WindowMinSize" to "Void", 35 | "WindowTitleAlign" to "Void", 36 | "ChildRounding" to "Float", 37 | "ChildBorderSize" to "Float", 38 | "PopupRounding" to "Float", 39 | "PopupBorderSize" to "Float", 40 | "FramePadding" to "Void", 41 | "FrameRounding" to "Float", 42 | "FrameBorderSize" to "Float", 43 | "ItemSpacing" to "Void", 44 | "ItemInnerSpacing" to "Void", 45 | "IndentSpacing" to "Float", 46 | "ScrollbarSize" to "Float", 47 | "ScrollbarRounding" to "Float", 48 | "GrabMinSize" to "Float", 49 | "GrabRounding" to "Float", 50 | "TabRounding" to "Float", 51 | "ButtonTextAlign" to "Void", 52 | "SelectableTextAlign" to "Void", 53 | ) 54 | 55 | override fun StringBuilder.genStatement(index: Int, element: Pair) { 56 | val (name, typeArg) = element 57 | append("@NotNull JImStyleVar<@NotNull ") 58 | append(typeArg) 59 | append("> ") 60 | append(name) 61 | append(" = new JImStyleVar<>(") 62 | append(index) 63 | append(')') 64 | } 65 | } 66 | 67 | open class GenStyleColorsTask : GenEnumTask("JImStyleColors") { 68 | override val list = listOf( 69 | "Text", 70 | "TextDisabled", 71 | "WindowBg", 72 | "ChildBg", 73 | "PopupBg", 74 | "Border", 75 | "BorderShadow", 76 | "FrameBg", 77 | "FrameBgHovered", 78 | "FrameBgActive", 79 | "TitleBg", 80 | "TitleBgActive", 81 | "TitleBgCollapsed", 82 | "MenuBarBg", 83 | "ScrollbarBg", 84 | "ScrollbarGrab", 85 | "ScrollbarGrabHovered", 86 | "ScrollbarGrabActive", 87 | "CheckMark", 88 | "SliderGrab", 89 | "SliderGrabActive", 90 | "Button", 91 | "ButtonHovered", 92 | "ButtonActive", 93 | "Header", 94 | "HeaderHovered", 95 | "HeaderActive", 96 | "Separator", 97 | "SeparatorHovered", 98 | "SeparatorActive", 99 | "ResizeGrip", 100 | "ResizeGripHovered", 101 | "ResizeGripActive", 102 | "Tab", 103 | "TabHovered", 104 | "TabActive", 105 | "TabUnfocused", 106 | "TabUnfocusedActive", 107 | "PlotLines", 108 | "PlotLinesHovered", 109 | "PlotHistogram", 110 | "PlotHistogramHovered", 111 | "TableHeaderBg", 112 | "TableBorderStrong", 113 | "TableBorderLight", 114 | "TableRowBg", 115 | "TableRowBgAlt", 116 | "TextSelectedBg", 117 | "DragDropTarget", 118 | "NavHighlight", 119 | "NavWindowingHighlight", 120 | "NavWindowingDimBg", 121 | "ModalWindowDimBg", 122 | ) 123 | } 124 | 125 | open class GenDefaultKeysTask : GenEnumTask("JImDefaultKeys") { 126 | override val list = listOf( 127 | "Tab", 128 | "LeftArrow", 129 | "RightArrow", 130 | "UpArrow", 131 | "DownArrow", 132 | "PageUp", 133 | "PageDown", 134 | "Home", 135 | "End", 136 | "Insert", 137 | "Delete", 138 | "Backspace", 139 | "Space", 140 | "Enter", 141 | "Escape", 142 | "KeyPadEnter", 143 | "LeftShift", 144 | "RightShift", 145 | "LeftCtrl", 146 | "RightCtrl", 147 | "Ctrl", 148 | "LeftAlt", 149 | "RightAlt", 150 | "_0", 151 | "_1", 152 | "_2", 153 | "_3", 154 | "_4", 155 | "_5", 156 | "_6", 157 | "_7", 158 | "_8", 159 | "_9", 160 | "A", 161 | "B", 162 | "C", 163 | "D", 164 | "E", 165 | "F", 166 | "G", 167 | "Q", 168 | "R", 169 | "S", 170 | "V", 171 | "W", 172 | "X", 173 | "Y", 174 | "Z", 175 | ) 176 | } 177 | -------------------------------------------------------------------------------- /buildSrc/src/naitve-build.kt: -------------------------------------------------------------------------------- 1 | package org.ice1000.gradle 2 | 3 | import org.apache.tools.ant.taskdefs.condition.Os 4 | import org.gradle.api.tasks.Exec 5 | import org.gradle.api.tasks.Input 6 | import org.gradle.api.tasks.Internal 7 | import java.io.File 8 | 9 | private val nativeLibraryExtensions = listOf("so", "dll", "dylib") 10 | val isWindows = Os.isFamily(Os.FAMILY_WINDOWS) 11 | val isMac = Os.isFamily(Os.FAMILY_MAC) 12 | const val Makefiles = "Unix Makefiles" 13 | const val VS2019 = "Visual Studio 16 2019" 14 | 15 | abstract class NativeBuildTask : Exec() { 16 | @Internal lateinit var jniDir: File 17 | @Internal lateinit var resDir: File 18 | 19 | init { 20 | group = "native compile" 21 | } 22 | } 23 | 24 | open class CMake : NativeBuildTask() { 25 | @Input var cmakePath = "cmake" 26 | 27 | fun simple(workingDir: File, arch: String) { 28 | if (isWindows) cmake(workingDir, VS2019, "-A", arch) 29 | else cmake(workingDir, Makefiles) 30 | } 31 | 32 | fun cmake(workingDir: File, generator: String, vararg additional: String) { 33 | workingDir(workingDir) 34 | outputs.dir(workingDir) 35 | inputs.dir(jniDir.resolve("imgui")) 36 | inputs.dir(jniDir.resolve("impl")) 37 | inputs.file(jniDir.resolve("CMakeLists.txt")) 38 | commandLine(cmakePath, "-DCMAKE_BUILD_TYPE=Release", "-G", generator, *additional, workingDir.parent) 39 | doFirst { workingDir.mkdirs() } 40 | } 41 | } 42 | 43 | open class CxxCompile : NativeBuildTask() { 44 | // @Finalize 45 | fun findNativeLibs() = workingDir.walk() 46 | .filter { it.extension in nativeLibraryExtensions } 47 | .forEach { 48 | println("Found native library $it") 49 | it.copyTo(resDir.resolve("native").resolve(it.name), overwrite = true) 50 | } 51 | 52 | fun cxx(workingDir: File, vararg commandLine: String) { 53 | workingDir(workingDir) 54 | commandLine(*commandLine) 55 | outputs.dir(workingDir) 56 | inputs.files(jniDir.listFiles().orEmpty().filter { it.name.endsWith("cpp") }) 57 | inputs.dir(jniDir.resolve("imgui")) 58 | inputs.dir(jniDir.resolve("impl")) 59 | doLast { findNativeLibs() } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /buildSrc/src/sort-specs.kt: -------------------------------------------------------------------------------- 1 | package org.ice1000.gradle 2 | 3 | import org.intellij.lang.annotations.Language 4 | 5 | open class GenTableSortSpecsTask : GenTask("JImTableSortSpecsGen", "imgui_table_sort_specs_gen", since = "v0.18") { 6 | override val `c++Expr` = "PTR_J2C(ImGuiTableSortSpecs, nativeObjectPtr)->" 7 | 8 | @Language("JAVA") 9 | override val userCode = """ /** package-private by design */ 10 | $className(long nativeObjectPtr) { 11 | this.nativeObjectPtr = nativeObjectPtr; 12 | } 13 | 14 | protected long nativeObjectPtr; 15 | """ 16 | 17 | override fun `c++`(cppCode: StringBuilder) { 18 | cppCode.appendLine(`c++PrimitiveAccessor`("int", "SpecsCount", "jlong nativeObjectPtr")) 19 | .append(`c++BooleanAccessor`("SpecsDirty", "jlong nativeObjectPtr")) 20 | } 21 | 22 | override fun java(javaCode: StringBuilder) { 23 | genSimpleJavaObjectivePrimitiveMembers(javaCode, "SpecsCount", "int") 24 | genSimpleJavaObjectiveBooleanMember(javaCode, "SpecsDirty") 25 | } 26 | } 27 | 28 | open class GenColumnSortSpecsTask : GenTask("JImColumnSortSpecsGen", "imgui_column_sort_specs_gen", since = "v0.18") { 29 | override val `c++Expr` = "PTR_J2C(ImGuiTableColumnSortSpecs, nativeObjectPtr)->" 30 | @Language("JAVA") 31 | override val userCode = """ /** package-private by design */ 32 | $className(long nativeObjectPtr) { 33 | this.nativeObjectPtr = nativeObjectPtr; 34 | } 35 | 36 | protected long nativeObjectPtr; 37 | """ 38 | 39 | override fun `c++`(cppCode: StringBuilder) { 40 | primitiveMembers.joinLinesTo(cppCode) { (type, name) -> `c++PrimitiveAccessor`(type, name, "jlong nativeObjectPtr") } 41 | } 42 | 43 | override fun java(javaCode: StringBuilder) { 44 | primitiveMembers.forEach { (type, name) -> genSimpleJavaObjectivePrimitiveMembers(javaCode, name, type) } 45 | } 46 | 47 | private val primitiveMembers = listOf( 48 | "int" to "ColumnUserID", 49 | "int" to "SortDirection", 50 | "short" to "ColumnIndex", 51 | "short" to "SortOrder", 52 | ) 53 | } 54 | -------------------------------------------------------------------------------- /core/jni/.gitignore: -------------------------------------------------------------------------------- 1 | imgui 2 | javah 3 | impl 4 | .idea 5 | 3rdparty 6 | cmake-build-debug/ 7 | cmake-build-release/ 8 | generated*.cpp 9 | cmake-build-debug-visual-studio 10 | #basics.hpp 11 | -------------------------------------------------------------------------------- /core/jni/config/fd_customization.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by ice1000 on 2020/12/16. 3 | // 4 | 5 | #ifndef JIMGUI_FD_CUSTOMIZATION_H 6 | #define JIMGUI_FD_CUSTOMIZATION_H 7 | 8 | // Fixing a typo 9 | #define SetExtentionInfos SetExtensionInfo 10 | #define GetExtentionInfos GetExtensionInfo 11 | #define ClearExtentionInfos ClearExtensionInfo 12 | 13 | // https://github.com/aiekick/ImGuiFileDialog/blob/master/ImGuiFileDialog/ImGuiFileDialogConfig.h 14 | 15 | // uncomment and modify defines under for customize ImGuiFileDialog 16 | 17 | //#define MAX_FILE_DIALOG_NAME_BUFFER 1024 18 | //#define MAX_PATH_BUFFER_SIZE 1024 19 | 20 | #define USE_IMGUI_TABLES 21 | 22 | //#define USE_EXPLORATION_BY_KEYS 23 | // this mapping by default is for GLFW but you can use another 24 | //#include 25 | // Up key for explore to the top 26 | //#define IGFD_KEY_UP GLFW_KEY_UP 27 | // Down key for explore to the bottom 28 | //#define IGFD_KEY_DOWN GLFW_KEY_DOWN 29 | // Enter key for open directory 30 | //#define IGFD_KEY_ENTER GLFW_KEY_ENTER 31 | // BackSpace for comming back to the last directory 32 | //#define IGFD_KEY_BACKSPACE GLFW_KEY_BACKSPACE 33 | 34 | // widget 35 | // filter combobox width 36 | //#define FILTER_COMBO_WIDTH 120.0f 37 | // button widget use for compose path 38 | //#define IMGUI_PATH_BUTTON ImGui::Button 39 | // standar button 40 | //#define IMGUI_BUTTON ImGui::Button 41 | 42 | // locales string 43 | //#define createDirButtonString "+" 44 | //#define okButtonString " OK" 45 | //#define cancelButtonString " Cancel" 46 | //#define resetButtonString "R" 47 | //#define drivesButtonString "Drives" 48 | //#define searchString "Search" 49 | //#define dirEntryString "[DIR] " 50 | //#define linkEntryString "[LINK] " 51 | //#define fileEntryString "[FILE] " 52 | //#define fileNameString "File Name : " 53 | //#define buttonResetSearchString "Reset search" 54 | //#define buttonDriveString "Drives" 55 | //#define buttonResetPathString "Reset to current directory" 56 | //#define buttonCreateDirString "Create Directory" 57 | 58 | // theses icons will appear in table headers 59 | //#define USE_CUSTOM_SORTING_ICON 60 | //#define AscendingIcon "A|" 61 | //#define DescendingIcon "D|" 62 | //#define tableHeaderFilenameString "File name" 63 | //#define tableHeaderSizeString "Size" 64 | //#define tableHeaderDateString "Date" 65 | 66 | #define USE_BOOKMARK 67 | //#define bookmarkPaneWith 150.0f 68 | //#define IMGUI_TOGGLE_BUTTON ToggleButton 69 | //#define bookmarksButtonString "Bookmark" 70 | //#define bookmarksButtonHelpString "Bookmark" 71 | //#define addBookmarkButtonString "+" 72 | //#define removeBookmarkButtonString "-" 73 | 74 | #endif //JIMGUI_FD_CUSTOMIZATION_H 75 | -------------------------------------------------------------------------------- /core/jni/project/basics.hpp: -------------------------------------------------------------------------------- 1 | /// 2 | /// Created by ice1000 3 | /// 4 | 5 | #include "jni.h" 6 | 7 | #ifndef __JIMGUI_BASICS_HPP__ 8 | #define __JIMGUI_BASICS_HPP__ 9 | 10 | #define STR_HELPER(x) #x 11 | 12 | template 13 | using Ptr = T *; 14 | 15 | template 16 | using Com = T const &; 17 | 18 | template 19 | using Ref = T &; 20 | 21 | using RawStr = Ptr; 22 | 23 | #define __release(type, name) \ 24 | if (_ ## name != nullptr) env->Release ## type ## ArrayElements(_ ## name, name, JNI_OK); 25 | 26 | #define __abort(type, name) \ 27 | env->Release ## type ## ArrayElements(_ ## name, name, JNI_ABORT); 28 | 29 | #define __get(type, name) \ 30 | auto name = _ ## name == nullptr ? nullptr : env->Get ## type ## ArrayElements(_ ## name, nullptr); 31 | 32 | #define __new(type, name, len) \ 33 | auto _ ## name = env->New ## type ## Array(len); 34 | 35 | #define __set_array(type, name, len) \ 36 | env->Set ## type ## ArrayRegion(_ ## name, 0, (len), name); 37 | 38 | #define __init_array(type, name, len) \ 39 | auto _ ## name = env->New ## type ## Array(len); \ 40 | env->Set ## type ## ArrayRegion(_ ## name, 0, (len), name); 41 | 42 | #define __len(name) \ 43 | env->GetArrayLength(_ ## name) 44 | 45 | #define STR_J2C(value) \ 46 | reinterpret_cast> ((value)) 47 | 48 | #define PTR_C2J(value) \ 49 | reinterpret_cast ((value)) 50 | 51 | #define PTR_J2C(type, value) \ 52 | reinterpret_cast> ((value)) 53 | 54 | #undef _ 55 | 56 | #endif // __JIMGUI_BASICS_HPP__ 57 | -------------------------------------------------------------------------------- /core/jni/project/fd_wrapper.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by ice1000 on 2020/12/16. 3 | // 4 | 5 | #include 6 | #include 7 | #include 8 | #include "basics.hpp" 9 | 10 | using IGFD::FileDialog; 11 | 12 | extern "C" { 13 | JNIEXPORT void JNICALL 14 | Java_org_ice1000_jimgui_JImFileDialog_loadIcons(JNIEnv *, jclass, jfloat fontSize) { 15 | static const ImWchar icons_ranges[] = {ICON_MIN_IGFD, ICON_MAX_IGFD, 0}; 16 | ImFontConfig icons_config; 17 | icons_config.MergeMode = true; 18 | icons_config.PixelSnapH = true; 19 | ImGui::GetIO().Fonts->AddFontFromMemoryCompressedBase85TTF( 20 | FONT_ICON_BUFFER_NAME_IGFD, fontSize, &icons_config, icons_ranges); 21 | } 22 | 23 | JNIEXPORT jboolean JNICALL 24 | JavaCritical_org_ice1000_jimgui_JImFileDialog_fileDialogP( 25 | jlong stringPtr, jint flags, 26 | jfloat minSizeX, jfloat minSizeY, 27 | jfloat maxSizeX, jfloat maxSizeY, 28 | jlong nativeObjectPtr 29 | ) { 30 | auto ret = PTR_J2C(FileDialog, nativeObjectPtr)->Display( 31 | *PTR_J2C(std::string, stringPtr), flags, ImVec2(minSizeX, minSizeY), 32 | ImVec2(maxSizeX, maxSizeY)); 33 | return (ret ? JNI_TRUE : JNI_FALSE); 34 | } 35 | 36 | JNIEXPORT jboolean JNICALL 37 | Java_org_ice1000_jimgui_JImFileDialog_fileDialogP( 38 | JNIEnv *, jclass, 39 | jlong stringPtr, jint flags, 40 | jfloat minSizeX, jfloat minSizeY, 41 | jfloat maxSizeX, jfloat maxSizeY, 42 | jlong nativeObjectPtr 43 | ) { 44 | return JavaCritical_org_ice1000_jimgui_JImFileDialog_fileDialogP( 45 | stringPtr, flags, minSizeX, minSizeY, maxSizeX, maxSizeY, nativeObjectPtr); 46 | } 47 | 48 | JNIEXPORT jlong JNICALL 49 | JavaCritical_org_ice1000_jimgui_JImFileDialog_selectedFiles(jlong nativeObjectPtr) { 50 | auto &&map = PTR_J2C(FileDialog, nativeObjectPtr)->GetSelection(); 51 | auto *vec = new std::vector(map.size()); 52 | vec->clear(); 53 | for (auto &&selection : map) vec->push_back(selection.second); 54 | return PTR_C2J(vec); 55 | } 56 | 57 | JNIEXPORT jlong JNICALL 58 | Java_org_ice1000_jimgui_JImFileDialog_selectedFiles(JNIEnv *, jclass, jlong nativeObjectPtr) { 59 | return JavaCritical_org_ice1000_jimgui_JImFileDialog_selectedFiles(nativeObjectPtr); 60 | } 61 | 62 | JNIEXPORT jlong JNICALL JavaCritical_org_ice1000_jimgui_JImFileDialog_currentPath0(jlong nativeObjectPtr) { 63 | return PTR_C2J(new std::string(PTR_J2C(FileDialog, nativeObjectPtr)->GetCurrentPath())); 64 | } 65 | 66 | JNIEXPORT jlong JNICALL JavaCritical_org_ice1000_jimgui_JImFileDialog_currentFileName0(jlong nativeObjectPtr) { 67 | return PTR_C2J(new std::string(PTR_J2C(FileDialog, nativeObjectPtr)->GetCurrentFileName())); 68 | } 69 | 70 | JNIEXPORT jlong JNICALL JavaCritical_org_ice1000_jimgui_JImFileDialog_filePathName0(jlong nativeObjectPtr) { 71 | return PTR_C2J(new std::string(PTR_J2C(FileDialog, nativeObjectPtr)->GetFilePathName())); 72 | } 73 | 74 | #define GET_STRING_FUNCTION(name) \ 75 | JNIEXPORT jlong JNICALL Java_org_ice1000_jimgui_JImFileDialog_ ## name(JNIEnv *env, jclass, jlong nativeObjectPtr) { \ 76 | return JavaCritical_org_ice1000_jimgui_JImFileDialog_ ## name(nativeObjectPtr); \ 77 | } 78 | 79 | GET_STRING_FUNCTION(currentPath0) 80 | GET_STRING_FUNCTION(currentFileName0) 81 | GET_STRING_FUNCTION(filePathName0) 82 | 83 | #undef GET_STRING_FUNCTION 84 | } 85 | -------------------------------------------------------------------------------- /core/jni/project/imgui_ext.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by ice1000 on 18-7-3. 3 | // 4 | 5 | #ifndef HUGE_IMGUI_EXT_H 6 | #define HUGE_IMGUI_EXT_H 7 | 8 | #include 9 | #include 10 | 11 | using ComVec2 = Com; 12 | using RefVec2 = Ref; 13 | 14 | using ComVec4 = Com; 15 | using RefVec4 = Ref; 16 | 17 | #define IM_VEC2_OP(op) \ 18 | static inline ImVec2 operator op(ComVec2 lhs, ComVec2 rhs) { return {lhs.x op rhs.x, lhs.y op rhs.y}; } \ 19 | static inline ImVec2 operator op(ComVec2 lhs, const float rhs) { return {lhs.x op rhs, lhs.y op rhs}; } \ 20 | static inline RefVec2 operator op ## =(RefVec2 lhs, ComVec2 rhs) { \ 21 | lhs.x op ## = rhs.x; \ 22 | lhs.y op ## = rhs.y; \ 23 | return lhs; \ 24 | } 25 | 26 | IM_VEC2_OP(+) 27 | IM_VEC2_OP(-) 28 | IM_VEC2_OP(*) 29 | IM_VEC2_OP(/) 30 | 31 | #undef IM_VEC2_OP 32 | 33 | static constexpr inline bool operator==(ComVec2 lhs, ComVec2 rhs) { return lhs.x == rhs.x && lhs.y == rhs.y; } 34 | static constexpr inline bool operator!=(ComVec2 lhs, ComVec2 rhs) { return !(lhs == rhs); } 35 | 36 | #define IM_VEC4_OP(op) \ 37 | static inline ImVec4 operator op(ComVec4 lhs, ComVec4 rhs) { \ 38 | return {lhs.x op rhs.x, lhs.y op rhs.y, lhs.z op rhs.z, lhs.w op rhs.w}; \ 39 | } \ 40 | static inline RefVec4 operator op ## =(RefVec4 lhs, ComVec4 rhs) { \ 41 | lhs.x op ## = rhs.x; \ 42 | lhs.y op ## = rhs.y; \ 43 | lhs.z op ## = rhs.z; \ 44 | lhs.w op ## = rhs.w; \ 45 | return lhs; \ 46 | } 47 | 48 | IM_VEC4_OP(+) 49 | IM_VEC4_OP(-) 50 | IM_VEC4_OP(*) 51 | IM_VEC4_OP(/) 52 | 53 | #undef IM_VEC4_OP 54 | 55 | namespace ImGui { 56 | auto EmptyButton(ComVec4 bounds) -> bool; 57 | auto SetDisableHighlight(bool newValue) -> void; 58 | auto GetDisableHighlight() -> bool; 59 | auto DragVec4(RawStr name, RefVec4 val, float speed = 1, float min = 0, float max = 0, ImGuiSliderFlags flags = 0) -> void; 60 | auto SliderVec4(RawStr name, RefVec4 val, float min = 0, float max = 100, ImGuiSliderFlags flags = 0) -> void; 61 | auto DragDouble(RawStr label, 62 | Ptr v, 63 | float v_speed = 1.0f, 64 | double v_min = .0, 65 | double v_max = .0, 66 | RawStr format = "%.6lf", 67 | ImGuiSliderFlags flags = 0) -> bool; 68 | auto LineTo(ComVec2 delta, ComVec4 color, float thickness = 1.0f) -> void; 69 | auto LineTo(ComVec2 delta, float thickness = 1.0f) -> void; 70 | /// if @param thickness < 0, circle will be filled 71 | auto Circle(float radius, ComVec4 color, int num_segments = 12, float thickness = 1.0f) -> void; 72 | /// if @param thickness < 0, circle will be filled 73 | auto Circle(float radius, int num_segments = 12, float thickness = 1.0f) -> void; 74 | size_t BeginRotate() noexcept; 75 | auto RotationCenter(size_t rotation_start_index) -> ImVec2; 76 | auto EndRotate(float rad, size_t rotation_start_index, ImVec2 center) -> void; 77 | auto EndRotate(float rad, size_t rotation_start_index) -> void; 78 | 79 | /// if @param thickness < 0, rect will be filled 80 | auto Rect(ComVec2 size, 81 | ComVec4 color = ImGui::GetStyle().Colors[ImGuiCol_Button], 82 | float rounding = 0.0f, 83 | float thickness = 1.0f, 84 | int rounding_corners_flags = ImDrawFlags_RoundCornersAll) -> void; 85 | /// if @param thickness < 0, rect will be filled 86 | auto DrawRect(ComVec4 border, 87 | ComVec4 color = ImGui::GetStyle().Colors[ImGuiCol_Button], 88 | float rounding = 0.0f, 89 | float thickness = 1.0f, 90 | int rounding_corners_flags = ImDrawFlags_RoundCornersAll) -> void; 91 | /// if @param thickness < 0, rect will be filled 92 | auto DrawRect(ComVec2 pos, 93 | ComVec2 size, 94 | ComVec4 color = ImGui::GetStyle().Colors[ImGuiCol_Button], 95 | float rounding = 0.0f, 96 | float thickness = 1.0f, 97 | int rounding_corners_flags = ImDrawFlags_RoundCornersAll) -> void; 98 | 99 | auto BufferingBar(float value, 100 | ComVec2 size, 101 | ComVec4 bg_col = ImGui::GetStyle().Colors[ImGuiCol_TextDisabled], 102 | ComVec4 fg_col = ImGui::GetStyle().Colors[ImGuiCol_Button]) -> void; 103 | auto Spinner(float radius, 104 | float thickness = 6.0f, 105 | int num_segments = 30, 106 | ComVec4 color = ImGui::GetStyle().Colors[ImGuiCol_Button]) -> void; 107 | 108 | #ifdef DialogBox 109 | #undef DialogBox 110 | #endif // DialogBox 111 | 112 | auto DialogBox(RawStr title, 113 | RawStr text, 114 | ComVec2 windowSize, 115 | Ptr pOpen = nullptr, 116 | float percentageOnScreen = .2f) -> void; 117 | auto ToggleButton(RawStr str_id, Ptr v) -> void; 118 | } 119 | 120 | #endif //HUGE_IMGUI_EXT_H 121 | -------------------------------------------------------------------------------- /core/jni/project/impl_header.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by ice10 on 12/18/2020. 3 | // 4 | 5 | #include 6 | #include 7 | 8 | #define DEFINE_PLATFORM_WINDOW_JNI_ACCESSORS(name) \ 9 | JNIEXPORT auto JNICALL \ 10 | Java_org_ice1000_jimgui_JImGui_getPlatformWindow ## name(JNIEnv *, jclass, jlong nativeObjectPtr) -> float { \ 11 | return JavaCritical_org_ice1000_jimgui_JImGui_getPlatformWindow ## name(nativeObjectPtr); \ 12 | } 13 | 14 | DEFINE_PLATFORM_WINDOW_JNI_ACCESSORS(SizeX) 15 | DEFINE_PLATFORM_WINDOW_JNI_ACCESSORS(SizeY) 16 | DEFINE_PLATFORM_WINDOW_JNI_ACCESSORS(PosX) 17 | DEFINE_PLATFORM_WINDOW_JNI_ACCESSORS(PosY) 18 | 19 | #undef DEFINE_PLATFORM_WINDOW_JNI_ACCESSORS 20 | 21 | JNIEXPORT void JNICALL 22 | Java_org_ice1000_jimgui_JImGui_setPlatformWindowSize( 23 | JNIEnv *, jclass, jlong nativeObjectPtr, jfloat newX, 24 | jfloat newY) { 25 | JavaCritical_org_ice1000_jimgui_JImGui_setPlatformWindowSize(nativeObjectPtr, newX, newY); 26 | } 27 | 28 | JNIEXPORT void JNICALL 29 | Java_org_ice1000_jimgui_JImGui_setPlatformWindowPos(JNIEnv *, jclass, jlong nativeObjectPtr, jfloat newX, jfloat newY) { 30 | JavaCritical_org_ice1000_jimgui_JImGui_setPlatformWindowPos(nativeObjectPtr, newX, newY); 31 | } 32 | 33 | JNIEXPORT void JNICALL 34 | Java_org_ice1000_jimgui_JImGui_deallocateNativeObjects(JNIEnv *, jclass, jlong nativeObjectPtr) { 35 | JavaCritical_org_ice1000_jimgui_JImGui_deallocateNativeObjects(nativeObjectPtr); 36 | } 37 | 38 | JNIEXPORT void JNICALL 39 | Java_org_ice1000_jimgui_JImGui_deallocateGuiFramework(JNIEnv *, jclass, jlong nativeObjectPtr) { 40 | JavaCritical_org_ice1000_jimgui_JImGui_deallocateGuiFramework(nativeObjectPtr); 41 | } 42 | 43 | JNIEXPORT void JNICALL 44 | Java_org_ice1000_jimgui_JImGui_initNewFrame(JNIEnv *, jclass, jlong nativeObjectPtr) { 45 | JavaCritical_org_ice1000_jimgui_JImGui_initNewFrame(nativeObjectPtr); 46 | } 47 | 48 | JNIEXPORT auto JNICALL 49 | Java_org_ice1000_jimgui_JImGui_windowShouldClose(JNIEnv *, jclass, jlong nativeObjectPtr) -> jboolean { 50 | return JavaCritical_org_ice1000_jimgui_JImGui_windowShouldClose(nativeObjectPtr); 51 | } 52 | 53 | JNIEXPORT void JNICALL 54 | Java_org_ice1000_jimgui_JImGui_render(JNIEnv *, jclass, jlong ptr, jlong colorPtr) { 55 | JavaCritical_org_ice1000_jimgui_JImGui_render(ptr, colorPtr); 56 | } 57 | 58 | JNIEXPORT void JNICALL 59 | Java_org_ice1000_jimgui_JImGui_setupImguiSpecificObjects(JNIEnv *, jclass, jlong nativeObjectPtr, jlong fontAtlas) { 60 | JavaCritical_org_ice1000_jimgui_JImGui_setupImguiSpecificObjects(nativeObjectPtr, fontAtlas); 61 | } 62 | 63 | JNIEXPORT void JNICALL 64 | Java_org_ice1000_jimgui_JImGui_setWindowTitle(JNIEnv *env, jclass, jlong nativeObjectPtr, jbyteArray _title) { 65 | __get(Byte, title); 66 | JavaCritical_org_ice1000_jimgui_JImGui_setWindowTitle(nativeObjectPtr, -1, title); 67 | __release(Byte, title); 68 | } 69 | 70 | JNIEXPORT void JNICALL 71 | Java_org_ice1000_jimgui_JImGui_setWindowTitlePtr(JNIEnv *env, jclass, jlong nativeObjectPtr, jlong stringPtr) { 72 | JavaCritical_org_ice1000_jimgui_JImGui_setWindowTitlePtr(nativeObjectPtr, stringPtr); 73 | } 74 | 75 | JNIEXPORT auto JNICALL 76 | Java_org_ice1000_jimgui_glfw_GlfwUtil_createWindowPointer0( 77 | JNIEnv *env, 78 | jclass, 79 | jint w, 80 | jint h, 81 | jbyteArray _title, 82 | jlong anotherWindow) -> jlong { 83 | __get(Byte, title) 84 | auto ret = JavaCritical_org_ice1000_jimgui_glfw_GlfwUtil_createWindowPointer0(w, h, -1, title, anotherWindow); 85 | __release(Byte, title) 86 | return ret; 87 | } 88 | -------------------------------------------------------------------------------- /core/jni/project/impl_header.h: -------------------------------------------------------------------------------- 1 | /// 2 | /// Created by ice1000 on 18-6-1. 3 | /// 4 | 5 | #ifndef JIMGUI_IMPL_HEADER_H 6 | #define JIMGUI_IMPL_HEADER_H 7 | 8 | #include 9 | #include 10 | 11 | #ifdef __cplusplus 12 | extern "C" { 13 | #endif 14 | 15 | #ifndef WIN32 16 | #pragma clang diagnostic push 17 | #pragma ide diagnostic ignored "OCUnusedGlobalDeclarationInspection" 18 | #endif 19 | 20 | JNIEXPORT void JNICALL 21 | JavaCritical_org_ice1000_jimgui_JImGui_deallocateNativeObjects(jlong nativeObjectPtr); 22 | 23 | JNIEXPORT void JNICALL 24 | JavaCritical_org_ice1000_jimgui_JImGui_deallocateGuiFramework(jlong nativeObjectPtr); 25 | 26 | JNIEXPORT void JNICALL 27 | JavaCritical_org_ice1000_jimgui_JImGui_initNewFrame(jlong nativeObjectPtr); 28 | 29 | JNIEXPORT auto JNICALL 30 | JavaCritical_org_ice1000_jimgui_JImGui_windowShouldClose(jlong nativeObjectPtr) -> jboolean; 31 | 32 | JNIEXPORT void JNICALL 33 | JavaCritical_org_ice1000_jimgui_JImGui_render(jlong nativeObjectPtr, jlong colorPtr); 34 | 35 | JNIEXPORT void JNICALL 36 | JavaCritical_org_ice1000_jimgui_JImGui_setWindowTitle(jlong nativeObjectPtr, jint titleSize, jbyte* title); 37 | 38 | JNIEXPORT void JNICALL 39 | JavaCritical_org_ice1000_jimgui_JImGui_setWindowTitlePtr(jlong nativeObjectPtr, jlong titlePtr); 40 | 41 | JNIEXPORT void JNICALL 42 | JavaCritical_org_ice1000_jimgui_JImGui_setupImguiSpecificObjects(jlong nativeObjectPtr, jlong fontAtlas); 43 | 44 | JNIEXPORT auto JNICALL 45 | JavaCritical_org_ice1000_jimgui_glfw_GlfwUtil_createWindowPointer0( 46 | jint width, 47 | jint height, 48 | jint titleSize, 49 | Ptr title, 50 | jlong anotherWindow) -> jlong; 51 | 52 | JNIEXPORT auto JNICALL 53 | JavaCritical_org_ice1000_jimgui_JImGui_getPlatformWindowSizeX(jlong nativeObjectPtr) -> float; 54 | JNIEXPORT auto JNICALL 55 | JavaCritical_org_ice1000_jimgui_JImGui_getPlatformWindowSizeY(jlong nativeObjectPtr) -> float; 56 | JNIEXPORT auto JNICALL 57 | JavaCritical_org_ice1000_jimgui_JImGui_getPlatformWindowPosX(jlong nativeObjectPtr) -> float; 58 | JNIEXPORT auto JNICALL 59 | JavaCritical_org_ice1000_jimgui_JImGui_getPlatformWindowPosY(jlong nativeObjectPtr) -> float; 60 | JNIEXPORT void JNICALL 61 | JavaCritical_org_ice1000_jimgui_JImGui_setPlatformWindowSize(jlong nativeObjectPtr, float newX, float newY); 62 | JNIEXPORT void JNICALL 63 | JavaCritical_org_ice1000_jimgui_JImGui_setPlatformWindowPos(jlong nativeObjectPtr, float newX, float newY); 64 | 65 | #ifdef __cplusplus 66 | } 67 | #endif 68 | 69 | #ifndef WIN32 70 | #pragma clang diagnostic pop 71 | #endif 72 | 73 | #endif //JIMGUI_IMPL_HEADER_H 74 | -------------------------------------------------------------------------------- /core/jni/project/overloads_helper.cpp: -------------------------------------------------------------------------------- 1 | /// 2 | /// Created by ice1000 on 18-5-7. 3 | /// 4 | 5 | #include "overloads_helper.hpp" 6 | 7 | auto ImGui::Selectable0(Ptr label, bool selected, ImGuiSelectableFlags flags, const ImVec2 &size) -> bool { 8 | return Selectable(label, selected, flags, size); 9 | } 10 | 11 | auto ImGui::PushStyleVarImVec2(ImGuiStyleVar idx, const ImVec2 &val) -> void { 12 | ImGui::PushStyleVar(idx, val); 13 | } 14 | 15 | auto ImGui::PushStyleVarFloat(ImGuiStyleVar idx, float val) -> void { 16 | ImGui::PushStyleVar(idx, val); 17 | } 18 | 19 | auto ImGui::BeginChild0(Ptr str_id, const ImVec2 &size, bool border, ImGuiWindowFlags flags) -> bool { 20 | return BeginChild(str_id, size, border, flags); 21 | } 22 | 23 | #define ColorRelated(name) \ 24 | auto ImGui::Color ## name(Ptrlabel, ImVec4& col, ImGuiColorEditFlags flags) -> bool { \ 25 | return Color ## name(label, PTR_J2C(float, &col), flags); \ 26 | } 27 | 28 | ColorRelated(Edit3) 29 | ColorRelated(Edit4) 30 | ColorRelated(Picker3) 31 | ColorRelated(Picker4) 32 | 33 | auto ImGui::RadioButton0(const char *label, bool active) -> bool { 34 | return RadioButton(label, active); 35 | } 36 | 37 | #undef ColorRelated 38 | -------------------------------------------------------------------------------- /core/jni/project/overloads_helper.hpp: -------------------------------------------------------------------------------- 1 | /// 2 | /// Created by ice1000 on 18-5-7. 3 | /// 4 | 5 | #ifndef JIMGUI_GENERATED_HELPER_H 6 | #define JIMGUI_GENERATED_HELPER_H 7 | 8 | #include 9 | #include "basics.hpp" 10 | 11 | namespace ImGui { 12 | auto Selectable0(Ptr label, bool selected = false, ImGuiSelectableFlags flags = 0, const ImVec2 &size = ImVec2(0, 0)) -> bool; 13 | auto PushStyleVarImVec2(ImGuiStyleVar idx, const ImVec2 &val) -> void; 14 | auto PushStyleVarFloat(ImGuiStyleVar idx, float val) -> void; 15 | auto BeginChild0( 16 | Ptr str_id, const ImVec2 &size = ImVec2(0, 0), 17 | bool border = false, ImGuiWindowFlags flags = 0) -> bool; 18 | auto ColorEdit3(Ptr label, ImVec4 &col, ImGuiColorEditFlags flags = 0) -> bool; 19 | auto ColorEdit4(Ptr label, ImVec4 &col, ImGuiColorEditFlags flags = 0) -> bool; 20 | auto ColorPicker3(Ptr label, ImVec4 &col, ImGuiColorEditFlags flags = 0) -> bool; 21 | auto ColorPicker4(Ptr label, ImVec4 &col, ImGuiColorEditFlags flags = 0) -> bool; 22 | auto RadioButton0(Ptr label, bool active) -> bool; 23 | } 24 | 25 | #endif //JIMGUI_GENERATED_HELPER_H 26 | -------------------------------------------------------------------------------- /core/jni/project/win32_impl.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by ice10 on 2019/7/12. 3 | // 4 | 5 | #include "win32_impl.h" 6 | #include 7 | 8 | NativeObject::NativeObject(jint width, jint height, Ptr title) : wc{ 9 | sizeof(WNDCLASSEX), CS_CLASSDC, WndProc, 0L, 10 | 0L, 11 | GetModuleHandle(nullptr), nullptr, 12 | nullptr, nullptr, nullptr, _T(WINDOW_ID), 13 | nullptr 14 | }, msg{} { 15 | RegisterClassEx(&wc); 16 | ZeroMemory(&msg, sizeof msg); 17 | hwnd = CreateWindow( 18 | _T(WINDOW_ID), _T(title), WS_OVERLAPPEDWINDOW, 19 | 100, 100, width, height, nullptr, nullptr, wc.hInstance, nullptr); 20 | } 21 | 22 | JNIEXPORT auto JNICALL 23 | JavaCritical_org_ice1000_jimgui_JImGui_windowShouldClose(jlong nativeObjectPtr) -> jboolean { 24 | auto object = PTR_J2C(NativeObject, nativeObjectPtr); 25 | return static_cast (object->msg.message == WM_QUIT ? JNI_TRUE : JNI_FALSE); 26 | } 27 | 28 | void setupImgui(jlong nativeObjectPtr, jlong fontAtlas) { 29 | auto *object = PTR_J2C(NativeObject, nativeObjectPtr); 30 | ShowWindow(object->hwnd, SW_SHOWDEFAULT); 31 | UpdateWindow(object->hwnd); 32 | IMGUI_CHECKVERSION(); 33 | ImGui::CreateContext(PTR_J2C(ImFontAtlas, fontAtlas)); 34 | ImGuiIO &io = ImGui::GetIO(); 35 | // Enable Keyboard Controls 36 | io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; 37 | ImGui_ImplWin32_Init(object->hwnd); 38 | } 39 | 40 | void dispatchMessage(NativeObject *object) { 41 | while (object->msg.message != WM_QUIT && PeekMessage(&object->msg, NULL, 0U, 0U, PM_REMOVE)) { 42 | TranslateMessage(&object->msg); 43 | DispatchMessage(&object->msg); 44 | } 45 | } 46 | 47 | #define DEFINE_PLATFORM_WINDOW_FUNCTIONS(name, expr) \ 48 | JNIEXPORT auto JNICALL \ 49 | JavaCritical_org_ice1000_jimgui_JImGui_getPlatformWindow ## name(jlong nativeObjectPtr) -> float { \ 50 | auto wc = PTR_J2C(NativeObject, nativeObjectPtr); \ 51 | RECT rect{}; \ 52 | GetClientRect(wc->hwnd, &rect); \ 53 | return static_cast(expr); \ 54 | } 55 | 56 | DEFINE_PLATFORM_WINDOW_FUNCTIONS(SizeX, rect.right - rect.left) 57 | DEFINE_PLATFORM_WINDOW_FUNCTIONS(SizeY, rect.bottom - rect.top) 58 | DEFINE_PLATFORM_WINDOW_FUNCTIONS(PosX, rect.left) 59 | DEFINE_PLATFORM_WINDOW_FUNCTIONS(PosY, rect.top) 60 | 61 | #undef DEFINE_PLATFORM_WINDOW_FUNCTIONS 62 | 63 | JNIEXPORT void JNICALL 64 | JavaCritical_org_ice1000_jimgui_JImGui_setPlatformWindowSize(jlong nativeObjectPtr, float newX, float newY) { 65 | auto wc = PTR_J2C(NativeObject, nativeObjectPtr); 66 | SetWindowPos( 67 | wc->hwnd, 68 | nullptr, 69 | 0, 70 | 0, 71 | static_cast(newX), 72 | static_cast(newY), 73 | SWP_NOMOVE | SWP_NOZORDER); 74 | } 75 | 76 | JNIEXPORT void JNICALL 77 | JavaCritical_org_ice1000_jimgui_JImGui_setPlatformWindowPos(jlong nativeObjectPtr, float newX, float newY) { 78 | auto wc = PTR_J2C(NativeObject, nativeObjectPtr); 79 | SetWindowPos( 80 | wc->hwnd, 81 | nullptr, 82 | static_cast(newX), 83 | static_cast(newY), 84 | 0, 85 | 0, 86 | SWP_NOSIZE | SWP_NOZORDER); 87 | } 88 | 89 | JNIEXPORT void JNICALL 90 | JavaCritical_org_ice1000_jimgui_JImGui_setWindowTitle(jlong nativeObjectPtr, jint, jbyte* title){ 91 | auto wc = PTR_J2C(NativeObject, nativeObjectPtr); 92 | SetWindowTextA(wc->hwnd, STR_J2C(title)); 93 | } 94 | 95 | JNIEXPORT void JNICALL 96 | JavaCritical_org_ice1000_jimgui_JImGui_setWindowTitlePtr(jlong nativeObjectPtr, jlong titlePtr) { 97 | auto wc = PTR_J2C(NativeObject, nativeObjectPtr); 98 | SetWindowTextA(wc->hwnd, PTR_J2C(std::string, titlePtr)->c_str()); 99 | } 100 | -------------------------------------------------------------------------------- /core/jni/project/win32_impl.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by ice10 on 2019/7/12. 3 | // 4 | 5 | #ifndef JIMGUI_WIN32_IMPL_H 6 | #define JIMGUI_WIN32_IMPL_H 7 | 8 | #define DIRECTINPUT_VERSION 0x0800 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | static auto WINDOW_ID = "JIMGUI_WINDOW"; 18 | 19 | LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); 20 | 21 | struct NativeObject { 22 | HWND hwnd; 23 | MSG msg; 24 | WNDCLASSEX wc; 25 | 26 | NativeObject(jint width, jint height, Ptr title); 27 | }; 28 | 29 | void dispatchMessage(NativeObject *object); 30 | void setupImgui(jlong nativeObjectPtr, jlong fontAtlas); 31 | 32 | extern LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); 33 | 34 | #endif //JIMGUI_WIN32_IMPL_H 35 | -------------------------------------------------------------------------------- /core/jni/win32-glfw/.gitignore: -------------------------------------------------------------------------------- 1 | # Created by .ignore support plugin (hsz.mobi) 2 | ### C++ template 3 | # Prerequisites 4 | *.d 5 | 6 | # Compiled Object files 7 | *.slo 8 | *.lo 9 | *.o 10 | *.obj 11 | 12 | # Precompiled Headers 13 | *.gch 14 | *.pch 15 | 16 | glfw 17 | 18 | # Compiled Dynamic libraries 19 | *.so 20 | *.dylib 21 | *.dll 22 | 23 | # Fortran module files 24 | *.mod 25 | *.smod 26 | 27 | # Compiled Static libraries 28 | *.lai 29 | *.la 30 | *.a 31 | *.lib 32 | 33 | # Executables 34 | *.exe 35 | *.out 36 | *.app 37 | ### CMake template 38 | CMakeCache.txt 39 | CMakeFiles 40 | CMakeScripts 41 | Testing 42 | Makefile 43 | cmake_install.cmake 44 | install_manifest.txt 45 | compile_commands.json 46 | CTestTestfile.cmake 47 | 48 | DebugX64 49 | DebugX86 50 | -------------------------------------------------------------------------------- /core/jni/win32-glfw/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.5) 2 | project(jimgui 3 | VERSION 0.1 4 | LANGUAGES C CXX) 5 | 6 | set(CMAKE_CXX_STANDARD 11) 7 | find_package(Java REQUIRED) 8 | find_package(JNI REQUIRED) 9 | 10 | if (JNI_FOUND) 11 | message(STATUS "JNI_INCLUDE_DIRS=${JNI_INCLUDE_DIRS}") 12 | message(STATUS "JNI_LIBRARIES=${JNI_LIBRARIES}") 13 | endif () 14 | 15 | set(GLFW_BUILD_DOCS OFF CACHE BOOL "" FORCE) 16 | set(GLFW_BUILD_TESTS OFF CACHE BOOL "" FORCE) 17 | set(GLFW_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE) 18 | add_subdirectory(glfw) 19 | 20 | find_package(OpenGL REQUIRED) 21 | find_package(PkgConfig REQUIRED) 22 | find_package(glfw3 REQUIRED) 23 | # pkg_search_module(GLFW REQUIRED glfw3) 24 | if (glfw3_FOUND) 25 | message(STATUS "GLFW_INCLUDE_DIRS=${GLFW_INCLUDE_DIRS}") 26 | endif () 27 | set(IMGUI_IMPL ../impl/imgui_impl_glfw.cpp ../impl/imgui_impl_opengl3.cpp ../impl/gl3w.c ../project/glfw_impl.cpp) 28 | include_directories(${GLFW_INCLUDE_DIRS}) 29 | 30 | set(TARGET_LINK_LIBS glfw opengl32 pthread gdi32 -static-libgcc -static-libstdc++ -static) 31 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-format-security -O3") 32 | add_definitions(-DCUSTOM_IMGUIFILEDIALOG_CONFIG="fd_customization.h") 33 | include_directories(${JNI_INCLUDE_DIRS} .. ../imgui ../javah ../impl ../config glfw/include ../3rdparty/fd) 34 | link_directories(../imgui ../impl) 35 | 36 | file(GLOB IMGUI_FILES "../imgui/*") 37 | file(GLOB GENERATED_FILES "../gen/*") 38 | file(GLOB FILE_DIALOG_FILES "../3rdparty/fd/*") 39 | file(GLOB DATE_TIME_CHOOSER_FILES "../3rdparty/dtc/*") 40 | 41 | set(ALL_LIBRARIES 42 | ${IMGUI_FILES} ${IMGUI_IMPL} 43 | ${GENERATED_FILES} 44 | ${FILE_DIALOG_FILES} 45 | ${DATE_TIME_CHOOSER_FILES} 46 | ../project/fd_wrapper.cpp 47 | ../project/hand_written_bindings.cpp 48 | ../project/overloads_helper.cpp 49 | ../project/basics.hpp 50 | ../project/imgui_ext.cpp 51 | ../project/impl_header.h 52 | ../project/cpp_interop.cpp) 53 | if (NOT X86) 54 | message(STATUS "64 bit architecture") 55 | add_library(jimgui-glfw SHARED ${ALL_LIBRARIES}) 56 | target_link_libraries(jimgui-glfw ${TARGET_LINK_LIBS}) 57 | # add_executable(main-test ${ALL_LIBRARIES} main-test.cpp) 58 | # target_link_libraries(main-test ${TARGET_LINK_LIBS}) 59 | else () 60 | set(CMAKE_C_FLAGS -m32) 61 | set(CMAKE_CXX_FLAGS -m32) 62 | message(STATUS "32 bit architecture") 63 | add_library(jimgui32-glfw SHARED ${ALL_LIBRARIES}) 64 | target_link_libraries(jimgui32-glfw ${TARGET_LINK_LIBS}) 65 | endif () 66 | -------------------------------------------------------------------------------- /core/jni/win32-glfw/build.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env perl 2 | 3 | use warnings FATAL => 'all'; 4 | use strict; 5 | use v5.15; 6 | 7 | foreach my $arch (qw(X64 X86)) { 8 | my $dir = "Debug$arch"; 9 | `rm -rf $dir`; 10 | say `mkdir -p $dir`; 11 | chdir $dir; 12 | say `cmake .. -D$arch=true -G "Unix Makefiles"`; 13 | say `make`; 14 | chdir '..'; 15 | } 16 | -------------------------------------------------------------------------------- /core/module-info.java: -------------------------------------------------------------------------------- 1 | module ice1000.jimgui { 2 | requires static org.jetbrains.annotations; 3 | 4 | exports org.ice1000.jimgui; 5 | exports org.ice1000.jimgui.cpp; 6 | exports org.ice1000.jimgui.flag; 7 | exports org.ice1000.jimgui.glfw; 8 | exports org.ice1000.jimgui.util; 9 | } 10 | -------------------------------------------------------------------------------- /core/src/org/ice1000/jimgui/JImDrawList.java: -------------------------------------------------------------------------------- 1 | package org.ice1000.jimgui; 2 | 3 | import org.jetbrains.annotations.Contract; 4 | import org.jetbrains.annotations.NotNull; 5 | 6 | import java.nio.charset.StandardCharsets; 7 | 8 | public class JImDrawList extends JImGuiDrawListGen { 9 | /** 10 | * package-private by design 11 | * 12 | * @param nativeObjectPtr native pointer ImDrawList * 13 | */ 14 | @Contract JImDrawList(long nativeObjectPtr) { 15 | super(nativeObjectPtr); 16 | } 17 | 18 | public void addText(float posX, float posY, int u32Color, @NotNull String text) { 19 | addText(0, posX, posY, u32Color, text); 20 | } 21 | 22 | public void addText(float fontSize, float posX, float posY, int u32Color, @NotNull String text) { 23 | addText(0, fontSize, posX, posY, u32Color, text.getBytes(StandardCharsets.UTF_8), 0, 0, nativeObjectPtr); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /core/src/org/ice1000/jimgui/JImFileDialog.java: -------------------------------------------------------------------------------- 1 | package org.ice1000.jimgui; 2 | 3 | import org.ice1000.jimgui.cpp.DeallocatableObject; 4 | import org.ice1000.jimgui.flag.*; 5 | import org.intellij.lang.annotations.MagicConstant; 6 | import org.jetbrains.annotations.NotNull; 7 | 8 | import static org.ice1000.jimgui.util.JImGuiUtil.FLT_MAX; 9 | 10 | /** 11 | * https://github.com/aiekick/ImGuiFileDialog 12 | * 13 | * @author ice1000 14 | * @since v0.13.0 15 | */ 16 | public final class JImFileDialog extends JImFileDialogGen implements DeallocatableObject { 17 | public JImFileDialog() { 18 | super(allocateNativeObject()); 19 | } 20 | 21 | public void setFileStyle(@MagicConstant(flagsFromClass = JImFDStyleFlags.class) int flags, @NotNull String criteria, @NotNull JImVec4 color) { 22 | setFileStyle(flags, criteria, color, ""); 23 | } 24 | 25 | public void setFileStyle(@MagicConstant(flagsFromClass = JImFDStyleFlags.class) int flags, @NotNull JImStr criteria, @NotNull JImVec4 color) { 26 | setFileStyle(flags, criteria, color, JImStr.EMPTY); 27 | } 28 | 29 | public boolean display( 30 | @NotNull NativeString key, @MagicConstant(flagsFromClass = JImWindowFlags.class) int flags) { 31 | return display(key, flags, 0, 0, FLT_MAX, FLT_MAX); 32 | } 33 | 34 | public boolean display( 35 | @NotNull NativeString key, 36 | @MagicConstant(flagsFromClass = JImWindowFlags.class) int flags, 37 | float minSizeX, 38 | float minSizeY, 39 | float maxSizeX, 40 | float maxSizeY) { 41 | return fileDialogP(key.nativeObjectPtr, flags, minSizeX, minSizeY, maxSizeX, maxSizeY, nativeObjectPtr); 42 | } 43 | 44 | private static native long allocateNativeObject(); 45 | private static native void deallocateNativeObject(long nativeObjectPtr); 46 | private static native long currentPath0(long nativeObjectPtr); 47 | private static native long currentFileName0(long nativeObjectPtr); 48 | private static native long selectedFiles(long nativeObjectPtr); 49 | private static native long filePathName0(long nativeObjectPtr); 50 | 51 | public @NotNull NativeString currentPath() { 52 | return new NativeString(currentPath0(nativeObjectPtr)); 53 | } 54 | 55 | public @NotNull NativeString currentFileName() { 56 | return new NativeString(currentFileName0(nativeObjectPtr)); 57 | } 58 | 59 | public @NotNull NativeString filePathName() { 60 | return new NativeString(filePathName0(nativeObjectPtr)); 61 | } 62 | 63 | public @NotNull NativeStrings selections() { 64 | return new NativeStrings(selectedFiles(nativeObjectPtr)); 65 | } 66 | 67 | private static native boolean fileDialogP( 68 | long nativeStringPtrKey, 69 | @MagicConstant(flagsFromClass = JImWindowFlags.class) int flags, 70 | float minSizeX, 71 | float minSizeY, 72 | float maxSizeX, 73 | float maxSizeY, 74 | long nativeObjectPtr); 75 | 76 | public static native void loadIcons(float fontSize); 77 | 78 | @Override public void deallocateNativeObject() { 79 | deallocateNativeObject(nativeObjectPtr); 80 | } 81 | 82 | public interface Icons { 83 | int MIN = 0xf002; 84 | int MAX = 0xf1c9; 85 | @NotNull JImStr ADD = new JImStr.Cached("\uf067"); 86 | @NotNull JImStr BOOKMARK = new JImStr.Cached("\uf02e"); 87 | @NotNull JImStr CANCEL = new JImStr.Cached("\uf00d"); 88 | @NotNull JImStr DRIVES = new JImStr.Cached("\uf0a0"); 89 | @NotNull JImStr EDIT = new JImStr.Cached("\uf040"); 90 | @NotNull JImStr CHEVRON_DOWN = new JImStr.Cached("\uf078"); 91 | @NotNull JImStr CHEVRON_UP = new JImStr.Cached("\uf077"); 92 | @NotNull JImStr FILE = new JImStr.Cached("\uf15b"); 93 | @NotNull JImStr FILE_PIC = new JImStr.Cached("\uf1c5"); 94 | @NotNull JImStr FOLDER = new JImStr.Cached("\uf07b"); 95 | @NotNull JImStr FOLDER_OPEN = new JImStr.Cached("\uf07c"); 96 | @NotNull JImStr LINK = new JImStr.Cached("\uf1c9"); 97 | @NotNull JImStr OK = new JImStr.Cached("\uf00c"); 98 | @NotNull JImStr REFRESH = new JImStr.Cached("\uf021"); 99 | @NotNull JImStr REMOVE = new JImStr.Cached("\uf068"); 100 | @NotNull JImStr RESET = new JImStr.Cached("\uf064"); 101 | @NotNull JImStr SAVE = new JImStr.Cached("\uf0c7"); 102 | @NotNull JImStr SEARCH = new JImStr.Cached("\uf002"); 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /core/src/org/ice1000/jimgui/JImFont.java: -------------------------------------------------------------------------------- 1 | package org.ice1000.jimgui; 2 | 3 | import org.jetbrains.annotations.Contract; 4 | import org.jetbrains.annotations.NotNull; 5 | 6 | /** 7 | * @author ice1000 8 | * @since v0.1 9 | */ 10 | public final class JImFont extends JImGuiFontGen { 11 | /** 12 | * {@inheritDoc} 13 | * 14 | * @param nativeObjectPtr native ImFont* 15 | */ 16 | @Contract(pure = true) JImFont(long nativeObjectPtr) { 17 | super(nativeObjectPtr); 18 | if (nativeObjectPtr == 0) throw new NullPointerException(); 19 | } 20 | 21 | @Contract("->new") public @NotNull NativeString debugName() { 22 | return NativeString.fromRaw(getDebugName()); 23 | } 24 | 25 | public @NotNull JImFontAtlas getContainerAtlas() { 26 | return new JImFontAtlas(getContainerFontAtlas(nativeObjectPtr)); 27 | } 28 | 29 | public @NotNull JImFontConfig getConfigData() { 30 | return new JImFontConfig(getConfigData(nativeObjectPtr)); 31 | } 32 | // public native void setDisplayOffset(float newX, float newY); 33 | 34 | private static native long getContainerFontAtlas(long nativeObjectPtr); 35 | 36 | private static native long getConfigData(long nativeObjectPtr); 37 | } 38 | -------------------------------------------------------------------------------- /core/src/org/ice1000/jimgui/JImFontConfig.java: -------------------------------------------------------------------------------- 1 | package org.ice1000.jimgui; 2 | 3 | import org.ice1000.jimgui.cpp.DeallocatableObject; 4 | import org.jetbrains.annotations.Contract; 5 | 6 | /** 7 | * @author ice1000 8 | * @since v0.4 9 | */ 10 | public final class JImFontConfig extends JImGuiFontConfigGen implements DeallocatableObject { 11 | /** 12 | * {@inheritDoc} 13 | * 14 | * @param nativeObjectPtr native ImFont* 15 | */ 16 | @Contract(pure = true) JImFontConfig(long nativeObjectPtr) { 17 | super(nativeObjectPtr); 18 | } 19 | 20 | /** 21 | * @apiNote Should call {@link JImFontConfig#deallocateNativeObject()}. 22 | * @see JImFont#getConfigData() 23 | */ 24 | @Contract public JImFontConfig() { 25 | this(allocateNativeObject()); 26 | } 27 | 28 | private static native long allocateNativeObject(); 29 | 30 | private static native void deallocateNativeObject(long nativeObjectPtr); 31 | 32 | @Override public void deallocateNativeObject() { 33 | deallocateNativeObject(nativeObjectPtr); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /core/src/org/ice1000/jimgui/JImGuiIO.java: -------------------------------------------------------------------------------- 1 | package org.ice1000.jimgui; 2 | 3 | import org.ice1000.jimgui.flag.JImMouseButton; 4 | import org.intellij.lang.annotations.MagicConstant; 5 | import org.jetbrains.annotations.NotNull; 6 | 7 | /** 8 | * @author ice1000 9 | * @since v0.1 10 | */ 11 | public final class JImGuiIO extends JImGuiIOGen { 12 | /** package-private by design */ 13 | JImGuiIO() { 14 | } 15 | 16 | public native float getMouseClickedPosX(@MagicConstant(valuesFromClass = JImMouseButton.class) int index); 17 | public native float getMouseClickedPosY(@MagicConstant(valuesFromClass = JImMouseButton.class) int index); 18 | public native float getMouseDragMaxDistanceAbsX(@MagicConstant(valuesFromClass = JImMouseButton.class) int index); 19 | public native float getMouseDragMaxDistanceAbsY(@MagicConstant(valuesFromClass = JImMouseButton.class) int index); 20 | 21 | public @NotNull String getInputString() { 22 | return new String(getInputChars()); 23 | } 24 | 25 | public void addInputCharacter(char character) { 26 | addInputCharacter((int) character); 27 | } 28 | 29 | public @NotNull JImFontAtlas getFonts() { 30 | return new JImFontAtlas(getFonts0()); 31 | } 32 | 33 | public @NotNull JImFont getFontDefault() { 34 | return new JImFont(getFontDefault0()); 35 | } 36 | 37 | public native char @NotNull [] getInputChars(); 38 | 39 | private static native long getFonts0(); 40 | 41 | private static native long getFontDefault0(); 42 | } 43 | -------------------------------------------------------------------------------- /core/src/org/ice1000/jimgui/JImSortSpecs.java: -------------------------------------------------------------------------------- 1 | package org.ice1000.jimgui; 2 | 3 | import org.ice1000.jimgui.flag.JImSortDirection; 4 | import org.intellij.lang.annotations.MagicConstant; 5 | import org.jetbrains.annotations.NotNull; 6 | 7 | /** 8 | * No need to deallocate. 9 | * 10 | * @author ice1000 11 | * @since v0.18 12 | */ 13 | public class JImSortSpecs extends JImTableSortSpecsGen { 14 | /** package-private by design */ 15 | JImSortSpecs(long nativeObjectPtr) { 16 | super(nativeObjectPtr); 17 | } 18 | public @NotNull Column columnSortSpecs(int index) { 19 | return new Column(columnSortSpecs(nativeObjectPtr, index)); 20 | } 21 | private static native long columnSortSpecs(long nativeObjectPtr, int offset); 22 | @SuppressWarnings("MagicConstant") 23 | public static class Column extends JImColumnSortSpecsGen { 24 | /** package-private by design */ 25 | Column(long nativeObjectPtr) { 26 | super(nativeObjectPtr); 27 | } 28 | @Override public @MagicConstant(valuesFromClass = JImSortDirection.class) int getSortDirection() { 29 | return super.getSortDirection(); 30 | } 31 | @Override public void setSortDirection(@MagicConstant(valuesFromClass = JImSortDirection.class) int newValue) { 32 | super.setSortDirection(newValue); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /core/src/org/ice1000/jimgui/JImStr.java: -------------------------------------------------------------------------------- 1 | package org.ice1000.jimgui; 2 | 3 | import org.jetbrains.annotations.Contract; 4 | import org.jetbrains.annotations.NotNull; 5 | 6 | import java.util.Arrays; 7 | 8 | import static org.ice1000.jimgui.util.JImGuiUtil.getBytes; 9 | 10 | /** 11 | * An alternative to {@link String} used in 12 | * {@link JImGui} functions. 13 | * Reduces memory allocations. 14 | * 15 | * @author ice1000 16 | * @since 0.9 17 | */ 18 | public class JImStr { 19 | public static class Cached extends JImStr { 20 | public final @NotNull String source; 21 | 22 | public Cached(@NotNull String source) { 23 | super(source); 24 | this.source = source; 25 | } 26 | 27 | @Override public @NotNull String toString() { 28 | return source; 29 | } 30 | } 31 | 32 | public static final @NotNull JImStr EMPTY = new JImStr(""); 33 | public final byte @NotNull [] bytes; 34 | 35 | private JImStr(byte @NotNull [] bytes) { 36 | this.bytes = bytes; 37 | } 38 | 39 | public JImStr(@NotNull String source) { 40 | this(getBytes(source)); 41 | } 42 | 43 | @Override public boolean equals(Object o) { 44 | if (this == o) return true; 45 | if (o == null || getClass() != o.getClass()) return false; 46 | JImStr imStr = (JImStr) o; 47 | return Arrays.equals(bytes, imStr.bytes); 48 | } 49 | 50 | @Override public int hashCode() { 51 | return Arrays.hashCode(bytes); 52 | } 53 | 54 | @Contract(pure = true) @Override public @NotNull String toString() { 55 | return new String(Arrays.copyOfRange(bytes, 0, bytes.length - 1)); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /core/src/org/ice1000/jimgui/JImStyle.java: -------------------------------------------------------------------------------- 1 | package org.ice1000.jimgui; 2 | 3 | import org.ice1000.jimgui.cpp.DeallocatableObject; 4 | import org.intellij.lang.annotations.MagicConstant; 5 | import org.jetbrains.annotations.Contract; 6 | import org.jetbrains.annotations.NotNull; 7 | 8 | /** 9 | * @author ice1000 10 | * @since v0.1 11 | */ 12 | public final class JImStyle extends JImGuiStyleGen implements DeallocatableObject { 13 | /** 14 | * package-private by design 15 | * 16 | * @param nativeObjectPtr native pointer {@code ImStyle*} 17 | */ 18 | @Contract(pure = true) JImStyle(long nativeObjectPtr) { 19 | super(nativeObjectPtr); 20 | } 21 | 22 | /** 23 | * @apiNote Should call {@link JImStyle#deallocateNativeObject()}. 24 | * @see JImGuiStyleGen#getInstance(JImGui) 25 | * @see JImGui#getStyle() 26 | * @since v0.4 27 | */ 28 | @Contract public JImStyle() { 29 | this(allocateNativeObject()); 30 | } 31 | 32 | public @NotNull JImVec4 getColor(@MagicConstant(valuesFromClass = JImStyleColors.class) int index) { 33 | return new JImVec4(getColor0(nativeObjectPtr, index)); 34 | } 35 | 36 | static native long getColor0( 37 | long nativeObjectPtr, @MagicConstant(valuesFromClass = JImStyleColors.class) int index); 38 | 39 | private static native long allocateNativeObject(); 40 | 41 | private static native void deallocateNativeObject(long nativeObjectPtr); 42 | 43 | @Override public void deallocateNativeObject() { 44 | deallocateNativeObject(nativeObjectPtr); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /core/src/org/ice1000/jimgui/JImStyleVar.java: -------------------------------------------------------------------------------- 1 | package org.ice1000.jimgui; 2 | 3 | /** 4 | * @param Corresponding style var type, 5 | * {@link Float} or ImVec2(Use {@link Void} to represent) 6 | * @author ice1000 7 | * @since v0.1 8 | */ 9 | @SuppressWarnings({"unused"}) 10 | public final class JImStyleVar { 11 | /** package-private by design */ 12 | int nativeValue; 13 | 14 | /** package-private by design */ 15 | JImStyleVar(int nativeValue) { 16 | this.nativeValue = nativeValue; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /core/src/org/ice1000/jimgui/JImTextureID.java: -------------------------------------------------------------------------------- 1 | package org.ice1000.jimgui; 2 | 3 | import org.jetbrains.annotations.Contract; 4 | import org.jetbrains.annotations.NotNull; 5 | import org.jetbrains.annotations.Nullable; 6 | 7 | import java.io.File; 8 | import java.net.URI; 9 | import java.nio.file.Path; 10 | import java.nio.file.Paths; 11 | 12 | import static org.ice1000.jimgui.util.JImGuiUtil.getBytes; 13 | 14 | /** 15 | * Cannot use after closing the current window 16 | * 17 | * @author ice1000 18 | * @since v0.2 19 | */ 20 | @SuppressWarnings("WeakerAccess") 21 | public final class JImTextureID { 22 | /** package-private by design */ 23 | long nativeObjectPtr; 24 | public final int width; 25 | public final int height; 26 | 27 | /** 28 | * private by design 29 | * you're encouraged to call this if you want to use opengl or dx9 only 30 | * for opengl, {@code nativeObjectPtr} is {@code GLuint} 31 | * for dx9, {@code nativeObjectPtr} is {@code LPDIRECT3DTEXTURE9} 32 | * 33 | * @param nativeObjectPtr native ImTextureID* 34 | * have different implementation on difference platforms 35 | * @param width image width 36 | * @param height image height 37 | */ 38 | private JImTextureID(long nativeObjectPtr, int width, int height) { 39 | this.width = width; 40 | this.height = height; 41 | this.nativeObjectPtr = nativeObjectPtr; 42 | } 43 | 44 | public static @NotNull JImTextureID fromFile(@NotNull String fileName) { 45 | return createJImTextureID("cannot load " + fileName, createTextureFromFile(getBytes(fileName))); 46 | } 47 | 48 | @Contract("_, null -> fail") private static @NotNull JImTextureID createJImTextureID( 49 | @NotNull String errorMessage, long @Nullable [] extractedData) { 50 | if (extractedData == null || extractedData.length != 3 || extractedData[0] == 0) 51 | throw new IllegalStateException(errorMessage); 52 | return new JImTextureID(extractedData[0], (int) extractedData[1], (int) extractedData[2]); 53 | } 54 | 55 | /** 56 | * Create a texture from file. 57 | * 58 | * @param uri file path 59 | * @return the texture 60 | * @throws IllegalStateException if load failed 61 | */ 62 | public static @NotNull JImTextureID fromUri(@NotNull URI uri) { 63 | return fromPath(Paths.get(uri)); 64 | } 65 | 66 | /** 67 | * Create a texture from file. 68 | * 69 | * @param file file instance 70 | * @return the texture 71 | * @throws IllegalStateException if load failed 72 | */ 73 | public static @NotNull JImTextureID fromFile(@NotNull File file) { 74 | return fromFile(file.getAbsolutePath()); 75 | } 76 | 77 | /** 78 | * Create a texture from file. 79 | * 80 | * @param path file path 81 | * @return the texture 82 | * @throws IllegalStateException if load failed 83 | */ 84 | public static @NotNull JImTextureID fromPath(@NotNull Path path) { 85 | return fromFile(path.toString()); 86 | } 87 | 88 | /** 89 | * Create a texture from in-memory files 90 | * 91 | * @param rawData raw memory data, directly passed to C++ 92 | * @return the texture 93 | * @throws IllegalStateException if native interface cannot create texture 94 | */ 95 | public static @NotNull JImTextureID fromBytes(byte @NotNull [] rawData) { 96 | long[] texture = createTextureFromBytes(rawData, rawData.length); 97 | return createJImTextureID("Failed to create texture!", texture); 98 | } 99 | 100 | /** 101 | * @param nativeObjectPtr existing texture id, like {@code GLuint} in glfw 102 | * @param width size, used in {@link JImGui#image(JImTextureID)} 103 | * @param height size, used in {@link JImGui#image(JImTextureID)} 104 | * @return created texture 105 | */ 106 | public static @NotNull JImTextureID fromExistingID(long nativeObjectPtr, int width, int height) { 107 | return new JImTextureID(nativeObjectPtr, width, height); 108 | } 109 | 110 | private static native long[] createTextureFromFile(byte @NotNull [] fileName); 111 | 112 | private static native long[] createTextureFromBytes(byte @NotNull [] rawData, int size); 113 | } 114 | -------------------------------------------------------------------------------- /core/src/org/ice1000/jimgui/JImVec4.java: -------------------------------------------------------------------------------- 1 | package org.ice1000.jimgui; 2 | 3 | import org.ice1000.jimgui.cpp.DeallocatableObject; 4 | import org.jetbrains.annotations.Contract; 5 | import org.jetbrains.annotations.NotNull; 6 | 7 | /** 8 | * Off-stack Vector, read only 9 | * 10 | * @author ice1000 11 | * @see MutableJImVec4 which is mutable 12 | * @since v0.1 13 | */ 14 | public class JImVec4 implements DeallocatableObject { 15 | // not sure if there should be one 16 | // public static final @NotNull JImVec4 NULL = new JImVec4(0); 17 | /** package-private by design */ 18 | long nativeObjectPtr; 19 | 20 | @Contract public JImVec4() { 21 | this(0, 0, 0, 0); 22 | } 23 | 24 | /** package-private by design */ 25 | @Contract(pure = true) JImVec4(long nativeObjectPtr) { 26 | this.nativeObjectPtr = nativeObjectPtr; 27 | } 28 | 29 | @Contract public JImVec4(float x, float y, float z, float w) { 30 | this(allocateNativeObjects(x, y, z, w)); 31 | } 32 | 33 | /** Don't call this unless necessary. */ 34 | @Contract(pure = true) public final float getW() { 35 | return getW(nativeObjectPtr); 36 | } 37 | 38 | /** Don't call this unless necessary. */ 39 | @Contract(pure = true) public final float getX() { 40 | return getX(nativeObjectPtr); 41 | } 42 | 43 | /** Don't call this unless necessary. */ 44 | @Contract(pure = true) public final float getY() { 45 | return getY(nativeObjectPtr); 46 | } 47 | 48 | /** Don't call this unless necessary. */ 49 | @Contract(pure = true) public final float getZ() { 50 | return getZ(nativeObjectPtr); 51 | } 52 | 53 | /** convert to {@code ImU32}, unsigned 32-bit integer */ 54 | @Contract(pure = true) public final int toU32() { 55 | return toU32(nativeObjectPtr); 56 | } 57 | 58 | /** Should only be called once. */ 59 | @Override public final void deallocateNativeObject() { 60 | deallocateNativeObjects(nativeObjectPtr); 61 | } 62 | 63 | /** 64 | * Convert HSV color to RGB 65 | * 66 | * @return a mutable imgui vec4 instance 67 | */ 68 | @Contract public static @NotNull MutableJImVec4 fromHSV(float h, float s, float v) { 69 | return fromHSV(h, s, v, 1); 70 | } 71 | 72 | /** 73 | * Convert HSV color to RGB 74 | * 75 | * @return a mutable imgui vec4 instance 76 | */ 77 | @Contract public static @NotNull MutableJImVec4 fromHSV(float h, float s, float v, float a) { 78 | return new MutableJImVec4(fromHSV0(h, s, v, a)); 79 | } 80 | 81 | /** 82 | * @param u32 unsigned 32-bit int color representation 83 | * @return a mutable imgui vec4 instance 84 | * @see JImVec4#toU32() 85 | */ 86 | @Contract public static @NotNull MutableJImVec4 fromU32(int u32) { 87 | return new MutableJImVec4(fromImU32(u32)); 88 | } 89 | 90 | @Override public String toString() { 91 | return "ImVec4{" + getX() + ',' + getY() + ',' + getZ() + ',' + getW() + '}'; 92 | } 93 | 94 | private static native float getZ(final long nativeObjectPtr); 95 | 96 | private static native float getY(final long nativeObjectPtr); 97 | 98 | private static native float getX(final long nativeObjectPtr); 99 | 100 | private static native float getW(final long nativeObjectPtr); 101 | 102 | private static native int toU32(final long nativeObjectPtr); 103 | 104 | private static native long fromImU32(int u32); 105 | 106 | private static native long fromHSV0(float h, float s, float v, float a); 107 | 108 | private static native long allocateNativeObjects(float x, float y, float z, float w); 109 | 110 | private static native void deallocateNativeObjects(long nativeObjectPtr); 111 | } 112 | -------------------------------------------------------------------------------- /core/src/org/ice1000/jimgui/MutableJImVec4.java: -------------------------------------------------------------------------------- 1 | package org.ice1000.jimgui; 2 | 3 | import org.jetbrains.annotations.Contract; 4 | 5 | /** 6 | * Off-stack Vector providing mutability. 7 | * 8 | * @author ice1000 9 | * @see JImVec4 10 | * @since v0.1 11 | */ 12 | public final class MutableJImVec4 extends JImVec4 { 13 | public MutableJImVec4() { 14 | super(); 15 | } 16 | 17 | /** package-private by design */ 18 | @Contract(pure = true) MutableJImVec4(long nativeObjectPtr) { 19 | super(nativeObjectPtr); 20 | } 21 | 22 | public MutableJImVec4(float x, float y, float z, float w) { 23 | super(x, y, z, w); 24 | } 25 | 26 | @Contract public final void setZ(final float newValue) { 27 | setZ(nativeObjectPtr, newValue); 28 | } 29 | 30 | @Contract public final void setY(final float newValue) { 31 | setY(nativeObjectPtr, newValue); 32 | } 33 | 34 | @Contract public final void setX(final float newValue) { 35 | setX(nativeObjectPtr, newValue); 36 | } 37 | 38 | @Contract public final void setW(final float newValue) { 39 | setW(nativeObjectPtr, newValue); 40 | } 41 | 42 | @Contract public final void incZ(final float increment) { 43 | incZ(nativeObjectPtr, increment); 44 | } 45 | 46 | @Contract public final void incY(final float increment) { 47 | incY(nativeObjectPtr, increment); 48 | } 49 | 50 | @Contract public final void incX(final float increment) { 51 | incX(nativeObjectPtr, increment); 52 | } 53 | 54 | @Contract public final void incW(final float increment) { 55 | incW(nativeObjectPtr, increment); 56 | } 57 | 58 | private static native void setZ(final long nativeObjectPtr, final float newValue); 59 | 60 | private static native void setY(final long nativeObjectPtr, final float newValue); 61 | 62 | private static native void setX(final long nativeObjectPtr, final float newValue); 63 | 64 | private static native void setW(final long nativeObjectPtr, final float newValue); 65 | 66 | private static native void incZ(final long nativeObjectPtr, final float increment); 67 | 68 | private static native void incY(final long nativeObjectPtr, final float increment); 69 | 70 | private static native void incX(final long nativeObjectPtr, final float increment); 71 | 72 | private static native void incW(final long nativeObjectPtr, final float increment); 73 | } 74 | -------------------------------------------------------------------------------- /core/src/org/ice1000/jimgui/NativeBool.java: -------------------------------------------------------------------------------- 1 | package org.ice1000.jimgui; 2 | 3 | import org.ice1000.jimgui.cpp.DeallocatableObject; 4 | import org.jetbrains.annotations.Contract; 5 | import org.jetbrains.annotations.NotNull; 6 | import org.jetbrains.annotations.Nullable; 7 | 8 | /** 9 | * @author ice1000 10 | * @since v0.1 11 | */ 12 | public final class NativeBool implements DeallocatableObject, Cloneable { 13 | /** package-private by design */ 14 | long nativeObjectPtr; 15 | 16 | @Contract public NativeBool() { 17 | nativeObjectPtr = allocateNativeObject(); 18 | } 19 | 20 | @Override @Contract public void deallocateNativeObject() { 21 | deallocateNativeObject0(nativeObjectPtr); 22 | nativeObjectPtr = 0; 23 | } 24 | 25 | @Contract(pure = true) public boolean accessValue() { 26 | return accessValue(nativeObjectPtr); 27 | } 28 | 29 | @Contract public void invertValue() { 30 | invertValue(nativeObjectPtr); 31 | } 32 | 33 | @Contract public void modifyValue(boolean newValue) { 34 | modifyValue(nativeObjectPtr, newValue); 35 | } 36 | 37 | private static native boolean accessValue(long nativeObjectPtr); 38 | 39 | private static native void modifyValue(long nativeObjectPtr, boolean newValue); 40 | 41 | private static native void invertValue(long nativeObjectPtr); 42 | 43 | private static native long allocateNativeObject(); 44 | 45 | private static native void deallocateNativeObject0(long nativeObjectPtr); 46 | 47 | @Override @Contract(value = "null -> false", pure = true) public boolean equals(@Nullable Object o) { 48 | return this == o || o instanceof NativeBool && nativeObjectPtr == ((NativeBool) o).nativeObjectPtr; 49 | } 50 | 51 | @Override @Contract(pure = true) public int hashCode() { 52 | return Long.hashCode(nativeObjectPtr); 53 | } 54 | 55 | @Override @Contract(pure = true) public @NotNull String toString() { 56 | return String.valueOf(accessValue()); 57 | } 58 | 59 | @Override @Contract @SuppressWarnings("MethodDoesntCallSuperMethod") public @NotNull NativeBool clone() { 60 | NativeBool nativeBool = new NativeBool(); 61 | nativeBool.modifyValue(accessValue()); 62 | return nativeBool; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /core/src/org/ice1000/jimgui/NativeString.java: -------------------------------------------------------------------------------- 1 | package org.ice1000.jimgui; 2 | 3 | import org.ice1000.jimgui.cpp.DeallocatableObject; 4 | import org.jetbrains.annotations.Contract; 5 | import org.jetbrains.annotations.NotNull; 6 | import org.jetbrains.annotations.Nullable; 7 | import java.nio.charset.StandardCharsets; 8 | 9 | /** 10 | * A wrapper of C++ std::string. 11 | * 12 | * @author ice1000 13 | * @since v0.13 14 | */ 15 | public final class NativeString implements CharSequence, DeallocatableObject { 16 | /** package-private by design */ 17 | long nativeObjectPtr; 18 | 19 | @Contract public NativeString() { 20 | this(16); 21 | } 22 | 23 | @Contract public NativeString(int initialCapacity) { 24 | this(allocateNativeObject(initialCapacity)); 25 | } 26 | 27 | public boolean isNull() { 28 | return nativeObjectPtr == 0; 29 | } 30 | 31 | @Contract(pure = true) protected NativeString(long nativeObjectPtr) { 32 | this.nativeObjectPtr = nativeObjectPtr; 33 | } 34 | 35 | @Override @Contract public void deallocateNativeObject() { 36 | deallocateNativeObject0(nativeObjectPtr); 37 | nativeObjectPtr = 0; 38 | } 39 | 40 | @Override @Contract(value = "null -> false", pure = true) public boolean equals(@Nullable Object o) { 41 | return this == o || o instanceof NativeBool && nativeObjectPtr == ((NativeBool) o).nativeObjectPtr; 42 | } 43 | 44 | @Override @Contract(pure = true) public int hashCode() { 45 | return Long.hashCode(nativeObjectPtr); 46 | } 47 | 48 | @Override @Contract(pure = true) public int length() { 49 | return length(nativeObjectPtr); 50 | } 51 | 52 | @Contract public void clear() { 53 | clear(nativeObjectPtr); 54 | } 55 | 56 | @Contract public void append(byte chr) { 57 | appendChar(nativeObjectPtr, chr); 58 | } 59 | 60 | @Contract public void append(char chr) { 61 | append((byte) chr); 62 | } 63 | 64 | @Override @Contract(pure = true) public char charAt(int position) { 65 | return (char) byteAt(nativeObjectPtr, position); 66 | } 67 | 68 | @Contract public void setByteAt(int position, byte newValue) { 69 | setByteAt(nativeObjectPtr, position, newValue); 70 | } 71 | 72 | @Contract public void setCharAt(int position, char newValue) { 73 | setByteAt(position, (byte) newValue); 74 | } 75 | 76 | @Override public @NotNull NativeString subSequence(int start, int end) { 77 | return new NativeString(substring(nativeObjectPtr, start, end)); 78 | } 79 | 80 | @Contract(pure = true) public byte byteAt(int position) { 81 | return byteAt(nativeObjectPtr, position); 82 | } 83 | 84 | public byte @NotNull [] toBytes() { 85 | byte[] values = new byte[length()]; 86 | readValues(nativeObjectPtr, values); 87 | return values; 88 | } 89 | 90 | @Override public @NotNull String toString() { 91 | return new String(toBytes(), StandardCharsets.UTF_8); 92 | } 93 | 94 | @Contract("_ -> new") public static @NotNull NativeString fromRaw(long constCharPtr) { 95 | return new NativeString(allocateNativeObjectFromRaw(constCharPtr)); 96 | } 97 | 98 | private static native long allocateNativeObject(int initialCapacity); 99 | private static native long allocateNativeObjectFromRaw(long constCharPtr); 100 | private static native void deallocateNativeObject0(long nativeObjectPtr); 101 | private static native byte byteAt(long nativeObjectPtr, int position); 102 | private static native void setByteAt(long nativeObjectPtr, int position, byte newValue); 103 | private static native int length(long nativeObjectPtr); 104 | private static native void clear(long nativeObjectPtr); 105 | private static native long substring(long nativeObjectPtr, int start, int end); 106 | private static native void appendChar(long nativeObjectPtr, byte chr); 107 | private static native void readValues(long nativeObjectPtr, byte @NotNull [] buf); 108 | } 109 | -------------------------------------------------------------------------------- /core/src/org/ice1000/jimgui/NativeStrings.java: -------------------------------------------------------------------------------- 1 | package org.ice1000.jimgui; 2 | 3 | import org.ice1000.jimgui.cpp.DeallocatableObject; 4 | import org.jetbrains.annotations.Contract; 5 | import org.jetbrains.annotations.NotNull; 6 | 7 | /** 8 | * @author ice1000 9 | * @since v0.17 10 | */ 11 | public class NativeStrings implements DeallocatableObject { 12 | long nativeObjectPtr; 13 | 14 | NativeStrings(long nativeObjectPtr) { 15 | this.nativeObjectPtr = nativeObjectPtr; 16 | } 17 | 18 | public boolean isEmpty() { 19 | return size() == 0; 20 | } 21 | 22 | public int size() { 23 | return size(nativeObjectPtr); 24 | } 25 | 26 | /** 27 | * @apiNote you need to close the returned string. 28 | */ 29 | @Contract public @NotNull NativeString get(int index) { 30 | return new NativeString(get(nativeObjectPtr, index)); 31 | } 32 | 33 | private static native int size(long nativeObjectPtr); 34 | private static native long get(long nativeObjectPtr, int index); 35 | private static native void deallocateNativeObject(long nativeObjectPtr); 36 | 37 | @Override public void deallocateNativeObject() { 38 | deallocateNativeObject(nativeObjectPtr); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /core/src/org/ice1000/jimgui/NativeTime.java: -------------------------------------------------------------------------------- 1 | package org.ice1000.jimgui; 2 | 3 | import org.ice1000.jimgui.cpp.DeallocatableObject; 4 | import org.jetbrains.annotations.Contract; 5 | 6 | /** 7 | * @author ice1000 8 | * @since v0.16 9 | */ 10 | public class NativeTime implements DeallocatableObject { 11 | long nativeObjectPtr; 12 | 13 | public NativeTime() { 14 | nativeObjectPtr = allocateNativeObject(); 15 | } 16 | 17 | @Override @Contract public void deallocateNativeObject() { 18 | deallocateNativeObject(nativeObjectPtr); 19 | nativeObjectPtr = 0; 20 | } 21 | 22 | public void resetToToday() { 23 | resetToToday(nativeObjectPtr); 24 | } 25 | 26 | public void reset() { 27 | reset(nativeObjectPtr); 28 | } 29 | 30 | /** Replace with {@link NativeTime#accessAbsoluteSeconds()} */ 31 | @Deprecated public long toAbsoluteSeconds() { 32 | return accessAbsoluteSeconds(); 33 | } 34 | 35 | public long accessAbsoluteSeconds() { 36 | return toAbsoluteSeconds(nativeObjectPtr); 37 | } 38 | 39 | public void modifyAbsoluteSeconds(long absoluteSeconds) { 40 | fromAbsoluteSeconds(nativeObjectPtr, absoluteSeconds); 41 | } 42 | 43 | private static native long allocateNativeObject(); 44 | private static native long toAbsoluteSeconds(long nativeObjectPtr); 45 | private static native void fromAbsoluteSeconds(long nativeObjectPtr, long absoluteSeconds); 46 | private static native void resetToToday(long nativeObjectPtr); 47 | private static native void reset(long nativeObjectPtr); 48 | private static native void deallocateNativeObject(long nativeObjectPtr); 49 | } 50 | -------------------------------------------------------------------------------- /core/src/org/ice1000/jimgui/cpp/DeallocatableObject.java: -------------------------------------------------------------------------------- 1 | package org.ice1000.jimgui.cpp; 2 | 3 | import org.jetbrains.annotations.Contract; 4 | 5 | /** 6 | * Represents a native (C++) object 7 | * 8 | * @author ice1000 9 | * @since v0.1 10 | */ 11 | public interface DeallocatableObject extends AutoCloseable { 12 | @Contract void deallocateNativeObject(); 13 | @Override default void close() { 14 | deallocateNativeObject(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /core/src/org/ice1000/jimgui/cpp/DeallocatableObjectManager.java: -------------------------------------------------------------------------------- 1 | package org.ice1000.jimgui.cpp; 2 | 3 | import org.jetbrains.annotations.NotNull; 4 | 5 | import java.io.Closeable; 6 | import java.util.ArrayList; 7 | import java.util.Collection; 8 | 9 | public class DeallocatableObjectManager extends ArrayList<@NotNull DeallocatableObject> implements AutoCloseable, Closeable { 10 | public DeallocatableObjectManager(int initialCapacity) { 11 | super(initialCapacity); 12 | } 13 | 14 | public DeallocatableObjectManager() { 15 | } 16 | 17 | public DeallocatableObjectManager(@NotNull Collection<@NotNull ? extends @NotNull DeallocatableObject> c) { 18 | super(c); 19 | } 20 | 21 | @Override public void close() { 22 | deallocateAll(); 23 | } 24 | 25 | public void deallocateAll() { 26 | for (DeallocatableObject object : this) object.deallocateNativeObject(); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /core/src/org/ice1000/jimgui/flag/Flag.java: -------------------------------------------------------------------------------- 1 | package org.ice1000.jimgui.flag; 2 | 3 | import org.jetbrains.annotations.NotNull; 4 | 5 | import java.lang.reflect.Array; 6 | import java.util.ArrayList; 7 | import java.util.Arrays; 8 | import java.util.List; 9 | 10 | public interface Flag { 11 | int get(); 12 | /** 13 | * @param flag to check for 14 | * @param flags to check if flag is contained within 15 | * @return boolean true of flag was found 16 | */ 17 | static boolean hasFlag(int flag, @NotNull Flag @NotNull ... flags) { 18 | return Arrays.stream(flags).anyMatch(value -> value.get() == flag); 19 | } 20 | // Slot enum[0], emum[1] for flags should be nothing and no flag found 21 | /** 22 | * This method assumes that all Flag.Type classes have a enum at position 0 23 | * labeled NoSuchFlag that takes the default or nothing value for error 24 | * prevention. 25 | * 26 | * @param enumType class that and enum type that extends Flag 27 | * @param flag the flag to lookup 28 | * @param the Flag which extends Enum 29 | * @return the Flag which is the flag int value 30 | */ 31 | static @NotNull E reverseLookup(@NotNull Class<@NotNull E> enumType, int flag) { 32 | E[] enumConstants = enumType.getEnumConstants(); 33 | for (int i = 1; i < enumConstants.length; i++) { 34 | E enumConstant = enumConstants[i]; 35 | int flagConstant = enumConstant.get(); 36 | if (flagConstant == flag) return enumConstant; 37 | } 38 | return enumConstants[0]; 39 | } 40 | /** 41 | * This method assumes that all Flag.Type classes have a enum at position 0 42 | * labeled NoSuchFlag that takes the default or nothing value for error 43 | * prevention. 44 | * 45 | * @param enumType class that and enum type that extends Flag 46 | * @param flags the flags to lookup 47 | * @param the Flag which extends Enum 48 | * @return the flags which is the flags int values 49 | */ 50 | static @NotNull E @NotNull [] getAsFlags(@NotNull Class<@NotNull E> enumType, int flags) { 51 | List setFlags = new ArrayList<>(); 52 | E[] enumConstants = enumType.getEnumConstants(); 53 | for (int i = 1; i < enumConstants.length; i++) { 54 | E enumConstant = enumConstants[i]; 55 | int flagConstant = enumConstant.get(); 56 | boolean flagSet = (flags & flagConstant) != 0; 57 | if (flagSet) setFlags.add(enumConstant); 58 | } 59 | final E[] a = (E[]) Array.newInstance(enumType, setFlags.size()); 60 | setFlags.toArray(a); 61 | return a; 62 | } 63 | /** 64 | * @param flagSelection Flags 65 | * @return value of all the flags set 66 | */ 67 | static int getAsValue(@NotNull Flag @NotNull ... flagSelection) { 68 | int flags = 0; 69 | for (Flag flag : flagSelection) { 70 | flags |= flag.get(); 71 | } 72 | return flags; 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /core/src/org/ice1000/jimgui/flag/JImDirection.java: -------------------------------------------------------------------------------- 1 | package org.ice1000.jimgui.flag; 2 | 3 | /** 4 | * @author ice1000 5 | * @since v0.1 6 | */ 7 | public interface JImDirection { 8 | int None = -1; 9 | int Left = 0; 10 | int Right = 1; 11 | int Up = 2; 12 | int Down = 3; 13 | 14 | enum Type implements Flag { 15 | /** 16 | * Used for reverse lookup results and enum comparison. 17 | * Return the Nothing or Default flag to prevent errors. 18 | */ 19 | NoSuchFlag(JImDirection.None), 20 | /** @see JImDirection#None */ 21 | None(JImDirection.None), 22 | /** @see JImDirection#Left */ 23 | Left(JImDirection.Left), 24 | /** @see JImDirection#Right */ 25 | Right(JImDirection.Right), 26 | /** @see JImDirection#Up */ 27 | Up(JImDirection.Up), 28 | /** @see JImDirection#Down */ 29 | Down(JImDirection.Down); 30 | public final int flag; 31 | 32 | Type(int flag) { 33 | this.flag = flag; 34 | } 35 | 36 | @Override public int get() { 37 | return flag; 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /core/src/org/ice1000/jimgui/flag/JImDrawCornerFlags.java: -------------------------------------------------------------------------------- 1 | package org.ice1000.jimgui.flag; 2 | 3 | /** 4 | * Flags for {@link org.ice1000.jimgui.JImDrawList} 5 | * 6 | * @author ice1000 7 | * @since v0.1 8 | */ 9 | public interface JImDrawCornerFlags { 10 | int Nothing = 0; 11 | /** 0x1 */ 12 | int TopLeft = 1; 13 | /** 0x2 */ 14 | int TopRight = 1 << 1; 15 | /** 0x4 */ 16 | int BotLeft = 1 << 2; 17 | /** 0x8 */ 18 | int BotRight = 1 << 3; 19 | /** 0x3 */ 20 | int Top = TopLeft | TopRight; 21 | /** 0xC */ 22 | int Bot = BotLeft | BotRight; 23 | /** 0x5 */ 24 | int Left = TopLeft | BotLeft; 25 | /** 0xA */ 26 | int Right = TopRight | BotRight; 27 | /** 28 | * In your function calls you may use ~0 29 | * (= all bits sets) instead of this, as a convenience 30 | */ 31 | int All = 0xF; 32 | 33 | enum Type implements Flag { 34 | /** 35 | * Used for reverse lookup results and enum comparison. 36 | * Return the Nothing or Default flag to prevent errors. 37 | */ 38 | NoSuchFlag(JImDrawCornerFlags.Nothing), Nothing(JImDrawCornerFlags.Nothing), 39 | /** @see JImDrawCornerFlags#TopLeft */ 40 | TopLeft(JImDrawCornerFlags.TopLeft), 41 | /** @see JImDrawCornerFlags#TopRight */ 42 | TopRight(JImDrawCornerFlags.TopRight), 43 | /** @see JImDrawCornerFlags#BotLeft */ 44 | BotLeft(JImDrawCornerFlags.BotLeft), 45 | /** @see JImDrawCornerFlags#BotRight */ 46 | BotRight(JImDrawCornerFlags.BotRight), 47 | /** @see JImDrawCornerFlags#Top */ 48 | Top(JImDrawCornerFlags.Top), 49 | /** @see JImDrawCornerFlags#Bot */ 50 | Bot(JImDrawCornerFlags.Bot), 51 | /** @see JImDrawCornerFlags#Left */ 52 | Left(JImDrawCornerFlags.Left), 53 | /** @see JImDrawCornerFlags#Right */ 54 | Right(JImDrawCornerFlags.Right), 55 | /** @see JImDrawCornerFlags#All */ 56 | All(JImDrawCornerFlags.All); 57 | public final int flag; 58 | 59 | Type(int flag) { 60 | this.flag = flag; 61 | } 62 | 63 | @Override public int get() { 64 | return flag; 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /core/src/org/ice1000/jimgui/flag/JImDrawListFlags.java: -------------------------------------------------------------------------------- 1 | package org.ice1000.jimgui.flag; 2 | 3 | /** 4 | * @author ice1000 5 | * @since v0.1 6 | */ 7 | public interface JImDrawListFlags { 8 | int Nothing = 0; 9 | int AntiAliasedLines = 1; 10 | int AntiAliasedFill = 1 << 1; 11 | 12 | enum Type implements Flag { 13 | /** 14 | * Used for reverse lookup results and enum comparison. 15 | * Return the Nothing or Default flag to prevent errors. 16 | */ 17 | NoSuchFlag(JImDrawListFlags.Nothing), Nothing(JImDrawListFlags.Nothing), 18 | /** @see JImDrawListFlags#AntiAliasedLines */ 19 | AntiAliasedLines(JImDrawListFlags.AntiAliasedLines), 20 | /** @see JImDrawListFlags#AntiAliasedFill */ 21 | AntiAliasedFill(JImDrawListFlags.AntiAliasedFill); 22 | public final int flag; 23 | 24 | Type(int flag) { 25 | this.flag = flag; 26 | } 27 | 28 | @Override public int get() { 29 | return flag; 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /core/src/org/ice1000/jimgui/flag/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * ImGui uses int flags by default. In addition to the FlagsClass.CONSTANTS 3 | * provided by each interface a library user will find FlagClass.Type which 4 | * are Enumerations that Implement the Flag interface and mirror the 5 | * FlagClass.CONSTANTS to allow for object oriented programming and human 6 | * readable reverse lookups which are useful for the developer to set 7 | * flags easier. Flags.class has some helper methods for flags and numbers. 8 | */ 9 | package org.ice1000.jimgui.flag; -------------------------------------------------------------------------------- /core/src/org/ice1000/jimgui/glfw/GlfwUtil.java: -------------------------------------------------------------------------------- 1 | package org.ice1000.jimgui.glfw; 2 | 3 | import org.ice1000.jimgui.JImGui; 4 | import org.jetbrains.annotations.NotNull; 5 | 6 | import static org.ice1000.jimgui.util.JImGuiUtil.getBytes; 7 | 8 | /** 9 | * Only work when using glfw 10 | * 11 | * @author ice1000 12 | * @since v0.5 13 | */ 14 | public class GlfwUtil { 15 | /** 16 | * Will not initialize GLFW 17 | * 18 | * @return newly created window pointer, 0 if it's not windows 19 | * @see org.ice1000.jimgui.JImGui#fromExistingPointer(long) 20 | */ 21 | public static long createWindowPointer() { 22 | return createWindowPointer(1280, 720, JImGui.DEFAULT_TITLE, 0); 23 | } 24 | 25 | /** 26 | * Will not initialize GLFW 27 | * 28 | * @param anotherWindow the pointer to the former-created window 29 | * @return newly created window pointer, 0 if it's not windows 30 | * @see org.ice1000.jimgui.JImGui#fromExistingPointer(long) 31 | */ 32 | public static long createWindowPointer(long anotherWindow) { 33 | return createWindowPointer(1280, 720, JImGui.DEFAULT_TITLE, anotherWindow); 34 | } 35 | 36 | /** 37 | * Will not initialize GLFW 38 | * 39 | * @param width window width 40 | * @param height window height 41 | * @return newly created window pointer, 0 if it's not windows 42 | * @see org.ice1000.jimgui.JImGui#fromExistingPointer(long) 43 | */ 44 | public static long createWindowPointer(int width, int height, @NotNull String title) { 45 | return createWindowPointer(width, height, title, 0); 46 | } 47 | 48 | /** 49 | * With another already created GLFW window 50 | * 51 | * @param anotherWindow the pointer to the former-created window 52 | * @param width window width 53 | * @param height window height 54 | * @return newly created window pointer, 0 if it's not windows 55 | * @see org.ice1000.jimgui.JImGui#fromExistingPointer(long) 56 | */ 57 | public static long createWindowPointer(int width, int height, @NotNull String title, long anotherWindow) { 58 | return createWindowPointer0(width, height, getBytes(title), anotherWindow); 59 | } 60 | 61 | private static native long createWindowPointer0(int w, int h, byte[] title, long anotherWindow); 62 | } 63 | -------------------------------------------------------------------------------- /core/src/org/ice1000/jimgui/util/ColorUtil.java: -------------------------------------------------------------------------------- 1 | package org.ice1000.jimgui.util; 2 | 3 | import org.jetbrains.annotations.Contract; 4 | 5 | /** 6 | * @author ice1000 7 | * @since v0.12 8 | */ 9 | public interface ColorUtil { 10 | int IM_COL32_R_SHIFT = 0; 11 | int IM_COL32_G_SHIFT = 8; 12 | int IM_COL32_B_SHIFT = 16; 13 | int IM_COL32_A_SHIFT = 24; 14 | int IM_COL32_A_MASK = 0xFF000000; 15 | @Contract(pure = true) static int colorU32(int red, int green, int blue, int alpha) { 16 | return alpha << IM_COL32_A_SHIFT | blue << IM_COL32_B_SHIFT | green << IM_COL32_G_SHIFT | red << IM_COL32_R_SHIFT; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /core/src/org/ice1000/jimgui/util/SharedState.java: -------------------------------------------------------------------------------- 1 | package org.ice1000.jimgui.util; 2 | 3 | import org.jetbrains.annotations.Contract; 4 | import org.jetbrains.annotations.Nullable; 5 | 6 | import java.nio.charset.StandardCharsets; 7 | import java.util.function.Function; 8 | 9 | /** 10 | * Private state shared in this package. 11 | * 12 | * @author ice1000 13 | * @since v0.12 14 | */ 15 | class SharedState { 16 | static boolean isLoaded = false; 17 | static @Nullable Function STRING_TO_BYTES = null; 18 | 19 | @Contract(value = "!null -> !null; null -> null", pure = true) 20 | static byte @Nullable [] getBytesDefaultImpl(@Nullable String text) { 21 | return text != null ? (text + '\0').getBytes(StandardCharsets.UTF_8) : null; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /core/test/org/ice1000/jimgui/features/ComboTest.java: -------------------------------------------------------------------------------- 1 | package org.ice1000.jimgui.features; 2 | 3 | import org.ice1000.jimgui.NativeInt; 4 | import org.ice1000.jimgui.util.JImGuiUtil; 5 | import org.ice1000.jimgui.util.JniLoader; 6 | import org.jetbrains.annotations.NotNull; 7 | import org.junit.BeforeClass; 8 | import org.junit.Test; 9 | 10 | import static org.ice1000.jimgui.tests.JImGuiTest.useAlternativeJniLibAndCheckHeadless; 11 | 12 | public class ComboTest { 13 | @BeforeClass public static void setup() { 14 | useAlternativeJniLibAndCheckHeadless(); 15 | } 16 | 17 | @Test public void testSandbox() { 18 | main(); 19 | } 20 | 21 | public static void main(String @NotNull ... args) { 22 | JniLoader.load(); 23 | final int totalMillis = 6000; 24 | NativeInt currentItem = new NativeInt(); 25 | JImGuiUtil.runWithinPer(totalMillis, 15, imGui -> { 26 | imGui.combo("Wtf", currentItem, "Java\0Kotlin\0Clojure\0Ceylon\0Scala\0"); 27 | imGui.text("Selected: " + currentItem); 28 | }); 29 | currentItem.deallocateNativeObject(); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /core/test/org/ice1000/jimgui/features/DateChooserTest.java: -------------------------------------------------------------------------------- 1 | package org.ice1000.jimgui.features; 2 | 3 | import org.ice1000.jimgui.JImGui; 4 | import org.ice1000.jimgui.NativeTime; 5 | import org.ice1000.jimgui.util.JImGuiUtil; 6 | import org.ice1000.jimgui.util.JniLoader; 7 | 8 | public class DateChooserTest { 9 | public static void main(String... args) { 10 | JniLoader.load(); 11 | JImGuiUtil.cacheStringToBytes(); 12 | try (JImGui imGui = new JImGui(); NativeTime time = new NativeTime()) { 13 | while (!imGui.windowShouldClose()) { 14 | imGui.initNewFrame(); 15 | imGui.text("Picked text: " + time.accessAbsoluteSeconds()); 16 | final long now = System.currentTimeMillis() / 1000; 17 | imGui.text("Current time text: " + now); 18 | if (imGui.button("Set to now")) time.modifyAbsoluteSeconds(now); 19 | if (imGui.dateChooser("Pick a time", time)) imGui.text("Text"); 20 | imGui.render(); 21 | } 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /core/test/org/ice1000/jimgui/features/FileDialogTest.java: -------------------------------------------------------------------------------- 1 | package org.ice1000.jimgui.features; 2 | 3 | import org.ice1000.jimgui.*; 4 | import org.ice1000.jimgui.flag.JImFDStyleFlags; 5 | import org.ice1000.jimgui.tests.Sandbox; 6 | import org.ice1000.jimgui.util.JniLoader; 7 | 8 | import java.awt.*; 9 | import java.util.ArrayList; 10 | import java.util.List; 11 | 12 | public class FileDialogTest { 13 | public static void main(String... args) { 14 | JniLoader.load(); 15 | List strings = new ArrayList<>(); 16 | try (JImGui imGui = new JImGui(); NativeBool modal = new NativeBool()) { 17 | imGui.getIO().getFonts().addFontDefault(); 18 | JImFileDialog.loadIcons(15); 19 | JImStr key = new JImStr("deep_dark_fantasy"); 20 | JImStr title = new JImStr(JImFileDialog.Icons.FOLDER_OPEN + " Choose a Java file"); 21 | JImStr filter = new JImStr(".md"); 22 | JImStr pwd = new JImStr("."); 23 | JImFileDialog instance = new JImFileDialog(); 24 | while (!imGui.windowShouldClose()) { 25 | imGui.initNewFrame(); 26 | imGui.checkbox("Use modal dialog", modal); 27 | instance.setFileStyle(JImFDStyleFlags.ByExtension, ".java", Sandbox.fromAWT(Color.ORANGE), "[Java]"); 28 | instance.setFileStyle(JImFDStyleFlags.ByExtension, ".md", Sandbox.fromAWT(Color.BLUE), JImFileDialog.Icons.FILE_PIC.toString()); 29 | if (imGui.button("Open dialog")) { 30 | if (modal.accessValue()) instance.openModal(key, title, filter, pwd, 2); 31 | else instance.openDialog(key, title, filter, pwd, 2); 32 | } 33 | if (instance.display(key)) { 34 | if (instance.isOk()) try (NativeString currentPath = instance.currentPath(); 35 | NativeStrings selectedFiles = instance.selections()) { 36 | imGui.text(currentPath); 37 | imGui.text("Size: " + selectedFiles.size()); 38 | if (!selectedFiles.isEmpty()) { 39 | for (NativeString string : strings) string.deallocateNativeObject(); 40 | strings.clear(); 41 | for (int i = 0, size = selectedFiles.size(); i < size; i++) strings.add(selectedFiles.get(i)); 42 | } 43 | } 44 | instance.close(); 45 | } 46 | imGui.text("Selections:"); 47 | for (NativeString string : strings) { 48 | imGui.text(string); 49 | imGui.sameLine(); 50 | imGui.text(", size = " + string.length()); 51 | } 52 | // instance.drawBookmarkPane(100, 100); 53 | imGui.render(); 54 | } 55 | instance.deallocateNativeObject(); 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /core/test/org/ice1000/jimgui/features/InputNativeString.java: -------------------------------------------------------------------------------- 1 | package org.ice1000.jimgui.features; 2 | 3 | import org.ice1000.jimgui.JImGui; 4 | import org.ice1000.jimgui.NativeString; 5 | import org.ice1000.jimgui.util.JniLoader; 6 | 7 | import java.nio.charset.StandardCharsets; 8 | import java.util.Arrays; 9 | 10 | public class InputNativeString { 11 | public static void main(String... args) { 12 | JniLoader.load(); 13 | try (NativeString s = new NativeString(); 14 | JImGui imGui = new JImGui()) { 15 | byte[] bytes = "não".getBytes(StandardCharsets.UTF_8); 16 | for (byte b : bytes) s.append(b); 17 | while (!imGui.windowShouldClose()) { 18 | imGui.initNewFrame(); 19 | imGui.inputText("input", s); 20 | imGui.text(s); 21 | imGui.text("Size: " + s.length()); 22 | final String str = s.toString(); 23 | imGui.text("Content: " + str); 24 | imGui.text("Content-Length: " + str.length()); 25 | imGui.text("Bytes: " + Arrays.toString(s.toBytes())); 26 | imGui.render(); 27 | } 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /core/test/org/ice1000/jimgui/features/InputTextTest.java: -------------------------------------------------------------------------------- 1 | package org.ice1000.jimgui.features; 2 | 3 | import org.ice1000.jimgui.*; 4 | import org.ice1000.jimgui.util.JImGuiUtil; 5 | import org.ice1000.jimgui.util.JniLoader; 6 | import org.junit.BeforeClass; 7 | 8 | import static org.ice1000.jimgui.tests.JImGuiTest.useAlternativeJniLibAndCheckHeadless; 9 | 10 | public class InputTextTest { 11 | @BeforeClass public static void setup() { 12 | useAlternativeJniLibAndCheckHeadless(); 13 | } 14 | 15 | public static void main(String... args) { 16 | JniLoader.load(); 17 | JImGuiUtil.cacheStringToBytes(); 18 | try (JImGui imGui = new JImGui(); 19 | NativeString multiline = new NativeString(); 20 | NativeFloat width = new NativeFloat(); 21 | NativeFloat height = new NativeFloat(); 22 | NativeBool bool = new NativeBool(); 23 | NativeString withHint = new NativeString()) { 24 | width.modifyValue(300); 25 | height.modifyValue(200); 26 | try (JImFontConfig config = new JImFontConfig()) { 27 | JImFontAtlas fontAtlas = imGui.getIO().getFonts(); 28 | fontAtlas.clearFonts(); 29 | config.setSizePixels(26); 30 | fontAtlas.addDefaultFont(config); 31 | } 32 | imGui.getStyle().scaleAllSizes(2); 33 | while (!imGui.windowShouldClose()) { 34 | imGui.initNewFrame(); 35 | imGui.sliderFloat("Width", width, 100, 500); 36 | imGui.sliderFloat("Height", height, 100, 300); 37 | bool.modifyValue(imGui.inputTextMultiline("InputTextMultiline", 38 | multiline, 39 | width.accessValue(), 40 | height.accessValue())); 41 | imGui.checkbox("Return value of InputTextMultiline", bool); 42 | imGui.text("Text length: " + multiline.length()); 43 | if (multiline.length() != 0) { 44 | imGui.text("First char: " + multiline.charAt(0)); 45 | if (imGui.button("Upshift the first character")) multiline.setByteAt(0, (byte) (multiline.byteAt(0) + 1)); 46 | if (imGui.button("Downshift the first character")) multiline.setByteAt(0, (byte) (multiline.byteAt(0) - 1)); 47 | } 48 | if (imGui.button("Clear multiline text")) multiline.clear(); 49 | imGui.inputTextWithHint("InputTextWithHint", "This is the hint", withHint); 50 | imGui.render(); 51 | } 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /core/test/org/ice1000/jimgui/features/NativeStringTest.java: -------------------------------------------------------------------------------- 1 | package org.ice1000.jimgui.features; 2 | 3 | import org.ice1000.jimgui.NativeString; 4 | import org.ice1000.jimgui.util.JniLoader; 5 | import org.junit.BeforeClass; 6 | import org.junit.Test; 7 | 8 | import static org.ice1000.jimgui.util.JImGuiUtil.EMPTY_BYTES; 9 | import static org.junit.Assert.*; 10 | 11 | public class NativeStringTest { 12 | @BeforeClass public static void setup() { 13 | JniLoader.load(); 14 | } 15 | 16 | @Test public void sizeIs0() { 17 | NativeString string = new NativeString(); 18 | assertEquals(0, string.length()); 19 | assertArrayEquals(EMPTY_BYTES, string.toBytes()); 20 | string.deallocateNativeObject(); 21 | } 22 | 23 | @Test public void appendOneChar() { 24 | NativeString string = new NativeString(); 25 | string.append('A'); 26 | assertEquals(1, string.length()); 27 | assertEquals('A', string.charAt(0)); 28 | assertEquals("A", string.toString()); 29 | string.deallocateNativeObject(); 30 | } 31 | 32 | @Test public void modifyOneChar() { 33 | NativeString string = new NativeString(); 34 | string.append('A'); 35 | assertEquals(1, string.length()); 36 | assertEquals('A', string.charAt(0)); 37 | string.setCharAt(0, 'B'); 38 | assertEquals('B', string.charAt(0)); 39 | string.deallocateNativeObject(); 40 | } 41 | 42 | @Test public void clearText() { 43 | NativeString string = new NativeString(); 44 | string.append('A'); 45 | assertEquals(1, string.length()); 46 | assertEquals('A', string.charAt(0)); 47 | string.clear(); 48 | assertEquals(0, string.length()); 49 | string.deallocateNativeObject(); 50 | } 51 | 52 | @Test public void appendTwoChars() { 53 | NativeString string = new NativeString(); 54 | string.append('X'); 55 | string.append('Y'); 56 | assertEquals(2, string.length()); 57 | assertEquals('X', string.charAt(0)); 58 | assertEquals('Y', string.charAt(1)); 59 | assertEquals("XY", string.toString()); 60 | NativeString subSequence01 = string.subSequence(0, 1); 61 | assertEquals("X", subSequence01.toString()); 62 | NativeString subSequence12 = string.subSequence(1, 2); 63 | assertEquals("Y", subSequence12.toString()); 64 | subSequence01.deallocateNativeObject(); 65 | subSequence12.deallocateNativeObject(); 66 | string.deallocateNativeObject(); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /core/test/org/ice1000/jimgui/features/ProgressBarTest.java: -------------------------------------------------------------------------------- 1 | package org.ice1000.jimgui.features; 2 | 3 | import org.ice1000.jimgui.util.JImGuiUtil; 4 | import org.ice1000.jimgui.util.JniLoader; 5 | import org.jetbrains.annotations.NotNull; 6 | import org.junit.BeforeClass; 7 | import org.junit.Test; 8 | 9 | import static org.ice1000.jimgui.tests.JImGuiTest.useAlternativeJniLibAndCheckHeadless; 10 | 11 | public class ProgressBarTest { 12 | @BeforeClass public static void setup() { 13 | useAlternativeJniLibAndCheckHeadless(); 14 | } 15 | 16 | @Test public void testSandbox() { 17 | main(); 18 | } 19 | 20 | public static void main(String @NotNull ... args) { 21 | JniLoader.load(); 22 | final long start = System.currentTimeMillis(); 23 | final int totalMillis = 3000; 24 | JImGuiUtil.runWithinPer(totalMillis, 15, imGui -> { 25 | imGui.text("IntelliJ IDEA is booting..."); 26 | imGui.progressBar((System.currentTimeMillis() - start) / (float) totalMillis); 27 | imGui.text("ICEditor is booting..."); 28 | imGui.progressBar(2 * (System.currentTimeMillis() - start) / (float) totalMillis); 29 | }); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /core/test/org/ice1000/jimgui/features/SetWindowTitle.java: -------------------------------------------------------------------------------- 1 | package org.ice1000.jimgui.features; 2 | 3 | import org.ice1000.jimgui.NativeString; 4 | import org.ice1000.jimgui.util.JImGuiUtil; 5 | import org.ice1000.jimgui.util.JniLoader; 6 | import org.junit.BeforeClass; 7 | import org.junit.Test; 8 | 9 | import static org.ice1000.jimgui.tests.JImGuiTest.useAlternativeJniLibAndCheckHeadless; 10 | 11 | public class SetWindowTitle { 12 | @BeforeClass public static void setup() { 13 | useAlternativeJniLibAndCheckHeadless(); 14 | } 15 | @Test public void test() { 16 | main(); 17 | } 18 | 19 | public static void main(String... args) { 20 | JniLoader.load(); 21 | NativeString string = new NativeString(); 22 | JImGuiUtil.runWithinPer(6000, 15, imgui -> { 23 | if (imgui.button("Hey Jude")) imgui.setWindowTitle("Don't make it bad"); 24 | imgui.inputText("Sally can wait", string); 25 | if (imgui.button("She knows it's too late")) imgui.setWindowTitle(string); 26 | }); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /core/test/org/ice1000/jimgui/features/Tables.java: -------------------------------------------------------------------------------- 1 | package org.ice1000.jimgui.features; 2 | 3 | import org.ice1000.jimgui.flag.JImTableFlags; 4 | import org.ice1000.jimgui.util.JImGuiUtil; 5 | import org.ice1000.jimgui.util.JniLoader; 6 | import org.junit.BeforeClass; 7 | import org.junit.Test; 8 | 9 | import static org.ice1000.jimgui.tests.JImGuiTest.useAlternativeJniLibAndCheckHeadless; 10 | 11 | public class Tables { 12 | @BeforeClass public static void setup() { 13 | useAlternativeJniLibAndCheckHeadless(); 14 | } 15 | 16 | @Test public void testSandbox() { 17 | main(); 18 | } 19 | 20 | public static void main(String... args) { 21 | JniLoader.load(); 22 | JImGuiUtil.runWithinPer(114514, 15, imGui -> { 23 | if (imGui.beginTable("Table1", 2, JImTableFlags.Borders | JImTableFlags.Resizable | JImTableFlags.Reorderable)) { 24 | imGui.tableNextRow(); 25 | imGui.tableNextColumn(); 26 | imGui.text("Upper Left"); 27 | imGui.tableNextColumn(); 28 | imGui.text("Upper Right"); 29 | imGui.tableNextColumn(); 30 | imGui.text("Lower Left"); 31 | imGui.tableNextColumn(); 32 | imGui.text("Lower Right"); 33 | imGui.endTable(); 34 | } 35 | }); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /core/test/org/ice1000/jimgui/features/ToggleButtonTest.java: -------------------------------------------------------------------------------- 1 | package org.ice1000.jimgui.features; 2 | 3 | import org.ice1000.jimgui.JImStr; 4 | import org.ice1000.jimgui.JImVec4; 5 | import org.ice1000.jimgui.NativeBool; 6 | import org.ice1000.jimgui.tests.Sandbox; 7 | import org.ice1000.jimgui.util.JImGuiUtil; 8 | import org.ice1000.jimgui.util.JniLoader; 9 | import org.junit.BeforeClass; 10 | import org.junit.Test; 11 | 12 | import java.awt.*; 13 | 14 | import static org.ice1000.jimgui.tests.JImGuiTest.useAlternativeJniLibAndCheckHeadless; 15 | 16 | public class ToggleButtonTest { 17 | @BeforeClass public static void setup() { 18 | useAlternativeJniLibAndCheckHeadless(); 19 | } 20 | 21 | @Test public void testSandbox() { 22 | main(); 23 | } 24 | 25 | public static void main(String... args) { 26 | JniLoader.load(); 27 | final int totalMillis = 8000; 28 | NativeBool pOpen = new NativeBool(); 29 | JImStr ok = new JImStr("Checked"); 30 | JImStr not = new JImStr("Unchecked"); 31 | JImVec4 color = Sandbox.fromAWT(Color.GREEN); 32 | pOpen.modifyValue(false); 33 | JImGuiUtil.runWithinPer(totalMillis, 15, imGui -> { 34 | imGui.spinner(80, 10, 10, color); 35 | imGui.toggleButton("my_id", pOpen); 36 | imGui.text(pOpen.accessValue() ? ok : not); 37 | }); 38 | pOpen.deallocateNativeObject(); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /core/test/org/ice1000/jimgui/flag/FlagTest.java: -------------------------------------------------------------------------------- 1 | package org.ice1000.jimgui.flag; 2 | 3 | import org.junit.Test; 4 | 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | 8 | import static org.junit.Assert.assertEquals; 9 | import static org.junit.Assert.assertTrue; 10 | 11 | public class FlagTest { 12 | @Test public void hasFlag() { 13 | assertTrue(Flag.hasFlag(2, JImColorEditFlags.Type.NoAlpha, JImColorEditFlags.Type.NoPicker)); 14 | } 15 | 16 | @Test public void reverseLookup() { 17 | assertEquals(JImColorEditFlags.Type.NoAlpha, Flag.reverseLookup(JImColorEditFlags.Type.class, 2)); 18 | } 19 | 20 | @Test public void getAsFlags() { 21 | List flags = new ArrayList<>(2); 22 | flags.add(JImColorEditFlags.Type.NoAlpha); 23 | flags.add(JImColorEditFlags.Type.NoPicker); 24 | JImColorEditFlags.Type[] asFlags = Flag.getAsFlags(JImColorEditFlags.Type.class, 6); 25 | for (int i = 0; i < asFlags.length; i++) { 26 | JImColorEditFlags.Type asFlag = asFlags[i]; 27 | assertTrue(flags.contains(asFlag)); 28 | } 29 | } 30 | 31 | @Test public void getFlagsValue() { 32 | assertEquals(6, Flag.getAsValue(JImColorEditFlags.Type.NoAlpha, JImColorEditFlags.Type.NoPicker)); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /core/test/org/ice1000/jimgui/tests/EditorTest.java: -------------------------------------------------------------------------------- 1 | package org.ice1000.jimgui.tests; 2 | 3 | import org.ice1000.jimgui.*; 4 | import org.ice1000.jimgui.util.JniLoader; 5 | import org.jetbrains.annotations.NotNull; 6 | 7 | import java.net.URISyntaxException; 8 | 9 | public class EditorTest { 10 | public static final int LIMIT = 3; 11 | 12 | @SuppressWarnings("AccessStaticViaInstance") 13 | public static void main(String @NotNull ... args) throws InterruptedException, URISyntaxException { 14 | JniLoader.load(); 15 | StringBuilder builder = new StringBuilder("输入一些文本"); 16 | int cursor = builder.length(); 17 | try (JImGui gui = new JImGui()) { 18 | JImGuiIO io = gui.getIO(); 19 | JImFontAtlas fonts = io.getFonts(); 20 | // String fontPath = EditorTest.class.getResource("/font/sarasa-gothic-sc-regular.ttf").toURI().getPath(); 21 | int texHeight = 20; 22 | // JImFont sarasaGothic = fonts.addFontFromFile(fontPath, 23 | // texHeight, 24 | // fonts.getGlyphRangesForChineseSimplifiedCommon()); 25 | System.out.println(texHeight); 26 | long lastMovedTime = 0; 27 | JImStyle style = gui.getStyle(); 28 | style.setItemSpacingX(2f); 29 | while (!gui.windowShouldClose()) { 30 | // long deltaTime = (long) (io.getDeltaTime() * 1000); 31 | // Thread.sleep(LIMIT - deltaTime < 0 ? 0 : (LIMIT - deltaTime)); 32 | gui.initNewFrame(); 33 | char[] inputString = io.getInputChars(); 34 | io.clearInputCharacters(); 35 | builder.insert(cursor, inputString); 36 | cursor += inputString.length; 37 | if (gui.isKeyPressed(io.keyMapAt(JImDefaultKeys.LeftArrow)) && cursor > 0) { 38 | lastMovedTime = System.currentTimeMillis(); 39 | cursor--; 40 | } 41 | if (gui.isKeyPressed(io.keyMapAt(JImDefaultKeys.RightArrow)) && cursor < builder.length()) { 42 | lastMovedTime = System.currentTimeMillis(); 43 | cursor++; 44 | } 45 | if (gui.isKeyPressed(io.keyMapAt(JImDefaultKeys.Enter))) builder.insert(cursor++, '\n'); 46 | if (gui.isKeyPressed(io.keyMapAt(JImDefaultKeys.Backspace)) && cursor > 0) builder.deleteCharAt(--cursor); 47 | gui.begin("Editor"); 48 | int length = builder.length(); 49 | for (int i = 0; i <= length; i++) { 50 | if (i == cursor && ((System.currentTimeMillis() - lastMovedTime) / 500) % 2 == 0) { 51 | float cursorPosX = gui.getCursorPosX() + gui.getWindowPosX() - 1; 52 | float cursorPosY = gui.getCursorPosY() + gui.getWindowPosY(); 53 | gui.windowDrawListAddLine(cursorPosX, cursorPosY, cursorPosX, cursorPosY + texHeight, 0xffffffff, 1.5f); 54 | } 55 | if (i == length) break; 56 | char c = builder.charAt(i); 57 | if (c != '\n') { 58 | gui.text(String.valueOf(c)); 59 | gui.sameLine(); 60 | } else gui.newLine(); 61 | } 62 | gui.end(); 63 | gui.render(); 64 | } 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /core/test/org/ice1000/jimgui/tests/Issue14.java: -------------------------------------------------------------------------------- 1 | package org.ice1000.jimgui.tests; 2 | 3 | import org.ice1000.jimgui.JImFont; 4 | import org.ice1000.jimgui.JImFontAtlas; 5 | import org.ice1000.jimgui.JImGui; 6 | import org.ice1000.jimgui.NativeFloat; 7 | import org.ice1000.jimgui.util.JniLoader; 8 | 9 | import java.net.URISyntaxException; 10 | 11 | public class Issue14 { 12 | public static void main(String... args) throws InterruptedException, URISyntaxException { 13 | JniLoader.load(); 14 | long initialTime = System.currentTimeMillis(); 15 | try (NativeFloat fontSize = new NativeFloat(); JImGui imGui = new JImGui()) { 16 | fontSize.modifyValue(18); 17 | JImFontAtlas fonts = imGui.getIO().getFonts(); 18 | //fonts.addFontDefault(); 19 | JImFont fontFromFile = fonts.addFontFromFile(Issue14.class.getResource("/font/sarasa-gothic-sc-regular.ttf") 20 | .toURI() 21 | .getPath(), 18, fonts.getGlyphRangesForChineseSimplifiedCommon()); 22 | long latestRefresh = System.currentTimeMillis(); 23 | while (!imGui.windowShouldClose()) { 24 | long currentTimeMillis = System.currentTimeMillis(); 25 | //if (currentTimeMillis - initialTime > 8000) break; 26 | long deltaTime = currentTimeMillis - latestRefresh; 27 | Thread.sleep(deltaTime / 2); 28 | if (deltaTime > (long) 15) { 29 | imGui.initNewFrame(); 30 | JImFont font = imGui.findFont(); 31 | if (font != null) { 32 | font.setFontSize(fontSize.accessValue()); 33 | imGui.text("卧槽" + "哈哈"); 34 | } else imGui.text("Not found"); 35 | imGui.dragFloat("Font size", fontSize); 36 | imGui.showFontSelector("Wtf"); 37 | //imGui.showStyleSelector("asd"); 38 | imGui.render(); 39 | latestRefresh = currentTimeMillis; 40 | } 41 | } 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /core/test/org/ice1000/jimgui/tests/Issue52.java: -------------------------------------------------------------------------------- 1 | package org.ice1000.jimgui.tests; 2 | 3 | import org.ice1000.jimgui.NativeFloat; 4 | import org.ice1000.jimgui.NativeInt; 5 | import org.ice1000.jimgui.util.JImGuiUtil; 6 | import org.ice1000.jimgui.util.JniLoader; 7 | import org.jetbrains.annotations.NotNull; 8 | import org.junit.BeforeClass; 9 | import org.junit.Test; 10 | 11 | import static org.ice1000.jimgui.tests.JImGuiTest.useAlternativeJniLibAndCheckHeadless; 12 | 13 | public class Issue52 { 14 | @BeforeClass public static void setup() { 15 | useAlternativeJniLibAndCheckHeadless(); 16 | } 17 | 18 | @Test public void testSandbox() { 19 | main(); 20 | } 21 | 22 | public static void main(String @NotNull ... args) { 23 | JniLoader.load(); 24 | final int totalMillis = 1006000; 25 | NativeInt nativeInt = new NativeInt(); 26 | NativeFloat nativeFloat = new NativeFloat(); 27 | nativeInt.modifyValue(20); 28 | nativeFloat.modifyValue(40); 29 | JImGuiUtil.runWithinPer(totalMillis, 15, imGui -> { 30 | imGui.sliderInt("TIZ", nativeInt, 0, 100); 31 | imGui.sliderFloat("TCL", nativeFloat, 0, 100); 32 | imGui.text("Int: " + nativeInt); 33 | imGui.text("Float: " + nativeFloat); 34 | }); 35 | nativeInt.deallocateNativeObject(); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /core/test/org/ice1000/jimgui/tests/Issue66.java: -------------------------------------------------------------------------------- 1 | package org.ice1000.jimgui.tests; 2 | 3 | import org.ice1000.jimgui.JImGui; 4 | import org.ice1000.jimgui.NativeBool; 5 | import org.ice1000.jimgui.util.JImGuiUtil; 6 | import org.ice1000.jimgui.util.JniLoader; 7 | 8 | public class Issue66 { 9 | public static void main(String[] args) { 10 | JniLoader.load(); 11 | JImGuiUtil.cacheStringToBytes(); 12 | try (JImGui imgui = new JImGui(); NativeBool bool = new NativeBool()) { 13 | byte[] b = new byte[100]; 14 | while (!imgui.windowShouldClose()) { 15 | imgui.initNewFrame(); 16 | imgui.checkbox("Check to test input, uncheck to test ID", bool); 17 | if (imgui.button("System.gc()")) System.gc(); 18 | for (int i = 0; i < 150; i++) { 19 | if (bool.accessValue()) { 20 | imgui.inputText("Label " + i, b); 21 | } else { 22 | imgui.pushID("btn" + i); 23 | imgui.button("OK"); 24 | imgui.popID(); 25 | } 26 | } 27 | imgui.render(); 28 | } 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /core/test/org/ice1000/jimgui/tests/JImDrawListTest.java: -------------------------------------------------------------------------------- 1 | package org.ice1000.jimgui.tests; 2 | 3 | import org.ice1000.jimgui.JImDrawList; 4 | import org.ice1000.jimgui.util.JImGuiUtil; 5 | import org.ice1000.jimgui.util.JniLoader; 6 | import org.jetbrains.annotations.NotNull; 7 | import org.junit.BeforeClass; 8 | import org.junit.Test; 9 | 10 | import java.awt.*; 11 | 12 | import static org.ice1000.jimgui.tests.JImGuiTest.useAlternativeJniLibAndCheckHeadless; 13 | import static org.junit.Assert.*; 14 | 15 | public class JImDrawListTest { 16 | @BeforeClass public static void setup() { 17 | useAlternativeJniLibAndCheckHeadless(); 18 | } 19 | 20 | @Test public void testSandbox() { 21 | main(); 22 | } 23 | 24 | @SuppressWarnings("AccessStaticViaInstance") public static void main(@NotNull String @NotNull ... args) { 25 | JniLoader.load(); 26 | JImGuiUtil.runWithinPer(5000, 15, imGui -> { 27 | JImDrawList windowDrawList = imGui.findWindowDrawList(); 28 | assertNotNull(windowDrawList); 29 | JImDrawList overlayDrawList = imGui.findForegroundDrawList(); 30 | assertNotNull(overlayDrawList); 31 | float cursorPosX = imGui.getWindowPosX(); 32 | float cursorPosY = imGui.getWindowPosY(); 33 | windowDrawList.addText(30, 34 | cursorPosX + 122, 35 | cursorPosY + 22, 36 | Color.BLUE.getRGB(), 37 | "I XiHuan Reiuji Utsuho forever\nQAQ"); 38 | int rgb = Color.GREEN.getRGB(); 39 | windowDrawList.addCircle(cursorPosX + 250, cursorPosY + 150, 50, rgb, 100); 40 | windowDrawList.addText(72, cursorPosX + 230, cursorPosY + 120, rgb, "6"); 41 | }); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /core/test/org/ice1000/jimgui/tests/JImFontTest.java: -------------------------------------------------------------------------------- 1 | package org.ice1000.jimgui.tests; 2 | 3 | import org.ice1000.jimgui.*; 4 | import org.ice1000.jimgui.util.JniLoader; 5 | import org.jetbrains.annotations.NotNull; 6 | import org.junit.BeforeClass; 7 | import org.junit.Test; 8 | 9 | import static org.ice1000.jimgui.tests.JImGuiTest.useAlternativeJniLibAndCheckHeadless; 10 | 11 | public class JImFontTest { 12 | @BeforeClass public static void setup() { 13 | useAlternativeJniLibAndCheckHeadless(); 14 | } 15 | 16 | @Test public void testSandbox() throws InterruptedException { 17 | main(); 18 | } 19 | 20 | public static void main(String @NotNull ... args) throws InterruptedException { 21 | JniLoader.load(); 22 | long initialTime = System.currentTimeMillis(); 23 | try (NativeFloat fontSize = new NativeFloat(); JImGui imGui = new JImGui()) { 24 | fontSize.modifyValue(18); 25 | JImFontAtlas fonts = imGui.getIO().getFonts(); 26 | fonts.addFontDefault(); 27 | JImFont fontFromFile = fonts.addFontFromFile("core/testRes/font/FiraCode-Regular.ttf", 18); 28 | if (fontFromFile.isLoaded()) System.out.println(fontFromFile.debugName()); 29 | long latestRefresh = System.currentTimeMillis(); 30 | while (!imGui.windowShouldClose()) { 31 | long currentTimeMillis = System.currentTimeMillis(); 32 | if (currentTimeMillis - initialTime > 8000) break; 33 | long deltaTime = currentTimeMillis - latestRefresh; 34 | if (deltaTime > (long) 15) { 35 | imGui.initNewFrame(); 36 | JImFont font = imGui.findFont(); 37 | if (font != null) { 38 | font.setFontSize(fontSize.accessValue()); 39 | final NativeString string = font.debugName(); 40 | if (string.isNull()) imGui.text("Dunno"); 41 | else imGui.text(string); 42 | } else imGui.text("Not found"); 43 | imGui.dragFloat("Font size", fontSize); 44 | imGui.showFontSelector("Wtf"); 45 | imGui.pushFont(imGui.getIO().getFontDefault()); 46 | imGui.text("Default font"); 47 | imGui.popFont(); 48 | imGui.pushFont(fontFromFile); 49 | imGui.text("FiraCode font"); 50 | imGui.popFont(); 51 | imGui.render(); 52 | latestRefresh = currentTimeMillis; 53 | } 54 | } 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /core/test/org/ice1000/jimgui/tests/JImGuiTest.java: -------------------------------------------------------------------------------- 1 | package org.ice1000.jimgui.tests; 2 | 3 | import org.ice1000.jimgui.JImGui; 4 | import org.ice1000.jimgui.JImGuiIO; 5 | import org.ice1000.jimgui.flag.JImMouseButton; 6 | import org.ice1000.jimgui.util.JImGuiUtil; 7 | import org.ice1000.jimgui.util.JniLoader; 8 | import org.jetbrains.annotations.NotNull; 9 | import org.jetbrains.annotations.TestOnly; 10 | import org.junit.BeforeClass; 11 | import org.junit.Test; 12 | 13 | import java.lang.reflect.Field; 14 | 15 | import static org.junit.Assert.assertTrue; 16 | import static org.junit.Assume.assumeFalse; 17 | 18 | public class JImGuiTest { 19 | @BeforeClass @TestOnly public static void useAlternativeJniLibAndCheckHeadless() { 20 | assumeFalse("true".equalsIgnoreCase(System.getenv("CI"))); 21 | assumeFalse("true".equalsIgnoreCase(System.getenv("APPVEYOR"))); 22 | assumeFalse("true".equalsIgnoreCase(System.getProperty("java.awt.headless"))); 23 | JniLoader.load(); 24 | } 25 | 26 | @Test public void jniInitialization() throws @NotNull NoSuchFieldException, @NotNull IllegalAccessException { 27 | try (JImGui imGui = new JImGui()) { 28 | Field nativeObjectPtr = JImGui.class.getDeclaredField("nativeObjectPtr"); 29 | nativeObjectPtr.setAccessible(true); 30 | assertTrue((long) nativeObjectPtr.get(imGui) != 0); 31 | nativeObjectPtr.setAccessible(false); 32 | } 33 | } 34 | 35 | @Test(expected = IllegalStateException.class) public void jniDisposal() { 36 | JImGui imGui = new JImGui(); 37 | imGui.close(); 38 | assertTrue(imGui.isDisposed()); 39 | JImGuiIO io = imGui.getIO(); 40 | System.out.println(io); 41 | } 42 | 43 | public static void main(String @NotNull ... args) { 44 | JniLoader.load(); 45 | JImGuiUtil.runPer(15, imGui -> { 46 | if (imGui.isMouseClicked(JImMouseButton.Left)) imGui.text("Mouse clicked!"); 47 | imGui.text(imGui.getClipboardText()); 48 | }); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /core/test/org/ice1000/jimgui/tests/JImStyleVarTest.java: -------------------------------------------------------------------------------- 1 | package org.ice1000.jimgui.tests; 2 | 3 | import org.ice1000.jimgui.JImStyleVars; 4 | import org.ice1000.jimgui.util.JImGuiUtil; 5 | import org.ice1000.jimgui.util.JniLoader; 6 | import org.jetbrains.annotations.NotNull; 7 | import org.junit.BeforeClass; 8 | import org.junit.Test; 9 | 10 | import static org.ice1000.jimgui.tests.JImGuiTest.useAlternativeJniLibAndCheckHeadless; 11 | import static org.junit.Assert.assertNotNull; 12 | 13 | public class JImStyleVarTest { 14 | @BeforeClass public static void setup() { 15 | useAlternativeJniLibAndCheckHeadless(); 16 | } 17 | 18 | @Test public void testSandbox() { 19 | main(); 20 | } 21 | 22 | public static void main(@NotNull String @NotNull ... args) { 23 | JniLoader.load(); 24 | JImGuiUtil.runWithinPer(2000, 15, imGui -> { 25 | imGui.pushStyleVar(JImStyleVars.WindowMinSize, 300, 300); 26 | imGui.pushStyleVar(JImStyleVars.Alpha, 0.5f); 27 | imGui.begin("What =_=?"); 28 | if (imGui.button("I love Reiuji Utsuho forever QAQ")) imGui.text("Don't touch me there! >_<"); 29 | imGui.end(); 30 | imGui.popStyleVar(2); 31 | assertNotNull(imGui.findStyle()); 32 | }); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /core/test/org/ice1000/jimgui/tests/JImTextureTest.java: -------------------------------------------------------------------------------- 1 | package org.ice1000.jimgui.tests; 2 | 3 | import org.ice1000.jimgui.JImGui; 4 | import org.ice1000.jimgui.JImTextureID; 5 | import org.ice1000.jimgui.util.JniLoader; 6 | import org.jetbrains.annotations.NotNull; 7 | import org.junit.BeforeClass; 8 | import org.junit.Test; 9 | 10 | import java.net.URISyntaxException; 11 | 12 | import static org.ice1000.jimgui.tests.JImGuiTest.useAlternativeJniLibAndCheckHeadless; 13 | 14 | public class JImTextureTest { 15 | @BeforeClass public static void setup() { 16 | useAlternativeJniLibAndCheckHeadless(); 17 | } 18 | 19 | @Test public void testSandbox() throws InterruptedException, URISyntaxException { 20 | main(); 21 | } 22 | 23 | @SuppressWarnings("AccessStaticViaInstance") 24 | public static void main(String @NotNull ... args) throws InterruptedException, URISyntaxException { 25 | JniLoader.load(); 26 | try (JImGui imGui = new JImGui()) { 27 | long latestRefresh = System.currentTimeMillis(); 28 | long end = System.currentTimeMillis() + (long) 3000; 29 | JImTextureID texture = JImTextureID.fromUri(JImTextureTest.class.getResource("/pics/ice1000.png").toURI()); 30 | while (!imGui.windowShouldClose() && System.currentTimeMillis() < end) { 31 | long currentTimeMillis = System.currentTimeMillis(); 32 | long deltaTime = currentTimeMillis - latestRefresh; 33 | Thread.sleep(deltaTime * 2 / 3); 34 | if (deltaTime > (long) 16) { 35 | imGui.initNewFrame(); 36 | if (end - System.currentTimeMillis() > 1500) imGui.image(texture, texture.width, texture.height); 37 | else imGui.image(texture, imGui.getWindowWidth(), imGui.getWindowHeight()); 38 | imGui.render(); 39 | latestRefresh = currentTimeMillis; 40 | } 41 | } 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /core/test/org/ice1000/jimgui/tests/JImVec4Test.java: -------------------------------------------------------------------------------- 1 | package org.ice1000.jimgui.tests; 2 | 3 | import org.ice1000.jimgui.JImVec4; 4 | import org.ice1000.jimgui.util.JniLoader; 5 | import org.junit.AfterClass; 6 | import org.junit.BeforeClass; 7 | import org.junit.Test; 8 | 9 | import static org.ice1000.jimgui.tests.JImGuiTest.useAlternativeJniLibAndCheckHeadless; 10 | import static org.junit.Assert.assertEquals; 11 | 12 | public class JImVec4Test { 13 | private static float randX; 14 | private static float randY; 15 | private static float randZ; 16 | private static float randW; 17 | private static JImVec4 vec1; 18 | private static JImVec4 vec2; 19 | 20 | @BeforeClass public static void loadJni() { 21 | JniLoader.load(); 22 | randX = (float) Math.random(); 23 | randY = (float) Math.random(); 24 | randZ = (float) Math.random(); 25 | randW = (float) Math.random(); 26 | vec1 = new JImVec4(); 27 | vec2 = new JImVec4(randX, randY, randZ, randW); 28 | } 29 | 30 | @Test public void getW() { 31 | assertEquals(randW, vec2.getW(), 0.0001f); 32 | assertEquals(0, vec1.getW(), 0.0001f); 33 | } 34 | 35 | @Test public void getX() { 36 | assertEquals(randX, vec2.getX(), 0.0001f); 37 | assertEquals(0, vec1.getX(), 0.0001f); 38 | } 39 | 40 | @Test public void getY() { 41 | assertEquals(randY, vec2.getY(), 0.0001f); 42 | assertEquals(0, vec1.getY(), 0.0001f); 43 | } 44 | 45 | @Test public void getZ() { 46 | assertEquals(randZ, vec2.getZ(), 0.0001f); 47 | assertEquals(0, vec1.getZ(), 0.0001f); 48 | } 49 | 50 | @AfterClass public static void deallocate() { 51 | if (vec1 != null) { 52 | vec1.close(); 53 | vec2.close(); 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /core/test/org/ice1000/jimgui/tests/MultiWindowTest.java: -------------------------------------------------------------------------------- 1 | package org.ice1000.jimgui.tests; 2 | 3 | import org.ice1000.jimgui.JImGui; 4 | import org.ice1000.jimgui.glfw.GlfwUtil; 5 | import org.ice1000.jimgui.util.JniLoader; 6 | import org.jetbrains.annotations.NotNull; 7 | import org.junit.BeforeClass; 8 | import org.junit.Test; 9 | 10 | import java.lang.reflect.Field; 11 | 12 | import static org.ice1000.jimgui.tests.JImGuiTest.useAlternativeJniLibAndCheckHeadless; 13 | import static org.junit.Assume.assumeTrue; 14 | 15 | public class MultiWindowTest { 16 | @BeforeClass public static void setup() { 17 | useAlternativeJniLibAndCheckHeadless(); 18 | assumeTrue(JniLoader.OS.Current == JniLoader.OS.Linux || JniLoader.OS.Current == JniLoader.OS.MacOS); 19 | } 20 | 21 | @Test public void testSandbox() throws @NotNull NoSuchFieldException, @NotNull IllegalAccessException { 22 | main(); 23 | } 24 | 25 | public static void main(String @NotNull ... args) throws @NotNull NoSuchFieldException, @NotNull IllegalAccessException { 26 | JniLoader.load(); 27 | JImGui gui = new JImGui(); 28 | Field declaredField = JImGui.class.getDeclaredField("nativeObjectPtr"); 29 | declaredField.setAccessible(true); 30 | long nativeObjectPtr = (Long) declaredField.get(gui); 31 | JImGui gui1 = JImGui.fromExistingPointer(GlfwUtil.createWindowPointer(500, 500, "Hello World", nativeObjectPtr)); 32 | while (!gui.windowShouldClose() || !gui1.windowShouldClose()) { 33 | gui.initNewFrame(); 34 | gui.text("This is gui"); 35 | gui.render(); 36 | gui1.initNewFrame(); 37 | gui1.text("This is gui1"); 38 | gui1.render(); 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /core/test/org/ice1000/jimgui/tests/MutableJImVec4Test.java: -------------------------------------------------------------------------------- 1 | package org.ice1000.jimgui.tests; 2 | 3 | import org.ice1000.jimgui.MutableJImVec4; 4 | import org.ice1000.jimgui.util.JniLoader; 5 | import org.junit.AfterClass; 6 | import org.junit.BeforeClass; 7 | import org.junit.Test; 8 | 9 | import static org.ice1000.jimgui.tests.JImGuiTest.useAlternativeJniLibAndCheckHeadless; 10 | import static org.junit.Assert.assertEquals; 11 | 12 | public class MutableJImVec4Test { 13 | private static MutableJImVec4 vec; 14 | private static MutableJImVec4 vec2; 15 | 16 | @BeforeClass public static void loadJni() { 17 | JniLoader.load(); 18 | vec = new MutableJImVec4(); 19 | vec2 = new MutableJImVec4(0, 0, 0, 0); 20 | } 21 | 22 | @Test public void setW() { 23 | assertEquals(0, vec.getW(), 0.00001f); 24 | float newValue = (float) Math.random(); 25 | vec.setW(newValue); 26 | assertEquals(newValue, vec.getW(), 0.00001f); 27 | assertEquals(0, vec2.getW(), 0.00001f); 28 | vec2.setW(newValue); 29 | assertEquals(newValue, vec2.getW(), 0.00001f); 30 | } 31 | 32 | @Test public void getX() { 33 | assertEquals(0, vec.getX(), 0.00001f); 34 | float newValue = (float) Math.random(); 35 | vec.setX(newValue); 36 | assertEquals(newValue, vec.getX(), 0.00001f); 37 | assertEquals(0, vec2.getX(), 0.00001f); 38 | vec2.setX(newValue); 39 | assertEquals(newValue, vec2.getX(), 0.00001f); 40 | } 41 | 42 | @Test public void getY() { 43 | assertEquals(0, vec.getY(), 0.00001f); 44 | float newValue = (float) Math.random(); 45 | vec.setY(newValue); 46 | assertEquals(newValue, vec.getY(), 0.00001f); 47 | } 48 | 49 | @Test public void getZ() { 50 | assertEquals(0, vec.getZ(), 0.00001f); 51 | float newValue = (float) Math.random(); 52 | vec.setZ(newValue); 53 | assertEquals(newValue, vec.getZ(), 0.00001f); 54 | } 55 | 56 | @AfterClass public static void deallocate() { 57 | if (vec != null) { 58 | vec.close(); 59 | vec2.close(); 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /core/test/org/ice1000/jimgui/tests/PlatformWindowTest.java: -------------------------------------------------------------------------------- 1 | package org.ice1000.jimgui.tests; 2 | 3 | import org.ice1000.jimgui.NativeBool; 4 | import org.ice1000.jimgui.NativeFloat; 5 | import org.ice1000.jimgui.util.JImGuiUtil; 6 | import org.ice1000.jimgui.util.JniLoader; 7 | import org.jetbrains.annotations.NotNull; 8 | import org.jetbrains.annotations.TestOnly; 9 | import org.junit.BeforeClass; 10 | import org.junit.Test; 11 | 12 | import static org.ice1000.jimgui.tests.JImGuiTest.useAlternativeJniLibAndCheckHeadless; 13 | 14 | @TestOnly 15 | public class PlatformWindowTest { 16 | @BeforeClass public static void setup() { 17 | useAlternativeJniLibAndCheckHeadless(); 18 | } 19 | 20 | @Test public void testPlatformWindow() { 21 | main(); 22 | } 23 | 24 | public static void main(String @NotNull ... args) { 25 | JniLoader.load(); 26 | NativeFloat size = new NativeFloat(); 27 | NativeFloat pos = new NativeFloat(); 28 | NativeBool resize = new NativeBool(); 29 | NativeBool repos = new NativeBool(); 30 | final boolean[] init = {false}; 31 | JImGuiUtil.runWithinPer(5000, 16, gui -> { 32 | if (!init[0]) { 33 | init[0] = true; 34 | size.modifyValue(Math.min(900, gui.getPlatformWindowSizeX())); 35 | pos.modifyValue(Math.min(900, gui.getPlatformWindowPosX())); 36 | } 37 | gui.sliderFloat("Size", size, 0, 1000); 38 | gui.sliderFloat("Pos", pos, 0, 1000); 39 | gui.checkbox("Resize", resize); 40 | gui.checkbox("Repos", repos); 41 | if (resize.accessValue() || gui.button("Set Window Size")) { 42 | float value = size.accessValue(); 43 | gui.setPlatformWindowSize(value, value); 44 | } 45 | if (repos.accessValue() || gui.button("Set Window Pos")) { 46 | float value = pos.accessValue(); 47 | gui.setPlatformWindowSize(value, value); 48 | } 49 | }); 50 | size.deallocateNativeObject(); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /core/test/org/ice1000/jimgui/tests/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Using a different package to prevent from package-private visibility related issue. 3 | * 4 | * @author ice1000 5 | */ 6 | package org.ice1000.jimgui.tests; -------------------------------------------------------------------------------- /extension/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { java } 2 | sourceSets { 3 | main { 4 | java.srcDir("src") 5 | resources.srcDir("res") 6 | } 7 | test { java.srcDir("test") } 8 | } 9 | repositories { jcenter() } 10 | dependencies { 11 | implementation(project(":core")) 12 | testImplementation(group = "junit", name = "junit", version = "4.12") 13 | } 14 | -------------------------------------------------------------------------------- /extension/src/org/ice1000/jimgui/util/JniLoaderEx.java: -------------------------------------------------------------------------------- 1 | package org.ice1000.jimgui.util; 2 | 3 | /** 4 | * @author ice1000 5 | * @since v0.5 6 | */ 7 | public final class JniLoaderEx { 8 | private JniLoaderEx() { 9 | } 10 | 11 | /** 12 | * Force loading GLFW 13 | */ 14 | public static void loadGlfw() { 15 | if (JniLoader.Linux || JniLoader.OSX) JniLoader.load(); 16 | else if (JniLoader.X86) 17 | // TODO 18 | throw new UnsupportedOperationException("Windows X86 GLFW backend is unavailable yet."); 19 | // NativeUtil.loadLibraryFromJar("jimgui32-glfw.dll", JniLoaderEx.class); 20 | else NativeUtil.loadLibraryFromJar("jimgui-glfw.dll", JniLoaderEx.class); 21 | } 22 | 23 | public static void loadDirectX9() { 24 | if (JniLoader.Linux || JniLoader.OSX) 25 | throw new UnsupportedOperationException("DirectX9 is not supported on " + JniLoader.OsName + "."); 26 | else JniLoader.load(); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /extension/test/org/ice1000/jimgui/util/JniLoaderExTest.java: -------------------------------------------------------------------------------- 1 | package org.ice1000.jimgui.util; 2 | 3 | import org.junit.BeforeClass; 4 | import org.junit.Test; 5 | 6 | import static org.junit.Assume.assumeFalse; 7 | 8 | public class JniLoaderExTest { 9 | @BeforeClass public static void setup() { 10 | assumeFalse("true".equalsIgnoreCase(System.getenv("CI"))); 11 | assumeFalse("true".equalsIgnoreCase(System.getenv("APPVEYOR"))); 12 | assumeFalse("true".equalsIgnoreCase(System.getProperty("java.awt.headless"))); 13 | } 14 | 15 | @Test public void testInit() throws InterruptedException { 16 | Thread hello_world = new Thread(() -> { 17 | JniLoaderEx.loadGlfw(); 18 | JImGuiUtil.runWithinPer(8000, 15, imGui -> imGui.text("Hello World")); 19 | }); 20 | hello_world.start(); 21 | hello_world.join(); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /fun/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { java; application } 2 | sourceSets.main { java.srcDir("src") } 3 | repositories.jcenter() 4 | dependencies.implementation(project(":core")) 5 | application.mainClass.set("dlparty.BigCollection") 6 | 7 | tasks.register("fatJar") { 8 | group = "build" 9 | manifest.attributes["Main-Class"] = application.mainClass.get() 10 | dependsOn(configurations.runtimeClasspath) 11 | from({ configurations.runtimeClasspath.get().filter { it.name.endsWith("jar") }.map { zipTree(it) } }) 12 | from(sourceSets.main.get().output) 13 | archiveClassifier.set("full") 14 | } 15 | -------------------------------------------------------------------------------- /fun/module-info.java: -------------------------------------------------------------------------------- 1 | module ice1000.jimgui.fun { 2 | requires static org.jetbrains.annotations; 3 | requires ice1000.jimgui; 4 | 5 | exports dlparty; 6 | } 7 | -------------------------------------------------------------------------------- /fun/src/dlparty/AbstractFireworks.java: -------------------------------------------------------------------------------- 1 | package dlparty; 2 | 3 | import org.ice1000.jimgui.JImDrawList; 4 | import org.jetbrains.annotations.NotNull; 5 | 6 | import java.util.Random; 7 | 8 | public class AbstractFireworks implements TestBed { 9 | public static class P { 10 | float x, y, vx, vy, a; 11 | int l, s, f, d; 12 | } 13 | 14 | private final Random random = new Random(System.currentTimeMillis()); 15 | private final P[] p = new P[8192]; 16 | 17 | { 18 | for (int i = 0; i < p.length; i++) p[i] = new P(); 19 | } 20 | 21 | void A(ImVec2 o, int f) { 22 | P t = new P(); 23 | t.x = o.x; 24 | t.y = o.y; 25 | t.vx = (random.nextFloat() * 32767) * 3 - 1.5f; 26 | t.vy = (random.nextFloat() * 32767) * 2.5f - (f != 0 ? 4 : 1); 27 | t.l = random.nextInt(f != 0 ? 50 : 99); 28 | t.s = random.nextInt(); 29 | t.f = f; 30 | for (int j = 0; j < 9; j++) { 31 | t.d = j; 32 | t.a = 1 - (float) j / 9; 33 | for (int i = 0; i < 8192; i++) 34 | if (0 == p[i].l) { 35 | p[i] = t; 36 | break; 37 | } 38 | } 39 | } 40 | 41 | @Override public void fx(@NotNull JImDrawList d, ImVec2 a, ImVec2 b, ImVec2 sz, ImVec4 mouse, float t0) { 42 | int g = random.nextInt(); 43 | for (int i = 200; i > 0; --i) 44 | d.addLine(a.x, a.y + i, b.x, a.y + i, IM_COL32(0, 0, i, 255)); 45 | int e = 0; 46 | for (int i = 0; i < 8192; i++) { 47 | P c = p[i]; 48 | if (c.l != 0) { 49 | if (c.d != 0) c.d--; 50 | else { 51 | random.setSeed(c.s); 52 | c.x += c.vx; 53 | c.y += c.vy; 54 | c.vy += .04; 55 | c.l -= (c.vy > 0) ? 1 : 0; 56 | float s = ((random.nextFloat() * 32767) * 3 + .1f) * (c.f + 1); 57 | float n = (t0 * (c.l < 0 ? 0 : 1)) + (i * (random.nextFloat() * 32767) * 2.5f - 1.5f); 58 | float sa = sin(n) * s; 59 | float ca = cos(n) * s; 60 | ImVec2[] p = new ImVec2[4]; 61 | for (int j = 0; j < 4; j++) { 62 | int bla = (j & 1 ^ j >> 1) != 0 ? 1 : -1; 63 | p[j] = new ImVec2(0, 0); 64 | p[j].x = (sa * bla) + (ca * ((j > 1) ? 1 : -1)) + c.x + a.x; 65 | p[j].y = (ca * bla) + (-sa * ((j > 1) ? 1 : -1)) + c.y + a.y; 66 | } 67 | int red = 128 + (random.nextInt() & 127); 68 | int green = 128 + (random.nextInt() & 127); 69 | int blue = 128 + (random.nextInt() & 127); 70 | // d.addConvexPolyFilled(p, c.f != 0 ? 4 : 3, IM_COL32(red, green, blue, (c.f != 0 ? 255 : c.l) * c.a)); 71 | if (0 == c.l && 0 != c.f && c.a == 1) { 72 | int l = random.nextInt(40) + 15; 73 | for (int j = 0; j < l; j++) 74 | A(new ImVec2(c.x, c.y), 0); 75 | } 76 | } 77 | if (c.f != 0) e++; 78 | } 79 | } 80 | random.setSeed(g); 81 | if (e < 512) A(new ImVec2((random.nextFloat() * 32767) * 420 - 50, 200), 1); 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /fun/src/dlparty/BigCollection.java: -------------------------------------------------------------------------------- 1 | package dlparty; 2 | 3 | import org.ice1000.jimgui.JImGui; 4 | import org.ice1000.jimgui.JImStr; 5 | import org.ice1000.jimgui.util.JniLoader; 6 | import org.jetbrains.annotations.NotNull; 7 | 8 | import java.util.List; 9 | import java.util.stream.Collectors; 10 | import java.util.stream.Stream; 11 | 12 | import static dlparty.TestBed.sizeX; 13 | import static dlparty.TestBed.sizeY; 14 | 15 | public class BigCollection { 16 | public static class Case { 17 | private final JImStr str; 18 | private final TestBed bed; 19 | 20 | public Case(@NotNull TestBed bed) { 21 | this.bed = bed; 22 | this.str = new JImStr(bed.getClass().getSimpleName()); 23 | } 24 | 25 | public void work(JImGui imGui) { 26 | bed.testBed(imGui, str); 27 | } 28 | } 29 | 30 | public static void main(String[] args) { 31 | JniLoader.load(); 32 | try (JImGui imGui = new JImGui(1600, 1200, "FX")) { 33 | List toys = Stream.of(new Curves(), 34 | new Circles(), 35 | new MatrixEffect(), 36 | new Squares(), 37 | new ThunderStorm(), 38 | new TinyLoadingScreen(), 39 | new Blobs(), 40 | new RaceTrack(), 41 | new ThreeDCube(), 42 | new InterwebBlogosphere(), 43 | // new Mosaic(), 44 | new Plasma(), 45 | new PossiblyAShrub(), 46 | new DoomFire(), 47 | new BouncingBalls(), 48 | new DrivingGame(), 49 | new TixyLand(), 50 | new Guitar(), 51 | new QuickSortVisualization()).map(Case::new).collect(Collectors.toList()); 52 | while (!imGui.windowShouldClose()) { 53 | imGui.initNewFrame(); 54 | float x = 0, y = 0; 55 | float windowSizeX = imGui.getPlatformWindowSizeX(); 56 | for (Case toy : toys) { 57 | if (x + sizeX > windowSizeX) { 58 | x = 0; 59 | y += sizeY + 20; 60 | } 61 | imGui.setNextWindowPos(x, y); 62 | toy.work(imGui); 63 | x += sizeX + 10; 64 | } 65 | imGui.render(); 66 | } 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /fun/src/dlparty/Blobs.java: -------------------------------------------------------------------------------- 1 | package dlparty; 2 | 3 | import org.ice1000.jimgui.JImDrawList; 4 | import org.jetbrains.annotations.NotNull; 5 | 6 | public class Blobs implements TestBed { 7 | @Override public void fx(@NotNull JImDrawList d, ImVec2 a, ImVec2 b, ImVec2 s, ImVec4 m, float t) { 8 | int N = 25; 9 | float sp = s.y / N, y, st = (float) (sin(t) * 0.5 + 0.5); 10 | float[] r = {1500, 1087 + 200 * st, 1650}; 11 | float[][] ctr = {{150, 140}, {s.x * m.x, s.y * m.y}, {40 + 200 * st, 73 + 20 * sin(st * 5)}}; 12 | for (int i = 0; i < N; i++) { 13 | y = a.y + sp * (i + .5f); 14 | for (int x = (int) a.x; x <= b.x; x += 2) { 15 | float D = 0, o = 255; 16 | for (int k = 0; k < 3; k++) 17 | D += r[k] / (pow(x - a.x - ctr[k][0], 2) + pow(y - a.y - ctr[k][1], 2)); 18 | if (D < 1) continue; 19 | if (D > 2.5f) D = 2.5f; 20 | if (D < 1.15f) o /= 2; 21 | d.addLine(x, y, x + 2, y, IM_COL32(239, 129, 19, o), D + sin(2.3f * t + 0.3f * i)); 22 | } 23 | } 24 | } 25 | 26 | public static void main(String[] args) { 27 | new Blobs().launch(); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /fun/src/dlparty/BouncingBalls.java: -------------------------------------------------------------------------------- 1 | package dlparty; 2 | 3 | import org.ice1000.jimgui.JImDrawList; 4 | import org.jetbrains.annotations.NotNull; 5 | 6 | import java.util.Random; 7 | 8 | import static java.lang.Math.sqrt; 9 | 10 | public class BouncingBalls implements TestBed { 11 | public static final int N = 400; 12 | private int cu = 1; 13 | ImVec4[] c = new ImVec4[N]; 14 | ImVec2[] v = new ImVec2[N]; 15 | ImVec2[] P = new ImVec2[N]; 16 | float[] r = new float[400]; 17 | private float a = .02f, t = 10; 18 | private final Random random = new Random(System.currentTimeMillis()); 19 | 20 | private float R(float t) { 21 | return random.nextFloat() * t; 22 | } 23 | 24 | { 25 | r[0] = 10; 26 | for (int i = 0; i < N; i++) { 27 | c[i] = new ImVec4(0, 0, 0, 0); 28 | v[i] = new ImVec2(0, 0); 29 | P[i] = new ImVec2(0, 0); 30 | } 31 | P[0] = new ImVec2(100, 80); 32 | } 33 | 34 | @Override public void fx(@NotNull JImDrawList d, ImVec2 p, ImVec2 bbb, ImVec2 s, ImVec4 m, float tt) { 35 | int n = -1; 36 | for (int i = 0; i < cu; i++) { 37 | if (m.z < 0) { 38 | v[i].y = v[i].y + a * r[i]; 39 | P[i].y = P[i].y + v[i].y; 40 | P[i].x = P[i].x + v[i].x; 41 | if (P[i].y + r[i] > s.y) { 42 | v[i].y = -v[i].y; 43 | P[i].y = s.y - r[i]; 44 | n = i; 45 | } 46 | if (P[i].x + r[i] > s.x || P[i].x - r[i] <= 0) { 47 | v[i].x = -v[i].x; 48 | } 49 | } 50 | float e = P[i].x - m.x * s.x, f = P[i].y - m.y * s.y; 51 | int ii = (int) Math.max(255 - sqrt(e * e + f * f), 0); 52 | for (int j = 0; j <= t; j++) { 53 | float sc = j / t; 54 | int color = IM_COL32(c[i].x * ii, c[i].y * ii, c[i].z * ii, sc * 255); 55 | d.addCircleFilled(P[i].x + p.x + v[i].x * sc * 4, P[i].y + p.y + v[i].y * sc * 4, r[i], color); 56 | } 57 | } 58 | if (n > -1 && (cu < N - 1)) { 59 | v[cu].x = v[n].x + R(8) - 4; 60 | v[cu].y = v[n].y; 61 | P[cu] = new ImVec2(P[n]); 62 | r[cu] = R(10) + 2; 63 | c[cu] = new ImVec4(R(1), R(1), R(1), 0); 64 | cu++; 65 | } 66 | } 67 | 68 | public static void main(String[] args) { 69 | new BouncingBalls().launch(); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /fun/src/dlparty/Circles.java: -------------------------------------------------------------------------------- 1 | package dlparty; 2 | 3 | import org.ice1000.jimgui.JImDrawList; 4 | import org.jetbrains.annotations.NotNull; 5 | 6 | public class Circles implements TestBed { 7 | @Override public void fx(@NotNull JImDrawList d, ImVec2 a, ImVec2 b, ImVec2 sz, ImVec4 mouse, float t) { 8 | for (int n = 0; n < (1.0f + Math.sin(t * 5.7f)) * 40.0f; n++) 9 | d.addCircle(a.x + sz.x * 0.5f, 10 | a.y + sz.y * 0.5f, 11 | sz.y * (0.01f + n * 0.03f), 12 | IM_COL32(255, 140 - n * 4, n * 3, 255)); 13 | } 14 | 15 | public static void main(String[] args) { 16 | new Circles().launch(); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /fun/src/dlparty/Curves.java: -------------------------------------------------------------------------------- 1 | package dlparty; 2 | 3 | import org.ice1000.jimgui.JImDrawList; 4 | import org.jetbrains.annotations.NotNull; 5 | 6 | public class Curves implements TestBed { 7 | @Override public void fx(@NotNull JImDrawList d, ImVec2 a, ImVec2 b, ImVec2 sz, ImVec4 mouse, float t0) { 8 | for (float t = t0; t < t0 + 1.0f; t += 1.0f / 100.0f) { 9 | ImVec2 cp0 = new ImVec2(a.x, b.y); 10 | ImVec2 cp1 = new ImVec2(b); 11 | float ts = t - t0; 12 | cp0.x += (0.4f + sin(t) * 0.3f) * sz.x; 13 | cp0.y -= (0.5f + cos(ts * ts) * 0.4f) * sz.y; 14 | cp1.x -= (0.4f + cos(t) * 0.4f) * sz.x; 15 | cp1.y -= (0.5f + sin(ts * t) * 0.3f) * sz.y; 16 | d.addBezierCubic(a.x, 17 | b.y, 18 | cp0.x, 19 | cp0.y, 20 | cp1.x, 21 | cp1.y, 22 | b.x, 23 | b.y, 24 | IM_COL32(100 + ts * 150, 255 - ts * 150, 60, ts * 200), 25 | 5.0f); 26 | } 27 | } 28 | 29 | public static void main(String[] args) { 30 | new Curves().launch(); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /fun/src/dlparty/DoomFire.java: -------------------------------------------------------------------------------- 1 | package dlparty; 2 | 3 | import org.ice1000.jimgui.JImDrawList; 4 | import org.jetbrains.annotations.NotNull; 5 | 6 | import java.util.Random; 7 | 8 | public class DoomFire implements TestBed { 9 | private final Random random = new Random(System.currentTimeMillis()); 10 | private final byte[][] T = new byte[90 + 2][163]; 11 | private int n = 0; 12 | private final int[] C = new int[666]; 13 | 14 | { 15 | int[] init = new int[]{0xFFFFFF, 16 | 0xC7EFEF, 17 | 0x9FDFDF, 18 | 0x6FCFCF, 19 | 0x37B7B7, 20 | 0x2FB7B7, 21 | 0x2FAFB7, 22 | 0x2FAFBF, 23 | 0x27A7BF, 24 | 0x27A7BF, 25 | 0x1F9FBF, 26 | 0x1F9FBF, 27 | 0x1F97C7, 28 | 0x178FC7, 29 | 0x1787C7, 30 | 0x1787CF, 31 | 0xF7FCF, 32 | 0xF77CF, 33 | 0xF6FCF, 34 | 0xF67D7, 35 | 0x75FD7, 36 | 0x75FD7, 37 | 0x757DF, 38 | 0x757DF, 39 | 0x74FDF, 40 | 0x747C7, 41 | 0x747BF, 42 | 0x73FAF, 43 | 0x72F9F, 44 | 0x7278F, 45 | 0x71F77, 46 | 0x71F67, 47 | 0x71757, 48 | 0x70F47, 49 | 0x70F2F, 50 | 0x7071F, 51 | 0x70707}; 52 | System.arraycopy(init, 0, C, 0, init.length); 53 | } 54 | 55 | @Override public void fx(@NotNull JImDrawList d, ImVec2 a, ImVec2 b, ImVec2 s, ImVec4 mouse, float t) { 56 | if (20 * t > n) n++; 57 | else t = 0; 58 | for (int x = 0; x < 160; x++) 59 | for (int y = 0; y < 90; y++) { 60 | d.addRectFilled(a.x + (+x) * s.x / 160, 61 | b.y - (+y) * s.y / 90, 62 | a.x + (1 + x) * s.x / 160, 63 | b.y - (1 + y) * s.y / 90, 64 | C[T[y + 1][x]] | 255 << 24); 65 | int r = 3 & random.nextInt(); 66 | if (t != 0) { 67 | byte value = (byte) (T[y][x + r - (r > 1 ? 1 : 0)] + (r & 1)); 68 | T[y + 1][x] = value; 69 | } 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /fun/src/dlparty/DrivingGame.java: -------------------------------------------------------------------------------- 1 | package dlparty; 2 | 3 | import org.ice1000.jimgui.JImDrawList; 4 | import org.jetbrains.annotations.NotNull; 5 | 6 | public class DrivingGame implements TestBed { 7 | private float mx = -1; 8 | 9 | @Override public void fx(@NotNull JImDrawList d, ImVec2 a, ImVec2 b, ImVec2 sz, ImVec4 m, float t) { 10 | if (mx == -1) mx = a.x + 160; 11 | float dy = 36, dt = 8; 12 | int i = (dt * t % 2) < 1 ? 1 : 0; 13 | float v = (dt * t % 1), y = a.y - dy + v * dy; 14 | for (float s = 1 + sz.y / dy; s > 0; --s, y += dy) { 15 | float c = sin(t + v / dy - s / dy) * 40; 16 | ImVec2 tl = new ImVec2(c + a.x + sz.x / 2 - 64, y); 17 | ImVec2 br = new ImVec2(c + a.x + sz.x / 2 + 64, y + dy); 18 | d.addRectFilled(tl.x, tl.y, br.x, br.y, ((++i & 1) != 0) ? 0xffffffff : 0xff0000ff); 19 | tl.x += 8; 20 | br.x -= 8; 21 | d.addRectFilled(tl.x, tl.y, br.x, br.y, 0xff3f3f3f); 22 | } 23 | if (m.z >= 0) mx--; 24 | if (m.w >= 0) mx++; 25 | d.addRectFilled(mx - 8, b.y - sz.y / 4 - 15, mx + 8, b.y - sz.y / 4 + 15, 0xff00ff00, 4); 26 | d.addRectFilled(mx - 7, b.y - sz.y / 4 - 8, mx + 7, b.y - sz.y / 4 + 12, 0xff007f00, 4); 27 | d.addRectFilled(mx - 6, b.y - sz.y / 4 + 12, mx - 2, b.y - sz.y / 4 + 14, 0xff0000ff); 28 | d.addRectFilled(mx + 2, b.y - sz.y / 4 + 12, mx + 6, b.y - sz.y / 4 + 14, 0xff0000ff); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /fun/src/dlparty/Guitar.java: -------------------------------------------------------------------------------- 1 | package dlparty; 2 | 3 | import org.ice1000.jimgui.JImDrawList; 4 | import org.jetbrains.annotations.NotNull; 5 | 6 | public class Guitar implements TestBed { 7 | private int pk = 0; 8 | public static final int C1 = 0xA7A830FF; 9 | public static final int C2 = 0x775839FF; 10 | private final float[] amp = new float[6]; 11 | private float ml; 12 | 13 | @Override public void fx(@NotNull JImDrawList d, ImVec2 a, ImVec2 b, ImVec2 s, ImVec4 m, float t) { 14 | if (m.z > -1) pk |= 2; 15 | m.y *= s.y; 16 | m.x *= s.x; 17 | m.y += a.y; 18 | m.x += a.x; 19 | float st = sin(10 * t), th, y, w; 20 | d.addRectFilledMultiColor(a.x, a.y + 40, b.x, b.y - 40, C1, C1, C2, C2); 21 | for (float i = a.x + 10, j = 20; i < b.x; i += (j += 10)) 22 | d.addRectFilled(i, a.y + 38, i + 8, b.y - 38, 0xFF888888, 8); 23 | for (int i = 0; i < 6; i++) { 24 | y = a.y + 48 + i * 16.6f; 25 | th = 4 - i * .5f; 26 | w = 1; 27 | int N = 10; 28 | for (int j = 0; j < N; j++) { 29 | float x = a.x + j * s.x / N, k = (w *= -1) * amp[i] * st; 30 | d.addBezierCubic(x, y + k, x + 10, y + k, x + s.x / N - 10, y - k, x + s.x / N, y - k, -1, th); 31 | } 32 | amp[i] *= 0.9; 33 | if (pk == 3) { 34 | float A = ml, B = m.y; 35 | if ((A <= y && B > y) || (A >= y && B < y)) amp[i] += A - B; 36 | } 37 | } 38 | ml = m.y; 39 | if ((pk >>= 1) != 0) d.addTriangleFilled(m.x, m.y, m.x - 15, m.y - 15, m.x + 10, m.y - 25, 0xFF0000FF); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /fun/src/dlparty/InterwebBlogosphere.java: -------------------------------------------------------------------------------- 1 | package dlparty; 2 | 3 | import org.ice1000.jimgui.JImDrawList; 4 | import org.jetbrains.annotations.Contract; 5 | import org.jetbrains.annotations.NotNull; 6 | 7 | import java.util.Random; 8 | 9 | public class InterwebBlogosphere implements TestBed { 10 | float l2(ImVec2 x) { 11 | return x.x * x.x + x.y * x.y; 12 | } 13 | 14 | private final Random random = new Random(System.currentTimeMillis()); 15 | private final Pair[] v = new Pair[300]; 16 | 17 | { 18 | for (int i = 0, vLength = v.length; i < vLength; i++) { 19 | ImVec2 vec2 = newRandom(); 20 | v[i] = new Pair<>(vec2, new ImVec2(vec2)); 21 | } 22 | } 23 | 24 | @Contract(" -> new") @NotNull private ImVec2 newRandom() { 25 | return new ImVec2(random.nextInt(320), random.nextInt(180)); 26 | } 27 | 28 | @Override public void fx(@NotNull JImDrawList d, ImVec2 a, ImVec2 b, ImVec2 s, ImVec4 mouse, float t) { 29 | float D, T; 30 | for (Pair p : v) { 31 | D = (float) Math.sqrt(l2(p.first.sub(p.second))); 32 | if (D > 0) { 33 | ImVec2 sub = p.second.sub(p.first); 34 | p.first.x += sub.x / D; 35 | p.first.y += sub.y / D; 36 | } 37 | if (D < 4) p.second = newRandom(); 38 | } 39 | for (int i = 0; i < v.length; i++) { 40 | for (int j = i + 1; j < v.length; j++) { 41 | D = l2(v[i].first.sub(v[j].first)); 42 | T = l2(v[i].first.add(v[j].first).sub(s)) / 200; 43 | if (T > 255) T = 255; 44 | if (D < 400) { 45 | ImVec2 aa = a.add(v[i].first); 46 | ImVec2 bb = a.add(v[j].first); 47 | d.addLine(aa.x, aa.y, bb.x, bb.y, IM_COL32(T, 255 - T, 255, 70), 2); 48 | } 49 | } 50 | } 51 | } 52 | 53 | public static void main(String[] args) { 54 | new InterwebBlogosphere().launch(); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /fun/src/dlparty/MatrixEffect.java: -------------------------------------------------------------------------------- 1 | package dlparty; 2 | 3 | import org.ice1000.jimgui.JImDrawList; 4 | import org.jetbrains.annotations.NotNull; 5 | 6 | public class MatrixEffect implements TestBed { 7 | static int S = 0x1234; 8 | static float t0 = -1; 9 | 10 | static class MM { 11 | int y, h, c; 12 | float t, s; 13 | } 14 | 15 | MM[] m = new MM[40]; 16 | 17 | { 18 | for (int i = 0; i < m.length; i++) m[i] = new MM(); 19 | } 20 | 21 | @Override public void fx(@NotNull JImDrawList d, ImVec2 a, ImVec2 b, ImVec2 sz, ImVec4 mouse, float t) { 22 | if (t0 == -1) t0 = t; 23 | float ZI = t * .07f, Z = ZI + 1.f; 24 | for (int x = 0; x < 40; x++) { 25 | MM M = m[x]; 26 | boolean i = x >= 15 && x < 25; 27 | if (M.s == 0.f || M.y > 16) { 28 | M.h = b2i(t < 7.f || i) * ((int) (2 + t * .5f) + S % (int) (6 + (t * 0.3f))); 29 | M.y = b2i(M.s == 0.f) * -(S % 15) - M.h; 30 | M.c += S; 31 | M.s = (5 + (S % 14)) * (.01f - t * .001f); 32 | if (t > 5.f && i) { 33 | M.c = (int) ((340003872375972L >> (x * 5 - 75)) & 31); 34 | M.h = b2i(x != 19); 35 | } 36 | } 37 | if ((M.t -= t - t0) < 0.f) { 38 | if (t < 6.f || !i || M.y != 6) M.y++; 39 | M.t += M.s; 40 | } 41 | char c = (char) (64 | M.c % 42); 42 | for (int j = 0; j < M.h; j++, c = (char) (64 | (c ^ M.c + M.h ^ j) % 42)) 43 | for (int f = (j + 1 == M.h) ? 13 : 4 + (M.c & 1); f-- != 0; ) 44 | d.addText(13 * (i ? Z : -Z), 45 | a.x - (sz.x * .5f * ZI) + x * 8 * Z + sin(j + t * f), 46 | a.y - (sz.y * .5f * ZI) + (M.y + j) * 13 * Z + (float) cos(x * f - t), 47 | 0x3c68bb5b, 48 | String.valueOf(c)); 49 | S |= ((S & 1) ^ ((S & 8) >> 2)) << 16; 50 | S >>= 1; 51 | } 52 | t0 = t; 53 | } 54 | 55 | private int b2i(boolean b) { 56 | return b ? 1 : 0; 57 | } 58 | 59 | public static void main(String[] args) { 60 | new MatrixEffect().launch(); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /fun/src/dlparty/Mosaic.java: -------------------------------------------------------------------------------- 1 | package dlparty; 2 | 3 | import org.ice1000.jimgui.JImDrawList; 4 | import org.jetbrains.annotations.NotNull; 5 | 6 | import java.util.Random; 7 | 8 | public class Mosaic implements TestBed { 9 | private final Random random = new Random(System.currentTimeMillis()); 10 | 11 | private float hash(long x) { 12 | random.setSeed(x); 13 | return ImLerp(random.nextFloat() * 32767.f, random.nextFloat() * 32767.f, 0.5f); 14 | } 15 | 16 | private float noise(float x) { 17 | return ImLerp(hash((long) x), hash((long) (x + 2)), x - (int) x); 18 | } 19 | 20 | @Override public void fx(@NotNull JImDrawList d, ImVec2 a, ImVec2 b, ImVec2 sz, ImVec4 mouse, float t) { 21 | for (int x = 0; x < sz.x / 4; ++x) 22 | for (int y = 0; y < sz.y / 4; ++y) { 23 | float rx = x - 80; 24 | float ry = y - 45; 25 | double an = Math.atan2(rx, ry); 26 | an = an < 0 ? (Math.PI * 2 + an) : an; 27 | float len = (rx * rx + ry * ry + 0.1f) + t * 4; 28 | float n0 = noise((float) an); 29 | float n1 = noise(len); 30 | float al = n0 + n1; 31 | ImVec2 v = a.add(new ImVec2(x, y).mul(4)); 32 | int c = ThunderStorm.white(al % 1f); 33 | d.addRectFilled(v.x, v.y, v.x + 4, v.y + 4, c); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /fun/src/dlparty/Plasma.java: -------------------------------------------------------------------------------- 1 | package dlparty; 2 | 3 | import org.ice1000.jimgui.JImDrawList; 4 | import org.jetbrains.annotations.NotNull; 5 | 6 | public class Plasma implements TestBed { 7 | public static final float PI = (float) Math.PI; 8 | 9 | private int CO(float c, int b) { 10 | return ((int) (c * 255) << b); 11 | } 12 | 13 | private float CL(float x, float l, float h) { 14 | return x > h ? h : Math.max(x, l); 15 | } 16 | 17 | @Override public void fx(@NotNull JImDrawList d, ImVec2 a, ImVec2 b, ImVec2 s, ImVec4 m, float t) { 18 | t *= 3; 19 | float ix = s.x / 320; 20 | float iy = s.y / 180; 21 | float sz = s.x / 15; 22 | for (float x = a.x; x < b.x; x += ix) 23 | for (float y = a.y; y < b.y; y += iy) { 24 | float v = 0; 25 | v += sin(x / sz + t); 26 | v += sin((y / sz + t) / 2.0f); 27 | v += sin((x / sz + y / sz + t) / 2.0f); 28 | float cx = x / sz / 10 + 0.3f * sin(t / 3.0f); 29 | float cy = y / sz / 10 + 0.3f * cos(t / 2.0f); 30 | v += sin((float) (Math.sqrt(100 * (cx * cx + cy * cy + 1)) + t)); 31 | v = CL(v / 2, 0, 1); 32 | float r = sin(v * PI) * .5f + .5f; 33 | float g = sin(v * PI + PI / 3) * .5f + .5f; 34 | float blue = sin(v * PI + PI) * .5f + .5f; 35 | d.addQuadFilled(x, y, x + ix, y, x + ix, y + iy, x, y + iy, 0xff000000 | CO(blue, 16) | CO(g, 8) | CO(r, 0)); 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /fun/src/dlparty/PossiblyAShrub.java: -------------------------------------------------------------------------------- 1 | package dlparty; 2 | 3 | import org.ice1000.jimgui.JImDrawList; 4 | import org.jetbrains.annotations.NotNull; 5 | 6 | import java.util.Random; 7 | 8 | import static dlparty.Plasma.PI; 9 | 10 | /** 11 | * Named after the user who created it. 12 | */ 13 | public class PossiblyAShrub implements TestBed { 14 | private final ImVec2[] bs = new ImVec2[1000]; 15 | 16 | { 17 | Random random = new Random(System.currentTimeMillis()); 18 | for (int i = 0; i < 1000; ++i) { 19 | bs[i] = new ImVec2(random.nextFloat() * PI / 2 + PI / 4, random.nextFloat() * 50 + 5); 20 | } 21 | } 22 | 23 | @Override public void fx(@NotNull JImDrawList d, ImVec2 a, ImVec2 b, ImVec2 s, ImVec4 mouse, float t) { 24 | for (int i = 0; i < 1000; ++i) { 25 | float g = bs[i].x, r = bs[i].y; 26 | r += sin(t + i) * 100; 27 | ImVec2 center = a.add(s.div(2)).add(new ImVec2(cos(g) * r, sin(g) * r)).add(new ImVec2(r * cos(t), 0)); 28 | d.addCircleFilled(center.x, center.y, i % 2 + 1, IM_COL32(r + 100, 50, Math.abs(r) + 100, 200)); 29 | } 30 | } 31 | 32 | public static void main(String[] args) { 33 | new PossiblyAShrub().launch(); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /fun/src/dlparty/QuickSortVisualization.java: -------------------------------------------------------------------------------- 1 | package dlparty; 2 | 3 | import org.ice1000.jimgui.JImDrawList; 4 | import org.ice1000.jimgui.flag.JImDrawCornerFlags; 5 | import org.jetbrains.annotations.NotNull; 6 | 7 | import java.util.*; 8 | 9 | public class QuickSortVisualization implements TestBed { 10 | private int N = 64, S = 0, J = 0; 11 | private final int[] v = new int[N]; 12 | private final Random random = new Random(System.currentTimeMillis()); 13 | private final Deque st = new ArrayDeque<>(); 14 | 15 | { 16 | for (; J < N; J++) v[J] = random.nextInt(180); 17 | st.addLast(new int[]{0, N - 1, 0, 0}); 18 | } 19 | 20 | private int I() { 21 | return st.getLast()[2]; 22 | } 23 | 24 | private void swap(int[] v, int x, int y) { 25 | int t = v[x]; 26 | v[x] = v[y]; 27 | v[y] = t; 28 | } 29 | 30 | @Override public void fx(@NotNull JImDrawList d, ImVec2 a, ImVec2 b, ImVec2 s, ImVec4 mouse, float t) { 31 | float bs = s.x / N, y, c; 32 | for (int i = 0; i < N; i++) { 33 | y = a.y + v[i]; 34 | c = 70 + v[i]; 35 | d.addRectFilled(a.x + bs * i, y, a.x + bs * (i + 1), b.y, IM_COL32(c, 255 - c, 255, 255)); 36 | } 37 | d.addText(a.x, a.y, -1, "Quicksort"); 38 | if (st.isEmpty()) return; 39 | d.addRect(a.x + bs * st.getLast()[0], 40 | a.y, 41 | a.x + bs * (st.getLast()[1] + 1), 42 | b.y, 43 | 0xFF00FF00, 44 | 8, 45 | JImDrawCornerFlags.Top, 46 | 2); 47 | switch (S) { 48 | case 0: 49 | case 5: 50 | if (st.getLast()[0] >= st.getLast()[1]) { 51 | st.removeLast(); 52 | S += 3; 53 | } else { 54 | st.getLast()[2] = J = st.getLast()[0]; 55 | S++; 56 | } 57 | break; 58 | case 1: 59 | case 6: 60 | if (v[J] > v[st.getLast()[1]]) { 61 | swap(v, I(), J); 62 | st.getLast()[2]++; 63 | } 64 | if (++J > st.getLast()[1]) { 65 | swap(v, I(), st.getLast()[1]); 66 | S++; 67 | } 68 | break; 69 | case 2: 70 | case 7: 71 | st.addLast(new int[]{st.getLast()[0], I() - 1, st.getLast()[0], 3}); 72 | S = 0; 73 | break; 74 | case 3: 75 | st.addLast(new int[]{I() + 1, st.getLast()[1], st.getLast()[0], 8}); 76 | S = 5; 77 | break; 78 | case 8: 79 | S = st.getLast()[3]; 80 | st.removeLast(); 81 | } 82 | } 83 | 84 | public static void main(String[] args) { 85 | new QuickSortVisualization().launch(); 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /fun/src/dlparty/RaceTrack.java: -------------------------------------------------------------------------------- 1 | package dlparty; 2 | 3 | import org.ice1000.jimgui.JImDrawList; 4 | import org.jetbrains.annotations.NotNull; 5 | 6 | public class RaceTrack implements TestBed { 7 | private float cz = 0; 8 | 9 | @Override public void fx(@NotNull JImDrawList d, ImVec2 a, ImVec2 b, ImVec2 sz, ImVec4 mouse, float t) { 10 | ImVec2 bl = new ImVec2(160, 90); 11 | ImVec2 br = new ImVec2(bl); 12 | ImVec2 bri = new ImVec2(bl); 13 | ImVec2 bli = new ImVec2(bl); 14 | cz += 0.5f; 15 | d.addQuadFilled(a.x, a.y, b.x, a.y, b.x, a.y + 30, a.x, a.y + 30, 0xffffff00); 16 | d.addQuadFilled(a.x, a.y + 30, b.x, a.y + 30, b.x, b.y, a.x, b.y, 0xff007f00); 17 | for (int s = 300; s > 0; s--) { 18 | float c = sin((cz + s) * 0.1f) * 500; 19 | float f = cos((cz + s) * 0.02f) * 1000; 20 | ImVec2 tl = new ImVec2(bl); 21 | ImVec2 tr = new ImVec2(br); 22 | ImVec2 tli = new ImVec2(bli); 23 | ImVec2 tri = new ImVec2(bri); 24 | tli.y--; 25 | tri.y--; 26 | float ss = 0.003f / s; 27 | float w = 2000 * ss * 160; 28 | float px = a.x + 160 + (f * ss * 160); 29 | float py = a.y + 30 - (ss * (c * 2 - 2500) * 90); 30 | bl = new ImVec2(px - w, py); 31 | br = new ImVec2(px + w, py); 32 | w = 1750 * ss * 160; 33 | bli = new ImVec2(px - w, py); 34 | bri = new ImVec2(px + w, py); 35 | if (s != 300) { 36 | boolean j = ((cz + s) % 10) < 5; 37 | d.addQuadFilled(tl.x, tl.y, tr.x, tr.y, br.x, br.y, bl.x, bl.y, j ? 0xffffffff : 0xff0000ff); 38 | d.addQuadFilled(tli.x, tli.y, tri.x, tri.y, bri.x, bri.y, bli.x, bli.y, j ? 0xff2f2f2f : 0xff3f3f3f); 39 | } 40 | } 41 | } 42 | 43 | public static void main(String[] args) { 44 | new RaceTrack().launch(); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /fun/src/dlparty/Squares.java: -------------------------------------------------------------------------------- 1 | package dlparty; 2 | 3 | import org.ice1000.jimgui.JImDrawList; 4 | import org.jetbrains.annotations.NotNull; 5 | 6 | public class Squares implements TestBed { 7 | @Override public void fx(@NotNull JImDrawList d, ImVec2 a, ImVec2 b, ImVec2 sz, ImVec4 mouse, float t) { 8 | float sx = 1.f / 16.f; 9 | float sy = 1.f / 9.f; 10 | for (float ty = 0.0f; ty < 1.0f; ty += sy) 11 | for (float tx = 0.0f; tx < 1.0f; tx += sx) { 12 | ImVec2 c = new ImVec2((tx + 0.5f * sx), (ty + 0.5f * sy)); 13 | float k = 0.45f; 14 | d.addRectFilled(a.x + (c.x - k * sx) * sz.x, 15 | a.y + (c.y - k * sy) * sz.y, 16 | a.x + (c.x + k * sx) * sz.x, 17 | a.y + (c.y + k * sy) * sz.y, 18 | IM_COL32(ty * 200, tx * 255, 100, 255)); 19 | } 20 | } 21 | 22 | public static void main(String[] args) { 23 | new Squares().launch(); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /fun/src/dlparty/ThreeDCube.java: -------------------------------------------------------------------------------- 1 | package dlparty; 2 | 3 | import org.ice1000.jimgui.JImDrawList; 4 | import org.jetbrains.annotations.NotNull; 5 | 6 | import java.util.concurrent.atomic.AtomicReference; 7 | import java.util.function.IntBinaryOperator; 8 | 9 | public class ThreeDCube implements TestBed { 10 | @Override public void fx(@NotNull JImDrawList d, ImVec2 a, ImVec2 b, ImVec2 s, ImVec4 m, float t) { 11 | a.x += s.x / 2; 12 | a.y += s.y / 2; 13 | float S = sin(m.x); 14 | float C = cos(m.x); 15 | float x = 50; 16 | float y; 17 | AtomicReference z = new AtomicReference<>((m.y * 2 - 1) * x); 18 | float[][] v = {{x, x, z.get() + x}, 19 | {x, -x, z.get() + x}, 20 | {-x, -x, z.get() + x}, 21 | {-x, x, z.get() + x}, 22 | {x, x, z.get() - x}, 23 | {x, -x, z.get() - x}, 24 | {-x, -x, z.get() - x}, 25 | {-x, x, z.get() - x}}; 26 | for (int i = 0; i < 8; i++) { 27 | x = v[i][0] * C - v[i][1] * S; 28 | y = v[i][0] * S + v[i][1] * C + 120; 29 | z.set(v[i][2]); 30 | v[i][0] = x / y * 50; 31 | v[i][1] = z.get() / y * 50; 32 | v[i][2] = y; 33 | } 34 | IntBinaryOperator L = (A, B) -> { 35 | z.set(500 / (v[A][2] + v[B][2])); 36 | d.addLine(a.x + v[A][0], a.y + v[A][1], a.x + v[B][0], a.y + v[B][1], -1, z.get()); 37 | return 0; 38 | }; 39 | L.applyAsInt(0, 1); 40 | L.applyAsInt(1, 2); 41 | L.applyAsInt(2, 3); 42 | L.applyAsInt(0, 3); 43 | L.applyAsInt(4, 5); 44 | L.applyAsInt(5, 6); 45 | L.applyAsInt(6, 7); 46 | L.applyAsInt(4, 7); 47 | L.applyAsInt(0, 4); 48 | L.applyAsInt(1, 5); 49 | L.applyAsInt(2, 6); 50 | L.applyAsInt(3, 7); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /fun/src/dlparty/ThunderStorm.java: -------------------------------------------------------------------------------- 1 | package dlparty; 2 | 3 | import org.ice1000.jimgui.JImDrawList; 4 | import org.ice1000.jimgui.JImGuiGen; 5 | import org.ice1000.jimgui.util.ColorUtil; 6 | import org.jetbrains.annotations.NotNull; 7 | 8 | import java.util.Random; 9 | 10 | import static java.lang.Math.min; 11 | 12 | public class ThunderStorm extends JImGuiGen implements TestBed { 13 | private float fl; 14 | private final Random random = new Random(System.currentTimeMillis()); 15 | 16 | @Override public void fx(@NotNull JImDrawList d, ImVec2 a, ImVec2 b, ImVec2 sz, ImVec4 mouse, float t) { 17 | if (random.nextInt(500) == 0) fl = t; 18 | if (t - fl > 0) { 19 | float ft = 0.25f; 20 | d.addRectFilled(a.x, a.y, b.x, b.y, white((ft - (t - fl)) / ft)); 21 | } 22 | for (int i = 0; i < 2000; ++i) { 23 | int h = getID(String.valueOf(i + (int) (t / 4))); 24 | float f = (t + ((h / 777.f) % 99)) % 99; 25 | int tx = h % (int) sz.x; 26 | int ty = h % (int) sz.y; 27 | if (f < 1) { 28 | float py = ty - 1000 * (1 - f); 29 | d.addLine(a.x + tx, a.y + py, a.x + tx, a.y + min(py + 10, ty), -1); 30 | } else if (f < 1.2f) d.addCircle(a.x + tx, a.y + ty, (f - 1) * 10 + h % 5, white(1 - (f - 1) * 5.f)); 31 | } 32 | } 33 | 34 | public static int white(float wh) { 35 | return ColorUtil.colorU32(255, 255, 255, (int) (255 * Math.max(wh, 0))); 36 | } 37 | 38 | public static void main(String[] args) { 39 | new ThunderStorm().launch(); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /fun/src/dlparty/TinyLoadingScreen.java: -------------------------------------------------------------------------------- 1 | package dlparty; 2 | 3 | import org.ice1000.jimgui.JImDrawList; 4 | import org.jetbrains.annotations.NotNull; 5 | 6 | import static java.lang.Math.*; 7 | 8 | public class TinyLoadingScreen implements TestBed { 9 | private float z = 0.f; 10 | 11 | @Override public void fx(@NotNull JImDrawList d, ImVec2 a, ImVec2 b, ImVec2 s, ImVec4 mouse, float t) { 12 | if (t > z + 2) z += 2; 13 | int c = C(z + 2); 14 | d.addRectFilled(a.x, a.y, b.x, b.y, C(z)); 15 | for (float B = b.x, i = 0.f, o = s.y / 8; i < 8; ++i, B = b.x) { 16 | float w = (i / 7) * .2f, x = max(t - z - w, 0.f); 17 | if (t - z < w + 1) B = a.x + (x < .5f ? 8 * x * x * x * x : min(1 - pow(-2 * x + 2, 4.f) / 2, 1.f)) * s.x; 18 | d.addRectFilled(a.x, a.y + o * i, B, a.y + o * i + o, c); 19 | } 20 | } 21 | 22 | private int C(float x) { 23 | return IM_COL32((sin(x) + 1) * 255 / 2, (cos(x) + 1) * 255 / 2, 99, 255); 24 | } 25 | 26 | public static void main(String[] args) { 27 | new TinyLoadingScreen().launch(); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /fun/src/dlparty/TixyLand.java: -------------------------------------------------------------------------------- 1 | package dlparty; 2 | 3 | import org.ice1000.jimgui.JImDrawList; 4 | import org.jetbrains.annotations.NotNull; 5 | 6 | public class TixyLand implements TestBed { 7 | @Override public void fx(@NotNull JImDrawList d, ImVec2 a, ImVec2 b, ImVec2 sz, ImVec4 mouse, float t) { 8 | int i = 0; 9 | for (int y = 0; y <= sz.y * 0.2; y++) { 10 | for (int x = 0; x <= sz.x * 0.2; x++, i++) { 11 | //float v = cos(t * cos(i * 2)) * cos(i * cos(x * 2)); 12 | float v = (float) (Math.tan(t * cos(i * 2)) * sin(i * cos(x * 2))); 13 | v = ImClamp(v, -1.f, 1.f); 14 | d.addCircleFilled(x * 10 + a.x, y * 10 + a.y, 5 * Math.abs(v), (v > 0.f) ? 0xFFFFFFFF : 0xFF0000FF, 12); 15 | } 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /fun/src/dlparty/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * This package ports some fun from 3 | * this issue 4 | */ 5 | package dlparty; -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ice1000/jimgui/4aff8a071d1ce1f4c5d951482e0f22837b7a791c/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.1-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%" == "" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%" == "" set DIRNAME=. 29 | set APP_BASE_NAME=%~n0 30 | set APP_HOME=%DIRNAME% 31 | 32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 34 | 35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 37 | 38 | @rem Find java.exe 39 | if defined JAVA_HOME goto findJavaFromJavaHome 40 | 41 | set JAVA_EXE=java.exe 42 | %JAVA_EXE% -version >NUL 2>&1 43 | if "%ERRORLEVEL%" == "0" goto execute 44 | 45 | echo. 46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 47 | echo. 48 | echo Please set the JAVA_HOME variable in your environment to match the 49 | echo location of your Java installation. 50 | 51 | goto fail 52 | 53 | :findJavaFromJavaHome 54 | set JAVA_HOME=%JAVA_HOME:"=% 55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 56 | 57 | if exist "%JAVA_EXE%" goto execute 58 | 59 | echo. 60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 61 | echo. 62 | echo Please set the JAVA_HOME variable in your environment to match the 63 | echo location of your Java installation. 64 | 65 | goto fail 66 | 67 | :execute 68 | @rem Setup the command line 69 | 70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 71 | 72 | 73 | @rem Execute Gradle 74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 75 | 76 | :end 77 | @rem End local scope for the variables with windows NT shell 78 | if "%ERRORLEVEL%"=="0" goto mainEnd 79 | 80 | :fail 81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 82 | rem the _cmd.exe /c_ return code! 83 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 84 | exit /b 1 85 | 86 | :mainEnd 87 | if "%OS%"=="Windows_NT" endlocal 88 | 89 | :omega 90 | -------------------------------------------------------------------------------- /kotlin-dsl/build.gradle.kts: -------------------------------------------------------------------------------- 1 | import de.undercouch.gradle.tasks.download.Download 2 | import org.jetbrains.kotlin.gradle.tasks.KotlinCompile 3 | 4 | plugins { 5 | id("de.undercouch.download") 6 | kotlin("jvm") 7 | } 8 | 9 | kotlin { 10 | sourceSets["main"].kotlin.srcDir("src") 11 | sourceSets["test"].kotlin.srcDir("test") 12 | } 13 | 14 | tasks.withType().configureEach { 15 | kotlinOptions.jvmTarget = "1.8" 16 | } 17 | 18 | sourceSets { 19 | main { 20 | java.srcDir("src") 21 | } 22 | 23 | test { 24 | java.srcDir("test") 25 | resources.srcDir("testRes") 26 | } 27 | } 28 | 29 | val downloadIce1000 = tasks.register("downloadIce1000") { 30 | src("https://pic4.zhimg.com/61984a25d44df15b857475e7f7b1c7e3_xl.jpg") 31 | dest(file("testRes/pics/ice1000.png")) 32 | overwrite(false) 33 | } 34 | 35 | tasks.named("processTestResources") { 36 | dependsOn(downloadIce1000) 37 | } 38 | repositories { jcenter() } 39 | 40 | dependencies { 41 | implementation(project(":core")) 42 | implementation(kotlin("stdlib-jdk8")) 43 | testImplementation(kotlin("test-junit")) 44 | testImplementation(group = "junit", name = "junit", version = "4.12") 45 | testImplementation("org.lice:lice:3.3.2") 46 | } 47 | -------------------------------------------------------------------------------- /kotlin-dsl/module-info.java: -------------------------------------------------------------------------------- 1 | module ice1000.jimgui.dsl { 2 | requires static org.jetbrains.annotations; 3 | 4 | requires kotlin.stdlib; 5 | requires static kotlin.stdlib.jdk7; 6 | requires static kotlin.stdlib.jdk8; 7 | 8 | exports org.ice1000.jimgui.dsl; 9 | } 10 | -------------------------------------------------------------------------------- /kotlin-dsl/src/JImGuiContext.kt: -------------------------------------------------------------------------------- 1 | package org.ice1000.jimgui.dsl 2 | 3 | import org.ice1000.jimgui.JImGui 4 | import org.ice1000.jimgui.NativeBool 5 | import org.ice1000.jimgui.flag.JImWindowFlags 6 | import org.intellij.lang.annotations.MagicConstant 7 | 8 | class JImGuiContext( 9 | width: Int = 1280, 10 | height: Int = 720, 11 | title: String = "Window created by JImGui Kotlin DSL", 12 | ) : JImGui(width, height, title) { 13 | inline operator fun String.invoke(block: JImGuiBlock) { 14 | begin(this@invoke) 15 | block() 16 | end() 17 | } 18 | 19 | inline operator fun String.invoke( 20 | pOpen: NativeBool, 21 | @MagicConstant(flagsFromClass = JImWindowFlags::class) 22 | flags: Flags = JImWindowFlags.None, 23 | block: JImGuiBlock, 24 | ) { 25 | begin(this@invoke, pOpen, flags) 26 | block() 27 | end() 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /kotlin-dsl/src/jimgui.kt: -------------------------------------------------------------------------------- 1 | @file:JvmName("KotlinDsl") 2 | @file:JvmMultifileClass 3 | 4 | package org.ice1000.jimgui.dsl 5 | 6 | import org.ice1000.jimgui.JImGui 7 | import org.ice1000.jimgui.JImGuiGen.* 8 | import org.ice1000.jimgui.JImStyleVar 9 | import org.ice1000.jimgui.NativeBool 10 | import org.ice1000.jimgui.flag.JImTabBarFlags 11 | import org.ice1000.jimgui.flag.JImTabItemFlags 12 | import org.ice1000.jimgui.flag.JImTreeNodeFlags 13 | import org.ice1000.jimgui.flag.JImWindowFlags 14 | import org.intellij.lang.annotations.MagicConstant 15 | 16 | inline fun JImGuiContext.mainMenuBar(block: JImGuiBlock) { 17 | if (beginMainMenuBar()) { 18 | block() 19 | endMainMenuBar() 20 | } 21 | } 22 | 23 | inline fun JImGuiContext.menuBar(block: JImGuiBlock) { 24 | if (beginMenuBar()) { 25 | block() 26 | endMenuBar() 27 | } 28 | } 29 | 30 | inline fun JImGuiContext.tabBar( 31 | stringId: StrID, 32 | @MagicConstant(flagsFromClass = JImTabBarFlags::class) 33 | flags: Flags = 0, 34 | block: JImGuiBlock, 35 | ) { 36 | if (beginTabBar(stringId, flags)) { 37 | block() 38 | endTabBar() 39 | } 40 | } 41 | 42 | inline fun JImGuiContext.tabItem( 43 | label: String, 44 | pOpen: NativeBool, 45 | @MagicConstant(flagsFromClass = JImTabItemFlags::class) 46 | flags: Flags = 0, 47 | block: JImGuiBlock, 48 | ) { 49 | if (beginTabItem(label, pOpen, flags)) { 50 | block() 51 | endTabItem() 52 | } 53 | } 54 | 55 | inline fun JImGuiContext.tabItem( 56 | label: String, 57 | @MagicConstant(flagsFromClass = JImTabItemFlags::class) 58 | flags: Flags = 0, 59 | block: JImGuiBlock, 60 | ) { 61 | if (beginTabItem(label, flags)) { 62 | block() 63 | endTabItem() 64 | } 65 | } 66 | 67 | inline fun JImGuiContext.collapsingHeader( 68 | label: String, 69 | pOpen: NativeBool, 70 | @MagicConstant(flagsFromClass = JImTreeNodeFlags::class) 71 | flags: Flags = 0, 72 | block: JImGuiBlock, 73 | ) { 74 | if (collapsingHeader(label, pOpen, flags)) block() 75 | } 76 | 77 | inline fun JImGuiContext.collapsingHeader(label: String, pOpen: NativeBool, block: JImGuiBlock) { 78 | if (collapsingHeader(label, pOpen)) block() 79 | } 80 | 81 | inline fun JImGuiContext.button( 82 | text: String, 83 | width: Float = 0f, 84 | height: Float = 0f, 85 | block: JImGuiBlock, 86 | ) { 87 | if (button(text, width, height)) block() 88 | } 89 | 90 | inline fun JImGuiContext.menu(label: String, enabled: Boolean = true, block: JImGuiBlock) { 91 | if (beginMenu(label, enabled)) { 92 | block() 93 | endMenu() 94 | } 95 | } 96 | 97 | inline fun JImGuiContext.popup( 98 | id: StrID, 99 | @MagicConstant(flagsFromClass = JImWindowFlags::class) 100 | flags: Flags = JImWindowFlags.None, 101 | block: JImGuiBlock, 102 | ) { 103 | if (beginPopup(id, flags)) { 104 | block() 105 | endPopup() 106 | } 107 | } 108 | 109 | inline fun JImGuiContext.tooltip(block: JImGuiBlock) { 110 | beginTooltip() 111 | block() 112 | endTooltip() 113 | } 114 | 115 | inline fun JImGuiContext.group(block: JImGuiBlock) { 116 | beginGroup() 117 | block() 118 | endGroup() 119 | } 120 | 121 | inline fun JImGuiContext.treeNode(label: String, block: JImGuiBlock) { 122 | if (treeNode(label)) { 123 | block() 124 | treePop() 125 | } 126 | } 127 | 128 | inline fun JImGuiContext.child( 129 | strId: StrID, 130 | width: Float = 0f, 131 | height: Float = 0f, 132 | border: Boolean = false, 133 | block: JImGuiBlock, 134 | ) { 135 | if (beginChild0(strId, width, height, border)) { 136 | block() 137 | endChild() 138 | } 139 | } 140 | 141 | inline fun JImGuiContext.child( 142 | id: IntID, 143 | width: Float = 0f, 144 | height: Float = 0f, 145 | border: Boolean = false, 146 | @MagicConstant(flagsFromClass = JImWindowFlags::class) 147 | flags: Flags = JImWindowFlags.None, 148 | block: JImGuiBlock, 149 | ) { 150 | if (beginChild(id, width, height, border, flags)) { 151 | block() 152 | endChild() 153 | } 154 | } 155 | 156 | inline fun JImGuiContext.withStyle(styleVar: JImStyleVar, value: Float, block: JImGuiBlock) { 157 | pushStyleVar(styleVar, value) 158 | block() 159 | popStyleVar() 160 | } 161 | 162 | inline fun JImGuiContext.withStyle( 163 | styleVar: JImStyleVar, 164 | valueA: Float, 165 | valueB: Float, 166 | block: JImGuiBlock, 167 | ) { 168 | pushStyleVar(styleVar, valueA, valueB) 169 | block() 170 | popStyleVar() 171 | } 172 | -------------------------------------------------------------------------------- /kotlin-dsl/src/primitives.kt: -------------------------------------------------------------------------------- 1 | @file:JvmName("KotlinDsl") 2 | @file:JvmMultifileClass 3 | 4 | package org.ice1000.jimgui.dsl 5 | 6 | import org.ice1000.jimgui.* 7 | 8 | operator fun NativeInt.inc() = apply { increaseValue(1) } 9 | operator fun NativeInt.dec() = apply { increaseValue(-1) } 10 | operator fun NativeInt.plusAssign(value: Int) = increaseValue(value) 11 | operator fun NativeInt.minusAssign(value: Int) = increaseValue(-value) 12 | 13 | operator fun NativeLong.inc() = apply { increaseValue(1) } 14 | operator fun NativeLong.dec() = apply { increaseValue(-1) } 15 | operator fun NativeLong.plusAssign(value: Long) = increaseValue(value) 16 | operator fun NativeLong.minusAssign(value: Long) = increaseValue(-value) 17 | 18 | operator fun NativeDouble.plusAssign(value: Double) = increaseValue(value) 19 | operator fun NativeDouble.minusAssign(value: Double) = increaseValue(-value) 20 | 21 | operator fun NativeFloat.plusAssign(value: Float) = increaseValue(value) 22 | operator fun NativeFloat.minusAssign(value: Float) = increaseValue(-value) 23 | 24 | operator fun NativeBool.not() = apply { invertValue() } 25 | -------------------------------------------------------------------------------- /kotlin-dsl/src/types.kt: -------------------------------------------------------------------------------- 1 | @file:JvmName("KotlinDsl") 2 | @file:JvmMultifileClass 3 | 4 | package org.ice1000.jimgui.dsl 5 | 6 | typealias JImGuiBlock = JImGuiContext.() -> Unit 7 | typealias StrID = String 8 | typealias IntID = Int 9 | typealias Flags = Int 10 | typealias ImWChar = Short 11 | typealias ImU32 = Int 12 | -------------------------------------------------------------------------------- /kotlin-dsl/src/util.kt: -------------------------------------------------------------------------------- 1 | @file:JvmName("KotlinDsl") 2 | @file:JvmMultifileClass 3 | 4 | package org.ice1000.jimgui.dsl 5 | 6 | /** 7 | * Copied [org.ice1000.jimgui.util.JImGuiUtil.runPer] 8 | * to be inlined. 9 | * 10 | * @param millis Long millis 11 | * @param block [@kotlin.ExtensionFunctionType] Function1 12 | * @see org.ice1000.jimgui.util.JImGuiUtil.runPer(long, java.util.function.Consumer) 13 | */ 14 | inline fun runPer(millis: Long, block: JImGuiBlock) { 15 | JImGuiContext().use { imGui -> 16 | var latestRefresh = System.currentTimeMillis() 17 | /** Don't call it. */ 18 | while (!imGui.windowShouldClose()) { 19 | val currentTimeMillis = System.currentTimeMillis() 20 | val deltaTime = currentTimeMillis - latestRefresh 21 | Thread.sleep(deltaTime / 2) 22 | if (deltaTime > millis) { 23 | imGui.initNewFrame() 24 | block(imGui) 25 | imGui.render() 26 | latestRefresh = currentTimeMillis 27 | } 28 | } 29 | } 30 | } 31 | 32 | /** 33 | * Copied [org.ice1000.jimgui.util.JImGuiUtil.runPer] 34 | * to be inlined. 35 | * 36 | * @param millisSupplier Function0 provides millis 37 | * @param block [@kotlin.ExtensionFunctionType] Function1 38 | * @see org.ice1000.jimgui.util.JImGuiUtil.runPer(java.util.function.LongSupplier, java.util.function.Consumer) 39 | */ 40 | inline fun runPer(millisSupplier: () -> Long, block: JImGuiBlock) { 41 | JImGuiContext().use { imGui -> 42 | var latestRefresh = System.currentTimeMillis() 43 | var millis = millisSupplier() 44 | /** Don't call it. */ 45 | while (!imGui.windowShouldClose()) { 46 | val currentTimeMillis = System.currentTimeMillis() 47 | val deltaTime = currentTimeMillis - latestRefresh 48 | Thread.sleep(deltaTime / 2) 49 | if (deltaTime > millis) { 50 | imGui.initNewFrame() 51 | block(imGui) 52 | imGui.render() 53 | latestRefresh = currentTimeMillis 54 | millis = millisSupplier() 55 | } 56 | } 57 | } 58 | } 59 | 60 | /** 61 | * Copied [org.ice1000.jimgui.util.JImGuiUtil.runWithin] 62 | * to be inlined. 63 | * 64 | * @param millis Long 65 | * @param block [@kotlin.ExtensionFunctionType] Function1 66 | * @see org.ice1000.jimgui.util.JImGuiUtil.runWithin 67 | */ 68 | inline fun runWithin(millis: Long, block: JImGuiBlock) { 69 | JImGuiContext().use { imGui -> 70 | val end = System.currentTimeMillis() + millis 71 | /** Don't call it. */ 72 | while (!imGui.windowShouldClose() && System.currentTimeMillis() < end) { 73 | imGui.initNewFrame() 74 | block(imGui) 75 | imGui.render() 76 | } 77 | } 78 | } 79 | 80 | /** 81 | * Copied [org.ice1000.jimgui.util.JImGuiUtil.run] 82 | * to be inlined. 83 | * 84 | * @param block [@kotlin.ExtensionFunctionType] Function1 85 | * @see org.ice1000.jimgui.util.JImGuiUtil.run 86 | */ 87 | inline fun run(block: JImGuiBlock) { 88 | JImGuiContext().use { imGui -> 89 | /** Don't call it. */ 90 | while (!imGui.windowShouldClose()) { 91 | imGui.initNewFrame() 92 | block(imGui) 93 | imGui.render() 94 | } 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /kotlin-dsl/test/lice-test.kt: -------------------------------------------------------------------------------- 1 | package test 2 | 3 | import org.ice1000.jimgui.JImStyleVars 4 | import org.ice1000.jimgui.JImVec4 5 | import org.ice1000.jimgui.MutableJImVec4 6 | import org.ice1000.jimgui.cpp.DeallocatableObjectManager 7 | import org.ice1000.jimgui.dsl.JImGuiContext 8 | import org.ice1000.jimgui.dsl.runPer 9 | import org.ice1000.jimgui.dsl.treeNode 10 | import org.ice1000.jimgui.util.JniLoader 11 | import org.lice.core.SymbolList 12 | import org.lice.model.ExpressionNode 13 | import org.lice.model.Node 14 | import org.lice.model.SymbolNode 15 | import org.lice.model.ValueNode 16 | import org.lice.parse.Lexer 17 | import org.lice.parse.Parser 18 | import java.awt.Color 19 | 20 | fun fromAWT(color: Color) = MutableJImVec4(color.red / 256f, 21 | color.green / 256f, 22 | color.blue / 256f, 23 | color.alpha / 256f) 24 | 25 | fun main() { 26 | JniLoader.load() 27 | val sourceCode = JImGuiContext::class.java 28 | .getResource("/bizarre.lice").readText() 29 | val sourceCodeLines = sourceCode.split(System.lineSeparator()) 30 | val liceAST = Parser 31 | .parseTokenStream(Lexer(sourceCode)) 32 | .accept(SymbolList()) 33 | val keywords = fromAWT(Color.decode("#CC7832")) 34 | val strings = fromAWT(Color.decode("#6A8759")) 35 | val numbers = fromAWT(Color.decode("#6897BB")) 36 | val manager = DeallocatableObjectManager(listOf(keywords, strings, numbers)) 37 | val codeColors = arrayOfNulls(sourceCode.length) 38 | val eolLen = System.lineSeparator().length 39 | 40 | fun colorizeNode(root: Node, color: JImVec4) { 41 | val metaData = root.meta 42 | val startOffset = sourceCodeLines 43 | .subList(0, metaData.beginLine - 1) 44 | .sumBy { it.length } + metaData.beginIndex + (metaData.beginLine - 2) * eolLen 45 | val endOffset = sourceCodeLines 46 | .subList(0, metaData.endLine - 1) 47 | .sumBy { it.length } + metaData.endIndex - 1 + (metaData.endLine - 2) * eolLen 48 | for (offset in startOffset..endOffset) codeColors[offset] = color 49 | } 50 | 51 | fun colorizeAST(root: Node) { 52 | when (root) { 53 | is ValueNode -> { 54 | val value = root.eval() 55 | if (value is String) colorizeNode(root, strings) 56 | else if (value is Number) colorizeNode(root, numbers) 57 | } 58 | is ExpressionNode -> { 59 | colorizeAST(root.node) 60 | root.params.forEach(::colorizeAST) 61 | } 62 | is SymbolNode -> if (root.name.startsWith("def") || 63 | root.name == "lazy" || 64 | root.name == "if" || 65 | root.name == "while" || 66 | root.name == "when" || 67 | root.name == "lambda" || 68 | root.name == "expr") 69 | colorizeNode(root, keywords) 70 | } 71 | } 72 | colorizeAST(liceAST) 73 | 74 | runPer(15) { 75 | "Lice AST" { displayAST(liceAST, this) } 76 | "Source Code" { 77 | pushStyleVar(JImStyleVars.ItemSpacing, 0f, 2f) 78 | var tokenStart = 0 79 | var attributeSet = codeColors[0] 80 | codeColors[0] = null 81 | for (i in codeColors.indices) { 82 | val isEol = sourceCode[i] == '\n' 83 | if (attributeSet != codeColors[i] || isEol) { 84 | val token = sourceCode.substring(tokenStart, i) 85 | if (attributeSet != null) 86 | textColored(attributeSet, token) 87 | else text(token) 88 | if (attributeSet === keywords && isItemHovered) 89 | setTooltip("Keyword: $token") 90 | if (!isEol) sameLine() 91 | tokenStart = if (isEol) i + eolLen else i 92 | attributeSet = codeColors[i] 93 | } 94 | } 95 | popStyleVar() 96 | } 97 | } 98 | manager.deallocateAll() 99 | } 100 | 101 | fun displayAST(root: Node, imgui: JImGuiContext): Unit = when (root) { 102 | is ValueNode -> imgui.text(root.toString()) 103 | is SymbolNode -> imgui.text(root.name) 104 | is ExpressionNode -> imgui.treeNode("${root.node}") { 105 | root.params.forEach { displayAST(it, imgui) } 106 | } 107 | else -> { 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /kotlin-dsl/test/psi-viewer.kt: -------------------------------------------------------------------------------- 1 | package test 2 | 3 | import org.ice1000.jimgui.dsl.runPer 4 | import org.ice1000.jimgui.dsl.treeNode 5 | import org.ice1000.jimgui.util.JniLoader 6 | 7 | fun main() { 8 | JniLoader.load() 9 | runPer(15) { 10 | "Psi Viewer" { 11 | treeNode("PsiFile") { 12 | treeNode("PsiImportStatement") { 13 | text("PsiLeafElement") 14 | text("PsiJavaReferenceExpression") 15 | } 16 | treeNode("PsiImportStatement") { 17 | text("PsiLeafElement") 18 | text("PsiJavaReferenceExpression") 19 | } 20 | treeNode("PsiClass") { 21 | text("PsiLeafElement") 22 | text("PsiIdentifier") 23 | text("PsiLeafElement") 24 | treeNode("PsiClassBody") { 25 | treeNode("PsiConstructor") { 26 | text("PsiLeafElement") 27 | text("PsiIdentifier") 28 | } 29 | treeNode("PsiMethod") { 30 | text("PsiAnnotation") 31 | text("PsiLeafElement") 32 | text("PsiIdentifier") 33 | } 34 | } 35 | text("PsiLeafElement") 36 | } 37 | } 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /kotlin-dsl/test/tabs.kt: -------------------------------------------------------------------------------- 1 | package test 2 | 3 | import org.ice1000.jimgui.dsl.runPer 4 | import org.ice1000.jimgui.dsl.tabBar 5 | import org.ice1000.jimgui.dsl.tabItem 6 | import org.ice1000.jimgui.util.JniLoader 7 | 8 | fun main() { 9 | JniLoader.load() 10 | runPer(10) { 11 | "Window with Tabs" { 12 | tabBar("tab bar id") { 13 | tabItem("Tab One") { text("I am in Tab one!") } 14 | tabItem("Tab Two") { button("I am in Tab two!") } 15 | tabItem("Tab Three") { bulletText("I am in Tab three!") } 16 | } 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /kotlin-dsl/test/test.kt: -------------------------------------------------------------------------------- 1 | package test 2 | 3 | import org.ice1000.jimgui.JImGuiGen.popID 4 | import org.ice1000.jimgui.dsl.* 5 | import org.ice1000.jimgui.util.JniLoader 6 | 7 | fun main() { 8 | JniLoader.load() 9 | runPer(15) { 10 | pushID("WtfID") 11 | "Window 2" { 12 | menuBar { 13 | menu("What?") { 14 | menuItem("Secret places, we don't fight fair~") 15 | } 16 | } 17 | } 18 | mainMenuBar { 19 | menu("File") { 20 | menu("New") { 21 | menuItem("Kotlin File") 22 | menuItem("Script") 23 | } 24 | menuItem("Open...") 25 | } 26 | menu("Edit") { 27 | menuItem("Copy", "Ctrl+C") 28 | } 29 | } 30 | treeNode("Platforms") { 31 | treeNode("JVM") { 32 | treeNode("Kotlin") { 33 | if (isItemHovered) tooltip { text("This is an aji language") } 34 | text("Kotlin JVM") 35 | text("Kotlin Native") 36 | text("Kotlin JavaScript") 37 | } 38 | treeNode("Scala") { 39 | text("Scala JVM") 40 | text("Scala Native") 41 | text("Scala JavaScript") 42 | } 43 | text("Java") 44 | } 45 | treeNode("CLR") { 46 | text("Visual C#") 47 | text("Visual F#") 48 | text("Visual Basic .NET") 49 | text("IronRuby") 50 | text("IronPython") 51 | } 52 | } 53 | button("Reiuji Utsuho") 54 | button("Show completions") { 55 | openPopup("WtfID") 56 | } 57 | popup("WtfID") { 58 | text("System.out.println") 59 | text("System") 60 | text("Security") 61 | } 62 | popID() 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /kotlin-dsl/test/texture.kt: -------------------------------------------------------------------------------- 1 | package test 2 | 3 | import org.ice1000.jimgui.JImGui 4 | import org.ice1000.jimgui.JImGui.getWindowHeight 5 | import org.ice1000.jimgui.JImGui.getWindowWidth 6 | import org.ice1000.jimgui.JImTextureID 7 | import org.ice1000.jimgui.util.JniLoader 8 | 9 | class PlaceHolder 10 | 11 | fun main() { 12 | JniLoader.load() 13 | JImGui().use { imGui -> 14 | var latestRefresh = System.currentTimeMillis() 15 | val texture = JImTextureID.fromBytes(PlaceHolder::class.java.getResourceAsStream("/pics/ice1000.png").readBytes()) 16 | /** Don't call it. */ 17 | while (!imGui.windowShouldClose()) { 18 | val currentTimeMillis = System.currentTimeMillis() 19 | val deltaTime = currentTimeMillis - latestRefresh 20 | if (deltaTime > 16.toLong()) { 21 | imGui.initNewFrame() 22 | if (System.currentTimeMillis() % 1500 < 750) 23 | imGui.image(texture, texture.width.toFloat(), texture.height.toFloat()) 24 | else 25 | imGui.image(texture, getWindowWidth(), getWindowHeight()) 26 | imGui.render() 27 | latestRefresh = currentTimeMillis 28 | } 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /kotlin-dsl/testRes/bizarre.lice: -------------------------------------------------------------------------------- 1 | ;; 2 | ;; Created by ice1000 on 2018-05-07 3 | ;; 4 | 5 | ;; comments 6 | (def fib n 7 | (if (in? (list 1 2) n) 8 | 1 9 | (+ (fib (- n 1)) (fib (- n 2))))) 10 | 11 | ;; travel through a range 12 | (for-each i (.. 1 10) (print i " ")) 13 | 14 | (|> 15 | (println "DIO! The World!")) 16 | 17 | ((if (in? (list 1 2 3) 6) 18 | + 19 | -) 1 2 3) 20 | 21 | (list->array (distinct (union 22 | (split "It was me, DIO!", " ") 23 | (list "Hello" "World") 24 | (array->list (array "DIO!" "The" "World"))))) 25 | 26 | ; define a call-by-name function 27 | (defexpr fold ls init op 28 | (for-each index-var ls 29 | (-> init (op init index-var)))) 30 | fold 31 | ; invoke the function defined above 32 | (fold (.. 1 5) 0 +) 33 | 34 | ; passing a call-by-value lambda to a call-by-value lambda 35 | ((lambda op (op 3 4)) 36 | (lambda a b (+ (* a a) (* b b)))) 37 | 38 | ;; command line output 39 | (print "String literals", ) 40 | 41 | ;; unresolved reference 42 | (println unresolved-reference) 43 | 44 | ;; omega-combinator 45 | ((lambda x (x x)) (lambda x (x x))) 46 | 47 | ((lambda l 48 | (l "qaq" "qaq" "qaq")) 49 | (lambda a b c (|> 50 | (print a) 51 | (print (str-con " " b)) 52 | (print c)))) 53 | 54 | 55 | -------------------------------------------------------------------------------- /settings.gradle.kts: -------------------------------------------------------------------------------- 1 | include("core", "kotlin-dsl", /*"extension",*/ "fun") 2 | --------------------------------------------------------------------------------