diff --git a/.github/weekly-digest.yml b/.github/weekly-digest.yml new file mode 100644 index 0000000000..fe502fbc98 --- /dev/null +++ b/.github/weekly-digest.yml @@ -0,0 +1,7 @@ +# Configuration for weekly-digest - https://github.com/apps/weekly-digest +publishDay: sun +canPublishIssues: true +canPublishPullRequests: true +canPublishContributors: true +canPublishStargazers: true +canPublishCommits: true diff --git a/CHANGELOG.md b/CHANGELOG.md index ba86b85eec..9349589f8f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,169 @@ # Changelog -## [2.12.0](https://github.com/pypeclub/pype/tree/2.12.0) (2020-09-09) +## [2.13.1](https://github.com/pypeclub/pype/tree/2.13.1) (2020-10-23) + +[Full Changelog](https://github.com/pypeclub/pype/compare/2.13.0...2.13.1) + +**Enhancements:** + +- move maya look assigner to pype menu [\#292](https://github.com/pypeclub/pype/issues/292) + +**Fixed bugs:** + +- Layer name is not propagating to metadata in Photoshop [\#654](https://github.com/pypeclub/pype/issues/654) +- Loader in Photoshop fails with "can't set attribute" [\#650](https://github.com/pypeclub/pype/issues/650) +- Hiero: Review video file adding one frame to the end [\#659](https://github.com/pypeclub/pype/issues/659) + +## [2.13.0](https://github.com/pypeclub/pype/tree/2.13.0) (2020-10-18) + +[Full Changelog](https://github.com/pypeclub/pype/compare/2.12.5...2.13.0) + +**Enhancements:** + +- Deadline Output Folder [\#636](https://github.com/pypeclub/pype/issues/636) +- Nuke Camera Loader [\#565](https://github.com/pypeclub/pype/issues/565) +- Deadline publish job shows publishing output folder [\#649](https://github.com/pypeclub/pype/pull/649) +- Get latest version in lib [\#642](https://github.com/pypeclub/pype/pull/642) +- Improved publishing of multiple representation from SP [\#638](https://github.com/pypeclub/pype/pull/638) +- Launch TvPaint shot work file from within Ftrack [\#631](https://github.com/pypeclub/pype/pull/631) +- Add mp4 support for RV action. [\#628](https://github.com/pypeclub/pype/pull/628) +- Maya: allow renders to have version synced with workfile [\#618](https://github.com/pypeclub/pype/pull/618) +- Renaming nukestudio host folder to hiero [\#617](https://github.com/pypeclub/pype/pull/617) +- Harmony: More efficient publishing [\#615](https://github.com/pypeclub/pype/pull/615) +- Ftrack server action improvement [\#608](https://github.com/pypeclub/pype/pull/608) +- Deadline user defaults to pype username if present [\#607](https://github.com/pypeclub/pype/pull/607) +- Standalone publisher now has icon [\#606](https://github.com/pypeclub/pype/pull/606) +- Nuke render write targeting knob improvement [\#603](https://github.com/pypeclub/pype/pull/603) +- Animated pyblish gui [\#602](https://github.com/pypeclub/pype/pull/602) +- Maya: Deadline - make use of asset dependencies optional [\#591](https://github.com/pypeclub/pype/pull/591) +- Nuke: Publishing, loading and updating alembic cameras [\#575](https://github.com/pypeclub/pype/pull/575) +- Maya: add look assigner to pype menu even if scriptsmenu is not available [\#573](https://github.com/pypeclub/pype/pull/573) +- Store task types in the database [\#572](https://github.com/pypeclub/pype/pull/572) +- Maya: Tiled EXRs to scanline EXRs render option [\#512](https://github.com/pypeclub/pype/pull/512) +- Fusion basic integration [\#452](https://github.com/pypeclub/pype/pull/452) + +**Fixed bugs:** + +- Burnin script did not propagate ffmpeg output [\#640](https://github.com/pypeclub/pype/issues/640) +- Pyblish-pype spacer in terminal wasn't transparent [\#646](https://github.com/pypeclub/pype/pull/646) +- Lib subprocess without logger [\#645](https://github.com/pypeclub/pype/pull/645) +- Nuke: prevent crash if we only have single frame in sequence [\#644](https://github.com/pypeclub/pype/pull/644) +- Burnin script logs better output [\#641](https://github.com/pypeclub/pype/pull/641) +- Missing audio on farm submission. [\#639](https://github.com/pypeclub/pype/pull/639) +- review from imagesequence error [\#633](https://github.com/pypeclub/pype/pull/633) +- Hiero: wrong order of fps clip instance data collecting [\#627](https://github.com/pypeclub/pype/pull/627) +- Add source for review instances. [\#625](https://github.com/pypeclub/pype/pull/625) +- Task processing in event sync [\#623](https://github.com/pypeclub/pype/pull/623) +- sync to avalon doesn t remove renamed task [\#619](https://github.com/pypeclub/pype/pull/619) +- Intent publish setting wasn't working with default value [\#562](https://github.com/pypeclub/pype/pull/562) +- Maya: Updating a look where the shader name changed, leaves the geo without a shader [\#514](https://github.com/pypeclub/pype/pull/514) + +**Merged pull requests:** + +- Audio file existence check [\#614](https://github.com/pypeclub/pype/pull/614) +- Avalon module without Qt [\#581](https://github.com/pypeclub/pype/pull/581) +- Ftrack module without Qt [\#577](https://github.com/pypeclub/pype/pull/577) + +## [2.12.5](https://github.com/pypeclub/pype/tree/2.12.5) (2020-10-14) + +[Full Changelog](https://github.com/pypeclub/pype/compare/2.12.4...2.12.5) + +**Enhancements:** + +- Launch TvPaint shot work file from within Ftrack [\#629](https://github.com/pypeclub/pype/issues/629) + +**Merged pull requests:** + +- Harmony: Disable application launch logic [\#637](https://github.com/pypeclub/pype/pull/637) + +## [2.12.4](https://github.com/pypeclub/pype/tree/2.12.4) (2020-10-08) + +[Full Changelog](https://github.com/pypeclub/pype/compare/2.12.3...2.12.4) + +**Enhancements:** + +- convert nukestudio to hiero host [\#616](https://github.com/pypeclub/pype/issues/616) +- Fusion basic integration [\#451](https://github.com/pypeclub/pype/issues/451) + +**Fixed bugs:** + +- Sync to avalon doesn't remove renamed task [\#605](https://github.com/pypeclub/pype/issues/605) +- NukeStudio: FPS collecting into clip instances [\#624](https://github.com/pypeclub/pype/pull/624) + +**Merged pull requests:** + +- NukeStudio: small fixes [\#622](https://github.com/pypeclub/pype/pull/622) +- NukeStudio: broken order of plugins [\#620](https://github.com/pypeclub/pype/pull/620) + +## [2.12.3](https://github.com/pypeclub/pype/tree/2.12.3) (2020-10-06) + +[Full Changelog](https://github.com/pypeclub/pype/compare/2.12.2...2.12.3) + +**Enhancements:** + +- Nuke Publish Camera [\#567](https://github.com/pypeclub/pype/issues/567) +- Harmony: open xstage file no matter of its name [\#526](https://github.com/pypeclub/pype/issues/526) +- Stop integration of unwanted data [\#387](https://github.com/pypeclub/pype/issues/387) +- Move avalon-launcher functionality to pype [\#229](https://github.com/pypeclub/pype/issues/229) +- avalon workfiles api [\#214](https://github.com/pypeclub/pype/issues/214) +- Store task types [\#180](https://github.com/pypeclub/pype/issues/180) +- Avalon Mongo Connection split [\#136](https://github.com/pypeclub/pype/issues/136) +- nk camera workflow [\#71](https://github.com/pypeclub/pype/issues/71) +- Hiero integration added [\#590](https://github.com/pypeclub/pype/pull/590) +- Anatomy instance data collection is substantially faster for many instances [\#560](https://github.com/pypeclub/pype/pull/560) + +**Fixed bugs:** + +- test issue [\#596](https://github.com/pypeclub/pype/issues/596) +- Harmony: empty scene contamination [\#583](https://github.com/pypeclub/pype/issues/583) +- Edit publishing in SP doesn't respect shot selection for publishing [\#542](https://github.com/pypeclub/pype/issues/542) +- Pathlib breaks compatibility with python2 hosts [\#281](https://github.com/pypeclub/pype/issues/281) +- Updating a look where the shader name changed leaves the geo without a shader [\#237](https://github.com/pypeclub/pype/issues/237) +- Better error handling [\#84](https://github.com/pypeclub/pype/issues/84) +- Harmony: function signature [\#609](https://github.com/pypeclub/pype/pull/609) +- Nuke: gizmo publishing error [\#594](https://github.com/pypeclub/pype/pull/594) +- Harmony: fix clashing namespace of called js functions [\#584](https://github.com/pypeclub/pype/pull/584) +- Maya: fix maya scene type preset exception [\#569](https://github.com/pypeclub/pype/pull/569) + +**Closed issues:** + +- Nuke Gizmo publishing [\#597](https://github.com/pypeclub/pype/issues/597) +- nuke gizmo publishing error [\#592](https://github.com/pypeclub/pype/issues/592) +- Publish EDL [\#579](https://github.com/pypeclub/pype/issues/579) +- Publish render from SP [\#576](https://github.com/pypeclub/pype/issues/576) +- rename ftrack custom attribute group to `pype` [\#184](https://github.com/pypeclub/pype/issues/184) + +**Merged pull requests:** + +- NKS small fixes [\#587](https://github.com/pypeclub/pype/pull/587) +- Standalone publisher editorial plugins interfering [\#580](https://github.com/pypeclub/pype/pull/580) + +## [2.12.2](https://github.com/pypeclub/pype/tree/2.12.2) (2020-09-25) + +[Full Changelog](https://github.com/pypeclub/pype/compare/2.12.1...2.12.2) + +**Enhancements:** + +- pype config GUI [\#241](https://github.com/pypeclub/pype/issues/241) + +**Fixed bugs:** + +- Harmony: Saving heavy scenes will crash [\#507](https://github.com/pypeclub/pype/issues/507) +- Extract review a representation name with `\*\_burnin` [\#388](https://github.com/pypeclub/pype/issues/388) +- Hierarchy data was not considering active isntances [\#551](https://github.com/pypeclub/pype/pull/551) + +## [2.12.1](https://github.com/pypeclub/pype/tree/2.12.1) (2020-09-15) + +[Full Changelog](https://github.com/pypeclub/pype/compare/2.12.0...2.12.1) + +**Fixed bugs:** + +- Pype: changelog.md is outdated [\#503](https://github.com/pypeclub/pype/issues/503) +- dependency security alert ! [\#484](https://github.com/pypeclub/pype/issues/484) +- Maya: RenderSetup is missing update [\#106](https://github.com/pypeclub/pype/issues/106) +- \ extract effects creates new instance [\#78](https://github.com/pypeclub/pype/issues/78) + +## [2.12.0](https://github.com/pypeclub/pype/tree/2.12.0) (2020-09-10) [Full Changelog](https://github.com/pypeclub/pype/compare/2.11.8...2.12.0) @@ -16,13 +179,13 @@ - Properly containerize image plane loads. [\#434](https://github.com/pypeclub/pype/pull/434) - Option to keep the review files. [\#426](https://github.com/pypeclub/pype/pull/426) - Isolate view on instance members. [\#425](https://github.com/pypeclub/pype/pull/425) -- ftrack group is bcw compatible [\#418](https://github.com/pypeclub/pype/pull/418) - Maya: Publishing of tile renderings on Deadline [\#398](https://github.com/pypeclub/pype/pull/398) - Feature/little bit better logging gui [\#383](https://github.com/pypeclub/pype/pull/383) **Fixed bugs:** - Maya: Fix tile order for Draft Tile Assembler [\#511](https://github.com/pypeclub/pype/pull/511) +- NukeStudio: Fix comment tag collection and integration. [\#508](https://github.com/pypeclub/pype/pull/508) - Remove extra dash [\#501](https://github.com/pypeclub/pype/pull/501) - Fix: strip dot from repre names in single frame renders [\#498](https://github.com/pypeclub/pype/pull/498) - Better handling of destination during integrating [\#485](https://github.com/pypeclub/pype/pull/485) diff --git a/pype/modules/websocket_server/stubs/photoshop_server_stub.py b/pype/modules/websocket_server/stubs/photoshop_server_stub.py index da69127799..04fb7eff0f 100644 --- a/pype/modules/websocket_server/stubs/photoshop_server_stub.py +++ b/pype/modules/websocket_server/stubs/photoshop_server_stub.py @@ -22,8 +22,9 @@ class PhotoshopServerStub(): def open(self, path): """ Open file located at 'path' (local). - :param path: file path locally - :return: None + Args: + path(string): file path locally + Returns: None """ self.websocketserver.call(self.client.call ('Photoshop.open', path=path) @@ -32,9 +33,10 @@ class PhotoshopServerStub(): def read(self, layer, layers_meta=None): """ Parses layer metadata from Headline field of active document - :param layer: Layer("id": XXX, "name":'YYY') - :param data: json representation for single layer - :param all_layers: - for performance, could be + Args: + layer (namedtuple): Layer("id": XXX, "name":'YYY') + data(string): json representation for single layer + all_layers (list of namedtuples): for performance, could be injected for usage in loop, if not, single call will be triggered - :param layers_meta: json representation from Headline + layers_meta(string): json representation from Headline (for performance - provide only if imprint is in loop - value should be same) - :return: None + Returns: None """ if not layers_meta: layers_meta = self.get_layers_metadata() # json.dumps writes integer values in a dictionary to string, so # anticipating it here. if str(layer.id) in layers_meta and layers_meta[str(layer.id)]: - layers_meta[str(layer.id)].update(data) + if data: + layers_meta[str(layer.id)].update(data) + else: + layers_meta.pop(str(layer.id)) else: layers_meta[str(layer.id)] = data @@ -83,7 +89,7 @@ class PhotoshopServerStub(): """ Returns JSON document with all(?) layers in active document. - :return: + Returns: Format of tuple: { 'id':'123', 'name': 'My Layer 1', 'type': 'GUIDE'|'FG'|'BG'|'OBJ' @@ -97,8 +103,9 @@ class PhotoshopServerStub(): def get_layers_in_layers(self, layers): """ Return all layers that belong to layers (might be groups). - :param layers: - :return: + Args: + layers : + Returns: """ all_layers = self.get_layers() ret = [] @@ -116,7 +123,7 @@ class PhotoshopServerStub(): def create_group(self, name): """ Create new group (eg. LayerSet) - :return: + Returns: """ ret = self.websocketserver.call(self.client.call ('Photoshop.create_group', @@ -128,7 +135,7 @@ class PhotoshopServerStub(): def group_selected_layers(self, name): """ Group selected layers into new LayerSet (eg. group) - :return: + Returns: """ res = self.websocketserver.call(self.client.call ('Photoshop.group_selected_layers', @@ -139,7 +146,7 @@ class PhotoshopServerStub(): def get_selected_layers(self): """ Get a list of actually selected layers - :return: + Returns: """ res = self.websocketserver.call(self.client.call ('Photoshop.get_selected_layers')) @@ -147,9 +154,10 @@ class PhotoshopServerStub(): def select_layers(self, layers): """ - Selecte specified layers in Photoshop - :param layers: - :return: None + Selects specified layers in Photoshop by its ids + Args: + layers: + Returns: None """ layer_ids = [layer.id for layer in layers] @@ -161,7 +169,7 @@ class PhotoshopServerStub(): def get_active_document_full_name(self): """ Returns full name with path of active document via ws call - :return: full path with name + Returns(string): full path with name """ res = self.websocketserver.call( self.client.call('Photoshop.get_active_document_full_name')) @@ -171,7 +179,7 @@ class PhotoshopServerStub(): def get_active_document_name(self): """ Returns just a name of active document via ws call - :return: file name + Returns(string): file name """ res = self.websocketserver.call(self.client.call ('Photoshop.get_active_document_name')) @@ -181,7 +189,7 @@ class PhotoshopServerStub(): def is_saved(self): """ Returns true if no changes in active document - :return: + Returns: """ return self.websocketserver.call(self.client.call ('Photoshop.is_saved')) @@ -189,7 +197,7 @@ class PhotoshopServerStub(): def save(self): """ Saves active document - :return: None + Returns: None """ self.websocketserver.call(self.client.call ('Photoshop.save')) @@ -197,10 +205,11 @@ class PhotoshopServerStub(): def saveAs(self, image_path, ext, as_copy): """ Saves active document to psd (copy) or png or jpg - :param image_path: full local path - :param ext: - :param as_copy: - :return: None + Args: + image_path(string): full local path + ext: + as_copy: + Returns: None """ self.websocketserver.call(self.client.call ('Photoshop.saveAs', @@ -211,9 +220,10 @@ class PhotoshopServerStub(): def set_visible(self, layer_id, visibility): """ Set layer with 'layer_id' to 'visibility' - :param layer_id: - :param visibility: - :return: None + Args: + layer_id: + visibility: + Returns: None """ self.websocketserver.call(self.client.call ('Photoshop.set_visible', @@ -224,7 +234,7 @@ class PhotoshopServerStub(): """ Reads layers metadata from Headline from active document in PS. (Headline accessible by File > File Info) - :return: - json documents + Returns(string): - json documents """ layers_data = {} res = self.websocketserver.call(self.client.call('Photoshop.read')) @@ -234,22 +244,26 @@ class PhotoshopServerStub(): pass return layers_data - def import_smart_object(self, path): + def import_smart_object(self, path, layer_name): """ Import the file at `path` as a smart object to active document. Args: path (str): File path to import. + layer_name (str): Unique layer name to differentiate how many times + same smart object was loaded """ res = self.websocketserver.call(self.client.call ('Photoshop.import_smart_object', - path=path)) + path=path, name=layer_name)) return self._to_records(res).pop() - def replace_smart_object(self, layer, path): + def replace_smart_object(self, layer, path, layer_name): """ Replace the smart object `layer` with file at `path` + layer_name (str): Unique layer name to differentiate how many times + same smart object was loaded Args: layer (namedTuple): Layer("id":XX, "name":"YY"..). @@ -257,8 +271,18 @@ class PhotoshopServerStub(): """ self.websocketserver.call(self.client.call ('Photoshop.replace_smart_object', - layer=layer, - path=path)) + layer_id=layer.id, + path=path, name=layer_name)) + + def delete_layer(self, layer_id): + """ + Deletes specific layer by it's id. + Args: + layer_id (int): id of layer to delete + """ + self.websocketserver.call(self.client.call + ('Photoshop.delete_layer', + layer_id=layer_id)) def close(self): self.client.close() @@ -267,8 +291,8 @@ class PhotoshopServerStub(): """ Converts string json representation into list of named tuples for dot notation access to work. - :return: - :param res: - json representation + Returns: + res(string): - json representation """ try: layers_data = json.loads(res) diff --git a/pype/plugins/hiero/publish/collect_hierarchy_context.py b/pype/plugins/hiero/publish/collect_hierarchy_context.py index f18783cd37..77b10dc9e4 100644 --- a/pype/plugins/hiero/publish/collect_hierarchy_context.py +++ b/pype/plugins/hiero/publish/collect_hierarchy_context.py @@ -217,7 +217,7 @@ class CollectHierarchyContext(pyblish.api.ContextPlugin): ''' label = "Collect Hierarchy Context" - order = pyblish.api.CollectorOrder + 0.102 + order = pyblish.api.CollectorOrder + 0.103 def update_dict(self, ex_dict, new_dict): for key in ex_dict: diff --git a/pype/plugins/hiero/publish/collect_plates.py b/pype/plugins/hiero/publish/collect_plates.py index 34ea622414..7b671ef718 100644 --- a/pype/plugins/hiero/publish/collect_plates.py +++ b/pype/plugins/hiero/publish/collect_plates.py @@ -183,7 +183,7 @@ class CollectPlatesData(api.InstancePlugin): "frameEnd": instance.data["sourceOut"] - instance.data["sourceIn"] + 1, 'step': 1, 'fps': instance.context.data["fps"], - 'tags': ["preview"], + 'tags': ["review"], 'name': "preview", 'ext': "mov", } diff --git a/pype/plugins/hiero/publish/extract_review_cutup.py b/pype/plugins/hiero/publish/extract_review_cutup.py index 57ec6c1107..88b19b7ec8 100644 --- a/pype/plugins/hiero/publish/extract_review_cutup.py +++ b/pype/plugins/hiero/publish/extract_review_cutup.py @@ -133,14 +133,24 @@ class ExtractReviewCutUp(pype.api.Extractor): "{ffprobe_path} -i \"{full_input_path}\" -show_streams " "-select_streams a -loglevel error" ).format(**locals()) + self.log.debug("ffprob_cmd: {}".format(ffprob_cmd)) audio_check_output = pype.api.subprocess(ffprob_cmd) self.log.debug( "audio_check_output: {}".format(audio_check_output)) + # Fix one frame difference + """ TODO: this is just work-around for issue: + https://github.com/pypeclub/pype/issues/659 + """ + frame_duration_extend = 1 + if audio_check_output: + frame_duration_extend = 0 + # translate frame to sec start_sec = float(frame_start) / fps - duration_sec = float(frame_end - frame_start + 1) / fps + duration_sec = float( + (frame_end - frame_start) + frame_duration_extend) / fps empty_add = None diff --git a/pype/plugins/photoshop/load/load_image.py b/pype/plugins/photoshop/load/load_image.py index 75c02bb327..301e60fbb1 100644 --- a/pype/plugins/photoshop/load/load_image.py +++ b/pype/plugins/photoshop/load/load_image.py @@ -1,4 +1,6 @@ from avalon import api, photoshop +import os +import re stub = photoshop.stub() @@ -13,10 +15,13 @@ class ImageLoader(api.Loader): representations = ["*"] def load(self, context, name=None, namespace=None, data=None): + layer_name = self._get_unique_layer_name(context["asset"]["name"], + name) with photoshop.maintained_selection(): - layer = stub.import_smart_object(self.fname) + layer = stub.import_smart_object(self.fname, layer_name) self[:] = [layer] + namespace = namespace or layer_name return photoshop.containerise( name, @@ -27,11 +32,25 @@ class ImageLoader(api.Loader): ) def update(self, container, representation): + """ Switch asset or change version """ layer = container.pop("layer") + context = representation.get("context", {}) + + namespace_from_container = re.sub(r'_\d{3}$', '', + container["namespace"]) + layer_name = "{}_{}".format(context["asset"], context["subset"]) + # switching assets + if namespace_from_container != layer_name: + layer_name = self._get_unique_layer_name(context["asset"], + context["subset"]) + else: # switching version - keep same name + layer_name = container["namespace"] + + path = api.get_representation_path(representation) with photoshop.maintained_selection(): stub.replace_smart_object( - layer, api.get_representation_path(representation) + layer, path, layer_name ) stub.imprint( @@ -39,7 +58,36 @@ class ImageLoader(api.Loader): ) def remove(self, container): - container["layer"].Delete() + """ + Removes element from scene: deletes layer + removes from Headline + Args: + container (dict): container to be removed - used to get layer_id + """ + layer = container.pop("layer") + stub.imprint(layer, {}) + stub.delete_layer(layer.id) def switch(self, container, representation): self.update(container, representation) + + def _get_unique_layer_name(self, asset_name, subset_name): + """ + Gets all layer names and if 'name' is present in them, increases + suffix by 1 (eg. creates unique layer name - for Loader) + Args: + name (string): in format asset_subset + + Returns: + (string): name_00X (without version) + """ + name = "{}_{}".format(asset_name, subset_name) + names = {} + for layer in stub.get_layers(): + layer_name = re.sub(r'_\d{3}$', '', layer.name) + if layer_name in names.keys(): + names[layer_name] = names[layer_name] + 1 + else: + names[layer_name] = 1 + occurrences = names.get(name, 0) + + return "{}_{:0>3d}".format(name, occurrences + 1) diff --git a/pype/tools/launcher/delegates.py b/pype/tools/launcher/delegates.py index 95ccde6445..e2eecc6ad5 100644 --- a/pype/tools/launcher/delegates.py +++ b/pype/tools/launcher/delegates.py @@ -20,12 +20,22 @@ class ActionDelegate(QtWidgets.QStyledItemDelegate): if not is_group: return - extender_width = int(option.decorationSize.width() / 2) - extender_height = int(option.decorationSize.height() / 2) + grid_size = option.widget.gridSize() + x_offset = int( + (grid_size.width() / 2) + - (option.rect.width() / 2) + ) + item_x = option.rect.x() - x_offset + + tenth_width = int(grid_size.width() / 10) + tenth_height = int(grid_size.height() / 10) + + extender_width = tenth_width * 2 + extender_height = tenth_height * 2 exteder_rect = QtCore.QRectF( - option.rect.x() + (option.rect.width() / 10), - option.rect.y() + (option.rect.height() / 10), + item_x + tenth_width, + option.rect.y() + tenth_height, extender_width, extender_height ) @@ -38,13 +48,14 @@ class ActionDelegate(QtWidgets.QStyledItemDelegate): painter.drawPath(path) divider = (2 * self.extender_lines) + 1 - line_height = extender_height / divider - line_width = extender_width - (extender_width / 5) - pos_x = exteder_rect.x() + extender_width / 10 + extender_offset = int(extender_width / 6) + line_height = round(extender_height / divider) + line_width = extender_width - (extender_offset * 2) + 1 + pos_x = exteder_rect.x() + extender_offset pos_y = exteder_rect.y() + line_height for _ in range(self.extender_lines): line_rect = QtCore.QRectF( - pos_x, pos_y, line_width, round(line_height) + pos_x, pos_y, line_width, line_height ) painter.fillRect(line_rect, self.extender_fg) pos_y += 2 * line_height diff --git a/pype/version.py b/pype/version.py index 521faacafe..930e2cd686 100644 --- a/pype/version.py +++ b/pype/version.py @@ -1 +1 @@ -__version__ = "2.12.3" +__version__ = "2.13.0"