Skip to content
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

Custom formatting in SpinButton #191

Open
Psirus opened this issue Dec 12, 2021 · 7 comments
Open

Custom formatting in SpinButton #191

Psirus opened this issue Dec 12, 2021 · 7 comments

Comments

@Psirus
Copy link

Psirus commented Dec 12, 2021

Hello, and thanks for these great GTK bindings. I'm trying to display seconds in a SpinButton, i.e. the value 5.4 should be seen in the button as 5.4 s. Here is what I have so far by trying to adapting the SpinButton example from the gtk3-demo, but no luck. It doesn't show the starting value, and crashes upon trying to change it. Where is my mistake?

import strutils
import gintro/[gtk, glib, gobject, gio]

proc printSeconds(button: SpinButton): bool =
  let adj = button.getAdjustment()
  let value = adj.getValue()
  button.setText($value & " s")
  return true

proc parseSeconds(button: SpinButton, new_val: var float): int =
  var text = button.getText()
  text.removeSuffix(" s")
  new_val = parseFloat(text)
  return 1

proc appActivate(app: Application) =
  let window = newApplicationWindow(app)
  window.title = "GTK3 & Nim"
  window.defaultSize = (200, 200)
  let button = newSpinButtonWithRange(0, 20.0, 0.1)
  button.connect("input", parseSeconds)
  button.connect("output", printSeconds)
  window.add(button)
  showAll(window)

proc main =
  let app = newApplication("org.gtk.example")
  connect(app, "activate", appActivate)
  discard run(app)

main()
@StefanSalewski
Copy link
Owner

Do you really intent to use still GTK3? GTK4 is available for more than one year now.

Unfortunately I have available only gtk4-demo, and there something like setText() seems to be not used, and I can not find it in the GTK4 API docs, so it may be removed?

If it is really removed, and you want to continue using GTK3, I have to do some research.

Maybe you can provide a working GTK3 C example, or at least send a copy of the sourcecode shown in the gtk3-demo. Otherwise I have to ask Google or Mr. Bassi at GTK forum.

@Psirus
Copy link
Author

Psirus commented Dec 12, 2021

Unfortunately GTK4 hasn't made it into Debian stable yet, which is what I'm using, so its not as easy as apt install libgtk-4-dev. It seemed easier just to go with GTK3 than building GTK from source, but I'll look into it.

I have uploaded the code of the GTK3 example here: https://gist.github.com/Psirus/5661cdc94aff4fa61df1b97f8e40d2cd

@StefanSalewski
Copy link
Owner

Thanks for the C example, I will look into it. Should be not that difficult to fix.

Generally I would recommend using GTK4 instead of GTK3 now -- even Debian should offer more recent software than its stable. I always install recent GTK4 from git sources to /opt, which is easy with the exception of webkitgtk, which you should not need. And there should be other solutions, flatpack and that.

When you start with GTK3, you have to convert it later to GTK4, which is again some work.

Will see If I get your GTK3 spin button code to work, maybe later this evening or tomorrow.

@StefanSalewski
Copy link
Owner

Your problems are in no way related to GTK or the gintro bindings. You just have to learn some basic programming skills. And indeed the compiler tells you already where the issue is:

$ ./t2
>>>
/tmp/hhh/t2.nim(33)      t2
/tmp/hhh/t2.nim(31)      main
/home/salewski/.nimble/pkgs/gintro-0.9.6/gintro/gio.nim(31423) run
(3)                      connect_for_signal_cdecl_input1
/tmp/hhh/t2.nim(14)      parseSeconds
/home/salewski/Nim/lib/pure/strutils.nim(1120) parseFloat
Error: unhandled exception: invalid float:  [ValueError]
import strutils
import gintro/[gtk, glib, gobject, gio]

proc printSeconds(button: SpinButton): bool =
  let adj = button.getAdjustment()
  let value = adj.getValue()
  button.setText($value & " s")
  return true

proc parseSeconds(button: SpinButton, new_val: var float): int =
  var text = button.getText()
  echo ">>>",  text
  text.removeSuffix(" s")
  new_val = parseFloat(text)
  echo "end of parseSeconds"
  return 1

proc appActivate(app: Application) =
  let window = newApplicationWindow(app)
  window.title = "GTK3 & Nim"
  window.defaultSize = (200, 200)
  let button = newSpinButtonWithRange(0, 20.0, 0.1)
  button.connect("input", parseSeconds)
  button.connect("output", printSeconds)
  window.add(button)
  showAll(window)

proc main =
  let app = newApplication("org.gtk.example")
  connect(app, "activate", appActivate)
  discard run(app)

main()

Well, I have added two echo statements, but without the error message should be very similar. You problem is just, that you call "new_val = parseFloat(text)" where text is an empty string. Well you may expect that text is always a valid floating point number, but to be sure one would have to study GTK docs very carefully. And even then, calling parseFloat() in that way would be still not a good idea.

Here is my code with which I started my investigations one hour ago:

#import strutils
from parseutils import parseFloat
import gintro/[gtk, glib, gobject, gio]

#[
gboolean
output (
  GtkSpinButton* self,
  gpointer user_data
)
]#
proc printSeconds(button: SpinButton): bool =
  echo "printSeconds"
  echo button.getText
  echo button.getValue
  button.setText($button.getValue & " s")
  return true # TRUE if the value has been displayed.

#https://docs.gtk.org/gtk3/signal.SpinButton.input.html
#[
gint
input (
  GtkSpinButton* self,
  gdouble* new_value,
  gpointer user_data
)
]#
proc parseSeconds(button: SpinButton, new_val: var float): int =
  var text = button.getText()
  echo "parseSeconds"
  if text == "zero":
    new_val = 0
    return true.ord
  var f: float
  var res = text.parseFloat(f)
  if res > 0:
    new_val = f
    return true.ord
  else:
    return INPUT_ERROR
  #return 1 #TRUE for a successful conversion, FALSE if the input was not handled, and GTK_INPUT_ERROR if the conversion failed.

proc appActivate(app: Application) =
  let window = newApplicationWindow(app)
  window.title = "GTK3 & Nim"
  window.defaultSize = (200, 200)
  let button = newSpinButtonWithRange(0, 20.0, 0.1)
  button.numeric = false
  button.connect("input", parseSeconds)
  button.connect("output", printSeconds)
  window.add(button)
  showAll(window)

proc main =
  let app = newApplication("org.gtk.example")
  connect(app, "activate", appActivate)
  discard run(app)

main()

Seems to work. I would recommend you to read a good book about computer programming -- my one is still freely available, but some people do not like it :-). The other question is if I should really recommend you to use GTK at all. Learning GTK is a lot of hard work, and I have to admit that the number of gintro users is tiny, maybe two or tree currently, after all these years. Nim has 20 other GUI toolkits, I have listed them in the GTK4 book at the beginning. Maybe one of them is a better solution for you. When GTK4 was released one year ago I still had the hope that this would increase the general popularity of the GTK toolkit, but my feeling is that the number of all GTK users is close to zero currently. There are some people who still use it from C or Python, but all the other bindings seems to have nearly zero users now. And I have seen only very few new GTK projects in the last 10 years.

Araq seems to favor the fidget GUI project. I can not say much about it, but at least it is pure Nim, and its author is really smart.

@Psirus
Copy link
Author

Psirus commented Dec 12, 2021

Thanks for your help. I quite like GTK, since the resulting app looks "native". Fidget, Electron etc. seem to assume that I want to apply my own "branding", which I don't really care about. I'll look through the list of toolkits, maybe something else intrigues me. As for users, maybe gintro hasn't taken off, but in C, all of the Xfce, Gnome and Mate apps are using GTK, no? Seems like a healthy userbase.

@StefanSalewski
Copy link
Owner

Fine.

Unfortunately most people hate the GTK look, as it does not look native on Windows and Mac, and as it has no Web and ANDROID support. And for the userbase, well many people are still using GTK apps, but most is old stuff written more then 10 years ago.

But when you like me mostly use Linux, then GTK may be fine for you. Unfortunately the gintro bindings are not that good as the Rust and Python bindings, and I don't know if they ever will be. Due to the few users no one really has motivation to do much more work on the bindings.

@gavr123456789
Copy link

I think 60-80% of linuxoids using GTK. And on Windows nobody care about native look of app.
There no such thing as native look on Windows!
image
image
image
image
image
image
image
image
image
image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants