newcat / baklavajs

Graph / node editor in the browser using VueJS
http://baklava.tech
MIT License
1.59k stars 116 forks source link

Suggestion: inline input/output #25

Open Stumblinbear opened 5 years ago

Stumblinbear commented 5 years ago

Not exactly an issue, but a feature request. I'm using this library in an attempt to build a sort of visual programmer for my quest system, however the lack of a way to make a nice looking "execution input/output" is a bit annoying.

Current: image

Suggestion: image

I'm hoping this is something that you'll consider adding, as this is the only library that I can get to reliably work within VueJS. Thanks in advance! ^^

If not, if you could perhaps point me in the right direction to the location in which I can add the feature myself, that would be great!

Also, if you could also consider having an option to move the options below the inputs and outputs, that would also be great!

newcat commented 5 years ago

I'm sorry, I probably won't add this exact feature, since I think it is pretty special for your use-case. However, I'd suggest styling the node interfaces for the special inputs/outputs (which is probably what you want to do anyway, considering your PR ;) ). Additionally, you can also style the connections between those interfaces specially, by hooking into the renderConnection hook of the ViewPlugin, checking whether the connection is between two of the special interfaces and if so, applying custom styles or adding a custom CSS class. Let me know if you have questions about the implementation.

Concerning the option to change the order of outputs/options/inputs: Good idea, I will probably move them into a CSS Flexbox container, so you can change the order using Flexbox's order property.

Stumblinbear commented 5 years ago

I went ahead and edited the plugin locally, and moved the inputs over the outputs, then applied the following styles:

.node-interface.--input {
    float: left;
    max-width: 60%;

    clear: both;
}

.node div[node] {
    clear: both;
}

Doing so resulted in this:

image

Which, in my opinion, looks better than making each input and each output take up a whole line.

Also, since we're technically on the topic of styling, since you apply the width in a style tag, I am unable to style them myself, and there's no option to change the width of a node. Is that something you could consider changing, as well?

newcat commented 5 years ago

Fully agree; for your use-case it looks much better. Generally though I expect that input interfaces display an option to change their value when they are not connected. This would probably lead to a bad user experience when using a two-column layout since the controls would get really small. But I will add a property to the node class to allow using a two-column layout.

The reason for the width property being set in the style tag is that the nodes are already prepared for being resizable. Therefore, the width attribute needs to be set dynamically. When I implement resizing of nodes, this value will be exposed though, so you can set the width programatically.

Stumblinbear commented 5 years ago

Aha, width being where it is makes more sense, with resizing of nodes. Sounds good. I would like to suggest fixed-sized node types, in that case.

Stumblinbear commented 5 years ago

Not sure if it's it's something you'd consider (I could probably add it if necessary), but some of the styles I wish to apply to special nodes cannot be done, as they include removing the title bar, however that causes the node to be immovable.

image

I'm doing something like this for event handlers and such:

image

While this works fine, if it was possible to make the entire node draggable from anywhere (so that the title can be removed), that would make it further customizable in such a way.

Better yet, make it possible to change what component is used for nodes entirely, and just give users the components necessary (in the vue renderer) to add their connection ports, options, etc anywhere. While it's likely currently possible, it doesn't feel supported. Though that's probably more work than it's worth.

Stumblinbear commented 5 years ago

If you do happen to implement vertically split layouts, and this isn't required but it would be very nice, perhaps implement a way for input types to define themselves as taking up the whole width.

For instance: if I have an input that uses a text area option, it should take up the whole width and push outputs on the same level downwards, however if it's only a checkbox, it should only take up half.

However, I believe implementing a customizable node component system would be easier than adding every possibility into the base component.

(I really hope im not being annoying)

newcat commented 5 years ago

I have added a possibility to use custom components for rendering everything (nodes, connections, context menu, sidebar, ...). No documentation on it yet, but you can have a look in the following playground files:

With that change, you can implement whatever you want, also do like comment nodes and stuff :) you just have to do it ;)

I am going to leave this issue open though, as I am planning to implement the two column layout anyway

Stumblinbear commented 5 years ago

That'll work for now, however it may be a good idea to add a registry in the default vue renderer for adding custom components

Stumblinbear commented 5 years ago

While I believe this could be massively improved (I just hacked it together), it essentially puts each input/output in a row, then if only one input or one output exists, it takes up the whole row.

image

https://gist.github.com/Stumblinbear/14e2d634e2974c46bb2b208c13cc8ede

It looks ugly, but it works. Note: I do like the vue component class library, but I wasn't using it before I started this project, so I didn't add it for this.