Skip to content

Commit

Permalink
Add since field pragma
Browse files Browse the repository at this point in the history
  • Loading branch information
can-lehmann committed Mar 28, 2024
1 parent bae4a0e commit 8254267
Show file tree
Hide file tree
Showing 7 changed files with 109 additions and 75 deletions.
6 changes: 3 additions & 3 deletions docs/widgets.md
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ renderable CenterBox of BaseWidget
- `centerWidget: Widget`
- `endWidget: Widget`
- `baselinePosition: BaselinePosition = BaselineCenter`
- `shrinkCenterLast: bool = false` Requires GTK 4.12 or higher to work. Compile with `-d:gtkminor=12` to enable it
- `shrinkCenterLast: bool = false` Since: `GtkMinor >= 12`
- `orient: Orient = OrientX`

###### Adders
Expand Down Expand Up @@ -904,8 +904,8 @@ renderable SearchEntry of BaseWidget

- All fields from [BaseWidget](#BaseWidget)
- `text: string`
- `searchDelay: uint = 100` Determines the minimum time after a `searchChanged` event occurred before the next can be emitted. Only available when compiling for gtk 4.8
- `placeholderText: string = "Search"` Only available when compiling for gtk 4.10
- `searchDelay: uint = 100` Determines the minimum time after a `searchChanged` event occurred before the next can be emitted. Since: `GtkMinor >= 8`
- `placeholderText: string = "Search"` Since: `GtkMinor >= 10`

###### Events

Expand Down
12 changes: 6 additions & 6 deletions docs/widgets_adwaita.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ renderable ButtonContent of BaseWidget
- `label: string`
- `iconName: string`
- `useUnderline: bool` Defines whether you can use `_` on part of the label to make the button accessible via hotkey. If you prefix a character of the label text with `_` it will hide the `_` and activate the button if you press ALT + the key of the character. E.g. `_Button Text` will trigger the button when pressing `ALT + B`.
- `canShrink: bool` Defines whether the ButtonContent can be smaller than the size of its contents. Only available for adwaita version 1.3 or higher. Does nothing if set when compiled for lower adwaita versions.
- `canShrink: bool` Defines whether the ButtonContent can be smaller than the size of its contents. Since: `AdwVersion >= (1, 4)`


## Clamp
Expand Down Expand Up @@ -177,7 +177,7 @@ renderable PreferencesPage of BaseWidget
- `name: string`
- `title: string`
- `useUnderline: bool`
- `description: string`
- `description: string` Since: `AdwVersion >= (1, 4)`

###### Adders

Expand Down Expand Up @@ -241,8 +241,8 @@ renderable ExpanderRow of PreferencesRow
- `expanded: bool = false`
- `enableExpansion: bool = true`
- `showEnableSwitch: bool = false`
- `titleLines: int` Determines how many lines of text from the title are shown before it ellipsizes the text. Defaults to 0 which means it never elipsizes and instead adds new lines to show the full text. Only available for adwaita version 1.3 or higher. Does nothing if set when compiled for lower adwaita versions.
- `subtitleLines: int` Determines how many lines of text from the subtitle are shown before it ellipsizes the text. Defaults to 0 which means it never elipsizes and instead adds new lines to show the full text. Only available for adwaita version 1.3 or higher. Does nothing if set when compiled for lower adwaita versions.
- `titleLines: int` Determines how many lines of text from the title are shown before it ellipsizes the text. Defaults to 0 which means it never elipsizes and instead adds new lines to show the full text. Since: `AdwVersion >= (1, 3)`
- `subtitleLines: int` Determines how many lines of text from the subtitle are shown before it ellipsizes the text. Defaults to 0 which means it never elipsizes and instead adds new lines to show the full text. Since: `AdwVersion >= (1, 3)`

###### Events

Expand Down Expand Up @@ -462,8 +462,8 @@ Adwaita Headerbar that combines GTK Headerbar and WindowControls.
- `showRightButtons: bool = true` Determines whether the buttons in `rightButtons` are shown. Does not affect Widgets in `packRight`.
- `showLeftButtons: bool = true` Determines whether the buttons in `leftButtons` are shown. Does not affect Widgets in `packLeft`.
- `titleWidget: Widget` A widget for the title. Replaces the title string, if there is one.
- `showBackButton: bool = true`
- `showTitle: bool = true` Determines whether to show or hide the title
- `showBackButton: bool = true` Since: `AdwVersion >= (1, 4)`
- `showTitle: bool = true` Determines whether to show or hide the title Since: `AdwVersion >= (1, 4)`

###### Setters

Expand Down
6 changes: 3 additions & 3 deletions docs/widgets_dataentries.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ A entry for entering floating point numbers.
###### Fields

- `value: float`
- `current {.onlyState.}: float`
- `text {.onlyState.}: string`
- `consistent {.onlyState.}: bool = true`
- `current: float` `onlyState`
- `text: string` `onlyState`
- `consistent: bool = true` `onlyState`
- `eps: float = 0.000001`
- `placeholder: string`
- `width: int = -1`
Expand Down
33 changes: 14 additions & 19 deletions owlkettle/adw.nim
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ renderable ButtonContent of BaseWidget:
label: string
iconName: string
useUnderline: bool ## Defines whether you can use `_` on part of the label to make the button accessible via hotkey. If you prefix a character of the label text with `_` it will hide the `_` and activate the button if you press ALT + the key of the character. E.g. `_Button Text` will trigger the button when pressing `ALT + B`.
canShrink: bool ## Defines whether the ButtonContent can be smaller than the size of its contents. Only available for adwaita version 1.3 or higher. Does nothing if set when compiled for lower adwaita versions.
canShrink {.since: AdwVersion >= (1, 4).}: bool ## Defines whether the ButtonContent can be smaller than the size of its contents.

hooks:
beforeBuild:
Expand All @@ -164,8 +164,7 @@ renderable ButtonContent of BaseWidget:

hooks canShrink:
property:
when AdwVersion >= (1, 4):
adw_button_content_set_can_shrink(state.internalWidget, state.canShrink.cbool)
adw_button_content_set_can_shrink(state.internalWidget, state.canShrink.cbool)

renderable Clamp of BaseWidget:
maximumSize: int ## Maximum width of the content
Expand Down Expand Up @@ -254,7 +253,7 @@ renderable PreferencesPage of BaseWidget:
name: string
title: string
useUnderline: bool
description: string
description {.since: AdwVersion >= (1, 4).}: string

hooks:
beforeBuild:
Expand Down Expand Up @@ -287,8 +286,7 @@ renderable PreferencesPage of BaseWidget:

hooks description:
property:
when AdwVersion >= (1, 4):
adw_preferences_page_set_description(state.internalWidget, state.description.cstring)
adw_preferences_page_set_description(state.internalWidget, state.description.cstring)

adder add:
widget.valPreferences.add(child)
Expand Down Expand Up @@ -347,8 +345,8 @@ renderable ExpanderRow of PreferencesRow:
expanded: bool = false
enableExpansion: bool = true
showEnableSwitch: bool = false
titleLines: int ## Determines how many lines of text from the title are shown before it ellipsizes the text. Defaults to 0 which means it never elipsizes and instead adds new lines to show the full text. Only available for adwaita version 1.3 or higher. Does nothing if set when compiled for lower adwaita versions.
subtitleLines: int ## Determines how many lines of text from the subtitle are shown before it ellipsizes the text. Defaults to 0 which means it never elipsizes and instead adds new lines to show the full text. Only available for adwaita version 1.3 or higher. Does nothing if set when compiled for lower adwaita versions.
titleLines {.since: AdwVersion >= (1, 3).}: int ## Determines how many lines of text from the title are shown before it ellipsizes the text. Defaults to 0 which means it never elipsizes and instead adds new lines to show the full text.
subtitleLines {.since: AdwVersion >= (1, 3).}: int ## Determines how many lines of text from the subtitle are shown before it ellipsizes the text. Defaults to 0 which means it never elipsizes and instead adds new lines to show the full text.

proc expand(newExpandState: bool) ## Triggered when row gets expanded

Expand Down Expand Up @@ -378,7 +376,8 @@ renderable ExpanderRow of PreferencesRow:

hooks actions:
(build, update):
const rowAdder = when AdwVersion >= (1, 4):
const rowAdder =
when AdwVersion >= (1, 4):
adw_expander_row_add_suffix
else:
adw_expander_row_add_action
Expand Down Expand Up @@ -409,13 +408,11 @@ renderable ExpanderRow of PreferencesRow:

hooks titleLines:
property:
when AdwVersion >= (1, 3):
adw_expander_row_set_title_lines(state.internalWidget, state.titleLines.cint)
adw_expander_row_set_title_lines(state.internalWidget, state.titleLines.cint)

hooks subtitleLines:
property:
when AdwVersion >= (1, 3):
adw_expander_row_set_subtitle_lines(state.internalWidget, state.subtitleLines.cint)
adw_expander_row_set_subtitle_lines(state.internalWidget, state.subtitleLines.cint)

adder addAction {.hAlign: AlignFill, vAlign: AlignCenter.}:
widget.hasActions = true
Expand Down Expand Up @@ -841,8 +838,8 @@ renderable AdwHeaderBar of BaseWidget:
showRightButtons: bool = true ## Determines whether the buttons in `rightButtons` are shown. Does not affect Widgets in `packRight`.
showLeftButtons: bool = true ## Determines whether the buttons in `leftButtons` are shown. Does not affect Widgets in `packLeft`.
titleWidget: Widget ## A widget for the title. Replaces the title string, if there is one.
showBackButton: bool = true
showTitle: bool = true ## Determines whether to show or hide the title
showBackButton {.since: AdwVersion >= (1, 4).}: bool = true
showTitle {.since: AdwVersion >= (1, 4).}: bool = true ## Determines whether to show or hide the title

setter windowControls: DecorationLayout
setter windowControls: Option[DecorationLayout]
Expand Down Expand Up @@ -898,13 +895,11 @@ renderable AdwHeaderBar of BaseWidget:

hooks showBackButton:
property:
when AdwVersion >= (1, 4):
adw_header_bar_set_show_back_button(state.internalWidget, state.showBackButton.cbool)
adw_header_bar_set_show_back_button(state.internalWidget, state.showBackButton.cbool)

hooks showTitle:
property:
when AdwVersion >= (1, 4):
adw_header_bar_set_show_title(state.internalWidget, state.showTitle.cbool)
adw_header_bar_set_show_title(state.internalWidget, state.showTitle.cbool)

adder addLeft:
## Adds a widget to the left side of the HeaderBar.
Expand Down
2 changes: 1 addition & 1 deletion owlkettle/bindings/gtk.nim
Original file line number Diff line number Diff line change
Expand Up @@ -836,7 +836,7 @@ proc gtk_image_set_from_pixbuf*(image: GtkWidget, pixbuf: GdkPixbuf)
# Gtk.Picture
proc gtk_picture_new*(): GtkWidget
proc gtk_picture_set_pixbuf*(picture: GtkWidget, pixbuf: GdkPixbuf)
when defined(gtk48):
when GtkMinor >= 8:
proc gtk_picture_set_content_fit*(picture: GtkWidget, fit: GtkContentFit)
else:
proc gtk_picture_set_keep_aspect_ratio*(picture: GtkWidget, keep: cbool)
Expand Down
99 changes: 71 additions & 28 deletions owlkettle/widgetdef.nim
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ type
default: NimNode
hooks: array[HookKind, NimNode]
modifiers: set[FieldModifier]
since: NimNode
lineInfo: NimNode
doc: string

Expand All @@ -124,6 +125,7 @@ type
name: string
kind: WidgetKind
base: string
since: NimNode
events: seq[EventDef]
fields: seq[Field]
hooks: array[HookKind, seq[NimNode]]
Expand Down Expand Up @@ -213,21 +215,27 @@ proc extractDocComment(node: NimNode): string =
newline = str.len - 1
result = str[(pos + 2)..newline].strip()

proc parseFieldModifiers(node: NimNode): set[FieldModifier] =
proc parseFieldPragmas(node: NimNode): tuple[modifiers: set[FieldModifier], since: NimNode] =
case node.kind:
of nnkPragma:
for child in node:
var foundModifier = false
for modifier in low(FieldModifier)..high(FieldModifier):
if child.eqIdent($modifier):
result.incl(modifier)
foundModifier = true
break
if not foundModifier:
error("Invalid field modifier " & node.repr, node)
if child.kind == nnkExprColonExpr and
child[0].eqIdent("since"):
result.since = child[1]
else:
var foundModifier = false
for modifier in low(FieldModifier)..high(FieldModifier):
if child.eqIdent($modifier):
result.modifiers.incl(modifier)
foundModifier = true
break
if not foundModifier:
error("Invalid field modifier " & node.repr, node)
else:
for child in node:
result = result + child.parseFieldModifiers()
let (modifiers, since) = child.parseFieldPragmas()
result.modifiers = result.modifiers + modifiers
result.since = result.since or since

proc parseBody(body: NimNode, def: var WidgetDef) =
assert def.fields.len == 0
Expand Down Expand Up @@ -302,11 +310,14 @@ proc parseBody(body: NimNode, def: var WidgetDef) =
def.adders.add(adder)
else:
child[^1].expectKind(nnkStmtList)
let name = child[0].unwrapName()
let
name = child[0].unwrapName()
(modifiers, since) = child[0].parseFieldPragmas()
var field = Field(
name: name.strVal,
modifiers: child[0].parseFieldModifiers(),
modifiers: modifiers,
lineInfo: name,
since: since,
doc: child[1].extractDocComment()
)
case child[1][0].kind:
Expand Down Expand Up @@ -414,8 +425,10 @@ proc genBuildState(def: WidgetDef): NimNode =
for field in def.fields:
if field.isOnlyState:
continue

let buildField = newStmtList()
if not field.hooks[HookBuild].isNil:
result.add(newBlockStmt(field.hooks[HookBuild].copyNimTree()))
buildField.add(newBlockStmt(field.hooks[HookBuild].copyNimTree()))
else:
var cond = newTree(nnkIfStmt, [
newTree(nnkElifBranch, [
Expand All @@ -431,14 +444,25 @@ proc genBuildState(def: WidgetDef): NimNode =
newDotExpr(state, field.name),
field.default
))))
result.add(cond)
buildField.add(cond)
if not field.hooks[HookProperty].isNil:
result.add(newBlockStmt(field.hooks[HookProperty].copyNimTree()))
buildField.add(newBlockStmt(field.hooks[HookProperty].copyNimTree()))

if field.since.isNil:
result.add(buildField)
else:
result.add(newTree(nnkWhenStmt, [
newTree(nnkElifBranch, [
field.since.copyNimTree(), buildField
])
]))

for event in def.events:
result.add(newAssignment(
newDotExpr(state, event.name),
newDotExpr(widget, event.name)
))

for body in def.hooks[HookConnectEvents]:
result.add(newBlockStmt(body.copyNimTree()))

Expand Down Expand Up @@ -495,11 +519,14 @@ proc genUpdateState(def: WidgetDef): NimNode =

for hook in def.hooks[HookDisconnectEvents]:
result.add(hook.copyNimTree())

for field in def.fields:
if field.isOnlyState:
continue

let updateField = newStmtList()
if not field.hooks[HookUpdate].isNil:
result.add(newBlockStmt(field.hooks[HookUpdate]))
updateField.add(newBlockStmt(field.hooks[HookUpdate]))
else:
let update = newStmtList(newAssignment(
newDotExpr(state, field.name),
Expand All @@ -515,16 +542,28 @@ proc genUpdateState(def: WidgetDef): NimNode =
newDotExpr(widget, field.value)
])
])
result.add(newTree(nnkIfStmt, newTree(nnkElifBranch, [
updateField.add(newTree(nnkIfStmt, newTree(nnkElifBranch, [
cond, update
])))

if field.since.isNil:
result.add(updateField)
else:
result.add(newTree(nnkWhenStmt, [
newTree(nnkElifBranch, [
field.since.copyNimTree(), updateField
])
]))

for event in def.events:
result.add(newAssignment(
newDotExpr(state, event.name),
newDotExpr(widget, event.name)
))

for hook in def.hooks[HookUpdate]:
result.add(newBlockStmt(hook.copyNimTree()))

for hook in def.hooks[HookConnectEvents]:
result.add(newBlockStmt(hook.copyNimTree()))

Expand Down Expand Up @@ -627,25 +666,29 @@ proc formatReference(widget: WidgetDef): string =
if widget.base.len > 0:
result &= "- All fields from [" & widget.base & "](#" & widget.base & ")\n"
for field in widget.fields:
if FieldPrivate in field.modifiers:
if field.isPrivate:
continue
result &= "- `" & field.name
if field.modifiers.len > 0:
result &= " {."
var isFirst = true
for modifier in field.modifiers:
if isFirst:
isFirst = false
else:
result &= ", "
result &= $modifier
result &= ".}"
result &= ": " & field.typ.repr
if not field.default.isNil:
result &= " = " & field.default.repr
result &= "`"
if field.doc.len > 0:
result &= " " & field.doc

if field.modifiers.len > 0 or not field.since.isNil:
result &= " "
var pragmas: seq[string] = @[]
if not field.since.isNil:
pragmas.add("Since: `" & field.since.repr & "`")
for modifier in field.modifiers:
pragmas.add("`" & $modifier & "`")

for it, pragma in pragmas:
if it != 0:
result &= ", "
result &= pragma

result &= "\n"
result &= "\n"
if widget.setters.len > 0:
Expand Down
Loading

0 comments on commit 8254267

Please sign in to comment.