2025-12-01
This commit is contained in:
@@ -28,20 +28,24 @@ def _build_section_free_user(cTB) -> None:
|
||||
box_free = cTB.vBase.box()
|
||||
col = box_free.column()
|
||||
|
||||
msg = _t("Access 3,000+ studio quality assets")
|
||||
wrapped_label(cTB, w_label, msg, col, add_padding=False)
|
||||
msg = _t("Unused asset balance rolls over each month")
|
||||
wrapped_label(cTB, w_label, msg, col, add_padding=False, icon="CHECKMARK")
|
||||
msg = _t("Commercial & personal use license")
|
||||
wrapped_label(cTB, w_label, msg, col, add_padding=False, icon="CHECKMARK")
|
||||
msg = _t("Redownload even if your subscription ends")
|
||||
wrapped_label(cTB, w_label, msg, col, add_padding=False, icon="CHECKMARK")
|
||||
msg = _t("Cancel or pause at any time in a few clicks")
|
||||
wrapped_label(cTB, w_label, msg, col, add_padding=False, icon="CHECKMARK")
|
||||
msg = _t("50% discount for students and teachers")
|
||||
wrapped_label(cTB, w_label, msg, col, add_padding=False, icon="CHECKMARK")
|
||||
col.label(text=_t("Get more with Pro"),
|
||||
icon_value=cTB.ui_icons["ICON_checkmark_verified"].icon_id)
|
||||
spacer = col.row()
|
||||
spacer.scale_y = 0.5
|
||||
spacer.label(text="")
|
||||
|
||||
op = col.operator("poliigon.poliigon_link", text=_t("View Pricing"))
|
||||
msg = _t("Access the full resolution downloads of 5,000+ assets")
|
||||
wrapped_label(cTB, w_label, msg, col, add_padding=False, add_padding_bottom=True, icon="CHECKMARK")
|
||||
msg = _t("Commercial & personal use license")
|
||||
wrapped_label(cTB, w_label, msg, col, add_padding=False, add_padding_bottom=True, icon="CHECKMARK")
|
||||
msg = _t("Cancel or pause at any time in a few clicks")
|
||||
wrapped_label(cTB, w_label, msg, col, add_padding=False, add_padding_bottom=True, icon="CHECKMARK")
|
||||
msg = _t("50% discount for students and teachers")
|
||||
wrapped_label(cTB, w_label, msg, col, add_padding=False, add_padding_bottom=True, icon="CHECKMARK")
|
||||
|
||||
button_row = col.row()
|
||||
button_row.scale_y = 1.3
|
||||
op = button_row.operator("poliigon.poliigon_link", text=_t("View Pricing"), depress=True)
|
||||
op.mode = "subscribe"
|
||||
# TODO(Andreas): Figma did not contain any tooltips...
|
||||
op.tooltip = _t("View Poliigon Pricing Online")
|
||||
@@ -53,27 +57,35 @@ def _build_section_paid_plan(cTB) -> None:
|
||||
box_free = cTB.vBase.box()
|
||||
col = box_free.column()
|
||||
|
||||
col.label(text=_t("My Account"),
|
||||
icon="COMMUNITY")
|
||||
spacer = col.row()
|
||||
spacer.scale_y = 0.5
|
||||
spacer.label(text="")
|
||||
|
||||
name_plan = cTB.user.plan.plan_name
|
||||
wrapped_label(cTB, w_label, name_plan, col, add_padding=False)
|
||||
wrapped_label(cTB, w_label, name_plan, col, add_padding=False, add_padding_bottom=True)
|
||||
|
||||
if not cTB.is_unlimited_user():
|
||||
credits = cTB.user.plan.plan_credit
|
||||
msg = _t("Assets per month: {0}").format(credits)
|
||||
wrapped_label(cTB, w_label, msg, col, add_padding=False)
|
||||
wrapped_label(cTB, w_label, msg, col, add_padding=False, add_padding_bottom=True)
|
||||
|
||||
next_renew = cTB.user.plan.next_subscription_renewal_date
|
||||
msg = _t("Renewal Date: {0}").format(next_renew)
|
||||
wrapped_label(cTB, w_label, msg, col, add_padding=False)
|
||||
wrapped_label(cTB, w_label, msg, col, add_padding=False, add_padding_bottom=True)
|
||||
|
||||
is_paused = cTB.is_paused_subscription()
|
||||
status = _t("Paused") if is_paused else _t("Active")
|
||||
msg = _t("Status: {0}").format(status)
|
||||
wrapped_label(cTB, w_label, msg, col, add_padding=False)
|
||||
wrapped_label(cTB, w_label, msg, col, add_padding=False, add_padding_bottom=True)
|
||||
|
||||
op = col.operator("poliigon.poliigon_link", text=_t("View Details"))
|
||||
button_row = col.row()
|
||||
button_row.scale_y = 1.3
|
||||
op = button_row.operator("poliigon.poliigon_link", text=_t("Manage Account"))
|
||||
op.mode = "credits"
|
||||
# TODO(Andreas): Figma did not contain any tooltips...
|
||||
op.tooltip = _t("View Details of Your Plan Online")
|
||||
op.tooltip = _t("View details of your plan online")
|
||||
|
||||
|
||||
def _build_still_loading(cTB) -> None:
|
||||
@@ -86,14 +98,13 @@ def _build_still_loading(cTB) -> None:
|
||||
|
||||
def build_user(cTB) -> None:
|
||||
cTB.logger_ui.debug("build_user")
|
||||
|
||||
cTB.vBase.label(text=_t("Your Plan"))
|
||||
free_account = cTB.is_free_user() or cTB.user.plan.plan_name is None
|
||||
|
||||
if cTB.fetching_user_data:
|
||||
_build_still_loading(cTB)
|
||||
return
|
||||
|
||||
if cTB.is_free_user() or cTB.user.plan.plan_name is None:
|
||||
if free_account:
|
||||
_build_section_free_user(cTB)
|
||||
else:
|
||||
_build_section_paid_plan(cTB)
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
|
||||
from ..modules.poliigon_core.api_remote_control_params import (
|
||||
CATEGORY_ALL,
|
||||
CATEGORY_FREE,
|
||||
KEY_TAB_ONLINE)
|
||||
from ..modules.poliigon_core.assets import (
|
||||
AssetType,
|
||||
@@ -68,15 +69,15 @@ def build_categories(cTB):
|
||||
|
||||
row_sub_cat = row_categories.row(align=True)
|
||||
|
||||
type_hdri = ASSET_TYPE_TO_CATEGORY_NAME[AssetType.HDRI]
|
||||
type_hdri = "HDRIS" # TODO(SOFT-2733): Cleanup HDRIS mapping
|
||||
type_model = ASSET_TYPE_TO_CATEGORY_NAME[AssetType.MODEL]
|
||||
type_tex = ASSET_TYPE_TO_CATEGORY_NAME[AssetType.TEXTURE]
|
||||
list_types = [CATEGORY_ALL, type_tex, type_model, type_hdri]
|
||||
|
||||
area = cTB.settings["area"]
|
||||
if cTB.search_free and area == KEY_TAB_ONLINE:
|
||||
lbl_button_cat = _t("Free")
|
||||
elif cTB.vAssetType == CATEGORY_ALL:
|
||||
if area == KEY_TAB_ONLINE:
|
||||
list_types.append(CATEGORY_FREE)
|
||||
|
||||
if cTB.vAssetType == CATEGORY_ALL:
|
||||
lbl_button_cat = _t("Select Category")
|
||||
else:
|
||||
lbl_button_cat = cTB.vAssetType
|
||||
|
||||
@@ -31,31 +31,6 @@ def build_mode(url, action, id_notice):
|
||||
return "notify@{}@{}@{}".format(url, action, id_notice)
|
||||
|
||||
|
||||
def _draw_notification_open_url_single_row(cTB, notice, first_row, icon) -> None:
|
||||
# Single row with text + button.
|
||||
# TODO: generalize this for notification message and length,
|
||||
# and if dismiss is included.
|
||||
# During SOFT-780 this has been changed for POPUP_MESSAGE in a
|
||||
# very simplistic way
|
||||
# (commit: https://github.com/poliigon/poliigon-addon-blender/pull/278/commits/00296ab70288893a023a6705d52eb4505ce36897).
|
||||
# When addressing this properly,
|
||||
# make sure to address it for all notification types.
|
||||
first_row.alert = True
|
||||
first_row.label(text=notice.title)
|
||||
first_row.alert = False
|
||||
op = first_row.operator(
|
||||
"poliigon.poliigon_link",
|
||||
icon=icon,
|
||||
text=notice.label,
|
||||
)
|
||||
if notice.tooltip != "":
|
||||
op.tooltip = notice.tooltip
|
||||
op.mode = build_mode(
|
||||
notice.url,
|
||||
notice.label,
|
||||
notice.id_notice)
|
||||
|
||||
|
||||
def _draw_notification_open_url_two_rows(
|
||||
cTB, notice, first_row, main_col, icon) -> None:
|
||||
# Two rows (or more, if text wrapping).
|
||||
@@ -88,13 +63,7 @@ def _draw_notification_open_url_two_rows(
|
||||
|
||||
def _draw_notification_open_url(
|
||||
cTB, notice, first_row, main_col, panel_width, icon) -> None:
|
||||
# Empirical for width for "Beta addon: [Take survey]" specifically.
|
||||
single_row_width = 250
|
||||
if panel_width > single_row_width:
|
||||
_draw_notification_open_url_single_row(cTB, notice, first_row, icon)
|
||||
else:
|
||||
_draw_notification_open_url_two_rows(
|
||||
cTB, notice, first_row, main_col, icon)
|
||||
_draw_notification_open_url_two_rows(cTB, notice, first_row, main_col, icon)
|
||||
|
||||
|
||||
def _draw_notification_update_ready_single_row(cTB, notice, first_row, icon) -> None:
|
||||
@@ -231,6 +200,25 @@ def _draw_notification_run_operator(cTB, notice, first_row, icon) -> None:
|
||||
op.tooltip = notice.tooltip
|
||||
|
||||
|
||||
def _draw_notification_none_action(cTB, notice, first_row, icon) -> None:
|
||||
"""Draws a notification with no clickable action - just text with dismiss button."""
|
||||
# Create a row with icon on the left and text in center (X button handled by main function)
|
||||
row = first_row.row(align=True)
|
||||
|
||||
# Icon column on the left - single row for compact height
|
||||
icon_col = row.column(align=True)
|
||||
icon_col.alignment = "CENTER"
|
||||
icon_col.label(text="", icon=icon)
|
||||
|
||||
# Text column in center - fills remaining space
|
||||
text_col = row.column()
|
||||
text_col.alignment = "CENTER"
|
||||
# Using full available width for text
|
||||
wrapped_label(
|
||||
cTB, cTB.width_draw_ui, notice.title, text_col)
|
||||
text_col.alert = False
|
||||
|
||||
|
||||
# TODO(Andreas): deactivated reporting here, as I needed a third parameter and
|
||||
# was not able to quickly make handle_draw() work
|
||||
# @reporting.handle_draw()
|
||||
@@ -270,6 +258,8 @@ def notification_banner(cTB, layout):
|
||||
cTB, notice, first_row, main_col, panel_width, icon)
|
||||
elif notice.action == ActionType.RUN_OPERATOR:
|
||||
_draw_notification_run_operator(cTB, notice, first_row, icon)
|
||||
elif notice.action == ActionType.NONE:
|
||||
_draw_notification_none_action(cTB, notice, first_row, icon)
|
||||
else:
|
||||
main_col.label(text=notice.title)
|
||||
cTB.logger_ui.error("Invalid notifcation type")
|
||||
|
||||
@@ -18,10 +18,6 @@
|
||||
|
||||
import bpy
|
||||
|
||||
from ..modules.poliigon_core.api_remote_control_params import (
|
||||
KEY_TAB_IMPORTED,
|
||||
KEY_TAB_MY_ASSETS,
|
||||
KEY_TAB_ONLINE)
|
||||
from ..modules.poliigon_core.multilingual import _t
|
||||
|
||||
|
||||
@@ -88,52 +84,60 @@ def build_areas(cTB):
|
||||
cTB.logger_ui.debug("build_areas")
|
||||
cTB.initial_view_screen()
|
||||
|
||||
row = cTB.vBase.row(align=True)
|
||||
row.scale_x = 1.1
|
||||
row.scale_y = 1.1
|
||||
row = cTB.vBase.row()
|
||||
label_column = row.column(align=True)
|
||||
label_column.alignment = "LEFT"
|
||||
|
||||
_add_asset_tab(
|
||||
cTB,
|
||||
row,
|
||||
tab=KEY_TAB_ONLINE,
|
||||
mode="area_poliigon",
|
||||
icon="HOME",
|
||||
tooltip=_t("Show Poliigon Assets"))
|
||||
_add_asset_tab(
|
||||
cTB,
|
||||
row,
|
||||
tab=KEY_TAB_MY_ASSETS,
|
||||
mode="area_my_assets",
|
||||
icon_value=cTB.ui_icons["ICON_myassets"].icon_id,
|
||||
tooltip=_t("Show My Assets"))
|
||||
_add_asset_tab(
|
||||
cTB,
|
||||
row,
|
||||
tab=KEY_TAB_IMPORTED,
|
||||
mode="area_imported",
|
||||
icon="OUTLINER_OB_GROUP_INSTANCE",
|
||||
tooltip=_t("Show Imported Assets"))
|
||||
icon = 0
|
||||
label_txt = _t("Browse Assets")
|
||||
if cTB.is_unlimited_user():
|
||||
icon = cTB.ui_icons["LOGO_unlimited"].icon_id
|
||||
label_txt = _t("Pro Unlimited")
|
||||
elif not cTB.is_free_user():
|
||||
icon = cTB.ui_icons["ICON_asset_balance"].icon_id
|
||||
if cTB.is_paused_subscription() and cTB.get_user_credits() <= 0:
|
||||
icon = cTB.ui_icons["ICON_subscription_paused"].icon_id
|
||||
label_txt = _t("Downloads")
|
||||
label_txt = f"{cTB.get_user_credits()} {label_txt}"
|
||||
|
||||
op = row.operator(
|
||||
if not cTB.settings["show_user"]:
|
||||
label_column.label(text=label_txt, icon_value=icon)
|
||||
else:
|
||||
back_button = label_column.operator(
|
||||
"poliigon.poliigon_setting",
|
||||
text=_t("Back"),
|
||||
icon="BACK"
|
||||
)
|
||||
back_button.mode = "show_user"
|
||||
|
||||
row_right = row.row(align=True)
|
||||
row_right.alignment = "RIGHT"
|
||||
|
||||
op = row_right.operator(
|
||||
"poliigon.poliigon_setting",
|
||||
text="",
|
||||
icon_value=cTB.ui_icons["ICON_poliigon"].icon_id,
|
||||
icon="COMMUNITY",
|
||||
depress=cTB.settings["show_user"],
|
||||
)
|
||||
op.mode = "my_account"
|
||||
op.mode = "show_user"
|
||||
op.tooltip = _t("Show Your Account Details")
|
||||
|
||||
row.separator()
|
||||
op = row_right.operator(
|
||||
"poliigon.poliigon_link",
|
||||
text="",
|
||||
icon="HELP"
|
||||
)
|
||||
op.confirm_popup = True
|
||||
op.mode = "help"
|
||||
op.tooltip = _t("Addon help")
|
||||
|
||||
row_prefs = row.row(align=True)
|
||||
row_prefs.alignment = "RIGHT"
|
||||
|
||||
_draw_asset_balance(cTB, row=row_prefs)
|
||||
|
||||
_ = row_prefs.operator(
|
||||
_ = row_right.operator(
|
||||
"poliigon.open_preferences",
|
||||
text="",
|
||||
icon="PREFERENCES",
|
||||
).set_focus = "all"
|
||||
)
|
||||
|
||||
# TODO(Joao): Check if this operator should be moved somewhere else
|
||||
# _draw_asset_balance(cTB, row=row_prefs)
|
||||
|
||||
cTB.vBase.separator()
|
||||
|
||||
@@ -61,6 +61,7 @@ def _draw_banner(cTB, upgrade_content: UpgradeContent) -> None:
|
||||
text=label,
|
||||
icon_value=cTB.ui_icons[key_icon].icon_id)
|
||||
op.mode = "subscribe_banner"
|
||||
op.tooltip = "Opens the website to view available plans"
|
||||
|
||||
|
||||
def _draw_banner_in_progress(cTB, upgrade_content: UpgradeContent) -> None:
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -36,11 +36,13 @@ def build_library(cTB):
|
||||
|
||||
cTB.vBase.separator()
|
||||
|
||||
disabled_row = cTB.vBase.row()
|
||||
disabled_row.enabled = False
|
||||
wrapped_label(
|
||||
cTB,
|
||||
cTB.width_draw_ui,
|
||||
_t("Select where you will store Poliigon assets."),
|
||||
cTB.vBase
|
||||
disabled_row
|
||||
)
|
||||
|
||||
cTB.vBase.separator()
|
||||
|
||||
@@ -25,10 +25,12 @@ from .utils_dlg import (
|
||||
from ..toolbox import c_Toolbox
|
||||
|
||||
|
||||
ERR_CREDS_FORMAT = _t("Invalid email format/password length.")
|
||||
# TODO(Andreas): Currently not sure about this error
|
||||
ERR_LOGIN_TIMEOUT = _t("Login with website timed out, please try again")
|
||||
|
||||
# Base threshold for responsive layout adjustment (unscaled)
|
||||
RESPONSIVE_WIDTH_BASE = 250
|
||||
|
||||
|
||||
def _draw_welcome_or_error(cTB: c_Toolbox, layout: bpy.types.UILayout) -> None:
|
||||
if cTB.user_invalidated() and not cTB.login_in_progress:
|
||||
@@ -66,9 +68,8 @@ def _draw_welcome_or_error(cTB: c_Toolbox, layout: bpy.types.UILayout) -> None:
|
||||
def _draw_share_addon_errors(cTB: c_Toolbox,
|
||||
layout: bpy.types.UILayout,
|
||||
enabled: bool = True) -> None:
|
||||
# Show terms of service, optin/out.
|
||||
row_opt = layout.row()
|
||||
row_opt.alignment = "LEFT"
|
||||
row_opt.alignment = "CENTER"
|
||||
row_opt.enabled = enabled
|
||||
# __spec__.parent since __package__ got deprecated
|
||||
# Since this module moved into dialogs,
|
||||
@@ -76,237 +77,176 @@ def _draw_share_addon_errors(cTB: c_Toolbox,
|
||||
spec_parent = __spec__.parent
|
||||
spec_parent = spec_parent.split(".")[0]
|
||||
prefs = bpy.context.preferences.addons.get(spec_parent, None)
|
||||
row_opt.prop(prefs.preferences, "reporting_opt_in", text="")
|
||||
twidth = cTB.width_draw_ui - 42 * get_ui_scale(cTB)
|
||||
wrapped_label(cTB, twidth, _t("Share addon errors / usage"), row_opt)
|
||||
|
||||
|
||||
def _draw_switch_email_login(col: bpy.types.UILayout,
|
||||
enabled: bool = True) -> None:
|
||||
row_login_email = col.row()
|
||||
row_login_email.enabled = enabled
|
||||
op_login_email = row_login_email.operator("poliigon.poliigon_user",
|
||||
text=_t("Login via email"),
|
||||
emboss=False)
|
||||
op_login_email.mode = "login_switch_to_email"
|
||||
op_login_email.tooltip = _t("Login via email")
|
||||
|
||||
|
||||
def _draw_browser_login(cTB: c_Toolbox, col: bpy.types.UILayout) -> None:
|
||||
if cTB.login_in_progress:
|
||||
_draw_share_addon_errors(cTB, col, enabled=False)
|
||||
|
||||
row_buttons = col.row(align=True)
|
||||
row_buttons.scale_y = 1.25
|
||||
|
||||
col1 = row_buttons.column(align=True)
|
||||
op_login_website = col1.operator("poliigon.poliigon_user",
|
||||
text=_t("Opening browser..."),
|
||||
depress=True)
|
||||
op_login_website.mode = "none"
|
||||
op_login_website.tooltip = _t("Complete login via opened webpage")
|
||||
col1.enabled = False
|
||||
|
||||
col2 = row_buttons.column(align=True)
|
||||
op_login_cancel = col2.operator("poliigon.poliigon_user",
|
||||
text="",
|
||||
icon="X")
|
||||
op_login_cancel.mode = "login_cancel"
|
||||
op_login_cancel.tooltip = _t("Cancel Log In")
|
||||
|
||||
col.separator()
|
||||
|
||||
_draw_switch_email_login(col, enabled=False)
|
||||
else:
|
||||
_draw_share_addon_errors(cTB, col)
|
||||
|
||||
row_button = col.row()
|
||||
row_button.scale_y = 1.25
|
||||
|
||||
op_login_website = row_button.operator("poliigon.poliigon_user",
|
||||
text=_t("Login via Browser"))
|
||||
op_login_website.mode = "login_with_website"
|
||||
op_login_website.tooltip = _t("Login via Browser")
|
||||
|
||||
col.separator()
|
||||
|
||||
_draw_switch_email_login(col)
|
||||
|
||||
|
||||
def _draw_email_login(cTB: c_Toolbox, col: bpy.types.UILayout) -> None:
|
||||
vProps = bpy.context.window_manager.poliigon_props
|
||||
|
||||
col.label(text="Email")
|
||||
|
||||
row = col.row(align=True)
|
||||
row.prop(vProps, "vEmail")
|
||||
|
||||
col_x = row.column(align=True)
|
||||
op = col_x.operator("poliigon.poliigon_setting",
|
||||
text="",
|
||||
icon="X")
|
||||
op.tooltip = _t("Clear Email")
|
||||
op.mode = "clear_email"
|
||||
|
||||
error_credentials = False
|
||||
has_login_error = cTB.last_login_error is not None
|
||||
error_login = has_login_error and cTB.last_login_error != ERR_LOGIN_TIMEOUT
|
||||
if error_login and "@" not in vProps.vEmail:
|
||||
error_credentials = True
|
||||
|
||||
col.separator()
|
||||
if prefs and prefs.preferences:
|
||||
row_opt.prop(prefs.preferences, "reporting_opt_in", text="")
|
||||
twidth = int(cTB.width_draw_ui - 42 * get_ui_scale(cTB))
|
||||
wrapped_label(
|
||||
cTB,
|
||||
cTB.width_draw_ui - 40 * get_ui_scale(cTB),
|
||||
_t("Email format is invalid e.g. john@example.org"),
|
||||
col,
|
||||
icon="ERROR")
|
||||
col.separator()
|
||||
|
||||
col.label(text=_t("Password"))
|
||||
|
||||
row = col.row(align=True)
|
||||
|
||||
if cTB.settings["show_pass"]:
|
||||
row.prop(vProps, "vPassShow")
|
||||
vPass = vProps.vPassShow
|
||||
|
||||
else:
|
||||
row.prop(vProps, "vPassHide")
|
||||
vPass = vProps.vPassHide
|
||||
|
||||
col_x = row.column(align=True)
|
||||
|
||||
op = col_x.operator("poliigon.poliigon_setting",
|
||||
text="",
|
||||
icon="X")
|
||||
op.tooltip = _t("Clear Password")
|
||||
op.mode = "clear_pass"
|
||||
|
||||
if error_login and len(vPass) < 6:
|
||||
error_credentials = True
|
||||
|
||||
col.separator()
|
||||
wrapped_label(
|
||||
cTB,
|
||||
cTB.width_draw_ui - 40 * get_ui_scale(cTB),
|
||||
_t("Password should be at least 6 characters."),
|
||||
col,
|
||||
icon="ERROR")
|
||||
col.separator()
|
||||
|
||||
_draw_share_addon_errors(cTB, col)
|
||||
|
||||
enable_login_button = len(vProps.vEmail) > 0 and len(vPass) > 0
|
||||
|
||||
row = col.row()
|
||||
row.scale_y = 1.25
|
||||
|
||||
if cTB.login_in_progress:
|
||||
op_login = row.operator("poliigon.poliigon_setting",
|
||||
text=_t("Logging In..."),
|
||||
depress=enable_login_button)
|
||||
op_login.mode = "none"
|
||||
op_login.tooltip = _t("Logging In...")
|
||||
row.enabled = False
|
||||
else:
|
||||
op_login = row.operator("poliigon.poliigon_user",
|
||||
text=_t("Login via email"))
|
||||
op_login.mode = "login"
|
||||
op_login.tooltip = _t("Login via email")
|
||||
|
||||
row.enabled = enable_login_button
|
||||
|
||||
if cTB.last_login_error == ERR_CREDS_FORMAT:
|
||||
# Will draw above with more specific messages if condition true, like
|
||||
# invalid email format or password length.
|
||||
pass
|
||||
elif error_login and not error_credentials:
|
||||
col.separator()
|
||||
|
||||
wrapped_label(
|
||||
cTB,
|
||||
cTB.width_draw_ui - 40 * get_ui_scale(cTB),
|
||||
cTB.last_login_error,
|
||||
col,
|
||||
icon="ERROR",
|
||||
twidth,
|
||||
_t("Share addon errors / usage"),
|
||||
row_opt
|
||||
)
|
||||
|
||||
col.separator()
|
||||
|
||||
op_forgot = col.operator("poliigon.poliigon_link",
|
||||
text=_t("Forgot Password?"),
|
||||
emboss=False)
|
||||
op_forgot.mode = "forgot"
|
||||
op_forgot.tooltip = _t("Reset your Poliigon password")
|
||||
|
||||
op_login_website = col.operator("poliigon.poliigon_user",
|
||||
text=_t("Login via Browser"),
|
||||
emboss=False)
|
||||
op_login_website.mode = "login_switch_to_browser"
|
||||
op_login_website.tooltip = _t("Login via Browser")
|
||||
|
||||
|
||||
def _draw_login(cTB, layout: bpy.types.UILayout) -> None:
|
||||
spc = 1.0 / cTB.width_draw_ui
|
||||
"""Draw the simplified login UI with only web login option."""
|
||||
# Calculate the responsive width threshold with proper scaling
|
||||
responsive_width_threshold = RESPONSIVE_WIDTH_BASE * get_ui_scale(cTB)
|
||||
|
||||
box = layout.box()
|
||||
row = box.row()
|
||||
row.separator(factor=spc)
|
||||
col = row.column()
|
||||
row.separator(factor=spc)
|
||||
|
||||
twidth = cTB.width_draw_ui - 42 * get_ui_scale(cTB)
|
||||
wrapped_label(cTB, twidth, _t("Login"), col)
|
||||
col.separator()
|
||||
|
||||
if cTB.login_mode_browser:
|
||||
_draw_browser_login(cTB, col)
|
||||
|
||||
else:
|
||||
_draw_email_login(cTB, col)
|
||||
|
||||
|
||||
def _draw_signup(cTB, layout: bpy.types.UILayout) -> None:
|
||||
row_welcome = layout.row()
|
||||
row_welcome.alignment = 'CENTER'
|
||||
wrapped_label(
|
||||
cTB,
|
||||
cTB.width_draw_ui,
|
||||
_t("Don't have an account?"),
|
||||
layout,
|
||||
int(cTB.width_draw_ui * 0.9),
|
||||
_t("Welcome to the Poliigon Addon!"),
|
||||
row_welcome
|
||||
)
|
||||
op_signup = layout.operator("poliigon.poliigon_link",
|
||||
text=_t("Sign Up"))
|
||||
op_signup.mode = "signup"
|
||||
op_signup.tooltip = _t("Create a Poliigon account")
|
||||
|
||||
row_subtitle = layout.row()
|
||||
row_subtitle.alignment = 'CENTER'
|
||||
row_subtitle.enabled = False # Darker shading for subtitle
|
||||
wrapped_label(
|
||||
cTB,
|
||||
int(cTB.width_draw_ui * 0.9),
|
||||
_t("Login or Sign Up below in your browser to get started"),
|
||||
row_subtitle,
|
||||
alignment='CENTER'
|
||||
)
|
||||
|
||||
layout.separator()
|
||||
|
||||
# Content with padding for buttons and other elements
|
||||
col = layout.column(align=True)
|
||||
col.separator(factor=0.5)
|
||||
|
||||
if cTB.login_in_progress:
|
||||
# Create a row for the main button
|
||||
main_row = col.row(align=True)
|
||||
main_row.scale_y = 1.25
|
||||
|
||||
# Left side: "Opening browser..." button (90% of width)
|
||||
openingcol = main_row.column(align=True)
|
||||
openingcol.enabled = False
|
||||
main_button = openingcol.operator(
|
||||
"poliigon.poliigon_user",
|
||||
text=_t("Opening browser..."),
|
||||
depress=True
|
||||
)
|
||||
main_button.mode = "none"
|
||||
main_button.tooltip = _t("Complete authentication via opened webpage")
|
||||
|
||||
# Right side: X button (10% of width)
|
||||
cancelcol = main_row.column(align=True)
|
||||
cancel_button = cancelcol.operator(
|
||||
"poliigon.poliigon_user",
|
||||
text="",
|
||||
icon="X"
|
||||
)
|
||||
cancel_button.mode = "login_cancel"
|
||||
cancel_button.tooltip = _t("Cancel Authentication")
|
||||
|
||||
# Disable only the main button, not the whole row
|
||||
main_row.enabled = True
|
||||
|
||||
# Add space where the second button would be
|
||||
col.separator()
|
||||
else:
|
||||
# Login button
|
||||
row_login = col.row()
|
||||
row_login.scale_y = 1.25
|
||||
op_login = row_login.operator(
|
||||
"poliigon.poliigon_user",
|
||||
text=_t("Login"),
|
||||
depress=True
|
||||
)
|
||||
op_login.mode = "login_with_website"
|
||||
op_login.tooltip = _t("Login via Browser")
|
||||
|
||||
col.separator()
|
||||
|
||||
# Pass enabled=False to _draw_share_addon_errors when login is in progress
|
||||
_draw_share_addon_errors(cTB, col, enabled=not cTB.login_in_progress)
|
||||
|
||||
# Help and legal links - responsive layout
|
||||
col.separator()
|
||||
|
||||
# Get current region width and log it for reference
|
||||
region_width = bpy.context.region.width if hasattr(bpy.context, "region") else 0
|
||||
cTB.logger_ui.debug(f"Current region width: {region_width}")
|
||||
|
||||
# Determine layout based on width threshold
|
||||
if region_width > 0 and region_width < responsive_width_threshold:
|
||||
# Narrow layout - display links in three separate rows in new order
|
||||
# 1. Help
|
||||
row_help = col.row()
|
||||
row_help.alignment = 'CENTER'
|
||||
row_help.enabled = not cTB.login_in_progress
|
||||
op_help = row_help.operator(
|
||||
"poliigon.poliigon_link",
|
||||
text=_t("Need Help?"),
|
||||
emboss=False
|
||||
)
|
||||
op_help.mode = "help"
|
||||
op_help.tooltip = _t("Get help with the Poliigon addon")
|
||||
|
||||
# 2. Privacy Policy
|
||||
row_privacy = col.row()
|
||||
row_privacy.alignment = 'CENTER'
|
||||
row_privacy.enabled = not cTB.login_in_progress
|
||||
op_privacy = row_privacy.operator(
|
||||
"poliigon.poliigon_link",
|
||||
text=_t("Privacy Policy"),
|
||||
emboss=False
|
||||
)
|
||||
op_privacy.mode = "privacy"
|
||||
op_privacy.tooltip = _t("View the Privacy Policy")
|
||||
|
||||
# 3. Terms & Conditions
|
||||
row_terms = col.row()
|
||||
row_terms.alignment = 'CENTER'
|
||||
row_terms.enabled = not cTB.login_in_progress
|
||||
op_terms = row_terms.operator(
|
||||
"poliigon.poliigon_link",
|
||||
text=_t("Terms & Conditions"),
|
||||
emboss=False
|
||||
)
|
||||
op_terms.mode = "terms"
|
||||
op_terms.tooltip = _t("View the terms and conditions page")
|
||||
else:
|
||||
# Wide layout - two rows but with reordered links
|
||||
# First row: Help and Privacy Policy
|
||||
row_first = col.row(align=True)
|
||||
row_first.enabled = not cTB.login_in_progress
|
||||
|
||||
op_help = row_first.operator(
|
||||
"poliigon.poliigon_link",
|
||||
text=_t("Need Help?"),
|
||||
emboss=False
|
||||
)
|
||||
op_help.mode = "help"
|
||||
op_help.tooltip = _t("Get help with the Poliigon addon")
|
||||
|
||||
op_privacy = row_first.operator(
|
||||
"poliigon.poliigon_link",
|
||||
text=_t("Privacy Policy"),
|
||||
emboss=False
|
||||
)
|
||||
op_privacy.mode = "privacy"
|
||||
op_privacy.tooltip = _t("View the Privacy Policy")
|
||||
|
||||
# Second row: Terms & Conditions
|
||||
row_second = col.row()
|
||||
row_second.alignment = 'CENTER'
|
||||
row_second.enabled = not cTB.login_in_progress
|
||||
op_terms = row_second.operator(
|
||||
"poliigon.poliigon_link",
|
||||
text=_t("Terms & Conditions"),
|
||||
emboss=False
|
||||
)
|
||||
op_terms.mode = "terms"
|
||||
op_terms.tooltip = _t("View the terms and conditions page")
|
||||
|
||||
|
||||
def _draw_legal(layout: bpy.types.UILayout) -> None:
|
||||
row = layout.row()
|
||||
col = row.column(align=True)
|
||||
|
||||
op_terms = col.operator("poliigon.poliigon_link",
|
||||
text=_t("Terms & Conditions"),
|
||||
emboss=False)
|
||||
op_terms.tooltip = _t("View the terms and conditions page")
|
||||
op_terms.mode = "terms"
|
||||
|
||||
op_privacy = col.operator("poliigon.poliigon_link",
|
||||
text=_t("Privacy Policy"),
|
||||
emboss=False)
|
||||
op_privacy.tooltip = _t("View the Privacy Policy ")
|
||||
op_privacy.mode = "privacy"
|
||||
|
||||
|
||||
# @timer
|
||||
def build_login(cTB):
|
||||
cTB.logger_ui.debug("build_login")
|
||||
|
||||
if cTB.last_login_error is not None:
|
||||
cTB.login_in_progress = 0
|
||||
|
||||
_draw_welcome_or_error(cTB, cTB.vBase)
|
||||
_draw_login(cTB, cTB.vBase)
|
||||
cTB.vBase.separator()
|
||||
_draw_signup(cTB, cTB.vBase)
|
||||
cTB.vBase.separator()
|
||||
_draw_legal(cTB.vBase)
|
||||
|
||||
@@ -0,0 +1,128 @@
|
||||
# #### BEGIN GPL LICENSE BLOCK #####
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#
|
||||
# ##### END GPL LICENSE BLOCK #####
|
||||
|
||||
import bpy
|
||||
|
||||
from ..modules.poliigon_core.multilingual import _t
|
||||
from ..modules.poliigon_core.user import PoliigonUserProfiles
|
||||
from .utils_dlg import (
|
||||
get_ui_scale,
|
||||
wrapped_label)
|
||||
from ..toolbox import c_Toolbox
|
||||
|
||||
|
||||
def _draw_welcome_message(cTB: c_Toolbox, layout: bpy.types.UILayout) -> None:
|
||||
"""Draw the welcome message and setup prompt."""
|
||||
row = layout.row()
|
||||
row.enabled = False
|
||||
row.alignment = "CENTER"
|
||||
wrapped_label(
|
||||
cTB,
|
||||
int(cTB.width_draw_ui * 0.9),
|
||||
_t("Success! You are now logged in."),
|
||||
row,
|
||||
alignment='CENTER'
|
||||
)
|
||||
|
||||
layout.separator()
|
||||
|
||||
wrapped_label(
|
||||
cTB,
|
||||
int(cTB.width_draw_ui * 0.9),
|
||||
_t("Please complete your account setup below to continue"),
|
||||
layout,
|
||||
alignment='CENTER'
|
||||
)
|
||||
|
||||
layout.separator()
|
||||
|
||||
|
||||
def _draw_user_type_selection(cTB: c_Toolbox, layout: bpy.types.UILayout) -> None:
|
||||
"""Draw the user type selection radio buttons."""
|
||||
twidth = cTB.width_draw_ui - 42 * get_ui_scale(cTB)
|
||||
wrapped_label(
|
||||
cTB,
|
||||
int(twidth),
|
||||
_t("Which best describes you?"),
|
||||
layout,
|
||||
alignment="CENTER"
|
||||
)
|
||||
layout.separator()
|
||||
|
||||
if not cTB.signal_for_profile_survey_emitted:
|
||||
cTB.signal_for_profile_survey_emitted = True
|
||||
cTB.signal_view_screen("update_user")
|
||||
|
||||
for user_type in PoliigonUserProfiles.get_list():
|
||||
row = layout.row()
|
||||
row.scale_y = 1.2
|
||||
display_type = PoliigonUserProfiles.from_string(user_type).to_ui_display()
|
||||
|
||||
op = row.operator(
|
||||
"poliigon.poliigon_onboarding_survey",
|
||||
text=_t(display_type))
|
||||
op.user_type = user_type
|
||||
|
||||
layout.separator()
|
||||
|
||||
|
||||
def _draw_email_preference(cTB: c_Toolbox, layout: bpy.types.UILayout) -> None:
|
||||
"""Draw the email preference checkbox."""
|
||||
vProps = bpy.context.window_manager.poliigon_props
|
||||
|
||||
row_opt = layout.row()
|
||||
row_opt.alignment = "LEFT"
|
||||
|
||||
row_opt.prop(vProps, "onboarding_email_preference", text="")
|
||||
|
||||
twidth = cTB.width_draw_ui - 28 * get_ui_scale(cTB)
|
||||
wrapped_label(
|
||||
cTB,
|
||||
int(twidth),
|
||||
_t("Send me emails about new assets and other product updates"),
|
||||
row_opt
|
||||
)
|
||||
|
||||
|
||||
def _draw_onboarding_survey(cTB: c_Toolbox, layout: bpy.types.UILayout) -> None:
|
||||
"""Draw the main onboarding survey form."""
|
||||
spc = 1.0 / cTB.width_draw_ui
|
||||
|
||||
_draw_welcome_message(cTB, layout)
|
||||
|
||||
# User type selection in darker box
|
||||
box = layout.box()
|
||||
row = box.row()
|
||||
row.separator(factor=spc)
|
||||
col = row.column()
|
||||
row.separator(factor=spc)
|
||||
|
||||
_draw_user_type_selection(cTB, col)
|
||||
|
||||
# Email preference outside the box
|
||||
layout.separator()
|
||||
layout.separator()
|
||||
_draw_email_preference(cTB, layout)
|
||||
|
||||
|
||||
def build_onboarding_survey(cTB: c_Toolbox):
|
||||
"""Main function to build the onboarding survey dialog."""
|
||||
vProps = bpy.context.window_manager.poliigon_props
|
||||
# Initialize properties if they don't exist
|
||||
vProps.onboarding_user_type = ""
|
||||
_draw_onboarding_survey(cTB, cTB.vBase)
|
||||
@@ -118,7 +118,9 @@ def show_quick_menu(
|
||||
_imported_model_extras(context, layout)
|
||||
|
||||
# List the different resolution sizes to provide.
|
||||
if asset_data.is_purchased or is_free or cTB.is_unlimited_user():
|
||||
have_size_opts = asset_data.is_purchased or is_free or cTB.is_unlimited_user()
|
||||
have_size_opts &= not asset_data.state.has_error
|
||||
if have_size_opts:
|
||||
for size in sizes:
|
||||
if asset_type == AssetType.TEXTURE:
|
||||
draw_material_sizes(context, size, layout)
|
||||
@@ -152,22 +154,20 @@ def show_quick_menu(
|
||||
|
||||
# Always show view online and high res previews.
|
||||
if not hide_detail_view:
|
||||
# new detail viewer design is unstable on OSX and fails for awhile
|
||||
# for the remainder of the session. For consistency, we disable it
|
||||
# outright for all OSX users until a better solution is found.
|
||||
is_osx = bpy.app.build_platform.lower() == b"darwin"
|
||||
if bpy.app.version >= (4, 2) and not is_osx:
|
||||
op_name = "poliigon.detail_view_open"
|
||||
op_text = _t("View Asset Details")
|
||||
if bpy.app.version >= (4, 2):
|
||||
row_detail_view = layout.row()
|
||||
row_detail_view.operator_context = 'INVOKE_DEFAULT'
|
||||
op = row_detail_view.operator(
|
||||
"poliigon.detail_view",
|
||||
text=_t("View Asset Details"),
|
||||
icon="OUTLINER_OB_IMAGE",
|
||||
)
|
||||
else:
|
||||
op_name = "poliigon.view_thumbnail"
|
||||
op_text = _t("View Large Preview")
|
||||
|
||||
op = layout.operator(
|
||||
op_name,
|
||||
text=op_text,
|
||||
icon="OUTLINER_OB_IMAGE",
|
||||
)
|
||||
op = layout.operator(
|
||||
"poliigon.view_thumbnail",
|
||||
text=_t("View Large Preview"),
|
||||
icon="OUTLINER_OB_IMAGE",
|
||||
)
|
||||
op.asset_id = asset_data.asset_id
|
||||
|
||||
op = layout.operator(
|
||||
@@ -197,15 +197,26 @@ def show_quick_menu(
|
||||
if not is_feature_avail or missing_local_model:
|
||||
return
|
||||
|
||||
# Asset browser sync option
|
||||
client_starting = cTB.lock_client_start.locked()
|
||||
owned = cTB.check_if_purchased(asset_data.asset_id)
|
||||
layout.separator()
|
||||
row = layout.row()
|
||||
op = row.operator(
|
||||
"poliigon.update_asset_browser",
|
||||
text=_t("Synchronize with Asset Browser"),
|
||||
icon="FILE_REFRESH")
|
||||
op.asset_id = asset_id
|
||||
row.enabled = not in_asset_browser and not client_starting
|
||||
msg = _t("Synchronize with Asset Browser")
|
||||
if not owned:
|
||||
msg = _t("Must own to sync with Asset Browser")
|
||||
elif in_asset_browser:
|
||||
msg = _t("Already synced with Asset Browser")
|
||||
elif client_starting:
|
||||
msg = _t("Starting Asset Browser sync...")
|
||||
|
||||
if cTB.user_legacy_own_assets():
|
||||
op = row.operator(
|
||||
"poliigon.update_asset_browser",
|
||||
text=msg,
|
||||
icon="FILE_REFRESH")
|
||||
op.asset_id = asset_id
|
||||
row.enabled = not in_asset_browser and not client_starting and owned
|
||||
|
||||
def draw_material_sizes(
|
||||
context, size: str, layout: bpy.types.UILayout) -> None:
|
||||
|
||||
@@ -99,6 +99,9 @@ def safe_size_apply(cTB,
|
||||
If we try to apply a size which is not recognized as local, it will fail
|
||||
and disrupt further drawing. This function mitigates this problem.
|
||||
"""
|
||||
|
||||
if size_value is None:
|
||||
return
|
||||
try:
|
||||
op_ref.size = size_value
|
||||
except TypeError as e:
|
||||
@@ -157,16 +160,18 @@ def wrapped_label(cTB,
|
||||
add_padding: bool = False,
|
||||
add_padding_top: bool = False,
|
||||
add_padding_bottom: bool = False,
|
||||
alignment: str = 'LEFT'
|
||||
) -> None:
|
||||
"""Text wrap a label based on indicated width."""
|
||||
|
||||
cTB.logger_ui.debug(f"wrapped_label width={width}, text={text}, "
|
||||
f"icon={icon}, add_padding={add_padding}")
|
||||
f"icon={icon}, add_padding={add_padding}, alignment={alignment}")
|
||||
|
||||
list_words = [_word.replace("!@#", " ") for _word in text.split(" ")]
|
||||
|
||||
row = container.row()
|
||||
parent = row.column(align=True)
|
||||
parent.alignment = alignment # Set alignment on the parent column
|
||||
parent.scale_y = 0.8 # To make vertical height more natural for text.
|
||||
|
||||
if add_padding or add_padding_top:
|
||||
@@ -183,16 +188,36 @@ def wrapped_label(cTB,
|
||||
if width_line > width:
|
||||
if first:
|
||||
if icon is None:
|
||||
parent.label(text=line)
|
||||
if alignment == 'LEFT':
|
||||
parent.label(text=line)
|
||||
else:
|
||||
label_row = parent.row()
|
||||
label_row.alignment = alignment
|
||||
label_row.label(text=line)
|
||||
else:
|
||||
parent.label(text=line, icon=icon)
|
||||
if alignment == 'LEFT':
|
||||
parent.label(text=line, icon=icon)
|
||||
else:
|
||||
label_row = parent.row()
|
||||
label_row.alignment = alignment
|
||||
label_row.label(text=line, icon=icon)
|
||||
first = False
|
||||
|
||||
else:
|
||||
if icon is None:
|
||||
parent.label(text=line)
|
||||
if alignment == 'LEFT':
|
||||
parent.label(text=line)
|
||||
else:
|
||||
label_row = parent.row()
|
||||
label_row.alignment = alignment
|
||||
label_row.label(text=line)
|
||||
else:
|
||||
parent.label(text=line, icon="BLANK1")
|
||||
if alignment == 'LEFT':
|
||||
parent.label(text=line, icon="BLANK1")
|
||||
else:
|
||||
label_row = parent.row()
|
||||
label_row.alignment = alignment
|
||||
label_row.label(text=line, icon="BLANK1")
|
||||
|
||||
line = _word + " "
|
||||
|
||||
@@ -201,15 +226,32 @@ def wrapped_label(cTB,
|
||||
|
||||
if line != "":
|
||||
if icon is None:
|
||||
parent.label(text=line)
|
||||
if alignment == 'LEFT':
|
||||
parent.label(text=line)
|
||||
else:
|
||||
label_row = parent.row()
|
||||
label_row.alignment = alignment
|
||||
label_row.label(text=line)
|
||||
else:
|
||||
if first:
|
||||
parent.label(text=line, icon=icon)
|
||||
if alignment == 'LEFT':
|
||||
parent.label(text=line, icon=icon)
|
||||
else:
|
||||
label_row = parent.row()
|
||||
label_row.alignment = alignment
|
||||
label_row.label(text=line, icon=icon)
|
||||
else:
|
||||
parent.label(text=line, icon="BLANK1")
|
||||
if alignment == 'LEFT':
|
||||
parent.label(text=line, icon="BLANK1")
|
||||
else:
|
||||
label_row = parent.row()
|
||||
label_row.alignment = alignment
|
||||
label_row.label(text=line, icon="BLANK1")
|
||||
|
||||
if add_padding or add_padding_bottom:
|
||||
parent.label(text="")
|
||||
spacer = parent.row()
|
||||
spacer.scale_y = 0.3
|
||||
spacer.label(text="")
|
||||
|
||||
|
||||
def separator_p4b(
|
||||
|
||||
Reference in New Issue
Block a user