keharriso / love-nuklear

Lightweight immediate mode GUI for LÖVE games
MIT License
351 stars 32 forks source link

Native-like API #5

Closed karai17 closed 6 years ago

karai17 commented 8 years ago

While this is definitely a great Lua binding for nuklear, it does feel a bit thin. I wonder if it would be possible to design an API that feels more like a love module than a C wrapper?

keharriso commented 8 years ago

Thanks for the input. I've been contemplating one possible solution to this problem: replacing the _begin/_end pairs with a single function that takes a closure as a parameter. This looks especially clean in Moonscript, changing overview.lua to:

nk = require "nuklear"

checkA = value: false
checkB = value: true
radio = value: "A"
selectA = value: false
selectB = value: true
slider = value: 0.2
progress = value: 1
colorPicker = value: "#ff0000"
property = value: 6
edit = value: "Edit text"
combo = value: 1, items: {"A", "B", "C"}

->
  nk.window "Overview", 100, 100, 600, 450, {"border", "movable", "title"}, ->
    nk.menubar ->
      nk.layout_row "dynamic", 30, 1
      nk.menu "Menu", nil, 120, 90, ->
        nk.layout_row "dynamic", 40, 1
        nk.menu_item "Item A"
        nk.menu_item "Item B"
        nk.menu_item "Item C"
    nk.layout_row "dynamic", 400, 3
    nk.group "Group 1", {"border"}, ->
      nk.layout_row "dynamic", 30, 1
      nk.label "Left label"
      nk.label "Centered label", "centered"
      nk.label "Colored label", "left", "#ff0000"
      nk.tree "tab", "Tree Tab", ->
        nk.tree "node", "Tree Node 1", ->
          nk.label "Label 1"
        nk.tree "node", "Tree Node 2" ->
          nk.label "Label 2"
        nk.spacing 1
        nk.button "Button", ->
          print "Button pressed!"
        nk.spacing 1
        nk.checkbox "Checkbox A", checkA
        nk.checkbox "Checkbox B", checkB
    nk.group "Group 2", {"border"}, ->
      nk.layout_row "dynamic", 30, 1
      nk.label "Radio buttons:"
      nk.layout_row "dynamic", 30, 3
      nk.radio "A", radio
      nk.radio "B", radio
      nk.radio "C", radio
      nk.layout_row "dynamic", 30, 1
      nk.selectable "Selectable A", selectA
      nk.selectable "Selectable B", selectB
      nk.layout_row "dynamic", 30, {.35, .65}
      nk.label "Slider:"
      nk.slider 0, slider, 1, 0.05
      nk.label "Progress:"
      nk.progress progress, 10, true
      nk.spacing(2)
      nk.label "Color picker:"
      nk.button nil, colorPicker.value
      nk.layout_row "dynamic", 90, 1
      nk.color_picker colorPicker
    nk.group "Group 3", {"border"}, ->
      nk.layout_row "dynamic", 30, 1
      nk.property "Property", 0, property, 10, 0.25, 0.05
      nk.spacing 1
      nk.label "Edit:"
      nk.edit "box", edit
      nk.layout_row "dynamic", 5, 1
      nk.spacing 1
      nk.layout_row "dynamic", 30, 1
      nk.label "Combobox:"
      nk.combobox combo, combo.items
      nk.layout_row "dynamic", 5, 1
      nk.spacing 1
      nk.layout_row "dynamic", 30, 1
      nk.tooltip "Test tooltip" if nk.widget_is_hovered!
      x, y, w, h = nk.widget_bounds!
      nk.contextual 100, 100, x, y, w, h, ->
        nk.layout_row "dynamic", 30, 1
        nk.contextual_item "Item A"
        nk.contextual_item "Item B"
      nk.label "Contextual (Right click me)"

This might be one step in the right direction. Are there any suggestions you have?

karai17 commented 8 years ago

Well, I will say that LOVE does have some things that open/close already, such as love.graphics.push and love.graphics.pop. I think my first order of business would be to organize the various components into their own namespaces:

But that might be too much since I believe LOVE's API generally only goes 3 levels deep, and my above suggestion would be 4 levels deep.

Maybe @slime73 has some suggestions?

karai17 commented 8 years ago

I guess if you were to go with the LOVE API, you'd want to use camelCase instead of snake_case (much to my own dismay).

keharriso commented 8 years ago

I hesitate to use the love.* namespace for anything but official LOVE modules and functions. Making camelCase work would be really simple, though.

karai17 commented 8 years ago

Well sure, I am just giving an example. My reasoning here is I think nuklear would be a good fit as a native LOVE module. It seems small and simple and intuitive enough, and LOVE reeeeeally needs a GUI module to round off its main functionality. I've opened a discussion in the LOVE rep about this.


Landon Manning lmanning17@gmail.com

On 3 December 2016 at 13:06, Kevin Harrison notifications@github.com wrote:

I hesitate to use the love.* namespace for anything but official LOVE modules and functions. Making camelCase work would be really simple, though.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/keharriso/love-nuklear/issues/5#issuecomment-264651581, or mute the thread https://github.com/notifications/unsubscribe-auth/AAkB_MgTUhH-WL8PnA6fnO4J1mmJfjQ0ks5rEaGUgaJpZM4LDNgZ .

karai17 commented 8 years ago

GG github :|

keharriso commented 8 years ago

The bindings now use camelCase to be consistent with LOVE.

karai17 commented 8 years ago

Awesome! <3

karai17 commented 8 years ago

It looks like both camelCase and snake_case are working... My code can execute both, and the .so file I built seems to be about twice the size of the previous one. Thoughts?

keharriso commented 8 years ago

Yes, both cases work - hopefully that's not a problem. As for the binary size, are you sure you are using the same compiler options as before? I uploaded binaries for v1.1 and the size difference seems to be around 10kB.

karai17 commented 8 years ago

I had used your build last time. I don't mind if both work if the file size isn't significant.

keharriso commented 8 years ago

Yeah, if you used CMake without setting CMAKE_BUILD_TYPE to "Release", then it would make sense that the binaries are much larger. Hopefully the release binaries for v1.1 work for you.

karai17 commented 8 years ago

Cool. Any particular reason why you want both snake_case and camelCase?

keharriso commented 8 years ago

I don't want to break backwards compatibility needlessly. snake_case is now undocumented and will probably be removed in a future update, but I think it makes sense to wait for a major v2.0 to break compatibility. See also Semantic Versioning.

karai17 commented 8 years ago

Fair enough.