Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender-addons.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVilém Duha <vilda.novak@gmail.com>2021-04-29 13:13:40 +0300
committerVilém Duha <vilda.novak@gmail.com>2021-04-29 13:13:59 +0300
commite670cee07525af65395a13f30f57ca5e656771a1 (patch)
tree6b5433dd9521bb63770ea82849db190be9f1f1d6 /blenderkit/ui_panels.py
parent452996ae951478853af3c1bcac3e0e1a26a6cab4 (diff)
BlenderKit: improve right click menu
-basically a complete revamp of the code, enables to display asset information in a much cleaner way with more tooltips e.t.c. -simplified floating asset preview - name needs to be fixed still, and tooltip generation cleaned -added several new icons, deleted one unused -improve a lot of tooltips -fix rerender of thumbnails in unsaved files (would save assets into addon directory) -reorganize some rating functions into ratings_utils.py -new 'wrap' operator for web links, allows to have custom tooltips for each link
Diffstat (limited to 'blenderkit/ui_panels.py')
-rw-r--r--blenderkit/ui_panels.py483
1 files changed, 408 insertions, 75 deletions
diff --git a/blenderkit/ui_panels.py b/blenderkit/ui_panels.py
index 6bacc895..4f703ba3 100644
--- a/blenderkit/ui_panels.py
+++ b/blenderkit/ui_panels.py
@@ -17,8 +17,9 @@
# ##### END GPL LICENSE BLOCK #####
-from blenderkit import paths, ratings, utils, download, categories, icons, search, resolutions, ui, tasks_queue, \
- autothumb
+from blenderkit import paths, ratings, ratings_utils, utils, download, categories, icons, search, resolutions, ui, \
+ tasks_queue, \
+ autothumb, upload
from bpy.types import (
Panel
@@ -35,9 +36,7 @@ from bpy.props import (
import bpy
import os
-import random
import logging
-import blenderkit
bk_logger = logging.getLogger('blenderkit')
@@ -207,7 +206,6 @@ def draw_panel_hdr_search(self, context):
utils.label_multiline(layout, text=props.report)
-
def draw_thumbnail_upload_panel(layout, props):
update = False
tex = autothumb.get_texture_ui(props.thumbnail, '.upload_preview')
@@ -216,6 +214,7 @@ def draw_thumbnail_upload_panel(layout, props):
box = layout.box()
box.template_icon(icon_value=tex.image.preview.icon_id, scale=6.0)
+
def draw_panel_model_upload(self, context):
ob = bpy.context.active_object
while ob.parent is not None:
@@ -646,7 +645,8 @@ def draw_panel_material_upload(self, context):
prop_needed(row, props, 'thumbnail', props.has_thumbnail, False)
if bpy.context.scene.render.engine in ('CYCLES', 'BLENDER_EEVEE'):
- layout.operator("object.blenderkit_generate_material_thumbnail", text='Render thumbnail with Cycles', icon='EXPORT')
+ layout.operator("object.blenderkit_generate_material_thumbnail", text='Render thumbnail with Cycles',
+ icon='EXPORT')
if props.is_generating_thumbnail:
row = layout.row(align=True)
row.label(text=props.thumbnail_generating_state, icon='RENDER_STILL')
@@ -1153,12 +1153,13 @@ def draw_asset_context_menu(layout, context, asset_data, from_panel=False):
layout.operator_context = 'INVOKE_DEFAULT'
- op = layout.operator('wm.blenderkit_menu_rating_upload', text='Rate')
- op.asset_name = asset_data['name']
- op.asset_id = asset_data['id']
- op.asset_type = asset_data['assetType']
+ if from_panel:
+ op = layout.operator('wm.blenderkit_menu_rating_upload', text='Rate')
+ op.asset_name = asset_data['name']
+ op.asset_id = asset_data['id']
+ op.asset_type = asset_data['assetType']
- if wm.get('bkit authors') is not None and author_id is not None:
+ if from_panel and wm.get('bkit authors') is not None and author_id is not None:
a = bpy.context.window_manager['bkit authors'].get(author_id)
if a is not None:
# utils.p('author:', a)
@@ -1172,6 +1173,7 @@ def draw_asset_context_menu(layout, context, asset_data, from_panel=False):
op.author_id = author_id
op = layout.operator('view3d.blenderkit_search', text='Search Similar')
+ op.tooltip = 'Search for similar assets in the library'
# build search string from description and tags:
op.keywords = asset_data['name']
if asset_data.get('description'):
@@ -1263,7 +1265,6 @@ def draw_asset_context_menu(layout, context, asset_data, from_panel=False):
op.model_rotation = (0, 0, 0)
op.max_resolution = asset_data.get('max_resolution',
0) # str(utils.get_param(asset_data, 'textureResolutionMax'))
- print('should be drawn!')
# print('operator res ', resolution)
# op.resolution = resolution
@@ -1297,7 +1298,7 @@ def draw_asset_context_menu(layout, context, asset_data, from_panel=False):
row = layout.row()
row.operator_context = 'INVOKE_DEFAULT'
- op = layout.operator('wm.blenderkit_fast_metadata', text='Fast Edit Metadata')
+ op = layout.operator('wm.blenderkit_fast_metadata', text='Edit Metadata')
op.asset_id = asset_data['id']
op.asset_type = asset_data['assetType']
@@ -1377,97 +1378,429 @@ class OBJECT_MT_blenderkit_asset_menu(bpy.types.Menu):
asset_data = sr[ui_props.active_index]
draw_asset_context_menu(self.layout, context, asset_data, from_panel=False)
- # ui_props = context.scene.blenderkitUI
- #
- # sr = bpy.context.window_manager['search results']
- # asset_data = sr[ui_props.active_index]
- # layout = self.layout
- # row = layout.row()
- # split = row.split(factor=0.2)
- # col = split.column()
- # op = col.operator('view3d.asset_drag_drop')
- # op.asset_search_index=ui_props.active_index
- #
- # draw_asset_context_menu(col, context, asset_data, from_panel=False)
- # split = split.split(factor=0.3)
- # col1 = split.column()
- # box = col1.box()
- # utils.label_multiline(box, asset_data['tooltip'])
- # col2 = split.column()
- #
- # pcoll = icons.icon_collections["main"]
- # my_icon = pcoll['test']
- # row = col2.row()
- # row.scale_y = 4
- # row.template_icon(icon_value=my_icon.icon_id, scale=2.0)
- # # col2.template_icon(icon_value=self.img.preview.icon_id, scale=10.0)
- # box2 = col2.box()
- #
- # box2.label(text='and heere goes the rating')
- # box2.label(text='************')
- # box2.label(text='dadydadadada')
-
class AssetPopupCard(bpy.types.Operator):
"""Generate Cycles thumbnail for model assets"""
bl_idname = "wm.blenderkit_asset_popup"
bl_label = "BlenderKit asset popup"
- # bl_options = {'REGISTER', 'INTERNAL'}
- bl_options = {'REGISTER', }
+
+ width = 700
+
+ message: StringProperty(
+ name="message",
+ description="message",
+ default="Rating asset",
+ options={'SKIP_SAVE'})
+
+ asset_id: StringProperty(
+ name="Asset Base Id",
+ description="Unique id of the asset (hidden)",
+ default="",
+ options={'SKIP_SAVE'})
+
+ asset_name: StringProperty(
+ name="Asset Name",
+ description="Name of the asset (hidden)",
+ default="",
+ options={'SKIP_SAVE'})
+
+ asset_type: StringProperty(
+ name="Asset type",
+ description="asset type",
+ default="",
+ options={'SKIP_SAVE'})
+
+ rating_quality: IntProperty(name="Quality",
+ description="quality of the material",
+ default=0,
+ min=-1, max=10,
+ # update=update_ratings_quality,
+ options={'SKIP_SAVE'})
+
+ # the following enum is only to ease interaction - enums support 'drag over' and enable to draw the stars easily.
+ rating_quality_ui: EnumProperty(name='rating_quality_ui',
+ items=ratings_utils.stars_enum_callback,
+ description='Rating stars 0 - 10',
+ default=0,
+ update=ratings_utils.update_quality_ui,
+ options={'SKIP_SAVE'})
+
+ rating_work_hours: FloatProperty(name="Work Hours",
+ description="How many hours did this work take?",
+ default=0.00,
+ min=0.0, max=300,
+ # update=update_ratings_work_hours,
+ options={'SKIP_SAVE'}
+ )
+
+ high_rating_warning = "This is a high rating, please be sure to give such rating only to amazing assets"
+
+ rating_work_hours_ui: EnumProperty(name="Work Hours",
+ description="How many hours did this work take?",
+ items=[('0', '0', ''),
+ ('.5', '0.5', ''),
+ ('1', '1', ''),
+ ('2', '2', ''),
+ ('3', '3', ''),
+ ('4', '4', ''),
+ ('5', '5', ''),
+ ('6', '6', ''),
+ ('8', '8', ''),
+ ('10', '10', ''),
+ ('15', '15', ''),
+ ('20', '20', ''),
+ ('30', '30', high_rating_warning),
+ ('50', '50', high_rating_warning),
+ ('100', '100', high_rating_warning),
+ ('150', '150', high_rating_warning),
+ ('200', '200', high_rating_warning),
+ ('250', '250', high_rating_warning),
+ ],
+ default='0', update=ratings_utils.update_ratings_work_hours_ui,
+ options={'SKIP_SAVE'}
+ )
+
+ rating_work_hours_ui_1_5: EnumProperty(name="Work Hours",
+ description="How many hours did this work take?",
+ items=[('0', '0', ''),
+ ('.2', '0.2', ''),
+ ('.5', '0.5', ''),
+ ('1', '1', ''),
+ ('2', '2', ''),
+ ('3', '3', ''),
+ ('4', '4', ''),
+ ('5', '5', '')
+ ],
+ default='0',
+ update=ratings_utils.update_ratings_work_hours_ui_1_5,
+ options={'SKIP_SAVE'}
+ )
+
+ rating_work_hours_ui_1_10: EnumProperty(name="Work Hours",
+ description="How many hours did this work take?",
+ items=[('0', '0', ''),
+ ('1', '1', ''),
+ ('2', '2', ''),
+ ('3', '3', ''),
+ ('4', '4', ''),
+ ('5', '5', ''),
+ ('6', '6', ''),
+ ('7', '7', ''),
+ ('8', '8', ''),
+ ('9', '9', ''),
+ ('10', '10', '')
+ ],
+ default='0',
+ update=ratings_utils.update_ratings_work_hours_ui_1_10,
+ options={'SKIP_SAVE'}
+ )
@classmethod
def poll(cls, context):
return True
+ def draw_menu(self, context, layout):
+ ui_props = context.scene.blenderkitUI
+
+ col_left = layout.column()
+ # row_button = col_left.row()
+ # row_button.scale_y = 3
+ # op = row_button.operator('view3d.asset_drag_drop', text='Drag & Drop')
+ # op.asset_search_index = ui_props.active_index
+ draw_asset_context_menu(col_left, context, self.asset_data, from_panel=False)
+ # layout = col_left
+ # op = layout.operator('view3d.blenderkit_search', text='Search Similar')
+ # # build search string from description and tags:
+ # op.keywords = self.asset_data['name']
+ # if self.asset_data.get('description'):
+ # op.keywords += ' ' + self.asset_data.get('description') + ' '
+ # op.keywords += ' '.join(self.asset_data.get('tags'))
+
+ def draw_property(self, layout, left, right, icon=None, icon_value=None, url=None, tooltip=''):
+ right = str(right)
+ row = layout.row()
+ split = row.split(factor=0.4)
+ split.alignment = 'RIGHT'
+ split.label(text=left)
+ split = split.split()
+ # if url:
+ # if icon_value:
+ # op = split.operator('wm.url_open', text=right, icon_value=icon_value)
+ # elif icon:
+ # op = split.operator('wm.url_open', text=right, icon=icon)
+ # else:
+ # op = split.operator('wm.url_open', text=right)
+ # op.url = url
+ # return
+ if url:
+ split = split.split(factor=0.9)
+ if icon_value:
+ split.label(text=right, icon_value=icon_value)
+ elif icon:
+ split.label(text=right, icon=icon)
+
+ else:
+ split.label(text=right)
+ if url:
+ split = split.split()
+ op = split.operator('wm.blenderkit_url', text='', icon='QUESTION')
+ op.url = url
+ op.tooltip = tooltip
+
+ def draw_asset_parameter(self, layout, key='', pretext=''):
+ parameter = utils.get_param(self.asset_data, key)
+ if parameter == None:
+ return
+ self.draw_property(layout, pretext, parameter)
+
+ def draw_tooltip(self, layout):
+ if type(self.asset_data['parameters']) == list:
+ mparams = utils.params_to_dict(self.asset_data['parameters'])
+ else:
+ mparams = self.asset_data['parameters']
+
+ layout = layout.column()
+ if len(self.asset_data['description']) > 0:
+ box = layout.box()
+ box.scale_y = 0.8
+ box.label(text='Description:')
+ utils.label_multiline(box, self.asset_data['description'], width=200)
+
+ pcoll = icons.icon_collections["main"]
+
+ box = layout.box()
+ box.scale_y = 0.8
+
+ if self.asset_data.get('license') == 'cc_zero':
+ t = 'CC Zero'
+ icon = pcoll['cc0']
+
+ else:
+ t = 'Royalty free'
+ icon = pcoll['royalty_free']
+
+ self.draw_property(box,
+ 'license:', t,
+ icon_value=icon.icon_id,
+ url="https://www.blenderkit.com/docs/licenses/",
+ tooltip='All BlenderKit assets are available for commercial use. '
+ 'Click to read more about BlenderKit licenses online'
+ )
+
+ if upload.can_edit_asset(asset_data=self.asset_data):
+ icon = pcoll[self.asset_data['verificationStatus']]
+ verification_status_tooltips = {
+ 'uploading': "Your asset got stuck during upload. Probably, your file was too large "
+ "or your connection too slow or interrupting. If you have repeated issues, "
+ "please contact us and let us know, it might be a bug",
+ 'uploaded': "Your asset uploaded successfully. Yay! If it's public, "
+ "it's awaiting validation. If it's private, use it",
+ 'on_hold': "Your asset needs some (usually smaller) fixes, "
+ "so we can make it public for everybody."
+ " Please check your email to see the feedback "
+ "that we send to every creator personally",
+ 'rejected': "The asset has serious quality issues, " \
+ "and it's probable that it might be good to start " \
+ "all over again or try with something simpler. " \
+ "You also get personal feedback into your e-mail, " \
+ "since we believe that together, we can all learn " \
+ "to become awesome 3D artists",
+ 'deleted': "You deleted this asset",
+ 'validated': "Your asset passed our validation process, "
+ "and is now available to BlenderKit users"
+
+ }
+ self.draw_property(box,
+ 'Verification:',
+ self.asset_data['verificationStatus'],
+ icon_value=icon.icon_id,
+ url="https://www.blenderkit.com/docs/validation-status/",
+ tooltip=verification_status_tooltips[self.asset_data['verificationStatus']]
+
+ )
+
+ self.draw_asset_parameter(box, key='textureResolutionMax', pretext='Resolution:')
+
+ self.draw_asset_parameter(box, key='designer', pretext='Designer:')
+ self.draw_asset_parameter(box, key='manufacturer', pretext='Manufacturer:')
+ self.draw_asset_parameter(box, key='collection', pretext='Collection:')
+ self.draw_asset_parameter(box, key='designYear', pretext='Design year:')
+ self.draw_asset_parameter(box, key='faceCount', pretext='Face count:')
+ self.draw_asset_parameter(box, key='thumbnailScale', pretext='Preview scale:')
+
+ if utils.get_param(self.asset_data, 'dimensionX'):
+ t = '%s × %s × %s m' % (utils.fmt_length(mparams['dimensionX']),
+ utils.fmt_length(mparams['dimensionY']),
+ utils.fmt_length(mparams['dimensionZ']))
+ self.draw_property(box, 'Size:', t)
+
+ #Free/Full plan or private Access
+ if self.asset_data['isPrivate']:
+ t = 'Private'
+ self.draw_property(box, 'Access:', t, icon='LOCKED')
+ elif self.asset_data['isFree']:
+ t = 'Free plan'
+ icon = pcoll['free']
+ self.draw_property(box, 'Access:', t, icon_value=icon.icon_id)
+ else:
+ t = 'Full plan'
+ icon = pcoll['full']
+ self.draw_property(box, 'Access:', t, icon_value=icon.icon_id)
+
+ def draw_author(self, layout, width=330):
+ image_split = 0.25
+ text_width = width
+ authors = bpy.context.window_manager['bkit authors']
+ a = authors.get(self.asset_data['author']['id'])
+ if a is not None: # or a is '' or (a.get('gravatarHash') is not None and a.get('gravatarImg') is None):
+ row = layout.row()
+ author_box = row.box()
+ author_box.scale_y = 0.6 # get text lines closer to each other
+ if hasattr(self, 'gimg'):
+
+ author_left = author_box.split(factor=0.25)
+ author_left.template_icon(icon_value=self.gimg.preview.icon_id, scale=6.0)
+ text_area = author_left.split()
+ text_width = int(text_width * (1 - image_split))
+ else:
+ text_area = author_box
+
+ author_right = text_area.column()
+ row = author_right.row()
+ col = row.column()
+
+ utils.label_multiline(col, text=a['tooltip'], width=text_width)
+ if upload.can_edit_asset(asset_data=self.asset_data) and a.get('aboutMe') is not None and len(
+ a.get('aboutMe', '')) == 0:
+ col.label(text='Please write something about yourself!')
+ op = col.operator('wm.blenderkit_url', text='Edit your profile')
+ op.url = 'https://www.blenderkit.com/profile'
+ op.tooltip = 'Edit your profile on BlenderKit webpage'
+
+ button_row = author_box.row()
+ button_row.scale_y = 2.0
+
+ if a.get('aboutMeUrl') is not None:
+ url = a['aboutMeUrl']
+ text = url
+ if len(url) > 25:
+ text = url[:25] + '...'
+ else:
+ url = paths.get_author_gallery_url(a['id'])
+ text = "Open Author's Profile"
+
+ op = button_row.operator('wm.url_open', text=text)
+ op.url = url
+
+ op = button_row.operator('view3d.blenderkit_search', text="Show Assets By Author")
+ op.keywords = ''
+ op.author_id = self.asset_data['author']['id']
+
+ def draw_thumbnail_box(self, layout):
+ layout.emboss = 'NORMAL'
+
+ box_thumbnail = layout.box()
+ # row = split_right.row()
+ # column_right = row.column()
+
+ box_thumbnail.scale_y = 0.5
+ # row = box_thumbnail.row()
+ # row.scale_y = 20
+
+ box_thumbnail.template_icon(icon_value=self.img.preview.icon_id, scale=34.0)
+ # row = box_thumbnail.row()
+ # row.scale_y = 4
+ # op = row.operator('view3d.asset_drag_drop', text='Drag & Drop from here', depress=True)
+
+ row = box_thumbnail.row()
+ row.alignment = 'EXPAND'
+ rc = self.asset_data.get('ratingsCount')
+ show_rating_threshold = 3
+
+ if rc:
+ rcount = min(rc['quality'], rc['workingHours'])
+ else:
+ rcount = 0
+ if rcount >= show_rating_threshold or upload.can_edit_asset(asset_data=self.asset_data):
+ pcoll = icons.icon_collections["main"]
+ my_icon = pcoll['trophy']
+ s = self.asset_data['score']
+ if s:
+ row.label(text=str(round(s)), icon_value=my_icon.icon_id)
+ q = self.asset_data['ratingsAverage'].get('quality')
+ if q:
+ row.label(text=str(round(q)), icon='SOLO_ON')
+ c = self.asset_data['ratingsAverage'].get('workingHours')
+ if c:
+ row.label(text=str(round(c)), icon='SORTTIME')
+ else:
+ box_thumbnail.label(text=f"This asset needs more ratings ( {rcount} of {show_rating_threshold} ).")
+ # box_thumbnail.label(text=f"Please rate this asset.")
+
+ def draw_menu_desc_author(self, context, layout):
+ box = layout.column()
+
+ box.emboss = 'NORMAL'
+ # left - tooltip & params
+ row = box.row()
+ split_left_left = row.split(factor=0.7)
+ self.draw_tooltip(split_left_left)
+
+ # right - menu
+ col1 = split_left_left.split()
+ self.draw_menu(context, col1)
+
+ # author
+ self.draw_author(box)
+
def draw(self, context):
ui_props = context.scene.blenderkitUI
sr = bpy.context.window_manager['search results']
asset_data = sr[ui_props.active_index]
+ self.asset_data = asset_data
layout = self.layout
- row = layout.row()
- split = row.split(factor=0.2)
- col = split.column()
- op = col.operator('view3d.asset_drag_drop')
- op.asset_search_index = ui_props.active_index
- draw_asset_context_menu(col, context, asset_data, from_panel=False)
- split = split.split(factor=0.5)
- col1 = split.column()
- box = col1.box()
- utils.label_multiline(box, asset_data['tooltip'], width=300)
-
- col2 = split.column()
+ # top draggabe bar with name of the asset
+ top_row = layout.row()
+ top_drag_bar = top_row.box()
+ top_drag_bar.alignment = 'CENTER'
- pcoll = icons.icon_collections["main"]
- my_icon = pcoll['test']
- col2.template_icon(icon_value=my_icon.icon_id, scale=20.0)
- # col2.template_icon(icon_value=self.img.preview.icon_id, scale=10.0)
- box2 = col2.box()
-
- # draw_ratings(box2, context, asset_data)
- box2.label(text='Ratings')
- # print(tp, dir(tp))
- # if not hasattr(self, 'first_draw'):# try to redraw because of template preview which needs update
- # for region in context.area.regions:
- # region.tag_redraw()
- # self.first_draw = True
+ top_drag_bar.label(text=asset_data['displayName'])
+ # left side
+ row = layout.row(align=True)
+ split_left = row.split(factor=0.5)
+ self.draw_thumbnail_box(split_left)
- def execute(self, context):
- print('execute')
- return {'FINISHED'}
+ # right split
+ split_right = split_left.split()
+ self.draw_menu_desc_author(context, split_right)
- def invoke(self, context, event):
+ ratings_box = layout.box()
+ ratings_box.label(text='Rate asset quality:')
+ ratings.draw_ratings_menu(self, context, ratings_box)
+ tip_box = layout.box()
+ tip_box.label(text=self.tip)
+
+ def execute(self, context):
wm = context.window_manager
ui_props = context.scene.blenderkitUI
ui_props.draw_tooltip = False
sr = bpy.context.window_manager['search results']
asset_data = sr[ui_props.active_index]
self.img = ui.get_large_thumbnail_image(asset_data)
+ self.asset_type = asset_data['assetType']
# self.tex = utils.get_hidden_texture(self.img)
# self.tex.update_tag()
+ authors = bpy.context.window_manager['bkit authors']
+ a = authors.get(asset_data['author']['id'])
+ if a.get('gravatarImg') is not None:
+ self.gimg = utils.get_hidden_image(a['gravatarImg'], a['gravatarHash'])
+
bl_label = asset_data['name']
- return wm.invoke_props_dialog(self, width=700)
+ self.tip = search.get_random_tip()
+ self.tip = self.tip.replace('\n', '')
+ return wm.invoke_popup(self, width=self.width)
class OBJECT_MT_blenderkit_login_menu(bpy.types.Menu):