2025-12-01

This commit is contained in:
2026-03-17 14:58:51 -06:00
parent 183e865f8b
commit 4b82b57113
6846 changed files with 954887 additions and 162606 deletions
@@ -31,9 +31,9 @@ from ..modules.poliigon_core.api_remote_control_params import (
CATEGORY_ALL,
KEY_TAB_IMPORTED,
KEY_TAB_MY_ASSETS,
KEY_TAB_RECENT_DOWNLOADS,
KEY_TAB_ONLINE,
IDX_PAGE_ACCUMULATED,
PAGE_SIZE_ACCUMULATED)
KEY_TAB_LOCAL)
from ..modules.poliigon_core.multilingual import _t
from .utils_dlg import (
check_convention,
@@ -43,6 +43,23 @@ from .utils_dlg import (
safe_size_apply,
wrapped_label)
from ..operators.operator_material import set_op_mat_disp_strength
from ..operators.operator_asset_filter import FilterOptions
from .. import reporting
class POLIIGON_MT_asset_display_options(bpy.types.Menu):
bl_label = "Display Options"
bl_idname = "POLIIGON_MT_asset_display_options"
def draw(self, context):
layout = self.layout
props = context.window_manager.poliigon_props
layout.label(text="Thumbnail Size:")
layout.prop(props, "thumbnail_size", expand=True)
layout.separator()
layout.label(text="Assets Per Page:")
layout.prop(props, "assets_per_page", expand=True)
THUMB_SIZE_FACTOR = {"Tiny": 0.5,
@@ -82,6 +99,10 @@ def _build_assets_no_assets(cTB, area: str, category: str) -> None:
label = _t("No Poliigon {0} found in the Scene").format(category)
elif area == KEY_TAB_ONLINE:
label = _t("No Poliigon {0} found Online").format(category)
elif area == KEY_TAB_LOCAL:
label = _t("No Poliigon {0} found locally").format(category)
elif area == KEY_TAB_RECENT_DOWNLOADS:
label = _t("No {0} previously downloaded").format(category)
width = cTB.width_draw_ui - 20 * get_ui_scale(cTB)
wrapped_label(cTB, width, label, box_not_found, add_padding=True)
@@ -347,9 +368,8 @@ def _draw_button_quick_preview(
do_show = False
# TODO(Andreas): confused about backplate handling...
has_thumb_urls = len(asset_data.thumb_urls) > 0
has_cf_thumb_urls = len(asset_data.cloudflare_thumb_urls) > 0
if is_backplate and (has_thumb_urls or has_cf_thumb_urls):
if is_backplate and has_cf_thumb_urls:
do_show = True
elif len(asset_type_data.get_watermark_preview_url_list()):
do_show = True
@@ -392,31 +412,72 @@ def _draw_button_quick_preview(
"Preview {0} on a plane created during import").format(asset_name)
def _draw_new_asset_icon(cTB, layout_row: bpy.types.UILayout, days: int) -> None:
"""Draws the new asset icon."""
icon_value = cTB.ui_icons["ICON_new_asset"].icon_id
op = layout_row.operator(
"poliigon.poliigon_setting",
text="",
emboss=False,
depress=False,
icon_value=icon_value
)
op.mode = "none" # No action needed
op.tooltip = _t("Released {x} days ago").format(x=days)
def _draw_free_asset_icon(cTB, layout_row: bpy.types.UILayout) -> None:
"""Draws the free asset icon."""
icon_val = cTB.ui_icons["ICON_free_asset"].icon_id
op = layout_row.operator(
"poliigon.poliigon_setting",
text="",
emboss=False,
depress=False,
icon_value=icon_val
)
op.mode = "none" # No action needed
op.tooltip = _t("Free asset")
def _draw_checkmark_purchased(cTB, layout_row: bpy.types.UILayout) -> None:
col_checkmark = layout_row.column(align=True)
col_checkmark.enabled = False
icon_val = cTB.ui_icons["ICON_acquired_check"].icon_id
op = col_checkmark.operator(
icon_val = cTB.ui_icons["ICON_local"].icon_id
op = layout_row.operator(
"poliigon.poliigon_setting",
text="",
icon_value=icon_val,
depress=False,
emboss=True
emboss=False
)
op.tooltip = _t("Asset already acquired")
op.mode = "none" # No action needed
op.tooltip = _t("Asset Downloaded")
def _draw_checkmark_purchased_not_local(cTB,
layout_row: bpy.types.UILayout,
tooltip: str) -> None:
icon_val = cTB.ui_icons["LOGO_downloads_recent"].icon_id
op = layout_row.operator(
"poliigon.poliigon_setting",
text="",
icon_value=icon_val,
depress=False,
emboss=False
)
op.mode = "none" # No action needed
op.tooltip = tooltip
def _draw_checkmark_unlimited(cTB, layout_row: bpy.types.UILayout) -> None:
col_checkmark = layout_row.column(align=True)
col_checkmark.enabled = False
icon_val = cTB.ui_icons["ICON_unlimited_local"].icon_id
op = col_checkmark.operator(
icon_val = cTB.ui_icons["ICON_local"].icon_id
op = layout_row.operator(
"poliigon.poliigon_setting",
text="",
icon_value=icon_val,
depress=False,
emboss=True
emboss=False
)
op.mode = "none" # No action needed
op.tooltip = _t("Asset found locally")
@@ -503,7 +564,9 @@ def _draw_button_texture_local(cTB,
text="Retry",
icon="ERROR",
)
op.tooltip = error
# str(): Error may also be an exception class,
# which we can not assign to tooltip property.
op.tooltip = str(error)
else:
op = row_button.operator(
"poliigon.poliigon_material",
@@ -592,14 +655,23 @@ def determine_hdri_sizes(asset_data: AssetData,
size_light = find_closest_size(size_light_default, sizes_jpg)
else:
# Just get any best fit
size_light = asset_type_data.get_size(
size=size_light_default,
local_only=True,
addon_convention=addon_convention,
local_convention=asset_data.get_convention(local=True))
try:
size_light = asset_type_data.get_size(
size=size_light_default,
local_only=True,
addon_convention=addon_convention,
local_convention=asset_data.get_convention(local=True))
except KeyError:
size_light = None
size_bg = size_bg_default
if not use_jpg_bg:
if size_bg is None or size_light is None:
# If either of these sizes is None, we won't be able to set the
# size property. Yet, in order to not complicate any None checks,
# we need to let these pass, instead of converting them to
# strings.
pass
elif not use_jpg_bg:
size_bg = f"{size_light}_EXR"
elif len(sizes_jpg) > 0:
size_bg = find_closest_size(size_bg_default, sizes_jpg)
@@ -629,7 +701,9 @@ def _draw_button_hdri_local(cTB,
text="Retry",
icon="ERROR",
)
op.tooltip = error.description
# str(): Error may also be an exception class,
# which we can not assign to tooltip property.
op.tooltip = str(error)
else:
op = layout_row.operator(
"poliigon.poliigon_hdri",
@@ -646,7 +720,16 @@ def _draw_button_hdri_local(cTB,
use_jpg_bg=cTB.settings["hdri_use_jpg_bg"],
addon_convention=cTB.addon_convention)
safe_size_apply(cTB, op, size_light, asset_name)
op.size_bg = size_bg
if size_bg is None:
return
try:
op.size_bg = size_bg
except TypeError as e:
# Since this is a UI draw issue, there will be multiple of these
# these reports, but we have user-level debouncing for a max number
# per message type.
msg = f"Failed to assign {size_bg} size for {asset_name}: {e}"
cTB.logger_ui.error(msg)
def _draw_button_hdri_imported(cTB,
@@ -696,7 +779,9 @@ def _draw_button_download(cTB,
text=label,
icon="ERROR",
)
op.tooltip = error
# str(): Error may also be an exception class,
# which we can not assign to tooltip property.
op.tooltip = str(error)
else:
op = layout_row.operator(
"poliigon.poliigon_download",
@@ -718,54 +803,58 @@ def _draw_button_purchase(cTB,
) -> None:
asset_id = asset_data.asset_id
asset_name = asset_data.asset_name
num_credits = asset_data.credits
is_free = num_credits == 0
is_free_asset = asset_data.credits == 0
thumb_size = THUMB_SIZE_FACTOR[cTB.settings["thumbsize"]]
name_op = "poliigon.poliigon_download"
if cTB.is_free_user() and not is_free_asset:
name_op = "poliigon.poliigon_setting"
mode_purchase = "my_account"
label = _t("Download with Pro")
tooltip = _t("Learn more about Poliigon plans.")
elif is_free_asset or cTB.is_unlimited_user():
# While it will still be a purchase button,
# for free assets it will lead to an implicit auto-download
label = _t("Download {0}").format(size_default)
tooltip = _t("Download {0}").format(asset_name)
mode_purchase = "download"
elif not cTB.is_legacy_limited_user() and cTB.settings["auto_download"]:
# If not-legacy pro user, we are still using purchase endpoint but with
# Download label if auto-download option is set as true;
label = _t("Download {0}").format(size_default)
tooltip = _t("Download {0}").format(asset_name)
mode_purchase = "purchase"
else:
# If legacy pro user, then we are still using Purchase label and
# purchase endpoint;
if thumb_size >= 0.75:
label = _t("Purchase")
else:
label = _t("Buy")
tooltip = _t("Purchase {0}").format(asset_name)
mode_purchase = "purchase"
if error == ERR_NOT_ENOUGH_CREDITS:
label = "Balance"
elif error is not None:
# str(): Error may also be an exception class,
# which we can not assign to tooltip property.
tooltip = str(error)
label = "Retry"
elif is_free or cTB.is_unlimited_user():
# While it will still be a purchase button,
# for free assets it will lead to an implicit auto-download
label = _t("Download {0}").format(size_default)
elif thumb_size >= 0.75:
label = _t("Purchase")
else:
label = _t("Buy")
name_op = "poliigon.poliigon_download"
mode_purchase = "purchase"
tooltip = _t("Purchase {0}").format(asset_name)
if not is_free:
if cTB.is_free_user():
name_op = "poliigon.poliigon_setting"
mode_purchase = "my_account"
label = _t("Learn More")
tooltip = _t("Switch to your account overview.")
elif cTB.is_unlimited_user():
mode_purchase = "download"
tooltip = _t("Download {0}").format(asset_name)
elif not cTB.settings["one_click_purchase"]:
name_op = "poliigon.popup_purchase"
else:
tooltip = _t("Download {0}").format(asset_name)
if mode_purchase == "purchase" and not cTB.settings["one_click_purchase"]:
name_op = "poliigon.popup_purchase"
icon = "ERROR" if error is not None else "NONE"
op = layout_row.operator(
name_op, text=label,
icon=icon
)
op = layout_row.operator(name_op, text=label, icon=icon)
op.mode = mode_purchase
op.tooltip = tooltip
if mode_purchase == "purchase" or mode_purchase == "download":
op.asset_id = asset_id
safe_size_apply(cTB, op, size_default, asset_name)
if error:
op.tooltip = error
else:
op.tooltip = tooltip
def _draw_button_quick_menu(layout_row: bpy.types.UILayout,
@@ -808,15 +897,22 @@ def _draw_missing_grid_dummies(cTB,
layout_grid.column(align=1)
def _draw_view_more_my_assets(
cTB, layout_box_not_found: bpy.types.UILayout) -> None:
def _draw_reset_filters(cTB,
area: str,
layout_box_not_found: bpy.types.UILayout
) -> None:
if layout_box_not_found is None:
return
row = layout_box_not_found.row(align=True)
row.scale_y = 1.5
label = _t("View more online")
if cTB.vSearch[area] != "" and area == KEY_TAB_ONLINE:
label = _t("Clear Search")
mode = f"clear_search_{area}"
else:
label = _t("Reset Filters")
mode = f"area_{KEY_TAB_ONLINE}"
use_padding = 500
if cTB.width_draw_ui >= use_padding * get_ui_scale(cTB):
@@ -824,46 +920,14 @@ def _draw_view_more_my_assets(
op = row.operator(
"poliigon.poliigon_setting",
text=label,
icon_value=cTB.ui_icons["ICON_poliigon"].icon_id
text=label
)
op.mode = "view_more"
op.mode = mode
if cTB.width_draw_ui >= use_padding * get_ui_scale(cTB):
row.label(text="")
def _draw_view_more_imported(cTB, sorted_assets: List[Dict]) -> None:
if len(sorted_assets) != 0:
return
cTB.vBase.separator()
cTB.vBase.separator()
asset_ids_my_assets = cTB._asset_index.query(
"my_assets/All Assets",
chunk=IDX_PAGE_ACCUMULATED,
chunk_size=PAGE_SIZE_ACCUMULATED)
if asset_ids_my_assets is not None and len(asset_ids_my_assets) > 0:
row = cTB.vBase.row(align=True)
op = row.operator(
"poliigon.poliigon_setting",
text=_t("Explore Your Assets"),
icon_value=cTB.ui_icons["ICON_myassets"].icon_id,
)
op.mode = "area_my_assets"
op.tooltip = _t("Show My Assets")
else:
row = cTB.vBase.row(align=True)
op = row.operator(
"poliigon.poliigon_setting",
text=_t("Explore Poliigon Assets"),
icon_value=cTB.ui_icons["ICON_poliigon"].icon_id,
)
op.mode = "area_poliigon"
op.tooltip = _t("Show Poliigon Assets")
def _draw_button_unsupported_convention(row: bpy.types.UILayout) -> None:
_ = row.operator(
"poliigon.unsupported_convention",
@@ -960,7 +1024,7 @@ def _draw_page_buttons(
col = row_middle.column(align=True)
categories = cTB.settings["category"][area]
categories = cTB.settings["category"]
search = cTB.vSearch[area]
key_fetch = (tuple(categories), search)
enabled = key_fetch not in cTB.fetching_asset_data[area]
@@ -998,12 +1062,17 @@ def _build_unlimited_banner(cTB, layout: bpy.types.UILayout) -> None:
if area != KEY_TAB_MY_ASSETS:
return
col_grid = layout.column()
col_grid = layout.column(align=True)
box_unlimited = col_grid.box()
box_unlimited.alignment = "CENTER"
col_unlimited = box_unlimited.column()
# Spacer to ensure the box is given the full width
_wide_row = box_unlimited.row()
_wide_row.scale_y = 0.001
_wide_row.label(text="")
col_unlimited = box_unlimited.row()
col_unlimited.alignment = "CENTER"
text_info = _t("Unlimited Downloads - "
@@ -1013,16 +1082,20 @@ def _build_unlimited_banner(cTB, layout: bpy.types.UILayout) -> None:
w_info = cTB.width_draw_ui - 20 * get_ui_scale(cTB)
wrapped_label(cTB, w_info, text_info, col_unlimited, add_padding=False)
col_link = col_unlimited.column()
col_link.alignment = "LEFT"
# Spacer to ensure the box is given the full width
_wide_row = box_unlimited.row()
_wide_row.scale_y = 0.001
_wide_row.label(text="")
col_unlimited = box_unlimited.row()
icon_value = cTB.ui_icons["LOGO_unlimited"].icon_id
op_link = col_link.operator(
op_link = col_unlimited.operator(
"poliigon.poliigon_link", text=_t("Learn More"), emboss=True, icon_value=icon_value)
op_link.tooltip = _t("Learn more online about unlimited plans")
op_link.mode = "unlimited"
op_link.mode = "unlimited_plan_help"
def _build_tab_title(cTB) -> None:
def _build_tab_title(cTB, dummy_assets_grid: bool = False) -> None:
row = cTB.vBase.row()
area = cTB.settings["area"]
@@ -1033,69 +1106,44 @@ def _build_tab_title(cTB) -> None:
is_category_all = categories == [CATEGORY_ALL]
is_all = is_category_all and not has_search
if is_all and area != KEY_TAB_IMPORTED:
if is_all and area not in [KEY_TAB_IMPORTED, KEY_TAB_LOCAL]:
num_assets = cTB.num_assets[area]
else:
num_assets = cTB.num_assets_current_query
# We do not want the "All" removed, if search comes from our
# virtual "free category" (which only exists on Online tab), alone.
# TODO(Andreas): This will change again, once we do the "virtual free"
# category via API RC.
if area == KEY_TAB_ONLINE:
if has_search and cTB.vSearch[area] != "free ":
prefix_top_level = ""
else:
# Leads to deliberately replacing "All " with "All " (-> no change)
prefix_top_level = "All "
elif has_search:
prefix_top_level = ""
elif area == KEY_TAB_MY_ASSETS:
prefix_top_level = "My "
elif area == KEY_TAB_IMPORTED:
prefix_top_level = "Imported "
category = categories[-1]
if cTB.settings["show_settings"]:
area_title = _t("Settings")
elif cTB.settings["show_user"]:
area_title = _t("My Account")
elif len(categories) == 1:
category = categories[0]
if category in ["HDRIs", "Models", "Textures"]:
category = f"{prefix_top_level}{category}"
elif category == "All Assets" and area == KEY_TAB_ONLINE:
if "free" in cTB.vSearch[area]:
category = "All Free Assets"
category = category.replace("All ", prefix_top_level)
area_title = category
if has_search:
area_title = _t("Assets")
else:
area_title = categories[-1].title()
area_title = category
if area_title == KEY_TAB_ONLINE:
area_title = _t("Online")
area_title = f"{area_title} ({num_assets})"
if not dummy_assets_grid:
area_title = f"{area_title} ({num_assets})"
row.label(text=area_title)
row_right = row.row()
row_right = row.row(align=True)
row_right.alignment = "RIGHT"
curr_filter = FilterOptions.get_from_query(cTB.settings["area"])
set_pressed = curr_filter != FilterOptions.ALL_ASSETS
row_right.operator("poliigon.asset_filter",
text=curr_filter.value if set_pressed else _t("Filter"),
icon="FILTER",
depress=set_pressed)
if set_pressed:
reset_filters = row_right.operator("poliigon.poliigon_setting",
icon="PANEL_CLOSE",
depress=set_pressed)
reset_filters.mode = f"asset_filter_{FilterOptions.ALL_ASSETS.map_to_query()}"
row_right.separator()
col = row_right.column()
is_fetching_my_assets = len(cTB.fetching_asset_data[KEY_TAB_MY_ASSETS]) > 0
is_fetching_online = len(cTB.fetching_asset_data[KEY_TAB_ONLINE]) > 0
is_fetching = is_fetching_my_assets or is_fetching_online
op = col.operator(
"poliigon.refresh_data",
text="",
icon="FILE_REFRESH"
)
if is_fetching:
op.tooltip = _t("Fetching of asset data in progress")
col.enabled = not is_fetching
col = row_right.column(align=True)
col.operator("poliigon.refresh_data", text="", icon="FILE_REFRESH")
col.enabled = cTB.all_assets_fetched
row_right.menu("POLIIGON_MT_asset_display_options", icon="IMGDISPLAY", text="")
def _asset_is_local(cTB, asset_data: AssetData) -> bool:
@@ -1123,6 +1171,38 @@ def _asset_is_local(cTB, asset_data: AssetData) -> bool:
return is_local
def _create_icon_asset_layout(
cTB, row: bpy.types.UILayout, asset_data: Optional[AssetData]) -> None:
"""Creates the layout for new assets with icon and label."""
# Create a special row for the name with icon to ensure proper alignment
name_with_icon_row = row.row(align=True)
name_with_icon_row.alignment = "LEFT"
name_with_icon_row.separator(factor=0.8)
# # Draw the icon first - match text height
icon_col = name_with_icon_row.column(align=True)
# icon_col = row.column(align=True)
icon_col.separator(factor=0.4)
icon_col.scale_y = 0.6
icon_col.scale_x = 0.5
if asset_data.is_purchased and asset_data.is_local:
_draw_checkmark_purchased(cTB, icon_col)
elif asset_data.is_recent_downloaded:
_draw_checkmark_purchased_not_local(cTB, icon_col, _t("Previously Downloaded"))
elif asset_data.is_purchased:
_draw_checkmark_purchased_not_local(cTB, icon_col, _t("Asset acquired"))
elif cTB.is_unlimited_user() and asset_data.is_local:
_draw_checkmark_unlimited(cTB, icon_col)
elif asset_data.credits == 0:
_draw_free_asset_icon(cTB, icon_col)
elif asset_data.is_new():
days_ago = 1
_draw_new_asset_icon(cTB, icon_col, days_ago)
# Add more space between icon and text
row.separator(factor=1.5)
# @timer
def build_assets(cTB):
cTB.logger_ui.debug("build_assets")
@@ -1135,14 +1215,15 @@ def build_assets(cTB):
sorted_assets = cTB.f_GetAssetsSorted(idx_page_current)
cTB.logger_ui.debug(f"build_assets: sorted_assets {len(sorted_assets)}")
_draw_page_buttons(cTB, area, idx_page_current, at_top=True)
# If asset_id in sorted_assets is 0, we consider as dummy asset
# (for populating placeholder on the grid - check f_GetAssetsSorted);
dummy_assets = sorted_assets and sorted_assets[0] == 0
_build_tab_title(cTB, dummy_assets)
if cTB.is_unlimited_user():
row = cTB.vBase.row(align=False)
row = cTB.vBase.row(align=True)
_build_unlimited_banner(cTB, row)
_build_tab_title(cTB)
thumb_size_factor = THUMB_SIZE_FACTOR[cTB.settings["thumbsize"]]
category = cTB.vActiveCat[0].replace("All ", "")
@@ -1162,6 +1243,22 @@ def build_assets(cTB):
for _asset_id in sorted_assets:
if _asset_id != 0:
asset_data = cTB._asset_index.get_asset(_asset_id)
if asset_data is None:
# Asset could have been removed or failed to load for some reason.
# Skip this entry instead of raising an exception that breaks the UI.
# See historical errors at: SOFT-2849's linked report
msg = (f"Asset id {_asset_id} not found in index skipping.\n"
f"\tall_assets_fetched:{cTB.all_assets_fetched}\n"
f"\tpage {idx_page_current} of {category}\n"
f"\tAPI status: {getattr(cTB._api.status, 'name', cTB._api.status)}")
reporting.capture_message(
"asset_id_missing_during_draw",
msg,
"error",
max_reports=1
)
asset_data = AssetData(
0, AssetType.TEXTURE, "dummy", api_convention=0)
else:
asset_data = AssetData(
0, AssetType.TEXTURE, "dummy", api_convention=0)
@@ -1220,22 +1317,29 @@ def build_assets(cTB):
cell = grid.column(align=True)
box_thumb = cell.box().column()
# Add the name row
name_row = box_thumb.row(align=True)
ui_label = "" if "dummy" in asset_name.lower() else asset_name_display
name_row.label(text=ui_label)
name_row.scale_y = 0.8
name_row.alignment = "CENTER"
name_row.enabled = False # To fade label for less contrast.
# Icon element
is_dummy = asset_name == "dummy"
if not is_dummy and asset_data is not None:
# name_row.enabled = False
_create_icon_asset_layout(cTB, name_row, asset_data)
name_row.alignment = "LEFT"
# Label element
name_label_row = name_row.row(align=True)
ui_label = "" if is_dummy else asset_name_display
name_label_row.label(text=ui_label)
name_label_row.scale_y = 0.7
name_label_row.alignment = "LEFT"
name_label_row.enabled = False
# Draw the thumbnail normally
_draw_thumbnail(cTB, asset_data, thumb_size_factor, box_thumb)
# See if there's any errors associated with this asset,
# such as after or during purchase/download failure.
error = None
if asset_data.state.dl.has_error():
error = asset_data.state.dl.error
if asset_data.state.purchase.has_error():
error = asset_data.state.purchase.error
error = asset_data.state.get_any_error()
row = cell.row(align=True)
@@ -1248,19 +1352,15 @@ def build_assets(cTB):
elif asset_data.state.dl.is_in_progress():
_draw_thumb_state_asset_downloading(
row, asset_data, thumb_width)
elif area in [KEY_TAB_ONLINE, KEY_TAB_MY_ASSETS]:
elif area in [KEY_TAB_ONLINE,
KEY_TAB_MY_ASSETS,
KEY_TAB_LOCAL,
KEY_TAB_RECENT_DOWNLOADS]:
is_tex = asset_type == AssetType.TEXTURE
is_local = asset_data.is_local
if cTB.is_unlimited_user() and is_local:
_draw_checkmark_unlimited(cTB, row)
elif cTB.is_unlimited_user():
# No need for green checkmark or wm preview if unlimited
pass
elif is_tex and not is_purchased:
if is_tex and not is_purchased:
_draw_button_quick_preview(
cTB, row, asset_data, is_selection)
elif is_purchased and area == KEY_TAB_ONLINE:
_draw_checkmark_purchased(cTB, row)
if is_purchased or cTB.is_unlimited_user():
if is_downloaded:
@@ -1323,7 +1423,4 @@ def build_assets(cTB):
_draw_page_buttons(cTB, area, idx_page_current)
if area == KEY_TAB_MY_ASSETS:
_draw_view_more_my_assets(cTB, box_not_found)
elif area == KEY_TAB_IMPORTED:
_draw_view_more_imported(cTB, sorted_assets)
_draw_reset_filters(cTB, area, box_not_found)