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:
Diffstat (limited to 'blenderkit/ui.py')
-rw-r--r--blenderkit/ui.py299
1 files changed, 244 insertions, 55 deletions
diff --git a/blenderkit/ui.py b/blenderkit/ui.py
index 9f60d471..0dfed1d6 100644
--- a/blenderkit/ui.py
+++ b/blenderkit/ui.py
@@ -21,6 +21,7 @@
from blenderkit import paths, ratings, utils, search, upload, ui_bgl, download, bg_blender, colors, tasks_queue, \
ui_panels,icons
+
import bpy
import math, random
@@ -304,7 +305,6 @@ def draw_tooltip(x, y, text='', author='', img=None, gravatar=None):
isizey = int(512 * scale * img.size[1] / max(img.size[0], img.size[1]))
estimated_height = 2 * ttipmargin + textmargin + isizey
-
if estimated_height > y:
scaledown = y / (estimated_height)
scale *= scaledown
@@ -350,7 +350,6 @@ def draw_tooltip(x, y, text='', author='', img=None, gravatar=None):
bgcol)
# main preview image
ui_bgl.draw_image(x, y - isizey - ttipmargin, isizex, isizey, img, 1)
-
# text overlay background
ui_bgl.draw_rect(x - ttipmargin,
y - 2 * ttipmargin - isizey,
@@ -436,6 +435,23 @@ def draw_tooltip(x, y, text='', author='', img=None, gravatar=None):
t = time.time()
+def draw_tooltip_with_author(asset_data, x,y):
+ # TODO move this lazy loading into a function and don't duplicate through the code
+
+ img = get_large_thumbnail_image(asset_data)
+ gimg = None
+ atip = ''
+ if bpy.context.window_manager.get('bkit authors') is not None:
+ a = bpy.context.window_manager['bkit authors'].get(asset_data['author']['id'])
+ if a is not None and a != '':
+ if a.get('gravatarImg') is not None:
+ gimg = utils.get_hidden_image(a['gravatarImg'], a['gravatarHash'])
+ atip = a['tooltip']
+
+ # scene = bpy.context.scene
+ # ui_props = scene.blenderkitUI
+ draw_tooltip(x,y, text=asset_data['tooltip'], author=atip, img=img,
+ gravatar=gimg)
def draw_tooltip_old(x, y, text='', author='', img=None):
region = bpy.context.region
@@ -678,6 +694,22 @@ def is_upload_old(asset_data):
return (age.days - old.days)
return 0
+def get_large_thumbnail_image(asset_data):
+ '''Get thumbnail image from asset data'''
+ scene = bpy.context.scene
+ ui_props = scene.blenderkitUI
+ iname = utils.previmg_name(ui_props.active_index, fullsize=True)
+ directory = paths.get_temp_dir('%s_search' % mappingdict[ui_props.asset_type])
+ tpath = os.path.join(directory, asset_data['thumbnail'])
+ if not asset_data['thumbnail']:
+ tpath = paths.get_addon_thumbnail_path('thumbnail_not_available.jpg')
+
+ if asset_data['assetType'] == 'hdr':
+ colorspace = 'Non-Color'
+ else:
+ colorspace = 'sRGB'
+ img = utils.get_hidden_image(tpath, iname, colorspace=colorspace)
+ return img
def draw_asset_bar(self, context):
s = bpy.context.scene
@@ -817,63 +849,17 @@ def draw_asset_bar(self, context):
# report = 'BlenderKit - No matching results found.'
# ui_bgl.draw_text(report, ui_props.bar_x + ui_props.margin,
# ui_props.bar_y - 25 - ui_props.margin, 15)
+ if ui_props.draw_tooltip:
+ r = search_results[ui_props.active_index]
+ draw_tooltip_with_author(r, ui_props.mouse_x, ui_props.mouse_y)
s = bpy.context.scene
props = utils.get_search_props()
# if props.report != '' and props.is_searching or props.search_error:
# ui_bgl.draw_text(props.report, ui_props.bar_x,
# ui_props.bar_y - 15 - ui_props.margin - ui_props.bar_height, 15)
- props = s.blenderkitUI
- if props.draw_tooltip:
- # TODO move this lazy loading into a function and don't duplicate through the code
- iname = utils.previmg_name(ui_props.active_index, fullsize=True)
-
- directory = paths.get_temp_dir('%s_search' % mappingdict[props.asset_type])
- sr = s.get('search results')
- if sr != None and -1 < ui_props.active_index < len(sr):
- r = sr[ui_props.active_index]
- tpath = os.path.join(directory, r['thumbnail'])
- if not r['thumbnail']:
- tpath = paths.get_addon_thumbnail_path('thumbnail_not_available.jpg')
-
- # img = bpy.data.images.get(iname)
- # if img == None or img.filepath != tpath:
- # # TODO replace it with a function
- # if os.path.exists(tpath):
- #
- # if img is None:
- # img = bpy.data.images.load(tpath)
- # img.name = iname
- # else:
- # if img.filepath != tpath:
- # # todo replace imgs reloads with a method that forces unpack for thumbs.
- # if img.packed_file is not None:
- # img.unpack(method='USE_ORIGINAL')
- # img.filepath = tpath
- # img.reload()
- # img.name = iname
- # else:
- # iname = utils.previmg_name(ui_props.active_index)
- # img = bpy.data.images.get(iname)
- # if img:
- # img.colorspace_settings.name = 'sRGB'
- if r['assetType'] == 'hdr':
- colorspace = 'Non-Color'
- else:
- colorspace = 'sRGB'
- img = utils.get_hidden_image(tpath, iname, colorspace=colorspace)
- gimg = None
- atip = ''
- if bpy.context.window_manager.get('bkit authors') is not None:
- a = bpy.context.window_manager['bkit authors'].get(r['author']['id'])
- if a is not None and a != '':
- if a.get('gravatarImg') is not None:
- gimg = utils.get_hidden_image(a['gravatarImg'], a['gravatarHash'])
- atip = a['tooltip']
- draw_tooltip(ui_props.mouse_x, ui_props.mouse_y, text=ui_props.tooltip, author=atip, img=img,
- gravatar=gimg)
if ui_props.dragging and (
ui_props.draw_drag_image or ui_props.draw_snapped_bounds) and ui_props.active_index > -1:
@@ -1303,9 +1289,6 @@ class AssetBarOperator(bpy.types.Operator):
ui_props.mouse_x = 0
ui_props.mouse_y = self.region.height
- mx = event.mouse_x
- my = event.mouse_y
-
ui_props.draw_tooltip = True
# only generate tooltip once in a while
@@ -1472,6 +1455,7 @@ class AssetBarOperator(bpy.types.Operator):
my = event.mouse_y - r.y
if event.value == 'PRESS' and mouse_in_asset_bar(mx, my):
+ # bpy.ops.wm.blenderkit_asset_popup('INVOKE_DEFAULT')
bpy.ops.wm.call_menu(name='OBJECT_MT_blenderkit_asset_menu')
return {'RUNNING_MODAL'}
@@ -1803,6 +1787,205 @@ class UndoWithContext(bpy.types.Operator):
return {'FINISHED'}
+def draw_callback_dragging(self, context):
+ img = bpy.data.images.get(self.iname)
+ linelength = 35
+ scene = bpy.context.scene
+ ui_props = scene.blenderkitUI
+ ui_bgl.draw_image(self.mouse_x + linelength, self.mouse_y - linelength - ui_props.thumb_size,
+ ui_props.thumb_size, ui_props.thumb_size, img, 1)
+ ui_bgl.draw_line2d(self.mouse_x, self.mouse_y, self.mouse_x + linelength,
+ self.mouse_y - linelength, 2, colors.WHITE)
+
+
+def draw_callback_3d_dragging(self, context):
+ ''' Draw snapped bbox while dragging. '''
+ if not utils.guard_from_crash():
+ return
+ ui_props = context.scene.blenderkitUI
+ # print(ui_props.asset_type, self.has_hit, self.snapped_location)
+ if ui_props.asset_type == 'MODEL':
+ if self.has_hit:
+ draw_bbox(self.snapped_location, self.snapped_rotation, self.snapped_bbox_min, self.snapped_bbox_max)
+
+
+class AssetDragOperator(bpy.types.Operator):
+ """Draw a line with the mouse"""
+ bl_idname = "view3d.asset_drag_drop"
+ bl_label = "BlenderKit asset drag drop"
+
+ asset_search_index: IntProperty(name="Active Index", default=0)
+
+ def handlers_remove(self):
+ bpy.types.SpaceView3D.draw_handler_remove(self._handle, 'WINDOW')
+ bpy.types.SpaceView3D.draw_handler_remove(self._handle_3d, 'WINDOW')
+
+ def mouse_release(self):
+ scene = bpy.context.scene
+ ui_props = scene.blenderkitUI
+
+ if not self.has_hit:
+ return {'RUNNING_MODAL'}
+
+ if ui_props.asset_type == 'MODEL':
+ target_object = ''
+ if self.object_name is not None:
+ target_object = self.object_name
+ target_slot = ''
+
+ if ui_props.asset_type == 'MATERIAL':
+ # first, test if object can have material applied.
+ object = bpy.data.objects[self.object_name]
+ if object is not None and not object.is_library_indirect and object.type == 'MESH':
+ target_object = object.name
+ # create final mesh to extract correct material slot
+ depsgraph = bpy.context.evaluated_depsgraph_get()
+ object_eval = object.evaluated_get(depsgraph)
+ temp_mesh = object_eval.to_mesh()
+ target_slot = temp_mesh.polygons[self.face_index].material_index
+ object_eval.to_mesh_clear()
+ else:
+ self.report({'WARNING'}, "Invalid or library object as input:")
+ target_object = ''
+ target_slot = ''
+
+ if abs(self.start_mouse_x - self.mouse_x) < 20 and abs(self.start_mouse_y - self.mouse_y)<20:
+ #no dragging actually this was a click.
+ self.snapped_location = scene.cursor.location
+ self.snapped_rotation = (0,0,0)
+ if ui_props.asset_type in ('MATERIAL',):
+ ao = bpy.context.active_object
+ if ao != None and not ao.is_library_indirect:
+ target_object = bpy.context.active_object.name
+ target_slot = bpy.context.active_object.active_material_index
+ # change snapped location for placing material downloader.
+ self.snapped_location = bpy.context.active_object.location
+ else:
+ target_object = ''
+ target_slot = ''
+
+
+ # picking of assets and using them
+ if ui_props.asset_type == 'MATERIAL':
+ if target_object != '':
+ # position is for downloader:
+ loc = self.snapped_location
+ rotation = (0, 0, 0)
+
+ utils.automap(target_object, target_slot=target_slot,
+ tex_size=self.asset_data.get('texture_size_meters', 1.0))
+ bpy.ops.scene.blenderkit_download(True,
+ # asset_type=ui_props.asset_type,
+ asset_index=self.asset_search_index,
+ model_location=loc,
+ model_rotation=rotation,
+ target_object=target_object,
+ material_target_slot=target_slot)
+
+
+ elif ui_props.asset_type == 'MODEL':
+
+ if 'particle_plants' in self.asset_data['tags']:
+ bpy.ops.object.blenderkit_particles_drop("INVOKE_DEFAULT",
+ asset_search_index=self.asset_search_index,
+ model_location=self.snapped_location,
+ model_rotation=self.snapped_rotation,
+ target_object=target_object)
+ else:
+ bpy.ops.scene.blenderkit_download(True,
+ # asset_type=ui_props.asset_type,
+ asset_index=self.asset_search_index,
+ model_location=self.snapped_location,
+ model_rotation=self.snapped_rotation,
+ target_object=target_object)
+
+ else:
+ bpy.ops.scene.blenderkit_download( # asset_type=ui_props.asset_type,
+ asset_index=self.asset_search_index)
+
+ def modal(self, context, event):
+ scene = bpy.context.scene
+ ui_props = scene.blenderkitUI
+ context.area.tag_redraw()
+
+ # if event.type == 'MOUSEMOVE':
+ if not hasattr(self,'start_mouse_x'):
+ self.start_mouse_x = event.mouse_region_x
+ self.start_mouse_y = event.mouse_region_y
+
+ self.mouse_x = event.mouse_region_x
+ self.mouse_y = event.mouse_region_y
+
+ if event.type == 'LEFTMOUSE' and event.value == 'RELEASE':
+ self.mouse_release()
+ self.handlers_remove()
+ return {'FINISHED'}
+
+ elif event.type in {'RIGHTMOUSE', 'ESC'}:
+ self.handlers_remove()
+ return {'CANCELLED'}
+
+ sprops = bpy.context.scene.blenderkit_models
+ if event.type == 'WHEELUPMOUSE':
+ sprops.offset_rotation_amount += sprops.offset_rotation_step
+ elif event.type == 'WHEELDOWNMOUSE':
+ sprops.offset_rotation_amount -= sprops.offset_rotation_step
+
+ #### TODO - this snapping code below is 3x in this file.... refactor it.
+ self.has_hit, self.snapped_location, self.snapped_normal, self.snapped_rotation, self.face_index, object, self.matrix = mouse_raycast(
+ context, event.mouse_region_x, event.mouse_region_y)
+ if object is not None:
+ self.object_name =object.name
+
+
+
+ # MODELS can be dragged on scene floor
+ if not self.has_hit and ui_props.asset_type == 'MODEL':
+ self.has_hit, self.snapped_location, self.snapped_normal, self.snapped_rotation, self.face_index, object, self.matrix = floor_raycast(
+ context,
+ event.mouse_region_x, event.mouse_region_y)
+ if object is not None:
+ self.object_name = object.name
+
+ if ui_props.asset_type == 'MODEL':
+ self.snapped_bbox_min = Vector(self.asset_data['bbox_min'])
+ self.snapped_bbox_max = Vector(self.asset_data['bbox_max'])
+
+ return {'RUNNING_MODAL'}
+
+ def invoke(self, context, event):
+ if context.area.type == 'VIEW_3D':
+ # the arguments we pass the the callback
+ args = (self, context)
+ # Add the region OpenGL drawing callback
+ # draw in view space with 'POST_VIEW' and 'PRE_VIEW'
+ self.iname = utils.previmg_name(self.asset_search_index)
+
+ self._handle = bpy.types.SpaceView3D.draw_handler_add(draw_callback_dragging, args, 'WINDOW', 'POST_PIXEL')
+ self._handle_3d = bpy.types.SpaceView3D.draw_handler_add(draw_callback_3d_dragging, args, 'WINDOW',
+ 'POST_VIEW')
+
+ self.mouse_x = 0
+ self.mouse_y = 0
+
+ self.has_hit = False
+ self.snapped_location = (0,0,0)
+ self.snapped_normal = (0,0,1)
+ self.snapped_rotation = (0,0,0)
+ self.face_index = 0
+ object = None
+ self.matrix = None
+
+ sr = bpy.context.scene['search results']
+ self.asset_data = sr[self.asset_search_index]
+
+ context.window_manager.modal_handler_add(self)
+ return {'RUNNING_MODAL'}
+ else:
+ self.report({'WARNING'}, "View3D not found, cannot run operator")
+ return {'CANCELLED'}
+
+
class RunAssetBarWithContext(bpy.types.Operator):
"""Regenerate cobweb"""
bl_idname = "object.run_assetbar_fix_context"
@@ -1816,13 +1999,19 @@ class RunAssetBarWithContext(bpy.types.Operator):
def execute(self, context):
C_dict = utils.get_fake_context(context)
if C_dict.get('window'): # no 3d view, no asset bar.
- bpy.ops.view3d.blenderkit_asset_bar(C_dict, 'INVOKE_REGION_WIN', keep_running=True, do_search=False)
+ preferences = bpy.context.preferences.addons['blenderkit'].preferences
+ if preferences.experimental_features:
+ bpy.ops.view3d.blenderkit_asset_bar_widget(C_dict, 'INVOKE_REGION_WIN', keep_running=True, do_search=False)
+
+ else:
+ bpy.ops.view3d.blenderkit_asset_bar(C_dict, 'INVOKE_REGION_WIN', keep_running=True, do_search=False)
return {'FINISHED'}
classes = (
AssetBarOperator,
# AssetBarExperiment,
+ AssetDragOperator,
RunAssetBarWithContext,
TransferBlenderkitData,
UndoWithContext,