1bab7a778cd2e4ebe5dcbb8fc16ffdd60b15ebe2 — octaspire 5 months ago 43f9109 v0.470.0
Implement more Nuklear widgets in the Nuklear plugin

* Implement more Nuklear widgets in the Nuklear plugin;

  - Floating point slider
  - Radio button

* Include the (external) Nuklear implementation in the
  generated TAGS file and cscope databases to allow easy
  code navigation also in that implementation.

* Add more helper functions into the Dern implementation
  for easing and streamlining working with different kinds
  of (Dern) arguments.
M GNUmakefile => GNUmakefile +4 -1
@@ 18,7 18,10 @@ CFLAGS=-std=c99 -Wall -Wextra -g -O2 -DOCTASPIRE_DERN_CONFIG_BINARY_PLUGINS
  SQLITE3_CFLAGS=-std=c99 -Wall
  
- TAGS_C_FILES := $(SRCDIR)*.c $(INCDIR)*.h $(CORDIR)octaspire-core-amalgamated.c
+ TAGS_C_FILES := $(SRCDIR)*.c                          \
+                 $(INCDIR)*.h                          \
+                 $(CORDIR)octaspire-core-amalgamated.c \
+                 $(PLUGINDIR)external/nuklear/nuklear.h
  
  TAGS_DERN_FILES := $(GAMESDIR)octaspire-bounce.dern    \
                     $(GAMESDIR)octaspire-lightcube.dern \

M dev/include/octaspire/dern/octaspire_dern_config.h => dev/include/octaspire/dern/octaspire_dern_config.h +1 -1
@@ 18,7 18,7 @@ #define OCTASPIRE_DERN_CONFIG_H
  
  #define OCTASPIRE_DERN_CONFIG_VERSION_MAJOR "0"
- #define OCTASPIRE_DERN_CONFIG_VERSION_MINOR "469"
+ #define OCTASPIRE_DERN_CONFIG_VERSION_MINOR "470"
  #define OCTASPIRE_DERN_CONFIG_VERSION_PATCH "0"
  
  #define OCTASPIRE_DERN_CONFIG_VERSION_STR "Octaspire Dern version " \

M dev/include/octaspire/dern/octaspire_dern_value.h => dev/include/octaspire/dern/octaspire_dern_value.h +46 -0
@@ 544,6 544,10 @@ char const *octaspire_dern_value_as_symbol_get_c_string(
      octaspire_dern_value_t const * const self);
  
+ bool octaspire_dern_value_as_symbol_set_c_string(
+     octaspire_dern_value_t * const self,
+     char const * const str);
+ 
  bool octaspire_dern_value_is_symbol_and_equal_to_c_string(
      octaspire_dern_value_t const * const self,
      char const * const str);


@@ 635,6 639,22 @@ }
  octaspire_dern_number_or_unpushed_error_const_t;
  
+ typedef struct octaspire_dern_boolean_or_unpushed_error_t
+ {
+     bool                     boolean;
+     octaspire_dern_value_t * value;
+     octaspire_dern_value_t * unpushedError;
+ }
+ octaspire_dern_boolean_or_unpushed_error_t;
+ 
+ typedef struct octaspire_dern_boolean_or_unpushed_error_const_t
+ {
+     bool                           boolean;
+     octaspire_dern_value_t const * value;
+     octaspire_dern_value_t       * unpushedError;
+ }
+ octaspire_dern_boolean_or_unpushed_error_const_t;
+ 
  typedef struct octaspire_dern_text_or_unpushed_error_t
  {
      octaspire_string_t     const * text;


@@ 651,6 671,14 @@ }
  octaspire_dern_text_or_unpushed_error_const_t;
  
+ typedef struct octaspire_dern_symbol_or_unpushed_error_t
+ {
+     octaspire_string_t     const * symbol;
+     octaspire_dern_value_t       * value;
+     octaspire_dern_value_t       * unpushedError;
+ }
+ octaspire_dern_symbol_or_unpushed_error_t;
+ 
  typedef struct octaspire_dern_one_of_texts_or_unpushed_error_t
  {
      octaspire_string_t     const * text;


@@ 691,6 719,18 @@ ptrdiff_t const possiblyNegativeIndex,
      char const * const dernFuncName);
  
+ octaspire_dern_boolean_or_unpushed_error_t
+ octaspire_dern_value_as_vector_get_element_at_as_boolean_or_unpushed_error(
+     octaspire_dern_value_t * const self,
+     ptrdiff_t const possiblyNegativeIndex,
+     char const * const dernFuncName);
+ 
+ octaspire_dern_boolean_or_unpushed_error_const_t
+ octaspire_dern_value_as_vector_get_element_at_as_boolean_or_unpushed_error_const(
+     octaspire_dern_value_t const * const self,
+     ptrdiff_t const possiblyNegativeIndex,
+     char const * const dernFuncName);
+ 
  octaspire_dern_number_or_unpushed_error_t
  octaspire_dern_value_as_vector_get_element_at_as_number_or_unpushed_error(
      octaspire_dern_value_t * const self,


@@ 703,6 743,12 @@ ptrdiff_t const possiblyNegativeIndex,
      char const * const dernFuncName);
  
+ octaspire_dern_symbol_or_unpushed_error_t
+ octaspire_dern_value_as_vector_get_element_at_as_symbol_or_unpushed_error(
+     octaspire_dern_value_t * const self,
+     ptrdiff_t const possiblyNegativeIndex,
+     char const * const dernFuncName);
+ 
  octaspire_dern_one_of_texts_or_unpushed_error_const_t
  octaspire_dern_value_as_vector_get_element_at_as_one_of_texts_or_unpushed_error_const(
      octaspire_dern_value_t const * const self,

M dev/src/octaspire_dern_value.c => dev/src/octaspire_dern_value.c +111 -0
@@ 3059,6 3059,14 @@ return octaspire_string_get_c_string(self->value.symbol);
  }
  
+ bool octaspire_dern_value_as_symbol_set_c_string(
+     octaspire_dern_value_t * const self,
+     char const * const str)
+ {
+     octaspire_helpers_verify_true(self->typeTag == OCTASPIRE_DERN_VALUE_TAG_SYMBOL);
+     return octaspire_string_set_from_c_string(self->value.symbol, str);
+ }
+ 
  bool octaspire_dern_value_is_symbol_and_equal_to_c_string(
      octaspire_dern_value_t const * const self,
      char const * const str)


@@ 3524,6 3532,68 @@ return result;
  }
  
+ octaspire_dern_boolean_or_unpushed_error_t
+ octaspire_dern_value_as_vector_get_element_at_as_boolean_or_unpushed_error(
+     octaspire_dern_value_t * const self,
+     ptrdiff_t const possiblyNegativeIndex,
+     char const * const dernFuncName)
+ {
+     octaspire_dern_boolean_or_unpushed_error_t result = {false, 0, 0};
+ 
+     octaspire_dern_boolean_or_unpushed_error_const_t const constResult =
+         octaspire_dern_value_as_vector_get_element_at_as_boolean_or_unpushed_error_const(
+             self,
+             possiblyNegativeIndex,
+             dernFuncName);
+ 
+     result.boolean       = constResult.boolean;
+     result.value         = (octaspire_dern_value_t*)constResult.value;
+     result.unpushedError = constResult.unpushedError;
+ 
+     return result;
+ }
+ 
+ octaspire_dern_boolean_or_unpushed_error_const_t
+ octaspire_dern_value_as_vector_get_element_at_as_boolean_or_unpushed_error_const(
+     octaspire_dern_value_t const * const self,
+     ptrdiff_t const possiblyNegativeIndex,
+     char const * const dernFuncName)
+ {
+     octaspire_helpers_verify_not_null(self);
+ 
+     octaspire_dern_vm_t * const vm = self->vm;
+ 
+     octaspire_helpers_verify_not_null(vm);
+ 
+     size_t const stackLength = octaspire_dern_vm_get_stack_length(vm);
+     octaspire_dern_boolean_or_unpushed_error_const_t result = {false, 0, 0};
+ 
+     octaspire_dern_value_t const * const arg =
+         octaspire_dern_value_as_vector_get_element_at_const(self, possiblyNegativeIndex);
+ 
+     octaspire_helpers_verify_not_null(arg);
+ 
+     if (!octaspire_dern_value_is_boolean(arg))
+     {
+         result.unpushedError = octaspire_dern_vm_create_new_value_error_format(
+             vm,
+             "Builtin '%s' expects boolean as "
+             "%d. argument. Type '%s' was given.",
+             dernFuncName,
+             possiblyNegativeIndex,
+             octaspire_dern_value_helper_get_type_as_c_string(arg->typeTag));
+ 
+         octaspire_helpers_verify_true(
+             stackLength == octaspire_dern_vm_get_stack_length(vm));
+ 
+         return result;
+     }
+ 
+     result.value   = arg;
+     result.boolean = octaspire_dern_value_as_boolean_get_value(arg);
+     return result;
+ }
+ 
  octaspire_dern_number_or_unpushed_error_t
  octaspire_dern_value_as_vector_get_element_at_as_number_or_unpushed_error(
      octaspire_dern_value_t * const self,


@@ 3585,6 3655,47 @@ return result;
  }
  
+ octaspire_dern_symbol_or_unpushed_error_t
+ octaspire_dern_value_as_vector_get_element_at_as_symbol_or_unpushed_error(
+     octaspire_dern_value_t * const self,
+     ptrdiff_t const possiblyNegativeIndex,
+     char const * const dernFuncName)
+ {
+     octaspire_helpers_verify_not_null(self);
+ 
+     octaspire_dern_vm_t * const vm = self->vm;
+ 
+     octaspire_helpers_verify_not_null(vm);
+ 
+     size_t const stackLength = octaspire_dern_vm_get_stack_length(vm);
+     octaspire_dern_symbol_or_unpushed_error_t result = {0, 0, 0};
+ 
+     octaspire_dern_value_t * const arg =
+         octaspire_dern_value_as_vector_get_element_at(self, possiblyNegativeIndex);
+ 
+     octaspire_helpers_verify_not_null(arg);
+ 
+     if (!octaspire_dern_value_is_symbol(arg))
+     {
+         result.unpushedError = octaspire_dern_vm_create_new_value_error_format(
+             vm,
+             "Builtin '%s' expects symbol as "
+             "%d. argument. Type '%s' was given.",
+             dernFuncName,
+             possiblyNegativeIndex,
+             octaspire_dern_value_helper_get_type_as_c_string(arg->typeTag));
+ 
+         octaspire_helpers_verify_true(
+             stackLength == octaspire_dern_vm_get_stack_length(vm));
+ 
+         return result;
+     }
+ 
+     result.value  = arg;
+     result.symbol = octaspire_dern_value_as_text_get_string(arg);
+     return result;
+ }
+ 
  octaspire_dern_one_of_texts_or_unpushed_error_const_t
  octaspire_dern_value_as_vector_get_element_at_as_one_of_texts_or_unpushed_error_const(
      octaspire_dern_value_t const * const self,

M release/examples/dern-nuklear-example.dern => release/examples/dern-nuklear-example.dern +55 -5
@@ 33,22 33,72 @@ (define dern-nuklear-example-target-FPS            as {D+100} [target FPS])
  (define dern-nuklear-example-target-frame-duration as (/ {D+1.0} dern-nuklear-example-target-FPS) [time for a frame to last])
  
- (define dern-nuklear-example-checkbox-active       as false  [is checkbox active or not])
- (define dern-nuklear-example-slider-int-value      as {D+15} [current value of the integer slider])
+ (define dern-nuklear-example-checkbox-active       as false    [is checkbox active or not])
+ (define dern-nuklear-example-slider-int-value      as {D+15}   [current value of the integer slider])
+ (define dern-nuklear-example-slider-float-value    as {D+1.75} [current value of the floating point slider])
+ (define dern-nuklear-example-radio-option          as 'EASY    [currently selected option])
  
  (define dern-nuklear-example-render as (fn ()
    (if (nuklear-begin dern-nuklear-example-nuklear-ctx [] {D+10} {D+10} {D+780} {D+580})
      (do
+       ; Text Label
        (nuklear-layout-row-static dern-nuklear-example-nuklear-ctx {D+30} {D+150} {D+1})
        (nuklear-label dern-nuklear-example-nuklear-ctx [-- Text --] 'RIGHT)
+ 
+       ; Progress Bar
        (nuklear-layout-row-static dern-nuklear-example-nuklear-ctx {D+30} {D+150} {D+1})
        (nuklear-progress dern-nuklear-example-nuklear-ctx {D+125} {D+250} false)
+ 
+       ; Text Button
        (nuklear-layout-row-static dern-nuklear-example-nuklear-ctx {D+90} {D+150} {D+1})
-       (if (nuklear-button-label dern-nuklear-example-nuklear-ctx [Quit Button]) (= dern-nuklear-example-running false))
+       (if (nuklear-button-label
+             dern-nuklear-example-nuklear-ctx
+             [Quit Button])
+           (= dern-nuklear-example-running false))
+ 
+       ; Checkbox
        (nuklear-layout-row-static dern-nuklear-example-nuklear-ctx {D+90} {D+150} {D+1})
-       (if (nuklear-checkbox-label dern-nuklear-example-nuklear-ctx [Checkbox] dern-nuklear-example-checkbox-active) (println [Toggled to {}] dern-nuklear-example-checkbox-active))
+       (if (nuklear-checkbox-label
+             dern-nuklear-example-nuklear-ctx
+             [Checkbox]
+             dern-nuklear-example-checkbox-active)
+           (println [Toggled to {}] dern-nuklear-example-checkbox-active))
+ 
+       ; Slider (integer values and steps)
        (nuklear-layout-row-static dern-nuklear-example-nuklear-ctx {D+90} {D+150} {D+1})
-       (if (nuklear-slider-int dern-nuklear-example-nuklear-ctx {D+10} dern-nuklear-example-slider-int-value {D+20} {D+1}) (println [int to {}] dern-nuklear-example-slider-int-value))))
+       (if (nuklear-slider-int
+             dern-nuklear-example-nuklear-ctx
+             {D+10}                                ; Minimum value
+             dern-nuklear-example-slider-int-value ; Current value
+             {D+20}                                ; Maximum value
+             {D+1})                                ; Step size
+           (println [int to {}] dern-nuklear-example-slider-int-value))
+ 
+       ; Slider (floating point values and steps)
+       (nuklear-layout-row-static dern-nuklear-example-nuklear-ctx {D+90} {D+150} {D+1})
+       (if (nuklear-slider-float
+             dern-nuklear-example-nuklear-ctx
+             {D+1.5}                                 ; Minimum value
+             dern-nuklear-example-slider-float-value ; Current value
+             {D+2.5}                                 ; Maximum value
+             {D+0.1})                                ; Step size
+           (println [float to {}] dern-nuklear-example-slider-float-value))
+ 
+       ; Radio buttons
+       (nuklear-layout-row-static dern-nuklear-example-nuklear-ctx {D+90} {D+150} {D+2})
+       (if (nuklear-option-label
+             dern-nuklear-example-nuklear-ctx
+             [Easy]
+             'EASY
+             dern-nuklear-example-radio-option)
+           (println [EASY selected]))
+       (if (nuklear-option-label
+             dern-nuklear-example-nuklear-ctx
+             [Hard]
+             'HARD
+             dern-nuklear-example-radio-option)
+           (println [HARD selected]))
+       (println [Radio option {} is active] dern-nuklear-example-radio-option)))
    (nuklear-end dern-nuklear-example-nuklear-ctx)
    (nuklear-sdl-render)
    (sdl2-GL-SwapWindow dern-nuklear-example-window))

M release/octaspire-dern-amalgamated.c => release/octaspire-dern-amalgamated.c +158 -1
@@ 26223,7 26223,7 @@ #define OCTASPIRE_DERN_CONFIG_H
  
  #define OCTASPIRE_DERN_CONFIG_VERSION_MAJOR "0"
- #define OCTASPIRE_DERN_CONFIG_VERSION_MINOR "469"
+ #define OCTASPIRE_DERN_CONFIG_VERSION_MINOR "470"
  #define OCTASPIRE_DERN_CONFIG_VERSION_PATCH "0"
  
  #define OCTASPIRE_DERN_CONFIG_VERSION_STR "Octaspire Dern version " \


@@ 27130,6 27130,10 @@ char const *octaspire_dern_value_as_symbol_get_c_string(
      octaspire_dern_value_t const * const self);
  
+ bool octaspire_dern_value_as_symbol_set_c_string(
+     octaspire_dern_value_t * const self,
+     char const * const str);
+ 
  bool octaspire_dern_value_is_symbol_and_equal_to_c_string(
      octaspire_dern_value_t const * const self,
      char const * const str);


@@ 27221,6 27225,22 @@ }
  octaspire_dern_number_or_unpushed_error_const_t;
  
+ typedef struct octaspire_dern_boolean_or_unpushed_error_t
+ {
+     bool                     boolean;
+     octaspire_dern_value_t * value;
+     octaspire_dern_value_t * unpushedError;
+ }
+ octaspire_dern_boolean_or_unpushed_error_t;
+ 
+ typedef struct octaspire_dern_boolean_or_unpushed_error_const_t
+ {
+     bool                           boolean;
+     octaspire_dern_value_t const * value;
+     octaspire_dern_value_t       * unpushedError;
+ }
+ octaspire_dern_boolean_or_unpushed_error_const_t;
+ 
  typedef struct octaspire_dern_text_or_unpushed_error_t
  {
      octaspire_string_t     const * text;


@@ 27237,6 27257,14 @@ }
  octaspire_dern_text_or_unpushed_error_const_t;
  
+ typedef struct octaspire_dern_symbol_or_unpushed_error_t
+ {
+     octaspire_string_t     const * symbol;
+     octaspire_dern_value_t       * value;
+     octaspire_dern_value_t       * unpushedError;
+ }
+ octaspire_dern_symbol_or_unpushed_error_t;
+ 
  typedef struct octaspire_dern_one_of_texts_or_unpushed_error_t
  {
      octaspire_string_t     const * text;


@@ 27277,6 27305,18 @@ ptrdiff_t const possiblyNegativeIndex,
      char const * const dernFuncName);
  
+ octaspire_dern_boolean_or_unpushed_error_t
+ octaspire_dern_value_as_vector_get_element_at_as_boolean_or_unpushed_error(
+     octaspire_dern_value_t * const self,
+     ptrdiff_t const possiblyNegativeIndex,
+     char const * const dernFuncName);
+ 
+ octaspire_dern_boolean_or_unpushed_error_const_t
+ octaspire_dern_value_as_vector_get_element_at_as_boolean_or_unpushed_error_const(
+     octaspire_dern_value_t const * const self,
+     ptrdiff_t const possiblyNegativeIndex,
+     char const * const dernFuncName);
+ 
  octaspire_dern_number_or_unpushed_error_t
  octaspire_dern_value_as_vector_get_element_at_as_number_or_unpushed_error(
      octaspire_dern_value_t * const self,


@@ 27289,6 27329,12 @@ ptrdiff_t const possiblyNegativeIndex,
      char const * const dernFuncName);
  
+ octaspire_dern_symbol_or_unpushed_error_t
+ octaspire_dern_value_as_vector_get_element_at_as_symbol_or_unpushed_error(
+     octaspire_dern_value_t * const self,
+     ptrdiff_t const possiblyNegativeIndex,
+     char const * const dernFuncName);
+ 
  octaspire_dern_one_of_texts_or_unpushed_error_const_t
  octaspire_dern_value_as_vector_get_element_at_as_one_of_texts_or_unpushed_error_const(
      octaspire_dern_value_t const * const self,


@@ 47660,6 47706,14 @@ return octaspire_string_get_c_string(self->value.symbol);
  }
  
+ bool octaspire_dern_value_as_symbol_set_c_string(
+     octaspire_dern_value_t * const self,
+     char const * const str)
+ {
+     octaspire_helpers_verify_true(self->typeTag == OCTASPIRE_DERN_VALUE_TAG_SYMBOL);
+     return octaspire_string_set_from_c_string(self->value.symbol, str);
+ }
+ 
  bool octaspire_dern_value_is_symbol_and_equal_to_c_string(
      octaspire_dern_value_t const * const self,
      char const * const str)


@@ 48125,6 48179,68 @@ return result;
  }
  
+ octaspire_dern_boolean_or_unpushed_error_t
+ octaspire_dern_value_as_vector_get_element_at_as_boolean_or_unpushed_error(
+     octaspire_dern_value_t * const self,
+     ptrdiff_t const possiblyNegativeIndex,
+     char const * const dernFuncName)
+ {
+     octaspire_dern_boolean_or_unpushed_error_t result = {false, 0, 0};
+ 
+     octaspire_dern_boolean_or_unpushed_error_const_t const constResult =
+         octaspire_dern_value_as_vector_get_element_at_as_boolean_or_unpushed_error_const(
+             self,
+             possiblyNegativeIndex,
+             dernFuncName);
+ 
+     result.boolean       = constResult.boolean;
+     result.value         = (octaspire_dern_value_t*)constResult.value;
+     result.unpushedError = constResult.unpushedError;
+ 
+     return result;
+ }
+ 
+ octaspire_dern_boolean_or_unpushed_error_const_t
+ octaspire_dern_value_as_vector_get_element_at_as_boolean_or_unpushed_error_const(
+     octaspire_dern_value_t const * const self,
+     ptrdiff_t const possiblyNegativeIndex,
+     char const * const dernFuncName)
+ {
+     octaspire_helpers_verify_not_null(self);
+ 
+     octaspire_dern_vm_t * const vm = self->vm;
+ 
+     octaspire_helpers_verify_not_null(vm);
+ 
+     size_t const stackLength = octaspire_dern_vm_get_stack_length(vm);
+     octaspire_dern_boolean_or_unpushed_error_const_t result = {false, 0, 0};
+ 
+     octaspire_dern_value_t const * const arg =
+         octaspire_dern_value_as_vector_get_element_at_const(self, possiblyNegativeIndex);
+ 
+     octaspire_helpers_verify_not_null(arg);
+ 
+     if (!octaspire_dern_value_is_boolean(arg))
+     {
+         result.unpushedError = octaspire_dern_vm_create_new_value_error_format(
+             vm,
+             "Builtin '%s' expects boolean as "
+             "%d. argument. Type '%s' was given.",
+             dernFuncName,
+             possiblyNegativeIndex,
+             octaspire_dern_value_helper_get_type_as_c_string(arg->typeTag));
+ 
+         octaspire_helpers_verify_true(
+             stackLength == octaspire_dern_vm_get_stack_length(vm));
+ 
+         return result;
+     }
+ 
+     result.value   = arg;
+     result.boolean = octaspire_dern_value_as_boolean_get_value(arg);
+     return result;
+ }
+ 
  octaspire_dern_number_or_unpushed_error_t
  octaspire_dern_value_as_vector_get_element_at_as_number_or_unpushed_error(
      octaspire_dern_value_t * const self,


@@ 48186,6 48302,47 @@ return result;
  }
  
+ octaspire_dern_symbol_or_unpushed_error_t
+ octaspire_dern_value_as_vector_get_element_at_as_symbol_or_unpushed_error(
+     octaspire_dern_value_t * const self,
+     ptrdiff_t const possiblyNegativeIndex,
+     char const * const dernFuncName)
+ {
+     octaspire_helpers_verify_not_null(self);
+ 
+     octaspire_dern_vm_t * const vm = self->vm;
+ 
+     octaspire_helpers_verify_not_null(vm);
+ 
+     size_t const stackLength = octaspire_dern_vm_get_stack_length(vm);
+     octaspire_dern_symbol_or_unpushed_error_t result = {0, 0, 0};
+ 
+     octaspire_dern_value_t * const arg =
+         octaspire_dern_value_as_vector_get_element_at(self, possiblyNegativeIndex);
+ 
+     octaspire_helpers_verify_not_null(arg);
+ 
+     if (!octaspire_dern_value_is_symbol(arg))
+     {
+         result.unpushedError = octaspire_dern_vm_create_new_value_error_format(
+             vm,
+             "Builtin '%s' expects symbol as "
+             "%d. argument. Type '%s' was given.",
+             dernFuncName,
+             possiblyNegativeIndex,
+             octaspire_dern_value_helper_get_type_as_c_string(arg->typeTag));
+ 
+         octaspire_helpers_verify_true(
+             stackLength == octaspire_dern_vm_get_stack_length(vm));
+ 
+         return result;
+     }
+ 
+     result.value  = arg;
+     result.symbol = octaspire_dern_value_as_text_get_string(arg);
+     return result;
+ }
+ 
  octaspire_dern_one_of_texts_or_unpushed_error_const_t
  octaspire_dern_value_as_vector_get_element_at_as_one_of_texts_or_unpushed_error_const(
      octaspire_dern_value_t const * const self,

M release/plugins/dern_nuklear.c => release/plugins/dern_nuklear.c +337 -1
@@ 722,6 722,270 @@ return octaspire_dern_vm_create_new_value_boolean(vm, result);
  }
  
+ octaspire_dern_value_t *dern_nuklear_slider_float(
+     octaspire_dern_vm_t * const vm,
+     octaspire_dern_value_t * const arguments,
+     octaspire_dern_value_t * const environment)
+ {
+     OCTASPIRE_HELPERS_UNUSED_PARAMETER(environment);
+ 
+     size_t const stackLength = octaspire_dern_vm_get_stack_length(vm);
+     char   const * const dernFuncName    = "nuklear-slider-float";
+     char   const * const ctxName         = "ctx";
+     size_t const         numExpectedArgs = 5;
+ 
+     size_t const numArgs =
+         octaspire_dern_value_as_vector_get_length(arguments);
+ 
+     if (numArgs != numExpectedArgs)
+     {
+         octaspire_helpers_verify_true(
+             stackLength == octaspire_dern_vm_get_stack_length(vm));
+ 
+         return octaspire_dern_vm_create_new_value_error_format(
+             vm,
+             "Builtin '%s' expects %zu arguments. "
+             "%zu arguments were given.",
+             dernFuncName,
+             numExpectedArgs,
+             numArgs);
+     }
+ 
+     // ctx
+ 
+     octaspire_dern_c_data_or_unpushed_error_t cDataOrError =
+         octaspire_dern_value_as_vector_get_element_at_as_c_data_or_unpushed_error(
+             arguments,
+             0,
+             dernFuncName,
+             ctxName,
+             DERN_NUKLEAR_PLUGIN_NAME);
+ 
+     if (cDataOrError.unpushedError)
+     {
+         octaspire_helpers_verify_true(
+             stackLength == octaspire_dern_vm_get_stack_length(vm));
+ 
+         return cDataOrError.unpushedError;
+     }
+ 
+     struct nk_context * const ctx = cDataOrError.cData;
+ 
+     octaspire_helpers_verify_not_null(ctx);
+ 
+     // min
+ 
+     octaspire_dern_number_or_unpushed_error_const_t numberOrErrorMin =
+         octaspire_dern_value_as_vector_get_element_at_as_number_or_unpushed_error_const(
+             arguments,
+             1,
+             dernFuncName);
+ 
+     if (numberOrErrorMin.unpushedError)
+     {
+         octaspire_helpers_verify_true(
+             stackLength == octaspire_dern_vm_get_stack_length(vm));
+ 
+         return numberOrErrorMin.unpushedError;
+     }
+ 
+     float const minVal = numberOrErrorMin.number;
+ 
+     // value
+ 
+     octaspire_dern_number_or_unpushed_error_t numberOrErrorValue =
+         octaspire_dern_value_as_vector_get_element_at_as_number_or_unpushed_error(
+             arguments,
+             2,
+             dernFuncName);
+ 
+     if (numberOrErrorValue.unpushedError)
+     {
+         octaspire_helpers_verify_true(
+             stackLength == octaspire_dern_vm_get_stack_length(vm));
+ 
+         return numberOrErrorValue.unpushedError;
+     }
+ 
+     float valueVal = numberOrErrorValue.number;
+ 
+     // max
+ 
+     octaspire_dern_number_or_unpushed_error_const_t numberOrErrorMax =
+         octaspire_dern_value_as_vector_get_element_at_as_number_or_unpushed_error_const(
+             arguments,
+             3,
+             dernFuncName);
+ 
+     if (numberOrErrorMax.unpushedError)
+     {
+         octaspire_helpers_verify_true(
+             stackLength == octaspire_dern_vm_get_stack_length(vm));
+ 
+         return numberOrErrorMax.unpushedError;
+     }
+ 
+     float const maxVal = numberOrErrorMax.number;
+ 
+     // step
+ 
+     octaspire_dern_number_or_unpushed_error_const_t numberOrErrorStep =
+         octaspire_dern_value_as_vector_get_element_at_as_number_or_unpushed_error_const(
+             arguments,
+             4,
+             dernFuncName);
+ 
+     if (numberOrErrorStep.unpushedError)
+     {
+         octaspire_helpers_verify_true(
+             stackLength == octaspire_dern_vm_get_stack_length(vm));
+ 
+         return numberOrErrorStep.unpushedError;
+     }
+ 
+     float const stepVal = numberOrErrorStep.number;
+ 
+     // Show the widget.
+ 
+     bool const result =
+         nk_slider_float(ctx, minVal, &valueVal, maxVal, stepVal);
+ 
+     octaspire_dern_value_as_number_set_value(
+         numberOrErrorValue.value,
+         (double)valueVal);
+ 
+     octaspire_helpers_verify_true(
+         stackLength == octaspire_dern_vm_get_stack_length(vm));
+ 
+     return octaspire_dern_vm_create_new_value_boolean(vm, result);
+ }
+ 
+ octaspire_dern_value_t *dern_nuklear_option_label(
+     octaspire_dern_vm_t * const vm,
+     octaspire_dern_value_t * const arguments,
+     octaspire_dern_value_t * const environment)
+ {
+     OCTASPIRE_HELPERS_UNUSED_PARAMETER(environment);
+ 
+     size_t const stackLength = octaspire_dern_vm_get_stack_length(vm);
+     char   const * const dernFuncName    = "nuklear-option-label";
+     char   const * const ctxName         = "ctx";
+     size_t const         numExpectedArgs = 4;
+ 
+     size_t const numArgs =
+         octaspire_dern_value_as_vector_get_length(arguments);
+ 
+     if (numArgs != numExpectedArgs)
+     {
+         octaspire_helpers_verify_true(
+             stackLength == octaspire_dern_vm_get_stack_length(vm));
+ 
+         return octaspire_dern_vm_create_new_value_error_format(
+             vm,
+             "Builtin '%s' expects %zu arguments. "
+             "%zu arguments were given.",
+             dernFuncName,
+             numExpectedArgs,
+             numArgs);
+     }
+ 
+     // ctx
+ 
+     octaspire_dern_c_data_or_unpushed_error_t cDataOrError =
+         octaspire_dern_value_as_vector_get_element_at_as_c_data_or_unpushed_error(
+             arguments,
+             0,
+             dernFuncName,
+             ctxName,
+             DERN_NUKLEAR_PLUGIN_NAME);
+ 
+     if (cDataOrError.unpushedError)
+     {
+         octaspire_helpers_verify_true(
+             stackLength == octaspire_dern_vm_get_stack_length(vm));
+ 
+         return cDataOrError.unpushedError;
+     }
+ 
+     struct nk_context * const ctx = cDataOrError.cData;
+ 
+     octaspire_helpers_verify_not_null(ctx);
+ 
+     // label
+ 
+     octaspire_dern_text_or_unpushed_error_const_t textOrErrorLabel =
+         octaspire_dern_value_as_vector_get_element_at_as_text_or_unpushed_error_const(
+             arguments,
+             1,
+             dernFuncName);
+ 
+     if (textOrErrorLabel.unpushedError)
+     {
+         octaspire_helpers_verify_true(
+             stackLength == octaspire_dern_vm_get_stack_length(vm));
+ 
+         return textOrErrorLabel.unpushedError;
+     }
+ 
+     char const * const labelVal =
+         octaspire_string_get_c_string(textOrErrorLabel.text);
+ 
+     // id
+ 
+     octaspire_dern_text_or_unpushed_error_const_t textOrErrorId =
+         octaspire_dern_value_as_vector_get_element_at_as_text_or_unpushed_error_const(
+             arguments,
+             2,
+             dernFuncName);
+ 
+     if (textOrErrorId.unpushedError)
+     {
+         octaspire_helpers_verify_true(
+             stackLength == octaspire_dern_vm_get_stack_length(vm));
+ 
+         return textOrErrorId.unpushedError;
+     }
+ 
+     // active-id
+ 
+     octaspire_dern_symbol_or_unpushed_error_t symbolOrErrorActiveId =
+         octaspire_dern_value_as_vector_get_element_at_as_symbol_or_unpushed_error(
+             arguments,
+             3,
+             dernFuncName);
+ 
+     if (symbolOrErrorActiveId.unpushedError)
+     {
+         octaspire_helpers_verify_true(
+             stackLength == octaspire_dern_vm_get_stack_length(vm));
+ 
+         return symbolOrErrorActiveId.unpushedError;
+     }
+ 
+     // Show the widget.
+ 
+     bool const result = nk_option_label(
+         ctx,
+         labelVal,
+         octaspire_dern_value_as_text_is_equal_to_c_string(
+             textOrErrorId.value,
+             (octaspire_dern_value_as_text_get_c_string(
+                 symbolOrErrorActiveId.value))));
+ 
+     if (result)
+     {
+         octaspire_helpers_verify_true(
+             octaspire_dern_value_as_symbol_set_c_string(
+                 symbolOrErrorActiveId.value,
+                 octaspire_string_get_c_string(textOrErrorId.text)));
+     }
+ 
+     octaspire_helpers_verify_true(
+         stackLength == octaspire_dern_vm_get_stack_length(vm));
+ 
+     return octaspire_dern_vm_create_new_value_boolean(vm, result);
+ }
+ 
  octaspire_dern_value_t *dern_nuklear_progress(
      octaspire_dern_vm_t * const vm,
      octaspire_dern_value_t * const arguments,


@@ 1749,7 2013,79 @@ "\t(or error if something went wrong).\n"
              "\n"
              "SEE ALSO\n"
-             "\tnuklear-begin\n",
+             "\tnuklear-begin\n"
+             "\tnuklear-slider-float\n",
+             false,
+             targetEnv))
+     {
+         return false;
+     }
+ 
+     if (!octaspire_dern_vm_create_and_register_new_builtin(
+             vm,
+             "nuklear-slider-float",
+             dern_nuklear_slider_float,
+             5,
+             "NAME\n"
+             "\tnuklear-slider-float\n"
+             "\n"
+             "SYNOPSIS\n"
+             "\t(require 'dern_nuklear)\n"
+             "\n"
+             "\t(nuklear-slider-float ctx min val max step) -> true/false or error\n"
+             "\n"
+             "DESCRIPTION\n"
+             "\tDisplay a floating point slider.\n"
+             "\n"
+             "ARGUMENTS\n"
+             "\tctx           nuklear context.\n"
+             "\tmin           smallest possible value.\n"
+             "\tval           selected value.\n"
+             "\tmax           largest possible value.\n"
+             "\tstep          amount of change per step.\n"
+             "\n"
+             "RETURN VALUE\n"
+             "\ttrue if slider value was changed, false otherwise "
+             "\t(or error if something went wrong).\n"
+             "\n"
+             "SEE ALSO\n"
+             "\tnuklear-begin\n"
+             "\tnuklear-slider-int\n",
+             false,
+             targetEnv))
+     {
+         return false;
+     }
+ 
+     if (!octaspire_dern_vm_create_and_register_new_builtin(
+             vm,
+             "nuklear-option-label",
+             dern_nuklear_option_label,
+             4,
+             "NAME\n"
+             "\tnuklear-option-label\n"
+             "\n"
+             "SYNOPSIS\n"
+             "\t(require 'dern_nuklear)\n"
+             "\n"
+             "\t(nuklear-option-label ctx label active) -> boolean or error\n"
+             "\n"
+             "DESCRIPTION\n"
+             "\tDisplay a radio button\n"
+             "\n"
+             "ARGUMENTS\n"
+             "\tctx           nuklear context.\n"
+             "\tlabel         text label for the option.\n"
+             "\tid            symbol or string identifying this option.\n"
+             "\tactive-id     symbol identifying currently active option.\n"
+             "\n"
+             "RETURN VALUE\n"
+             "\ttrue if this option was selected, false otherwise "
+             "\t(or error if something went wrong).\n"
+             "\n"
+             "SEE ALSO\n"
+             "\tnuklear-begin\n"
+             "\tnuklear-checkbox-label\n",
              false,
              targetEnv))
      {