diff options
author | Vilem Duha <vilem.duha@gmail.com> | 2021-10-22 09:24:39 +0300 |
---|---|---|
committer | Vilem Duha <vilem.duha@gmail.com> | 2021-10-22 09:24:39 +0300 |
commit | 259ab9a873cbd66d8dd57d2ec730bf77548f2a6f (patch) | |
tree | 738f983e60b11f74e03391b50795cd846a24a4dd | |
parent | 79a0f96101e3e098f76ce22a88b320f6c831b7b5 (diff) |
BlenderKit lots of fixes for asset bar
lock icons are back
thumbnail update partially fixed.
-rw-r--r-- | blenderkit/asset_bar_op.py | 56 | ||||
-rw-r--r-- | blenderkit/comments_utils.py | 36 | ||||
-rw-r--r-- | blenderkit/search.py | 33 | ||||
-rw-r--r-- | blenderkit/ui.py | 2 | ||||
-rw-r--r-- | blenderkit/ui_panels.py | 32 | ||||
-rw-r--r-- | blenderkit/utils.py | 1 |
6 files changed, 108 insertions, 52 deletions
diff --git a/blenderkit/asset_bar_op.py b/blenderkit/asset_bar_op.py index 2a2ff4e8..403eb039 100644 --- a/blenderkit/asset_bar_op.py +++ b/blenderkit/asset_bar_op.py @@ -24,14 +24,6 @@ from bpy.props import ( ) -def draw_callback_tooltip(self, context): - if self.draw_tooltip: - wm = bpy.context.window_manager - sr = wm.get('search results') - r = sr[self.active_index] - ui.draw_tooltip_with_author(r, 0, 500) - - def get_area_height(self): if type(self.context) != dict: if self.context is None: @@ -90,14 +82,14 @@ def modal_inside(self,context,event): if event.type in {"ESC"}: self.finish() - x = event.mouse_region_x - y = event.mouse_region_y - if event.type == 'WHEELUPMOUSE' and self.panel.is_in_rect(x, y): + 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 -= 5 self.scroll_update() return {'RUNNING_MODAL'} - elif event.type == 'WHEELDOWNMOUSE' and self.panel.is_in_rect(x, y): + elif event.type == 'WHEELDOWNMOUSE' and self.panel.is_in_rect(self.mouse_x, self.mouse_y): self.scroll_offset += 5 self.scroll_update() return {'RUNNING_MODAL'} @@ -409,7 +401,9 @@ class BlenderKitAssetBarOperator(BL_UI_OT_draw_operator): self.position_and_hide_buttons() - self.button_close.set_location(self.bar_width - self.other_button_size, 0) + 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 @@ -543,7 +537,7 @@ class BlenderKitAssetBarOperator(BL_UI_OT_draw_operator): #notifications if not comments_utils.check_notifications_read(): - self.button_notifications = BL_UI_Button(self.bar_width - self.other_button_size, self.bar_height, self.other_button_size, + 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 @@ -568,6 +562,8 @@ class BlenderKitAssetBarOperator(BL_UI_OT_draw_operator): 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( @@ -738,11 +734,11 @@ class BlenderKitAssetBarOperator(BL_UI_OT_draw_operator): for r in bpy.context.area.regions: if r.type == 'UI': properties_width = r.width - tooltip_x = min(int(widget.x_screen + widget.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.update(tooltip_x, tooltip_y) + 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') @@ -756,6 +752,13 @@ class BlenderKitAssetBarOperator(BL_UI_OT_draw_operator): 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) @@ -781,13 +784,20 @@ class BlenderKitAssetBarOperator(BL_UI_OT_draw_operator): blenderkit.search.search(get_next=True) def update_validation_icon(self, asset_button, asset_data): - 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 + if utils.profile_is_validator(): + 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 + else: + asset_button.validation_icon.visible = False else: - asset_button.validation_icon.visible = False + 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') @@ -804,7 +814,7 @@ class BlenderKitAssetBarOperator(BL_UI_OT_draw_operator): # show indices for debug purposes # asset_button.text = str(asset_button.asset_index) img = bpy.data.images.get(iname) - if not img: + if img is None or len(img.pixels) == 0: img_filepath = paths.get_addon_thumbnail_path('thumbnail_notready.jpg') else: img_filepath = img.filepath diff --git a/blenderkit/comments_utils.py b/blenderkit/comments_utils.py index f91e151f..cf6ccd06 100644 --- a/blenderkit/comments_utils.py +++ b/blenderkit/comments_utils.py @@ -135,41 +135,59 @@ def get_comments(asset_id, api_key): def store_notifications_local(notifications): bpy.context.window_manager['bkit notifications'] = notifications +def count_unread_notifications(): + notifications = bpy.context.window_manager.get('bkit notifications') + if notifications is None: + return 0 + unread = 0 + for n in notifications: + + if n['unread'] == 1: + unread +=1 + print('counted', unread) + return unread + def check_notifications_read(): '''checks if all notifications were already read, and removes them if so''' - all_read = True notifications = bpy.context.window_manager.get('bkit notifications') if notifications is None: return True for n in notifications: if n['unread'] == 1: - all_read = False return False bpy.context.window_manager['bkit notifications'] = None return True -def get_notifications(api_key): +def get_notifications(api_key, unread_count = 1000): ''' - Retrieve ratings from BlenderKit server. Can be run from a thread + Retrieve notifications from BlenderKit server. Can be run from a thread. + Parameters ---------- - asset_id - headers + api_key + unread_count Returns ------- - ratings - dict of type:value ratings ''' headers = utils.get_headers(api_key) - url = paths.get_api_url() + 'notifications/unread/' params = {} + + url = paths.get_api_url() + 'notifications/api/unread_count/' + r = rerequests.get(url, params=params, verify=True, headers=headers) + if r.status_code ==200: + rj = r.json() + # no new notifications? + if unread_count >= rj['unreadCount']: + return + print('notifications', unread_count, rj['unreadCount']) + url = paths.get_api_url() + 'notifications/unread/' r = rerequests.get(url, params=params, verify=True, headers=headers) if r is None: return if r.status_code == 200: rj = r.json() - print(rj) # store notifications - send them to task queue tasks_queue.add_task((store_notifications_local, ([rj]))) diff --git a/blenderkit/search.py b/blenderkit/search.py index 9c0e5ac2..c6dd57e3 100644 --- a/blenderkit/search.py +++ b/blenderkit/search.py @@ -104,6 +104,15 @@ def refresh_token_timer(): return max(3600, user_preferences.api_key_life - 3600) +def refresh_notifications_timer(): + ''' this timer gets notifications.''' + preferences = bpy.context.preferences.addons['blenderkit'].preferences + fetch_server_data() + unread_notifications_count = comments_utils.count_unread_notifications() + comments_utils.get_notifications(preferences.api_key, unread_count = unread_notifications_count) + return 300 + + def update_ad(ad): if not ad.get('assetBaseId'): try: @@ -181,6 +190,10 @@ def scene_load(context): categories.load_categories() if not bpy.app.timers.is_registered(refresh_token_timer) and not bpy.app.background: bpy.app.timers.register(refresh_token_timer, persistent=True, first_interval=36000) + if utils.experimental_enabled() and not bpy.app.timers.is_registered( + refresh_notifications_timer) and not bpy.app.background: + bpy.app.timers.register(refresh_notifications_timer, persistent=True, first_interval=2) + update_assets_data() @@ -199,6 +212,7 @@ def fetch_server_data(): if bpy.context.window_manager.get('bkit_categories') is None: categories.fetch_categories_thread(api_key, force=False) + first_time = True last_clipboard = '' @@ -377,11 +391,15 @@ def search_timer(): ui_props = bpy.context.window_manager.blenderkitUI search_name = f'bkit {ui_props.asset_type.lower()} search' wm = bpy.context.window_manager + print('finishing reading thumbs') if wm.get(search_name) is not None: all_loaded = True for ri, r in enumerate(wm[search_name]): if not r.get('thumb_small_loaded'): - all_loaded = all_loaded and load_preview(r, ri) + preview_loaded = load_preview(r, ri) + print(ri, preview_loaded, all_thumbs_loaded) + all_loaded = all_loaded and preview_loaded + all_thumbs_loaded = all_loaded global search_threads @@ -434,6 +452,7 @@ def search_timer(): if ok: ui_props = bpy.context.window_manager.blenderkitUI orig_len = len(result_field) + print('reading from thread') for ri, r in enumerate(rdata['results']): asset_data = parse_result(r) @@ -487,13 +506,9 @@ def search_timer(): def load_preview(asset, index): - scene = bpy.context.scene # FIRST START SEARCH props = bpy.context.window_manager.blenderkitUI directory = paths.get_temp_dir('%s_search' % props.asset_type.lower()) - s = bpy.context.scene - results = bpy.context.window_manager.get('search results') - loaded = True tpath = os.path.join(directory, asset['thumbnail_small']) if not asset['thumbnail_small'] or asset['thumbnail_small'] == '' or not os.path.exists(tpath): @@ -505,7 +520,7 @@ def load_preview(asset, index): # if os.path.exists(tpath): # sometimes we are unlucky... img = bpy.data.images.get(iname) - if img is None: + if img is None or len(img.pixels) == 0: if not os.path.exists(tpath): return False # wrap into try statement since sometimes @@ -837,8 +852,6 @@ def get_profile(): a = bpy.context.window_manager.get('bkit profile') thread = threading.Thread(target=fetch_profile, args=(preferences.api_key,), daemon=True) thread.start() - if utils.experimental_enabled(): - comments_utils.get_notifications(preferences.api_key) return a @@ -1315,16 +1328,18 @@ def get_search_simple(parameters, filepath=None, page_size=100, max_results=1000 bk_logger.info(f'retrieved {len(results)} assets from elastic search') return results + def get_single_asset(asset_base_id): preferences = bpy.context.preferences.addons['blenderkit'].preferences params = { 'asset_base_id': asset_base_id } results = get_search_simple(params, api_key=preferences.api_key) - if len(results)>0: + if len(results) > 0: return results[0] return None + def search(category='', get_next=False, author_id=''): ''' initialize searching''' global search_start_time diff --git a/blenderkit/ui.py b/blenderkit/ui.py index b8689f5b..70abd898 100644 --- a/blenderkit/ui.py +++ b/blenderkit/ui.py @@ -1903,7 +1903,7 @@ class RunAssetBarWithContext(bpy.types.Operator): C_dict = utils.get_fake_context(context) if C_dict.get('window'): # no 3d view, no asset bar. preferences = bpy.context.preferences.addons['blenderkit'].preferences - if preferences.experimental_features: + if 1:# preferences.experimental_features: bpy.ops.view3d.blenderkit_asset_bar_widget(C_dict, 'INVOKE_REGION_WIN', keep_running=self.keep_running, do_search=self.do_search) diff --git a/blenderkit/ui_panels.py b/blenderkit/ui_panels.py index f7dce680..92794773 100644 --- a/blenderkit/ui_panels.py +++ b/blenderkit/ui_panels.py @@ -334,7 +334,7 @@ def draw_assetbar_show_hide(layout, props): ttip = 'Click to Show Asset Bar' preferences = bpy.context.preferences.addons['blenderkit'].preferences - if preferences.experimental_features: + if 1:#preferences.experimental_features: op = layout.operator('view3d.blenderkit_asset_bar_widget', text='', icon=icon) else: op = layout.operator('view3d.blenderkit_asset_bar', text='', icon=icon) @@ -1438,6 +1438,13 @@ def draw_asset_context_menu(layout, context, asset_data, from_panel=False): op.asset_id = asset_data['id'] op.asset_type = asset_data['assetType'] + if author_id == str(profile['user']['id']): + row.operator_context = 'EXEC_DEFAULT' + op = layout.operator('wm.blenderkit_url', text='Edit Metadata (browser)') + op.url = paths.get_bkit_url() + paths.BLENDERKIT_USER_ASSETS + f"/{asset_data['assetBaseId']}/?edit#" + + row.operator_context = 'INVOKE_DEFAULT' + if asset_data['assetType'] == 'model': op = layout.operator('object.blenderkit_regenerate_thumbnail', text='Regenerate thumbnail') op.asset_index = ui_props.active_index @@ -1957,7 +1964,11 @@ class AssetPopupCard(bpy.types.Operator, ratings_utils.RatingsProperties): row.scale_y = 3 ui_props = bpy.context.window_manager.blenderkitUI - row.prop(ui_props, 'drag_init_button', icon='MOUSE_LMB_DRAG', text='Click / Drag from here', emboss=True) + if self.asset_data.get('canDownload', True): + row.prop(ui_props, 'drag_init_button', icon='MOUSE_LMB_DRAG', text='Click / Drag from here', emboss=True) + else: + op = layout.operator('wm.blenderkit_url', text='Unlock this asset', icon = 'UNLOCKED') + op.url = paths.get_bkit_url() + '/get-blenderkit/' + self.asset_data['id'] + '/?from_addon=True' def draw_menu_desc_author(self, context, layout, width=330): box = layout.column() @@ -2026,13 +2037,14 @@ class AssetPopupCard(bpy.types.Operator, ratings_utils.RatingsProperties): def draw_comment(self, context, layout, comment, width=330): box = layout.box() box.emboss = 'NORMAL' + row = box.row() + split = row.split(factor = 0.8) is_moderator = comment['userModerator'] if is_moderator: role_text = f" - moderator" else: role_text = "" - box.label(text=f"{comment['submitDate']} - {comment['userName']}{role_text}") - utils.label_multiline(box, text=comment['comment'], width=width) + split.label(text=f"{comment['submitDate']} - {comment['userName']}{role_text}") removal = False likes = 0 dislikes = 0 @@ -2043,13 +2055,15 @@ class AssetPopupCard(bpy.types.Operator, ratings_utils.RatingsProperties): dislikes += 1 if l['flag'] == 'removal': removal = True - row = box.row() - - row.label(text=str(likes), icon='TRIA_UP') - row.label(text=str(dislikes), icon='TRIA_DOWN') + # row = box.row() + split1 = split.split() + split1.label(text=str(likes), icon='TRIA_UP') + split1.label(text=str(dislikes), icon='TRIA_DOWN') if removal: row.label(text='', icon='ERROR') + utils.label_multiline(box, text=comment['comment'], width=width) + # box.label(text=str(comment['flags'])) def draw(self, context): @@ -2316,7 +2330,7 @@ def draw_panel_categories(self, context): ctext = '%s (%i)' % (c['name'], c['assetCount']) preferences = bpy.context.preferences.addons['blenderkit'].preferences - if preferences.experimental_features: + if 1:#preferences.experimental_features: op = row.operator('view3d.blenderkit_asset_bar_widget', text=ctext) else: op = row.operator('view3d.blenderkit_asset_bar', text=ctext) diff --git a/blenderkit/utils.py b/blenderkit/utils.py index 33f8140a..d09c369b 100644 --- a/blenderkit/utils.py +++ b/blenderkit/utils.py @@ -62,7 +62,6 @@ def activate(ob): ob.select_set(True) bpy.context.view_layer.objects.active = ob - def selection_get(): aob = bpy.context.view_layer.objects.active selobs = bpy.context.view_layer.objects.selected[:] |