-
Notifications
You must be signed in to change notification settings - Fork 13
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 adw.SpinRow
widget
#88
Comments
Started tinkering around with this one. renderable SpinRow of ActionRow:
climbRate: float = 0.0
digits: uint = 0
numeric: bool = false
min: float = 0.0
max: float = 100.0
snapToTicks: bool = false
updatePolicy: SpinButtonUpdatePolicy = SpinButtonUpdateAlways
value: float = 0.0
wrap: bool = false
proc input(newValue: float)
hooks:
beforeBuild:
let climbRate: float = if widget.hasClimbRate: widget.valClimbRate else: 0.0
let digits: uint = if widget.hasDigits: widget.valDigits else: 0.uint
state.internalWidget = adw_spin_row_new(GtkAdjustment(nil), climbRate.cdouble, digits.cuint)
connectEvents:
proc inputEventCallback(
widget: GtkWidget,
newValue: cdouble,
data: ptr EventObj[proc(newValue: float)]
): cint {.cdecl.} =
let x = data[].widget
echo data == nil # false
echo data[].widget == nil # false
echo SpinRowState(data[].widget) == nil ## Line 740, this line segfaults according to the stacktrace
SpinRowState(data[].widget).value = newValue.float
data[].callback(newValue)
data[].redraw()
result = true.cint
state.connect(state.input, "input", inputEventCallback)
... tons of property hooks that all seem to work fine even though I don't quite get what some of the properties do... stacktrace: false
false
Traceback (most recent call last)
/home/philipp/dev/owlkettle/examples/widgets/adw/spin_row.nim(63) spin_row
/home/philipp/dev/owlkettle/owlkettle/adw.nim(912) brew
/home/philipp/dev/owlkettle/owlkettle/mainloop.nim(96) runMainloop
/home/philipp/dev/owlkettle/owlkettle/adw.nim(740) inputEventCallback
/home/philipp/.choosenim/toolchains/nim-2.0.0/lib/system/arc.nim(238) isObjDisplayCheck
SIGSEGV: Illegal storage access. (Attempt to read from nil?) I don't quite see why this blows up on me. Honestly I don't even quite get the GTK Explanation of what that signal is good for:
Like what? The main reason I wrap this because I assume this is what gets called if you change the value in general on this widget. Any idea what I could look into to try and solve this? I'm not even sure where to look next as the fact that it only blows up inside of I'm a bit flummoxed. (Edit: On an unrelated sidenote: That PR to be able to deal with different adwaita versions paid of so fast it made my head spin. Literally merged the PR and the next issue I stare at requires me to check for Adwaita version 1.4 😆 ) |
One thing I noticed is that your signal handler takes a |
The idea behind input is that you can use a custom parsing function. (idk, maybe parse inputs with units like |
is that not the same? Wait does that star make this a ptr cdouble? |
I officially do not know where the actual value I type into the field comes from or is supposed to come from. If I type in 90 into that value field, it'll do a lot but not return me 90 anywhere. |
Hand --> Face Seriously? The spinbutton wants you to use |
Yeah I'm as stuck as I was yesterday. I updated the example on the branch a bit as well as the widget, but basically I can't get this to work properly. Any value you input does not stick. I'm pretty much stuck. Below the code on the widget to provide cursory glances: when AdwVersion >= (1, 4):
renderable SpinRow of ActionRow:
climbRate: float = 0.0
digits: uint = 0
numeric: bool = false
min: float = 0.0
max: float = 100.0
snapToTicks: bool = false
updatePolicy: SpinButtonUpdatePolicy = SpinButtonUpdateAlways
value: float = 0.0
wrap: bool = false
parseToFloat: (proc(input: string): float) = parseFloat
proc input(newValue: float)
hooks:
beforeBuild:
let climbRate: float = if widget.hasClimbRate: widget.valClimbRate else: 0.0
let digits: uint = if widget.hasDigits: widget.valDigits else: 0.uint
state.internalWidget = adw_spin_row_new(GtkAdjustment(nil), climbRate.cdouble, digits.cuint)
connectEvents:
proc inputEventCallback(
widget: GtkWidget,
newValueHolder: ptr cdouble,
data: ptr EventObj[proc(newValue: float)]
): cint {.cdecl.} =
var newValue: float
try:
newValue = SpinRowState(data[].widget).parseToFloat($gtk_editable_get_text(widget))
except ValueError as e:
return GtkInputError
echo "Input event callback: ", newValue
echo "\n"
newValueHolder[] = newValue.cdouble
SpinRowState(data[].widget).value = newValue
data[].callback(newValue)
data[].redraw()
return true.cint
state.connect(state.input, "input", inputEventCallback)
# state.connect(state.output, "output", eventCallback)
# state.connect(state.wrapped, "wrapped", eventCallback)
hooks climbRate:
property:
adw_spin_row_set_climb_rate(state.internalWidget, state.climbRate.cdouble)
hooks digits:
property:
adw_spin_row_set_digits(state.internalWidget, state.digits.cuint)
hooks numeric:
property:
adw_spin_row_set_numeric(state.internalWidget, state.numeric.cbool)
hooks min:
property:
adw_spin_row_set_range(state.internalWidget, state.min.cdouble, state.max.cdouble)
hooks max:
property:
adw_spin_row_set_range(state.internalWidget, state.min.cdouble, state.max.cdouble)
hooks snapToTicks:
property:
adw_spin_row_set_snap_to_ticks(state.internalWidget, state.snapToTicks.cbool)
hooks updatePolicy:
property:
adw_spin_row_set_update_policy(state.internalWidget, state.updatePolicy)
hooks value:
property:
echo "Value was updated to: ", state.value
adw_spin_row_set_value(state.internalWidget, state.value.cdouble)
hooks wrap:
property:
adw_spin_row_set_wrap(state.internalWidget, state.wrap.cbool)
export SpinRow |
You currently don't have a changed/valueChanged/... callback (not sure what it is called for SpinRow), that makes a 2-way binding possible. |
Tried that just now by trying to start off simple and only doing changed. So with this approach, I have a widget. However that widget has the following bugs:
Here the ObjectConversionStackTrace echo'd out: ref Exception(parent: nil, name: "ObjectConversionDefect", msg: "invalid object conversion", trace:
@[
StackTraceEntry(procname: "spin_row", line: 61, filename: "/home/philipp/dev/owlkettle/examples/widgets/adw/spin_row.nim"),
StackTraceEntry(procname: "brew", line: 920, filename: "/home/philipp/dev/owlkettle/owlkettle/adw.nim"),
StackTraceEntry(procname: "runMainloop", line: 96, filename: "/home/philipp/dev/owlkettle/owlkettle/mainloop.nim"),
StackTraceEntry(procname: "changedCallback", line: 748, filename: "/home/philipp/dev/owlkettle/owlkettle/adw.nim"),
StackTraceEntry(procname: "sysFatal", line: 53, filename: "/home/philipp/.choosenim/toolchains/nim-2.0.0/lib/system/fatal.nim")
],
up: nil) I just can't explain why 0 somehow is a value that leads to ObjectConversionDefects. Nor why catching those exception still enables Segfaults elsewhere. Below the current still completely busted approach: when AdwVersion >= (1, 4):
renderable SpinRow of ActionRow:
climbRate: float = 0.0
digits: uint = 0
numeric: bool = false
min: float = 0.0
max: float = 100.0
snapToTicks: bool = false
updatePolicy: SpinButtonUpdatePolicy = SpinButtonUpdateAlways
value: float = 0
wrap: bool = false
proc changed(newValue: float)
hooks:
beforeBuild:
let climbRate: float = if widget.hasClimbRate: widget.valClimbRate else: 0.0
let digits: uint = if widget.hasDigits: widget.valDigits else: 0.uint
state.internalWidget = adw_spin_row_new(GtkAdjustment(nil), climbRate.cdouble, digits.cuint)
connectEvents:
proc changedCallback(widget: GtkWidget, data: ptr EventObj[proc (newValue: float)]) {.cdecl.} =
echo "Changed Signal"
var newValue: float
try:
let valueString = $gtk_editable_get_text(widget)
echo "The value: ", valueString
newValue = parseFloat(valueString)
except Exception as e:
echo "Borked: ", e.repr
newValue = 0.0
echo data.isNil
echo data[].widget.isNil
SpinRowState(data[].widget).value = newValue
data[].callback(newValue)
data[].redraw()
state.connect(state.changed, "changed", changedCallback)
# state.connect(state.output, "output", eventCallback)
# state.connect(state.wrapped, "wrapped", eventCallback)
hooks climbRate:
property:
adw_spin_row_set_climb_rate(state.internalWidget, state.climbRate.cdouble)
hooks digits:
property:
adw_spin_row_set_digits(state.internalWidget, state.digits.cuint)
hooks numeric:
property:
adw_spin_row_set_numeric(state.internalWidget, state.numeric.cbool)
hooks min:
property:
adw_spin_row_set_range(state.internalWidget, state.min.cdouble, state.max.cdouble)
hooks max:
property:
adw_spin_row_set_range(state.internalWidget, state.min.cdouble, state.max.cdouble)
hooks snapToTicks:
property:
adw_spin_row_set_snap_to_ticks(state.internalWidget, state.snapToTicks.cbool)
hooks updatePolicy:
property:
adw_spin_row_set_update_policy(state.internalWidget, state.updatePolicy)
hooks value:
property:
echo "Value was updated to: ", state.value
adw_spin_row_set_value(state.internalWidget, state.value.cdouble)
hooks wrap:
property:
adw_spin_row_set_wrap(state.internalWidget, state.wrap.cbool)
export SpinRow |
This doesn't really make it all that batter, it still segfaults if you do anything, but at least this is more according to the docs. No idea how to fix it.
https://gnome.pages.gitlab.gnome.org/libadwaita/doc/main/class.SpinRow.html
The text was updated successfully, but these errors were encountered: