Skip to content

Commit

Permalink
Merge pull request #46 from wojtryb/development
Browse files Browse the repository at this point in the history
Deploy v1.3.0
  • Loading branch information
wojtryb authored Jun 11, 2023
2 parents 84b6a5c + f6aafe6 commit 49c09f7
Show file tree
Hide file tree
Showing 65 changed files with 1,816 additions and 982 deletions.
402 changes: 42 additions & 360 deletions README.md

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion shortcut_composer/INFO.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# SPDX-FileCopyrightText: © 2022-2023 Wojciech Trybus <[email protected]>
# SPDX-License-Identifier: GPL-3.0-or-later

__version__ = "1.2.2"
__version__ = "1.3.0"
__author__ = "Wojciech Trybus"
__license__ = "GPL-3.0-or-later"
35 changes: 33 additions & 2 deletions shortcut_composer/actions.action
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,17 @@

<Action name="Temporary move tool">
<activationFlags>1</activationFlags>
<icon>krita_tool_move</icon>
</Action>

<Action name="Temporary eraser">
<activationFlags>1</activationFlags>
<icon>draw-eraser</icon>
</Action>

<Action name="Temporary preserve alpha">
<activationFlags>1</activationFlags>
<icon>bar-transparency-unlocked</icon>
</Action>

</Actions>
Expand All @@ -27,10 +30,12 @@

<Action name="Preview current layer visibility">
<activationFlags>1</activationFlags>
<icon>current-layer</icon>
</Action>

<Action name="Preview projection below">
<activationFlags>1</activationFlags>
<icon>all-layers</icon>
</Action>

</Actions>
Expand All @@ -39,10 +44,12 @@

<Action name="Cycle painting opacity">
<activationFlags>1</activationFlags>
<icon>opacity-increase</icon>
</Action>

<Action name="Cycle selection tools">
<activationFlags>1</activationFlags>
<icon>selectionMask</icon>
</Action>

</Actions>
Expand All @@ -51,22 +58,27 @@

<Action name="Scroll undo stack">
<activationFlags>1</activationFlags>
<icon>edit-undo</icon>
</Action>

<Action name="Scroll isolated layers">
<activationFlags>1</activationFlags>
<icon>all-layers</icon>
</Action>

<Action name="Scroll timeline or animated layers">
<activationFlags>1</activationFlags>
<icon>addduplicateframe</icon>
</Action>

<Action name="Scroll brush size or opacity">
<activationFlags>1</activationFlags>
<icon>brushsize-increase</icon>
</Action>

<Action name="Scroll canvas zoom or rotation">
<activationFlags>1</activationFlags>
<icon>zoom-original</icon>
</Action>

</Actions>
Expand All @@ -75,30 +87,42 @@

<Action name="Pick misc tools">
<activationFlags>1</activationFlags>
<icon>krita_tool_grid</icon>
</Action>

<Action name="Pick painting blending modes">
<activationFlags>1</activationFlags>
<icon>format-text-bold</icon>
</Action>

<Action name="Pick transform tool modes">
<activationFlags>1</activationFlags>
<icon>krita_tool_transform</icon>
</Action>

<Action name="Pick brush presets (red)">
<activationFlags>1</activationFlags>
<icon>config-popup-palette</icon>
</Action>

<Action name="Pick brush presets (green)">
<activationFlags>1</activationFlags>
<icon>config-popup-palette</icon>
</Action>

<Action name="Pick brush presets (blue)">
<activationFlags>1</activationFlags>
<icon>config-popup-palette</icon>
</Action>

<Action name="Pick local brush presets">
<activationFlags>1</activationFlags>
<icon>config-popup-palette</icon>
</Action>

<Action name="Create painting layer with blending mode">
<activationFlags>1</activationFlags>
<icon>addlayer</icon>
</Action>

</Actions>
Expand All @@ -107,36 +131,43 @@

<Action name="Configure Shortcut Composer">
<activationFlags>0</activationFlags>
<icon>configure</icon>
</Action>

<Action name="Transform tool: free">
<activationFlags>1</activationFlags>
<activationConditions>1</activationConditions>
<icon>krita_tool_transform</icon>
</Action>

<Action name="Transform tool: perspective">
<activationFlags>1</activationFlags>
<activationConditions>1</activationConditions>
<icon>transform_icons_perspective</icon>
</Action>

<Action name="Transform tool: warp">
<activationFlags>1</activationFlags>
<activationConditions>1</activationConditions>
<icon>transform_icons_warp</icon>
</Action>

<Action name="Transform tool: cage">
<activationFlags>1</activationFlags>
<activationConditions>1</activationConditions>
<icon>transform_icons_cage</icon>
</Action>

<Action name="Transform tool: liquify">
<activationFlags>1</activationFlags>
<activationConditions>1</activationConditions>
<icon>transform_icons_liquify_main</icon>
</Action>

<Action name="Transform tool: mesh">
<activationFlags>1</activationFlags>
<activationConditions>1</activationConditions>
<icon>transform_icons_mesh</icon>
</Action>

</Actions>
Expand Down
9 changes: 9 additions & 0 deletions shortcut_composer/actions.py
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,15 @@ def create_actions() -> List[templates.RawInstructions]: return [
active_color=QColor(110, 160, 235),
),

templates.PieMenu(
name="Pick local brush presets",
controller=controllers.PresetController(),
instructions=[instructions.SetBrushOnNonPaintable()],
values=[],
save_local=True,
active_color=QColor(234, 172, 0),
),

# .......................................
# Insert your actions implementation here
# .......................................
Expand Down
35 changes: 35 additions & 0 deletions shortcut_composer/api_krita/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
### Alternative Krita API
Package `api_krita` wraps krita api offering PEP8 compatibility, typings, and docstring documentation. Most of objects attributes are now available as settables properties.

```python
from .api_krita import Krita
from .api_krita.enums import BlendingMode, Tool, Toggle

# active tool operations
tool = Krita.active_tool # get current tool
Krita.active_tool = Tool.FREEHAND_BRUSH # set current tool
Tool.FREEHAND_BRUSH.activate() # set current tool (alternative way)

# operations on a document
document = Krita.get_active_document()
all_nodes = document.get_all_nodes() # all nodes with flattened structure
picked_node = all_nodes[3]

picked_node.name = "My layer name"
picked_node.visible = True
picked_node.opacity = 50 # remapped from 0-255 go 0-100 [%]
document.active_node = picked_node
document.refresh()

# Operations on a view
view = Krita.get_active_view()
view.brush_size = 100
view.blending_mode = BlendingMode.NORMAL # Enumerated blending modes

# Handling checkable actions
mirror_state = Toggle.MIRROR_CANVAS.state # get mirror state
Toggle.SOFT_PROOFING.state = False # turn off soft proofing
Toggle.PRESERVE_ALPHA.switch_state() # change state of preserve alpha
```

Only functionalities that were needed during this plugin development are wrapped, so some of them are not yet available. The syntax can also change over time.
11 changes: 7 additions & 4 deletions shortcut_composer/api_krita/core_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# SPDX-License-Identifier: GPL-3.0-or-later

from krita import Krita as Api, Extension, qApp
from typing import Callable, Protocol, Any, Optional
from typing import Callable, Protocol, Any, Dict, Optional

from PyQt5.QtWidgets import (
QMainWindow,
Expand Down Expand Up @@ -36,9 +36,12 @@ def get_active_view(self) -> View:
"""Return wrapper of krita `View`."""
return View(self.instance.activeWindow().activeView())

def get_active_document(self) -> Document:
def get_active_document(self) -> Optional[Document]:
"""Return wrapper of krita `Document`."""
return Document(self.instance.activeDocument())
document = self.instance.activeDocument()
if document is None:
return None
return Document(document)

def get_active_canvas(self) -> Canvas:
"""Return wrapper of krita `Canvas`."""
Expand All @@ -57,7 +60,7 @@ def get_action_shortcut(self, action_name: str) -> QKeySequence:
"""Return shortcut of krita action called `action_name`."""
return self.instance.action(action_name).shortcut()

def get_presets(self) -> dict:
def get_presets(self) -> Dict[str, Any]:
"""Return a list of unwrapped preset objects"""
return self.instance.resources('preset')

Expand Down
2 changes: 1 addition & 1 deletion shortcut_composer/api_krita/enums/blending_mode.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ class BlendingMode(Enum):
REFLECT_FREEZE = "reflect_freeze"

@property
def pretty_name(self):
def pretty_name(self) -> str:
"""Format blending mode name like: `Darker Color`."""
parts = self.name.split("_")
parts = [f"{part[0]}{part[1:].lower()}" for part in parts]
Expand Down
2 changes: 1 addition & 1 deletion shortcut_composer/api_krita/enums/node_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ def icon(self) -> QIcon:
return Api.instance().icon(icon_name)

@property
def pretty_name(self):
def pretty_name(self) -> str:
"""Format node type name like: `Paint layer`."""
return f"{self.name[0]}{self.name[1:].lower().replace('_', ' ')}"

Expand Down
2 changes: 1 addition & 1 deletion shortcut_composer/api_krita/enums/toggle.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ class Toggle(Enum):
SNAP_TO_GRID = "view_snap_to_grid"

@property
def pretty_name(self):
def pretty_name(self) -> str:
"""Format toggle name like: `Preserve alpha`."""
return f"{self.name[0]}{self.name[1:].lower().replace('_', ' ')}"

Expand Down
45 changes: 2 additions & 43 deletions shortcut_composer/api_krita/enums/tool.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,11 +64,10 @@ def is_paintable(tool: 'Tool') -> bool:
@property
def icon(self) -> QIcon:
"""Return the icon of this tool."""
icon_name = _ICON_NAME_MAP.get(self, "edit-delete")
return Api.instance().icon(icon_name)
return Api.instance().action(self.value).icon()

@property
def pretty_name(self):
def pretty_name(self) -> str:
"""Format tool name like: `Shape select tool`."""
return f"{self.name[0]}{self.name[1:].lower().replace('_', ' ')} tool"

Expand All @@ -83,43 +82,3 @@ def pretty_name(self):
Tool.POLYLINE,
}
"""Set of tools that are used to paint on the canvas."""

_ICON_NAME_MAP = {
Tool.FREEHAND_BRUSH: "krita_tool_freehand",
Tool.FREEHAND_SELECTION: "tool_outline_selection",
Tool.GRADIENT: "krita_tool_gradient",
Tool.LINE: "krita_tool_line",
Tool.TRANSFORM: "krita_tool_transform",
Tool.MOVE: "krita_tool_move",
Tool.RECTANGULAR_SELECTION: "tool_rect_selection",
Tool.CONTIGUOUS_SELECTION: "tool_contiguous_selection",
Tool.REFERENCE: "krita_tool_reference_images",
Tool.CROP: "tool_crop",
Tool.BEZIER_PATH: "krita_draw_path",
Tool.FREEHAND_PATH: "krita_tool_freehandvector",
Tool.POLYLINE: "polyline",
Tool.SHAPE_SELECT: "select",
Tool.ASSISTANTS: "krita_tool_assistant",
Tool.COLOR_SAMPLER: "krita_tool_color_sampler",
Tool.POLYGON: "krita_tool_polygon",
Tool.MEASUREMENT: "krita_tool_measure",
Tool.TEXT: "draw-text",
Tool.ELLIPSE: "krita_tool_ellipse",
Tool.FILL: "krita_tool_color_fill",
Tool.ENCLOSE_AND_FILL: "krita_tool_enclose_and_fill",
Tool.BEZIER_SELECTION: "tool_path_selection",
Tool.DYNAMIC_BRUSH: "krita_tool_dyna",
Tool.RECTANGLE: "krita_tool_rectangle",
Tool.PAN: "tool_pan",
Tool.MULTI_BRUSH: "krita_tool_multihand",
Tool.EDIT_SHAPES: "shape_handling",
Tool.ELIPTICAL_SELECTION: "tool_elliptical_selection",
Tool.SMART_PATCH: "krita_tool_smart_patch",
Tool.COLORIZE_MASK: "krita_tool_lazybrush",
Tool.SIMILAR_COLOR_SELECTION: "tool_similar_selection",
Tool.ZOOM: "tool_zoom",
Tool.MAGNETIC_SELECTION: "tool_magnetic_selection",
Tool.CALLIGRAPHY: "calligraphy",
Tool.POLYGONAL_SELECTION: "tool_polygonal_selection"
}
"""Maps tools to names of their icons."""
2 changes: 2 additions & 0 deletions shortcut_composer/api_krita/pyqt/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"""Wrappers and utilities based on PyQt5 objects."""

from .custom_widgets import AnimatedWidget, BaseWidget
from .safe_confirm_button import SafeConfirmButton
from .pixmap_transform import PixmapTransform
from .round_button import RoundButton
from .colorizer import Colorizer
Expand All @@ -12,6 +13,7 @@
from .text import Text

__all__ = [
"SafeConfirmButton",
"PixmapTransform",
"AnimatedWidget",
"RoundButton",
Expand Down
8 changes: 4 additions & 4 deletions shortcut_composer/api_krita/pyqt/custom_widgets.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ def move_center(self, new_center: QPoint) -> None:
"""Move the widget by providing a new center point."""
self.move(new_center-self.center) # type: ignore

def setGeometry(self, ax: int, ay: int, aw: int, ah: int):
def setGeometry(self, ax: int, ay: int, aw: int, ah: int) -> None:
center = self.center_global
super().setGeometry(ax, ay, aw, ah)
self.move_center(center)
Expand All @@ -42,20 +42,20 @@ def __init__(self, parent, animation_time: float = 0) -> None:
self._animation_interval = self._read_animation_interval()
self._animation_timer = Timer(self._increase_opacity, 17)

def show(self):
def show(self) -> None:
"""Decrease opacity to 0, and start a timer which animates it."""
self.setWindowOpacity(0)
self._animation_timer.start()
super().show()

def _increase_opacity(self):
def _increase_opacity(self) -> None:
"""Add interval to current opacity, stop the timer when full."""
current_opacity = self.windowOpacity()
self.setWindowOpacity(current_opacity+self._animation_interval)
if current_opacity >= 1:
self._animation_timer.stop()

def _read_animation_interval(self):
def _read_animation_interval(self) -> float:
"""Return how much opacity (0-1) should be increased on each frame."""
if time := self._animation_time:
return 0.0167/time
Expand Down
Loading

0 comments on commit 49c09f7

Please sign in to comment.