mirror of
https://github.com/fjvallarino/monomer.git
synced 2024-09-11 12:05:35 +03:00
Improve design decisions document
This commit is contained in:
parent
f5e1f29c7e
commit
523355c389
@ -18,7 +18,7 @@ Users take care of storing and providing the state to the library. This is
|
||||
similar to how the model's fields are associated to widgets.
|
||||
|
||||
The advantage is that this makes the library more functionally pure. It also
|
||||
simplifies the internals and may improve performance, since the merge process
|
||||
simplifies the internals and may improve performance since the merge process
|
||||
could be simplified.
|
||||
|
||||
The disadvantage is that it requires more boilerplate from part of the user,
|
||||
@ -35,7 +35,7 @@ is transparent from the user's point of view.
|
||||
|
||||
The disadvantages are that it makes the library more complex and less
|
||||
functionally pure than the other approach. It also makes creating custom widgets
|
||||
a bit more complex, since the merge process needs to be considered.
|
||||
more complicated, since the merge process needs to be considered.
|
||||
|
||||
### What this library does
|
||||
|
||||
@ -50,8 +50,8 @@ Sometimes, for performance reasons, you may want to use `mergeRequired` as the
|
||||
## Are themes really necessary?
|
||||
|
||||
While it's true that you can create a customized version of a widget by writing
|
||||
a regular function, and it is in fact encouraged and used in the examples, in
|
||||
some cases it is not enough.
|
||||
a regular function, and it is encouraged and used in the examples, in some cases
|
||||
it is not enough.
|
||||
|
||||
Some widgets, such as `alert` and `confirm`, are built out of nested widgets and
|
||||
do not expose styling options for all their sub widgets. In this scenario,
|
||||
@ -61,9 +61,9 @@ Themes also have the nice property of simplifying color scheme switching.
|
||||
|
||||
## Why there is not a margin property, considering border and padding do exist?
|
||||
|
||||
Margin used to be part of the library, but made mouse event handling more
|
||||
complex. Since margin is just space outside the border, it can be emulated
|
||||
by adding a wrapper widget. For example:
|
||||
Margin used to be part of the library but made mouse event handling more
|
||||
complex. Since margin is just space outside the border, it can be emulated by
|
||||
adding a wrapper widget. For example:
|
||||
|
||||
```haskell
|
||||
box (label "Test" `styleBasic` [padding 10, border 1 black])
|
||||
@ -79,7 +79,7 @@ in handling it. With that in mind, relying on messages or regular events made
|
||||
more sense.
|
||||
|
||||
Considering there is not broadcasting support for messages (they are sent to
|
||||
a widget on a given path), restricting to the top level widget seemed clearer.
|
||||
a widget on a given path), restricting to the top-level widget seemed clearer.
|
||||
|
||||
## Why, except for render, is the widget interface non monadic?
|
||||
|
||||
@ -94,24 +94,24 @@ Reader stack may have been a good idea).
|
||||
|
||||
## Why is the return type of Tasks and Producers IO and not MonadIO?
|
||||
|
||||
There were some type mismatch issues down the road plus the async library
|
||||
There were some type mismatch issues down the road, plus the async library
|
||||
requires using IO to launch asynchronous tasks. Maybe MonadBaseControl or
|
||||
MonadUnliftIO could be used.
|
||||
|
||||
## Why does WidgetNode have a reference to children widget, considering the widget may not have any?
|
||||
|
||||
It made development of container widgets simpler. It also gave me the ability to
|
||||
create utility functions that can be used across the library for inspecting the
|
||||
widget node tree.
|
||||
It made the development of container widgets more straightforward. It also gave
|
||||
me the ability to create utility functions that can be used across the library
|
||||
for inspecting the widget node tree.
|
||||
|
||||
## Why is the location of the optional config argument inconsistent between single and container widgets?
|
||||
|
||||
For single widgets having the optional config as the last argument makes sense,
|
||||
since it is something extra compared to the default version.
|
||||
|
||||
For container widgets the usage pattern is a bit different. While splitting a
|
||||
complex UI into smaller parts is necessary for maintainability, being able to
|
||||
see the widget hierarchy at first glance is also useful for understanding an
|
||||
For container widgets, the usage pattern is a bit different. While splitting a
|
||||
complex UI into smaller parts is necessary for maintainability, seeing the
|
||||
widget hierarchy at first glance is also helpful for understanding an
|
||||
application. For this reason, sometimes, widgets are nested directly in their
|
||||
parent instead of creating a separate list that is later provided to the parent
|
||||
widget. In that scenario, having the config of the parent widget _after_ its
|
||||
@ -138,13 +138,13 @@ example,
|
||||
|
||||
I wanted to provide a standardized interface for configuring widgets. For
|
||||
example, all widgets which generate events when clicked should expose a
|
||||
configuration option using the same name (in this case `onClick`). I think the
|
||||
configuration option using the same name (in this case, `onClick`). I think the
|
||||
only options to achieve this are typeclasses and labels, and I chose typeclasses
|
||||
because I know them better.
|
||||
|
||||
This choice may also cause namespace issues that require using qualified
|
||||
imports. I tried to avoid _reserving_ common names to reduce the number of times
|
||||
this is required.
|
||||
this is needed.
|
||||
|
||||
If you know a better option to solve this, please let me know!
|
||||
|
||||
@ -154,3 +154,28 @@ I needed to store references to lenses in custom data types, which is not
|
||||
possible with the standard `Lens` type. The lens library provides `ALens`, which
|
||||
allows for that use case. I don't think microlens has something similar, plus
|
||||
I'm currently using more things from lens.
|
||||
|
||||
## Why nanovg? The project's repository says it's not actively maintained.
|
||||
|
||||
[NanoVG](https://github.com/memononen/nanovg) is an easy to use vector graphics
|
||||
library that uses OpenGL, making it GPU accelerated. It provides a nice set of
|
||||
drawing operations that cover all the current use cases of Monomer. When I
|
||||
started the project, NanoVG was actively maintained and was a very reasonable
|
||||
option.
|
||||
|
||||
NanoVG not being maintained is not ideal, but the feature set used by Monomer
|
||||
has been stable for quite a while. It's also a kind of small library, which
|
||||
makes porting it to other backends feasible (a version for Metal, which I have
|
||||
not tested, can be found [here](https://github.com/ollix/MetalNanoVG)).
|
||||
|
||||
I have this situation on the back of my mind since I also worry at some point
|
||||
Apple will discontinue OpenGL support, but it's not on my list of priorities. I
|
||||
have taken a look at these options:
|
||||
|
||||
- [Skia](https://skia.org) has lots of features and is used by Chrome and other
|
||||
major applications, but the C bindings are marked as not stable, and it does
|
||||
not look like an easy to distribute library (plus compiling it takes a long
|
||||
time).
|
||||
- ImGui's [ImDrawList](https://github.com/ocornut/imgui/issues/1878), the option
|
||||
I like the most, supports several backends and is an easy to embed library. I
|
||||
haven't validated if something Monomer uses is missing.
|
||||
|
Loading…
Reference in New Issue
Block a user