-
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 a "Form-Generating"-feature to Owlkettle #93
Comments
I've got it to work! Mostly with the approach you had in mind I think: import owlkettle
import owlkettle/[dataentries, adw, widgetutils]
import std/[options, json, macros, strutils]
type A = object
name: string
viewable App:
value: float64 = 100.0
orient: Orient = OrientX
inverted: bool = false
bla: A = A(name: "lala")
text: string = "Something"
macro getField*(someType: untyped, fieldName: static string): untyped =
nnkDotExpr.newTree(someType, ident(fieldName))
proc toFormField(state: auto, fieldName: static string, typ: typedesc[SomeFloat]): Widget =
return gui:
NumberEntry(value = state.getField(fieldName)):
proc changed(value: float) =
state.getField(fieldName) = value
proc toFormField(state: auto, fieldName: static string, typ: typedesc[SomeInteger]): Widget =
return gui:
NumberEntry(value = state.getField(fieldName).float):
proc changed(value: float) =
state.getField(fieldName) = value.int
proc toFormField(state: auto, fieldName: static string, typ: typedesc[string]): Widget =
return gui:
Entry(text = state.getField(fieldName)):
proc changed(text: string) =
state.getField(fieldName) = text
proc toFormField(state: auto, fieldName: static string, typ: typedesc[bool]): Widget =
return gui:
Switch(state = state.getField(fieldName)):
proc changed(newVal: bool) =
state.getField(fieldName) = newVal
proc toFormField(state: auto, fieldName: static string, typ: typedesc[object]): Widget =
return gui:
Entry(text = $ %*state.getField(fieldName)):
proc changed(text: string) =
try:
state.getField(fieldName) = text.parseJson().to(typ)
except Exception: discard
proc toFormField(state: auto, fieldName: static string, typ: typedesc[enum]): Widget =
return gui:
Entry(text = $state.getField(fieldName)):
proc changed(text: string) =
try:
state.getField(fieldName) = parseEnum[typ](text)
except Exception: discard
method view(app: AppState): Widget =
var fieldWidgets: seq[tuple[name: string, field: AlignedChild[Widget]]] = @[]
for name, value in app[].fieldPairs:
when name notin ["app", "viewed"]:
let fieldWidget = app.toFormField(name, value.type)
if fieldWidget != nil:
let alignedWidget = AlignedChild[Widget](widget: fieldWidget)
fieldWidgets.add((name, alignedWidget))
result = gui:
Window:
Box(orient = OrientY, spacing = 6, margin = 12):
for field in fieldWidgets:
ActionRow {.expand: false.}:
margin = 6
title = field.name
suffixes = @[field.field]
owlkettle.brew(gui(App())) Sadly couldn't figure out how to get past the need for the third field as "discriminator" between the various |
…d-form-generator
Generates a Box widget with editable dataentry widgets for each field on the state. You can exclude certain fields as desired.
I decided to create a BoxWidget via a generic proc and use The main reason for me not making a viewable instead was honestly that I've never seen a generic viewable before and felt that would be too much hassle to troubleshoot for something that is mostly anyway a QoL addition. Also given that I have no clue where to put it, I put it into its own file for now. |
Sidenote, this issue will encompass 2 PRs that I'll open one after another (because 1) depends on the Scale PR and 2) depends on 1)):
That is in order to keep the individual PRs smaller, as I thought you might find that preferable over one larger PR. Also I opened them as Draft PRs already since I have time right now and this way I can basically do everything I can right now, as particularly writing PR descriptions takes me some time typically that I might not have later. |
…d-form-generator
A fully generic approach using T and SomeNumber does the job better and covers more ground.
It now no longer is one that represents tuples etc. as JSON and parses that back. Instead, it now provides a dummy widget that will explain to the user that they must implement a `toFormField` proc with a more elaborate tooltip.
newValue is a ptr
Values for this widget must be fetched via gtk_editable_get_text and then parsed. This provides a default parseInput proc that users can override. However this state still doesn't update the value displayed by the widget. It does however update the value within the state of the example so... yay?
They now provide the form as a menu button popover
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.
* debug attempt * #83 Add first attempt at scale widget * #83 Fix types on bindings double in C translates to cdouble in nim, not cfloat. * #83 improve examples and implementation * stuff * #83 Add support for initial widget value * #83 Add support for inverting widget * #83 fix some bugs * #83 add update of ScaleState to change proc * #83 let pageSize just default to double the pageSize * #83 add support for showing or hiding fill level and precision * #83 Fix bug causing infinite window growth * #83 refactor state-variables to use property hooks * #83 implement suggestion for value 2way bindings * #83 Fix example * #83 Add support for configuring value position * #83 Make orientation configurable * #83 Fix example datatype (this was int but needs to be float64) * #83 Fix semantics on marks * #83 Ensure order of hooks is the same as order of properties * #83 Add build hook to make initial value assignment work again * #83 slightly beautify example * #83 Adjust proc-calling to code conventions * #83 Add widgets example * ##83 add doc comments to Scale widget * #83 Update widgets.md * Add notice that there's a nimble task to generate docs as well * #83 Remove nonsense workflow change * #83 Add scale to example README and mild improvements * Remove nonsense workflow change from myself * #83 Mild doc comment improvements * #83 Fix error introduced by last commit in doc comments * #83 Remove build hook * #83 Move float64 to float * #83 Minor doc update * #83 Improve Scale example to make it more configurable * #93 Add AutoForm function Generates a Box widget with editable dataentry widgets for each field on the state. You can exclude certain fields as desired. * #93 Minor Fix to Scale Widget example * #93 add support for DateTime with Calendar widget * Add Autoform to calendar * Add Autoform to drop_down * #93 Add ability to deal with tuples generally * #93 add basewidget fields * Add Basewidget fields to dropdown * Add autoform to picture.nim with Basewidget fields * Add autoform to popover_menu.nim Note: It appears while `hasArrow` and `tooltip` are available for PopoverMenu, they don't really do much * Add Autoform to radio group Orientation of radio group appears to not change when you change the orientation. It appears to solely rely on Box. Is that a bug or just gtk behaviour? * Fix radiogroup not allow runtime orient updates Radiogroup was missing a property hook for orient. This commit adds said missing property hook. This enables runtime-changing of the orientation of RadioGroup * Add autoform to text_view * Fix popover_menu example * Fixed wrong fix for popover_menu * Beautify Scale * Improve example * Fix Text View example image width * Update gitignore * #93 Update Autoform for scale * debug attempt * Remove nonsense workflow change from myself * #93 Add BaseWidget attributes back to example * #93 Add an auto mini form generator * Update calendar example * Update Dropdown example * Update picture example * Update Popover example * Update radiogroup * Update text_view example * Update calendar image * #93 Add nicer form fields specifically for sizeRequest tuple * #93 Fully move over to the non-form-generating approach * Update calendar image * Update popover_menu example screenshot * Update images of remaining examples * #93 Minor fixes * #93 update callback useable for calendar * Remove pointless AlignedChild export * Update Autoform to use FormulaEntry * Move Calendar into a dialog * #93 remove completely pointless overload for ints A fully generic approach using T and SomeNumber does the job better and covers more ground. * #93 Change Default widget for objects and Co It now no longer is one that represents tuples etc. as JSON and parses that back. Instead, it now provides a dummy widget that will explain to the user that they must implement a `toFormField` proc with a more elaborate tooltip. * Minimize example to menubutton instead of sidebar * #93 Move all toFormFields into autoform * #93 Update widget examples They now provide the form as a menu button popover * Undo changes to example images * #93 Overhaul autoform 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. * #93 Remove unused imports * #93 Move examples back from WindowSurface to Window * Update doc comments * Undo examples changes * Update example headerbars * Make menubutton for form flat as per adw standards * Make headerbar buttons into flat buttons * Rename autoform to playground * Variousf ixes to popover example * Lots of example fixes * Undo unnecessary changes * Remove unnecessary defaultsize --------- Co-authored-by: Can Lehmann <can.l@posteo.de>
Closed by eba600b |
* debug attempt * #83 Add first attempt at scale widget * #83 Fix types on bindings double in C translates to cdouble in nim, not cfloat. * #83 improve examples and implementation * stuff * #83 Add support for initial widget value * #83 Add support for inverting widget * #83 fix some bugs * #83 add update of ScaleState to change proc * #83 let pageSize just default to double the pageSize * #83 add support for showing or hiding fill level and precision * #83 Fix bug causing infinite window growth * #83 refactor state-variables to use property hooks * #83 implement suggestion for value 2way bindings * #83 Fix example * #83 Add support for configuring value position * #83 Make orientation configurable * #83 Fix example datatype (this was int but needs to be float64) * #83 Fix semantics on marks * #83 Ensure order of hooks is the same as order of properties * #83 Add build hook to make initial value assignment work again * #83 slightly beautify example * #83 Adjust proc-calling to code conventions * #83 Add widgets example * ##83 add doc comments to Scale widget * #83 Update widgets.md * Add notice that there's a nimble task to generate docs as well * #83 Remove nonsense workflow change * #83 Add scale to example README and mild improvements * Remove nonsense workflow change from myself * #83 Mild doc comment improvements * #83 Fix error introduced by last commit in doc comments * #83 Remove build hook * #83 Move float64 to float * #83 Minor doc update * #83 Improve Scale example to make it more configurable * #93 Add AutoForm function Generates a Box widget with editable dataentry widgets for each field on the state. You can exclude certain fields as desired. * #93 Minor Fix to Scale Widget example * #93 add support for DateTime with Calendar widget * #93 Add ability to deal with tuples generally * #93 add basewidget fields * Improve example * Fix Text View example image width * Update gitignore * #93 Update Autoform for scale * debug attempt * Remove nonsense workflow change from myself * #93 Add BaseWidget attributes back to example * #93 Add an auto mini form generator * #93 Add nicer form fields specifically for sizeRequest tuple * #93 Fully move over to the non-form-generating approach * #86 Add Status Page widget + example * #86 Add mention of freedesktop spec Also update other docs to point to the tooling section. * #86 Update link to not point to localhost * #86 Update Status Page docs * #86 Remove autoform and refine example * #86 update image * Update examples/widgets/adw/status_page.nim Co-authored-by: Can Lehmann <85876381+can-lehmann@users.noreply.github.com> * #86 Fix incorrect alt attribute on example README --------- Co-authored-by: Can Lehmann <can.l@posteo.de>
* debug attempt * can-lehmann#83 Add first attempt at scale widget * can-lehmann#83 Fix types on bindings double in C translates to cdouble in nim, not cfloat. * can-lehmann#83 improve examples and implementation * stuff * can-lehmann#83 Add support for initial widget value * can-lehmann#83 Add support for inverting widget * can-lehmann#83 fix some bugs * can-lehmann#83 add update of ScaleState to change proc * can-lehmann#83 let pageSize just default to double the pageSize * can-lehmann#83 add support for showing or hiding fill level and precision * can-lehmann#83 Fix bug causing infinite window growth * can-lehmann#83 refactor state-variables to use property hooks * can-lehmann#83 implement suggestion for value 2way bindings * can-lehmann#83 Fix example * can-lehmann#83 Add support for configuring value position * can-lehmann#83 Make orientation configurable * can-lehmann#83 Fix example datatype (this was int but needs to be float64) * can-lehmann#83 Fix semantics on marks * can-lehmann#83 Ensure order of hooks is the same as order of properties * can-lehmann#83 Add build hook to make initial value assignment work again * can-lehmann#83 slightly beautify example * can-lehmann#83 Adjust proc-calling to code conventions * can-lehmann#83 Add widgets example * #can-lehmann#83 add doc comments to Scale widget * can-lehmann#83 Update widgets.md * Add notice that there's a nimble task to generate docs as well * can-lehmann#83 Remove nonsense workflow change * can-lehmann#83 Add scale to example README and mild improvements * Remove nonsense workflow change from myself * can-lehmann#83 Mild doc comment improvements * can-lehmann#83 Fix error introduced by last commit in doc comments * can-lehmann#83 Remove build hook * can-lehmann#83 Move float64 to float * can-lehmann#83 Minor doc update * can-lehmann#83 Improve Scale example to make it more configurable * can-lehmann#93 Add AutoForm function Generates a Box widget with editable dataentry widgets for each field on the state. You can exclude certain fields as desired. * can-lehmann#93 Minor Fix to Scale Widget example * can-lehmann#93 add support for DateTime with Calendar widget * can-lehmann#93 Add ability to deal with tuples generally * can-lehmann#93 add basewidget fields * Improve example * Fix Text View example image width * Update gitignore * can-lehmann#93 Update Autoform for scale * debug attempt * Remove nonsense workflow change from myself * can-lehmann#93 Add BaseWidget attributes back to example * can-lehmann#93 Add an auto mini form generator * can-lehmann#93 Add nicer form fields specifically for sizeRequest tuple * can-lehmann#93 Fully move over to the non-form-generating approach * can-lehmann#86 Add Status Page widget + example * can-lehmann#86 Add mention of freedesktop spec Also update other docs to point to the tooling section. * can-lehmann#86 Update link to not point to localhost * can-lehmann#86 Update Status Page docs * can-lehmann#86 Remove autoform and refine example * can-lehmann#86 update image * Update examples/widgets/adw/status_page.nim Co-authored-by: Can Lehmann <85876381+can-lehmann@users.noreply.github.com> * can-lehmann#86 Fix incorrect alt attribute on example README --------- Co-authored-by: Can Lehmann <can.l@posteo.de>
* debug attempt * #83 Add first attempt at scale widget * #83 Fix types on bindings double in C translates to cdouble in nim, not cfloat. * #83 improve examples and implementation * stuff * #83 Add support for initial widget value * #83 Add support for inverting widget * #83 fix some bugs * #83 add update of ScaleState to change proc * #83 let pageSize just default to double the pageSize * #83 add support for showing or hiding fill level and precision * #83 Fix bug causing infinite window growth * #83 refactor state-variables to use property hooks * #83 implement suggestion for value 2way bindings * #83 Fix example * #83 Add support for configuring value position * #83 Make orientation configurable * #83 Fix example datatype (this was int but needs to be float64) * #83 Fix semantics on marks * #83 Ensure order of hooks is the same as order of properties * #83 Add build hook to make initial value assignment work again * #83 slightly beautify example * #83 Adjust proc-calling to code conventions * #83 Add widgets example * ##83 add doc comments to Scale widget * #83 Update widgets.md * Add notice that there's a nimble task to generate docs as well * #83 Remove nonsense workflow change * #83 Add scale to example README and mild improvements * Remove nonsense workflow change from myself * #83 Mild doc comment improvements * #83 Fix error introduced by last commit in doc comments * #83 Remove build hook * #83 Move float64 to float * #83 Minor doc update * #83 Improve Scale example to make it more configurable * #93 Add AutoForm function Generates a Box widget with editable dataentry widgets for each field on the state. You can exclude certain fields as desired. * #93 Minor Fix to Scale Widget example * #93 add support for DateTime with Calendar widget * #93 Add ability to deal with tuples generally * #93 add basewidget fields * Improve example * Fix Text View example image width * Update gitignore * #93 Update Autoform for scale * debug attempt * Remove nonsense workflow change from myself * #93 Add BaseWidget attributes back to example * #93 Add an auto mini form generator * #93 Add nicer form fields specifically for sizeRequest tuple * #93 Fully move over to the non-form-generating approach * #85 Add Expander Widget including example * #85 Add BaseWidget fields * #85 Add example to README.md * #85 add Activation callback and doc comments * #85 Update and expand docs * #85 Fix expander callback delivering outdated values * #85 Move expander example over to autoform * #85 Update docs and example screenshot * #85 Refine example and remove autoform * #85 Update widgets.md The introduction of gtkminor in an earlier PR changed this doc comment. That caused a change in widgets.md * Update owlkettle/widgets.nim Co-authored-by: Can Lehmann <85876381+can-lehmann@users.noreply.github.com> * #85 Move Expander to make sure list is sorted alphabetically * #85 Update docs --------- Co-authored-by: Can Lehmann <can.l@posteo.de> Co-authored-by: Can Lehmann <85876381+can-lehmann@users.noreply.github.com>
The usecase
For all the example widgets I would like to have a generic proc or template or so that I can just hand any kind of
<WidgetName>State
and that generates me a Form where I have DataEntry fields for every field on said state (except for app and viewed as those are owlkettle internal I think?).This would be useful to let the user see what happens under various circumstances if they manipulate the state of a widget as they please.
It could also be useful if users want to generate a form to manipulate data on the fly without having to write it by hand.
The concept of a solution
Conceptually, I'd have assumed any approach would simply need to iterate over the fields of
<WidgetName>State
type, transform the values of the fields into an enum-type and then use fieldName and the enum-type to associate the field on<WidgetName>State
with a DataEntry widget. Which DataEntry widget is chosen is determined by the enum-type.This normally wouldn't be toooooo hard without but the combination of any State type having
app
andviewed
fields that somehow cause compiler crashes when accessed by the loop as well as the guidsl tolerating neither when statements (which would allow me to avoid those) nor macros that enable unrolling astatic: seq[string]
for-loop in the gui section makes all my typical non-macro approaches impossible.Prior approach (Placeholder for like 3 other similar ones I all attempted)
Removed, it is irrelevant as I found a solution
The text was updated successfully, but these errors were encountered: