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/asset_bar_op.py')
-rw-r--r--blenderkit/asset_bar_op.py1034
1 files changed, 0 insertions, 1034 deletions
diff --git a/blenderkit/asset_bar_op.py b/blenderkit/asset_bar_op.py
deleted file mode 100644
index 09124f87..00000000
--- a/blenderkit/asset_bar_op.py
+++ /dev/null
@@ -1,1034 +0,0 @@
-import bpy
-
-from bpy.types import Operator
-
-from blenderkit.bl_ui_widgets.bl_ui_label import *
-from blenderkit.bl_ui_widgets.bl_ui_button import *
-from blenderkit.bl_ui_widgets.bl_ui_image import *
-# from blenderkit.bl_ui_widgets.bl_ui_checkbox import *
-# from blenderkit.bl_ui_widgets.bl_ui_slider import *
-# from blenderkit.bl_ui_widgets.bl_ui_up_down import *
-from blenderkit.bl_ui_widgets.bl_ui_drag_panel import *
-from blenderkit.bl_ui_widgets.bl_ui_draw_op import *
-# from blenderkit.bl_ui_widgets.bl_ui_textbox import *
-import random
-import math
-import time
-
-import blenderkit
-from blenderkit import ui, paths, utils, search, comments_utils
-
-from bpy.props import (
- IntProperty,
- BoolProperty,
- StringProperty
-)
-
-active_area_pointer = 0
-
-
-def get_area_height(self):
- if type(self.context) != dict:
- if self.context is None:
- self.context = bpy.context
- self.context = self.context.copy()
- # print(self.context)
- if self.context.get('area') is not None:
- return self.context['area'].height
- # else:
- # maxw, maxa, region = utils.get_largest_area()
- # if maxa:
- # self.context['area'] = maxa
- # self.context['window'] = maxw
- # self.context['region'] = region
- # self.update(self.x,self.y)
- #
- # return self.context['area'].height
- # print('no area found')
- return 100
-
-
-BL_UI_Widget.get_area_height = get_area_height
-
-
-def modal_inside(self, context, event):
- ui_props = bpy.context.window_manager.blenderkitUI
- if ui_props.turn_off:
- ui_props.turn_off = False
- self.finish()
-
- if self._finished:
- return {'FINISHED'}
-
- if context.area:
- context.area.tag_redraw()
- else:
- self.finish()
- return {'FINISHED'}
-
- self.update_timer += 1
-
- if self.update_timer > self.update_timer_limit:
- self.update_timer = 0
- # print('timer', time.time())
- self.update_images()
-
- # progress bar
- sr = bpy.context.window_manager.get('search results')
- ui_scale = bpy.context.preferences.view.ui_scale
- for asset_button in self.asset_buttons:
- if sr is not None and len(sr) > asset_button.asset_index:
- asset_data = sr[asset_button.asset_index]
-
- if asset_data['downloaded'] > 0:
- asset_button.progress_bar.width = int(self.button_size * ui_scale * asset_data['downloaded'] / 100)
- asset_button.progress_bar.visible = True
- else:
- asset_button.progress_bar.visible = False
-
- if self.handle_widget_events(event):
- return {'RUNNING_MODAL'}
-
- if event.type in {"ESC"}:
- self.finish()
-
- self.mouse_x = event.mouse_region_x
- self.mouse_y = event.mouse_region_y
- if event.type == 'WHEELUPMOUSE' and self.panel.is_in_rect(self.mouse_x, self.mouse_y):
- self.scroll_offset -= 2
- self.scroll_update()
- return {'RUNNING_MODAL'}
-
- elif event.type == 'WHEELDOWNMOUSE' and self.panel.is_in_rect(self.mouse_x, self.mouse_y):
- self.scroll_offset += 2
- self.scroll_update()
- return {'RUNNING_MODAL'}
-
- if self.check_ui_resized(context) or self.check_new_search_results(context):
- # print(self.check_ui_resized(context), print(self.check_new_search_results(context)))
- self.update_ui_size(context)
- self.update_layout(context, event)
-
- # this was here to check if sculpt stroke is running, but obviously that didn't help,
- # since the RELEASE event is cought by operator and thus there is no way to detect a stroke has ended...
- if bpy.context.mode in ('SCULPT', 'PAINT_TEXTURE'):
- if event.type == 'MOUSEMOVE': # ASSUME THAT SCULPT OPERATOR ACTUALLY STEALS THESE EVENTS,
- # SO WHEN THERE ARE SOME WE CAN APPEND BRUSH...
- bpy.context.window_manager['appendable'] = True
- if event.type == 'LEFTMOUSE':
- if event.value == 'PRESS':
- bpy.context.window_manager['appendable'] = False
- return {"PASS_THROUGH"}
-
-
-def asset_bar_modal(self, context, event):
- return modal_inside(self, context, event)
-
-
-def asset_bar_invoke(self, context, event):
- if not self.on_invoke(context, event):
- return {"CANCELLED"}
-
- args = (self, context)
-
- self.register_handlers(args, context)
-
- self.update_timer_limit = 30
- self.update_timer = 0
- # print('adding timer')
- # self._timer = context.window_manager.event_timer_add(10.0, window=context.window)
- global active_area_pointer
- context.window_manager.modal_handler_add(self)
- self.active_window_pointer = context.window.as_pointer()
- self.active_area_pointer = context.area.as_pointer()
- active_area_pointer = context.area.as_pointer()
- self.active_region_pointer = context.region.as_pointer()
-
- return {"RUNNING_MODAL"}
-
-
-BL_UI_OT_draw_operator.modal = asset_bar_modal
-BL_UI_OT_draw_operator.invoke = asset_bar_invoke
-
-
-def set_mouse_down_right(self, mouse_down_right_func):
- self.mouse_down_right_func = mouse_down_right_func
-
-
-def mouse_down_right(self, x, y):
- if self.is_in_rect(x, y):
- self.__state = 1
- try:
- self.mouse_down_right_func(self)
- except Exception as e:
- print(e)
-
- return True
-
- return False
-
-
-BL_UI_Button.mouse_down_right = mouse_down_right
-BL_UI_Button.set_mouse_down_right = set_mouse_down_right
-
-asset_bar_operator = None
-
-
-# BL_UI_Button.handle_event = handle_event
-
-def get_tooltip_data(asset_data):
- gimg = None
- tooltip_data = asset_data.get('tooltip_data')
- if tooltip_data is None:
- author_text = ''
-
- 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']).name
-
- if len(a['firstName']) > 0 or len(a['lastName']) > 0:
- author_text = f"by {a['firstName']} {a['lastName']}"
-
- aname = asset_data['displayName']
- aname = aname[0].upper() + aname[1:]
- if len(aname) > 36:
- aname = f"{aname[:33]}..."
-
- rc = asset_data.get('ratingsCount')
- show_rating_threshold = 0
- rcount = 0
- quality = '-'
- if rc:
- rcount = min(rc.get('quality', 0), rc.get('workingHours', 0))
- if rcount > show_rating_threshold:
- quality = str(round(asset_data['ratingsAverage'].get('quality')))
- tooltip_data = {
- 'aname': aname,
- 'author_text': author_text,
- 'quality': quality,
- 'gimg': gimg
- }
- asset_data['tooltip_data'] = tooltip_data
- gimg = tooltip_data['gimg']
- if gimg is not None:
- gimg = bpy.data.images[gimg]
-
-
-class BlenderKitAssetBarOperator(BL_UI_OT_draw_operator):
- bl_idname = "view3d.blenderkit_asset_bar_widget"
- bl_label = "BlenderKit asset bar refresh"
- bl_description = "BlenderKit asset bar refresh"
- bl_options = {'REGISTER'}
-
- do_search: BoolProperty(name="Run Search", description='', default=True, options={'SKIP_SAVE'})
- keep_running: BoolProperty(name="Keep Running", description='', default=True, options={'SKIP_SAVE'})
- free_only: BoolProperty(name="Free first", description='', default=False, options={'SKIP_SAVE'})
-
- category: StringProperty(
- name="Category",
- description="search only subtree of this category",
- default="", options={'SKIP_SAVE'})
-
- tooltip: bpy.props.StringProperty(default='Runs search and displays the asset bar at the same time')
-
- @classmethod
- def description(cls, context, properties):
- return properties.tooltip
-
- def new_text(self, text, x, y, width=100, height=15, text_size=None, halign='LEFT'):
- label = BL_UI_Label(x, y, width, height)
- label.text = text
- if text_size is None:
- text_size = 14
- label.text_size = text_size
- label.text_color = self.text_color
- label._halign = halign
- return label
-
- def init_tooltip(self):
- self.tooltip_widgets = []
- self.tooltip_height = self.tooltip_size
- self.tooltip_width = self.tooltip_size
- ui_props = bpy.context.window_manager.blenderkitUI
- if ui_props.asset_type == 'HDR':
- self.tooltip_width = self.tooltip_size * 2
- # total_size = tooltip# + 2 * self.margin
- self.tooltip_panel = BL_UI_Drag_Panel(0, 0, self.tooltip_width, self.tooltip_height)
- self.tooltip_panel.bg_color = (0.0, 0.0, 0.0, 0.5)
- self.tooltip_panel.visible = False
-
- tooltip_image = BL_UI_Image(0, 0, 1, 1)
- img_path = paths.get_addon_thumbnail_path('thumbnail_notready.jpg')
- tooltip_image.set_image(img_path)
- tooltip_image.set_image_size((self.tooltip_width, self.tooltip_height))
- tooltip_image.set_image_position((0, 0))
- self.tooltip_image = tooltip_image
- self.tooltip_widgets.append(tooltip_image)
-
- bottom_panel_fraction = 0.15
- labels_start = self.tooltip_height * (1 - bottom_panel_fraction)
-
- dark_panel = BL_UI_Widget(0, labels_start, self.tooltip_width, self.tooltip_height * bottom_panel_fraction)
- dark_panel.bg_color = (0.0, 0.0, 0.0, 0.7)
- self.tooltip_dark_panel = dark_panel
- self.tooltip_widgets.append(dark_panel)
-
- name_label = self.new_text('', self.margin, labels_start + self.margin,
- text_size=self.asset_name_text_size)
- self.asset_name = name_label
- self.tooltip_widgets.append(name_label)
-
- self.gravatar_size = int(self.tooltip_height * bottom_panel_fraction - self.margin)
-
- authors_name = self.new_text('author', self.tooltip_width - self.gravatar_size - self.margin,
- self.tooltip_height - self.author_text_size - self.margin, labels_start,
- text_size=self.author_text_size, halign='RIGHT')
- self.authors_name = authors_name
- self.tooltip_widgets.append(authors_name)
-
- gravatar_image = BL_UI_Image(self.tooltip_width - self.gravatar_size, self.tooltip_height - self.gravatar_size,
- 1, 1)
- img_path = paths.get_addon_thumbnail_path('thumbnail_notready.jpg')
- gravatar_image.set_image(img_path)
- gravatar_image.set_image_size((self.gravatar_size - 1 * self.margin, self.gravatar_size - 1 * self.margin))
- gravatar_image.set_image_position((0, 0))
- self.gravatar_image = gravatar_image
- self.tooltip_widgets.append(gravatar_image)
-
- quality_star = BL_UI_Image(self.margin, self.tooltip_height - self.margin - self.asset_name_text_size,
- 1, 1)
- img_path = paths.get_addon_thumbnail_path('star_grey.png')
- quality_star.set_image(img_path)
- quality_star.set_image_size((self.asset_name_text_size, self.asset_name_text_size))
- quality_star.set_image_position((0, 0))
- # self.quality_star = quality_star
- self.tooltip_widgets.append(quality_star)
- label = self.new_text('', 2 * self.margin + self.asset_name_text_size,
- self.tooltip_height - int(self.asset_name_text_size + self.margin * .5),
- text_size=self.asset_name_text_size)
- self.tooltip_widgets.append(label)
- self.quality_label = label
-
- # label = self.new_text('Right click for menu.', self.margin,
- # self.tooltip_height - int(self.author_text_size) - self.margin,
- # text_size=int(self.author_text_size*.7))
- # self.tooltip_widgets.append(label)
-
- def hide_tooltip(self):
- self.tooltip_panel.visible = False
- for w in self.tooltip_widgets:
- w.visible = False
-
- def show_tooltip(self):
- self.tooltip_panel.visible = True
- for w in self.tooltip_widgets:
- w.visible = True
-
- def show_notifications(self, widget):
- bpy.ops.wm.show_notifications()
- if comments_utils.check_notifications_read():
- widget.visible = False
-
- def check_new_search_results(self, context):
- sr = bpy.context.window_manager.get('search results')
- if not hasattr(self, 'search_results_count'):
- if not sr:
- self.search_results_count = 0
- return True
-
- self.search_results_count = len(sr)
-
- if sr is not None and len(sr) != self.search_results_count:
- self.search_results_count = len(sr)
- return True
- return False
-
- def get_region_size(self, context):
- # just check the size of region..
-
- region = context.region
- area = context.area
- ui_width = 0
- tools_width = 0
- for r in area.regions:
- if r.type == 'UI':
- ui_width = r.width
- if r.type == 'TOOLS':
- tools_width = r.width
- total_width = region.width - tools_width - ui_width
- return total_width, region.height
-
- def check_ui_resized(self, context):
- # TODO this should only check if region was resized, not really care about the UI elements size.
- region_width, region_height = self.get_region_size(context)
-
- if not hasattr(self, 'total_width'):
- self.total_width = region_width
- self.region_height = region_height
-
- if region_height != self.region_height or region_width != self.total_width:
- self.region_height = region_height
- self.total_width = region_width
- return True
- return False
-
- def update_ui_size(self, context):
-
- if bpy.app.background or not context.area:
- return
-
- region = context.region
- area = context.area
-
- ui_props = bpy.context.window_manager.blenderkitUI
- user_preferences = bpy.context.preferences.addons['blenderkit'].preferences
- ui_scale = bpy.context.preferences.view.ui_scale
-
- self.margin = ui_props.bl_rna.properties['margin'].default * ui_scale
- self.margin = int(9 * ui_scale)
- self.button_margin = int(0 * ui_scale)
- self.asset_name_text_size = int(20 * ui_scale)
- self.author_text_size = int(self.asset_name_text_size * .7 * ui_scale)
- self.assetbar_margin = int(2 * ui_scale)
- self.tooltip_size = int(512 * ui_scale)
-
- if ui_props.asset_type == 'HDR':
- self.tooltip_width = self.tooltip_size * 2
- else:
- self.tooltip_width = self.tooltip_size
-
- self.thumb_size = user_preferences.thumb_size * ui_scale
- self.button_size = 2 * self.button_margin + self.thumb_size
- self.other_button_size = 30 * ui_scale
- self.icon_size = 24 * ui_scale
- self.validation_icon_margin = 3 * ui_scale
- reg_multiplier = 1
- if not bpy.context.preferences.system.use_region_overlap:
- reg_multiplier = 0
-
- ui_width = 0
- tools_width = 0
- reg_multiplier = 1
- if not bpy.context.preferences.system.use_region_overlap:
- reg_multiplier = 0
- for r in area.regions:
- if r.type == 'UI':
- ui_width = r.width * reg_multiplier
- if r.type == 'TOOLS':
- tools_width = r.width * reg_multiplier
- self.bar_x = tools_width + self.margin + ui_props.bar_x_offset * ui_scale
- self.bar_end = ui_width + 180 * ui_scale + self.other_button_size
- self.bar_width = region.width - self.bar_x - self.bar_end
-
- self.wcount = math.floor((self.bar_width) / (self.button_size))
-
- self.max_hcount = math.floor(context.window.width / self.button_size)
- self.max_wcount = user_preferences.max_assetbar_rows
-
- search_results = bpy.context.window_manager.get('search results')
- # we need to init all possible thumb previews in advance/
- # self.hcount = user_preferences.max_assetbar_rows
- if search_results is not None and self.wcount > 0:
- self.hcount = min(user_preferences.max_assetbar_rows, math.ceil(len(search_results) / self.wcount))
- self.hcount = max(self.hcount, 1)
- else:
- self.hcount = 1
-
- self.bar_height = (self.button_size) * self.hcount + 2 * self.assetbar_margin
- # self.bar_y = region.height - ui_props.bar_y_offset * ui_scale
- self.bar_y = ui_props.bar_y_offset * ui_scale
- if ui_props.down_up == 'UPLOAD':
- self.reports_y = region.height - self.bar_y - 600
- ui_props.reports_y = region.height - self.bar_y - 600
- self.reports_x = self.bar_x
- ui_props.reports_x = self.bar_x
- else: # ui.bar_y - ui.bar_height - 100
-
- self.reports_y = region.height - self.bar_y - self.bar_height - 50
- ui_props.reports_y = region.height - self.bar_y - self.bar_height - 50
- self.reports_x = self.bar_x
- ui_props.reports_x = self.bar_x
- # print(self.bar_y, self.bar_height, region.height)
-
- def update_layout(self, context, event):
- # restarting asset_bar completely since the widgets are too hard to get working with updates.
-
- self.position_and_hide_buttons()
- self.scroll_update()
-
- self.button_close.set_location(self.bar_width - self.other_button_size, -self.other_button_size)
- if hasattr(self, 'button_notifications'):
- self.button_notifications.set_location(self.bar_width - self.other_button_size * 2, -self.other_button_size)
- self.button_scroll_up.set_location(self.bar_width, 0)
- self.panel.width = self.bar_width
- self.panel.height = self.bar_height
-
- self.panel.set_location(self.bar_x, self.panel.y)
-
- # update Tooltip size
- if self.tooltip_dark_panel.width != self.tooltip_width:
- self.tooltip_dark_panel.width = self.tooltip_width
- self.tooltip_panel.width = self.tooltip_width
- self.tooltip_image.width = self.tooltip_width
- self.tooltip_image.set_image_size((self.tooltip_width, self.tooltip_height))
- self.gravatar_image.set_location(self.tooltip_width - self.gravatar_size,
- self.tooltip_height - self.gravatar_size)
- self.authors_name.set_location(self.tooltip_width - self.gravatar_size - self.margin,
- self.tooltip_height - self.author_text_size - self.margin)
-
- # to hide arrows accordingly
-
- def asset_button_init(self, asset_x, asset_y, button_idx):
- ui_scale = bpy.context.preferences.view.ui_scale
-
- button_bg_color = (0.2, 0.2, 0.2, .1)
- button_hover_color = (0.8, 0.8, 0.8, .2)
-
- new_button = BL_UI_Button(asset_x, asset_y, self.button_size, self.button_size)
-
- # asset_data = sr[asset_idx]
- # iname = blenderkit.utils.previmg_name(asset_idx)
- # img = bpy.data.images.get(iname)
-
- new_button.bg_color = button_bg_color
- new_button.hover_bg_color = button_hover_color
- new_button.text = "" # asset_data['name']
- # if img:
- # new_button.set_image(img.filepath)
-
- new_button.set_image_size((self.thumb_size, self.thumb_size))
- new_button.set_image_position((self.button_margin, self.button_margin))
- new_button.button_index = button_idx
- new_button.search_index = button_idx
- new_button.set_mouse_down(self.drag_drop_asset)
- new_button.set_mouse_down_right(self.asset_menu)
- new_button.set_mouse_enter(self.enter_button)
- new_button.set_mouse_exit(self.exit_button)
- new_button.text_input = self.handle_key_input
- # add validation icon to button
-
- validation_icon = BL_UI_Image(
- asset_x + self.button_size - self.icon_size - self.button_margin - self.validation_icon_margin,
- asset_y + self.button_size - self.icon_size - self.button_margin - self.validation_icon_margin, 0, 0)
-
- # v_icon = ui.verification_icons[asset_data.get('verificationStatus', 'validated')]
- # if v_icon is not None:
- # img_fp = paths.get_addon_thumbnail_path(v_icon)
- # validation_icon.set_image(img_fp)
- validation_icon.set_image_size((self.icon_size, self.icon_size))
- validation_icon.set_image_position((0, 0))
- self.validation_icons.append(validation_icon)
- new_button.validation_icon = validation_icon
-
- progress_bar = BL_UI_Widget(asset_x, asset_y + self.button_size - 3, self.button_size, 3)
- progress_bar.bg_color = (0.0, 1.0, 0.0, 0.3)
- new_button.progress_bar = progress_bar
- self.progress_bars.append(progress_bar)
-
- if utils.profile_is_validator():
- red_alert = BL_UI_Widget(asset_x, asset_y, self.button_size, self.button_size)
- red_alert.bg_color = (1.0, 0.0, 0.0, 0.0)
- red_alert.visible = False
- new_button.red_alert = red_alert
- self.red_alerts.append(red_alert)
- # if result['downloaded'] > 0:
- # ui_bgl.draw_rect(x, y, int(ui_props.thumb_size * result['downloaded'] / 100.0), 2, green)
-
- return new_button
-
- def init_ui(self):
- ui_scale = bpy.context.preferences.view.ui_scale
-
- button_bg_color = (0.2, 0.2, 0.2, .1)
- button_hover_color = (0.8, 0.8, 0.8, .2)
-
- self.buttons = []
- self.asset_buttons = []
- self.validation_icons = []
- self.progress_bars = []
- self.red_alerts = []
- self.widgets_panel = []
-
- self.panel = BL_UI_Drag_Panel(0, 0, self.bar_width, self.bar_height)
- self.panel.bg_color = (0.0, 0.0, 0.0, 0.5)
-
- # sr = bpy.context.window_manager.get('search results', [])
- # if sr is not None:
- # we init max possible buttons.
- button_idx = 0
- for x in range(0, self.max_wcount):
- for y in range(0, self.max_hcount):
- # asset_x = self.assetbar_margin + a * (self.button_size)
- # asset_y = self.assetbar_margin + b * (self.button_size)
- # button_idx = x + y * self.max_wcount
- asset_idx = button_idx + self.scroll_offset
- # if asset_idx < len(sr):
- new_button = self.asset_button_init(0, 0, button_idx)
- new_button.asset_index = asset_idx
- self.asset_buttons.append(new_button)
- button_idx += 1
-
- self.button_close = BL_UI_Button(self.bar_width - self.other_button_size, -self.other_button_size,
- self.other_button_size,
- self.other_button_size)
- self.button_close.bg_color = button_bg_color
- self.button_close.hover_bg_color = button_hover_color
- self.button_close.text = ""
- img_fp = paths.get_addon_thumbnail_path('vs_rejected.png')
- self.button_close.set_image(img_fp)
- self.button_close.set_mouse_down(self.cancel_press)
-
- self.widgets_panel.append(self.button_close)
-
- self.scroll_width = 30
- self.button_scroll_down = BL_UI_Button(-self.scroll_width, 0, self.scroll_width, self.bar_height)
- self.button_scroll_down.bg_color = button_bg_color
- self.button_scroll_down.hover_bg_color = button_hover_color
- self.button_scroll_down.text = ""
- self.button_scroll_down.set_image(paths.get_addon_thumbnail_path('arrow_left.png'))
- self.button_scroll_down.set_image_size((self.scroll_width, self.button_size))
- self.button_scroll_down.set_image_position((0, int((self.bar_height - self.button_size) / 2)))
-
- self.button_scroll_down.set_mouse_down(self.scroll_down)
-
- self.widgets_panel.append(self.button_scroll_down)
-
- self.button_scroll_up = BL_UI_Button(self.bar_width, 0, self.scroll_width, self.bar_height)
- self.button_scroll_up.bg_color = button_bg_color
- self.button_scroll_up.hover_bg_color = button_hover_color
- self.button_scroll_up.text = ""
- self.button_scroll_up.set_image(paths.get_addon_thumbnail_path('arrow_right.png'))
- self.button_scroll_up.set_image_size((self.scroll_width, self.button_size))
- self.button_scroll_up.set_image_position((0, int((self.bar_height - self.button_size) / 2)))
-
- self.button_scroll_up.set_mouse_down(self.scroll_up)
-
- self.widgets_panel.append(self.button_scroll_up)
-
- # notifications
- if not comments_utils.check_notifications_read():
- self.button_notifications = BL_UI_Button(self.bar_width - self.other_button_size * 2,
- -self.other_button_size, self.other_button_size,
- self.other_button_size)
- self.button_notifications.bg_color = button_bg_color
- self.button_notifications.hover_bg_color = button_hover_color
- self.button_notifications.text = ""
- img_fp = paths.get_addon_thumbnail_path('bell.png')
- self.button_notifications.set_image(img_fp)
- self.button_notifications.set_mouse_down(self.show_notifications)
- self.widgets_panel.append(self.button_notifications)
-
- self.update_images()
-
- def position_and_hide_buttons(self):
- # position and layout buttons
- sr = bpy.context.window_manager.get('search results', [])
- if sr is None:
- sr = []
-
- i = 0
- for y in range(0, self.hcount):
- for x in range(0, self.wcount):
- asset_x = self.assetbar_margin + x * (self.button_size)
- asset_y = self.assetbar_margin + y * (self.button_size)
- button_idx = x + y * self.wcount
- asset_idx = button_idx + self.scroll_offset
- if len(self.asset_buttons) <= button_idx:
- break
- button = self.asset_buttons[button_idx]
- button.set_location(asset_x, asset_y)
- button.validation_icon.set_location(
- asset_x + self.button_size - self.icon_size - self.button_margin - self.validation_icon_margin,
- asset_y + self.button_size - self.icon_size - self.button_margin - self.validation_icon_margin)
- button.progress_bar.set_location(asset_x, asset_y + self.button_size - 3)
- if asset_idx < len(sr):
- button.visible = True
- button.validation_icon.visible = True
- # button.progress_bar.visible = True
- else:
- button.visible = False
- button.validation_icon.visible = False
- button.progress_bar.visible = False
- if utils.profile_is_validator():
- button.red_alert.set_location(asset_x, asset_y)
- i += 1
-
- for a in range(i, len(self.asset_buttons)):
- button = self.asset_buttons[a]
- button.visible = False
- button.validation_icon.visible = False
- button.progress_bar.visible = False
-
- self.button_scroll_down.height = self.bar_height
- self.button_scroll_down.set_image_position((0, int((self.bar_height - self.button_size) / 2)))
- self.button_scroll_down.height = self.bar_height
- self.button_scroll_down.set_image_position((0, int((self.bar_height - self.button_size) / 2)))
-
- def __init__(self):
- super().__init__()
-
- self.update_ui_size(bpy.context)
-
- # todo move all this to update UI size
- ui_props = bpy.context.window_manager.blenderkitUI
-
- self.draw_tooltip = False
- # let's take saved scroll offset and use it to keep scroll between operator runs
- self.scroll_offset = ui_props.scroll_offset
-
- self.text_color = (0.9, 0.9, 0.9, 1.0)
-
- self.init_ui()
- self.init_tooltip()
- self.hide_tooltip()
-
- def setup_widgets(self, context, event):
- widgets_panel = []
- widgets_panel.extend(self.widgets_panel)
- widgets_panel.extend(self.buttons)
- widgets_panel.extend(self.asset_buttons)
- widgets_panel.extend(self.validation_icons)
- widgets_panel.extend(self.progress_bars)
- widgets_panel.extend(self.red_alerts)
-
- widgets = [self.panel]
-
- widgets += widgets_panel
- widgets.append(self.tooltip_panel)
- widgets += self.tooltip_widgets
-
- self.init_widgets(context, widgets)
- self.panel.add_widgets(widgets_panel)
- self.tooltip_panel.add_widgets(self.tooltip_widgets)
-
- def on_invoke(self, context, event):
-
- self.context = context
-
- if self.do_search or context.window_manager.get('search results') is None:
- # TODO: move the search behaviour to separate operator, since asset bar can be already woken up from a timer.
-
- # we erase search keywords for cateogry search now, since these combinations usually return nothing now.
- # when the db gets bigger, this can be deleted.
- if self.category != '':
- sprops = utils.get_search_props()
- sprops.search_keywords = ''
- search.search(category=self.category)
-
- ui_props = context.window_manager.blenderkitUI
- if ui_props.assetbar_on:
- # TODO solve this otehrwise to enable more asset bars?
-
- # we don't want to run the assetbar many times, that's why it has a switch on/off behaviour,
- # unless being called with 'keep_running' prop.
-
- if not self.keep_running:
- # this sends message to the originally running operator, so it quits, and then it ends this one too.
- # If it initiated a search, the search will finish in a thread. The switch off procedure is run
- # by the 'original' operator, since if we get here, it means
- # same operator is already running.
- ui_props.turn_off = True
- # if there was an error, we need to turn off these props so we can restart after 2 clicks
- ui_props.assetbar_on = False
-
- else:
- pass
- return False
-
- ui_props.assetbar_on = True
- global asset_bar_operator
-
- asset_bar_operator = self
-
- self.active_index = -1
-
- self.setup_widgets(context, event)
- self.position_and_hide_buttons()
- self.hide_tooltip()
-
- self.panel.set_location(self.bar_x,
- self.bar_y)
- # to hide arrows accordingly
- self.scroll_update()
-
- self.window = context.window
- self.area = context.area
- self.scene = bpy.context.scene
- # global active_window_pointer, active_area_pointer, active_region_pointer
- # ui.active_window_pointer = self.window.as_pointer()
- # ui.active_area_pointer = self.area.as_pointer()
- # ui.active_region_pointer = self.region.as_pointer()
-
- return True
-
- def on_finish(self, context):
- # redraw all areas, since otherwise it stays to hang for some more time.
- # bpy.types.SpaceView3D.draw_handler_remove(self._handle_2d_tooltip, 'WINDOW')
- # to pass the operator to validation icons
- global asset_bar_operator
- asset_bar_operator = None
-
- # context.window_manager.event_timer_remove(self._timer)
-
- scene = bpy.context.scene
- ui_props = bpy.context.window_manager.blenderkitUI
- ui_props.assetbar_on = False
- ui_props.scroll_offset = self.scroll_offset
-
- wm = bpy.data.window_managers[0]
-
- for w in wm.windows:
- for a in w.screen.areas:
- a.tag_redraw()
- self._finished = True
-
- # handlers
-
- def enter_button(self, widget):
- # print('enter button', self.active_index, widget.button_index)
- # print(widget.button_index+ self.scroll_offset, self.active_index)
- search_index = widget.button_index + self.scroll_offset
- if search_index < self.search_results_count:
- self.show_tooltip()
- # print(self.active_index, search_index)
- if self.active_index != search_index:
- self.active_index = search_index
-
- scene = bpy.context.scene
- wm = bpy.context.window_manager
- sr = wm['search results']
- asset_data = sr[search_index] # + self.scroll_offset]
-
- self.draw_tooltip = True
- # self.tooltip = asset_data['tooltip']
- ui_props = bpy.context.window_manager.blenderkitUI
- ui_props.active_index = search_index # + self.scroll_offset
-
- img = ui.get_large_thumbnail_image(asset_data)
- if img:
- self.tooltip_image.set_image(img.filepath)
-
- get_tooltip_data(asset_data)
- an = asset_data['name']
- max_name_length = 30
- if len(an) > max_name_length + 3:
- an = an[:30] + '...'
- self.asset_name.text = an
- self.authors_name.text = asset_data['tooltip_data']['author_text']
- self.quality_label.text = asset_data['tooltip_data']['quality']
- # print(asset_data['tooltip_data']['quality'])
- gimg = asset_data['tooltip_data']['gimg']
- if gimg is not None:
- gimg = bpy.data.images[gimg]
- if gimg:
- self.gravatar_image.set_image(gimg.filepath
- )
- # print('moving tooltip')
- properties_width = 0
- for r in bpy.context.area.regions:
- if r.type == 'UI':
- properties_width = r.width
- tooltip_x = min(int(widget.x_screen),
- int(bpy.context.region.width - self.tooltip_panel.width - properties_width))
- tooltip_y = int(widget.y_screen + widget.height)
- # self.init_tooltip()
- self.tooltip_panel.set_location(tooltip_x, tooltip_y)
- self.tooltip_panel.layout_widgets()
- # print(tooltip_x, tooltip_y)
- # bpy.ops.wm.blenderkit_asset_popup('INVOKE_DEFAULT')
-
- def exit_button(self, widget):
- # print(f'exit {widget.search_index} , {self.active_index}')
- # this condition checks if there wasn't another button already entered, which can happen with small button gaps
- if self.active_index == widget.button_index + self.scroll_offset:
- scene = bpy.context.scene
- ui_props = bpy.context.window_manager.blenderkitUI
- ui_props.draw_tooltip = False
- self.draw_tooltip = False
- self.hide_tooltip()
- # popup asset card on mouse down
- # if utils.experimental_enabled():
- # h = widget.get_area_height()
- # print(h,h-self.mouse_y,self.panel.y_screen, self.panel.y,widget.y_screen, widget.y)
- # if utils.experimental_enabled() and self.mouse_y<widget.y_screen:
- # self.active_index = widget.button_index + self.scroll_offset
- # bpy.ops.wm.blenderkit_asset_popup('INVOKE_DEFAULT')
-
- def drag_drop_asset(self, widget):
- bpy.ops.view3d.asset_drag_drop('INVOKE_DEFAULT', asset_search_index=widget.search_index + self.scroll_offset)
-
- def cancel_press(self, widget):
- self.finish()
-
- def asset_menu(self, widget):
- self.hide_tooltip()
- bpy.ops.wm.blenderkit_asset_popup('INVOKE_DEFAULT')
- # bpy.ops.wm.call_menu(name='OBJECT_MT_blenderkit_asset_menu')
-
- def search_more(self):
- sro = bpy.context.window_manager.get('search results orig')
- if sro is None:
- return
- if sro.get('next') is None:
- return
- search_props = utils.get_search_props()
- if search_props.is_searching:
- return
-
- blenderkit.search.search(get_next=True)
-
- def update_validation_icon(self, asset_button, asset_data):
- if utils.profile_is_validator():
- ar = bpy.context.window_manager.get('asset ratings')
- rating = ar.get(asset_data['id'])
- if rating is not None:
- rating = rating.to_dict()
-
- v_icon = ui.verification_icons[asset_data.get('verificationStatus', 'validated')]
- if v_icon is not None:
- img_fp = paths.get_addon_thumbnail_path(v_icon)
- asset_button.validation_icon.set_image(img_fp)
- asset_button.validation_icon.visible = True
- elif rating in (None, {}):
- v_icon = 'star_grey.png'
- img_fp = paths.get_addon_thumbnail_path(v_icon)
- asset_button.validation_icon.set_image(img_fp)
- asset_button.validation_icon.visible = True
- else:
- asset_button.validation_icon.visible = False
- else:
- if asset_data.get('canDownload', True) == 0:
- img_fp = paths.get_addon_thumbnail_path('locked.png')
- asset_button.validation_icon.set_image(img_fp)
- else:
- asset_button.validation_icon.visible = False
-
- def update_images(self):
- sr = bpy.context.window_manager.get('search results')
- if not sr:
- return
- for asset_button in self.asset_buttons:
- if asset_button.visible:
- asset_button.asset_index = asset_button.button_index + self.scroll_offset
- # print(asset_button.asset_index, len(sr))
- if asset_button.asset_index < len(sr):
- asset_button.visible = True
-
- asset_data = sr[asset_button.asset_index]
- if asset_data is None:
- continue
- iname = blenderkit.utils.previmg_name(asset_button.asset_index)
- # show indices for debug purposes
- # asset_button.text = str(asset_button.asset_index)
- img = bpy.data.images.get(iname)
- if img is None or len(img.pixels) == 0:
- img_filepath = paths.get_addon_thumbnail_path('thumbnail_notready.jpg')
- else:
- img_filepath = img.filepath
- # print(asset_button.button_index, img_filepath)
-
- asset_button.set_image(img_filepath)
- self.update_validation_icon(asset_button, asset_data)
-
- if utils.profile_is_validator() and asset_data['verificationStatus'] == 'uploaded':
- over_limit = utils.is_upload_old(asset_data)
- if over_limit:
- redness = min(over_limit * .05, 0.7)
- asset_button.red_alert.bg_color = (1, 0, 0, redness)
- asset_button.red_alert.visible = True
- else:
- asset_button.red_alert.visible = False
- elif utils.profile_is_validator():
- asset_button.red_alert.visible = False
- else:
- asset_button.visible = False
- asset_button.validation_icon.visible = False
- if utils.profile_is_validator():
- asset_button.red_alert.visible = False
-
- def scroll_update(self):
- sr = bpy.context.window_manager.get('search results')
- sro = bpy.context.window_manager.get('search results orig')
- # empty results
- if sr is None:
- self.button_scroll_down.visible = False
- self.button_scroll_up.visible = False
- return
-
- self.scroll_offset = min(self.scroll_offset, len(sr) - (self.wcount * self.hcount))
- self.scroll_offset = max(self.scroll_offset, 0)
- self.update_images()
-
- # print(sro)
- if sro['count'] > len(sr) and len(sr) - self.scroll_offset < (self.wcount * self.hcount) + 15:
- self.search_more()
-
- if self.scroll_offset == 0:
- self.button_scroll_down.visible = False
- else:
- self.button_scroll_down.visible = True
-
- if self.scroll_offset >= sro['count'] - (self.wcount * self.hcount):
- self.button_scroll_up.visible = False
- else:
- self.button_scroll_up.visible = True
-
- def search_by_author(self, asset_index):
- sr = bpy.context.window_manager['search results']
- asset_data = sr[asset_index]
- a = asset_data['author']['id']
- if a is not None:
- sprops = utils.get_search_props()
- sprops.search_keywords = ''
- sprops.search_verification_status = 'ALL'
- # utils.p('author:', a)
- search.search(author_id=a)
- return True
-
- def handle_key_input(self, event):
- if event.type == 'A':
- self.search_by_author(self.active_index)
- return True
- if event.type == 'X' and self.active_index > -1:
- # delete downloaded files for this asset
- sr = bpy.context.window_manager['search results']
- asset_data = sr[self.active_index]
- print('delete asset from local drive:' + asset_data['name'])
- paths.delete_asset_debug(asset_data)
- asset_data['downloaded'] = 0
- return True
- if event.type == 'W' and self.active_index > -1:
- sr = bpy.context.window_manager['search results']
- asset_data = sr[self.active_index]
- a = bpy.context.window_manager['bkit authors'].get(asset_data['author']['id'])
- if a is not None:
- utils.p('author:', a)
- if a.get('aboutMeUrl') is not None:
- bpy.ops.wm.url_open(url=a['aboutMeUrl'])
- return True
- # FastRateMenu
- if event.type == 'R' and self.active_index > -1:
- sr = bpy.context.window_manager['search results']
- asset_data = sr[self.active_index]
- if not utils.user_is_owner(asset_data=asset_data):
- bpy.ops.wm.blenderkit_menu_rating_upload(asset_name = asset_data['name'], asset_id =asset_data['id'], asset_type = asset_data['assetType'])
- return True
- return False
-
- def scroll_up(self, widget):
- self.scroll_offset += self.wcount * self.hcount
- self.scroll_update()
-
- def scroll_down(self, widget):
- self.scroll_offset -= self.wcount * self.hcount
- self.scroll_update()
-
-
-def register():
- bpy.utils.register_class(BlenderKitAssetBarOperator)
-
-
-def unregister():
- bpy.utils.unregister_class(BlenderKitAssetBarOperator)