HeinrichApfelmus / threepenny-gui

GUI framework that uses the web browser as a display.
https://heinrichapfelmus.github.io/threepenny-gui/
Other
439 stars 77 forks source link

Reusable components with reactive-banana-threepenny #40

Closed duplode closed 11 years ago

duplode commented 11 years ago

(I was unsure about to which repository I should post this. The code has actually more to do with reactive-banana than with Threepenny, but the case being made is mainly about Threepenny.)

I was wondering how convenient it would be to write reusable widgets for Threepenny. Nothing sophisticated would be needed at first, just the bare minimum so that we wouldn't have to rewrite or copy-paste stuff like a custom file picker on every project. So I went ahead and made a proof-of-concept, and now I am stunned at how easy it was, given that I basically started from scratch. It could be even simpler - someone wishing to use similar methods right now without any fanciness could just drop the trivial Component class.

I do not know how sound this approach to components would be in the long run, and interesting questions would arise were it to be made more general. For instance, how to minimize the boilerplate needed for defining the component data type? Or what the best way to let users style components is? (Just export the Element fields and let users do whatever they want with them? Or perhaps add styling hooks into the component network?) In any case, and however the actual code might look like, I believe it would be good if Threepenny users were made aware of the possibility of defining reusable widgets, be it through the packaged examples, or, eventually, even through novel support modules.

HeinrichApfelmus commented 11 years ago

Writing reusable widgets is very simple indeed, you just create a couple of Elements and events and bundle them up in a record. I'm definitely open to including useful compound widgets in the main package, or in a separate threepenny-gui-contrib module. (This reminds me of the days where I used to search the internet for cool GUI objects to be used with Borland Delphi. Ah, good times.)

Several recommendations concerning your code:

  1. To stay consistent with the rest of Threepenny, I would recommend to use Control.Event instead of AddHandler for the events. They have the same implementation anyway, and I intend to remove the reactive-banana variant.
  2. It is not necessary to have a separate mkNetwork function. You can simply create a new event network and actuate that right in the new function.
  3. The GHC language extension RecordWildCards is extremely useful for removing the boilerplate in the new function.

Especially concerning point 1 and 2, I intend to replace Control.Event with an event type that supports full FRP, eliminating the need for setting up networks etc altogether. This way, you can program GUIs with FRP out of the box (with the optional choice of using a traditional imperative event-based style if you really want to). However, this will take me a while to implement.

duplode commented 11 years ago

Thanks for the suggestions - RecordWildCards in particular is a godsend! Only the first one is a bit awkward right now due to the name clashes involving Event and newEvent; nothing I can't live with for the time being, anyway. As for useful widgets, I will need to write a few simple ones in the near future. I will let you know if they turn out good :)