# #### 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 platform from bpy.types import Panel import bpy from .modules.poliigon_core.assets import AssetType 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, KEY_TAB_LOCAL) from .modules.poliigon_core.multilingual import _t from .dialogs.dlg_account import build_user from .dialogs.dlg_add_node_groups import ( append_poliigon_groups_node_add, POLIIGON_MT_add_node_groups) from .dialogs.dlg_area_categories import build_categories from .dialogs.dlg_area_notifications import notification_banner from .dialogs.dlg_area_tabs import build_areas from .dialogs.dlg_area_upgrade_banner import build_upgrade_banner from .dialogs.dlg_assets import build_assets, POLIIGON_MT_asset_display_options from .dialogs.dlg_init_library import build_library from .dialogs.dlg_login import build_login from .dialogs.dlg_onboarding_survey import build_onboarding_survey from .dialogs.utils_dlg import ( check_dpi, get_ui_scale) from .toolbox import get_context from .toolbox_settings import save_settings from . import reporting def _determine_draw_width() -> None: for vA in bpy.context.screen.areas: if vA.type != "VIEW_3D": continue for vR in vA.regions: if vR.type != "UI": continue panel_padding = 15 * get_ui_scale(cTB) # Left padding. sidebar_width = 15 * get_ui_scale(cTB) # Tabname width. # Mac blender 3.x up seems to be reported wider than # reality; it does not seem affected by UI scale or HDPI. ex_pad = "mac" in platform.platform() ex_pad = ex_pad or "darwin" in platform.platform() ex_pad = ex_pad and bpy.app.version >= (3, 0) if ex_pad: sidebar_width += 17 * get_ui_scale(cTB) w_draw = vR.width - panel_padding - sidebar_width if w_draw < 1: # To avoid div by zero errors below w_draw = 1 if w_draw != cTB.width_draw_ui: cTB.width_draw_ui = w_draw check_dpi(cTB) def _imported_tab_check_assets(area: str, props_wm) -> None: if area != KEY_TAB_IMPORTED: return category_list = cTB.settings["category"] query_key = cTB.get_accumulated_query_cache_key( tab=KEY_TAB_IMPORTED, search=props_wm.search, category_list=category_list) if query_key not in cTB._asset_index.cached_queries: return if len(cTB._asset_index.cached_queries[query_key]) > 0: return cTB.f_GetSceneAssets() def _get_assets_upon_changed_search(area: str) -> None: search = cTB.vSearch[area] if search == cTB.vLastSearch[area]: return # Reset category to "All Assets" # We can't use the operator durinng draw, so we need to do it manually # bpy.ops.poliigon.poliigon_setting(mode="category_0_All Assets") cTB.settings["category"] = [CATEGORY_ALL] cTB.vActiveAsset = None cTB.vActiveMat = None cTB.vActiveMode = None cTB.vActiveCat = [CATEGORY_ALL] cTB.vAssetType = CATEGORY_ALL cTB.vPage[area] = 0 cTB.vPages[area] = 0 cTB.f_GetAssets() if search != "": cTB.signal_search(search) cTB.vLastSearch[area] = search def _build_search(cTB, props_wm, area: str) -> None: row = cTB.vBase.row() row_aligned = row.row(align=True) # NEED SEPARATE PROPS FOR SPECIFIC DESCRIPTIONS row_aligned.prop(props_wm, "search", icon="VIEWZOOM") if len(props_wm.search): search_show_x = 1 else: search_show_x = 0 if search_show_x: op = row_aligned.operator( "poliigon.poliigon_setting", text="", icon="X", ) op.tooltip = _t("Clear Search") op.mode = f"clear_search_{cTB.settings['area']}" def build_ui(ui, context): """Primary draw function used to build the main panel.""" cTB.logger_ui.debug("build_ui") # Flag in request's meta data for Mixpanel cTB._api._mp_relevant = True cTB.vUI = ui cTB.vContext = context props_wm = bpy.context.window_manager.poliigon_props # Reset Filter to Online if any search term is added if props_wm.search != "" and props_wm.search != cTB.vSearch[KEY_TAB_ONLINE]: cTB.settings["area"] = KEY_TAB_ONLINE area = cTB.settings["area"] cTB.vSearch[KEY_TAB_ONLINE] = props_wm.search cTB.vSearch[KEY_TAB_MY_ASSETS] = props_wm.search cTB.vSearch[KEY_TAB_RECENT_DOWNLOADS] = props_wm.search cTB.vSearch[KEY_TAB_IMPORTED] = props_wm.search cTB.vSearch[KEY_TAB_LOCAL] = props_wm.search _imported_tab_check_assets(area, props_wm) _determine_draw_width() _get_assets_upon_changed_search(area) layout = ui.layout layout.alignment = "CENTER" row_base = layout.row() cTB.vBase = row_base.column() cTB.interval_check_update() if cTB.f_add_survey_notification_once(cTB): save_settings(cTB) if not cTB.is_logged_in() or cTB.user is None: build_login(cTB) return # If user_profile is None, "how_will_you_use_poliigon" is null in the API # but don't show the survey if already submitted once this session (in # case the request failed) and also to immediately proceed to the grid. if cTB.user.user_profile is None and cTB.did_show_profile_survey is False: build_onboarding_survey(cTB) return # Here we really need to check settings and not simply get primary path # from addon-core, to get around addon-core providing a default path we # are not interested in. primary_lib_path = cTB.settings_config.get( "library", "primary", fallback=None) if primary_lib_path in [None, ""]: build_library(cTB) return notification_banner(cTB, cTB.vBase) cTB.vBase.separator() cTB.logger_ui.debug("build_ui -> build_upgrade_banner") build_upgrade_banner(cTB) cTB.logger_ui.debug("build_ui -> build_areas") build_areas(cTB) if cTB.settings["show_user"]: build_user(cTB) return _build_search(cTB, props_wm, area) cTB.vActiveCat = cTB.settings["category"] cTB.vAssetType = cTB.vActiveCat[0] cTB.logger_ui.debug("build_ui -> build_categories") build_categories(cTB) cTB.logger_ui.debug("build_ui -> build_assets") build_assets(cTB) # TODO(Andreas): Function not in use (only called from operator # poliigon.poliigon_active in mode "info", which is not used) def f_AssetInfo(cTB, asset_id: int): """Dynamic menu popup call populated based on info on this asset.""" cTB.logger_ui.debug(f"f_AssetInfo asset_id={asset_id}") @reporting.handle_draw() def asset_info_draw(self, context): """Called as part of the popup in operators for info mode.""" asset_data = cTB._asset_index.get_asset(asset_id) asset_type_data = asset_data.get_type_data() asset_name = asset_data.asset_name asset_type = asset_data.asset_type vLayout = self.layout vLayout.alignment = "CENTER" column = vLayout.column(align=True) with cTB.lock_thumbs: column.template_icon(icon_value=cTB.thumbs[asset_name].icon_id, scale=10) row = column.row(align=False) row.label(text=asset_name) op = row.operator( "poliigon.poliigon_asset_options", text="", icon="FILE_FOLDER" ) op.asset_id = asset_id op.mode = "dir" op.tooltip = _t("Open {0} Folder(s)").format(asset_name) op = row.operator( "poliigon.poliigon_link", text="", icon_value=cTB.ui_icons["ICON_poliigon"].icon_id, ) op.mode = str(asset_id) op.asset_id = asset_id op.tooltip = _t("View on Poliigon.com") column.separator() if asset_type == AssetType.MODEL: column.label(text=_t("Models :")) column.separator() column.label(text=_t("Maps :")) vGrid = column.box().grid_flow( row_major=1, columns=4, even_columns=0, even_rows=0, align=False ) tex_maps = asset_type_data.get_maps() # TODO(Andreas): need maps for all sizes for _tex_map in tex_maps: path = _tex_map.get_path() vGrid.label(text=path) column.separator() column.label(text=_t("Map Sizes :")) asset_sizes = asset_type_data.get_size_list() column.box().label(text=" ".join(asset_sizes)) column.separator() bpy.context.window_manager.popover(asset_info_draw, ui_units_x=15) class POLIIGON_PT_toolbox(Panel): bl_idname = "POLIIGON_PT_toolbox" bl_label = "Poliigon" bl_category = "Poliigon" bl_space_type = "VIEW_3D" bl_region_type = "UI" @reporting.handle_draw() def draw(self, context): build_ui(self, context) classes = ( POLIIGON_PT_toolbox, POLIIGON_MT_add_node_groups, POLIIGON_MT_asset_display_options ) cTB = None def register(addon_version: str): global cTB cTB = get_context(addon_version) for cls in classes: bpy.utils.register_class(cls) bpy.types.NODE_MT_add.append(append_poliigon_groups_node_add) def unregister(): bpy.types.NODE_MT_add.remove(append_poliigon_groups_node_add) for cls in reversed(classes): bpy.utils.unregister_class(cls)