| 78 | } |
| 79 | |
| 80 | void ValToGUI(VM &vm, Value *v, const TypeInfo &ti, string_view label, bool expanded) { |
| 81 | auto l = null_terminated(label); |
| 82 | auto flags = expanded ? ImGuiTreeNodeFlags_DefaultOpen : 0; |
| 83 | switch (ti.t) { |
| 84 | case V_INT: { |
| 85 | if (ti.enumidx == 0) { |
| 86 | assert(vm.EnumName(ti.enumidx) == "bool"); |
| 87 | bool b = v->True(); |
| 88 | if (ImGui::Checkbox(l, &b)) *v = b; |
| 89 | } else if (ti.enumidx >= 0) { |
| 90 | int val = v->intval(); |
| 91 | int sel = 0; |
| 92 | auto &vals = *vm.bcf->enums()->Get(ti.enumidx)->vals(); |
| 93 | vector<const char *> items(vals.size()); |
| 94 | int i = 0; |
| 95 | for (auto vi : vals) { |
| 96 | items[i] = vi->name()->c_str(); |
| 97 | if (val == vi->val()) sel = i; |
| 98 | i++; |
| 99 | } |
| 100 | ImGui::Combo(l, &sel, items.data(), (int)items.size()); |
| 101 | *v = vals[sel]->val(); |
| 102 | } else { |
| 103 | int i = v->intval(); // FIXME: what if int64_t? |
| 104 | if (ImGui::InputInt(l, &i)) *v = i; |
| 105 | } |
| 106 | return; |
| 107 | } |
| 108 | case V_FLOAT: { |
| 109 | float f = v->fltval(); // FIXME: what if double? |
| 110 | if (ImGui::InputFloat(l, &f)) *v = f; |
| 111 | return; |
| 112 | } |
| 113 | case V_VECTOR: |
| 114 | if (!v->True()) break; |
| 115 | if (ImGui::TreeNodeEx(*l ? l : "[]", flags)) { |
| 116 | auto &sti = vm.GetTypeInfo(ti.subt); |
| 117 | auto vec = v->vval(); |
| 118 | for (intp i = 0; i < vec->len; i++) { |
| 119 | ValToGUI(vm, vec->AtSt(i), sti, to_string(i), false); |
| 120 | } |
| 121 | ImGui::TreePop(); |
| 122 | } |
| 123 | return; |
| 124 | case V_CLASS: |
| 125 | if (!v->True()) break; |
| 126 | v = v->oval()->Elems(); // To iterate it like a struct. |
| 127 | case V_STRUCT_R: |
| 128 | case V_STRUCT_S: { |
| 129 | auto st = vm.bcf->udts()->Get(ti.structidx); |
| 130 | // Special case for numeric structs & colors. |
| 131 | if (ti.len >= 2 && ti.len <= 4) { |
| 132 | for (int i = 1; i < ti.len; i++) |
| 133 | if (ti.elemtypes[i] != ti.elemtypes[0]) goto generic; |
| 134 | if (ti.elemtypes[0] == TYPE_ELEM_INT) { |
| 135 | auto nums = ValueToI<4>(v, ti.len); |
| 136 | if (ImGui::InputScalarN( |
| 137 | l, sizeof(intp) == sizeof(int) ? ImGuiDataType_S32 : ImGuiDataType_S64, |
no test coverage detected