-
Notifications
You must be signed in to change notification settings - Fork 12
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add autoform to all the widgets #95
Add autoform to all the widgets #95
Conversation
double in C translates to cdouble in nim, not cfloat.
The new implementation enables generating an entire form based on either `toFormField` for individual entries with custom datatypes or `toListFormField` for seq[T] of custom datatypes.
Alrighty, the recent changes should've added the new Popover version to the examples I've listed for individual widgets. I also did a small overhaul, mostly to "simplify"/"unify" forms for types like seq[string] etc. If you have a field of type If you have a field of type That way you only need to worry about making a form for one entry, not for an entire list of them. If you have better idea for wording, shoot it out, I'll happily improve upon the meh names I landed on for these procs. Naming is hard. Now with that out of the way, I have the following questions:
|
We could already call it
I decided to only create examples for the more complex widgets pretty early on, since I trust that users should be able to figure out how to use the basic widgets like |
I played with some of the examples and I very much like it! I think that the new design works quite well. A few general notes:
|
Punkt:
Particularly for 4: The only reason these are separate is because in I want very much to act directly on state because I know that is a ref that is shared between the main widget in the example as well as every proc in autoform that gets passed said state. I can not assume that every field on the state is a ref type. I'll launch an attempt at using |
I can't seem to find any approach that allows me to unify The approach of "just pass the fieldValue as a mutable parameter proc toFormField[T: SomeNumber](fieldName: static string, fieldValue: var T): Widget =
## Provides a form field for any number type
return gui:
ActionRow:
title = fieldName
FormulaEntry() {.addSuffix.}:
value = fieldValue.float
xAlign = 1.0
maxWidth = 8
proc changed(value: float) =
fieldValue = value.T
Since you can't assume that every type on a state is a ref-type, you must capture the I did various attempts centered around templates for that, the most recent one being to turn the gui block into a template like this: template stringField(fieldName: string, fieldExpression: untyped): Widget =
## Provides a form field for string
gui:
ActionRow:
title = fieldName & "I am from the trees"
Entry() {.addSuffix.}:
text = fieldExpression
proc changed(text: string) =
fieldExpression = text
proc toFormField(state: auto, fieldName: static string, typ: typedesc[string]): Widget =
## Provides a form field for string
return stringField(fieldName):
state.getField(fieldName)
proc toListFormField(state: auto, fieldName: static string, index: int, typ: typedesc[string]): Widget =
## Provides a form to display a single entry of type `string` in a list of `string` entries.
return stringField(fieldName & $index):
state.getField(fieldName)[index] All of them blow up with the error: stack trace: (most recent call last)
/home/philipp/dev/owlkettle/owlkettle/guidsl.nim(293, 17) gui
/home/philipp/dev/owlkettle/owlkettle/guidsl.nim(111, 36) parseGui
/home/philipp/dev/owlkettle/owlkettle/guidsl.nim(94, 11) parseGui
/home/philipp/dev/owlkettle/owlkettle/guidsl.nim(111, 36) parseGui
/home/philipp/dev/owlkettle/owlkettle/guidsl.nim(94, 11) parseGui
/home/philipp/dev/owlkettle/owlkettle/guidsl.nim(111, 36) parseGui
/home/philipp/dev/owlkettle/owlkettle/guidsl.nim(113, 11) parseGui
/home/philipp/.choosenim/toolchains/nim-2.0.0/lib/std/assertions.nim(41, 14) failedAssertImpl
/home/philipp/.choosenim/toolchains/nim-2.0.0/lib/std/assertions.nim(36, 13) raiseAssert
/home/philipp/.choosenim/toolchains/nim-2.0.0/lib/system/fatal.nim(53, 5) sysFatal
/home/philipp/dev/owlkettle/examples/widgets/drop_down.nim(38, 12) template/generic instantiation of `gui` from here
/home/philipp/dev/owlkettle/examples/widgets/drop_down.nim(46, 19) template/generic instantiation of `toAutoFormMenu` from here
/home/philipp/dev/owlkettle/owlkettle/autoform.nim(321, 27) template/generic instantiation of `toAutoFormMenu` from here
/home/philipp/dev/owlkettle/owlkettle/autoform.nim(302, 28) template/generic instantiation of `toFormField` from here
/home/philipp/dev/owlkettle/owlkettle/autoform.nim(277, 38) template/generic instantiation of `toListFormField` from here
/home/philipp/dev/owlkettle/owlkettle/autoform.nim(184, 21) template/generic instantiation of `stringField` from here
/home/philipp/.choosenim/toolchains/nim-2.0.0/lib/system/fatal.nim(53, 5) Error: unhandled exception: /home/philipp/dev/owlkettle/owlkettle/guidsl.nim(113, 7) `node[0].isName` [AssertionDefect] Beef had some approach regarding turning Over all, I got nothing regarding deduplicating this. That is, outside of using |
Updated this just now:
Edit: |
examples/widgets/popover_menu.nim
Outdated
HeaderBar {.addTitlebar.}: | ||
insert(app.toAutoFormMenu(ignoreFields = @["pixbuf", "loading"], sizeRequest = (400, 300))) {.addRight.} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ignoreFields is not necessary
is sizeRequest necessary?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That is actually the way to go here from what I can see. However, since this PR is currently blocking your other widgets, I would be fine with merging this as is (provided the things in the review above are fixed) and going over |
I must say that I am really happy with this PR at this point. Good work 😄 !
The point about larger PRs was mainly about when they actively influence each other. E.g every time you changed something in #94, this impacted this PR, so thats why I prefer one single, larger PR in that case. If the features are independent, having separate PRs is of course nicer, however, I would also be fine with a single larger PR if that is less work for you. The main issue I have is just when the features actively depend on each other, which makes reviewing quite difficult when they are spread across multiple PRs. If I remember correctly, you already implemented #85 and #86 in large parts. Given that the (at least planned) release date for 3.0.0 approaches quickly, it would make sense to merge them before then. |
Looks like the already paid off. While playing with the examples, I found a pretty stupid bug in the |
Basically a "continuation" of #93 . This PR simply adds autoform to all widget examples under /examples/widgets.
Again, the only files changed here are actually widgets.nim and the various example files, anything else stems from either #90 or #94.
This should only be merged (and honestly also only reviewed) after #94 was merged as it directly depends upon that PR.
The exact examples in total that autoform was added to encompass thusly:
Beyond just adding autoform, I also added the fields of the BaseWidget to those examples so that users can be made more aware that they also have access to those and can see their effects on the different widgets.
Further this PR also fixes a small bug with Radio Group:
It was missing a property hook for its
orient
field.This PR adds the missing property hook in widgets.nim, which enables RadioGroup to change its orientation at runtime, which previously wasn't possible.