Skip to content
Snippets Groups Projects
ui_panels.py 84.6 KiB
Newer Older
  • Learn to ignore specific revisions
  • Vilem Duha's avatar
    Vilem Duha committed
    # ##### 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 #####
    
    
    from blenderkit import paths, ratings, ratings_utils, utils, download, categories, icons, search, resolutions, ui, \
        tasks_queue, \
        autothumb, upload
    
    Vilem Duha's avatar
    Vilem Duha committed
    
    from bpy.types import (
        Panel
    )
    
    from bpy.props import (
        IntProperty,
        FloatProperty,
        FloatVectorProperty,
        StringProperty,
        EnumProperty,
        BoolProperty,
        PointerProperty,
    )
    
    Vilem Duha's avatar
    Vilem Duha committed
    
    import bpy
    
    import os
    
    import random
    
    Vilém Duha's avatar
    Vilém Duha committed
    import logging
    
    import platform
    import ctypes
    
    Vilém Duha's avatar
    Vilém Duha committed
    bk_logger = logging.getLogger('blenderkit')
    
    
    Vilem Duha's avatar
    Vilem Duha committed
    
    #   this was moved to separate interface:
    
    
    def draw_ratings(layout, context, asset):
    
    Vilem Duha's avatar
    Vilem Duha committed
        # layout.operator("wm.url_open", text="Read rating instructions", icon='QUESTION').url = 'https://support.google.com/?hl=en'
    
    Vilém Duha's avatar
    Vilém Duha committed
        # the following shouldn't happen at all in an optimal case,
        # this function should run only when asset was already checked to be existing
        if asset == None:
            return;
    
    Vilém Duha's avatar
    Vilém Duha committed
    
    
        col = layout.column()
    
    Vilem Duha's avatar
    Vilem Duha committed
        bkit_ratings = asset.bkit_ratings
    
    
        # layout.template_icon_view(bkit_ratings, property, show_labels=False, scale=6.0, scale_popup=5.0)
    
        row = col.row()
    
        row.prop(bkit_ratings, 'rating_quality_ui', expand=True, icon_only=True, emboss=False)
        if bkit_ratings.rating_quality > 0:
    
            col.separator()
            col.prop(bkit_ratings, 'rating_work_hours')
        # w = context.region.width
    
    Vilém Duha's avatar
    Vilém Duha committed
        # layout.label(text='problems')
        # layout.prop(bkit_ratings, 'rating_problems', text='')
        # layout.label(text='compliments')
        # layout.prop(bkit_ratings, 'rating_compliments', text='')
    
        # row = layout.row()
        # op = row.operator("object.blenderkit_rating_upload", text="Send rating", icon='URL')
        # return op
    
    Vilém Duha's avatar
    Vilém Duha committed
        # re-enable layout if included in longer panel
    
    def draw_not_logged_in(source, message='Please Login/Signup to use this feature'):
    
        title = "You aren't logged in"
    
    Vilém Duha's avatar
    Vilém Duha committed
        def draw_message(source, context):
            layout = source.layout
    
            utils.label_multiline(layout, text=message)
    
    Vilém Duha's avatar
    Vilém Duha committed
            draw_login_buttons(layout)
    
    Vilém Duha's avatar
    Vilém Duha committed
        bpy.context.window_manager.popup_menu(draw_message, title=title, icon='INFO')
    
    Vilem Duha's avatar
    Vilem Duha committed
    def draw_upload_common(layout, props, asset_type, context):
    
        op = layout.operator("wm.url_open", text=f"Read {asset_type.lower()} upload instructions",
    
    Vilem Duha's avatar
    Vilem Duha committed
                             icon='QUESTION')
        if asset_type == 'MODEL':
            op.url = paths.BLENDERKIT_MODEL_UPLOAD_INSTRUCTIONS_URL
        if asset_type == 'MATERIAL':
            op.url = paths.BLENDERKIT_MATERIAL_UPLOAD_INSTRUCTIONS_URL
    
        if asset_type == 'BRUSH':
            op.url = paths.BLENDERKIT_BRUSH_UPLOAD_INSTRUCTIONS_URL
    
        if asset_type == 'SCENE':
            op.url = paths.BLENDERKIT_SCENE_UPLOAD_INSTRUCTIONS_URL
        if asset_type == 'HDR':
            op.url = paths.BLENDERKIT_HDR_UPLOAD_INSTRUCTIONS_URL
    
    Vilem Duha's avatar
    Vilem Duha committed
    
        row = layout.row(align=True)
        if props.upload_state != '':
    
            utils.label_multiline(layout, text=props.upload_state, width=context.region.width)
    
    Vilem Duha's avatar
    Vilem Duha committed
        if props.uploading:
            op = layout.operator('object.kill_bg_process', text="", icon='CANCEL')
            op.process_source = asset_type
            op.process_type = 'UPLOAD'
            layout = layout.column()
            layout.enabled = False
        # if props.upload_state.find('Error') > -1:
        #     layout.label(text = props.upload_state)
    
        if props.asset_base_id == '':
            optext = 'Upload %s' % asset_type.lower()
    
            op = layout.operator("object.blenderkit_upload", text=optext, icon='EXPORT')
            op.asset_type = asset_type
    
            op.reupload = False
    
            # make sure everything gets uploaded.
    
            op.main_file = True
            op.metadata = True
            op.thumbnail = True
    
    Vilem Duha's avatar
    Vilem Duha committed
    
        if props.asset_base_id != '':
    
            op = layout.operator("object.blenderkit_upload", text='Reupload asset', icon='EXPORT')
    
    Vilem Duha's avatar
    Vilem Duha committed
            op.asset_type = asset_type
    
            op.reupload = True
    
    
    Vilem Duha's avatar
    Vilem Duha committed
            op = layout.operator("object.blenderkit_upload", text='Upload as new asset', icon='EXPORT')
            op.asset_type = asset_type
    
            op.reupload = False
    
            # layout.label(text = 'asset id, overwrite only for reuploading')
    
            layout.label(text='asset has a version online.')
    
            # row = layout.row()
            # row.enabled = False
            # row.prop(props, 'asset_base_id', icon='FILE_TICK')
            # row = layout.row()
            # row.enabled = False
            # row.prop(props, 'id', icon='FILE_TICK')
    
    Vilem Duha's avatar
    Vilem Duha committed
        layout.prop(props, 'category')
    
        if props.category != 'NONE' and props.subcategory != 'NONE':
    
    Vilem Duha's avatar
    Vilem Duha committed
            layout.prop(props, 'subcategory')
    
        if props.subcategory != 'NONE' and props.subcategory1 != 'NONE':
            layout.prop(props, 'subcategory1')
    
        layout.prop(props, 'is_private', expand=True)
        if props.is_private == 'PUBLIC':
    
            layout.prop(props, 'license')
    
            layout.prop(props, 'is_free', expand=True)
    
        prop_needed(layout, props, 'name', props.name)
        if props.is_private == 'PUBLIC':
            prop_needed(layout, props, 'description', props.description)
            prop_needed(layout, props, 'tags', props.tags)
        else:
            layout.prop(props, 'description')
            layout.prop(props, 'tags')
    
    Vilém Duha's avatar
    Vilém Duha committed
    
    
    Vilem Duha's avatar
    Vilem Duha committed
    def poll_local_panels():
        user_preferences = bpy.context.preferences.addons['blenderkit'].preferences
        return user_preferences.panel_behaviour == 'BOTH' or user_preferences.panel_behaviour == 'LOCAL'
    
    
    
    def prop_needed(layout, props, name, value='', is_not_filled=''):
    
    Vilem Duha's avatar
    Vilem Duha committed
        row = layout.row()
        if value == is_not_filled:
            # row.label(text='', icon = 'ERROR')
            icon = 'ERROR'
    
            row.alert = True
    
    Vilém Duha's avatar
    Vilém Duha committed
            row.prop(props, name)  # , icon=icon)
    
            row.alert = False
    
    Vilem Duha's avatar
    Vilem Duha committed
        else:
            # row.label(text='', icon = 'FILE_TICK')
            icon = None
            row.prop(props, name)
    
    
    def draw_panel_hdr_upload(self, context):
        layout = self.layout
        ui_props = bpy.context.scene.blenderkitUI
    
        # layout.prop_search(ui_props, "hdr_upload_image", bpy.data, "images")
        layout.prop(ui_props, "hdr_upload_image")
    
        hdr = utils.get_active_HDR()
    
        if hdr is not None:
            props = hdr.blenderkit
    
            layout = self.layout
    
            draw_upload_common(layout, props, 'HDR', context)
    
    
    def draw_panel_hdr_search(self, context):
        s = context.scene
        props = s.blenderkit_HDR
    
        layout = self.layout
        row = layout.row()
        row.prop(props, "search_keywords", text="", icon='VIEWZOOM')
        draw_assetbar_show_hide(row, props)
        layout.prop(props, "own_only")
    
        utils.label_multiline(layout, text=props.report)
    
    Vilém Duha's avatar
    Vilém Duha committed
    def draw_thumbnail_upload_panel(layout, props):
        update = False
        tex = autothumb.get_texture_ui(props.thumbnail, '.upload_preview')
        if not tex or not tex.image:
            return
        box = layout.box()
        box.template_icon(icon_value=tex.image.preview.icon_id, scale=6.0)
    
    
    Vilem Duha's avatar
    Vilem Duha committed
    def draw_panel_model_upload(self, context):
        ob = bpy.context.active_object
        while ob.parent is not None:
            ob = ob.parent
        props = ob.blenderkit
    
        layout = self.layout
    
        draw_upload_common(layout, props, 'MODEL', context)
    
        col = layout.column()
        if props.is_generating_thumbnail:
            col.enabled = False
    
    Vilém Duha's avatar
    Vilém Duha committed
    
        draw_thumbnail_upload_panel(col, props)
    
    
        prop_needed(col, props, 'thumbnail', props.thumbnail)
    
    Vilem Duha's avatar
    Vilem Duha committed
        if bpy.context.scene.render.engine in ('CYCLES', 'BLENDER_EEVEE'):
            col.operator("object.blenderkit_generate_thumbnail", text='Generate thumbnail', icon='IMAGE')
    
        # row = layout.row(align=True)
        if props.is_generating_thumbnail:
            row = layout.row(align=True)
            row.label(text=props.thumbnail_generating_state)
            op = row.operator('object.kill_bg_process', text="", icon='CANCEL')
            op.process_source = 'MODEL'
            op.process_type = 'THUMBNAILER'
        elif props.thumbnail_generating_state != '':
    
            utils.label_multiline(layout, text=props.thumbnail_generating_state)
    
    Vilem Duha's avatar
    Vilem Duha committed
    
        # prop_needed(layout, props, 'style', props.style)
        # prop_needed(layout, props, 'production_level', props.production_level)
        layout.prop(props, 'style')
        layout.prop(props, 'production_level')
    
        layout.prop(props, 'condition')
        layout.prop(props, 'pbr')
        layout.label(text='design props:')
        layout.prop(props, 'manufacturer')
        layout.prop(props, 'designer')
        layout.prop(props, 'design_collection')
        layout.prop(props, 'design_variant')
        layout.prop(props, 'use_design_year')
        if props.use_design_year:
            layout.prop(props, 'design_year')
    
        row = layout.row()
        row.prop(props, 'work_hours')
    
        layout.prop(props, 'adult')
    
    
    def draw_panel_scene_upload(self, context):
        s = bpy.context.scene
        props = s.blenderkit
    
        layout = self.layout
    
        # if bpy.app.debug_value != -1:
        #     layout.label(text='Scene upload not Implemented')
        #     return
    
    Vilem Duha's avatar
    Vilem Duha committed
        draw_upload_common(layout, props, 'SCENE', context)
    
        #    layout = layout.column()
    
        # row = layout.row()
    
        # if props.dimensions[0] + props.dimensions[1] == 0 and props.face_count == 0:
        #     icon = 'ERROR'
        #     layout.operator("object.blenderkit_auto_tags", text='Auto fill tags', icon=icon)
        # else:
        #     layout.operator("object.blenderkit_auto_tags", text='Auto fill tags')
    
        col = layout.column()
        # if props.is_generating_thumbnail:
        #     col.enabled = False
    
    Vilém Duha's avatar
    Vilém Duha committed
        draw_thumbnail_upload_panel(col, props)
    
    
    Vilem Duha's avatar
    Vilem Duha committed
        prop_needed(col, props, 'thumbnail', props.has_thumbnail, False)
        # if bpy.context.scene.render.engine == 'CYCLES':
        #     col.operator("object.blenderkit_generate_thumbnail", text='Generate thumbnail', icon='IMAGE_COL')
    
        # row = layout.row(align=True)
        # if props.is_generating_thumbnail:
        #     row = layout.row(align=True)
        #     row.label(text = props.thumbnail_generating_state)
        #     op = row.operator('object.kill_bg_process', text="", icon='CANCEL')
        #     op.process_source = 'MODEL'
        #     op.process_type = 'THUMBNAILER'
        # elif props.thumbnail_generating_state != '':
    
        #    utils.label_multiline(layout, text = props.thumbnail_generating_state)
    
    Vilem Duha's avatar
    Vilem Duha committed
    
        layout.prop(props, 'style')
        layout.prop(props, 'production_level')
        layout.prop(props, 'use_design_year')
        if props.use_design_year:
            layout.prop(props, 'design_year')
        layout.prop(props, 'condition')
        row = layout.row()
        row.prop(props, 'work_hours')
        layout.prop(props, 'adult')
    
    
    Vilém Duha's avatar
    Vilém Duha committed
    
    
    def draw_assetbar_show_hide(layout, props):
        s = bpy.context.scene
        ui_props = s.blenderkitUI
    
        if ui_props.assetbar_on:
            icon = 'HIDE_OFF'
    
            ttip = 'Click to Hide Asset Bar'
    
        else:
            icon = 'HIDE_ON'
    
            ttip = 'Click to Show Asset Bar'
    
        preferences = bpy.context.preferences.addons['blenderkit'].preferences
        if preferences.experimental_features:
    
            op = layout.operator('view3d.blenderkit_asset_bar_widget', text='', icon=icon)
    
            op.keep_running = False
            op.do_search = False
            op.tooltip = ttip
        else:
            op = layout.operator('view3d.blenderkit_asset_bar', text='', icon=icon)
            op.keep_running = False
            op.do_search = False
    
            op.tooltip = ttip
    
    Vilem Duha's avatar
    Vilem Duha committed
    
    def draw_panel_model_search(self, context):
        s = context.scene
    
    Vilem Duha's avatar
    Vilem Duha committed
        props = s.blenderkit_models
        layout = self.layout
    
    
        row = layout.row()
        row.prop(props, "search_keywords", text="", icon='VIEWZOOM')
        draw_assetbar_show_hide(row, props)
    
    Vilem Duha's avatar
    Vilem Duha committed
    
        icon = 'NONE'
    
        if props.report == 'You need Full plan to get this item.':
    
    Vilem Duha's avatar
    Vilem Duha committed
            icon = 'ERROR'
    
        utils.label_multiline(layout, text=props.report, icon=icon)
    
        if props.report == 'You need Full plan to get this item.':
            layout.operator("wm.url_open", text="Get Full plan", icon='URL').url = paths.BLENDERKIT_PLANS
    
    Vilém Duha's avatar
    Vilém Duha committed
        # layout.prop(props, "search_style")
        # layout.prop(props, "own_only")
        # layout.prop(props, "free_only")
    
    Vilem Duha's avatar
    Vilem Duha committed
        # if props.search_style == 'OTHER':
        #     layout.prop(props, "search_style_other")
        # layout.prop(props, "search_engine")
        # col = layout.column()
        # layout.prop(props, 'append_link', expand=True, icon_only=False)
        # layout.prop(props, 'import_as', expand=True, icon_only=False)
    
    
        # draw_panel_categories(self, context)
    
    Vilem Duha's avatar
    Vilem Duha committed
    
    
    def draw_panel_scene_search(self, context):
        s = context.scene
        props = s.blenderkit_scene
        layout = self.layout
        # layout.label(text = "common search properties:")
    
        row = layout.row()
        row.prop(props, "search_keywords", text="", icon='VIEWZOOM')
        draw_assetbar_show_hide(row, props)
    
    Vilém Duha's avatar
    Vilém Duha committed
        layout.prop(props, "own_only")
    
        utils.label_multiline(layout, text=props.report)
    
        # layout.prop(props, "search_style")
        # if props.search_style == 'OTHER':
        #     layout.prop(props, "search_style_other")
    
    Vilem Duha's avatar
    Vilem Duha committed
        # layout.prop(props, "search_engine")
    
    Vilem Duha's avatar
    Vilem Duha committed
        layout.separator()
    
        # draw_panel_categories(self, context)
    
    Vilem Duha's avatar
    Vilem Duha committed
    
    
    class VIEW3D_PT_blenderkit_model_properties(Panel):
        bl_category = "BlenderKit"
        bl_idname = "VIEW3D_PT_blenderkit_model_properties"
        bl_space_type = 'VIEW_3D'
        bl_region_type = 'UI'
    
        bl_label = "Selected Model"
    
    Vilem Duha's avatar
    Vilem Duha committed
        bl_context = "objectmode"
    
        @classmethod
        def poll(cls, context):
    
            p = bpy.context.view_layer.objects.active is not None
    
    Vilem Duha's avatar
    Vilem Duha committed
            return p
    
        def draw(self, context):
            # draw asset properties here
            layout = self.layout
    
    
            o = utils.get_active_model()
            # o = bpy.context.active_object
            if o.get('asset_data') is None:
    
                utils.label_multiline(layout,
                                      text='To upload this asset to BlenderKit, go to the Find and Upload Assets panel.')
    
                layout.prop(o, 'name')
    
    
            if o.get('asset_data') is not None:
                ad = o['asset_data']
                layout.label(text=str(ad['name']))
                if o.instance_type == 'COLLECTION' and o.instance_collection is not None:
                    layout.operator('object.blenderkit_bring_to_scene', text='Bring to scene')
    
    Vilém Duha's avatar
    Vilém Duha committed
    
    
                layout.label(text='Asset tools:')
    
                draw_asset_context_menu(self.layout, context, ad, from_panel=True)
    
    Vilém Duha's avatar
    Vilém Duha committed
                # if 'rig' in ad['tags']:
                #     # layout.label(text = 'can make proxy')
                #     layout.operator('object.blenderkit_make_proxy', text = 'Make Armature proxy')
            # fast upload, blocked by now
            # else:
            #     op = layout.operator("object.blenderkit_upload", text='Store as private', icon='EXPORT')
            #     op.asset_type = 'MODEL'
            #     op.fast = True
            # fun override project, not finished
            # layout.operator('object.blenderkit_color_corrector')
    
    
    class NODE_PT_blenderkit_material_properties(Panel):
        bl_category = "BlenderKit"
        bl_idname = "NODE_PT_blenderkit_material_properties"
        bl_space_type = 'NODE_EDITOR'
        bl_region_type = 'UI'
        bl_label = "Selected Material"
        bl_context = "objectmode"
    
        @classmethod
        def poll(cls, context):
            p = bpy.context.view_layer.objects.active is not None and bpy.context.active_object.active_material is not None
            return p
    
        def draw(self, context):
            # draw asset properties here
            layout = self.layout
    
            m = bpy.context.active_object.active_material
            # o = bpy.context.active_object
            if m.get('asset_data') is None and m.blenderkit.id == '':
                utils.label_multiline(layout,
                                      text='To upload this asset to BlenderKit, go to the Find and Upload Assets panel.')
                layout.prop(m, 'name')
    
            if m.get('asset_data') is not None:
                ad = m['asset_data']
                layout.label(text=str(ad['name']))
    
                layout.label(text='Asset tools:')
    
                draw_asset_context_menu(self.layout, context, ad, from_panel=True)
    
                # if 'rig' in ad['tags']:
                #     # layout.label(text = 'can make proxy')
                #     layout.operator('object.blenderkit_make_proxy', text = 'Make Armature proxy')
    
            # fast upload, blocked by now
    
            # else:
            #     op = layout.operator("object.blenderkit_upload", text='Store as private', icon='EXPORT')
            #     op.asset_type = 'MODEL'
            #     op.fast = True
    
            # fun override project, not finished
    
    Vilem Duha's avatar
    Vilem Duha committed
            # layout.operator('object.blenderkit_color_corrector')
    
    
    
    def draw_rating_asset(self, context, asset):
    
        layout = self.layout
        col = layout.box()
        # split = layout.split(factor=0.5)
        # col1 = split.column()
        # col2 = split.column()
    
        # print('%s_search' % asset['asset_data']['assetType'])
    
        directory = paths.get_temp_dir('%s_search' % asset['asset_data']['assetType'])
        tpath = os.path.join(directory, asset['asset_data']['thumbnail_small'])
        for image in bpy.data.images:
            if image.filepath == tpath:
                # split = row.split(factor=1.0, align=False)
                col.template_icon(icon_value=image.preview.icon_id, scale=6.0)
                break;
            # layout.label(text = '', icon_value=image.preview.icon_id, scale = 10)
        col.label(text=asset.name)
        draw_ratings(col, context, asset=asset)
    
    
    class VIEW3D_PT_blenderkit_ratings(Panel):
        bl_category = "BlenderKit"
        bl_idname = "VIEW3D_PT_blenderkit_ratings"
        bl_space_type = 'VIEW_3D'
        bl_region_type = 'UI'
        bl_label = "Please rate"
        bl_context = "objectmode"
    
        @classmethod
        def poll(cls, context):
            #
            p = bpy.context.view_layer.objects.active is not None
            return p
    
        def draw(self, context):
    
            # TODO make a list of assets inside asset appending code, to happen only when assets are added to the scene.
    
            # draw asset properties here
            layout = self.layout
            assets = ratings.get_assets_for_rating()
    
            if len(assets) > 0:
    
                utils.label_multiline(layout, text='Please help BlenderKit community by rating these assets:')
    
    
                for a in assets:
    
                    if a.bkit_ratings.rating_work_hours == 0:
    
                        draw_rating_asset(self, context, asset=a)
    
    def draw_login_progress(layout):
        layout.label(text='Login through browser')
        layout.label(text='in progress.')
        layout.operator("wm.blenderkit_login_cancel", text="Cancel", icon='CANCEL')
    
    Vilem Duha's avatar
    Vilem Duha committed
    class VIEW3D_PT_blenderkit_profile(Panel):
        bl_category = "BlenderKit"
        bl_idname = "VIEW3D_PT_blenderkit_profile"
        bl_space_type = 'VIEW_3D'
        bl_region_type = 'UI'
    
    Vilém Duha's avatar
    Vilém Duha committed
        bl_label = "BlenderKit Profile"
    
    Vilem Duha's avatar
    Vilem Duha committed
    
        @classmethod
        def poll(cls, context):
    
    Vilem Duha's avatar
    Vilem Duha committed
    
        def draw(self, context):
            # draw asset properties here
            layout = self.layout
            user_preferences = bpy.context.preferences.addons['blenderkit'].preferences
    
            if user_preferences.login_attempt:
    
    Vilem Duha's avatar
    Vilem Duha committed
                return
    
    
    Vilém Duha's avatar
    Vilém Duha committed
            if user_preferences.api_key != '':
    
    Vilem Duha's avatar
    Vilem Duha committed
                me = bpy.context.window_manager.get('bkit profile')
                if me is not None:
                    me = me['user']
    
                    # user name
    
                    if len(me['firstName']) > 0 or len(me['lastName']) > 0:
    
                        layout.label(text=f"Me: {me['firstName']} {me['lastName']}")
                    else:
                        layout.label(text=f"Me: {me['email']}")
    
    Vilém Duha's avatar
    Vilém Duha committed
                    # layout.label(text='Email: %s' % (me['email']))
    
                    # plan information
    
    
                    if me.get('currentPlanName') is not None:
                        pn = me['currentPlanName']
                        pcoll = icons.icon_collections["main"]
                        if pn == 'Free':
                            my_icon = pcoll['free']
                        else:
                            my_icon = pcoll['full']
    
                        row = layout.row()
                        row.label(text='My plan:')
    
                        row.label(text='%s plan' % pn, icon_value=my_icon.icon_id)
    
                            layout.operator("wm.url_open", text="Change plan",
    
                                            icon='URL').url = paths.get_bkit_url() + paths.BLENDERKIT_PLANS
    
    Vilém Duha's avatar
    Vilém Duha committed
    
    
                    # storage statistics
    
    Vilém Duha's avatar
    Vilém Duha committed
                    # if me.get('sumAssetFilesSize') is not None:  # TODO remove this when production server has these too.
                    #     layout.label(text='My public assets: %i MiB' % (me['sumAssetFilesSize']))
                    # if me.get('sumPrivateAssetFilesSize') is not None:
                    #     layout.label(text='My private assets: %i MiB' % (me['sumPrivateAssetFilesSize']))
    
                    if me.get('remainingPrivateQuota') is not None:
    
    Vilém Duha's avatar
    Vilém Duha committed
                        layout.label(text='My free storage: %i MiB' % (me['remainingPrivateQuota']))
    
                layout.operator("wm.url_open", text="See my uploads",
    
                                icon='URL').url = paths.get_bkit_url() + paths.BLENDERKIT_USER_ASSETS
    
    Vilem Duha's avatar
    Vilem Duha committed
    
    
    
    Vilém Duha's avatar
    Vilém Duha committed
    class VIEW3D_PT_blenderkit_login(Panel):
        bl_category = "BlenderKit"
        bl_idname = "VIEW3D_PT_blenderkit_login"
        bl_space_type = 'VIEW_3D'
        bl_region_type = 'UI'
        bl_label = "BlenderKit Login"
    
        @classmethod
        def poll(cls, context):
            return True
    
        def draw(self, context):
            layout = self.layout
            user_preferences = bpy.context.preferences.addons['blenderkit'].preferences
    
            if user_preferences.login_attempt:
                draw_login_progress(layout)
                return
    
            if user_preferences.enable_oauth:
                draw_login_buttons(layout)
    
    
    Vilém Duha's avatar
    Vilém Duha committed
    
    
    Vilem Duha's avatar
    Vilem Duha committed
    def draw_panel_model_rating(self, context):
    
        # o = bpy.context.active_object
        o = utils.get_active_model()
        # print('ratings active',o)
    
        draw_ratings(self.layout, context, asset=o)  # , props)
    
        # op.asset_type = 'MODEL'
    
    Vilem Duha's avatar
    Vilem Duha committed
    
    
    def draw_panel_material_upload(self, context):
        o = bpy.context.active_object
        mat = bpy.context.active_object.active_material
    
        props = mat.blenderkit
        layout = self.layout
    
        draw_upload_common(layout, props, 'MATERIAL', context)
    
        # THUMBNAIL
    
    Vilém Duha's avatar
    Vilém Duha committed
        row = layout.column()
    
    Vilem Duha's avatar
    Vilem Duha committed
        if props.is_generating_thumbnail:
            row.enabled = False
    
    
    Vilém Duha's avatar
    Vilém Duha committed
        draw_thumbnail_upload_panel(row, props)
    
    Vilém Duha's avatar
    Vilém Duha committed
        prop_needed(row, props, 'thumbnail', props.has_thumbnail, False)
    
    
        if bpy.context.scene.render.engine in ('CYCLES', 'BLENDER_EEVEE'):
    
            layout.operator("object.blenderkit_generate_material_thumbnail", text='Render thumbnail with Cycles',
                            icon='EXPORT')
    
    Vilem Duha's avatar
    Vilem Duha committed
        if props.is_generating_thumbnail:
            row = layout.row(align=True)
            row.label(text=props.thumbnail_generating_state, icon='RENDER_STILL')
            op = row.operator('object.kill_bg_process', text="", icon='CANCEL')
            op.process_source = 'MATERIAL'
            op.process_type = 'THUMBNAILER'
        elif props.thumbnail_generating_state != '':
    
            utils.label_multiline(layout, text=props.thumbnail_generating_state)
    
        layout.prop(props, 'style')
        # if props.style == 'OTHER':
        #     layout.prop(props, 'style_other')
        # layout.prop(props, 'engine')
        # if props.engine == 'OTHER':
        #     layout.prop(props, 'engine_other')
        # layout.prop(props,'shaders')#TODO autofill on upload
        # row = layout.row()
    
        layout.prop(props, 'pbr')
        layout.prop(props, 'uv')
        layout.prop(props, 'animated')
        layout.prop(props, 'texture_size_meters')
    
    
    Vilem Duha's avatar
    Vilem Duha committed
        # tname = "." + bpy.context.active_object.active_material.name + "_thumbnail"
        # if props.has_thumbnail and bpy.data.textures.get(tname) is not None:
        #     row = layout.row()
        #     # row.scale_y = 1.5
        #     row.template_preview(bpy.data.textures[tname], preview_id='test')
    
    
    def draw_panel_material_search(self, context):
        wm = context.scene
        props = wm.blenderkit_mat
    
        layout = self.layout
    
        row = layout.row()
        row.prop(props, "search_keywords", text="", icon='VIEWZOOM')
        draw_assetbar_show_hide(row, props)
    
        utils.label_multiline(layout, text=props.report)
    
        # layout.prop(props, 'search_style')F
    
        # if props.search_style == 'OTHER':
        #     layout.prop(props, 'search_style_other')
        # layout.prop(props, 'search_engine')
        # if props.search_engine == 'OTHER':
        #     layout.prop(props, 'search_engine_other')
    
        # draw_panel_categories(self, context)
    
    Vilém Duha's avatar
    Vilém Duha committed
    
    
    Vilem Duha's avatar
    Vilem Duha committed
    def draw_panel_material_ratings(self, context):
    
        asset = bpy.context.active_object.active_material
        draw_ratings(self.layout, context, asset)  # , props)
    
        # op.asset_type = 'MATERIAL'
    
    Vilem Duha's avatar
    Vilem Duha committed
    
    
    def draw_panel_brush_upload(self, context):
        brush = utils.get_active_brush()
        if brush is not None:
            props = brush.blenderkit
    
            layout = self.layout
    
            draw_upload_common(layout, props, 'BRUSH', context)
    
    
    def draw_panel_brush_search(self, context):
    
        s = context.scene
        props = s.blenderkit_brush
    
    Vilem Duha's avatar
    Vilem Duha committed
    
        layout = self.layout
    
        row = layout.row()
        row.prop(props, "search_keywords", text="", icon='VIEWZOOM')
        draw_assetbar_show_hide(row, props)
    
    Vilém Duha's avatar
    Vilém Duha committed
        layout.prop(props, "own_only")
    
        utils.label_multiline(layout, text=props.report)
    
        # draw_panel_categories(self, context)
    
    Vilem Duha's avatar
    Vilem Duha committed
    
    
    def draw_panel_brush_ratings(self, context):
        # props = utils.get_brush_props(context)
    
        brush = utils.get_active_brush()
    
        draw_ratings(self.layout, context, asset=brush)  # , props)
    
        #
        # op.asset_type = 'BRUSH'
    
    def draw_login_buttons(layout, invoke=False):
    
        user_preferences = bpy.context.preferences.addons['blenderkit'].preferences
    
        if user_preferences.login_attempt:
    
            if invoke:
                layout.operator_context = 'INVOKE_DEFAULT'
            else:
                layout.operator_context = 'EXEC_DEFAULT'
    
    Vilém Duha's avatar
    Vilém Duha committed
            if user_preferences.api_key == '':
                layout.operator("wm.blenderkit_login", text="Login",
                                icon='URL').signup = False
                layout.operator("wm.blenderkit_login", text="Sign up",
                                icon='URL').signup = True
    
            else:
                layout.operator("wm.blenderkit_login", text="Login as someone else",
    
                                icon='URL').signup = False
    
    Vilém Duha's avatar
    Vilém Duha committed
                layout.operator("wm.blenderkit_logout", text="Logout",
                                icon='URL')
    
    
    
    class VIEW3D_PT_blenderkit_advanced_model_search(Panel):
        bl_category = "BlenderKit"
        bl_idname = "VIEW3D_PT_blenderkit_advanced_model_search"
    
        bl_parent_id = "VIEW3D_PT_blenderkit_unified"
    
        bl_space_type = 'VIEW_3D'
        bl_region_type = 'UI'
    
        bl_label = "Search filters"
        bl_options = {'DEFAULT_CLOSED'}
    
    
        @classmethod
        def poll(cls, context):
    
            s = context.scene
            ui_props = s.blenderkitUI
    
    Vilém Duha's avatar
    Vilém Duha committed
            return ui_props.down_up == 'SEARCH' and ui_props.asset_type == 'MODEL'
    
    
        def draw(self, context):
            s = context.scene
    
            props = s.blenderkit_models
            layout = self.layout
            layout.separator()
    
            # layout.label(text = "common searches keywords:")
            # layout.prop(props, "search_global_keywords", text = "")
            # layout.prop(props, "search_modifier_keywords")
            # if props.search_engine == 'OTHER':
            #     layout.prop(props, "search_engine_keyword")
    
    
    Vilém Duha's avatar
    Vilém Duha committed
            layout.prop(props, "own_only")
            layout.prop(props, "free_only")
            layout.prop(props, "search_style")
    
    
    Vilém Duha's avatar
    Vilém Duha committed
            layout.prop(props, "search_design_year", text='Designed in Year')
    
            if props.search_design_year:
                row = layout.row(align=True)
    
    Vilém Duha's avatar
    Vilém Duha committed
                row.prop(props, "search_design_year_min", text='Min')
                row.prop(props, "search_design_year_max", text='Max')
    
    Vilém Duha's avatar
    Vilém Duha committed
            layout.prop(props, "search_polycount", text='Poly Count ')
    
            if props.search_polycount:
                row = layout.row(align=True)
    
    Vilém Duha's avatar
    Vilém Duha committed
                row.prop(props, "search_polycount_min", text='Min')
                row.prop(props, "search_polycount_max", text='Max')
    
    Vilém Duha's avatar
    Vilém Duha committed
            layout.prop(props, "search_texture_resolution", text='Texture Resolutions')
    
            if props.search_texture_resolution:
                row = layout.row(align=True)
    
    Vilém Duha's avatar
    Vilém Duha committed
                row.prop(props, "search_texture_resolution_min", text='Min')
                row.prop(props, "search_texture_resolution_max", text='Max')
    
    Vilém Duha's avatar
    Vilém Duha committed
            layout.prop(props, "search_file_size", text='File Size (MB)')
    
            if props.search_file_size:
                row = layout.row(align=True)
    
    Vilém Duha's avatar
    Vilém Duha committed
                row.prop(props, "search_file_size_min", text='Min')
                row.prop(props, "search_file_size_max", text='Max')
    
            # AGE
            layout.prop(props, "search_condition", text='Condition')  # , text ='condition of object new/old e.t.c.')
    
    
            # layout.prop(props, "search_procedural", expand=True)
            # ADULT
            # layout.prop(props, "search_adult")  # , text ='condition of object new/old e.t.c.')
    
    
    class VIEW3D_PT_blenderkit_advanced_material_search(Panel):
        bl_category = "BlenderKit"
        bl_idname = "VIEW3D_PT_blenderkit_advanced_material_search"
        bl_parent_id = "VIEW3D_PT_blenderkit_unified"
        bl_space_type = 'VIEW_3D'
        bl_region_type = 'UI'
        bl_label = "Search filters"
        bl_options = {'DEFAULT_CLOSED'}
    
        @classmethod
        def poll(cls, context):
            s = context.scene
            ui_props = s.blenderkitUI
    
    Vilém Duha's avatar
    Vilém Duha committed
            return ui_props.down_up == 'SEARCH' and ui_props.asset_type == 'MATERIAL'
    
    
        def draw(self, context):
            s = context.scene
    
    
            props = s.blenderkit_mat
    
            layout = self.layout
            layout.separator()
    
    
    Vilém Duha's avatar
    Vilém Duha committed
            layout.prop(props, "own_only")
    
            layout.label(text='Texture:')
    
            col = layout.column()
            col.prop(props, "search_procedural", expand=True)
    
            if props.search_procedural == 'TEXTURE_BASED':
                # TEXTURE RESOLUTION
    
    Vilém Duha's avatar
    Vilém Duha committed
                layout.prop(props, "search_texture_resolution", text='Texture Resolution')
    
                if props.search_texture_resolution:
                    row = layout.row(align=True)
    
    Vilém Duha's avatar
    Vilém Duha committed
                    row.prop(props, "search_texture_resolution_min", text='Min')
                    row.prop(props, "search_texture_resolution_max", text='Max')
    
    Vilém Duha's avatar
    Vilém Duha committed
            layout.prop(props, "search_file_size", text='File size (MB)')
    
            if props.search_file_size:
                row = layout.row(align=True)
    
    Vilém Duha's avatar
    Vilém Duha committed
                row.prop(props, "search_file_size_min", text='Min')
                row.prop(props, "search_file_size_max", text='Max')
    
    class VIEW3D_PT_blenderkit_categories(Panel):
        bl_category = "BlenderKit"
        bl_idname = "VIEW3D_PT_blenderkit_categories"
        bl_space_type = 'VIEW_3D'
        bl_region_type = 'UI'
        bl_label = "Categories"
        bl_parent_id = "VIEW3D_PT_blenderkit_unified"
        bl_options = {'DEFAULT_CLOSED'}
    
        @classmethod
        def poll(cls, context):
            s = context.scene
            ui_props = s.blenderkitUI
    
    Vilém Duha's avatar
    Vilém Duha committed
            mode = True
    
            if ui_props.asset_type == 'BRUSH' and not (context.sculpt_object or context.image_paint_object):
    
    Vilém Duha's avatar
    Vilém Duha committed
                mode = False
            return ui_props.down_up == 'SEARCH' and mode
    
    
        def draw(self, context):
    
    Vilém Duha's avatar
    Vilém Duha committed
            draw_panel_categories(self, context)
    
    
    def draw_scene_import_settings(self, context):
        s = context.scene
        props = s.blenderkit_scene
        layout = self.layout
        layout.prop(props, 'switch_after_append')
        # layout.label(text='Import method:')
        row = layout.row()
        row.prop(props, 'append_link', expand=True, icon_only=False)
    
    
    
    class VIEW3D_PT_blenderkit_import_settings(Panel):
        bl_category = "BlenderKit"
        bl_idname = "VIEW3D_PT_blenderkit_import_settings"
        bl_space_type = 'VIEW_3D'
        bl_region_type = 'UI'
        bl_label = "Import settings"
        bl_parent_id = "VIEW3D_PT_blenderkit_unified"
        bl_options = {'DEFAULT_CLOSED'}
    
        @classmethod
        def poll(cls, context):
            s = context.scene
            ui_props = s.blenderkitUI
    
            return ui_props.down_up == 'SEARCH' and ui_props.asset_type in ['MATERIAL', 'MODEL', 'SCENE', 'HDR']
    
    
        def draw(self, context):
    
            layout = self.layout
    
    
            s = context.scene
            ui_props = s.blenderkitUI
    
            if ui_props.asset_type == 'MODEL':
                # noinspection PyCallByClass
                props = s.blenderkit_models
                layout.prop(props, 'randomize_rotation')
                if props.randomize_rotation:
                    layout.prop(props, 'randomize_rotation_amount')
    
                layout.prop(props, 'perpendicular_snap')
    
    Vilém Duha's avatar
    Vilém Duha committed
                # if props.perpendicular_snap:
                #     layout.prop(props,'perpendicular_snap_threshold')
    
                layout.label(text='Import method:')
                row = layout.row()
                row.prop(props, 'append_method', expand=True, icon_only=False)
    
            if ui_props.asset_type == 'MATERIAL':
                props = s.blenderkit_mat
                layout.prop(props, 'automap')
    
    Vilém Duha's avatar
    Vilém Duha committed
                layout.label(text='Import method:')
                row = layout.row()
    
                row.prop(props, 'append_method', expand=True, icon_only=False)
    
            if ui_props.asset_type == 'SCENE':
    
                draw_scene_import_settings(self,context)
    
    
            if ui_props.asset_type == 'HDR':
                props = s.blenderkit_HDR
    
            if ui_props.asset_type in ['MATERIAL', 'MODEL', 'HDR']:
                layout.prop(props, 'resolution')
    
    Vilém Duha's avatar
    Vilém Duha committed
            # layout.prop(props, 'unpack_files')
    
    Vilem Duha's avatar
    Vilem Duha committed
    class VIEW3D_PT_blenderkit_unified(Panel):
        bl_category = "BlenderKit"
        bl_idname = "VIEW3D_PT_blenderkit_unified"
        bl_space_type = 'VIEW_3D'
        bl_region_type = 'UI'
    
    Vilém Duha's avatar
    Vilém Duha committed
        bl_label = "Find and Upload Assets"
    
    Vilem Duha's avatar
    Vilem Duha committed
    
        @classmethod
        def poll(cls, context):
            user_preferences = bpy.context.preferences.addons['blenderkit'].preferences
            return user_preferences.panel_behaviour == 'BOTH' or user_preferences.panel_behaviour == 'UNIFIED'
    
        def draw(self, context):
            s = context.scene
            ui_props = s.blenderkitUI
            user_preferences = bpy.context.preferences.addons['blenderkit'].preferences
            wm = bpy.context.window_manager
            layout = self.layout
    
    Vilém Duha's avatar
    Vilém Duha committed
            # layout.prop_tabs_enum(ui_props, "asset_type", icon_only = True)
    
    Vilem Duha's avatar
    Vilem Duha committed
            row = layout.row()
    
    Vilém Duha's avatar
    Vilém Duha committed
            # row.scale_x = 1.6
            # row.scale_y = 1.6
    
            row.prop(ui_props, 'down_up', expand=True, icon_only=False)
    
    Vilém Duha's avatar
    Vilém Duha committed
            # row = row.split().row()
            # layout.alert = True
            # layout.alignment = 'CENTER'
    
    Vilém Duha's avatar
    Vilém Duha committed
            row = layout.row(align=True)
    
            row.scale_x = 1.6
            row.scale_y = 1.6
    
            # split = row.split(factor=.
    
    
            expand_icon = 'TRIA_DOWN'
    
            if ui_props.asset_type_fold:
    
                expand_icon = 'TRIA_RIGHT'
            row = layout.row()
    
    Vilém Duha's avatar
    Vilém Duha committed
            split = row.split(factor=0.15)
            split.prop(ui_props, 'asset_type_fold', icon=expand_icon, icon_only=True, emboss=False)
    
    
            if ui_props.asset_type_fold:
                pass
    
    Vilém Duha's avatar
    Vilém Duha committed
                # expanded interface with names in column
    
                split = split.row()