142 lines
4.6 KiB
Python
142 lines
4.6 KiB
Python
|
|
# SPDX-FileCopyrightText: © 2022-2023 Wojciech Trybus <wojtryb@gmail.com>
|
||
|
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
||
|
|
|
||
|
|
from dataclasses import dataclass
|
||
|
|
from typing import List, Protocol
|
||
|
|
from ..enums import BlendingMode
|
||
|
|
|
||
|
|
|
||
|
|
class KritaNode(Protocol):
|
||
|
|
"""Krita `Node` object API."""
|
||
|
|
|
||
|
|
def addChildNode(self, child: 'KritaNode', above: 'KritaNode') -> bool: ...
|
||
|
|
def name(self) -> str: ...
|
||
|
|
def setName(self, name: str) -> None: ...
|
||
|
|
def visible(self) -> bool: ...
|
||
|
|
def setVisible(self, visibility: bool) -> None: ...
|
||
|
|
def opacity(self) -> int: ...
|
||
|
|
def setOpacity(self, opacity: int) -> None: ...
|
||
|
|
def blendingMode(self) -> str: ...
|
||
|
|
def setBlendingMode(self, mode: str) -> None: ...
|
||
|
|
def isPinnedToTimeline(self) -> bool: ...
|
||
|
|
def setPinnedToTimeline(self, pinned: bool) -> None: ...
|
||
|
|
def type(self) -> str: ...
|
||
|
|
def collapsed(self) -> bool: ...
|
||
|
|
def setCollapsed(self, value: bool) -> None: ...
|
||
|
|
def animated(self) -> bool: ...
|
||
|
|
def uniqueId(self) -> str: ...
|
||
|
|
def childNodes(self) -> List['KritaNode']: ...
|
||
|
|
def parentNode(self) -> 'KritaNode': ...
|
||
|
|
|
||
|
|
|
||
|
|
@dataclass
|
||
|
|
class Node():
|
||
|
|
"""Wraps krita `Node` for typing, documentation and PEP8 compatibility."""
|
||
|
|
|
||
|
|
node: KritaNode
|
||
|
|
|
||
|
|
def add_child_node(self, child: 'Node', above: 'Node') -> bool:
|
||
|
|
"""
|
||
|
|
Add the given node in the list of children.
|
||
|
|
|
||
|
|
Parameters:
|
||
|
|
child - the node to be added
|
||
|
|
above - the node above which this node will be placed
|
||
|
|
|
||
|
|
Returns false if adding the node failed.
|
||
|
|
"""
|
||
|
|
return self.node.addChildNode(child.node, above.node)
|
||
|
|
|
||
|
|
@property
|
||
|
|
def name(self) -> str:
|
||
|
|
"""Settable property with this node's name."""
|
||
|
|
return self.node.name()
|
||
|
|
|
||
|
|
@name.setter
|
||
|
|
def name(self, new_name: str) -> None:
|
||
|
|
"""Set name of this node."""
|
||
|
|
self.node.setName(new_name)
|
||
|
|
|
||
|
|
@property
|
||
|
|
def visible(self) -> bool:
|
||
|
|
"""Settable property with visibility of this node."""
|
||
|
|
return self.node.visible()
|
||
|
|
|
||
|
|
@visible.setter
|
||
|
|
def visible(self, value: bool) -> None:
|
||
|
|
"""Set visibility of this node."""
|
||
|
|
self.node.setVisible(value)
|
||
|
|
|
||
|
|
def toggle_visility(self) -> None:
|
||
|
|
"""Change visibility of this node to the opposite one."""
|
||
|
|
self.visible = not self.visible
|
||
|
|
|
||
|
|
@property
|
||
|
|
def opacity(self) -> int:
|
||
|
|
"""Settable property with opacity of this node."""
|
||
|
|
return round(self.node.opacity()/2.55)
|
||
|
|
|
||
|
|
@opacity.setter
|
||
|
|
def opacity(self, opacity: int) -> None:
|
||
|
|
"""Set opacity of this node."""
|
||
|
|
self.node.setOpacity(round(2.55*opacity))
|
||
|
|
|
||
|
|
@property
|
||
|
|
def blending_mode(self) -> BlendingMode:
|
||
|
|
"""Settable property with blending_mode of this node."""
|
||
|
|
return BlendingMode(self.node.blendingMode())
|
||
|
|
|
||
|
|
@blending_mode.setter
|
||
|
|
def blending_mode(self, blending_mode: BlendingMode) -> None:
|
||
|
|
"""Set blending_mode of this node."""
|
||
|
|
self.node.setBlendingMode(blending_mode.value)
|
||
|
|
|
||
|
|
@property
|
||
|
|
def pinned_to_timeline(self) -> bool:
|
||
|
|
"""Settable property of node being pinned to timeline."""
|
||
|
|
return self.node.isPinnedToTimeline()
|
||
|
|
|
||
|
|
@pinned_to_timeline.setter
|
||
|
|
def pinned_to_timeline(self, pinned_to_timeline: bool) -> None:
|
||
|
|
"""Set pinned_to_timeline property of this node."""
|
||
|
|
self.node.setPinnedToTimeline(pinned_to_timeline)
|
||
|
|
|
||
|
|
@property
|
||
|
|
def collapsed(self) -> bool:
|
||
|
|
"""Settable property telling whether this node is collapsed."""
|
||
|
|
return self.node.collapsed()
|
||
|
|
|
||
|
|
@collapsed.setter
|
||
|
|
def collapsed(self, value: bool) -> None:
|
||
|
|
"""Change collapsed state of this node."""
|
||
|
|
self.node.setCollapsed(value)
|
||
|
|
|
||
|
|
@property
|
||
|
|
def is_group_layer(self) -> bool:
|
||
|
|
"""Read-only property telling if this node is a group."""
|
||
|
|
return self.node.type() == "grouplayer"
|
||
|
|
|
||
|
|
@property
|
||
|
|
def is_animated(self) -> bool:
|
||
|
|
"""Read-only property telling if this node has animation frames."""
|
||
|
|
return self.node.animated()
|
||
|
|
|
||
|
|
def get_child_nodes(self) -> List['Node']:
|
||
|
|
"""Return a list of wrapped Nodes that are children of this one."""
|
||
|
|
return [Node(node) for node in self.node.childNodes()]
|
||
|
|
|
||
|
|
def get_parent_node(self) -> 'Node':
|
||
|
|
"""Return wrapped Node being a parent of this node."""
|
||
|
|
return Node(self.node.parentNode())
|
||
|
|
|
||
|
|
@property
|
||
|
|
def unique_id(self) -> str:
|
||
|
|
"""Read-only property holding unique ID of a node."""
|
||
|
|
return self.node.uniqueId()
|
||
|
|
|
||
|
|
def __eq__(self, node: 'Node') -> bool:
|
||
|
|
"""Two objects are the same node, when their unique IDs matches."""
|
||
|
|
if not isinstance(node, Node):
|
||
|
|
return False
|
||
|
|
return self.unique_id == node.unique_id
|