Skip to content

Commit

Permalink
GDScript bindings for clipper and table sort
Browse files Browse the repository at this point in the history
  • Loading branch information
pkdawson committed Aug 2, 2024
1 parent edde6e8 commit f2dc3fc
Show file tree
Hide file tree
Showing 3 changed files with 92 additions and 27 deletions.
49 changes: 41 additions & 8 deletions doc/examples/GdsDemo/demo.gd
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ var anim_counter := 0
var wc_topmost: ImGuiWindowClassPtr
var ms_items := items
var ms_selection := []
var table_items := []

func _ready():
var io := ImGui.GetIO()
Expand All @@ -21,6 +22,9 @@ func _ready():
style.Colors[ImGui.Col_PlotHistogram] = Color.REBECCA_PURPLE
style.Colors[ImGui.Col_PlotHistogramHovered] = Color.SLATE_BLUE

for i in range(items.size()):
table_items.append([i, items[i]])

func _process(_delta: float) -> void:
ImGui.ShowDemoWindow()

Expand All @@ -47,14 +51,43 @@ func _process(_delta: float) -> void:
ImGui.Text("choice = %s" % items[current_item[0]])

ImGui.SeparatorText("Multi-Select")
var ms_io := ImGui.BeginMultiSelectEx(ImGui.MultiSelectFlags_None, ms_items.size(), ms_selection.size())
apply_selection_requests(ms_io)
for i in range(items.size()):
var is_selected := ms_selection.has(i)
ImGui.SetNextItemSelectionUserData(i)
ImGui.SelectableEx(ms_items[i], is_selected)
ms_io = ImGui.EndMultiSelect()
apply_selection_requests(ms_io)
if ImGui.BeginChild("MSItems", Vector2(0,0), ImGui.ChildFlags_FrameStyle):
var flags := ImGui.MultiSelectFlags_ClearOnEscape | ImGui.MultiSelectFlags_BoxSelect1d
var ms_io := ImGui.BeginMultiSelectEx(flags, ms_selection.size(), ms_items.size())
apply_selection_requests(ms_io)
for i in range(items.size()):
var is_selected := ms_selection.has(i)
ImGui.SetNextItemSelectionUserData(i)
ImGui.SelectableEx(ms_items[i], is_selected)
ms_io = ImGui.EndMultiSelect()
apply_selection_requests(ms_io)
ImGui.EndChild()
ImGui.End()

ImGui.Begin("Sortable Table")
if ImGui.BeginTable("sortable_table", 2, ImGui.TableFlags_Sortable):
ImGui.TableSetupColumn("ID", ImGui.TableColumnFlags_DefaultSort)
ImGui.TableSetupColumn("Name")
ImGui.TableSetupScrollFreeze(0, 1)
ImGui.TableHeadersRow()

var sort_specs := ImGui.TableGetSortSpecs()
if sort_specs.SpecsDirty:
for spec: ImGuiTableColumnSortSpecsPtr in sort_specs.Specs:
var col := spec.ColumnIndex
if spec.SortDirection == ImGui.SortDirection_Ascending:
table_items.sort_custom(func(lhs, rhs): return lhs[col] < rhs[col])
else:
table_items.sort_custom(func(lhs, rhs): return lhs[col] > rhs[col])
sort_specs.SpecsDirty = false

for i in range(table_items.size()):
ImGui.TableNextRow()
ImGui.TableNextColumn()
ImGui.Text("%d" % table_items[i][0])
ImGui.TableNextColumn()
ImGui.Text(table_items[i][1])
ImGui.EndTable()
ImGui.End()

ImGui.SetNextWindowClass(wc_topmost)
Expand Down
55 changes: 36 additions & 19 deletions gdext/scripts/gds_bindings.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
"ImFont*": "int64_t",
"ImGuiID": "uint32_t",
"ImGuiIO*": "Ref<ImGuiIOPtr>",
"ImGuiListClipper*": "Ref<ImGuiListClipperPtr>",
"ImGuiSelectionUserData": "int64_t",
"ImGuiStyle*": "Ref<ImGuiStylePtr>",
"ImS16": "int16_t",
Expand Down Expand Up @@ -81,16 +82,17 @@
"ImGuiIO",
"ImGuiStyle",
"ImDrawList",
# "ImGuiTableColumnSortSpecs",
# "ImGuiTableSortSpecs",
"ImGuiTableColumnSortSpecs",
"ImGuiTableSortSpecs",
# "ImGuiTextFilter",
"ImGuiWindowClass",
"ImGuiMultiSelectIO",
"ImGuiSelectionRequest",
# "ImGuiSelectionBasicStorage", # not useful
"ImGuiListClipper",
)

constructible_structs = ("ImGuiWindowClass",)
constructible_structs = ("ImGuiWindowClass", "ImGuiListClipper")

exclude_props = (
"MouseDown",
Expand Down Expand Up @@ -219,8 +221,8 @@ def __init__(self, j):
dv = dv.replace("NULL", f"{self.gdtype}()")
self.dv = dv
self.is_struct = self.gdtype and self.gdtype.endswith("Ptr>")
# if self.gdtype is None:
# print(f"no type for param {self.orig_type} {self.name}")
if self.gdtype is None:
print(f"no type for param {self.orig_type} {self.name}")

def gen_decl(self):
rv = f"{self.gdtype} {self.name}"
Expand Down Expand Up @@ -296,13 +298,16 @@ def __init__(self, j):
and not self.orig_name.endswith("V")
and not self.orig_name.startswith("ImGuiIO_")
and not self.orig_name.startswith("ImFont_")
# double underscore = internal
and not self.orig_name.startswith("ImDrawList__")
)

if self.valid:
for p in self.params:
if p.gdtype is None:
self.valid = False

if not self.valid and not self.orig_name in exclude_funcs:
if not self.valid and not self.orig_name in exclude_funcs and not self.obsolete:
print(f"skip function {self.orig_name}")

def gen_decl(self):
Expand Down Expand Up @@ -377,6 +382,12 @@ def __init__(self, j, name, struct_name):
self.gdtype = Property.array_types[self.array_type]
if self.gdtype == "String":
self.gdtype = None
try:
self.is_const = (
"const" in j["type"]["description"]["inner_type"]["storage_classes"]
)
except:
self.is_const = False
self.valid = self.gdtype is not None

if not self.valid:
Expand Down Expand Up @@ -406,25 +417,31 @@ def gen_def(self):
fcall = f"static_cast<{self.gdtype}>({fcall})"
elif self.orig_type.startswith("ImVector_"):
fcall = f"FromImVector({fcall})"
elif self.orig_type == "const ImGuiTableColumnSortSpecs*":
fcall = f"SpecsToArray(ptr)"

rv += f"if (ptr) [[likely]] return {fcall}; else return {dv};\\\n"
rv += "} \\\n"

# setter
rv += f"void {self.struct_name}::_Set{self.name}({self.gdtype} x) {{ \\\n"
x = "x"
if self.orig_type == "ImVec2":
x = "{x.x, x.y}"
elif self.orig_type in ["ImFont*"]:
x = "(ImFont*)x"
elif self.gdtype in non_bitfield_enums:
x = f"static_cast<{self.orig_type}>(x)"
elif self.orig_type.startswith("ImVector_"):
x = "ToImVector(x)"

if self.gdtype == "PackedColorArray":
rv += f"FromPackedColorArray(x, ptr->{self.name}); \\\n"
if self.is_const:
rv += f'ERR_FAIL_MSG("{self.name} is const");'
else:
rv += f"ptr->{self.name} = {x}; \\\n"
x = "x"
if self.orig_type == "ImVec2":
x = "{x.x, x.y}"
elif self.orig_type in ["ImFont*"]:
x = "(ImFont*)x"
elif self.gdtype in non_bitfield_enums:
x = f"static_cast<{self.orig_type}>(x)"
elif self.orig_type.startswith("ImVector_"):
x = "ToImVector(x)"

if self.gdtype == "PackedColorArray":
rv += f"FromPackedColorArray(x, ptr->{self.name}); \\\n"
else:
rv += f"ptr->{self.name} = {x}; \\\n"
rv += "} \\\n"
return rv

Expand Down
15 changes: 15 additions & 0 deletions gdext/src/ImGuiAPI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,21 @@ inline ImVector_ImGuiSelectionRequest ToImVector(const Array& in)
return {};
}

inline Array SpecsToArray(const ImGuiTableSortSpecs* p)
{
ERR_FAIL_COND_V(!p, {});

Array rv;
for (int i = 0; i < p->SpecsCount; ++i)
{
Ref<ImGui::Godot::ImGuiTableColumnSortSpecsPtr> col;
col.instantiate();
col->_SetPtr(const_cast<ImGuiTableColumnSortSpecs*>(&p->Specs[i]));
rv.append(col);
}
return rv;
}

const char* sn_to_cstr(const StringName& sn)
{
static std::unordered_map<StringName, std::string> stringname_cache;
Expand Down

0 comments on commit f2dc3fc

Please sign in to comment.