can-lehmann / owlkettle

A declarative user interface framework based on GTK 4
https://can-lehmann.github.io/owlkettle/README
MIT License
367 stars 14 forks source link

[FR] Docs for components/modular organization of code. #39

Closed ITwrx closed 1 year ago

ITwrx commented 1 year ago

It would be nice if it were documented how to organize a more complex/real world project. For instance, i want my "pages" code to be in their own Views directory, code for data access with something like litestor in another directory, etc. I like my main.nim file to be as sparse and clean as possible, with everything linked from directories that help "explain" how things work. Especially GUI-related code, which, even with something as clean as owlkettle, can still get kind of "hairy". It looks like the app_launcher example used to have components (i saw it referenced IRT components), but not anymore.

thanks

can-lehmann commented 1 year ago

You can split your application into multiple "components" (called viewables in owlkettle). In my experience you usually end up having a pretty clean split between your gui logic and the underlying data model. Here is an extremely contrived example of how this might look for the counter example from the README:

model.nim

type Counter* = ref object
  count: int

proc `$`*(counter: Counter): string =
  result = $counter.count

proc increment*(counter: Counter) =
  counter.count += 1

type Model* = ref object
  counter*: Counter

proc newModel*(): Model =
  Model(counter: Counter())

counter_view.nim

import owlkettle

import model

viewable CounterView:
  counter: Counter

method view(counterView: CounterViewState): Widget =
  result = gui:
    Box:
      margin = 12
      spacing = 6
      orient = OrientX

      Label:
        text = $counterView.counter

      Button {.expand: false.}:
        text = "+"
        style = {ButtonSuggested}

        proc clicked() =
          counterView.counter.increment()

export CounterView

app.nim

import owlkettle
import model, counter_view

const APP_NAME = "Counter"

viewable App:
  model: Model = newModel()

method view(app: AppState): Widget =
  result = gui:
    Window:
      title = APP_NAME
      defaultSize = (200, 100)

      CounterView:
        counter = app.model.counter

brew(gui(App()))

You can check out https://github.com/can-lehmann/Graphing for a more complex example. I don't split the app into multiple files here (except for the algebra module), but I use viewables quite heavily.

can-lehmann commented 1 year ago

For more information on using viewables it might also be worth checking out the internals documentation here: https://github.com/can-lehmann/owlkettle/blob/main/docs/internals.md

ITwrx commented 1 year ago

Thanks a lot for the good example and the link to the internals doc. It looks like it's all right there! I had missed that somehow and was wondering what was going on. :)

Owlkettle seems really nice so far, and is giving me a lot of hope and motivation for my previously paused desktop application projects. I'll leave this issue for you to close in case you wanted to add an example that was using viewables and models or something.

thanks again

ITwrx commented 1 year ago

I probably skipped the internals doc due to the name. internals makes me think it's stuff that only people contributing code to owlkettle need to know, but this doc is more of an overview of how owlkettle works and eventually everyone building a real app will need to know this stuff and was all the info that was "mysteriously missing" for me. :) You might consider renaming it to owlkettle_in_depth_overview or how_owlkettle_works, or similar, and i would link it from the readme, so people know it's something they should look at prior to trying to build a real application.

thanks

can-lehmann commented 1 year ago

I agree, the name is maybe a bit non-optimal. I think that the discoverability issue is fixed to some extent by https://github.com/can-lehmann/owlkettle/pull/34, because the document outline provides a much better overview of what docs are available. I will consider changing the name of the section.

Note: The "internals" docs now moved to https://can-lehmann.github.io/owlkettle/README.html

ITwrx commented 1 year ago

yeah, discoverability is much better now. All this docs work is great!

thanks