do note that there is still a bug about resetting presets of the brush that at this point only extending libkis i think is the solution and i cant do it in python. [I have started with it] so if you use popup pallete a lot it get troublesome.
OTH i can’t live without this plugin anymore. So im willing to improve it / just need to get time to do it.
Using the nightly for 5.2 of the 31 of December krita had an error with the plugin enabled, may be worth checking out. Haven’t tested any newer nightly yet. If i remember correctly it was an error when calling findchild
Needed some sleep to figure out the Paint mode.
I’ll push this update today and edit this post ,
but i might push another update later this week - not for functionality but to change the icon to custom ones.
I feel they don’t represent how they work right now.
For now, I use show coloring icon.
For Soak Ink, Off → no soak ink, On → Soak Ink
For Paint Mode, Off → Build up, On → Wash
I wish im capable of adding that, I still have not figure out the rotating widget.
[EDIT] : The git repository have been updated with Soak and Paint Mode. Color Rate is a bit… it work on my linux mint. My internet is going haywire so. Also have not tested on 5.1.4 nightly of dec 31 to latest. will do after work.
Hello I have check it :
and it seems the issue is that the pop up frame object name has been change from “popup frame” to “KisPopupButtonFrame”. Post Dec 31 nightly.
This branch has the fix version for 5.2: [i cant put in my main for now till 5.2 but will update it in split]
It’s causing lag on the first selection of brush… so i don’t think its good to add it on the UI.
I’ll look into actions and just tying it to a shortcut.
Its visible around 0:14. and I confirmed that its due to the plugin.
[my machine is pretty good spec - w/ plenty of ram so its happen here it probably be worse on other machine]
After testing the performance lag at the brush switch doesnt seem to be much related to the plugin.
though after testing a bit more … i stand that its still much better as shortcut bound than being in the docker. The workflow is not intuitive.
I have not tried making an extension - but if anyone want to this is how i track it in the brush editor.
#----------------------------------------------------#
# For Traversing nodes to get to Brush Editor Docker #
# #
#----------------------------------------------------#
def walk_widgets(self,start):
stack = [(start, 0)]
while stack:
cursor, depth = stack.pop(-1)
yield cursor, depth
stack.extend((c, depth + 1) for c in reversed(cursor.children()))
def get_brush_editor(self):
for window in QApplication.topLevelWidgets():
if isinstance(window, QFrame) and window.objectName() == 'popup frame':
for widget, _ in self.walk_widgets(window):
real_cls_name = widget.metaObject().className()
obj_name = widget.objectName()
if real_cls_name == 'KisPaintOpPresetsEditor' and obj_name == 'KisPaintOpPresetsEditor':
return widget
#----------------------------------------------------#
# Get the corresponding container of the #
# brush property selected on the list view #
#----------------------------------------------------#
def selectBrushContainer(self,br_property):
editor = self.get_brush_editor()
option_widget_container = editor.findChild(QWidget, 'frmOptionWidgetContainer')
current_view = None
selectedRow = None
for view in option_widget_container.findChildren(QListView):
if view.metaObject().className() == 'KisCategorizedListView':
if view.isVisibleTo(option_widget_container):
current_view = view
break
if current_view:
current_settings_widget = current_view.parent()
s_model = current_view.selectionModel()
model = current_view.model()
target_index = None
for row in range(model.rowCount()):
index = model.index(row,0)
if index.data() == br_property:
target_index = index
selectedRow = row
break
if target_index is not None:
s_model.clear()
s_model.select(target_index, QItemSelectionModel.SelectCurrent)
s_model.setCurrentIndex(target_index, QItemSelectionModel.SelectCurrent)
current_view.setCurrentIndex(target_index)
current_view.activated.emit(target_index)
container_info = dict()
container_info["model_index"] = target_index
container_info["current_view"] = current_view
container_info["row_count"] = selectedRow
container_info["option_widget_container"] = option_widget_container
container_info["current_settings_widget"] = current_settings_widget
return container_info
/* Call This to rotate the brush angle */
def set_brushRotValue(self, rotationValue):
container_info = self.selectBrushContainer("Brush Tip")
current_view = container_info["current_view"]
option_widget_container = container_info["option_widget_container"]
current_settings_widget = container_info["current_settings_widget"]
if current_view:
for spin_box in current_settings_widget.findChildren(QDoubleSpinBox):
if spin_box.isVisibleTo(option_widget_container) and spin_box.metaObject().className() == 'KisAngleSelectorSpinBox' :
spin_box.setValue(rotationValue)
break
This will account for both the One in the predefined brush tip and the standard brushtip.
I tired making extension because this thing is haunting me… Its almost there.
I needed to execute toggleOutline off/on [so that the outline update] if i didnt do that you need to move the cursor for it to update. Im pressing F10 F11,
A couple of times i got confuse and pressed [ ].
It rotates at 5 deg increment
On different note - it got attack by the reset to default size thing when you are changing too fast.
Much better off to code this as native. If only i could.
I’m studying yours and @Grum999 yesterday as I use both of them. Its a big help , thank you.
As for this, Krita has a behavior of resetting brushsize when an action is trigerred. I feel it will be an issue. I mitigated most of it with exemption - it still hapen on rapid press.
I did something for brush size with Tela. I honestly forget everything to say anything but I don’t remember brush size being awkward but this plugin is something I never do so I am not sure.
Its nature of this plugin - since it just modify the value in the UI.
When it modify something in the brush editor by walking down all elements there till find the target and change the value of the target. the brush size somehow resets.
I’ll take this chance to ask, how do one determine if the shortcut press is long or short?
as a docker it is kinda impossible if the mouse is not over the docker and still it will not read always. I made the extension to have my own shortcuts but then I had to compete for the same keys. But there si a thing called like Key or Keyboard Event or something and you can listen to the event of a key but for an actual action being triggered I don’t know.
with my new plugin is were I will try to listen to some stuff but it is like document creation, save and the like.
to determine if it is long or short I guess you have to make a QTimer that is single shot and make a threshold limit to consider one or another. I did a Feature request a while back to help with it but no one was interested in it nor can I find it now. lol
As for the Icon set in the past I had custom sets but I started to think about making it as compatible with Krita’s theme as possible.But in the past I would make a SVG in Inkscape, extract it’s code of the save into my docker python script as a function and then I would use it to trigger a QIcon object inside the button or where ever. and because I was all inside the script I was able to change the color of single elements on the icon by reloading it again but with a different hex code for the object.
I think i accidentaly found solution to my brushSize issue.
as for icons, i guess i need to ask Krita team. After my goal is when i learned enough to eventually extend krita api and make this native. I forgot that theme compatibility is important for a moment there