haskell-game / dear-imgui.hs Goto Github PK
View Code? Open in Web Editor NEWHaskell bindings to Dear ImGui, an immediate mode GUI toolkit
License: BSD 3-Clause "New" or "Revised" License
Haskell bindings to Dear ImGui, an immediate mode GUI toolkit
License: BSD 3-Clause "New" or "Revised" License
stack.yaml
:
packages:
- .
- /.../dear-imgui.hs
package.yaml
:
dependencies:
- base >= 4.7 && < 5
- dear-imgui
$ stack build
cabal file path /home/sino/github/dear-imgui.hs/hs-dear-imgui.cabal does not match the package name it defines.
Please rename the file to: dear-imgui.cabal
For more information, see: https://github.com/commercialhaskell/stack/issues/317
Hi all,
thanks for your work! Is there any chance to have the package relased on Hackage? Any blockers?
Thanks,
Andrea
With the user-facing API decoupled, it is possible to expand raw bindings without stirring the bikeshedding gods.
I noticed that the demo app was using ~ 86% of a cpu core,
on the chance that its because of the default renderloop never sleeping, i added a threadDelay 10_000
to the end of the loop and my CPU usage went down to like ~ 15%. I also disabled Idle gc for now (yeolde +RTS I0 flage)
I think the "at scale" approach is probably using sleeping semantics that wakeup either after an idle period or when inputs over a large enough time interval to debounce or whatever "simultaneous keys" is done, probably using MVars or STM. But what are suggested best practices?
https://github.com/ocornut/imgui/releases/tag/v1.87
There are some breaking changes and the generator is failing:
generator/DearImGui/Generator.hs:72:11: error:
• Exception when trying to run compile-time code:
Couldn't parse Dear ImGui headers:
offset=9459:
Couldn't lookup the following values in enum ImGuiKey_:
- ImGuiKey_COUNT
Number 512.0 ""
ReservedSymbol ','
Identifier "ImGuiKey_NamedKey_END"
ReservedSymbol '='
Identifier "ImGuiKey_COUNT"
ReservedSymbol ','
Identifier "ImGuiKey_NamedKey_COUNT"
ReservedSymbol '='
Identifier "ImGuiKey_NamedKey_END"
Symbolic "-"
Identifier "ImGuiKey_NamedKey_BEGIN"
ReservedSymbol ','
BeginCPP "ifdef"
Identifier "IMGUI_DISABLE_OBSOLETE_KEYIO"
EndCPPLine
Identifier "ImGuiKey_KeysData_SIZE"
ReservedSymbol '='
Identifier "ImGuiKey_NamedKey_COUNT"
ReservedSymbol ','
Comment "Size of KeysData[]: only hold named keys"
CallStack (from HasCallStack):
error, called at generator/DearImGui/Generator.hs:87:9 in dear-imgui-1.3.1-inplace-dear-imgui-generator:DearImGui.Generator
Code: do currentPath <- TH.loc_filename <$> TH.location
basicHeaders <- TH.runIO
do headersPath <- canonicalizePath
(takeDirectory currentPath
<> "/../../imgui/imgui.h")
....
TH.lift $ generateNames basicHeaders
• In the untyped splice:
$(do currentPath <- TH.loc_filename <$> TH.location
basicHeaders <- TH.runIO
do headersPath <- canonicalizePath
(takeDirectory currentPath
<> "/../../imgui/imgui.h")
headersSource <- Text.readFile headersPath
....
TH.lift $ generateNames basicHeaders)
|
72 | headers = $( do
| ^^^^^...
Is there any situation in which users might need to use beginXXX
/endXXX
in an atypical way? As far as I understand:
begin
/end
, beginChild
/endChild
, beginGroup
/endGroup
, beginTooltip
/endTooltip
, beginChildFrame
/endChildFrame
must always occur in matching pairs, so we can replace them with simple with
-style functions,beginCombo
/endCombo
, beginListBox
/endListBox
, beginMenuBar
/endMenuBar
, beginMainMenuBar
/endMainMenuBar
, beginPopup
/endPopup
, beginTable
/endTable
, beginTabBar
/endTabBar
, beginDragDropSource
/endDragDropSource
, beginDragDropTarget
/endDragDropTarget
all require a matching end
function precisely when the begin
function returned True
. Is there any other way to use them than with the whenTrue
idiom we are currently using in the example?If there is literally no other valid usage pattern, I would recommend entirely replacing the beginXXX
/endXXX
functions with bracketed functions. Then users aren't confused about which one to use, and can't get it wrong.
If there are valid usage patterns, then of course we should keep the individual beginXXX
/endXXX
functions, and provide additional helpers.
These 3 functions return a reference.
GetStyleColorVec4
seems to just be used to pass a reference to PushStyleColor
, so I don't think we need to do anything special.
On the other hand, GetIO
and GetStyle
allow the user to change internal ImGui settings by mutating the state. So I think we might want a slightly different API. For instance, we could have:
data ImGuiIO = ImGuiIOHandle ( Ptr ImGuiIO )
data ImGuiStyle = ImGuiStyleHandle ( Ptr ImGuiStyle )
getIO :: MonadIO m => m ImGuiIO
getStyle :: MonadIO m => m ImGuiStyle
and then an interface for getting/setting fields:
data ImGuiIOFieldName
= ConfigFlags
| BackendFlags
| DisplaySize
| DeltaTime
...
data ImGuiStyleFieldName
= Alpha
| WindowPadding
| WindowRounding
...
class HasImGuiIOField ( name :: ImGuiIOFieldName ) ( a :: Type ) | name -> a where
getIOField :: ImGuiIO -> m a
setIOField :: ImGuiIO -> a -> m ()
class ImGuiStyleField ( name :: ImGuiStyleFieldName ) ( a :: Type ) | name -> a where
getStyleField :: ImGuiStyle -> m a
setStyleField :: ImGuiStyle -> a -> m ()
instance HasImGuiIOField 'ConfigFlags ImGuiConfigFlags
instance HasImGuiIOField 'BackendFlags ImGuiBackendFlags
instance HasImGuiIOField 'DisplaySize ImVec4
instance HasImGuiIOField 'DeltaTime Float
instance HasImGuiStyleField 'Alpha Float
instance HasImGuiStyleField 'WindowPadding ImVec2
instance HasImGuiStyleField 'WindowRounding Float
This would definitely be an improvement in usability over manually mutating fields through the reference.
Another upside is that it avoids us having to actually define the ImGuiIO
and ImGuiStyle
structs proper: we can just implement whatever get
/set
operations we want. I think this is particularly relevant with the function pointers in the ImGuiIO
struct like GetClipboardTextFn
, SetClipboardTextFn
, where it seems much more appropriate to have a HasImGuiIOField
instance for 'ClipboardTextFn
as opposed to requiring the user to manage two different function pointers.
Hi, thanks for coming to see how you can help! We need help in a variety of places:
A good starting point is to add bindings to more functions. We're trying to implement all of imgui.h
. If you head down the line namespace ImGui
, you should find the majority of ImGui's functions. Go through this list and see if you can spot anything that's not in DearImGui.hs
. If there's something missing, please help us add it!
ImGui ships with a variety of different backends, and we currently only support a handful. Implementing a backend is similar to wrapping functions - open up the relevant .h
file and create a corresponding .hs
module and then wrap each function. Check the other implemented backends for reference, and if you get stuck raise an issue and we'll help
Dear ImGui has a rich and active community with lots of contributed extensions. We'd love to have wrappers for these, too! The list is constantly growing, but the "Useful Widgets" wiki page shows a lot of projects.
A great way to help us find out if this library is useful is to just use it! Try making some cool stuff and see what you think. Any feedback is appreciated.
There is a Matrix room set up - if you have any questions or just want to come hang out, come join!
I wanted to use this, but could not find it in Hackage. It must be there to support my workflow. So when do you intend to place it there?
Thanks.
I was looking through C++ code and found that it assumes its text data is in UTF-8.
This may not be necessarily the case, since Foreign.withCString
is locale-dependent and some users may have ASCII/C or some other national locales. This regularly trips up Windows users with symptoms like "invalid argument (invalid character)".
Besides, using withCString
will waste CPU on the same [Char] -> CString
conversion for every call on every frame. While the raw bindings are exempt from this churn, the library can provide smart constructors that will take in something like Text
, encode to UTF8 ByteString
once and then use its pointer for raw calls. Anyway, even with Text-to-BS encoding happening every frame at least it will be correct for any environment.
https://github.com/cimgui/cimgui
This may, or may not, alleviate our extension pains.
// GLFW callbacks
// - When calling Init with 'install_callbacks=true': GLFW callbacks will be installed for you. They will call user's previously installed callbacks, if any.
// - When calling Init with 'install_callbacks=false': GLFW callbacks won't be installed. You will need to call those function yourself from your own GLFW callbacks.
IMGUI_IMPL_API void ImGui_ImplGlfw_WindowFocusCallback(GLFWwindow* window, int focused);
IMGUI_IMPL_API void ImGui_ImplGlfw_CursorEnterCallback(GLFWwindow* window, int entered);
IMGUI_IMPL_API void ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow* window, int button, int action, int mods);
IMGUI_IMPL_API void ImGui_ImplGlfw_ScrollCallback(GLFWwindow* window, double xoffset, double yoffset);
IMGUI_IMPL_API void ImGui_ImplGlfw_KeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods);
IMGUI_IMPL_API void ImGui_ImplGlfw_CharCallback(GLFWwindow* window, unsigned int c);
IMGUI_IMPL_API void ImGui_ImplGlfw_MonitorCallback(GLFWmonitor* monitor, int event);
The code is not a big deal by itself, but require a window pointer that isn't published in GLFW-b
.
The original uses variable args, but the bindings pass text as a single argument.
[C.exp| void { Text("%s", $(char* textPtr)) } |]
Either some type trickery is in order, or documentation tweak.
I've been playing with Yampa and this lib lately. I'm facing the issue where I need to split code for rendering new frames into different yampa's signal functions. After splitting code for rendering frames I get this error:
Assertion failed: g.WithinFrameScope && "Forgot to call ImGui::NewFrame()?"
This is just minimal example:
mainSF:: SDL.Window -> SF (Event SDL.EventPayload) (IOProgramRWSType Bool)
mainSF window = beginRender >>> middleRender >>> (endRender window)
beginRender:: SF (Event SDL.EventPayload) (IOProgramRWSType (Event SDL.EventPayload))
beginRender = arr (\i -> do
openGL3NewFrame
sdl2NewFrame
newFrame
return i
)
middleRender:: SF (IOProgramRWSType (Event SDL.EventPayload)) (IOProgramRWSType Bool)
middleRender= arr (\_ -> do
t <- get >>= \x -> return $ view (intermediateState . blueishTexture) x
liftIO $ buttonWindow t
)
endRender:: SDL.Window -> SF (IOProgramRWSType Bool) (IOProgramRWSType Bool)
endRender window = arr (\i -> do
liftIO $ do
glClear GL_COLOR_BUFFER_BIT
DearImGui.render
DearImGui.getDrawData >>= openGL3RenderDrawData
SDL.glSwapWindow window
i
)
MainSF is signal function for Yampa's reactimate.
IOProgramRWSType is RWST monad with IO.
ButtonWindow is just button which returns IO bool (isClicked).
Is there a way on how I can split rendering new frames? I don't want to lose the yampa's functionality where I can detect the signals from different windows and do fancy stuff with them.
Currently, dear-imgui.hs is marked as broken on nixpkgs. Temporarily allowing broken packages gives the following error:
@nix { "action": "setPhase", "phase": "configurePhase" }
configuring
configureFlags: --verbose --prefix=/nix/store/r0z0xjm7p1cdsz1am22rswl97y6fg5vq-dear-imgui-2.1.3 --libdir=$prefix/lib/$compiler --libsubdir=$abi/$libname --with-gcc=gcc --package-db=/build/tmp.qo7rfeAam4/packa>Using Parsec parser
Configuring dear-imgui-2.1.3...
Setup: Encountered missing or private dependencies:
megaparsec >=9.0 && <9.3
Ignoring dependency bounds with haskell-flake produces a different error:
error: builder for '/nix/store/5mr7mfnacvzynjizdr3xqkq488mk7ayh-source-dear-imgui-sdist.tar.gz.drv' failed with exit code 1;
last 8 log lines:
> unpacking source archive /nix/store/gfanl0krmlsgv2ij5x3nfslh2dfk1c7c-source-dear-imgui
> source root is source-dear-imgui
> Config file path source is default config file.
> Config file not found: /build/source-dear-imgui/.config/cabal/config
> Writing default configuration to /build/source-dear-imgui/.config/cabal/config
> Error: cabal: sdist of dear-imgui-2.1.3: filepath wildcard 'imgui/*.h' does
> not match any files.
>
For full logs, run 'nix log /nix/store/5mr7mfnacvzynjizdr3xqkq488mk7ayh-source-dear-imgui-sdist.tar.gz.drv'.
error: 1 dependencies of derivation '/nix/store/pjll751gmfh225wxiadrd94b90s7zc9q-dear-imgui-2.1.3.drv' failed to build
I am using pkgs.haskell.packages.ghc92 (ghc 9.2.8) for my project.
It is ImGuiTabBarFlags.
Should be ImGuiTabItemFlags
instead.
IMGUI_API bool BeginTabItem(const char* label, bool* p_open = NULL, ImGuiTabItemFlags flags = 0);
// create a Tab. Returns true if the Tab is selected.
I was building a minimal example based on the code in the readme: https://github.com/ad-si/dear-imgui-test (Only changes: using OpenGL3).
However, it just opens a blank black screen and I'm getting following error:
$ stack run
ERROR: ImGui_ImplOpenGL3_CreateDeviceObjects: failed to compile vertex shader! With GLSL: #version 150
ERROR: 0:1: '' : version '150' is not supported
ERROR: ImGui_ImplOpenGL3_CreateDeviceObjects: failed to compile fragment shader! With GLSL: #version 150
ERROR: 0:1: '' : version '150' is not supported
ERROR: ImGui_ImplOpenGL3_CreateDeviceObjects: failed to link shader program! With GLSL #version 150
ERROR: One or more attached shaders not successfully compiled
My system:
OS: macOS 13.6.2 22G320 arm64
Host: MacBookPro18,3
Kernel: 22.6.0
CPU: Apple M1 Pro
GPU: Apple M1 Pro
Memory: 3127MiB / 16384MiB
https://github.com/ocornut/imgui/blob/master/imconfig.h
A) You may edit imconfig.h (and not overwrite it when updating Dear ImGui, or maintain a patch/rebased branch with your modifications to it)
B) or '#define IMGUI_USER_CONFIG "my_imgui_config.h"' in your project and then add directives in your own file without touching this template.
In 1d6b7cc
dear-imgui
appears to build fine with 0.2.15, but its cabal file forbids it.
The sliderScalar
function takes three scalar values: the slider setting, which must be read and updated, and the low and high values of the range, which only need to be read. However, the type used for both is
(HasSetter ref a, HasGetter ref a) => ref
This means that we have to create (e.g.) IORef
containers for the bounds, instead of just passing pure lo
. This isn't an enormous problem -- we can just create new IORef
s before calling sliderScalar
and they'lll be GCed after the call -- but it's one more thing to remember, and the range references don't need the extra power.
I therefore suggest that the references work the same as in sliderScalarN
, separating valueRef
from rangeRef
. The new signature of sliderScalar
would thus be
sliderScalar
:: (HasSetter valueRef a, HasGetter valueRef a, HasGetter rangeRef a, Storable a, MonadIO m)
=> String -> ImGuiDataType -> valueRef -> rangeRef -> rangeRef -> String -> ImGuiSliderFlags -> m Bool
In fact, I think that the signature is the only change that would have to be made.
When running:
$ cabal repl exe:glfw
[1 of 1] Compiling Main ( examples/glfw/Main.hs, interpreted )
Ok, one module loaded.
ghci> Main.main
[blank window appears]
Note that this work with exe:vulkan
: the dear-imgui window is displayed.
What could be the issue?
However, ....
https://github.com/ocornut/imgui/releases/tag/v1.84
Backends: GLFW: backend uses glfwSetCursorEnterCallback() + glfwSetWindowFocusCallback() (#3751, #4377, #2445, #4388)
- If calling ImGui_ImplGlfw_InitXXX with install_callbacks=true: this is already done for you.
- If calling ImGui_ImplGlfw_InitXXX with install_callbacks=false: you WILL NEED to register the GLFW callbacks and forward them to the backend:
- Register glfwSetCursorEnterCallback, forward events to ImGui_ImplGlfw_CursorEnterCallback().
- Register glfwSetWindowFocusCallback, forward events to ImGui_ImplGlfw_WindowFocusCallback().
It seems fairly obvious that a bracket-style scoping of ImGuiContext mutation should be supported per the dear-imgui.hs API. My intuition says to more-or-less implement a function such as:
setStyleVar :: (MonadIO m) => StyleVar -> StyleVarValue -> m a -> m a
setStyleVars :: (MonadIO m) => [(StyleVar, StyleVarValue)] -> m a -> m a
this would effectively invoke pushStyleVar with its first two parameters, invoke the provided MonadIO instance, and then invoke popStyleVar.
Last time i accidentally had checked out the wrong branch on imgui locally (using master instead of v1.87) it compiled flawlessly.
However there is at least one "breaking" change i am aware of when the new implot-version broke my generator:
https://github.com/epezent/implot/blob/master/implot.h#L545-L552
#if (IMGUI_VERSION_NUM < 18716) // Renamed in 1.88
#define ImGuiModFlags ImGuiKeyModFlags
#define ImGuiModFlags_None ImGuiKeyModFlags_None
#define ImGuiModFlags_Ctrl ImGuiKeyModFlags_Ctrl
#define ImGuiModFlags_Shift ImGuiKeyModFlags_Shift
#define ImGuiModFlags_Alt ImGuiKeyModFlags_Alt
#define ImGuiModFlags_Super ImGuiKeyModFlags_Super
#endif
according to imgui:
https://github.com/ocornut/imgui/blob/v1.88/imgui.cpp#L390-L392
- 2022/04/05 (1.88) - inputs: renamed ImGuiKeyModFlags to ImGuiModFlags. Kept inline redirection enums (will obsolete). This was never used in public API functions but technically present in imgui.h and ImGuiIO.
but i think the dear-imgui-generator we use for the enums generated & exposed them.
So i'm hesitant to just open a PR with "just checkout v1.88 - what could possible go wrong"-mentality :D
A follow-up to #52, but can be done concurrently.
The current functions can remain intact and a new set of functions can be added as a cheap wrapper for raw procedures.
-- current
withWindowOpen :: MonadUnliftIO m => String -> m () -> m ()
-- proposed
withWindowOpen' :: (MonadUnliftIO m, StateVar Bool isOpen) => ImGuiWindowFlags -> isOpen -> String -> m () -> m ()
Fancy wrappers (labels, lenses, etc.) can be provided as alternatives in their own packages.
Cons: this will double the amount of functions published. The previous implementation, however, can be rebased upon those new expanded.
Alternative 1: Add all the arguments to existing functions. A breaking change, a bit noisier to write but lighter on maintenance.
Alternative 2: Rename current shortcuts to underscored, add expanded versions like in A1. Also a breaking change and may require breakage again when "expandable defaults" are to be implemented.
When I try to build a project with dear-imgui.hs
, I get the following error:
dear-imgui> generator\DearImGui\Generator.hs:75:11: error:
dear-imgui> * Exception when trying to run compile-time code:
dear-imgui> C:\Users\bradn\AppData\Local\Programs\stack\x86_64-windows\msys2-20150512\tmp\stack-2831df5137059ac1\dear-imgui-1.0.0\imgui\imgui.h: openFile: does not exist (N
dear-imgui> Code: do currentPath <- TH.loc_filename <$> TH.location
dear-imgui> basicHeaders <- TH.runIO
dear-imgui> do headersPath <- canonicalizePath
dear-imgui> (takeDirectory currentPath
dear-imgui> <> "/../../imgui/imgui.h")
dear-imgui> ....
dear-imgui> TH.lift $ generateNames basicHeaders
dear-imgui> * In the untyped splice:
dear-imgui> $(do currentPath <- TH.loc_filename <$> TH.location
dear-imgui> basicHeaders <- TH.runIO
dear-imgui> do headersPath <- canonicalizePath
dear-imgui> (takeDirectory currentPath
dear-imgui> <> "/../../imgui/imgui.h")
dear-imgui> headersSource <- Text.readFile headersPath
dear-imgui> ....
dear-imgui> TH.lift $ generateNames basicHeaders)
dear-imgui> |
dear-imgui> 75 | headers = $( do
dear-imgui> | ^^^^^...
dear-imgui>
The cause of this error is obvious: dear-imgui.hs
looks for imgui at ./../../imgui/imgui.h
. However, I am using Stack, which changes the working directory to a temporary one while building; it is thus infeasible to place imgui at this location. For this reason, would it be possible to avoid hardcoding the location of imgui? Preferably it would be possible for the user to specify the location of their imgui installation in some fasion. (Cabal flags would be perfect for this, if only they supported string values…)
This is not an issue as such, but to record for the benefit of other users that I was able to build the 'Hello World' example on Windows 11 with EDIT: a modified version of Stack 2.15.1 the master
branch version of Stack (post-Stack 2.15.1), as follows:
A Stack configuration:
snapshot: lts-22.11 # GHC 9.6.4
extra-deps:
# Release v2.2.0
- git: https://github.com/haskell-game/dear-imgui.hs.git
commit: bab4d769eaacba2de5da342e853f18746db0e12c
- megaparsec-9.2.2@sha256:c306a135ec25d91d252032c6128f03598a00e87ea12fcf5fc4878fdffc75c768,3219
flags:
dear-imgui:
sdl: true
opengl3: true
A package.yaml
:
name: imGuiHelloWorld
version: 0.1.0.0
dependencies:
- base >= 4.7 && < 5
- dear-imgui
- gl
- managed
- sdl2
executables:
imguiHelloWorld:
main: Main.hs
source-dirs: app
ghc-options:
- -threaded
- -rtsopts
- -with-rtsopts=-N
I needed also needed to install with stack exec -- pacman
(SDL versions after 2.24.1-1 do not work):
-S mingw-w64-x86_64-pkgconf
-U mingw-w64-x86_64-SDL2-2.24.1-1-any.pkg.tar.zst # From archive at https://repo.msys2.org/mingw/mingw64/
-S mingw-w64-x86_64-glew
EDIT: Stack 2.15.1/pantry-9.3.2 does not appear to handle an extra-dep with submodules. That is being investigated at commercialhaskell/stack#5536. That has been fixed in the master
branch version of Stack (if you are not using GHCup to manage versions of Stack, stack upgrade --source-only --git
).
To debug the C/C++-calls and run in gdb a debug mode would be very handsome.
Something like:
if flag(debug)
if os(linux)
ghc-options: -Wall -g -rtsopts -dcore-lint -debug -O0
cc-options: -g -O0 -fsanitize=address -fno-omit-frame-pointer
if os(darwin)
....
if os(windows)
...
I've been trying to update upstream, but the parser breaks somewhere and has to be refreshed.
As title. When attempting to join, I receive an error:
#dear-imgui.hs:ocharles.org.uk is not accessible at this time.
Try again later, or ask a room or space admin to check if you have access.
Cheers :)
The current version does not build for me on MacOS (m1, GHC 8.10.7). I'm using the GLFW flag, but I suspect I might get other failures even with different flags.
022-08-23 13:59:47.286836: [info] dear-imgui > [ 2 of 17] Compiling DearImGui.GLFW
2022-08-23 13:59:47.636796: [warn] dear-imgui >
2022-08-23 13:59:47.637035: [warn] dear-imgui > /private/var/folders/f6/yyydf8_149gg2pc9pm3wvgcw0000gn/T/stack-5c40579330f2d8c1/dear-imgui-2.1.0/In file included from /var/folders/f
6/yyydf8_149gg2pc9pm3wvgcw0000gn/T/ghc7845_0/ghc_16.cpp:2:0: error:
2022-08-23 13:59:47.637096: [warn] dear-imgui >
2022-08-23 13:59:47.637128: [warn] dear-imgui >
2022-08-23 13:59:47.637319: [warn] dear-imgui > /private/var/folders/f6/yyydf8_149gg2pc9pm3wvgcw0000gn/T/stack-5c40579330f2d8c1/dear-imgui-2.1.0/imgui/imgui.h:252:5: error:
2022-08-23 13:59:47.637363: [warn] dear-imgui > error: unknown type name 'constexpr'
2022-08-23 13:59:47.637384: [warn] dear-imgui > constexpr ImVec2() : x(0.0f), y(0.0f) { }
2022-08-23 13:59:47.637402: [warn] dear-imgui > ^
2022-08-23 13:59:47.637417: [warn] dear-imgui > |
2022-08-23 13:59:47.637433: [warn] dear-imgui > 252 | constexpr ImVec2() : x(0.0f), y(0.0f) { }
2022-08-23 13:59:47.637450: [warn] dear-imgui > | ^
2022-08-23 13:59:47.637496: [warn] dear-imgui >
As far as I understand, DearImGui.GLFW has this inline-c call:
C.include "imgui.h" -- I think it's from this line? Not sure.
and we should be using a c++ compiler with -std=c++11
. But we're not (only on MacOS I assume).
The cabal library has
cxx-options: -std=c++11
but that doesn't seem to be enough.
I am actually able to fix the issue by adding
ghc-options:
-optcxx-std=c++11
-optcxx-Wall
as I did in this commit: e6c40ff
I got this idea from https://github.com/fpco/inline-c/blob/master/inline-c-cpp/inline-c-cpp.cabal#L46
But I'm not sure exactly what the fix should look like for this package.
Would be happy to make this a PR if it seems like a reasonable solution. (Side note: do we support GHC < 8.10?)
OpenPopupOnItemClick
BeginPopupContextItem
BeginPopupContextWindow
BeginPopupContextVoid
IsPopupOpen
I am trying to add ImGui to a small project I had using SDL but it didn't seem compatible with what this package offered. I looked at the original C++ project and they seem to have functions that allow rendering using the SDL renderer. I tried adding these binding on my own as in these functions:
sdl2InitForRenderer :: MonadIO m => Window -> Renderer -> m Bool
sdl2InitForRenderer (Window windowPtr) (Renderer rendererPtr) = liftIO do
(0 /=) <$> [C.exp| bool { ImGui_ImplSDL2_InitForSDLRenderer((SDL_Window*)$(void* windowPtr), (SDL_Renderer*)$(void* rendererPtr)) } |]
sdl2RendererInit :: MonadIO m => Renderer -> m Bool
sdl2RendererInit (Renderer rendererPtr) = liftIO do
(0 /=) <$> [C.exp| bool { ImGui_ImplSDLRenderer2_Init((SDL_Renderer*)$(void* rendererPtr)) } |]
sdl2RendererNewFrame :: MonadIO m => m ()
sdl2RendererNewFrame = liftIO do
[C.exp| void { ImGui_ImplSDLRenderer2_NewFrame(); } |]
sdl2RendererShutdown :: MonadIO m => m ()
sdl2RendererShutdown = liftIO do
[C.exp| void { ImGui_ImplSDLRenderer2_Shutdown(); } |]
sdl2RendererRenderDrawData :: MonadIO m => DrawData -> m ()
sdl2RendererRenderDrawData (DrawData drawDataPtr) = liftIO do
[C.exp| void { ImGui_ImplSDLRenderer2_RenderDrawData((ImDrawData*) $( void* drawDataPtr )); } |]
by i cant seem to get the ImGui window to show properly, the blue bars bug out and the text doesn't show. Since I'm not that savvy in neither cpp, haskell or either library, I though it would be best to ask for their implementation here.
Hello! I was trying to test out the image
example locally just now, unsuccessfully.
It seems that the file uses OpenGL3 imports, but the compile flags specified in dear-imgui.cabal says OpenGL2. Is this an error?
In 1d6b7cc
Stumbled upon the library on this week and pleased that it fits nicely for NixOS-based development and deploy. The problem is our intended end-users are Russian-speaking, and ImGui supposedly supports Unicode fonts. However, we should explicitly set needed character ranges, otherwise they would be replaced with ?
's.
So, I propose expanding font binds and adding glyph_ranges
option, if not also ImFontConfig
. Though, it seems that the issue is actually linked with #61.
Hey! So after some futzing, i got the readme example to work wiht >= opengl3 flavor stuff. as below.
i did hit a strange crash i'm not sure how to understand when i tried a compatiblity profile (not that i expect to need it, but was just trying things)
carterschonwald@CarterHydra ~/W/p/a/genicad (main) [1]> cabal run exe:trash_demo
Build profile: -w ghc-9.4.7 -O1
In order, the following will be built (use -v for more details):
- genicad-0.1.0.0 (exe:trash_demo) (file app/Trash.hs changed)
Preprocessing executable 'trash_demo' for genicad-0.1.0.0..
Building executable 'trash_demo' for genicad-0.1.0.0..
trash_demo: SDLCallFailed {sdlExceptionCaller = "SDL.Video.glCreateContext", sdlFunction = "SDL_GL_CreateContext", sdlExceptionError = "Failed creating OpenGL context at version requested"}
the full code with working core profile is as below
{-# LANGUAGE OverloadedStrings,GHC2021 #-}
module Main ( main ) where
import Control.Exception
import Control.Monad.IO.Class
import Control.Monad.Managed
import DearImGui
import DearImGui.OpenGL3
import DearImGui.SDL
import DearImGui.SDL.OpenGL
import Graphics.GL
import SDL
import SDL.Video
main :: IO ()
main = do
-- Initialize SDL
initializeAll
runManaged $ do
-- Create a window using SDL. As we're using OpenGL, we need to enable OpenGL too.
window <- do
let title = "Hello, Dear ImGui!"
let config = defaultWindow { windowGraphicsContext = OpenGLContext defaultOpenGL{glProfile=Core Normal 4 1} , windowResizable = True }
managed $ bracket (createWindow title config) destroyWindow
-- Create an OpenGL context
glContext <- managed $ bracket (glCreateContext window) glDeleteContext
-- Create an ImGui context
_ <- managed $ bracket createContext destroyContext
-- Initialize ImGui's SDL2 backend
_ <- managed_ $ bracket_ (sdl2InitForOpenGL window glContext) sdl2Shutdown
-- Initialize ImGui's OpenGL backend
_ <- managed_ $ bracket_ openGL3Init openGL3Shutdown
liftIO $ mainLoop window
mainLoop :: Window -> IO ()
mainLoop window = unlessQuit $ do
-- Tell ImGui we're starting a new frame
openGL3NewFrame
sdl2NewFrame
newFrame
-- Build the GUI
withWindowOpen "Hello, ImGui!" $ do
-- Add a text widget
text "Hello, ImGui!"
-- Add a button widget, and call 'putStrLn' when it's clicked
button "Clickety Click" >>= \x -> case x of
False -> return ()
True -> putStrLn "Ow!"
-- Show the ImGui demo window
showDemoWindow
-- Render
glClear GL_COLOR_BUFFER_BIT
render
openGL3RenderDrawData =<< getDrawData
glSwapWindow window
mainLoop window
where
-- Process the event loop
unlessQuit action = do
shouldQuit <- checkEvents
if shouldQuit then pure () else action
checkEvents = do
pollEventWithImGui >>= \x -> case x of
Nothing ->
return False
Just event ->
(isQuit event ||) <$> checkEvents
isQuit event =
SDL.eventPayload event == SDL.QuitEvent
Hey all,
I'm trying to make an inputText that returns true when an enter is hit, which requires the ImGuiInputTextFlags_EnterReturnsTrue
flag. I notice all flags are already there, but most widgets are set with a default value instead of exposing it to the public interface, I find it is a bit limiting. Is there a reason for this? e.g for this piece:
dear-imgui.hs/src/DearImGui.hs
Lines 1216 to 1224 in 7795b3d
Can we expose the flag as an option to the user like this?
inputText :: (MonadIO m, HasSetter ref Text, HasGetter ref Text) => Text -> ref -> Int -> ImGuiInputTextFlags -> m Bool
A small-effort stepping stone towards #50, the CI can be tasked with preparing source tarballs to be published as GitHub releases.
It is of little direct benefit but sets up an obvious iteration point.
I started looking at imgui.h. It's large. I don't think it's reasonable to achieve feature completeness, even less maintainability, without auto-generating at least some portion of the bindings. We could rely on cimgui, or generate directly from the headers. This would also allow easier access to different branches of ImGui
, such as the docking branch which supports multi-viewport.
I haven't looked too much into it, but for cimgui here are some possible steps:
CInt
for each enum type, with the corresponding pattern synonyms IMGUI_API ImVec2 GetWindowPos();
IMGUI_API ImVec2 GetWindowSize();
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.