Custom shortcuts for Display Mode (Mac)

Below is a script that allows you to assign keyboard shortcuts to different views in the File Browser. It may be particularly useful for Mac users. By default, it has the shortcuts ⌘+1, ⌘+2, ⌘+3 assigned, thus referring to the Finder. This is something I’ve long dreamed of doing, but I don’t know Python or the Blender API. Created mostly by ChatGPT. Restart Blender after add-on install.

I realise it’s a prosthesis - a temporary solution, but it brings the Blender File Browser a bit closer to the Finder.

file_browser_display_mode.py (3.4 KB)

2 Likes

Extended version - Thumbnails can be resized using ⌘+ and ⌘- (Numpad Emulate mode on)

file_browser_display_mode_size.py (6.5 KB)

Just in case you are interested:

you can improve your script by just using one class instead of three to set the view_size.

Like this:

bl_info = {
    "name": "File Browser View",
    "author": "AI",
    "version": (1, 0),
    "blender": (3, 0, 0),
    "location": "File Browser > View",
    "description": "Adds buttons to switch the file browser to different views and control thumbnail size.",
    "category": "File Browser",
}

import bpy
from bpy.props import IntProperty

addon_keymaps = []

# Define preset sizes for thumbnails
THUMBNAIL_SIZES = [64, 96, 128, 192, 256]

def set_file_browser_view(view_type):
    for window in bpy.context.window_manager.windows:
        screen = window.screen
        for area in screen.areas:
            if area.type == 'FILE_BROWSER':
                with bpy.context.temp_override(window=window, area=area):
                    space_data = area.spaces.active
                    params = space_data.params
                    if params:
                        params.display_type = view_type

def get_params(context):
    """Get file browser parameters"""
    space = context.space_data
    if hasattr(space, "params"):
        return space.params
    for area in context.screen.areas:
        if area.type == 'FILE_BROWSER':
            for space in area.spaces:
                if space.type == 'FILE_BROWSER':
                    return space.params
    return None

def get_current_size_index(context):
    """Get the index of the current thumbnail size"""
    params = get_params(context)
    if not params:
        return 2  # Default to middle size
    
    current_size = params.display_size
    return min(range(len(THUMBNAIL_SIZES)), key=lambda i: abs(THUMBNAIL_SIZES[i] - current_size))

class FILEBROWSER_OT_set_view_size(bpy.types.Operator):
    """Set File Browser to Thumbnails View"""
    bl_idname = "filebrowser.set"
    bl_label = "Thumbnails"
    bl_options = {'REGISTER', 'UNDO'}

    view_size: bpy.props.StringProperty()
    
    def execute(self, context):
        set_file_browser_view(self.view_size)
        return {'FINISHED'}

class FILEBROWSER_OT_thumbnail_size_change(bpy.types.Operator):
    """Change Thumbnail Size"""
    bl_idname = "file.thumbnail_size_change"
    bl_label = "Change Thumbnail Size"
    bl_description = "Increase or decrease thumbnail size"
    bl_options = {'INTERNAL'}

    increase: bpy.props.BoolProperty(
        name="Increase",
        description="Increase size if True, decrease if False",
        default=True
    )

    def execute(self, context):
        params = get_params(context)
        if not params or params.display_type != 'THUMBNAIL':
            self.report({'WARNING'}, "Only works in thumbnail view mode")
            return {'CANCELLED'}

        current_index = get_current_size_index(context)
        if self.increase:
            new_index = min(current_index + 1, len(THUMBNAIL_SIZES) - 1)
        else:
            new_index = max(current_index - 1, 0)

        params.display_size = THUMBNAIL_SIZES[new_index]

        # Force redraw
        for area in context.screen.areas:
            if area.type == 'FILE_BROWSER':
                area.tag_redraw()

        return {'FINISHED'}

class FILEBROWSER_PT_custom_panel(bpy.types.Panel):
    """Creates a custom panel in the File Browser"""
    bl_label = "Custom File Browser"
    bl_idname = "FILEBROWSER_PT_custom_panel"
    bl_space_type = 'FILE_BROWSER'
    bl_region_type = 'TOOLS'
    bl_category = "View"
    
    def draw(self, context):
        layout = self.layout
        op = layout.operator("filebrowser.set", icon='FILE_IMAGE')
        op.view_size = 'THUMBNAIL'
     #   layout.operator("filebrowser.set_thumbnails", icon='FILE_IMAGE')
        layout.operator("filebrowser.set_vertical_list", icon='ALIGN_JUSTIFY')
        layout.operator("filebrowser.set_horizontal_list", icon='ALIGN_CENTER')

        # Thumbnail size controls
        row = layout.row(align=True)
        row.operator("file.thumbnail_size_change", text="Increase Size").increase = True
        row.operator("file.thumbnail_size_change", text="Decrease Size").increase = False

def register():
    bpy.utils.register_class(FILEBROWSER_OT_set_view_size)
    bpy.utils.register_class(FILEBROWSER_OT_thumbnail_size_change)
    bpy.utils.register_class(FILEBROWSER_PT_custom_panel)
    
    # Register keymaps and ensure they persist in preferences
    wm = bpy.context.window_manager
    if wm.keyconfigs.addon:
        km = wm.keyconfigs.addon.keymaps.new(name="File Browser", space_type='FILE_BROWSER')

        # View Mode Shortcuts (CMD + Numpad 1, 2, 3)
        kmi1 = km.keymap_items.new("filebrowser.set", 'NUMPAD_1', 'PRESS', oskey=True)
        kmi1.properties.view_size = "THUMBNAIL"
        addon_keymaps.append((km, kmi1))
        kmi2 = km.keymap_items.new("filebrowser.set", 'NUMPAD_2', 'PRESS', oskey=True)
        kmi2.properties.view_size = "LIST_VERTICAL"
        addon_keymaps.append((km, kmi2))
        kmi3 = km.keymap_items.new("filebrowser.set", 'NUMPAD_3', 'PRESS', oskey=True)
        kmi3.properties.view_size = "LIST_HORIZONTAL"
        addon_keymaps.append((km, kmi3))

        # Thumbnail Size Shortcuts (CMD + Numpad +, CMD + Numpad -)
        kmi4 = km.keymap_items.new("file.thumbnail_size_change", 'NUMPAD_PLUS', 'PRESS', oskey=True)
        kmi4.properties.increase = True
        addon_keymaps.append((km, kmi4))

        kmi5 = km.keymap_items.new("file.thumbnail_size_change", 'NUMPAD_MINUS', 'PRESS', oskey=True)
        kmi5.properties.increase = False
        addon_keymaps.append((km, kmi5))

def unregister():
    bpy.utils.unregister_class(FILEBROWSER_PT_custom_panel)
    bpy.utils.unregister_class(FILEBROWSER_OT_set_view_size)
    bpy.utils.unregister_class(FILEBROWSER_OT_thumbnail_size_change)
    
    # Unregister keymaps properly
    wm = bpy.context.window_manager
    if wm.keyconfigs.addon:
        for km, kmi in addon_keymaps:
            km.keymap_items.remove(kmi)
        addon_keymaps.clear()

if __name__ == "__main__":
    register()
1 Like

But this removes ‘Horizontal List’ and ‘Verticla List’ buttons from the left panel. These buttons may not be very useful because you use keyboard shortcuts, but it’s probably better that they stay.

Can you please add a screenshot? I don’t understand what buttons you are writing about.

Left panel of the File View window:
Screenshot 2025-02-11 at 12.05.00
Screenshot 2025-02-11 at 12.05.57

1 Like

sorry, you are right, i corrected that:

bl_info = {
    "name": "File Browser View",
    "author": "AI",
    "version": (1, 0),
    "blender": (3, 0, 0),
    "location": "File Browser > View",
    "description": "Adds buttons to switch the file browser to different views and control thumbnail size.",
    "category": "File Browser",
}

import bpy
from bpy.props import IntProperty

addon_keymaps = []

# Define preset sizes for thumbnails
THUMBNAIL_SIZES = [64, 96, 128, 192, 256]

def set_file_browser_view(view_type):
    for window in bpy.context.window_manager.windows:
        screen = window.screen
        for area in screen.areas:
            if area.type == 'FILE_BROWSER':
                with bpy.context.temp_override(window=window, area=area):
                    space_data = area.spaces.active
                    params = space_data.params
                    if params:
                        params.display_type = view_type

def get_params(context):
    """Get file browser parameters"""
    space = context.space_data
    if hasattr(space, "params"):
        return space.params
    for area in context.screen.areas:
        if area.type == 'FILE_BROWSER':
            for space in area.spaces:
                if space.type == 'FILE_BROWSER':
                    return space.params
    return None

def get_current_size_index(context):
    """Get the index of the current thumbnail size"""
    params = get_params(context)
    if not params:
        return 2  # Default to middle size
    
    current_size = params.display_size
    return min(range(len(THUMBNAIL_SIZES)), key=lambda i: abs(THUMBNAIL_SIZES[i] - current_size))

class FILEBROWSER_OT_set_view_size(bpy.types.Operator):
    """Set File Browser to Thumbnails View"""
    bl_idname = "filebrowser.set"
    bl_label = "Thumbnails"
    bl_options = {'REGISTER', 'UNDO'}

    view_size: bpy.props.StringProperty()
    
    def execute(self, context):
        set_file_browser_view(self.view_size)
        return {'FINISHED'}

class FILEBROWSER_OT_thumbnail_size_change(bpy.types.Operator):
    """Change Thumbnail Size"""
    bl_idname = "file.thumbnail_size_change"
    bl_label = "Change Thumbnail Size"
    bl_description = "Increase or decrease thumbnail size"
    bl_options = {'INTERNAL'}

    increase: bpy.props.BoolProperty(
        name="Increase",
        description="Increase size if True, decrease if False",
        default=True
    )

    def execute(self, context):
        params = get_params(context)
        if not params or params.display_type != 'THUMBNAIL':
            self.report({'WARNING'}, "Only works in thumbnail view mode")
            return {'CANCELLED'}

        current_index = get_current_size_index(context)
        if self.increase:
            new_index = min(current_index + 1, len(THUMBNAIL_SIZES) - 1)
        else:
            new_index = max(current_index - 1, 0)

        params.display_size = THUMBNAIL_SIZES[new_index]

        # Force redraw
        for area in context.screen.areas:
            if area.type == 'FILE_BROWSER':
                area.tag_redraw()

        return {'FINISHED'}

class FILEBROWSER_PT_custom_panel(bpy.types.Panel):
    """Creates a custom panel in the File Browser"""
    bl_label = "Custom File Browser"
    bl_idname = "FILEBROWSER_PT_custom_panel"
    bl_space_type = 'FILE_BROWSER'
    bl_region_type = 'TOOLS'
    bl_category = "View"
    
    def draw(self, context):
        layout = self.layout
        op = layout.operator("filebrowser.set",text = "Thumbnails", icon='FILE_IMAGE')
        op.view_size = 'THUMBNAIL'
        op1 = layout.operator("filebrowser.set", text = "Vertical list", icon='ALIGN_JUSTIFY')
        op1.view_size = 'LIST_VERTICAL'
        op2 = layout.operator( "filebrowser.set",text = "Horizontal list", icon='ALIGN_CENTER')
        op2.view_size = 'LIST_HORIZONTAL'
        
        # Thumbnail size controls
        row = layout.row(align=True)
        row.operator("file.thumbnail_size_change", text="Increase Size").increase = True
        row.operator("file.thumbnail_size_change", text="Decrease Size").increase = False

def register():
    bpy.utils.register_class(FILEBROWSER_OT_set_view_size)
    bpy.utils.register_class(FILEBROWSER_OT_thumbnail_size_change)
    bpy.utils.register_class(FILEBROWSER_PT_custom_panel)
    
    # Register keymaps and ensure they persist in preferences
    wm = bpy.context.window_manager
    if wm.keyconfigs.addon:
        km = wm.keyconfigs.addon.keymaps.new(name="File Browser", space_type='FILE_BROWSER')

        # View Mode Shortcuts (CMD + Numpad 1, 2, 3)
        kmi1 = km.keymap_items.new("filebrowser.set", 'NUMPAD_1', 'PRESS', oskey=True)
        kmi1.properties.view_size = "THUMBNAIL"
        addon_keymaps.append((km, kmi1))
        kmi2 = km.keymap_items.new("filebrowser.set", 'NUMPAD_2', 'PRESS', oskey=True)
        kmi2.properties.view_size = "LIST_VERTICAL"
        addon_keymaps.append((km, kmi2))
        kmi3 = km.keymap_items.new("filebrowser.set", 'NUMPAD_3', 'PRESS', oskey=True)
        kmi3.properties.view_size = "LIST_HORIZONTAL"
        addon_keymaps.append((km, kmi3))

        # Thumbnail Size Shortcuts (CMD + Numpad +, CMD + Numpad -)
        kmi4 = km.keymap_items.new("file.thumbnail_size_change", 'NUMPAD_PLUS', 'PRESS', oskey=True)
        kmi4.properties.increase = True
        addon_keymaps.append((km, kmi4))

        kmi5 = km.keymap_items.new("file.thumbnail_size_change", 'NUMPAD_MINUS', 'PRESS', oskey=True)
        kmi5.properties.increase = False
        addon_keymaps.append((km, kmi5))

def unregister():
    bpy.utils.unregister_class(FILEBROWSER_PT_custom_panel)
    bpy.utils.unregister_class(FILEBROWSER_OT_set_view_size)
    bpy.utils.unregister_class(FILEBROWSER_OT_thumbnail_size_change)
    
    # Unregister keymaps properly
    wm = bpy.context.window_manager
    if wm.keyconfigs.addon:
        for km, kmi in addon_keymaps:
            km.keymap_items.remove(kmi)
        addon_keymaps.clear()

if __name__ == "__main__":
    register()
1 Like

Added ability to resize icons in the Thumbnails view using the mouse wheel - ⌘ Wheel

file_browser_display_mode_size_wheel.py (6.7 KB)

To sum up:
⌘1: Thumbnails view
⌘2: Vertical list
⌘3: Horizontal list
⌘+/- or ⌘Wheel: resize icons in Thumbnails view