-
Notifications
You must be signed in to change notification settings - Fork 34
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
NodeGraphEditor FieldEnum with dynamic options #15
Comments
Well, as far as I can remember there should be a user pointer you can pass to the function. So basically, based on it you could change some objects at execution time (or you can add a single callback to multiple combos for example). A potential difficulty is that the number of items must be specified in addFieldEnum() and not in the callback... Well, you can try and see if the user pointer is good for you and then report back. |
On a closer look, I've just seen that addFieldEnum() mimics the main ImGui::Combo() method. // addFieldEnum(...) now has all the 3 overloads ImGui::Combo(...) has.
// addFieldEnum(...) [1] (item_count + external callback)
node->fields.addFieldEnum(&node->enumIndex,3,&GetTextFromEnumIndex,"Fruit","Choose your favourite");
// addFieldEnum(...) [2] (items_count + item_names)
//static const char* FruitNames[3] = {"APPLE","LEMON","ORANGE"};
//node->fields.addFieldEnum(&node->enumIndex,3,FruitNames,"Fruit","Choose your favourite");
// addFieldEnum(...) [3] (zero_separated_item_names)
//node->fields.addFieldEnum(&node->enumIndex,"APPLE\0LEMON\0ORANGE\0\0","Fruit","Choose your favourite"); If this is OK for you I can add them in next commit. [Edit:] committed. |
@rff255 Have you solved it? What I cannot understand is if the change of your objects at execution time must be valid for all the instances of your node class, or only for some instances of the same node class.
class ComplexNode : public Node {
...
protected:
static FieldInfo* pEnumFieldInfo; // new
....
public:
static ThisClass* Create(const ImVec2& pos) {
...
// 3) init fields ( this uses the node->fields variable; otherwise we should have overridden other virtual methods (to render and serialize) )
node->fields.reserve(3); // MANDATORY to avoid reallocation of the fields vector that caould invalidate pEnumFieldInfo
// 3) init fields ( this uses the node->fields variable; otherwise we should have overridden other virtual methods (to render and serialize) )
node->fields.addField(&node->Value[0],3,"Angles","Three floats that are stored in radiant units internally",2,0,360,NULL,true);
node->fields.addFieldColor(&node->Color.x,true,"Color","color with alpha");
// addFieldEnum(...) (item_count + external callback)
pEnumFieldInfo = &node->fields.addFieldEnum(&node->enumIndex,3,&GetTextFromEnumIndex,"Fruit","Choose your favourite");
...
}
....
};
FieldInfo* ComplexNode::pEnumFieldInfo = NULL; Once you have pEnumFieldInfo, you can add to the class a public static method to change at runtime all the internal properties of the FieldInfo, that in your case are: // used only for FT_ENUM (internally it uses FT_INT, pdata must point to an int):
int numEnumElements;
typedef bool (*TextFromEnumDelegate)(void*, int, const char**); // userData is the first param
TextFromEnumDelegate textFromEnumFunctionPointer; // used only when type==FT_ENUM, otherwise set it to NULL. The method is used to convert an int to a char*.
void* userData; // passed to textFromEnumFunctionPointer when type==FT_ENUM (useful if you want to share the same TextFromEnumDelegate for multiple enums). Otherwise set it to NULL or use it as you like.
// should return "true" if the node has been edited and
// its values modified (to fire "edited callbacks")
virtual bool Node::render(float nodeWidth)
{
bool nodeEdited = false;
for (int i=0,isz=fields.size();i<isz;i++) {
FieldInfo& f = fields[i];
nodeEdited|=f.render(nodeWidth);
}
return nodeEdited;
}
Hope I've clarified a lot of things correctly... |
@Flix01 |
I'm confused:
Considering true the two questions: to use the new overload addFieldEnum, I should change the ComplexNode::Create() function to receive arguments relative to my list of objects dinamically, right? and as consequence, I must change MyNodeFactory() to pass those extra arguments, right? and so on with all the sequence of calls, including the addNode() functions, until the NodeGraphEditor() constructor? or there is another shorter way? Again, thanks for your attention, I hope I can include your work to enrich my(maybe ours) application :D |
So I think you're heading towards a wrong direction... |
I've added a new commit with another addFieldEnum() overloaded method that takes a callback that returns the number of item.. I've made a gist that explains very basically how to do it (https://gist.github.com/Flix01/a7873b73f0ffb00c87260e5bf13a18d4). However there is a problem I could not solve: Please see the code for a better understanding of this (BIG) problem. |
…ds. Solves #15. See: https://gist.github.com/Flix01/a7873b73f0ffb00c87260e5bf13a18d4 addons/imguihelper/imguihelper.h/cpp: Added an overloaded ImGuiHelper::Serializer::saveTextLines(...) to ease serialization of string lines vectors
OK. I solved the issue with a new commit that adds a Node Graph Editor reference to each Node. |
Wow, thanks @Flix01 ! Again, thanks for your attention to this. |
Hello!
I'm planning use your NodeGraphEditor in my graduation work as a part of a cellular automata GUI I'm developing. First of all, thanks for open your code, it's a nice and versatile 'widget'.
I'm still a noob in imgui, so maybe I haven't see the solution to this, but seems like the function (passed in addFieldEnum()) that returns the name of a selected index, must be static (as your APPLE/ LEMON/ ORANGE example). Once my application allows the user to define in execution time some objects that will appear as options in a FieldEnum, I can't define it statically.
So, there is a way to do this? Would be great if I can use your NodeGraphEditor on my work :)
The text was updated successfully, but these errors were encountered: