Open MewPurPur opened 4 months ago
Bummer, but I don't think GodSVG can have any functionality around deciding whether an attribute change in a
tag will affect a child or not. Normally, if you have something like
<g fill="red">
<circle fill="red">
<circle fill="red">
<circle fill="red">
</g>
when you change the fill of the
tag, the circles would remain the same. But GodSVG automatically would remove the circles' fill attributes, because they are the default value Hmm... Maybe if an attribute is taking its default value from a specific tag, you can have both cases?
If you have the attribute in the SVG or if you edit the attribute through the editor, the value won't default even if it's the same as the default. The attribute would be added to the SVG. But you can reset it to default by deleting all text, or maybe I'd even add an option in the context menu for resetting to the default.
I think that'd be the best of both worlds.
Edit: No, it wouldn't be, now you can't hardcode the circles to black.
After #799 we're a lot closer to this spec. I might soon close this and report the few remaining issues separately so they get more attention.
The core infrastructure refers to the native handling of the SVG text, the TagSVG representation of it, and the ways these implementations hook into the different places in the editor.
Needed for #663 and #434. The latter is the most important feature missing from GodSVG at the moment, and a direct blocker for the beta.
Put simply, when I implemented tag hierarchies in GodSVG, there are a few things I kicked down into the future, because I didn't have enough knowledge to be able to tackle them. The biggest one is the inheritance of default values for attributes. and
Currently, even though
A lot of limitations hamper the possibility to implement this though, for example the fact that attribute changes only propagate up to the root, but they need to also be able to propagate down, as when you change a or
Requirements
Below I've listed the things that GodSVG needs to be able to do, which would help me define a specification.
SVG Parser
Only SVG text can be used for generating a graphic, but you can't get specific information out of it before parsing it. The SVG Parser must have two important functions:
Undo and Redo
The UndoRedo that handles the SVG should handle versions of the SVG text. It should only take specific snapshots of it, that is, actions should be able to opt out of UndoRedo (e.g., no UndoRedo while you're dragging a gizmo, only when you finish the operation). Also, no operation if the SVG text didn't change.
Editing the SVG text without the SVG Code Editor
If importing or resetting makes it so the new text gives parser errors, don't parse it.
SVG Code Editor
When not focused, the SVG Code Editor should always reflect the underlying SVG text. Any changes to the text while it's not focused clear its undo history.
When focused, the text should only change how the user edits it. It would no longer reflect the underlying SVG text. Every time the user edits the text, it would be passed to the SVG Parser. If there's an error, don't change the underlying SVG text, keep the old one. If there's no error, feed the TagSVG representation back into the SVG Parser and use the returned text as an underlying SVG text.
When you click away, the SVG Code Editor should go back to reflecting the underlying SVG text. If this change resulted in any difference, that should count as a single UndoRedo action, and should be the only kind of external change that doesn't clear the SVG Code Editor's undo history.
Indications
Certain elements should be able to be marked as selected or hovered. They should reflect simultaneously inside the SVG Inspector and the SVG Viewport, if relevant there. Those things are:
You should be able to select multiple of all of these, but you shouldn't be able to select things from different categories, or path commands or segments of a polyline or polygon from different tags.
Moreover, there should be a mechanism to allow some of the attributes in a tag to be focused, specifically in the inspector. When you drag handles that can change this attribute, it should be highlighted specially in the inspector.
SVG Inspector
The SVG Inspector should always represent the root TagSVG's hierarchy. A tag would be represented as a frame which has attribute editors, some extra things that may allow certain operations or other actions, and the child XML nodes at the bottom.
XML nodes - Comments, Text, and CDATA - should have simpler editors, where the main part is a TextEdit. When text is edited inside them, it immediately affects the SVG itself, unless the new text is illegal (i.e.
--
inside a comment, or<
inside text). Their undo history management should be similar to that of the SVG Code Editor.The basic XML nodes don't need any context about the SVG hierarchy.
Tags should have more complex editors that allow you to focus attribute editors, tied to specific attributes of the tag, and edit those attributes. All attribute editors are shaping up to have LineEdits, which should enact their change on the TagSVG, and thereby the underlying SVG text, when they are unfocused. How undo history is done doesn't matter much for them (Godot doesn't make it very controllable anyway).
Tags need context about the SVG hierarchy, as there are multiple "illegal" configurations (they aren't errors, but they are still for the most part illegal), and they also have attributes which would require information about things like IDs, ancestor groups, etc.
Attribute editors may popup widgets. Changes in those should change the underlying SVG text immediately. The popup widgets should probably not have their own undo history management, but instead apply to the SVG itself in a reasonable way.
XML node operations
Add: Creates a new XML node with its default configuration, selecting it as well. Should be possible at any location.
Delete: Deletes all selected XML nodes, and the selection is removed.
Duplicate: Each selected XML node creates a new identical XML node under it, and the selection is changed to all the new XML nodes.
Convert To: Turns the selected XML node into some kind of equivalent one of a different type, keeping its selection.
Move Up/Down: If all selected XML nodes, after filtering descendants, are at the same depth, move them up or down, whilst keeping them selected.
Move To: Happens via drag-and-drop, and maybe other methods in the future. After filtering descendants, all XML nodes are moved to a set location, retaining their order from top to bottom. Locations can be below an XML node, above an XML node, or inside a tag (should not be a one of the selected ones or an ancestor of it)
SVG Viewport
In this section, a "sizeless" SVG is one without width and height, as well as without a viewBox.
The SVG viewport should have:
Ctrl+0
). The grid should also be redrawn. If the SVG is sizeless, zoom reset should take you to 100% size, and center you on (0, 0).Handles
Handles should be able to be hovered and selected, which would use the same interface as the inspector's hovering and selecting of tag editors.
The SVG viewport can also have options that context popups, with some actions occasionally. Right-clicking a place in the viewport should enable you to add a tag at that position, overriding the position defaults immediately upon the creation of the tag, with this being registered as a single action in the UndoRedo.
Moreover, certain actions that would normally create a handle, when done in the viewport, should force you to move that handle. For example, adding a new path command would also make you drag along the new handle, as well as any handles that should be relative to it in some way. Only when you click will an UndoRedo action be generated, and if you make any destructive operations in the meantime, the handle is just deleted without any UndoRedo action.
Attribute editing
The default of an attribute is defined, as per the SVG specification, by its usual default value, or its nearest or
If an attribute is edited to a value that's the same as its current default, it should be "turned off", its value dimmed.
When an attribute inside a tag is changed, the tag itself and all the ancestor tags need to somehow learn about this, so that they can update their default, in case this tag was somehow inherited. Moreover, a similar mechanic should somehow be implemented for IDs and URLs, i.e. changing a stop inside a gradient would change a gradient, which would need to propagate to everything that references this ID.
Formatting
The XML will have an autoformatter that will always be active.
Attribute formatters would have some more quirks. For all of them, you would have a number of settings to specify how formatting works, which will be used in scenarios where you don't input a value manually (such as "2 + 3" in a number field, using the color picker in a color field, or changing path commands in a path field). When you, the user, input things (i.e. the direct value through a LineEdit, like "5" in a number field, or "M4 2 h8" in a path field) they won't be formatted, unless you've turned on autoformatting for the particular type of attribute.
This list should elaborately define all the systems that need to interact with the core architecture of GodSVG. Knowing the requirements is essential to be able to come up with a good core architecture that can fulfill all of them. This can also serve as a baseline if/when further changes to the core infrastructure are needed.