-
Notifications
You must be signed in to change notification settings - Fork 443
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
Inspector, Multi-Selection, Undo and more #176
Conversation
- Implemented an inspector_gui decorator, like the node_gui one for registering an inspector. - Defined an InspectorWidget for managing the inspection - Defined an InspectorGUI (might be renamed) which any user can implement to have an inspector gui appear in the Inspector Section. This provides full control to the user.
- Added a selection mode that indicates how the selection works and how it handles the scenes' select event - Implemented a selection undo mechanism using the selection mode. Whatever has been selected can be undone (should be useful for inspectors). When drag-selection, the selection is over when mouse is released. - Added a on_move virtual function on GUIBase. This is called on move redoes, undoes. Currently it helps with recomputing the ConnectionItem when a move is undone. - Made sure that pressing delete doesn't register unnecessary delete undoes. - Removed self.remove_node_item and self.add_node_item forgotten functions. - On drop event, made sure to setFocus again, otherwise keyPressed didn't work.
- Added a basic class for providing additional information - Renamed InspectorGUI to BaseNodeInspector
Added a Delegate_Command for creating undo, redo functionality dynamically.
-WIP
- Fixed the bugs in different flow themes
- Animating the scale when a node is updated - Added a node item update when a connection is added or removed,(previously the state didn't refresh) - Unloading the flow uis at exit to avoid an exception with selection undo / redo
- Added a PrettyName interface in GUIBase.py for easier name display - NodeItem, ConnectionItem, DrawingObject implement the interface - All flow commands are now given a name and displayed in the undo history #TODO Still need a way to clear memory if undo commands are deleted. But this is hard to do currently
- Massive improvement on performance for any flow theme. Used reset_cache content to ensure that the rect was updated. That way, we're drawing only on a small portion - By resetting, any artifact problems with the proxy widgets in the scene seem to have been solved
+ Fix for Industrial Theme which had a bug
- Remove the starting of ConnectionAnimation on click
Awesome, this has a lot of great stuff! The undo history tab has been on my TODO for like two years and I never went and actually did it. Is it possible for you to pull out all the inspector stuff from this PR (via git rebase, revert, cherry-pick and whatnot)? I would like to do that separately. Everything else is fixing stuff and improving Flow UI as far as I can see. I have a few thoughts on the rest. Since there's a lot, I can offer to have a zoom/teams call instead of discussing everything here, which might save a lot of time. But if you prefer to keep it here, that's fine for me. |
Added defer source code loading in StartUpDialog for leon-thomm#175
The base inspector stuff is only a single file addition which I think is already quite intuitive and ready to use. The only other thing it affects is
We could arrange a call. I'm assuming you want to talk more about the RandNode traits example and less about the basic inspector implementation which is completely agnostic. Unless I got that completely wrong and you want to talk about everything else except the inspector. |
Can't tell how a pyside2 reference creeped into here.
I find some things confusing and the API is not yet well integrated with the rest, so I would request changes which might delay things. But if you're waiting for all features here to be merged anyway we can keep it here. Conceptually, I think your approach is fine.
that would be good
It's kind of the opposite ;) some notes on the rest and discussing the inspector stuff. But can share some thoughts on node properties as well. |
- Refactored the way packages are built. It's more efficient, more readable and allows for arbitrary nesting.
These last commits have:
The nodes widget below the package widget should also be refactored to use a QListView, which allows for far more efficient searching internally through regex (not for this PR) |
Btw. do you know why we cannot hide widgets in sliders anymore since the docking additions? I can put this on the TODO but it's bothering me quite a bit so I'd rather fix this sooner than later. I want to be able to drag a splitter handle all the way to one end so at the end it fully hides the content in that direction. |
I think it has to do with the fact that it's not a splitter anymore. Docks can be closed by right clicking on the title of a dock or through their X button or in the background of the main window in which the docks reside. For main window docks, you can also close them from View/Windows and for flow docks from the Menu button in the Graphs View. I don't think you can hide the whole dock area by dragging the splitter. The only docks that I made un-closeable are the flows and the nodes. |
Isn't the docking stuff just another widget? Can't we put a dock widget in a splitter? |
The docking stuff attach to a main window's predefined dock areas (left, top, right, bottom). They have various settings to make them float or be tabbed and etc... But I'm pretty sure you can't put a dock inside a splitter. I tried searching for this when I was making it but didn't find anything. |
Is it that important? We could add menu functions that close them all or open them all. |
Hm yeah I can't come up with a better solution right now... |
-From View/Windows where it acts on all docks, including every flow uis -From each flow view's menu, where it closes only the flow vies
Done, check it out. The code is the same for both |
thanks! i'll take a look later, can merge afterwards |
Oh, also, I got no answer on this, unless I missed it. |
Sorry, forgot about it and yes I misread your comment, of course we should do the same to |
Alright! We're good to go I think |
just check my review comment above |
The last review I see is about |
I commented on b542a40 |
Sorry, I'm searching but it shows 0 comments on my end. |
Weird that I can't see it. Anyway, I put that there so we could close only the docks of the flow through its menu in the graph view if needed and not all the docks everywhere. Also, now that I'm thinking about it, should we only close any tabified docks and not any detached, floating ones? |
ohh now I see where it is, yes that makes sense
good point, do you think this is easy to do? |
done |
looking good 👍 |
Found another potentially good thing. We can make it so that the menu isn't closed when clicking window actions, i.e not closing when pressing Menu/Windows/Inspector in the graph view menu. That way, the user can toggle many things at once. |
I agree. I found this |
Okay, I have this working: # add all docks to menu
for w in all_dock_widgets:
def toggle(checked, w=w):
# second parameter is to avoid the closure problem
# https://stackoverflow.com/questions/3431676/creating-functions-in-a-loop
w.setVisible(checked)
label = w.windowTitle()
cb = QCheckBox(label, self)
cb.setChecked(True)
cb.toggled.connect(toggle)
action = QWidgetAction(self)
action.setDefaultWidget(cb)
windows_menu.addAction(action) I'll push to edit: unfortunately, |
It also only works when pressing the check box or the name. If you press slightly to the right it closes the menu. And currently it isn't highlighted when hovered. Due to the fact that you may open a saved project, the tab would be closed but the action would be highlighted. I think this is too hacky. Perhaps add it to the TODO list? I'll search for a bit but I think it's too minor a thing to keep this PR open, since there is no apparent easy and correct way to do this. |
agreed |
This PR is a result of #173. Apart from the inspector, it includes some fixes, optimization and additions. Most of the updates are showcased in the video below.
show_case.mp4
Inspector
For the inspector, there's a new
InspectorGUI.py
file. It contains:InspectorWidget
: A simple wrapper for holding the actual [BaseNodeInspector
] inspector.BaseNodeInspector
: The base inspector;create_inspector
must be implemented, where the user can insert their GUI using theparent
parameter. Anunload
method is provided for cleanup.NodeInspector
: A basic implementation ofBaseNodeInspector
, where aNodeInspectorWidget
is used. This inspector shows the title of the node, the python and ryven id and meta-data information. Theattach_inspector
method can be implemented to attach a configuration gui between the title and the metadata. TheNodeInspector
is the default for any node that hasn't explicitly defined an inspector.For connecting an inspector to a node, a new decorator
inspector_gui
is defined which works like thenode_gui
decorator.A new example package named
traits_inspector_test
is given. It uses traits and traits ui to rapidly implement a configuration window for theRand
node. Configuration and value generation are undoable and there's a generate button for getting a new random value. State saving-loading is a simple hard-coded implementation, nothing generic here. The random state is not saved.This inspector could serve as an example on how one can use traits to create a base inspector for their packages.
Undo
New additions:
PrettyName
interface is defined inGUIBase.py
. It can be used on any object to define how it should be displayed in text format. It has been used onNodeItem
,ConnectionItem
andDrawingObject
.NestedCommand
. Not currently used, but provides a way to bundle commands together.DelegateCommand
. A command whose undo and redo are passed functions. The exampleRandNode
uses it to implement undo functionality.Selection
The
selection system
has been refactored to work with theundo system
. It utilizes a new_SelectionMode
enum that hasINSTANT
,UNDO_CLICK
andUNDO_DRAG
values.INSTANT
: Selection isn't added in undo stack. Whenever anything is created or removed, this mode is used.UNDO_CLICK
: A single selection that occurs when the user presses on an object and is added to the undo stack.UNDO_DRAG
: If the user presses on the canvas / view, then the selection event terminates onmouseRelease
. Anything that has been selected is a single multi-select event passed to the undo-stack.Node and Connection items
The
NodeItemAnimator
has been expanded to include a scaling animation. Whenever a node is updated, it plays that animation along with the others. You can see it in the showcase video.When a connection item is added or deleted, forced the corresponding node items to update their representation; This fixes a bug where ports weren't showing correct visuals.
ConnectionItem
has two additional useful classes:ConnectionItemsAnimation
that animates any abstractQGraphicsItem
over the path to create a visual flow. AQGraphicsItemWrapper
class is provide inGUIBase.py
for allowing the animation of any item, even if it doesn't implementQObject
.ConnectionAnimation
that utilizes theConnectionItemsAnimation
to toggle the data flow. You can see it at ~0:57 in the video. The toggling happens on click and it's for demonstration purposes. In this PR nothing happens when clicking. However, this item might be useful for anyone that wants to expand Ryven or use it as a template for something else.I've optimized the way these animations are created, played, paused and resumed. Here's a snapshot; a gif showing there's no visible performance problem.
Flow View
node_color
being a string instead of a color. If I haven't missed anything, every theme is bug free.resetCachedContent()
function.drawBackground
of the flow view. It uses only the visible rect and not the whole scene. It's much faster now.Pretty
andFast
modes aren't really that much different performance-wise now.Unfortunately, I could not fix the horrendous performance when there are a lot of items and we're zooming in / out (essentially scaling). I read that it may have something to do with setting the correct cache mode (1, 2), but I couldn't find anything that works.
This is all! Should provide a substantial update for Ryven.
(I didn't include panning and zooming in the undo. Perhaps it can be added at a later time.)
(Ideally I'd also like to implement port validation with specific data types and a multi port where you can add N connections automatically, but these two may need ryvencore changes or be package specific, so I opted out of this feature for now)