This is a comprehensive vision for evolving the GUI from a simple "point-and-click" interface to a fluid, professional-grade "drag-and-drop" development environment. This set of features that would dramatically accelerate workflow creation and refactoring.
Feature Suite: Advanced Workflow Editing Experience
The overarching goal is to enable fluid manipulation of steps within the WorkflowEditorFrame using modern GUI paradigms like drag-and-drop, multi-select, and clipboard operations.
Phase 1: Foundational Drag-and-Drop
This phase establishes the core mechanics of moving steps.
Adding Drag-and-Drop from the Agent List:
UI Indication: When the user starts dragging an agent from the left-side agent_list_frame, the cursor changes to a "dragging" icon.
Target Indication: As the mouse moves over the steps_frame on the right, a horizontal "drop indicator" line appears between the steps, showing exactly where the new agent will be inserted.
Implementation:
The agent buttons in the agent_list_frame need bindings for <ButtonPress-1> (to initiate the drag) and <B1-Motion> (to track movement).
The steps_frame needs bindings for <Enter>, <Leave>, and <B1-Motion> to detect when the dragged item is over it.
On drop (<ButtonRelease-1>), a new method insert_agent_as_step(agent_name, index) is called, which is a modification of the existing add_agent_as_step. This method inserts the new step at the calculated index and then calls refresh_steps_list.
Reordering Steps within the Workflow:
UI Indication: The user can click and drag an existing step within the steps_frame. The step being dragged could become semi-transparent, and the same horizontal drop indicator appears between other steps.
Implementation:
This is a more complex version of the above. The step frames themselves get the drag-and-drop event bindings.
On drop, the logic calculates the source_index and destination_index and performs an insert/pop operation on the self.data['steps'] list before refreshing.
Auto-Scrolling:
Functionality: While dragging an item, if the mouse is held near the top or bottom edge of the steps_frame's visible area, the scrollable frame should automatically scroll up or down at a reasonable speed.
Implementation:
Inside the <B1-Motion> event handler, check the mouse's y-coordinate relative to the widget's height. If it's within a certain threshold (e.g., top 15%), trigger a recurring self.after() job that programmatically scrolls the frame until the mouse moves away.
Phase 2: Advanced Selection and Clipboard Operations
This phase builds on the drag-and-drop foundation to allow for more powerful, bulk operations.
Multi-Select Logic:
Functionality:
A simple click on a step selects it and deselects all others.
Holding Command (macOS) or Control (Windows/Linux) while clicking adds/removes a step from the current selection.
Clicking on an empty area of the steps_frame deselects everything.
Implementation:
The WorkflowEditorFrame needs an instance variable, self.selected_indices = set().
The click event handlers for the step frames are updated to check for modifier keys (event.state).
The refresh_steps_list method is updated to draw selected steps with a different background or border color based on whether their index is in self.selected_indices.
Drag-and-Drop for Multiple Items:
Functionality: When multiple steps are selected, dragging any one of them drags the entire contiguous block of selected items. The drop indicator shows where the entire block will be moved.
Implementation:
The drag-and-drop logic now operates on the self.selected_indices set. It removes all selected steps from the steps list and re-inserts them as a group at the destination index.
Clipboard Integration (Copy/Cut/Paste):
Functionality:
Ctrl+C / Cmd+C: Copies the JSON representation of the selected steps to the system clipboard.
Ctrl+X / Cmd+X: Copies the steps and then removes them from the workflow.
Ctrl+V / Cmd+V: Pastes the steps from the clipboard at the current selection point or the end of the list.
Implementation:
The main App window needs key bindings for these shortcuts.
Copy/Cut: The handler function gets the selected steps from the WorkflowEditorFrame, converts them to a pretty-printed JSON string (json.dumps(selected_steps, indent=2)), and uses the clipboard library (pyperclip or tkinter's built-in clipboard functions) to set the clipboard content. If it's a "cut" operation, it then deletes the steps.
Paste: The handler function reads from the clipboard. It uses a try...except json.JSONDecodeError block to safely parse the text. If successful, it inserts the new steps into the workflow.
External Paste: As you astutely noted, this makes the workflow portable. A user can copy a block of steps, paste it into a text editor or chat message, and another user can copy that text and paste it into their own workflow editor.
Phase 3: The "Killer Feature" - Refactoring into a Workflow
This is the most advanced and powerful feature, leveraging the entire suite of capabilities.
"Create Workflow from Selection" Context Menu:
Functionality: After selecting a group of steps, a right-click brings up a context menu with an option like "Encapsulate as New Workflow...".
Implementation:
The step frames need a <Button-3> (or platform-equivalent) binding to show a simple menu.
The "Encapsulation" Logic (The Hard Part):
When the menu item is clicked, a complex analysis function is triggered. This is a mini-compiler for your DSL.
Algorithm:
Identify the Selection: Get the block of selected steps.
Analyze Inputs:
Iterate through all the params of the selected steps.
Any parameter value that starts with $ and refers to a variable defined before the selected block is a required input for the new workflow.
Use a set to get a unique list of these external dependencies.
Analyze Outputs:
Iterate through all steps after the selected block.
Check their params. Any parameter that refers to an output of a step inside the selected block is a required output for the new workflow.
Create the New Agent:
Programmatically create a new workflow agent using self.app_ref.config.create_new_agent(). Let's say its generated name is new_workflow_1.
Set its inputs and outputs based on the analysis from steps 2 and 3.
Set its steps to be a deep copy of the selected steps.
Refactor the Current Workflow:
Delete the selected block of steps.
Insert a single new step in its place that calls the new_workflow_1 agent.
Wire the params of this new step to the variables that were identified as inputs in step 2.
Remap the output of this new step to have the same names as the outputs identified in step 3, so subsequent steps continue to work.
Refresh Everything: Save the config, refresh the main agent list, and refresh the current workflow's step list. The user will see the block of steps seamlessly collapse into a single, new, reusable workflow agent.
No comments:
Post a Comment