Skip to content

Commit

Permalink
make combo and selectable data bindings more useful
Browse files Browse the repository at this point in the history
  • Loading branch information
tpecholt committed Jul 18, 2024
1 parent 2370e35 commit eecb15f
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 28 deletions.
37 changes: 31 additions & 6 deletions src/imrad.h
Original file line number Diff line number Diff line change
Expand Up @@ -304,13 +304,38 @@ inline void HashCombine(ImU32& hash, T data)
hash = ImHashData(&data, sizeof(data), hash);
}

inline bool Combo(const char* label, int* curr, const std::vector<std::string>& items, int maxh = -1)
inline bool Combo(const char* label, std::string* curr, const std::vector<std::string>& items, int flags = 0)
{
//todo: BeginCombo/Selectable
std::vector<const char*> citems(items.size());
for (size_t i = 0; i < items.size(); ++i)
citems[i] = items[i].c_str();
return ImGui::Combo(label, curr, citems.data(), (int)citems.size(), maxh);
bool changed = false;
if (ImGui::BeginCombo(label, curr->c_str(), flags))
{
for (const auto& item : items) {
if (ImGui::Selectable(item.c_str(), item == *curr)) {
*curr = item;
changed = true;
}
}
ImGui::EndCombo();
}
return changed;
}

inline bool Combo(const char* label, std::string* curr, const char* items, int flags = 0)
{
bool changed = false;
if (ImGui::BeginCombo(label, curr->c_str(), flags))
{
const char* p = items;
while (*p) {
if (ImGui::Selectable(p, !curr->compare(p))) {
*curr = p;
changed = true;
}
p += strlen(p) + 1;
}
ImGui::EndCombo();
}
return changed;
}

inline void Dummy(const ImVec2& size)
Expand Down
50 changes: 29 additions & 21 deletions src/node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3360,7 +3360,8 @@ void Selectable::DoDraw(UIContext& ctx)
ImVec2 size;
size.x = size_x.eval_px(ImGuiAxis_X, ctx);
size.y = size_y.eval_px(ImGuiAxis_Y, ctx);
ImRad::Selectable(DRAW_STR(label), false, flags, size);
bool selected = fieldName.empty()? value.eval(ctx) : fieldName.eval(ctx);
ImRad::Selectable(DRAW_STR(label), selected, flags, size);

if (readOnly)
ImGui::PopItemFlag();
Expand Down Expand Up @@ -3416,10 +3417,10 @@ void Selectable::DoExport(std::ostream& os, UIContext& ctx)
os << "if (";

os << "ImRad::Selectable(" << label.to_arg() << ", ";
if (fieldName.empty())
os << "false";
else
if (!fieldName.empty())
os << "&" << fieldName.to_arg();
else
os << value.to_arg();

os << ", " << flags.to_arg() << ", { "
<< size_x.to_arg(ctx.unit, ctx.stretchSizeExpr[0]) << ", "
Expand Down Expand Up @@ -3454,8 +3455,12 @@ void Selectable::DoImport(const cpp::stmt_iterator& sit, UIContext& ctx)
if (label.value() == cpp::INVALID_TEXT)
ctx.errors.push_back("Selectable: unable to parse label");
}
if (sit->params.size() >= 2 && !sit->params[1].compare(0, 1, "&"))
fieldName.set_from_arg(sit->params[1].substr(1));
if (sit->params.size() >= 2) {
if (!sit->params[1].compare(0, 1, "&"))
fieldName.set_from_arg(sit->params[1].substr(1));
else
value.set_from_arg(sit->params[1]);
}
if (sit->params.size() >= 3)
flags.set_from_arg(sit->params[2]);
if (sit->params.size() >= 4) {
Expand Down Expand Up @@ -3507,6 +3512,7 @@ Selectable::Properties()
{ "horizAlignment", &horizAlignment },
{ "vertAlignment", &vertAlignment },
{ "alignToFrame", &alignToFrame },
{ "selectable.value", &value },
{ "selectable.fieldName", &fieldName },
{ "size_x", &size_x },
{ "size_y", &size_y }
Expand Down Expand Up @@ -3591,21 +3597,31 @@ bool Selectable::PropertyUI(int i, UIContext& ctx)
changed = ImGui::Checkbox("##alignToFrame", alignToFrame.access());
break;
case 8:
ImGui::Text("value");
ImGui::TableNextColumn();
ImGui::BeginDisabled(!fieldName.empty());
ImGui::SetNextItemWidth(-ImGui::GetFrameHeight());
changed = InputBindable("##value", &value, false, ctx);
ImGui::SameLine(0, 0);
changed |= BindingButton("value", &value, ctx);
ImGui::EndDisabled();
break;
case 9:
ImGui::TableSetBgColor(ImGuiTableBgTarget_RowBg0, FIELD_NAME_CLR);
ImGui::Text("fieldName");
ImGui::TableNextColumn();
ImGui::SetNextItemWidth(-ImGui::GetFrameHeight());
changed = InputFieldRef("##fieldName", &fieldName, true, ctx);
break;
case 9:
case 10:
ImGui::Text("size_x");
ImGui::TableNextColumn();
ImGui::SetNextItemWidth(-ImGui::GetFrameHeight());
changed = InputBindable("##size_x", &size_x, {}, InputBindable_StretchButton, ctx);
ImGui::SameLine(0, 0);
changed |= BindingButton("size_x", &size_x, ctx);
break;
case 10:
case 11:
ImGui::Text("size_y");
ImGui::TableNextColumn();
ImGui::SetNextItemWidth(-ImGui::GetFrameHeight());
Expand All @@ -3614,7 +3630,7 @@ bool Selectable::PropertyUI(int i, UIContext& ctx)
changed |= BindingButton("size_y", &size_y, ctx);
break;
default:
return Widget::PropertyUI(i - 11, ctx);
return Widget::PropertyUI(i - 12, ctx);
}
return changed;
}
Expand Down Expand Up @@ -5055,7 +5071,7 @@ std::unique_ptr<Widget> Combo::Clone(UIContext& ctx)
{
auto sel = std::make_unique<Combo>(*this);
if (!fieldName.empty() && ctx.createVars) {
sel->fieldName.set_from_arg(ctx.codeGen->CreateVar("int", "-1", CppGen::Var::Interface));
sel->fieldName.set_from_arg(ctx.codeGen->CreateVar("std::string", "", CppGen::Var::Interface));
}
return sel;
}
Expand Down Expand Up @@ -5093,17 +5109,9 @@ void Combo::DoExport(std::ostream& os, UIContext& ctx)
std::string id = label.to_arg();
if (label.empty())
id = std::string("\"##") + fieldName.c_str() + "\"";
auto vars = items.used_variables();
if (vars.empty())
{
os << "ImGui::Combo(" << id << ", &"
<< fieldName.to_arg() << ", " << items.to_arg() << ")";
}
else
{
os << "ImRad::Combo(" << id << ", &"
<< fieldName.to_arg() << ", " << items.to_arg() << ")";
}

os << "ImRad::Combo(" << id << ", &" << fieldName.to_arg()
<< ", " << items.to_arg() << ")";

if (!onChange.empty()) {
os << ")\n";
Expand Down
3 changes: 2 additions & 1 deletion src/node.h
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,7 @@ struct Selectable : Widget
direct_val<bool> alignToFrame = false;
direct_val<bool> readOnly = false;
field_ref<bool> fieldName;
bindable<bool> value;
event<> onChange;

Selectable(UIContext& ctx);
Expand Down Expand Up @@ -285,7 +286,7 @@ struct Input : Widget
struct Combo : Widget
{
direct_val<std::string> label = "";
field_ref<int> fieldName;
field_ref<std::string> fieldName;
bindable<std::vector<std::string>> items;
event<> onChange;

Expand Down

0 comments on commit eecb15f

Please sign in to comment.