{"id":13496017,"url":"https://github.com/msink/kotlin-libui","last_synced_at":"2025-04-04T10:09:07.009Z","repository":{"id":37733866,"uuid":"133135153","full_name":"msink/kotlin-libui","owner":"msink","description":"Kotlin/Native interop to libui: a portable GUI library","archived":false,"fork":false,"pushed_at":"2023-10-24T02:42:33.000Z","size":14339,"stargazers_count":658,"open_issues_count":21,"forks_count":51,"subscribers_count":18,"default_branch":"master","last_synced_at":"2025-03-28T09:08:25.113Z","etag":null,"topics":["desktop","gui","kotlin","kotlin-native","libui","portable"],"latest_commit_sha":null,"homepage":"","language":"Kotlin","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/msink.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2018-05-12T10:15:44.000Z","updated_at":"2025-03-26T18:30:49.000Z","dependencies_parsed_at":"2024-01-16T10:09:05.566Z","dependency_job_id":null,"html_url":"https://github.com/msink/kotlin-libui","commit_stats":null,"previous_names":[],"tags_count":21,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/msink%2Fkotlin-libui","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/msink%2Fkotlin-libui/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/msink%2Fkotlin-libui/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/msink%2Fkotlin-libui/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/msink","download_url":"https://codeload.github.com/msink/kotlin-libui/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247157283,"owners_count":20893220,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["desktop","gui","kotlin","kotlin-native","libui","portable"],"created_at":"2024-07-31T19:01:40.765Z","updated_at":"2025-04-04T10:09:06.985Z","avatar_url":"https://github.com/msink.png","language":"Kotlin","funding_links":[],"categories":["Kotlin","Libraries"],"sub_categories":["GUI"],"readme":"kotlin-libui\n============\n\n[Kotlin/Native](https://github.com/JetBrains/kotlin-native) bindings to the\n[libui](https://github.com/andlabs/libui.git) C library.\n\n[![Build Status](https://travis-ci.org/msink/kotlin-libui.svg?branch=master)](https://travis-ci.org/msink/kotlin-libui)\n[![Build status](https://ci.appveyor.com/api/projects/status/github/msink/kotlin-libui?svg=true)](https://ci.appveyor.com/project/msink/kotlin-libui)\n\nlibui is a C lightweight multi-platform UI library using native widgets on Linux (Gtk3), macOS, and Windows.\nUsing this bindings you can develop cross-platform but native-looking GUI programs, written in Kotlin,\nand compiled to small native executable file.\n\n## Using\n\nTo use this library in your project you can clone [Hello World](https://github.com/msink/hello-libui.git)\napplication and use it as starting point.\n\n## Building\n\nCross-platform build is automated using [Travis](https://travis-ci.org) for Linux and macOS targets, and\n[AppVeyor](https://ci.appveyor.com) for Windows targets. Just create release on GitHub, and executable files\nfor all 3 major desktop platforms will be compiled and attached to release.\n\nFor local build use `./gradlew build` on Linux or macOS, or `gradlew build` on Windows.\nIn this case only one - native for your platform - file will be built.\n\nThe script below builds kotlin-libui then builds and runs the sample `hello-ktx`:\n\n```\n#clone this project\ngit clone https://github.com/msink/kotlin-libui.git\n\n#build libui.klib\ncd kotlin-libui/libui\n../gradlew build\n\n#build and run the hello-ktx sample\ncd ../samples/hello-ktx/\n../../gradlew run\n```\n\nYou can use IntelliJ IDEA CE/UE or CLion EAP for code navigation and code completion, debugging works only in CLion.\n\n## Status\n\n**Warning:** currently it is just a prototype - works in most cases, but not protected from errors.\nAnd as both libui and Kotlin/Native are currently in alpha stage, anything can change.\n\nWell, I'm also not sure about DSL syntax - it works, and for now is good enough.\nLet's leave it as is for a while.\n\nIf anyone have ideas - Issues and PullRequests are welcome.\n\n## Hello World\n\nLet's start from minimal sample application - single button and single scrollable text area.\n\n\u003cdetails\u003e\n \u003csummary\u003eScreenshots:\u003c/summary\u003e\n\n![Windows](samples/hello/hello-windows.png)\n\n![Unix](samples/hello/hello-linux.png)\n\n![macOS](samples/hello/hello-osx.png)\n\u003c/details\u003e\u003cbr/\u003e\n\n\u003cdetails\u003e\n \u003csummary\u003eC implementation:\u003c/summary\u003e\n    \n``` c\n#include \"ui.h\"\n\nstatic int onClosing(uiWindow *window, void *data)\n{\n    uiQuit();\n    return 1;\n}\n\nstatic void saySomething(uiButton *button, void *data)\n{\n    uiMultilineEntryAppend(uiMultilineEntry(data),\n        \"Hello, World!  Ciao, mondo!\\n\"\n        \"Привет, мир!  你好，世界！\\n\\n\");\n}\n\nint main(void)\n{\n    uiInitOptions options;\n    uiWindow *window;\n    uiBox *box;\n    uiButton *button;\n    uiMultilineEntry *scroll;\n\n    memset(\u0026options, 0, sizeof(options));\n    if (uiInit(\u0026options) != NULL)\n        abort();\n\n    window = uiNewWindow(\"Hello\", 320, 240, 0);\n    uiWindowSetMargined(window, 1);\n\n    box = uiNewVerticalBox();\n    uiBoxSetPadded(box, 1);\n    uiWindowSetChild(window, uiControl(box));\n\n    scroll = uiNewMultilineEntry();\n    uiMultilineEntrySetReadOnly(scroll, 1);\n\n    button = uiNewButton(\"libui говорит: click me!\");\n    uiButtonOnClicked(button, saySomething, scroll);\n    uiBoxAppend(box, uiControl(button), 0);\n\n    uiBoxAppend(box, uiControl(scroll), 1);\n\n    uiWindowOnClosing(window, onClosing, NULL);\n    uiControlShow(uiControl(window));\n    uiMain();\n    return 0;\n}\n```\n\u003c/details\u003e\u003cbr/\u003e\n\n\u003cdetails\u003e\n \u003csummary\u003eDirect translation to Kotlin:\u003c/summary\u003e\n    \n``` kt\nimport kotlinx.cinterop.*\nimport libui.*\n\nfun main(args: Array\u003cString\u003e) = memScoped {\n    val options = alloc\u003cuiInitOptions\u003e()\n    val error = uiInit(options.ptr)\n    if (error != null) throw Error(\"Error: '${error.toKString()}'\")\n\n    val window = uiNewWindow(\"Hello\", 320, 240, 0)\n    uiWindowSetMargined(window, 1)\n\n    val box = uiNewVerticalBox()\n    uiBoxSetPadded(box, 1)\n    uiWindowSetChild(window, box?.reinterpret())\n\n    val scroll = uiNewMultilineEntry()\n    uiMultilineEntrySetReadOnly(scroll, 1)\n    val button = uiNewButton(\"libui говорит: click me!\")\n    fun saySomething(button: CPointer\u003cuiButton\u003e?, data: COpaquePointer?) {\n        uiMultilineEntryAppend(data?.reinterpret(),\n            \"Hello, World!  Ciao, mondo!\\n\" +\n            \"Привет, мир!  你好，世界！\\n\\n\")\n    }\n    uiButtonOnClicked(button, staticCFunction(::saySomething), scroll)\n    uiBoxAppend(box, button?.reinterpret(), 0)\n    uiBoxAppend(box, scroll?.reinterpret(), 1)\n\n    fun onClosing(window: CPointer\u003cuiWindow\u003e?, data: COpaquePointer?): Int {\n        uiQuit()\n        return 1\n    }\n    uiWindowOnClosing(window, staticCFunction(::onClosing), null)\n    uiControlShow(window?.reinterpret())\n    uiMain()\n    uiUninit()\n}\n```\n\u003c/details\u003e\u003cbr/\u003e\n\nWhile this works, it's far from idiomatic Kotlin.\n\nOK, let's wrap all that noisy function calls, with final goal to get something similar to [TornadoFX](https://github.com/edvin/tornadofx):\n\n``` kt\nimport libui.*\n\nfun main(args: Array\u003cString\u003e) = appWindow(\n    title = \"Hello\",\n    width = 320,\n    height = 240\n) {\n    vbox {\n        lateinit var scroll: TextArea\n\n        button(\"libui говорит: click me!\") {\n            action {\n                scroll.append(\"\"\"\n                    |Hello, World!  Ciao, mondo!\n                    |Привет, мир!  你好，世界！\n                    |\n                    |\"\"\".trimMargin())\n            }\n        }\n        scroll = textarea {\n            readonly = true\n            stretchy = true\n        }\n    }\n}\n```\n\n## More samples\n\n- [simple form](samples/form)\n- [controls gallery](samples/controlgallery)\n- [histogram](samples/histogram)\n- [drawtext](samples/drawtext)\n- [datetime](samples/datetime)\n- [timer](samples/timer)\n- [logo](samples/logo)\n- [table](samples/table)\n\n## Documentation\n\nSee [autogenerated documentation](docs/index.md), samples and comments in source code.\n\n### Lifecycle management\n\nKotlin memory management differs from native C model, so all libui objects are wrapped in Kotlin objects\ninherited from [Disposable](docs/libui.ktx/-disposable/index.md), and direct using of libui functions is\nnot recommended in most cases.\n\nDisposable objects must be disposed by calling [dispose](docs/libui.ktx/-disposable/dispose.md)() method,\nbefore program ends. Most objects are attached as a child to some other object, in this case parent is\nresponsible to dispose all its children, recursively. As DSL builders automatically add created object to\nsome container - in most cases you do not have to worry about lifecycle management. But if you want to do\nsomething not supported by DSL builders - you can create Disposable object directly, and in this case\n*you* are responsible to dispose or attach it at some point.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmsink%2Fkotlin-libui","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmsink%2Fkotlin-libui","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmsink%2Fkotlin-libui/lists"}