haskell-game / dear-imgui.hs

Haskell bindings to Dear ImGui, an immediate mode GUI toolkit
BSD 3-Clause "New" or "Revised" License
143 stars 31 forks source link

Handling GetIO, GetStyle and GetStyleColorVec4 #16

Open sheaf opened 3 years ago

sheaf commented 3 years ago

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.

Swarthe commented 9 months ago

I would be willing to help with this! Is it alright if I make a beta implementation of your proposal?