bohonghuang / cl-gtk4

GTK4/Libadwaita/WebKit2 bindings for Common Lisp.
GNU Lesser General Public License v3.0
215 stars 9 forks source link

0 is not of type DOUBLE-FLOAT in make-level-bar #28

Closed jonathanabennett closed 1 year ago

jonathanabennett commented 1 year ago

when executing the code

(let ((level-bar-widget (gtk:make-level-bar :min-value 0 :max-value 4)))
  (setf (gtk:level-bar-mode level-bar-widget) gtk:+level-bar-mode-discrete+)
  (setf (gtk:level-bar-value level-bar-widget) 2)
  (gtk:box-append layout level-bar-widget))

I receive the following error:

#<THREAD "main thread" RUNNING {7006070483}>:
  The value
    0
  is not of type
    DOUBLE-FLOAT

Type HELP for debugger help, or (SB-EXT:EXIT) to exit from SBCL.

restarts (invokable by number or by possibly-abbreviated name):
  0: [RETURN                ] Return from current handler.
  1: [RETURN-AND-ABORT      ] Return from current handler and abort the GTK application.
  2: [RETURN-VALUE          ] Return from current handler with specified value.
  3: [RETURN-VALUE-AND-ABORT] Return from current handler with specified value and abort the GTK application.
  4: [CONTINUE              ] Ignore runtime option --eval "(megastrike)".
  5: [ABORT                 ] Skip rest of --eval and --load options.
  6:                          Skip to toplevel READ/EVAL/PRINT loop.
  7: [EXIT                  ] Exit SBCL (calling #'EXIT, killing the process).

(CFFI-SYS:%MEM-SET 0 #.(SB-SYS:INT-SAP #X600003149108) :DOUBLE 0)
   source: (DEFINE-TYPE-MAPPING
            ((8 SB-SYS:SIGNED-SAP-REF-8 SB-SYS:SAP-REF-8)
             (16 SB-SYS:SIGNED-SAP-REF-16 SB-SYS:SAP-REF-16)
             (32 SB-SYS:SIGNED-SAP-REF-32 SB-SYS:SAP-REF-32)
             (64 SB-SYS:SIGNED-SAP-REF-64 SB-SYS:SAP-REF-64))
            ((:CHAR CHAR) (:UNSIGNED-CHAR UNSIGNED-CHAR) (:SHORT SHORT)
             (:UNSIGNED-SHORT UNSIGNED-SHORT) (:INT INT)
             (:UNSIGNED-INT UNSIGNED-INT) (:LONG LONG)
             (:UNSIGNED-LONG UNSIGNED-LONG) (:LONG-LONG LONG-LONG)
             (:UNSIGNED-LONG-LONG UNSIGNED-LONG-LONG)
             (:FLOAT SINGLE-FLOAT SB-SYS:SAP-REF-SINGLE)
             (:DOUBLE DOUBLE-FLOAT SB-SYS:SAP-REF-DOUBLE) ...))

I receive the same error when using 0.0, 4.0, and 2.0 and my fumbling around inside the GTK and GOBJ namespaces doesn't return anything that looks like DOUBLE-FLOAT to me.

bohonghuang commented 1 year ago

In Common Lisp, single-precision floating-point is the default, so both 0.0 and 0s0 represent single-precision floating-point numbers. To use double-precision floating-point, you need to write it as 0d0. Therefore, your code should be modified as follows:

(let ((level-bar-widget (gtk:make-level-bar :min-value 0d0 :max-value 4d0)))
  (setf (gtk:level-bar-mode level-bar-widget) gtk:+level-bar-mode-discrete+)
  (setf (gtk:level-bar-value level-bar-widget) 2d0)
  (gtk:box-append box level-bar-widget))
jonathanabennett commented 1 year ago

Aha, so maybe I'm doing this wrong but what if the data in the code is an integer? I'm trying to draw the HP a unit has remaining and I had thought that a discrete-mode level-bar from 0 to unit/max-hp, with the value set to unit/current-hp would be the best way to do that. But you can't lose half a hitpoint, so I'm keeping it internally as an int.

Is there another widget that would be better for this? I had originally considered making a drawing-area and drawing filled and emptied circles to mark of hits, but then I found the level bar.

jonathanabennett commented 1 year ago

I went ahead and just used either 0d0 or (float (num/accessor obj) 0d0) and it is working. So I'll just run with that for now since looking through the widget gallery didn't give me any more inspiration.

bohonghuang commented 1 year ago

Many functions in GTK accept double-precision floating-point numbers as parameters. You can also use (coerce 123 'double-float) to achieve the same effect. You don't have to worry about the range of values because double-precision floating-point numbers can represent a much larger range than the commonly used int in C or Java.