Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'release/scripts/startup/bl_ui/space_userpref.py')
-rw-r--r--release/scripts/startup/bl_ui/space_userpref.py1983
1 files changed, 1214 insertions, 769 deletions
diff --git a/release/scripts/startup/bl_ui/space_userpref.py b/release/scripts/startup/bl_ui/space_userpref.py
index 7dacb8d9db6..a115213fc2a 100644
--- a/release/scripts/startup/bl_ui/space_userpref.py
+++ b/release/scripts/startup/bl_ui/space_userpref.py
@@ -32,34 +32,13 @@ class USERPREF_HT_header(Header):
def draw(self, context):
layout = self.layout
+ layout.operator_context = 'EXEC_AREA'
layout.template_header()
- prefs = context.preferences
-
- if prefs.active_section == 'INPUT':
- layout.operator("wm.keyconfig_import", icon='IMPORT')
- layout.operator("wm.keyconfig_export", icon='EXPORT')
- elif prefs.active_section == 'ADDONS':
- layout.operator("wm.addon_install", icon='FILEBROWSER')
- layout.operator("wm.addon_refresh", icon='FILE_REFRESH')
- layout.menu("USERPREF_MT_addons_online_resources")
- elif prefs.active_section == 'LIGHTS':
- layout.operator("wm.studiolight_install", text="Install MatCap").type = 'MATCAP'
- layout.operator("wm.studiolight_install", text="Install LookDev HDRI").type = 'WORLD'
- layout.operator("wm.studiolight_install", text="Install Studio Light").type = 'STUDIO'
- elif prefs.active_section == 'THEMES':
- layout.operator("wm.theme_install", icon='FILEBROWSER')
- layout.operator("ui.reset_default_theme", icon='LOOP_BACK')
-
- layout.separator_spacer()
-
- layout.operator_context = 'EXEC_AREA'
- layout.operator("wm.save_userpref")
-
class USERPREF_PT_navigation(Panel):
- bl_label = ""
+ bl_label = "Preferences Navigation"
bl_space_type = 'PREFERENCES'
bl_region_type = 'NAVIGATION_BAR'
bl_options = {'HIDE_HEADER'}
@@ -76,309 +55,515 @@ class USERPREF_PT_navigation(Panel):
col.prop(prefs, "active_section", expand=True)
-class USERPREF_PT_interface(Panel):
+class USERPREF_PT_save_preferences(Panel):
+ bl_label = "Save Preferences"
bl_space_type = 'PREFERENCES'
- bl_label = "Interface"
- bl_region_type = 'WINDOW'
+ bl_region_type = 'EXECUTE'
bl_options = {'HIDE_HEADER'}
+ def draw(self, context):
+ layout = self.layout
+ layout.operator_context = 'EXEC_AREA'
+
+ prefs = context.preferences
+
+ layout.scale_x = 1.3
+ layout.scale_y = 1.3
+
+ layout.operator("wm.save_userpref")
+
+
+class PreferencePanel(Panel):
+ """
+ Base class for panels to center align contents with some horizontal margin.
+ Deriving classes need to implement a ``draw_props(context, layout)`` function.
+ """
+
+ bl_space_type = 'PREFERENCES'
+ bl_region_type = 'WINDOW'
+
+ def draw(self, context):
+ layout = self.layout
+ width = context.region.width
+ pixel_size = context.preferences.system.pixel_size
+
+ layout.use_property_split = True
+ layout.use_property_decorate = False # No animation.
+
+ row = layout.row()
+ if width > (350 * pixel_size): # No horizontal margin if region is rather small.
+ row.label() # Needed so col below is centered.
+
+ col = row.column()
+ col.ui_units_x = 50
+
+ # draw_props implemented by deriving classes.
+ self.draw_props(context, col)
+
+ if width > (350 * pixel_size): # No horizontal margin if region is rather small.
+ row.label() # Needed so col above is centered.
+
+
+class USERPREF_PT_interface_display(PreferencePanel):
+ bl_label = "Display"
+
@classmethod
def poll(cls, context):
prefs = context.preferences
return (prefs.active_section == 'INTERFACE')
- def draw(self, context):
- layout = self.layout
+ def draw_props(self, context, layout):
+ prefs = context.preferences
+ view = prefs.view
+ layout.prop(view, "ui_scale", text="Resolution Scale")
+ layout.prop(view, "ui_line_width", text="Line Width")
+
+
+class USERPREF_PT_interface_display_info(PreferencePanel):
+ bl_label = "Information"
+ bl_parent_id = "USERPREF_PT_interface_display"
+ bl_options = {'DEFAULT_CLOSED'}
+
+ def draw_props(self, context, layout):
prefs = context.preferences
view = prefs.view
- split = layout.split()
- row = split.row()
- col = row.column()
+ flow = layout.grid_flow(row_major=True, columns=0, even_columns=False, even_rows=False, align=False)
+
+ flow.prop(view, "show_tooltips")
+ flow.prop(view, "show_object_info", text="Object Info")
+ flow.prop(view, "show_large_cursors")
+ flow.prop(view, "show_view_name", text="View Name")
+ flow.prop(view, "show_playback_fps", text="Playback FPS")
+
+
+class USERPREF_PT_interface_text(PreferencePanel):
+ bl_label = "Text"
+ bl_options = {'DEFAULT_CLOSED'}
+
+ @classmethod
+ def poll(cls, context):
+ prefs = context.preferences
+ return (prefs.active_section == 'INTERFACE')
+
+ def draw_props(self, context, layout):
+ prefs = context.preferences
+ view = prefs.view
+
+ layout.prop(view, "use_text_antialiasing", text="Anti-aliasing")
+ sub = layout.column()
+ sub.active = view.use_text_antialiasing
+ sub.prop(view, "text_hinting", text="Hinting")
+
+ layout.prop(view, "font_path_ui")
+ layout.prop(view, "font_path_ui_mono")
+
+
+class USERPREF_PT_interface_text_translate(PreferencePanel):
+ bl_label = "Translate UI"
+ bl_options = {'DEFAULT_CLOSED'}
+ bl_parent_id = "USERPREF_PT_interface_text"
+
+ @classmethod
+ def poll(cls, context):
+ prefs = context.preferences
+ if bpy.app.build_options.international:
+ return (prefs.active_section == 'INTERFACE')
+
+ def draw_header(self, context):
+ prefs = context.preferences
+ view = prefs.view
+
+ self.layout.prop(view, "use_international_fonts", text="")
+
+ def draw_props(self, context, layout):
+ prefs = context.preferences
+ view = prefs.view
+
+ layout.active = view.use_international_fonts
+ layout.prop(view, "language")
+
+ layout.prop(view, "use_translate_tooltips", text="Translate Tooltips")
+ layout.prop(view, "use_translate_interface", text="Translate Interface")
+ layout.prop(view, "use_translate_new_dataname", text="Translate New Data")
+
+
+class USERPREF_PT_interface_develop(PreferencePanel):
+ bl_label = "Develop"
+ bl_options = {'DEFAULT_CLOSED'}
+
+ @classmethod
+ def poll(cls, context):
+ prefs = context.preferences
+ return (prefs.active_section == 'INTERFACE')
+
+ def draw_props(self, context, layout):
+ prefs = context.preferences
+ view = prefs.view
+
+ layout.prop(view, "show_tooltips_python")
+ layout.prop(view, "show_developer_ui")
+
+
+class USERPREF_PT_interface_viewports(PreferencePanel):
+ bl_label = "Viewports"
+ bl_options = {'DEFAULT_CLOSED'}
+
+ @classmethod
+ def poll(cls, context):
+ prefs = context.preferences
+ return (prefs.active_section == 'INTERFACE')
+
+ def draw(self, context):
+ pass
- col.label(text="Display:")
- col.prop(view, "ui_scale", text="Scale")
- col.prop(view, "ui_line_width", text="Line Width")
- col.prop(view, "show_tooltips")
- col.prop(view, "show_object_info", text="Object Info")
- col.prop(view, "show_large_cursors")
- col.prop(view, "show_view_name", text="View Name")
- col.prop(view, "show_playback_fps", text="Playback FPS")
- col.prop(view, "object_origin_size")
- col.separator()
+class USERPREF_PT_interface_viewports_3d(PreferencePanel):
+ bl_label = "3D Viewports"
+ bl_parent_id = "USERPREF_PT_interface_viewports"
- # col.prop(view, "show_gizmo_navigate")
+ def draw_props(self, context, layout):
+ prefs = context.preferences
+ view = prefs.view
+
+ layout.prop(view, "smooth_view")
+ layout.prop(view, "rotation_angle")
+
+ layout.separator()
- sub = col.column(align=True)
+ layout.prop(view, "object_origin_size")
+ layout.prop(view, "gizmo_size", text="Gizmo Size")
+ layout.separator()
- sub.label(text="3D Viewport Axis:")
- sub.row().prop(view, "mini_axis_type", text="")
+ layout.prop(view, "mini_axis_type", text="3D Viewport Axis")
- sub = col.column(align=True)
+ sub = layout.column()
sub.active = view.mini_axis_type == 'MINIMAL'
sub.prop(view, "mini_axis_size", text="Size")
sub.prop(view, "mini_axis_brightness", text="Brightness")
- col.separator()
- # Toolbox doesn't exist yet
- # col.label(text="Toolbox:")
- #col.prop(view, "show_column_layout")
- #col.label(text="Open Toolbox Delay:")
- #col.prop(view, "open_left_mouse_delay", text="Hold LMB")
- #col.prop(view, "open_right_mouse_delay", text="Hold RMB")
- col.prop(view, "show_gizmo", text="Gizmos")
- sub = col.column()
- sub.active = view.show_gizmo
- sub.prop(view, "gizmo_size", text="Size")
+class USERPREF_PT_interface_viewports_3d_weight_paint(PreferencePanel):
+ bl_label = "Custom Weight Paint Range"
+ bl_options = {'DEFAULT_CLOSED'}
+ bl_parent_id = "USERPREF_PT_interface_viewports_3d"
- col.separator()
+ def draw_header(self, context):
+ prefs = context.preferences
+ view = prefs.view
- col.label(text="Development:")
- col.prop(view, "show_tooltips_python")
- col.prop(view, "show_developer_ui")
+ self.layout.prop(view, "use_weight_color_range", text="")
- row = split.row()
- row.separator()
- col = row.column()
+ def draw_props(self, context, layout):
+ prefs = context.preferences
+ view = prefs.view
- col.label(text="View Gizmos:")
- col.prop(view, "use_mouse_depth_cursor")
- col.prop(view, "use_cursor_lock_adjust")
- col.prop(view, "use_mouse_depth_navigate")
- col.prop(view, "use_zoom_to_mouse")
- col.prop(view, "use_rotate_around_active")
- col.prop(view, "use_camera_lock_parent")
+ layout.active = view.use_weight_color_range
+ layout.template_color_ramp(view, "weight_color_range", expand=True)
- col.separator()
- col.prop(view, "use_auto_perspective")
- col.prop(view, "smooth_view")
- col.prop(view, "rotation_angle")
+class USERPREF_PT_interface_viewports_2d(PreferencePanel):
+ bl_label = "2D Viewports"
+ bl_parent_id = "USERPREF_PT_interface_viewports"
- col.separator()
- col.separator()
+ def draw_props(self, context, layout):
+ prefs = context.preferences
+ view = prefs.view
- col.label(text="2D Viewports:")
- col.prop(view, "view2d_grid_spacing_min", text="Minimum Grid Spacing")
- col.prop(view, "timecode_style")
- col.prop(view, "view_frame_type")
+ layout.prop(view, "view2d_grid_spacing_min", text="Minimum Grid Spacing")
+ layout.prop(view, "timecode_style")
+ layout.prop(view, "view_frame_type")
if view.view_frame_type == 'SECONDS':
- col.prop(view, "view_frame_seconds")
+ layout.prop(view, "view_frame_seconds")
elif view.view_frame_type == 'KEYFRAMES':
- col.prop(view, "view_frame_keyframes")
+ layout.prop(view, "view_frame_keyframes")
- row = split.row()
- row.separator()
- col = row.column()
- col.label(text="Menus:")
- col.prop(view, "use_mouse_over_open")
- sub = col.column()
- sub.active = view.use_mouse_over_open
+class USERPREF_PT_interface_menus(PreferencePanel):
+ bl_label = "Menus"
+ bl_options = {'DEFAULT_CLOSED'}
- sub.prop(view, "open_toplevel_delay", text="Top Level")
- sub.prop(view, "open_sublevel_delay", text="Sub Level")
+ @classmethod
+ def poll(cls, context):
+ prefs = context.preferences
+ return (prefs.active_section == 'INTERFACE')
- col.separator()
- col.label(text="Pie Menus:")
- sub = col.column(align=True)
- sub.prop(view, "pie_animation_timeout")
- sub.prop(view, "pie_initial_timeout")
- sub.prop(view, "pie_menu_radius")
- sub.prop(view, "pie_menu_threshold")
- sub.prop(view, "pie_menu_confirm")
- col.separator()
+ def draw_props(self, context, layout):
+ prefs = context.preferences
+ view = prefs.view
- col.label(text="Header:")
- sub = col.split()
- sub.label(text="Default Position")
- sub.row().prop(view, "header_align_default", expand=True)
+ layout.prop(view, "color_picker_type")
+ layout.row().prop(view, "header_align_default", expand=True)
- col.prop(view, "show_splash")
+ layout.prop(view, "show_splash")
+ layout.prop(view, "use_quit_dialog")
- col.label(text="Warnings:")
- col.prop(view, "use_quit_dialog")
- col.separator()
+class USERPREF_PT_interface_menus_mouse_over(PreferencePanel):
+ bl_label = "Open on Mouse Over"
+ bl_parent_id = "USERPREF_PT_interface_menus"
+ bl_options = {'DEFAULT_CLOSED'}
- col.label(text="App Template:")
- col.label(text="Options intended for use with app-templates only")
- col.prop(view, "show_layout_ui")
+ def draw_header(self, context):
+ prefs = context.preferences
+ view = prefs.view
+ self.layout.prop(view, "use_mouse_over_open", text="")
-class USERPREF_PT_edit(Panel):
- bl_space_type = 'PREFERENCES'
- bl_label = "Edit"
- bl_region_type = 'WINDOW'
- bl_options = {'HIDE_HEADER'}
+ def draw_props(self, context, layout):
+ prefs = context.preferences
+ view = prefs.view
+
+ layout.active = view.use_mouse_over_open
+
+ layout.prop(view, "open_toplevel_delay", text="Top Level")
+ layout.prop(view, "open_sublevel_delay", text="Sub Level")
+
+
+class USERPREF_PT_interface_menus_pie(PreferencePanel):
+ bl_label = "Pie Menus"
+ bl_parent_id = "USERPREF_PT_interface_menus"
+ bl_options = {'DEFAULT_CLOSED'}
+
+ def draw_props(self, context, layout):
+ prefs = context.preferences
+ view = prefs.view
+
+ layout.prop(view, "pie_animation_timeout")
+ layout.prop(view, "pie_initial_timeout")
+ layout.prop(view, "pie_menu_radius")
+ layout.prop(view, "pie_menu_threshold")
+ layout.prop(view, "pie_menu_confirm")
+
+
+class USERPREF_PT_interface_templates(PreferencePanel):
+ bl_label = "Templates"
+ bl_options = {'DEFAULT_CLOSED'}
+
+ @classmethod
+ def poll(cls, context):
+ prefs = context.preferences
+ return (prefs.active_section == 'INTERFACE')
+
+ def draw_props(self, context, layout):
+ prefs = context.preferences
+ view = prefs.view
+
+ layout.label(text="Options intended for use with app-templates only")
+ layout.prop(view, "show_layout_ui")
+
+
+class USERPREF_PT_edit_objects(PreferencePanel):
+ bl_label = "Objects"
@classmethod
def poll(cls, context):
prefs = context.preferences
return (prefs.active_section == 'EDITING')
- def draw(self, context):
- layout = self.layout
+ def draw_props(self, context, layout):
+ prefs = context.preferences
+ edit = prefs.edit
+
+ layout.prop(edit, "material_link", text="Link Materials to")
+ layout.prop(edit, "object_align", text="Align New Objects to")
+ layout.prop(edit, "use_enter_edit_mode", text="Enter Edit Mode for New Objects")
+
+class USERPREF_PT_edit_animation(PreferencePanel):
+ bl_label = "Animation"
+ bl_options = {'DEFAULT_CLOSED'}
+
+ @classmethod
+ def poll(cls, context):
+ prefs = context.preferences
+ return (prefs.active_section == 'EDITING')
+
+ def draw_props(self, context, layout):
prefs = context.preferences
edit = prefs.edit
- split = layout.split()
- row = split.row()
- col = row.column()
+ layout.prop(edit, "use_negative_frames")
- col.label(text="Link Materials To:")
- col.prop(edit, "material_link", text="")
+ layout.prop(edit, "use_visual_keying")
+ layout.prop(edit, "use_keyframe_insert_needed", text="Only Insert Needed")
- col.separator()
- col.separator()
- col.separator()
- col.label(text="New Objects:")
- col.prop(edit, "use_enter_edit_mode")
- col.label(text="Align To:")
- col.prop(edit, "object_align", text="")
+class USERPREF_PT_edit_animation_autokey(PreferencePanel):
+ bl_label = "Auto-Keyframing"
+ bl_options = {'DEFAULT_CLOSED'}
+ bl_parent_id = "USERPREF_PT_edit_animation"
- col.separator()
- col.separator()
- col.separator()
+ def draw_header(self, context):
+ prefs = context.preferences
+ edit = prefs.edit
- col.label(text="Undo:")
- col.prop(edit, "use_global_undo")
- col.prop(edit, "undo_steps", text="Steps")
- col.prop(edit, "undo_memory_limit", text="Memory Limit")
+ self.layout.prop(edit, "use_auto_keying", text="")
- row = split.row()
- row.separator()
- col = row.column()
+ def draw_props(self, context, layout):
+ prefs = context.preferences
+ edit = prefs.edit
+
+ layout.prop(edit, "use_auto_keying_warning")
+ layout.prop(edit, "use_keyframe_insert_available", text="Only Insert Available")
- col.label(text="Grease Pencil/Annotations:")
- col.separator()
- col.prop(edit, "grease_pencil_manhattan_distance", text="Manhattan Distance")
- col.prop(edit, "grease_pencil_euclidean_distance", text="Euclidean Distance")
- col.separator()
-
- col.label(text="Annotations:")
- sub = col.row()
- sub.prop(edit, "grease_pencil_default_color", text="Default Color")
- col.prop(edit, "grease_pencil_eraser_radius", text="Eraser Radius")
- col.separator()
- col.prop(edit, "use_grease_pencil_simplify_stroke", text="Simplify Stroke")
- col.separator()
-
- col.separator()
- col.separator()
- col.separator()
- col.label(text="Playback:")
- col.prop(edit, "use_negative_frames")
- col.separator()
- col.label(text="Node Editor:")
- col.prop(edit, "node_margin")
- col.label(text="Animation Editors:")
- col.prop(edit, "fcurve_unselected_alpha", text="F-Curve Visibility")
-
- row = split.row()
- row.separator()
- col = row.column()
- col.label(text="Keyframing:")
- col.prop(edit, "use_visual_keying")
- col.prop(edit, "use_keyframe_insert_needed", text="Only Insert Needed")
+class USERPREF_PT_edit_animation_fcurves(PreferencePanel):
+ bl_label = "F-Curves"
+ bl_options = {'DEFAULT_CLOSED'}
+ bl_parent_id = "USERPREF_PT_edit_animation"
- col.separator()
+ def draw_props(self, context, layout):
+ prefs = context.preferences
+ edit = prefs.edit
- col.prop(edit, "use_auto_keying", text="Auto Keyframing:")
- col.prop(edit, "use_auto_keying_warning")
+ layout.prop(edit, "keyframe_new_interpolation_type", text="Default Interpolation")
+ layout.prop(edit, "keyframe_new_handle_type", text="Default Handles")
+ layout.prop(edit, "use_insertkey_xyz_to_rgb", text="XYZ to RGB")
- sub = col.column()
+ layout.separator()
- # ~ sub.active = edit.use_keyframe_insert_auto # incorrect, time-line can enable
- sub.prop(edit, "use_keyframe_insert_available", text="Only Insert Available")
+ layout.prop(edit, "fcurve_unselected_alpha", text="F-Curve Visibility")
- col.separator()
- col.label(text="New F-Curve Defaults:")
- col.prop(edit, "keyframe_new_interpolation_type", text="Interpolation")
- col.prop(edit, "keyframe_new_handle_type", text="Handles")
- col.prop(edit, "use_insertkey_xyz_to_rgb", text="XYZ to RGB")
+class USERPREF_PT_edit_transform(PreferencePanel):
+ bl_label = "Transform"
+ bl_options = {'DEFAULT_CLOSED'}
- col.separator()
- col.separator()
- col.separator()
+ @classmethod
+ def poll(cls, context):
+ prefs = context.preferences
+ return (prefs.active_section == 'EDITING')
- col.label(text="Transform:")
- col.prop(edit, "use_drag_immediately")
- col.prop(edit, "use_numeric_input_advanced")
+ def draw_props(self, context, layout):
+ prefs = context.preferences
+ edit = prefs.edit
- row = split.row()
- row.separator()
- col = row.column()
+ layout.prop(edit, "use_drag_immediately")
+ layout.prop(edit, "use_numeric_input_advanced")
- col.prop(edit, "sculpt_paint_overlay_color", text="Sculpt Overlay Color")
- col.separator()
- col.separator()
- col.separator()
+class USERPREF_PT_edit_duplicate_data(PreferencePanel):
+ bl_label = "Duplicate Data"
+ bl_options = {'DEFAULT_CLOSED'}
- col.label(text="Duplicate Data:")
- col.prop(edit, "use_duplicate_mesh", text="Mesh")
- col.prop(edit, "use_duplicate_surface", text="Surface")
- col.prop(edit, "use_duplicate_curve", text="Curve")
- col.prop(edit, "use_duplicate_text", text="Text")
- col.prop(edit, "use_duplicate_metaball", text="Metaball")
+ @classmethod
+ def poll(cls, context):
+ prefs = context.preferences
+ return (prefs.active_section == 'EDITING')
+
+ def draw_props(self, context, layout):
+ prefs = context.preferences
+ edit = prefs.edit
+
+ flow = layout.grid_flow(row_major=True, columns=0, even_columns=False, even_rows=False, align=True)
+
+ col = flow.column()
+ col.prop(edit, "use_duplicate_action", text="Action")
col.prop(edit, "use_duplicate_armature", text="Armature")
+ col.prop(edit, "use_duplicate_curve", text="Curve")
+ # col.prop(edit, "use_duplicate_fcurve", text="F-Curve")
col.prop(edit, "use_duplicate_light", text="Light")
+ col = flow.column()
col.prop(edit, "use_duplicate_material", text="Material")
- col.prop(edit, "use_duplicate_texture", text="Texture")
- #col.prop(edit, "use_duplicate_fcurve", text="F-Curve")
- col.prop(edit, "use_duplicate_action", text="Action")
+ col.prop(edit, "use_duplicate_mesh", text="Mesh")
+ col.prop(edit, "use_duplicate_metaball", text="Metaball")
col.prop(edit, "use_duplicate_particle", text="Particle")
+ col = flow.column()
+ col.prop(edit, "use_duplicate_surface", text="Surface")
+ col.prop(edit, "use_duplicate_text", text="Text")
+ col.prop(edit, "use_duplicate_texture", text="Texture")
-class USERPREF_PT_system_general(Panel):
- bl_space_type = 'PREFERENCES'
- bl_label = "System General"
- bl_region_type = 'WINDOW'
- bl_options = {'HIDE_HEADER'}
+class USERPREF_PT_edit_gpencil(PreferencePanel):
+ bl_label = "Grease Pencil"
+ bl_options = {'DEFAULT_CLOSED'}
@classmethod
def poll(cls, context):
prefs = context.preferences
- return (prefs.active_section == 'SYSTEM_GENERAL')
+ return (prefs.active_section == 'EDITING')
+
+ def draw_props(self, context, layout):
+ prefs = context.preferences
+ edit = prefs.edit
+
+ layout.prop(edit, "grease_pencil_manhattan_distance", text="Manhattan Distance")
+ layout.prop(edit, "grease_pencil_euclidean_distance", text="Euclidean Distance")
- def draw(self, context):
- import sys
- layout = self.layout
+class USERPREF_PT_edit_annotations(PreferencePanel):
+ bl_label = "Annotations"
+ bl_options = {'DEFAULT_CLOSED'}
+
+ @classmethod
+ def poll(cls, context):
prefs = context.preferences
- system = prefs.system
+ return (prefs.active_section == 'EDITING')
- split = layout.split()
+ def draw_props(self, context, layout):
+ prefs = context.preferences
+ edit = prefs.edit
- # 1. Column
- column = split.column()
- colsplit = column.split(factor=0.85)
+ layout.prop(edit, "grease_pencil_default_color", text="Default Color")
+ layout.prop(edit, "grease_pencil_eraser_radius", text="Eraser Radius")
+ layout.prop(edit, "use_grease_pencil_simplify_stroke", text="Simplify Stroke")
- col = colsplit.column()
- col.label(text="General:")
- col.prop(system, "scrollback", text="Console Scrollback")
+class USERPREF_PT_edit_misc(PreferencePanel):
+ bl_label = "Miscellaneous"
+ bl_options = {'DEFAULT_CLOSED'}
- col.separator()
+ @classmethod
+ def poll(cls, context):
+ prefs = context.preferences
+ return (prefs.active_section == 'EDITING')
+
+ def draw_props(self, context, layout):
+ prefs = context.preferences
+ edit = prefs.edit
- col.label(text="Sound:")
- col.row().prop(system, "audio_device", expand=False)
- sub = col.column()
+ layout.prop(edit, "sculpt_paint_overlay_color", text="Sculpt Overlay Color")
+ layout.prop(edit, "node_margin", text="Node Editor Auto-offset Margin")
+
+
+class USERPREF_PT_system_sound(PreferencePanel):
+ bl_label = "Sound"
+ bl_options = {'DEFAULT_CLOSED'}
+
+ @classmethod
+ def poll(cls, context):
+ prefs = context.preferences
+ return (prefs.active_section == 'SYSTEM_GENERAL')
+
+ def draw_props(self, context, layout):
+ prefs = context.preferences
+ system = prefs.system
+
+ layout.prop(system, "audio_device", expand=False)
+ sub = layout.column()
sub.active = system.audio_device not in {'NONE', 'Null'}
sub.prop(system, "audio_channels", text="Channels")
sub.prop(system, "audio_mixing_buffer", text="Mixing Buffer")
sub.prop(system, "audio_sample_rate", text="Sample Rate")
sub.prop(system, "audio_sample_format", text="Sample Format")
- col.separator()
+
+class USERPREF_PT_system_compute_device(PreferencePanel):
+ bl_label = "Cycles Compute Device"
+ bl_options = {'DEFAULT_CLOSED'}
+
+ @classmethod
+ def poll(cls, context):
+ prefs = context.preferences
+ return (prefs.active_section == 'SYSTEM_GENERAL')
+
+ def draw_props(self, context, layout):
+ prefs = context.preferences
+ system = prefs.system
+
+ col = layout.column()
if bpy.app.build_options.cycles:
addon = prefs.addons.get("cycles")
@@ -391,95 +576,94 @@ class USERPREF_PT_system_general(Panel):
# col.label(text="OpenSubdiv compute:")
# col.row().prop(system, "opensubdiv_compute_type", text="")
- # 2. Column
- column = split.column()
- colsplit = column.split(factor=0.85)
-
- col = colsplit.column()
- col.label(text="OpenGL:")
- col.prop(system, "gl_clip_alpha", slider=True)
- col.prop(system, "use_gpu_mipmap")
- col.prop(system, "use_16bit_textures")
- col.separator()
- col.label(text="Selection:")
- col.prop(system, "select_method", text="")
- col.prop(system, "use_select_pick_depth")
+class USERPREF_PT_system_opengl(PreferencePanel):
+ bl_label = "OpenGL"
- col.separator()
+ @classmethod
+ def poll(cls, context):
+ prefs = context.preferences
+ return (prefs.active_section == 'SYSTEM_GENERAL')
- col.label(text="Anisotropic Filtering:")
- col.prop(system, "anisotropic_filter", text="")
+ def draw_props(self, context, layout):
+ import sys
+ prefs = context.preferences
+ system = prefs.system
- col.separator()
+ layout.prop(system, "gpu_viewport_quality")
+ layout.prop(system, "gl_clip_alpha", slider=True)
+ layout.prop(system, "multi_sample", text="Multisampling")
+ layout.prop(system, "gpencil_multi_sample", text="Grease Pencil Multisampling")
- col.prop(system, "multi_sample", text="")
if sys.platform == "linux" and system.multi_sample != 'NONE':
- col.label(text="Might fail for Mesh editing selection!")
- col.separator()
- col.prop(system, "use_region_overlap")
+ layout.label(text="Might fail for Mesh editing selection!")
+ layout.separator()
- col.separator()
- col.prop(system, "gpu_viewport_quality")
+ layout.prop(system, "use_region_overlap")
- col.separator()
- col.label(text="Grease Pencil Options:")
- col.prop(system, "gpencil_multi_sample", text="")
- col.separator()
- col.label(text="Text Draw Options:")
- col.prop(system, "use_text_antialiasing", text="Anti-aliasing")
- sub = col.column()
- sub.active = system.use_text_antialiasing
- sub.prop(system, "text_hinting", text="Hinting")
+class USERPREF_PT_system_opengl_textures(PreferencePanel):
+ bl_label = "Textures"
+ bl_parent_id = "USERPREF_PT_system_opengl"
+ bl_options = {'DEFAULT_CLOSED'}
- # 3. Column
- column = split.column()
+ @classmethod
+ def poll(cls, context):
+ prefs = context.preferences
+ return (prefs.active_section == 'SYSTEM_GENERAL')
- column.label(text="Textures:")
- column.prop(system, "gl_texture_limit", text="Limit Size")
- column.prop(system, "texture_time_out", text="Time Out")
- column.prop(system, "texture_collection_rate", text="Collection Rate")
+ def draw_props(self, context, layout):
+ prefs = context.preferences
+ system = prefs.system
- column.separator()
+ layout.prop(system, "gl_texture_limit", text="Limit Size")
+ layout.prop(system, "anisotropic_filter")
+ layout.prop(system, "texture_time_out", text="Time Out")
+ layout.prop(system, "texture_collection_rate", text="Garbage Collection Rate")
+ layout.prop(system, "image_draw_method", text="Image Display Method")
- column.label(text="Images Draw Method:")
- column.prop(system, "image_draw_method", text="")
+ layout.prop(system, "use_16bit_textures")
+ layout.prop(system, "use_gpu_mipmap")
- column.separator()
- column.label(text="Sequencer/Clip Editor:")
- # currently disabled in the code
- # column.prop(system, "prefetch_frames")
- column.prop(system, "memory_cache_limit")
+class USERPREF_PT_system_opengl_selection(PreferencePanel):
+ bl_label = "Selection"
+ bl_parent_id = "USERPREF_PT_system_opengl"
+ bl_options = {'DEFAULT_CLOSED'}
- column.separator()
+ def draw_props(self, context, layout):
+ prefs = context.preferences
+ system = prefs.system
- column.label(text="Color Picker Type:")
- column.row().prop(system, "color_picker_type", text="")
+ layout.prop(system, "select_method", text="Selection Method")
+ layout.prop(system, "use_select_pick_depth")
- column.separator()
- column.prop(system, "use_weight_color_range", text="Custom Weight Paint Range")
- sub = column.column()
- sub.active = system.use_weight_color_range
- sub.template_color_ramp(system, "weight_color_range", expand=True)
+class USERPREF_PT_system_memory(PreferencePanel):
+ bl_label = "Memory"
+ bl_options = {'DEFAULT_CLOSED'}
- column.separator()
- column.prop(system, "font_path_ui")
- column.prop(system, "font_path_ui_mono")
+ @classmethod
+ def poll(cls, context):
+ prefs = context.preferences
+ return (prefs.active_section == 'SYSTEM_GENERAL')
- if bpy.app.build_options.international:
- column.prop(system, "use_international_fonts")
- sub_col = column.column()
- sub_col.active = system.use_international_fonts
- sub_col.prop(system, "language")
- row = sub_col.row()
- row.label(text="Translate:", text_ctxt=i18n_contexts.id_windowmanager)
- row = sub_col.row(align=True)
- row.prop(system, "use_translate_tooltips", text="Tooltips", toggle=True)
- row.prop(system, "use_translate_interface", text="Interface", toggle=True)
- row.prop(system, "use_translate_new_dataname", text="New Data", toggle=True)
+ def draw_props(self, context, layout):
+ prefs = context.preferences
+ system = prefs.system
+ edit = prefs.edit
+
+ layout.prop(edit, "undo_steps", text="Undo Steps")
+ layout.prop(edit, "undo_memory_limit", text="Undo Memory Limit")
+ layout.prop(edit, "use_global_undo")
+
+ layout.separator()
+
+ layout.prop(system, "memory_cache_limit", text="Sequencer Cache Limit")
+
+ layout.separator()
+
+ layout.prop(system, "scrollback", text="Console Scrollback Lines")
class USERPREF_MT_interface_theme_presets(Menu):
@@ -503,388 +687,448 @@ class USERPREF_PT_theme(Panel):
bl_region_type = 'WINDOW'
bl_options = {'HIDE_HEADER'}
- # not essential, hard-coded UI delimiters for the theme layout
- ui_delimiters = {
- 'VIEW_3D': {
- "text_grease_pencil",
- "text_keyframe",
- "speaker",
- "freestyle_face_mark",
- "split_normal",
- "bone_solid",
- "paint_curve_pivot",
- },
- 'GRAPH_EDITOR': {
- "handle_vertex_select",
- },
- 'IMAGE_EDITOR': {
- "paint_curve_pivot",
- },
- 'NODE_EDITOR': {
- "layout_node",
- },
- 'CLIP_EDITOR': {
- "handle_vertex_select",
- }
- }
-
- @staticmethod
- def _theme_generic(split, themedata, theme_area):
-
- col = split.column()
+ @classmethod
+ def poll(cls, context):
+ prefs = context.preferences
+ return (prefs.active_section == 'THEMES')
- def theme_generic_recurse(data):
- col.label(text=data.rna_type.name)
- row = col.row()
- subsplit = row.split(factor=0.95)
+ def draw(self, context):
+ layout = self.layout
- padding1 = subsplit.split(factor=0.15)
- padding1.column()
+ theme = context.preferences.themes[0]
- subsplit = row.split(factor=0.85)
+ row = layout.row()
- padding2 = subsplit.split(factor=0.15)
- padding2.column()
+ row.operator("wm.theme_install", text="Install...", icon='IMPORT')
+ row.operator("ui.reset_default_theme", text="Reset", icon='LOOP_BACK')
- colsub_pair = padding1.column(), padding2.column()
+ subrow = row.row(align=True)
+ subrow.menu("USERPREF_MT_interface_theme_presets", text=USERPREF_MT_interface_theme_presets.bl_label)
+ subrow.operator("wm.interface_theme_preset_add", text="", icon='ADD')
+ subrow.operator("wm.interface_theme_preset_add", text="", icon='REMOVE').remove_active = True
- props_type = {}
- for i, prop in enumerate(data.rna_type.properties):
- if prop.identifier == "rna_type":
- continue
+class USERPREF_PT_theme_user_interface(PreferencePanel):
+ bl_space_type = 'PREFERENCES'
+ bl_region_type = 'WINDOW'
+ bl_label = "User Interface"
+ bl_options = {'DEFAULT_CLOSED'}
- props_type.setdefault((prop.type, prop.subtype), []).append(prop)
+ @classmethod
+ def poll(cls, context):
+ prefs = context.preferences
+ return (prefs.active_section == 'THEMES')
- th_delimiters = USERPREF_PT_theme.ui_delimiters.get(theme_area)
- for props_type, props_ls in sorted(props_type.items()):
- if props_type[0] == 'POINTER':
- for i, prop in enumerate(props_ls):
- theme_generic_recurse(getattr(data, prop.identifier))
- else:
- if th_delimiters is None:
- # simple, no delimiters
- for i, prop in enumerate(props_ls):
- colsub_pair[i % 2].row().prop(data, prop.identifier)
- else:
- # add hard coded delimiters
- i = 0
- for prop in props_ls:
- colsub = colsub_pair[i]
- colsub.row().prop(data, prop.identifier)
- i = (i + 1) % 2
- if prop.identifier in th_delimiters:
- if i:
- colsub = colsub_pair[1]
- colsub.row().label(text="")
- colsub_pair[0].row().label(text="")
- colsub_pair[1].row().label(text="")
- i = 0
-
- theme_generic_recurse(themedata)
+ def draw_header(self, context):
+ layout = self.layout
- @staticmethod
- def _theme_widget_style(layout, widget_style):
+ layout.label(icon='WORKSPACE')
- row = layout.row()
+ def draw(self, context):
+ pass
- subsplit = row.split(factor=0.95)
-
- padding = subsplit.split(factor=0.15)
- colsub = padding.column()
- colsub = padding.column()
- colsub.row().prop(widget_style, "outline")
- colsub.row().prop(widget_style, "item", slider=True)
- colsub.row().prop(widget_style, "inner", slider=True)
- colsub.row().prop(widget_style, "inner_sel", slider=True)
- colsub.row().prop(widget_style, "roundness")
-
- subsplit = row.split(factor=0.85)
-
- padding = subsplit.split(factor=0.15)
- colsub = padding.column()
- colsub = padding.column()
- colsub.row().prop(widget_style, "text")
- colsub.row().prop(widget_style, "text_sel")
- colsub.prop(widget_style, "show_shaded")
- subsub = colsub.column(align=True)
- subsub.active = widget_style.show_shaded
- subsub.prop(widget_style, "shadetop")
- subsub.prop(widget_style, "shadedown")
- layout.separator()
+# Base class for dynamically defined widget color panels.
+class PreferenceThemeWidgetColorPanel(Panel):
+ bl_space_type = 'PREFERENCES'
+ bl_region_type = 'WINDOW'
+ bl_parent_id = "USERPREF_PT_theme_user_interface"
@staticmethod
- def _ui_font_style(layout, font_style):
+ def draw(self, context):
+ theme = context.preferences.themes[0]
+ ui = theme.user_interface
+ widget_style = getattr(ui, self.wcol)
+ layout = self.layout
- split = layout.split()
+ layout.use_property_split = True
- col = split.column()
- col.label(text="Kerning Style:")
- col.row().prop(font_style, "font_kerning_style", expand=True)
- col.prop(font_style, "points")
+ flow = layout.grid_flow(row_major=True, columns=0, even_columns=False, even_rows=False, align=False)
- col = split.column()
- col.label(text="Shadow Offset:")
- col.prop(font_style, "shadow_offset_x", text="X")
- col.prop(font_style, "shadow_offset_y", text="Y")
+ col = flow.column()
+ col.prop(widget_style, "outline")
+ col.prop(widget_style, "item", slider=True)
+ col.prop(widget_style, "inner", slider=True)
+ col.prop(widget_style, "inner_sel", slider=True)
- col = split.column()
- col.prop(font_style, "shadow")
- col.prop(font_style, "shadow_alpha")
- col.prop(font_style, "shadow_value")
+ col = flow.column()
+ col.prop(widget_style, "text")
+ col.prop(widget_style, "text_sel")
+ col.prop(widget_style, "roundness")
- layout.separator()
+ col = flow.column()
+ col.prop(widget_style, "show_shaded")
+
+ colsub = col.column()
+ colsub.active = widget_style.show_shaded
+ colsub.prop(widget_style, "shadetop")
+ colsub.prop(widget_style, "shadedown")
@classmethod
def poll(cls, context):
prefs = context.preferences
return (prefs.active_section == 'THEMES')
- def draw(self, context):
- layout = self.layout
+class USERPREF_PT_theme_interface_state(PreferencePanel):
+ bl_label = "State"
+ bl_options = {'DEFAULT_CLOSED'}
+ bl_parent_id = "USERPREF_PT_theme_user_interface"
+
+ def draw_props(self, context, layout):
theme = context.preferences.themes[0]
+ ui = theme.user_interface
+ ui_state = theme.user_interface.wcol_state
- split_themes = layout.split(factor=0.2)
+ flow = layout.grid_flow(row_major=True, columns=0, even_columns=False, even_rows=False, align=False)
- sub = split_themes.column()
+ col = flow.column(align=True)
+ col.prop(ui_state, "inner_anim")
+ col.prop(ui_state, "inner_anim_sel")
- sub.label(text="Presets:")
- subrow = sub.row(align=True)
+ col = flow.column(align=True)
+ col.prop(ui_state, "inner_driven")
+ col.prop(ui_state, "inner_driven_sel")
- subrow.menu("USERPREF_MT_interface_theme_presets", text=USERPREF_MT_interface_theme_presets.bl_label)
- subrow.operator("wm.interface_theme_preset_add", text="", icon='ADD')
- subrow.operator("wm.interface_theme_preset_add", text="", icon='REMOVE').remove_active = True
- sub.separator()
+ col = flow.column(align=True)
+ col.prop(ui_state, "inner_key")
+ col.prop(ui_state, "inner_key_sel")
- sub.prop(theme, "theme_area", expand=True)
+ col = flow.column(align=True)
+ col.prop(ui_state, "inner_overridden")
+ col.prop(ui_state, "inner_overridden_sel")
- split = layout.split(factor=0.4)
+ col = flow.column(align=True)
+ col.prop(ui_state, "inner_changed")
+ col.prop(ui_state, "inner_changed_sel")
- layout.separator()
- layout.separator()
+ col = flow.column(align=True)
+ col.prop(ui_state, "blend")
- split = split_themes.split()
- if theme.theme_area == 'USER_INTERFACE':
- col = split.column()
- ui = theme.user_interface
+class USERPREF_PT_theme_interface_styles(PreferencePanel):
+ bl_label = "Styles"
+ bl_options = {'DEFAULT_CLOSED'}
+ bl_parent_id = "USERPREF_PT_theme_user_interface"
- col.label(text="Regular:")
- self._theme_widget_style(col, ui.wcol_regular)
+ def draw_props(self, context, layout):
+ theme = context.preferences.themes[0]
+ ui = theme.user_interface
- col.label(text="Tool:")
- self._theme_widget_style(col, ui.wcol_tool)
+ flow = layout.grid_flow(row_major=True, columns=0, even_columns=False, even_rows=False, align=False)
- col.label(text="Toolbar Item:")
- self._theme_widget_style(col, ui.wcol_toolbar_item)
+ flow.prop(ui, "menu_shadow_fac")
+ flow.prop(ui, "icon_alpha")
+ flow.prop(ui, "icon_saturation")
+ flow.prop(ui, "editor_outline")
+ flow.prop(ui, "menu_shadow_width")
+ flow.prop(ui, "widget_emboss")
- col.label(text="Radio Buttons:")
- self._theme_widget_style(col, ui.wcol_radio)
- col.label(text="Text:")
- self._theme_widget_style(col, ui.wcol_text)
+class USERPREF_PT_theme_interface_gizmos(PreferencePanel):
+ bl_label = "Axis & Gizmo Colors"
+ bl_options = {'DEFAULT_CLOSED'}
+ bl_parent_id = "USERPREF_PT_theme_user_interface"
- col.label(text="Option:")
- self._theme_widget_style(col, ui.wcol_option)
+ def draw_props(self, context, layout):
+ theme = context.preferences.themes[0]
+ ui = theme.user_interface
- col.label(text="Toggle:")
- self._theme_widget_style(col, ui.wcol_toggle)
+ flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=True, align=False)
- col.label(text="Number Field:")
- self._theme_widget_style(col, ui.wcol_num)
+ col = flow.column(align=True)
+ col.prop(ui, "axis_x", text="Axis X")
+ col.prop(ui, "axis_y", text="Y")
+ col.prop(ui, "axis_z", text="Z")
- col.label(text="Value Slider:")
- self._theme_widget_style(col, ui.wcol_numslider)
+ col = flow.column()
+ col.prop(ui, "gizmo_primary")
+ col.prop(ui, "gizmo_secondary")
- col.label(text="Box:")
- self._theme_widget_style(col, ui.wcol_box)
+ col = flow.column()
+ col.prop(ui, "gizmo_a")
+ col.prop(ui, "gizmo_b")
- col.label(text="Menu:")
- self._theme_widget_style(col, ui.wcol_menu)
- col.label(text="Pie Menu:")
- self._theme_widget_style(col, ui.wcol_pie_menu)
+class USERPREF_PT_theme_interface_icons(PreferencePanel):
+ bl_label = "Icon Colors"
+ bl_options = {'DEFAULT_CLOSED'}
+ bl_parent_id = "USERPREF_PT_theme_user_interface"
- col.label(text="Pulldown:")
- self._theme_widget_style(col, ui.wcol_pulldown)
+ def draw_props(self, context, layout):
+ theme = context.preferences.themes[0]
+ ui = theme.user_interface
- col.label(text="Menu Back:")
- self._theme_widget_style(col, ui.wcol_menu_back)
+ flow = layout.grid_flow(row_major=True, columns=0, even_columns=False, even_rows=False, align=False)
- col.label(text="Tooltip:")
- self._theme_widget_style(col, ui.wcol_tooltip)
+ flow.prop(ui, "icon_collection")
+ flow.prop(ui, "icon_object")
+ flow.prop(ui, "icon_object_data")
+ flow.prop(ui, "icon_modifier")
+ flow.prop(ui, "icon_shading")
- col.label(text="Menu Item:")
- self._theme_widget_style(col, ui.wcol_menu_item)
- col.label(text="Scroll Bar:")
- self._theme_widget_style(col, ui.wcol_scroll)
+class USERPREF_PT_theme_text_style(PreferencePanel):
+ bl_label = "Text Style"
+ bl_options = {'DEFAULT_CLOSED'}
- col.label(text="Progress Bar:")
- self._theme_widget_style(col, ui.wcol_progress)
+ @classmethod
+ def poll(cls, context):
+ prefs = context.preferences
+ return (prefs.active_section == 'THEMES')
- col.label(text="List Item:")
- self._theme_widget_style(col, ui.wcol_list_item)
+ @staticmethod
+ def _ui_font_style(layout, font_style):
+ layout.use_property_split = True
+ flow = layout.grid_flow(row_major=True, columns=0, even_columns=False, even_rows=False, align=True)
- col.label(text="Tab:")
- self._theme_widget_style(col, ui.wcol_tab)
+ col = flow.column()
+ col.row().prop(font_style, "font_kerning_style", expand=True)
+ col.prop(font_style, "points")
- ui_state = theme.user_interface.wcol_state
- col.label(text="State:")
+ col = flow.column(align=True)
+ col.prop(font_style, "shadow_offset_x", text="Shadow Offset X")
+ col.prop(font_style, "shadow_offset_y", text="Y")
- row = col.row()
+ col = flow.column()
+ col.prop(font_style, "shadow")
+ col.prop(font_style, "shadow_alpha")
+ col.prop(font_style, "shadow_value")
- subsplit = row.split(factor=0.95)
+ def draw_header(self, context):
+ layout = self.layout
- padding = subsplit.split(factor=0.15)
- colsub = padding.column()
- colsub = padding.column()
- colsub.row().prop(ui_state, "inner_anim")
- colsub.row().prop(ui_state, "inner_anim_sel")
- colsub.row().prop(ui_state, "inner_driven")
- colsub.row().prop(ui_state, "inner_driven_sel")
- colsub.row().prop(ui_state, "blend")
+ layout.label(icon='FONTPREVIEW')
- subsplit = row.split(factor=0.85)
+ def draw_props(self, context, layout):
+ style = context.preferences.ui_styles[0]
- padding = subsplit.split(factor=0.15)
- colsub = padding.column()
- colsub = padding.column()
- colsub.row().prop(ui_state, "inner_key")
- colsub.row().prop(ui_state, "inner_key_sel")
- colsub.row().prop(ui_state, "inner_overridden")
- colsub.row().prop(ui_state, "inner_overridden_sel")
- colsub.row().prop(ui_state, "inner_changed")
- colsub.row().prop(ui_state, "inner_changed_sel")
+ layout.label(text="Panel Title")
+ self._ui_font_style(layout, style.panel_title)
- col.separator()
- col.separator()
+ layout.separator()
- col.label(text="Styles:")
+ layout.label(text="Widget")
+ self._ui_font_style(layout, style.widget)
- row = col.row()
+ layout.separator()
- subsplit = row.split(factor=0.95)
+ layout.label(text="Widget Label")
+ self._ui_font_style(layout, style.widget_label)
- padding = subsplit.split(factor=0.15)
- colsub = padding.column()
- colsub = padding.column()
- colsub.row().prop(ui, "menu_shadow_fac")
- colsub.row().prop(ui, "icon_alpha")
- colsub.row().prop(ui, "icon_saturation")
- colsub.row().prop(ui, "editor_outline")
- subsplit = row.split(factor=0.85)
+class USERPREF_PT_theme_bone_color_sets(PreferencePanel):
+ bl_label = "Bone Color Sets"
+ bl_options = {'DEFAULT_CLOSED'}
- padding = subsplit.split(factor=0.15)
- colsub = padding.column()
- colsub = padding.column()
- colsub.row().prop(ui, "menu_shadow_width")
- colsub.row().prop(ui, "widget_emboss")
+ @classmethod
+ def poll(cls, context):
+ prefs = context.preferences
+ return (prefs.active_section == 'THEMES')
- col.separator()
- col.separator()
+ def draw_header(self, context):
+ layout = self.layout
- col.label(text="Axis & Gizmo Colors:")
+ layout.label(icon='COLOR')
- row = col.row()
+ def draw_props(self, context, layout):
+ theme = context.preferences.themes[0]
- subsplit = row.split(factor=0.95)
+ layout.use_property_split = True
- padding = subsplit.split(factor=0.15)
- colsub = padding.column()
- colsub = padding.column()
- colsub.row().prop(ui, "axis_x")
- colsub.row().prop(ui, "axis_y")
- colsub.row().prop(ui, "axis_z")
+ for i, ui in enumerate(theme.bone_color_sets, 1):
+ layout.label(text=iface_(f"Color Set {i:d}"), translate=False)
- subsplit = row.split(factor=0.85)
+ flow = layout.grid_flow(row_major=True, columns=0, even_columns=False, even_rows=False, align=False)
- padding = subsplit.split(factor=0.15)
- colsub = padding.column()
- colsub = padding.column()
- colsub.row().prop(ui, "gizmo_primary")
- colsub.row().prop(ui, "gizmo_secondary")
- colsub.row().prop(ui, "gizmo_a")
- colsub.row().prop(ui, "gizmo_b")
+ flow.prop(ui, "normal")
+ flow.prop(ui, "select")
+ flow.prop(ui, "active")
+ flow.prop(ui, "show_colored_constraints")
- col.separator()
- col.separator()
- col.label(text="Icon Colors:")
+# Base class for dynamically defined theme-space panels.
+class PreferenceThemeSpacePanel(Panel):
+ bl_space_type = 'PREFERENCES'
+ bl_region_type = 'WINDOW'
- row = col.row()
+ # not essential, hard-coded UI delimiters for the theme layout
+ ui_delimiters = {
+ 'VIEW_3D': {
+ "text_grease_pencil",
+ "text_keyframe",
+ "speaker",
+ "freestyle_face_mark",
+ "split_normal",
+ "bone_solid",
+ "paint_curve_pivot",
+ },
+ 'GRAPH_EDITOR': {
+ "handle_vertex_select",
+ },
+ 'IMAGE_EDITOR': {
+ "paint_curve_pivot",
+ },
+ 'NODE_EDITOR': {
+ "layout_node",
+ },
+ 'CLIP_EDITOR': {
+ "handle_vertex_select",
+ }
+ }
- subsplit = row.split(factor=0.95)
+ # TODO theme_area should be deprecated
+ @staticmethod
+ def _theme_generic(layout, themedata, theme_area):
- padding = subsplit.split(factor=0.15)
- colsub = padding.column()
- colsub = padding.column()
- colsub.row().prop(ui, "icon_collection")
- colsub.row().prop(ui, "icon_object")
- colsub.row().prop(ui, "icon_object_data")
+ layout.use_property_split = True
- subsplit = row.split(factor=0.85)
+ flow = layout.grid_flow(row_major=True, columns=0, even_columns=False, even_rows=False, align=False)
- padding = subsplit.split(factor=0.15)
- colsub = padding.column()
- colsub = padding.column()
- colsub.row().prop(ui, "icon_modifier")
- colsub.row().prop(ui, "icon_shading")
+ props_type = {}
- col.separator()
- col.separator()
- elif theme.theme_area == 'BONE_COLOR_SETS':
- col = split.column()
+ for i, prop in enumerate(themedata.rna_type.properties):
+ if prop.identifier == "rna_type":
+ continue
- for i, ui in enumerate(theme.bone_color_sets, 1):
- col.label(text=iface_(f"Color Set {i:d}"), translate=False)
+ props_type.setdefault((prop.type, prop.subtype), []).append(prop)
- row = col.row()
+ th_delimiters = PreferenceThemeSpacePanel.ui_delimiters.get(theme_area)
+ for props_type, props_ls in sorted(props_type.items()):
+ if props_type[0] == 'POINTER':
+ continue
- subsplit = row.split(factor=0.95)
+ if th_delimiters is None:
+ # simple, no delimiters
+ for i, prop in enumerate(props_ls):
+ flow.prop(themedata, prop.identifier)
+ else:
- padding = subsplit.split(factor=0.15)
- colsub = padding.column()
- colsub = padding.column()
- colsub.row().prop(ui, "normal")
- colsub.row().prop(ui, "select")
- colsub.row().prop(ui, "active")
+ for prop in props_ls:
+ flow.prop(themedata, prop.identifier)
- subsplit = row.split(factor=0.85)
+ @staticmethod
+ def draw_header(self, context):
+ if hasattr(self, "icon") and self.icon != 'NONE':
+ layout = self.layout
+ layout.label(icon=self.icon)
- padding = subsplit.split(factor=0.15)
- colsub = padding.column()
- colsub = padding.column()
- colsub.row().prop(ui, "show_colored_constraints")
- elif theme.theme_area == 'STYLE':
- col = split.column()
+ @staticmethod
+ def draw(self, context):
+ layout = self.layout
+ theme = context.preferences.themes[0]
- style = context.preferences.ui_styles[0]
+ datapath_list = self.datapath.split(".")
+ data = theme
+ for datapath_item in datapath_list:
+ data = getattr(data, datapath_item)
+ PreferenceThemeSpacePanel._theme_generic(layout, data, self.theme_area)
- col.label(text="Panel Title:")
- self._ui_font_style(col, style.panel_title)
+ @classmethod
+ def poll(cls, context):
+ prefs = context.preferences
+ return (prefs.active_section == 'THEMES')
- col.separator()
- col.label(text="Widget:")
- self._ui_font_style(col, style.widget)
+class ThemeGenericClassGenerator():
+ generated_classes = []
- col.separator()
+ @staticmethod
+ def generate_panel_classes_for_wcols():
+ wcols = [
+ ("Regular", "wcol_regular"),
+ ("Tool", "wcol_tool"),
+ ("Toolbar Item", "wcol_toolbar_item"),
+ ("Radio Buttons", "wcol_radio"),
+ ("Text", "wcol_text"),
+ ("Option", "wcol_option"),
+ ("Toggle", "wcol_toggle"),
+ ("Number Field", "wcol_num"),
+ ("Value Slider", "wcol_numslider"),
+ ("Box", "wcol_box"),
+ ("Menu", "wcol_menu"),
+ ("Pie Menu", "wcol_pie_menu"),
+ ("Pulldown", "wcol_pulldown"),
+ ("Menu Back", "wcol_menu_back"),
+ ("Tooltip", "wcol_tooltip"),
+ ("Menu Item", "wcol_menu_item"),
+ ("Scroll Bar", "wcol_scroll"),
+ ("Progress Bar", "wcol_progress"),
+ ("List Item", "wcol_list_item"),
+ ("Tab", "wcol_tab"),
+ ]
- col.label(text="Widget Label:")
- self._ui_font_style(col, style.widget_label)
- else:
- self._theme_generic(split, getattr(theme, theme.theme_area.lower()), theme.theme_area)
+ for (name, wcol) in wcols:
+ panel_id = "USERPREF_PT_theme_interface_" + wcol
+ paneltype = type(panel_id, (PreferenceThemeWidgetColorPanel,), {
+ "bl_label": name,
+ "bl_options": {'DEFAULT_CLOSED'},
+ "draw": PreferenceThemeWidgetColorPanel.draw,
+ "wcol": wcol,
+ })
+
+ ThemeGenericClassGenerator.generated_classes.append(paneltype)
+
+ @staticmethod
+ def generate_theme_area_child_panel_classes(parent_id, rna_type, theme_area, datapath):
+ def generate_child_panel_classes_recurse(parent_id, rna_type, theme_area, datapath):
+ props_type = {}
+
+ for i, prop in enumerate(rna_type.properties):
+ if prop.identifier == "rna_type":
+ continue
+
+ props_type.setdefault((prop.type, prop.subtype), []).append(prop)
+
+ for props_type, props_ls in sorted(props_type.items()):
+ if props_type[0] == 'POINTER':
+ for i, prop in enumerate(props_ls):
+ new_datapath = datapath + "." + prop.identifier if datapath else prop.identifier
+ panel_id = parent_id + "_" + prop.identifier
+ paneltype = type(panel_id, (PreferenceThemeSpacePanel,), {
+ "bl_label": rna_type.properties[prop.identifier].name,
+ "bl_parent_id": parent_id,
+ "bl_options": {'DEFAULT_CLOSED'},
+ "draw": PreferenceThemeSpacePanel.draw,
+ "theme_area": theme_area.identifier,
+ "datapath": new_datapath,
+ })
+
+ ThemeGenericClassGenerator.generated_classes.append(paneltype)
+ generate_child_panel_classes_recurse(panel_id, prop.fixed_type, theme_area, new_datapath)
+
+ generate_child_panel_classes_recurse(parent_id, rna_type, theme_area, datapath)
+ @staticmethod
+ def generate_panel_classes_from_theme_areas():
+ from bpy.types import Theme
+
+ for theme_area in Theme.bl_rna.properties['theme_area'].enum_items_static:
+ if theme_area.identifier in {'USER_INTERFACE', 'STYLE', 'BONE_COLOR_SETS'}:
+ continue
-class USERPREF_PT_file(Panel):
+ panel_id = "USERPREF_PT_theme_" + theme_area.identifier.lower()
+ # Generate panel-class from theme_area
+ paneltype = type(panel_id, (PreferenceThemeSpacePanel,), {
+ "bl_label": theme_area.name,
+ "bl_options": {'DEFAULT_CLOSED'},
+ "draw_header": PreferenceThemeSpacePanel.draw_header,
+ "draw": PreferenceThemeSpacePanel.draw,
+ "theme_area": theme_area.identifier,
+ "icon": theme_area.icon,
+ "datapath": theme_area.identifier.lower(),
+ })
+
+ ThemeGenericClassGenerator.generated_classes.append(paneltype)
+ ThemeGenericClassGenerator.generate_theme_area_child_panel_classes(
+ panel_id, Theme.bl_rna.properties[theme_area.identifier.lower()].fixed_type,
+ theme_area, theme_area.identifier.lower())
+
+
+class USERPREF_PT_file_paths(Panel):
bl_space_type = 'PREFERENCES'
- bl_label = "Files"
bl_region_type = 'WINDOW'
- bl_options = {'HIDE_HEADER'}
+ bl_label = "File Paths"
@classmethod
def poll(cls, context):
@@ -893,104 +1137,127 @@ class USERPREF_PT_file(Panel):
def draw(self, context):
layout = self.layout
-
prefs = context.preferences
paths = prefs.filepaths
system = prefs.system
- split = layout.split(factor=0.7)
-
- col = split.column()
- col.label(text="File Paths:")
-
- colsplit = col.split(factor=0.95)
- col1 = colsplit.split(factor=0.3)
-
- sub = col1.column()
- sub.label(text="Fonts:")
- sub.label(text="Textures:")
- sub.label(text="Render Output:")
- sub.label(text="Scripts:")
- sub.label(text="Sounds:")
- sub.label(text="Temp:")
- sub.label(text="Render Cache:")
- sub.label(text="I18n Branches:")
- sub.label(text="Image Editor:")
- sub.label(text="Animation Player:")
-
- sub = col1.column()
- sub.prop(paths, "font_directory", text="")
- sub.prop(paths, "texture_directory", text="")
- sub.prop(paths, "render_output_directory", text="")
- sub.prop(paths, "script_directory", text="")
- sub.prop(paths, "sound_directory", text="")
- sub.prop(paths, "temporary_directory", text="")
- sub.prop(paths, "render_cache_directory", text="")
- sub.prop(paths, "i18n_branches_directory", text="")
- sub.prop(paths, "image_editor", text="")
- subsplit = sub.split(factor=0.3)
- subsplit.prop(paths, "animation_player_preset", text="")
- subsplit.prop(paths, "animation_player", text="")
-
- col.separator()
- col.separator()
-
- colsplit = col.split(factor=0.95)
- sub = colsplit.column()
-
- row = sub.split(factor=0.3)
- row.label(text="Auto Execution:")
- row.prop(system, "use_scripts_auto_execute")
-
- if system.use_scripts_auto_execute:
- box = sub.box()
+ layout.use_property_split = True
+ layout.use_property_decorate = False # No animation.
+
+ layout.prop(paths, "render_output_directory", text="Render Output")
+ layout.prop(paths, "render_cache_directory", text="Render Cache")
+ layout.prop(paths, "font_directory", text="Fonts")
+ layout.prop(paths, "texture_directory", text="Textures")
+ layout.prop(paths, "script_directory", text="Scripts")
+ layout.prop(paths, "sound_directory", text="Sounds")
+ layout.prop(paths, "temporary_directory", text="Temp")
+ layout.prop(paths, "i18n_branches_directory", text="I18n Branches")
+ layout.prop(paths, "image_editor", text="Image Editor")
+ layout.prop(paths, "animation_player_preset", text="Playback Preset")
+
+ row = layout.row()
+ row.enabled = paths.animation_player_preset == 'CUSTOM'
+ row.prop(paths, "animation_player", text="Animation Player")
+
+
+class USERPREF_PT_file_autorun(Panel):
+ bl_space_type = 'PREFERENCES'
+ bl_region_type = 'WINDOW'
+ bl_label = "Auto Run Python Scripts"
+ bl_options = {'DEFAULT_CLOSED'}
+
+ @classmethod
+ def poll(cls, context):
+ prefs = context.preferences
+ return (prefs.active_section == 'SYSTEM_FILES')
+
+ def draw_header(self, context):
+ prefs = context.preferences
+ paths = prefs.filepaths
+
+ self.layout.prop(paths, "use_scripts_auto_execute", text="")
+
+ def draw(self, context):
+ layout = self.layout
+ prefs = context.preferences
+ paths = prefs.filepaths
+
+ layout.use_property_split = True
+ layout.use_property_decorate = False # No animation.
+
+ layout.active = paths.use_scripts_auto_execute
+
+ box = layout.box()
+ row = box.row()
+ row.label(text="Excluded Paths:")
+ row.operator("wm.userpref_autoexec_path_add", text="", icon='ADD', emboss=False)
+ for i, path_cmp in enumerate(prefs.autoexec_paths):
row = box.row()
- row.label(text="Excluded Paths:")
- row.operator("wm.userpref_autoexec_path_add", text="", icon='ADD', emboss=False)
- for i, path_cmp in enumerate(prefs.autoexec_paths):
- row = box.row()
- row.prop(path_cmp, "path", text="")
- row.prop(path_cmp, "use_glob", text="", icon='FILTER')
- row.operator("wm.userpref_autoexec_path_remove", text="", icon='X', emboss=False).index = i
-
- col = split.column()
- col.label(text="Save & Load:")
- col.prop(paths, "use_relative_paths")
- col.prop(paths, "use_file_compression")
- col.prop(paths, "use_load_ui")
- col.prop(paths, "use_filter_files")
- col.prop(paths, "show_hidden_files_datablocks")
- col.prop(paths, "hide_recent_locations")
- col.prop(paths, "hide_system_bookmarks")
- col.prop(paths, "show_thumbnails")
-
- col.separator()
-
- col.prop(paths, "save_version")
- col.prop(paths, "recent_files")
- col.prop(paths, "use_save_preview_images")
-
- col.separator()
-
- col.label(text="Auto Save:")
- col.prop(paths, "use_keep_session")
- col.prop(paths, "use_auto_save_temporary_files")
- sub = col.column()
+ row.prop(path_cmp, "path", text="")
+ row.prop(path_cmp, "use_glob", text="", icon='FILTER')
+ row.operator("wm.userpref_autoexec_path_remove", text="", icon='X', emboss=False).index = i
+
+
+class USERPREF_PT_file_saveload(PreferencePanel):
+ bl_label = "Save & Load"
+ bl_options = {'DEFAULT_CLOSED'}
+
+ @classmethod
+ def poll(cls, context):
+ prefs = context.preferences
+ return (prefs.active_section == 'SYSTEM_FILES')
+
+ def draw_props(self, context, layout):
+ prefs = context.preferences
+ paths = prefs.filepaths
+ system = prefs.system
+
+ flow = layout.grid_flow(row_major=True, columns=0, even_columns=False, even_rows=False, align=False)
+
+ flow.prop(paths, "use_relative_paths")
+ flow.prop(paths, "use_file_compression")
+ flow.prop(paths, "use_load_ui")
+ flow.prop(paths, "use_filter_files")
+ flow.prop(paths, "show_hidden_files_datablocks")
+ flow.prop(paths, "hide_recent_locations")
+ flow.prop(paths, "hide_system_bookmarks")
+ flow.prop(paths, "show_thumbnails")
+ flow.prop(paths, "use_save_preview_images")
+
+ layout.separator()
+
+ layout.prop(paths, "save_version")
+ layout.prop(paths, "recent_files")
+
+
+class USERPREF_PT_file_saveload_autosave(PreferencePanel):
+ bl_label = "Auto Save"
+ bl_parent_id = "USERPREF_PT_file_saveload"
+ bl_options = {'DEFAULT_CLOSED'}
+
+ def draw_props(self, context, layout):
+ prefs = context.preferences
+ paths = prefs.filepaths
+ system = prefs.system
+
+ layout.prop(paths, "use_keep_session")
+ layout.prop(paths, "use_auto_save_temporary_files")
+ sub = layout.column()
sub.active = paths.use_auto_save_temporary_files
sub.prop(paths, "auto_save_time", text="Timer (mins)")
- col.separator()
- col.label(text="Text Editor:")
- col.prop(system, "use_tabs_as_spaces")
+class USERPREF_PT_file_saveload_texteditor(PreferencePanel):
+ bl_label = "Text Editor"
+ bl_parent_id = "USERPREF_PT_file_saveload"
+ bl_options = {'DEFAULT_CLOSED'}
- colsplit = col.split(factor=0.95)
- col1 = colsplit.split(factor=0.3)
+ def draw_props(self, context, layout):
+ prefs = context.preferences
+ paths = prefs.filepaths
- sub = col1.column()
- sub.label(text="Author:")
- sub = col1.column()
- sub.prop(system, "author", text="")
+ layout.prop(paths, "use_tabs_as_spaces")
+ layout.prop(paths, "author", text="Author")
class USERPREF_MT_ndof_settings(Menu):
@@ -1040,146 +1307,231 @@ class USERPREF_MT_ndof_settings(Menu):
layout.prop(input_prefs, "ndof_lock_horizon", icon='NDOF_DOM')
-class USERPREF_MT_keyconfigs(Menu):
- bl_label = "KeyPresets"
- preset_subdir = "keyconfig"
- preset_operator = "wm.keyconfig_activate"
+class USERPREF_PT_input_devices(PreferencePanel):
+ bl_label = "Devices"
+
+ @classmethod
+ def poll(cls, context):
+ prefs = context.preferences
+ return (prefs.active_section == 'INPUT')
def draw(self, context):
- Menu.draw_preset(self, context)
+ pass
-class USERPREF_PT_input(Panel):
- bl_space_type = 'PREFERENCES'
- bl_label = "Input"
- bl_region_type = 'WINDOW'
- bl_options = {'HIDE_HEADER'}
+class USERPREF_PT_input_devices_keyboard(PreferencePanel):
+ bl_label = "Keyboard"
+ bl_parent_id = "USERPREF_PT_input_devices"
+
+ def draw_props(self, context, layout):
+ prefs = context.preferences
+ inputs = prefs.inputs
+
+ layout.prop(inputs, "use_emulate_numpad")
+
+
+class USERPREF_PT_input_devices_mouse(PreferencePanel):
+ bl_label = "Mouse"
+ bl_parent_id = "USERPREF_PT_input_devices"
+
+ def draw_props(self, context, layout):
+ prefs = context.preferences
+ inputs = prefs.inputs
+
+ layout.prop(inputs, "drag_threshold")
+ layout.prop(inputs, "tweak_threshold")
+ layout.prop(inputs, "mouse_double_click_time", text="Double Click Speed")
+ layout.prop(inputs, "use_mouse_emulate_3_button")
+ layout.prop(inputs, "use_mouse_continuous")
+
+
+class USERPREF_PT_input_view(PreferencePanel):
+ bl_label = "View Manipulation"
+ bl_options = {'DEFAULT_CLOSED'}
@classmethod
def poll(cls, context):
prefs = context.preferences
return (prefs.active_section == 'INPUT')
- @staticmethod
- def draw_input_prefs(inputs, layout):
- import sys
+ def draw(self, context):
+ pass
- # General settings
- sub = layout.column()
- sub.label(text="Mouse:")
- sub.prop(inputs, "use_mouse_emulate_3_button")
- sub.prop(inputs, "use_mouse_continuous")
- sub.prop(inputs, "drag_threshold")
- sub.prop(inputs, "tweak_threshold")
+class USERPREF_PT_input_view_orbit(PreferencePanel):
+ bl_label = "Orbit & Pan"
+ bl_parent_id = "USERPREF_PT_input_view"
+ bl_options = {'DEFAULT_CLOSED'}
- sub = layout.column()
- sub.label(text="Double Click:")
- sub.prop(inputs, "mouse_double_click_time", text="Speed")
+ def draw_props(self, context, layout):
+ import sys
+ prefs = context.preferences
+ inputs = prefs.inputs
- sub.separator()
+ layout.row().prop(inputs, "view_rotate_method", expand=True)
+ layout.prop(inputs, "use_rotate_around_active")
+ layout.prop(inputs, "use_auto_perspective")
+ layout.prop(inputs, "use_mouse_depth_navigate")
- sub.prop(inputs, "use_emulate_numpad")
+ if sys.platform == "darwin":
+ layout.prop(inputs, "use_trackpad_natural", text="Natural Trackpad Direction")
- sub.separator()
- sub.label(text="Orbit Style:")
- sub.row().prop(inputs, "view_rotate_method", expand=True)
+class USERPREF_PT_input_view_zoom(PreferencePanel):
+ bl_label = "Zoom"
+ bl_parent_id = "USERPREF_PT_input_view"
+ bl_options = {'DEFAULT_CLOSED'}
- sub.separator()
+ def draw_props(self, context, layout):
+ prefs = context.preferences
+ inputs = prefs.inputs
- sub.label(text="Zoom Style:")
- sub.row().prop(inputs, "view_zoom_method", text="")
+ layout.row().prop(inputs, "view_zoom_method", text="Zoom Method", expand=True)
if inputs.view_zoom_method in {'DOLLY', 'CONTINUE'}:
- sub.row().prop(inputs, "view_zoom_axis", expand=True)
- sub.prop(inputs, "invert_mouse_zoom", text="Invert Mouse Zoom Direction")
+ layout.row().prop(inputs, "view_zoom_axis", expand=True)
+ layout.prop(inputs, "invert_mouse_zoom", text="Invert Mouse Zoom Direction")
- # layout.separator()
+ layout.prop(inputs, "invert_zoom_wheel", text="Invert Wheel Zoom Direction")
+ # sub.prop(view, "wheel_scroll_lines", text="Scroll Lines")
+ layout.prop(inputs, "use_zoom_to_mouse")
- sub = layout.column()
- sub.prop(inputs, "invert_zoom_wheel", text="Invert Wheel Zoom Direction")
- #sub.prop(view, "wheel_scroll_lines", text="Scroll Lines")
- if sys.platform == "darwin":
- sub = layout.column()
- sub.prop(inputs, "use_trackpad_natural", text="Natural Trackpad Direction")
+class USERPREF_PT_input_view_cursor(PreferencePanel):
+ bl_label = "Cursor"
+ bl_parent_id = "USERPREF_PT_input_view"
+ bl_options = {'DEFAULT_CLOSED'}
+
+ def draw_props(self, context, layout):
+ prefs = context.preferences
+ inputs = prefs.inputs
+
+ layout.prop(inputs, "use_mouse_depth_cursor")
+ layout.prop(inputs, "use_cursor_lock_adjust")
- layout.separator()
- sub = layout.column()
- sub.label(text="View Navigation:")
- sub.row().prop(inputs, "navigation_mode", expand=True)
- sub.label(text="Walk Navigation:")
+class USERPREF_PT_input_view_fly_walk(PreferencePanel):
+ bl_label = "Fly & Walk"
+ bl_parent_id = "USERPREF_PT_input_view"
+ bl_options = {'DEFAULT_CLOSED'}
+
+ def draw_props(self, context, layout):
+ prefs = context.preferences
+ inputs = prefs.inputs
+
+ layout.row().prop(inputs, "navigation_mode", expand=True)
+ layout.prop(inputs, "use_camera_lock_parent")
+
+ layout.label(text="Walk Navigation:")
walk = inputs.walk_navigation
- sub.prop(walk, "use_mouse_reverse")
- sub.prop(walk, "mouse_speed")
- sub.prop(walk, "teleport_time")
+ layout.prop(walk, "use_mouse_reverse")
+ layout.prop(walk, "mouse_speed")
+ layout.prop(walk, "teleport_time")
sub = layout.column(align=True)
sub.prop(walk, "walk_speed")
sub.prop(walk, "walk_speed_factor")
- sub.separator()
- sub.prop(walk, "use_gravity")
- sub = layout.column(align=True)
- sub.active = walk.use_gravity
- sub.prop(walk, "view_height")
- sub.prop(walk, "jump_height")
- sub.separator()
- sub = layout.column()
- sub.label(text="Tablet Pressure:")
- sub.prop(inputs, "pressure_threshold_max")
- sub.prop(inputs, "pressure_softness")
+class USERPREF_PT_input_view_fly_walk_gravity(PreferencePanel):
+ bl_label = "Gravity"
+ bl_parent_id = "USERPREF_PT_input_view_fly_walk"
- if inputs.use_ndof:
- layout.separator()
- layout.label(text="NDOF Device:")
- sub = layout.column(align=True)
- sub.prop(inputs, "ndof_sensitivity", text="Pan Sensitivity")
- sub.prop(inputs, "ndof_orbit_sensitivity", text="Orbit Sensitivity")
- sub.prop(inputs, "ndof_deadzone", text="Deadzone")
-
- sub.separator()
- layout.label(text="Navigation Style:")
- sub = layout.column(align=True)
- sub.row().prop(inputs, "ndof_view_navigate_method", expand=True)
-
- sub.separator()
- layout.label(text="Rotation Style:")
- sub = layout.column(align=True)
- sub.row().prop(inputs, "ndof_view_rotate_method", expand=True)
+ def draw_header(self, context):
+ prefs = context.preferences
+ inputs = prefs.inputs
+ walk = inputs.walk_navigation
- def draw(self, context):
- from rna_keymap_ui import draw_keymaps
+ self.layout.prop(walk, "use_gravity", text="")
- layout = self.layout
+ def draw_props(self, context, layout):
+ prefs = context.preferences
+ inputs = prefs.inputs
+ walk = inputs.walk_navigation
+
+ layout.active = walk.use_gravity
+ layout.prop(walk, "view_height")
+ layout.prop(walk, "jump_height")
- #import time
- #start = time.time()
+class USERPREF_PT_input_devices_tablet(PreferencePanel):
+ bl_label = "Tablet"
+ bl_parent_id = "USERPREF_PT_input_devices"
+ bl_options = {'DEFAULT_CLOSED'}
+ def draw_props(self, context, layout):
prefs = context.preferences
+ inputs = prefs.inputs
+
+ layout.prop(inputs, "pressure_threshold_max")
+ layout.prop(inputs, "pressure_softness")
+
+class USERPREF_PT_input_devices_ndof(PreferencePanel):
+ bl_label = "NDOF"
+ bl_parent_id = "USERPREF_PT_input_devices"
+ bl_options = {'DEFAULT_CLOSED'}
+
+ @classmethod
+ def poll(cls, context):
+ prefs = context.preferences
inputs = prefs.inputs
+ if inputs.use_ndof:
+ return (prefs.active_section == 'INPUT')
- split = layout.split(factor=0.25)
+ def draw_props(self, context, layout):
+ prefs = context.preferences
+ inputs = prefs.inputs
- row = split.row()
- col = row.column()
+ layout.prop(inputs, "ndof_sensitivity", text="Pan Sensitivity")
+ layout.prop(inputs, "ndof_orbit_sensitivity", text="Orbit Sensitivity")
+ layout.prop(inputs, "ndof_deadzone", text="Deadzone")
+
+ layout.separator()
+
+ layout.row().prop(inputs, "ndof_view_navigate_method", expand=True)
+ layout.row().prop(inputs, "ndof_view_rotate_method", expand=True)
+
+
+class USERPREF_MT_keyconfigs(Menu):
+ bl_label = "KeyPresets"
+ preset_subdir = "keyconfig"
+ preset_operator = "wm.keyconfig_activate"
+
+ def draw(self, context):
+ Menu.draw_preset(self, context)
+
+
+class USERPREF_PT_keymap(Panel):
+ bl_space_type = 'PREFERENCES'
+ bl_label = "Keymap"
+ bl_region_type = 'WINDOW'
+ bl_options = {'HIDE_HEADER'}
+
+ @classmethod
+ def poll(cls, context):
+ prefs = context.preferences
+ return (prefs.active_section == 'KEYMAP')
+
+ def draw(self, context):
+ from rna_keymap_ui import draw_keymaps
+
+ layout = self.layout
+
+ # import time
+
+ # start = time.time()
- # Input settings
- self.draw_input_prefs(inputs, col)
+ prefs = context.preferences
+ keymappref = prefs.keymap
- row.separator()
+ col = layout.column()
# Keymap Settings
- col = split.column()
draw_keymaps(context, col)
- #print("runtime", time.time() - start)
+ # print("runtime", time.time() - start)
class USERPREF_MT_addons_online_resources(Menu):
@@ -1281,17 +1633,19 @@ class USERPREF_PT_addons(Panel):
for mod in addon_utils.modules(refresh=False)
]
- split = layout.split(factor=0.2)
- col = split.column()
- col.prop(context.window_manager, "addon_search", text="", icon='VIEWZOOM')
+ row = layout.row()
+ row.operator("wm.addon_install", icon='IMPORT', text="Install...")
+ row.operator("wm.addon_refresh", icon='FILE_REFRESH', text="Refresh")
+ row.menu("USERPREF_MT_addons_online_resources", text="Online Resources")
- col.label(text="Supported Level")
- col.prop(context.window_manager, "addon_support", expand=True)
+ layout.separator()
- col.label(text="Categories")
- col.prop(context.window_manager, "addon_filter", expand=True)
+ row = layout.row()
+ row.prop(context.window_manager, "addon_support", expand=True)
+ row.prop(context.window_manager, "addon_filter", text="")
+ row.prop(context.window_manager, "addon_search", text="", icon='VIEWZOOM')
- col = split.column()
+ col = layout.column()
# set in addon_utils.modules_refresh()
if addon_utils.error_duplicates:
@@ -1378,7 +1732,7 @@ class USERPREF_PT_addons(Panel):
# WARNING: 2.8x exception, may be removed
# use disabled state for old add-ons, chances are they are broken.
if is_addon_27x:
- sub.label(text="Upgrade to 2.8x required")
+ sub.label(text="upgrade to 2.8x required")
sub.label(icon='ERROR')
# Remove code above after 2.8x migration is complete.
elif info["warning"]:
@@ -1441,7 +1795,7 @@ class USERPREF_PT_addons(Panel):
for _ in range(4 - tot_row):
split.separator()
- # Show addon preferences
+ # Show addon user preferences
if is_enabled:
addon_preferences = prefs.addons[module_name].preferences
if addon_preferences is not None:
@@ -1486,6 +1840,29 @@ class USERPREF_PT_addons(Panel):
row.label(text=module_name, translate=False)
+class USERPREF_PT_studiolight_add(PreferencePanel):
+ bl_space_type = 'PREFERENCES'
+ bl_label = "Add Lights"
+ bl_region_type = 'WINDOW'
+ bl_options = {'HIDE_HEADER'}
+
+ @classmethod
+ def poll(cls, context):
+ prefs = context.preferences
+ return (prefs.active_section == 'LIGHTS')
+
+ def draw(self, context):
+ layout = self.layout
+ prefs = context.preferences
+
+ row = layout.row()
+ row.operator("wm.studiolight_install", icon='IMPORT', text="Add MatCap...").type = 'MATCAP'
+ row.operator("wm.studiolight_install", icon='IMPORT', text="Add LookDev HDRI...").type = 'WORLD'
+ op = row.operator("wm.studiolight_install", icon='IMPORT', text="Add Studio Light...")
+ op.type = 'STUDIO'
+ op.filter_glob = ".sl"
+
+
class StudioLightPanelMixin():
bl_space_type = 'PREFERENCES'
bl_region_type = 'WINDOW'
@@ -1507,7 +1884,7 @@ class StudioLightPanelMixin():
def draw_light_list(self, layout, lights):
if lights:
- flow = layout.column_flow(columns=4)
+ flow = layout.grid_flow(row_major=True, columns=0, even_columns=False, even_rows=False, align=False)
for studio_light in lights:
self.draw_studio_light(flow, studio_light)
else:
@@ -1549,6 +1926,7 @@ class USERPREF_PT_studiolight_light_editor(Panel):
bl_parent_id = "USERPREF_PT_studiolight_lights"
bl_space_type = 'PREFERENCES'
bl_region_type = 'WINDOW'
+ bl_options = {'DEFAULT_CLOSED'}
def opengl_light_buttons(self, layout, light):
@@ -1597,26 +1975,93 @@ class USERPREF_PT_studiolight_light_editor(Panel):
layout.prop(system, "light_ambient")
-classes = (
+ThemeGenericClassGenerator.generate_panel_classes_for_wcols()
+
+# Order of registration defines order in UI, so dynamically generated classes are 'injected' in the intended order.
+classes = (USERPREF_PT_theme_user_interface,) + tuple(ThemeGenericClassGenerator.generated_classes)
+
+classes += (
USERPREF_HT_header,
USERPREF_PT_navigation,
- USERPREF_PT_interface,
- USERPREF_PT_edit,
- USERPREF_PT_system_general,
+ USERPREF_PT_save_preferences,
+
+ USERPREF_PT_interface_display,
+ USERPREF_PT_interface_display_info,
+ USERPREF_PT_interface_text,
+ USERPREF_PT_interface_text_translate,
+ USERPREF_PT_interface_viewports,
+ USERPREF_PT_interface_viewports_3d,
+ USERPREF_PT_interface_viewports_3d_weight_paint,
+ USERPREF_PT_interface_viewports_2d,
+ USERPREF_PT_interface_menus,
+ USERPREF_PT_interface_menus_mouse_over,
+ USERPREF_PT_interface_menus_pie,
+ USERPREF_PT_interface_develop,
+ USERPREF_PT_interface_templates,
+
+ USERPREF_PT_edit_objects,
+ USERPREF_PT_edit_animation,
+ USERPREF_PT_edit_animation_autokey,
+ USERPREF_PT_edit_animation_fcurves,
+ USERPREF_PT_edit_transform,
+ USERPREF_PT_edit_duplicate_data,
+ USERPREF_PT_edit_gpencil,
+ USERPREF_PT_edit_annotations,
+ USERPREF_PT_edit_misc,
+
+ USERPREF_PT_system_opengl,
+ USERPREF_PT_system_opengl_textures,
+ USERPREF_PT_system_opengl_selection,
+ USERPREF_PT_system_sound,
+ USERPREF_PT_system_compute_device,
+ USERPREF_PT_system_memory,
+
USERPREF_MT_interface_theme_presets,
USERPREF_PT_theme,
- USERPREF_PT_file,
+ USERPREF_PT_theme_interface_state,
+ USERPREF_PT_theme_interface_styles,
+ USERPREF_PT_theme_interface_gizmos,
+ USERPREF_PT_theme_interface_icons,
+ USERPREF_PT_theme_text_style,
+ USERPREF_PT_theme_bone_color_sets,
+
+ USERPREF_PT_file_paths,
+ USERPREF_PT_file_autorun,
+ USERPREF_PT_file_saveload,
+ USERPREF_PT_file_saveload_autosave,
+ USERPREF_PT_file_saveload_texteditor,
+
USERPREF_MT_ndof_settings,
USERPREF_MT_keyconfigs,
- USERPREF_PT_input,
+
+ USERPREF_PT_input_devices,
+ USERPREF_PT_input_devices_keyboard,
+ USERPREF_PT_input_devices_mouse,
+ USERPREF_PT_input_devices_tablet,
+ USERPREF_PT_input_devices_ndof,
+ USERPREF_PT_input_view,
+ USERPREF_PT_input_view_orbit,
+ USERPREF_PT_input_view_zoom,
+ USERPREF_PT_input_view_cursor,
+ USERPREF_PT_input_view_fly_walk,
+ USERPREF_PT_input_view_fly_walk_gravity,
+
+ USERPREF_PT_keymap,
USERPREF_MT_addons_online_resources,
USERPREF_PT_addons,
+
+ USERPREF_PT_studiolight_add,
USERPREF_PT_studiolight_lights,
USERPREF_PT_studiolight_light_editor,
USERPREF_PT_studiolight_matcaps,
USERPREF_PT_studiolight_world,
)
+# Add dynamically generated editor theme panels last, so they show up last in the theme section.
+ThemeGenericClassGenerator.generated_classes.clear()
+ThemeGenericClassGenerator.generate_panel_classes_from_theme_areas()
+classes += tuple(ThemeGenericClassGenerator.generated_classes)
+
if __name__ == "__main__": # only for live edit.
from bpy.utils import register_class
for cls in classes: