diff options
25 files changed, 1651 insertions, 1081 deletions
diff --git a/intern/cycles/blender/addon/properties.py b/intern/cycles/blender/addon/properties.py index 3f6c6de5c5e..9cbb2e86369 100644 --- a/intern/cycles/blender/addon/properties.py +++ b/intern/cycles/blender/addon/properties.py @@ -1485,7 +1485,6 @@ class CyclesPreferences(bpy.types.AddonPreferences): def draw_impl(self, layout, context): available_device_types = self.get_device_types(context) - layout.label(text="Cycles Compute Device:") if len(available_device_types) == 1: layout.label(text="No compatible GPUs found", icon='INFO') return diff --git a/release/datafiles/userdef/userdef_default_theme.c b/release/datafiles/userdef/userdef_default_theme.c index 6fe61c60470..7a7f804bbed 100644 --- a/release/datafiles/userdef/userdef_default_theme.c +++ b/release/datafiles/userdef/userdef_default_theme.c @@ -821,7 +821,8 @@ const bTheme U_theme_default = { .button_title = RGBA(0xffffffff), .button_text = RGBA(0xe5e5e5ff), .button_text_hi = RGBA(0xffffffff), - .navigation_bar = RGBA(0x373737ff), + .navigation_bar = RGBA(0x4b4b4bff), + .execution_buts = RGBA(0x4b4b4bff), .panelcolors = { .header = RGBA(0x42424200), .back = RGBA(0x333333b3), diff --git a/release/scripts/modules/bpy/utils/__init__.py b/release/scripts/modules/bpy/utils/__init__.py index 5fbff2eb51b..b4c8c0899ac 100644 --- a/release/scripts/modules/bpy/utils/__init__.py +++ b/release/scripts/modules/bpy/utils/__init__.py @@ -572,7 +572,7 @@ def preset_find(name, preset_path, display_name=False, ext=".py"): def keyconfig_init(): # Key configuration initialization and refresh, called from the Blender # window manager on startup and refresh. - active_config = _preferences.inputs.active_keyconfig + active_config = _preferences.keymap.active_keyconfig # Load the default key configuration. default_filepath = preset_find("blender", "keyconfig") diff --git a/release/scripts/modules/rna_keymap_ui.py b/release/scripts/modules/rna_keymap_ui.py index 3a44745e01b..268bcb6a7be 100644 --- a/release/scripts/modules/rna_keymap_ui.py +++ b/release/scripts/modules/rna_keymap_ui.py @@ -372,15 +372,24 @@ def draw_keymaps(context, layout): subcol = subsplit.column() col = subcol.column() - row = col.row(align=True) # row.prop_search(wm.keyconfigs, "active", wm, "keyconfigs", text="Key Config") text = bpy.path.display_name(kc_active.name) if not text: text = "Blender (default)" - row.menu("USERPREF_MT_keyconfigs", text=text) - row.operator("wm.keyconfig_preset_add", text="", icon='ADD') - row.operator("wm.keyconfig_preset_add", text="", icon='REMOVE').remove_active = True + + row = col.row() + + row.operator("wm.keyconfig_import", text="Import...", icon='IMPORT') + row.operator("wm.keyconfig_export", text="Export...", icon='EXPORT') + + row.separator() + + rowsub = row.row(align=True) + + rowsub.menu("USERPREF_MT_keyconfigs", text=text) + rowsub.operator("wm.keyconfig_preset_add", text="", icon='ADD') + rowsub.operator("wm.keyconfig_preset_add", text="", icon='REMOVE').remove_active = True # layout.context_pointer_set("keyconfig", wm.keyconfigs.active) # row.operator("wm.keyconfig_remove", text="", icon='X') @@ -413,14 +422,14 @@ def draw_keymaps(context, layout): box = col.box() row = box.row(align=True) - prefs = context.preferences - inputs = prefs.inputs - show_ui_keyconfig = inputs.show_ui_keyconfig + pref = context.preferences + keymappref = pref.keymap + show_ui_keyconfig = keymappref.show_ui_keyconfig row.prop( - inputs, + keymappref, "show_ui_keyconfig", text="", - icon='TRIA_DOWN' if show_ui_keyconfig else 'TRIA_RIGHT', + icon='DISCLOSURE_TRI_DOWN' if show_ui_keyconfig else 'DISCLOSURE_TRI_RIGHT', emboss=False, ) row.label(text="Preferences") 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: diff --git a/source/blender/blenkernel/BKE_blender_version.h b/source/blender/blenkernel/BKE_blender_version.h index 2d044fd9399..bc2212f6091 100644 --- a/source/blender/blenkernel/BKE_blender_version.h +++ b/source/blender/blenkernel/BKE_blender_version.h @@ -28,7 +28,7 @@ * and keep comment above the defines. * Use STRINGIFY() rather than defining with quotes */ #define BLENDER_VERSION 280 -#define BLENDER_SUBVERSION 39 +#define BLENDER_SUBVERSION 40 /* Several breakages with 280, e.g. collections vs layers */ #define BLENDER_MINVERSION 280 #define BLENDER_MINSUBVERSION 0 diff --git a/source/blender/blenloader/intern/versioning_280.c b/source/blender/blenloader/intern/versioning_280.c index 3b2950891f7..bf416fd2c02 100644 --- a/source/blender/blenloader/intern/versioning_280.c +++ b/source/blender/blenloader/intern/versioning_280.c @@ -2382,12 +2382,13 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) ARegion *navigation_region = BKE_spacedata_find_region_type(slink, area, RGN_TYPE_NAV_BAR); if (!navigation_region) { + ARegion *main_region = BKE_spacedata_find_region_type(slink, area, RGN_TYPE_WINDOW); ListBase *regionbase = (slink == area->spacedata.first) ? &area->regionbase : &slink->regionbase; navigation_region = MEM_callocN(sizeof(ARegion), "userpref navigation-region do_versions"); - BLI_addhead(regionbase, navigation_region); /* order matters, addhead not addtail! */ + BLI_insertlinkbefore(regionbase, main_region, navigation_region); /* order matters, addhead not addtail! */ navigation_region->regiontype = RGN_TYPE_NAV_BAR; navigation_region->alignment = RGN_ALIGN_LEFT; } @@ -2691,9 +2692,7 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) } } - { - /* Versioning code until next subversion bump goes here. */ - + if (!MAIN_VERSION_ATLEAST(bmain, 280, 40)) { if (!DNA_struct_elem_find(fd->filesdna, "ToolSettings", "char", "snap_transform_mode_flag")) { for (Scene *scene = bmain->scene.first; scene; scene = scene->id.next) { scene->toolsettings->snap_transform_mode_flag = @@ -2748,5 +2747,34 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) ca->gpu_dof.ratio = 0.01f; } } + + for (bScreen *screen = bmain->screen.first; screen; screen = screen->id.next) { + for (ScrArea *area = screen->areabase.first; area; area = area->next) { + for (SpaceLink *sl = area->spacedata.first; sl; sl = sl->next) { + if (sl->spacetype == SPACE_USERPREF) { + ARegion *execute_region = BKE_spacedata_find_region_type(sl, area, RGN_TYPE_EXECUTE); + + if (!execute_region) { + ListBase *regionbase = (sl == area->spacedata.first) ? &area->regionbase : &sl->regionbase; + ARegion *ar_navbar = BKE_spacedata_find_region_type(sl, area, RGN_TYPE_NAV_BAR); + + execute_region = MEM_callocN(sizeof(ARegion), "execute region for properties"); + + BLI_assert(ar_navbar); + + BLI_insertlinkafter(regionbase, ar_navbar, execute_region); + + execute_region->regiontype = RGN_TYPE_EXECUTE; + execute_region->alignment = RGN_ALIGN_BOTTOM | RGN_SPLIT_PREV; + execute_region->flag |= RGN_FLAG_DYNAMIC_SIZE; + } + } + } + } + } + } + + { + /* Versioning code until next subversion bump goes here. */ } } diff --git a/source/blender/blenloader/intern/versioning_userdef.c b/source/blender/blenloader/intern/versioning_userdef.c index bb0ad9d3ce5..de5a1c8a79e 100644 --- a/source/blender/blenloader/intern/versioning_userdef.c +++ b/source/blender/blenloader/intern/versioning_userdef.c @@ -106,6 +106,11 @@ static void do_versions_theme(UserDef *userdef, bTheme *btheme) copy_v4_v4_char(btheme->tclip.metadatabg, U_theme_default.tima.metadatabg); copy_v4_v4_char(btheme->tclip.metadatatext, U_theme_default.tima.metadatatext); } + + if (!USER_VERSION_ATLEAST(280, 40)) { + copy_v4_v4_char(btheme->tuserpref.execution_buts, btheme->tuserpref.navigation_bar); + } + #undef USER_VERSION_ATLEAST } diff --git a/source/blender/editors/include/ED_screen.h b/source/blender/editors/include/ED_screen.h index 4adf040f1ea..9ad4c06dee6 100644 --- a/source/blender/editors/include/ED_screen.h +++ b/source/blender/editors/include/ED_screen.h @@ -143,7 +143,7 @@ void ED_area_tag_redraw_no_rebuild(ScrArea *sa); void ED_area_tag_redraw_regiontype(ScrArea *sa, int type); void ED_area_tag_refresh(ScrArea *sa); void ED_area_do_refresh(struct bContext *C, ScrArea *sa); -void ED_area_azones_update(ScrArea *sa, const int mouse_xy[]); +struct AZone *ED_area_azones_update(ScrArea *sa, const int mouse_xy[]); void ED_area_status_text(ScrArea *sa, const char *str); void ED_area_newspace(struct bContext *C, ScrArea *sa, int type, const bool skip_ar_exit); void ED_area_prevspace(struct bContext *C, ScrArea *sa); diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c index 45c0498cda6..09033a5f56d 100644 --- a/source/blender/editors/interface/interface_layout.c +++ b/source/blender/editors/interface/interface_layout.c @@ -658,7 +658,6 @@ static void ui_item_enum_expand_exec( uiLayout *layout_radial = NULL; const EnumPropertyItem *item, *item_array; const char *name; - char group_name[UI_MAX_NAME_STR]; int itemw, icon, value; bool free; bool radial = (layout->root->type == UI_LAYOUT_PIEMENU); @@ -703,8 +702,7 @@ static void ui_item_enum_expand_exec( if (!is_first) { uiItemS(block->curlayout); } - BLI_snprintf(group_name, sizeof(group_name), "%s:", item->name); - uiItemL(block->curlayout, group_name, item->icon); + uiItemL(block->curlayout, item->name, item->icon); } else if (radial && layout_radial) { uiItemS(layout_radial); diff --git a/source/blender/editors/interface/interface_ops.c b/source/blender/editors/interface/interface_ops.c index 1cb9f156eeb..484debf554c 100644 --- a/source/blender/editors/interface/interface_ops.c +++ b/source/blender/editors/interface/interface_ops.c @@ -1345,7 +1345,7 @@ static int edittranslation_exec(bContext *C, wmOperator *op) if (!BLI_is_dir(root)) { BKE_report( op->reports, RPT_ERROR, - "Please set your User Preferences' 'Translation Branches " + "Please set your Preferences' 'Translation Branches " "Directory' path to a valid directory"); return OPERATOR_CANCELLED; } diff --git a/source/blender/editors/interface/interface_panel.c b/source/blender/editors/interface/interface_panel.c index 610c0d33bc9..469720c2d30 100644 --- a/source/blender/editors/interface/interface_panel.c +++ b/source/blender/editors/interface/interface_panel.c @@ -147,7 +147,7 @@ static int panel_aligned(ScrArea *sa, ARegion *ar) return BUT_VERTICAL; else if (sa->spacetype == SPACE_IMAGE && ar->regiontype == RGN_TYPE_PREVIEW) return BUT_VERTICAL; - else if (ELEM(ar->regiontype, RGN_TYPE_UI, RGN_TYPE_TOOLS, RGN_TYPE_TOOL_PROPS, RGN_TYPE_HUD, RGN_TYPE_NAV_BAR)) + else if (ELEM(ar->regiontype, RGN_TYPE_UI, RGN_TYPE_TOOLS, RGN_TYPE_TOOL_PROPS, RGN_TYPE_HUD, RGN_TYPE_NAV_BAR, RGN_TYPE_EXECUTE)) return BUT_VERTICAL; return 0; diff --git a/source/blender/editors/interface/resources.c b/source/blender/editors/interface/resources.c index fc761cedb8e..d7451b0d0e4 100644 --- a/source/blender/editors/interface/resources.c +++ b/source/blender/editors/interface/resources.c @@ -183,6 +183,8 @@ const uchar *UI_ThemeGetColorPtr(bTheme *btheme, int spacetype, int colorid) cp = ts->header; else if (theme_regionid == RGN_TYPE_NAV_BAR) cp = ts->navigation_bar; + else if (theme_regionid == RGN_TYPE_EXECUTE) + cp = ts->execution_buts; else cp = ts->button; diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c index 47c44468bc7..34a20c8ccf7 100644 --- a/source/blender/editors/screen/area.c +++ b/source/blender/editors/screen/area.c @@ -187,52 +187,6 @@ void ED_area_do_refresh(bContext *C, ScrArea *sa) } /** - * Action zones are only updated if the mouse is inside of them, but in some cases (currently only fullscreen icon) - * it might be needed to update their properties and redraw if the mouse isn't inside. - */ -void ED_area_azones_update(ScrArea *sa, const int mouse_xy[2]) -{ - AZone *az; - bool changed = false; - - for (az = sa->actionzones.first; az; az = az->next) { - if (az->type == AZONE_FULLSCREEN) { - /* only if mouse is not hovering the azone */ - if (BLI_rcti_isect_pt_v(&az->rect, mouse_xy) == false) { - az->alpha = 0.0f; - changed = true; - - /* can break since currently only this is handled here */ - break; - } - } - else if (az->type == AZONE_REGION_SCROLL) { - /* only if mouse is not hovering the azone */ - if (BLI_rcti_isect_pt_v(&az->rect, mouse_xy) == false) { - View2D *v2d = &az->ar->v2d; - - if (az->direction == AZ_SCROLL_VERT) { - az->alpha = v2d->alpha_vert = 0; - changed = true; - } - else if (az->direction == AZ_SCROLL_HOR) { - az->alpha = v2d->alpha_hor = 0; - changed = true; - } - else { - BLI_assert(0); - } - } - } - } - - if (changed) { - sa->flag &= ~AREA_FLAG_ACTIONZONES_UPDATE; - ED_area_tag_redraw_no_rebuild(sa); - } -} - -/** * \brief Corner widget use for quitting fullscreen. */ static void area_draw_azone_fullscreen(short x1, short y1, short x2, short y2, float alpha) @@ -412,18 +366,11 @@ static void region_draw_azones(ScrArea *sa, ARegion *ar) } else if (az->type == AZONE_FULLSCREEN) { area_draw_azone_fullscreen(az->x1, az->y1, az->x2, az->y2, az->alpha); - - if (az->alpha != 0.0f) { - area_azone_tag_update(sa); - } - } - else if (az->type == AZONE_REGION_SCROLL) { - if (az->alpha != 0.0f) { - area_azone_tag_update(sa); - } - /* Don't draw this azone. */ } } + if (!IS_EQF(az->alpha, 0.0f) && ELEM(az->type, AZONE_FULLSCREEN, AZONE_REGION_SCROLL)) { + area_azone_tag_update(sa); + } } GPU_matrix_pop(); @@ -1605,6 +1552,7 @@ void ED_area_update_region_sizes(wmWindowManager *wm, wmWindow *win, ScrArea *ar if (!(area->flag & AREA_FLAG_REGION_SIZE_UPDATE)) { return; } + const bScreen *screen = WM_window_get_active_screen(win); WM_window_rect_calc(win, &window_rect); area_calc_totrct(area, &window_rect); @@ -1614,6 +1562,9 @@ void ED_area_update_region_sizes(wmWindowManager *wm, wmWindow *win, ScrArea *ar overlap_rect = rect; region_rect_recursive(area, area->regionbase.first, &rect, &overlap_rect, 0); + /* Dynamically sized regions may have changed region sizes, so we have to force azone update. */ + area_azone_initialize(win, screen, area); + for (ARegion *ar = area->regionbase.first; ar; ar = ar->next) { region_subwindow(ar); @@ -1621,7 +1572,11 @@ void ED_area_update_region_sizes(wmWindowManager *wm, wmWindow *win, ScrArea *ar if (ar->type->init) { ar->type->init(wm, ar); } + + /* Some AZones use View2D data which is only updated in region init, so call that first! */ + region_azones_add(screen, area, ar, ar->alignment & ~RGN_SPLIT_PREV); } + ED_area_azones_update(area, &win->eventstate->x); area->flag &= ~AREA_FLAG_REGION_SIZE_UPDATE; } @@ -2386,6 +2341,9 @@ void ED_region_panels_draw(const bContext *C, ARegion *ar) /* set the view */ UI_view2d_view_ortho(v2d); + /* View2D matrix might have changed due to dynamic sized regions. */ + UI_blocklist_update_window_matrix(C, &ar->uiblocks); + /* draw panels */ UI_panels_draw(C, ar); diff --git a/source/blender/editors/screen/screen_edit.c b/source/blender/editors/screen/screen_edit.c index 62d60c39c0c..7e6e31d339d 100644 --- a/source/blender/editors/screen/screen_edit.c +++ b/source/blender/editors/screen/screen_edit.c @@ -639,7 +639,7 @@ void ED_screen_set_active_region(bContext *C, wmWindow *win, const int xy[2]) ED_screen_areas_iter(win, scr, area_iter) { if (xy[0] > area_iter->totrct.xmin && xy[0] < area_iter->totrct.xmax) { if (xy[1] > area_iter->totrct.ymin && xy[1] < area_iter->totrct.ymax) { - if (ED_area_actionzone_refresh_xy(area_iter, xy) == NULL) { + if (ED_area_azones_update(area_iter, xy) == NULL) { sa = area_iter; break; } @@ -1251,7 +1251,7 @@ ScrArea *ED_screen_state_toggle(bContext *C, wmWindow *win, ScrArea *sa, const s for (ar = newa->regionbase.first; ar; ar = ar->next) { ar->flagfullscreen = ar->flag; - if (ELEM(ar->regiontype, RGN_TYPE_UI, RGN_TYPE_HEADER, RGN_TYPE_TOOLS, RGN_TYPE_NAV_BAR)) { + if (ELEM(ar->regiontype, RGN_TYPE_UI, RGN_TYPE_HEADER, RGN_TYPE_TOOLS, RGN_TYPE_NAV_BAR, RGN_TYPE_EXECUTE)) { ar->flag |= RGN_FLAG_HIDDEN; } } diff --git a/source/blender/editors/screen/screen_intern.h b/source/blender/editors/screen/screen_intern.h index 7722f2c9fcc..5f36f4a06ab 100644 --- a/source/blender/editors/screen/screen_intern.h +++ b/source/blender/editors/screen/screen_intern.h @@ -57,7 +57,6 @@ int screen_area_join(struct bContext *C, bScreen *scr, ScrArea *sa1, Scr int area_getorientation(ScrArea *sa, ScrArea *sb); struct AZone *ED_area_actionzone_find_xy(ScrArea *sa, const int xy[2]); -struct AZone *ED_area_actionzone_refresh_xy(ScrArea *sa, const int xy[2]); /* screen_geometry.c */ int screen_geom_area_height(const ScrArea *area); diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index d41bf8d937b..62b4db94937 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -798,6 +798,32 @@ static AZone *area_actionzone_refresh_xy(ScrArea *sa, const int xy[2], const boo } } } + else if (!test_only && !IS_EQF(az->alpha, 0.0f)) { + bool changed = false; + + if (az->type == AZONE_FULLSCREEN) { + az->alpha = 0.0f; + changed = true; + } + else if (az->type == AZONE_REGION_SCROLL) { + if (az->direction == AZ_SCROLL_VERT) { + az->alpha = az->ar->v2d.alpha_vert = 0; + changed = true; + } + else if (az->direction == AZ_SCROLL_HOR) { + az->alpha = az->ar->v2d.alpha_hor = 0; + changed = true; + } + else { + BLI_assert(0); + } + } + + if (changed) { + sa->flag &= ~AREA_FLAG_ACTIONZONES_UPDATE; + ED_area_tag_redraw_no_rebuild(sa); + } + } } return az; @@ -808,7 +834,7 @@ AZone *ED_area_actionzone_find_xy(ScrArea *sa, const int xy[2]) return area_actionzone_refresh_xy(sa, xy, true); } -AZone *ED_area_actionzone_refresh_xy(ScrArea *sa, const int xy[2]) +AZone *ED_area_azones_update(ScrArea *sa, const int xy[2]) { return area_actionzone_refresh_xy(sa, xy, false); } @@ -2382,8 +2408,12 @@ static int region_scale_modal(bContext *C, wmOperator *op, const wmEvent *event) if (!(rmd->ar->flag & RGN_FLAG_HIDDEN)) region_scale_toggle_hidden(C, rmd); } - else if (rmd->ar->flag & RGN_FLAG_HIDDEN) + else if (rmd->ar->flag & RGN_FLAG_HIDDEN) { region_scale_toggle_hidden(C, rmd); + } + else if (rmd->ar->flag & RGN_FLAG_DYNAMIC_SIZE) { + rmd->ar->sizex = rmd->origval; + } } else { int maxsize = region_scale_get_maxsize(rmd); @@ -2411,10 +2441,15 @@ static int region_scale_modal(bContext *C, wmOperator *op, const wmEvent *event) if (!(rmd->ar->flag & RGN_FLAG_HIDDEN)) region_scale_toggle_hidden(C, rmd); } - else if (maxsize > 0 && (rmd->ar->sizey > maxsize)) + else if (maxsize > 0 && (rmd->ar->sizey > maxsize)) { rmd->ar->sizey = maxsize; - else if (rmd->ar->flag & RGN_FLAG_HIDDEN) + } + else if (rmd->ar->flag & RGN_FLAG_HIDDEN) { region_scale_toggle_hidden(C, rmd); + } + else if (rmd->ar->flag & RGN_FLAG_DYNAMIC_SIZE) { + rmd->ar->sizey = rmd->origval; + } } ED_area_tag_redraw(rmd->sa); WM_event_add_notifier(C, NC_SCREEN | NA_EDITED, NULL); @@ -4349,11 +4384,15 @@ static void SCREEN_OT_back_to_previous(struct wmOperatorType *ot) static int userpref_show_invoke(bContext *C, wmOperator *op, const wmEvent *event) { - int sizex = (800 + UI_NAVIGATION_REGION_WIDTH) * UI_DPI_FAC; - int sizey = 500 * UI_DPI_FAC; + int sizex = (500 + UI_NAVIGATION_REGION_WIDTH) * UI_DPI_FAC; + int sizey = 520 * UI_DPI_FAC; /* changes context! */ if (WM_window_open_temp(C, event->x, event->y, sizex, sizey, WM_WINDOW_USERPREFS) != NULL) { + /* The header only contains the editor switcher and looks empty. So hiding in the temp window makes sense. */ + ScrArea *area = CTX_wm_area(C); + ARegion *region = BKE_area_find_region_type(area, RGN_TYPE_HEADER); + region->flag |= RGN_FLAG_HIDDEN; return OPERATOR_FINISHED; } else { diff --git a/source/blender/editors/space_userpref/space_userpref.c b/source/blender/editors/space_userpref/space_userpref.c index a0a263cb5de..497cca22ba6 100644 --- a/source/blender/editors/space_userpref/space_userpref.c +++ b/source/blender/editors/space_userpref/space_userpref.c @@ -61,6 +61,14 @@ static SpaceLink *userpref_new(const ScrArea *UNUSED(area), const Scene *UNUSED( spref = MEM_callocN(sizeof(SpaceUserPref), "inituserpref"); spref->spacetype = SPACE_USERPREF; + /* header */ + ar = MEM_callocN(sizeof(ARegion), "header for userpref"); + + BLI_addtail(&spref->regionbase, ar); + ar->regiontype = RGN_TYPE_HEADER; + /* Ignore user preference "USER_HEADER_BOTTOM" here (always show bottom for new types). */ + ar->alignment = RGN_ALIGN_BOTTOM; + /* navigation region */ ar = MEM_callocN(sizeof(ARegion), "navigation region for userpref"); @@ -68,13 +76,13 @@ static SpaceLink *userpref_new(const ScrArea *UNUSED(area), const Scene *UNUSED( ar->regiontype = RGN_TYPE_NAV_BAR; ar->alignment = RGN_ALIGN_LEFT; - /* header */ - ar = MEM_callocN(sizeof(ARegion), "header for userpref"); + /* execution region */ + ar = MEM_callocN(sizeof(ARegion), "execution region for userpref"); BLI_addtail(&spref->regionbase, ar); - ar->regiontype = RGN_TYPE_HEADER; - /* Ignore user preference "USER_HEADER_BOTTOM" here (always show bottom for new types). */ - ar->alignment = RGN_ALIGN_BOTTOM; + ar->regiontype = RGN_TYPE_EXECUTE; + ar->alignment = RGN_ALIGN_BOTTOM | RGN_SPLIT_PREV; + ar->flag |= RGN_FLAG_DYNAMIC_SIZE; /* main region */ ar = MEM_callocN(sizeof(ARegion), "main region for userpref"); @@ -159,6 +167,13 @@ static void userpref_navigation_region_draw(const bContext *C, ARegion *ar) ED_region_panels(C, ar); } +/* add handlers, stuff you only do once or on area/region changes */ +static void userpref_execute_region_init(wmWindowManager *wm, ARegion *ar) +{ + ED_region_panels_init(wm, ar); + ar->v2d.keepzoom |= V2D_LOCKZOOM_X | V2D_LOCKZOOM_Y; +} + static void userpref_main_region_listener( wmWindow *UNUSED(win), ScrArea *UNUSED(sa), ARegion *UNUSED(ar), wmNotifier *UNUSED(wmn), const Scene *UNUSED(scene)) @@ -186,6 +201,13 @@ static void userpref_navigation_region_listener( /* context changes */ } +static void userpref_execute_region_listener( + wmWindow *UNUSED(win), ScrArea *UNUSED(sa), ARegion *UNUSED(ar), + wmNotifier *UNUSED(wmn), const Scene *UNUSED(scene)) +{ + /* context changes */ +} + /* only called once, from space/spacetypes.c */ void ED_spacetype_userpref(void) { @@ -234,6 +256,17 @@ void ED_spacetype_userpref(void) BLI_addhead(&st->regiontypes, art); + /* regions: execution window */ + art = MEM_callocN(sizeof(ARegionType), "spacetype userpref region"); + art->regionid = RGN_TYPE_EXECUTE; + art->init = userpref_execute_region_init; + art->layout = ED_region_panels_layout; + art->draw = ED_region_panels_draw; + art->listener = userpref_execute_region_listener; + art->keymapflag = ED_KEYMAP_UI; + + BLI_addhead(&st->regiontypes, art); + BKE_spacetype_register(st); } diff --git a/source/blender/makesdna/DNA_screen_types.h b/source/blender/makesdna/DNA_screen_types.h index a62e7bc5036..cdf67f1e11d 100644 --- a/source/blender/makesdna/DNA_screen_types.h +++ b/source/blender/makesdna/DNA_screen_types.h @@ -476,6 +476,8 @@ enum { RGN_TYPE_HUD = 8, /* Region to navigate the main region from (RGN_TYPE_WINDOW). */ RGN_TYPE_NAV_BAR = 9, + /* A place for buttons to trigger execution of somthing that was set up in other regions. */ + RGN_TYPE_EXECUTE = 10, }; /* use for function args */ #define RGN_TYPE_ANY -1 diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h index 3f3fa6819ae..41b8308c8f8 100644 --- a/source/blender/makesdna/DNA_userdef_types.h +++ b/source/blender/makesdna/DNA_userdef_types.h @@ -236,7 +236,7 @@ typedef struct ThemeSpace { /* navigation bar regions */ char navigation_bar[4]; /* region background */ - int pad2; + char execution_buts[4]; /* region background */ /* float panel */ /* char panel[4]; unused */ @@ -687,14 +687,15 @@ typedef enum eUserPref_Section { USER_SECTION_INPUT = 5, USER_SECTION_ADDONS = 6, USER_SECTION_LIGHT = 7, + USER_SECTION_KEYMAP = 8, #ifdef WITH_USERDEF_WORKSPACES - USER_SECTION_WORKSPACE_CONFIG = 8, - USER_SECTION_WORKSPACE_ADDONS = 9, - USER_SECTION_WORKSPACE_KEYMAPS = 10, + USER_SECTION_WORKSPACE_CONFIG = 9, + USER_SECTION_WORKSPACE_ADDONS = 10, + USER_SECTION_WORKSPACE_KEYMAPS = 11, #endif #ifdef WITH_USERDEF_SYSTEM_SPLIT - USER_SECTION_SYSTEM_DISPLAY = 11, - USER_SECTION_SYSTEM_DEVICES = 12, + USER_SECTION_SYSTEM_DISPLAY = 12, + USER_SECTION_SYSTEM_DEVICES = 13, #endif } eUserPref_Section; diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h index 7ac03d5d3f8..5d473ed635d 100644 --- a/source/blender/makesrna/RNA_access.h +++ b/source/blender/makesrna/RNA_access.h @@ -712,6 +712,7 @@ extern StructRNA RNA_Preferences; extern StructRNA RNA_PreferencesEdit; extern StructRNA RNA_PreferencesFilePaths; extern StructRNA RNA_PreferencesInput; +extern StructRNA RNA_PreferencesKeymap; extern StructRNA RNA_PreferencesSystem; extern StructRNA RNA_PreferencesView; extern StructRNA RNA_PreferencesWalkNavigation; diff --git a/source/blender/makesrna/intern/rna_screen.c b/source/blender/makesrna/intern/rna_screen.c index ab2a1b3dd82..709abdd1779 100644 --- a/source/blender/makesrna/intern/rna_screen.c +++ b/source/blender/makesrna/intern/rna_screen.c @@ -47,6 +47,7 @@ const EnumPropertyItem rna_enum_region_type_items[] = { {RGN_TYPE_TOOL_PROPS, "TOOL_PROPS", 0, "Tool Properties", ""}, {RGN_TYPE_PREVIEW, "PREVIEW", 0, "Preview", ""}, {RGN_TYPE_NAV_BAR, "NAVIGATION_BAR", 0, "Navigation Bar", ""}, + {RGN_TYPE_EXECUTE, "EXECUTE", 0, "Execute Buttons", ""}, {0, NULL, 0, NULL, NULL} }; diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index 8bdf947449e..d18ffd422e0 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -4735,7 +4735,7 @@ static void rna_def_space_userpref(BlenderRNA *brna) srna = RNA_def_struct(brna, "SpacePreferences", "Space"); RNA_def_struct_sdna(srna, "SpaceUserPref"); - RNA_def_struct_ui_text(srna, "Space User Preferences", "User preferences space data"); + RNA_def_struct_ui_text(srna, "Space Preferences", "Blender preferences space data"); prop = RNA_def_property(srna, "filter_type", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "filter_type"); diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c index f582c7ce399..7c7a484dd49 100644 --- a/source/blender/makesrna/intern/rna_userdef.c +++ b/source/blender/makesrna/intern/rna_userdef.c @@ -298,6 +298,11 @@ static PointerRNA rna_UserDef_input_get(PointerRNA *ptr) return rna_pointer_inherit_refine(ptr, &RNA_PreferencesInput, ptr->data); } +static PointerRNA rna_UserDef_keymap_get(PointerRNA *ptr) +{ + return rna_pointer_inherit_refine(ptr, &RNA_PreferencesKeymap, ptr->data); +} + static PointerRNA rna_UserDef_filepaths_get(PointerRNA *ptr) { return rna_pointer_inherit_refine(ptr, &RNA_PreferencesFilePaths, ptr->data); @@ -1369,6 +1374,11 @@ static void rna_def_userdef_theme_space_common(StructRNA *srna) RNA_def_property_ui_text(prop, "Navigation Bar Background", ""); RNA_def_property_update(prop, 0, "rna_userdef_update"); + prop = RNA_def_property(srna, "execution_buts", PROP_FLOAT, PROP_COLOR_GAMMA); + RNA_def_property_array(prop, 4); + RNA_def_property_ui_text(prop, "Execution Region Background", ""); + RNA_def_property_update(prop, 0, "rna_userdef_update"); + /* tabs */ prop = RNA_def_property(srna, "tab_active", PROP_FLOAT, PROP_COLOR_GAMMA); RNA_def_property_array(prop, 3); @@ -2084,7 +2094,7 @@ static void rna_def_userdef_theme_space_userpref(BlenderRNA *brna) srna = RNA_def_struct(brna, "ThemePreferences", NULL); RNA_def_struct_sdna(srna, "ThemeSpace"); RNA_def_struct_clear_flag(srna, STRUCT_UNDO); - RNA_def_struct_ui_text(srna, "Theme User Preferences", "Theme settings for the User Preferences"); + RNA_def_struct_ui_text(srna, "Theme Preferences", "Theme settings for the Blender Preferences"); rna_def_userdef_theme_spaces_main(srna); } @@ -3656,6 +3666,17 @@ static void rna_def_userdef_view(BlenderRNA *brna) {0, NULL, 0, NULL, NULL} }; + static const EnumPropertyItem color_picker_types[] = { + {USER_CP_CIRCLE_HSV, "CIRCLE_HSV", 0, "Circle (HSV)", "A circular Hue/Saturation color wheel, with " + "Value slider"}, + {USER_CP_CIRCLE_HSL, "CIRCLE_HSL", 0, "Circle (HSL)", "A circular Hue/Saturation color wheel, with " + "Lightness slider"}, + {USER_CP_SQUARE_SV, "SQUARE_SV", 0, "Square (SV + H)", "A square showing Saturation/Value, with Hue slider"}, + {USER_CP_SQUARE_HS, "SQUARE_HS", 0, "Square (HS + V)", "A square showing Hue/Saturation, with Value slider"}, + {USER_CP_SQUARE_HV, "SQUARE_HV", 0, "Square (HV + S)", "A square showing Hue/Value, with Saturation slider"}, + {0, NULL, 0, NULL, NULL} + }; + static const EnumPropertyItem zoom_frame_modes[] = { {ZOOM_FRAME_MODE_KEEP_RANGE, "KEEP_RANGE", 0, "Keep Range", ""}, {ZOOM_FRAME_MODE_SECONDS, "SECONDS", 0, "Seconds", ""}, @@ -3680,7 +3701,7 @@ static void rna_def_userdef_view(BlenderRNA *brna) RNA_def_struct_ui_text(srna, "View & Controls", "Preferences related to viewing data"); /* View */ - prop = RNA_def_property(srna, "ui_scale", PROP_FLOAT, PROP_FACTOR); + prop = RNA_def_property(srna, "ui_scale", PROP_FLOAT, PROP_NONE); RNA_def_property_ui_text(prop, "UI Scale", "Changes the size of the fonts and buttons in the interface"); RNA_def_property_range(prop, 0.25f, 4.0f); RNA_def_property_ui_range(prop, 0.5f, 2.0f, 1, 2); @@ -3734,6 +3755,23 @@ static void rna_def_userdef_view(BlenderRNA *brna) "Show the frames per second screen refresh rate, while animation is played back"); RNA_def_property_update(prop, 0, "rna_userdef_update"); + /* Weight Paint */ + + prop = RNA_def_property(srna, "use_weight_color_range", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", USER_CUSTOM_RANGE); + RNA_def_property_ui_text(prop, "Use Weight Color Range", + "Enable color range used for weight visualization in weight painting mode"); + RNA_def_property_update(prop, 0, "rna_UserDef_weight_color_update"); + + prop = RNA_def_property(srna, "weight_color_range", PROP_POINTER, PROP_NONE); + RNA_def_property_flag(prop, PROP_NEVER_NULL); + RNA_def_property_pointer_sdna(prop, NULL, "coba_weight"); + RNA_def_property_struct_type(prop, "ColorRamp"); + RNA_def_property_ui_text(prop, "Weight Color Range", + "Color range used for weight visualization in weight painting mode"); + RNA_def_property_update(prop, 0, "rna_UserDef_weight_color_update"); + + /* app flags (use for app-templates) */ prop = RNA_def_property(srna, "show_layout_ui", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_negative_sdna(prop, NULL, "app_flag", USER_APP_LOCK_UI_LAYOUT); @@ -3758,6 +3796,12 @@ static void rna_def_userdef_view(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Sub Level Menu Open Delay", "Time delay in 1/10 seconds before automatically opening sub level menus"); + prop = RNA_def_property(srna, "color_picker_type", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_items(prop, color_picker_types); + RNA_def_property_enum_sdna(prop, NULL, "color_picker_type"); + RNA_def_property_ui_text(prop, "Color Picker Type", "Different styles of displaying the color picker widget"); + RNA_def_property_update(prop, 0, "rna_userdef_update"); + /* pie menus */ prop = RNA_def_property(srna, "pie_initial_timeout", PROP_INT, PROP_NONE); RNA_def_property_range(prop, 0, 1000); @@ -3822,44 +3866,13 @@ static void rna_def_userdef_view(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Header Position", "Default header position for new space-types"); RNA_def_property_update(prop, 0, "rna_userdef_update"); - prop = RNA_def_property(srna, "use_mouse_depth_navigate", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "uiflag", USER_DEPTH_NAVIGATE); - RNA_def_property_ui_text(prop, "Auto Depth", - "Use the depth under the mouse to improve view pan/rotate/zoom functionality"); - - prop = RNA_def_property(srna, "use_mouse_depth_cursor", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "uiflag", USER_DEPTH_CURSOR); - RNA_def_property_ui_text(prop, "Cursor Surface Project", - "Use the surface depth for cursor placement"); - - prop = RNA_def_property(srna, "use_cursor_lock_adjust", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "uiflag", USER_LOCK_CURSOR_ADJUST); - RNA_def_property_ui_text(prop, "Cursor Lock Adjust", - "Place the cursor without 'jumping' to the new location (when lock-to-cursor is used)"); - - prop = RNA_def_property(srna, "use_camera_lock_parent", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_negative_sdna(prop, NULL, "uiflag", USER_CAM_LOCK_NO_PARENT); - RNA_def_property_ui_text(prop, "Camera Parent Lock", - "When the camera is locked to the view and in fly mode, " - "transform the parent rather than the camera"); - - /* view zoom */ - prop = RNA_def_property(srna, "use_zoom_to_mouse", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "uiflag", USER_ZOOM_TO_MOUSEPOS); - RNA_def_property_ui_text(prop, "Zoom To Mouse Position", - "Zoom in towards the mouse pointer's position in the 3D view, " - "rather than the 2D window center"); - - /* view rotation */ - prop = RNA_def_property(srna, "use_auto_perspective", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "uiflag", USER_AUTOPERSP); - RNA_def_property_ui_text(prop, "Auto Perspective", - "Automatically switch between orthographic and perspective when changing " - "from top/front/side views"); - - prop = RNA_def_property(srna, "use_rotate_around_active", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "uiflag", USER_ORBIT_SELECTION); - RNA_def_property_ui_text(prop, "Rotate Around Selection", "Use selection as the pivot point"); + static const EnumPropertyItem text_hinting_items[] = { + {0, "AUTO", 0, "Auto", ""}, + {USER_TEXT_HINTING_NONE, "NONE", 0, "None", ""}, + {USER_TEXT_HINTING_SLIGHT, "SLIGHT", 0, "Slight", ""}, + {USER_TEXT_HINTING_FULL, "FULL", 0, "Full", ""}, + {0, NULL, 0, NULL, NULL} + }; /* mini axis */ static const EnumPropertyItem mini_axis_type_items[] = { @@ -3948,6 +3961,64 @@ static void rna_def_userdef_view(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Zoom Seconds", "Seconds around cursor that we zoom around"); + + /* Text. */ + + prop = RNA_def_property(srna, "use_text_antialiasing", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_negative_sdna(prop, NULL, "text_render", USER_TEXT_DISABLE_AA); + RNA_def_property_ui_text(prop, "Text Anti-aliasing", "Draw user interface text anti-aliased"); + RNA_def_property_update(prop, 0, "rna_userdef_text_update"); + + prop = RNA_def_property(srna, "text_hinting", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_bitflag_sdna(prop, NULL, "text_render"); + RNA_def_property_enum_items(prop, text_hinting_items); + RNA_def_property_ui_text(prop, "Text Hinting", "Method for making user interface text render sharp"); + RNA_def_property_update(prop, 0, "rna_userdef_text_update"); + + prop = RNA_def_property(srna, "font_path_ui", PROP_STRING, PROP_FILEPATH); + RNA_def_property_string_sdna(prop, NULL, "font_path_ui"); + RNA_def_property_ui_text(prop, "Interface Font", "Path to interface font"); + RNA_def_property_update(prop, NC_WINDOW, "rna_userdef_language_update"); + + prop = RNA_def_property(srna, "font_path_ui_mono", PROP_STRING, PROP_FILEPATH); + RNA_def_property_string_sdna(prop, NULL, "font_path_ui_mono"); + RNA_def_property_ui_text(prop, "Mono-space Font", "Path to interface mono-space Font"); + RNA_def_property_update(prop, NC_WINDOW, "rna_userdef_language_update"); + + + /* Language. */ + + prop = RNA_def_property(srna, "use_international_fonts", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "transopts", USER_DOTRANSLATE); + RNA_def_property_ui_text(prop, "Translate UI", "Enable UI translation and use international fonts"); + RNA_def_property_update(prop, NC_WINDOW, "rna_userdef_language_update"); + + prop = RNA_def_property(srna, "language", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_items(prop, rna_enum_language_default_items); +#ifdef WITH_INTERNATIONAL + RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_lang_enum_properties_itemf"); +#endif + RNA_def_property_ui_text(prop, "Language", "Language used for translation"); + RNA_def_property_update(prop, NC_WINDOW, "rna_userdef_language_update"); + + prop = RNA_def_property(srna, "use_translate_tooltips", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "transopts", USER_TR_TOOLTIPS); + RNA_def_property_ui_text(prop, "Translate Tooltips", + "Translate the descriptions when hovering UI elements (recommended)"); + RNA_def_property_update(prop, 0, "rna_userdef_update"); + + prop = RNA_def_property(srna, "use_translate_interface", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "transopts", USER_TR_IFACE); + RNA_def_property_ui_text(prop, "Translate Interface", + "Translate all labels in menus, buttons and panels " + "(note that this might make it hard to follow tutorials or the manual)"); + RNA_def_property_update(prop, 0, "rna_userdef_update"); + + prop = RNA_def_property(srna, "use_translate_new_dataname", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "transopts", USER_TR_NEWDATANAME); + RNA_def_property_ui_text(prop, "Translate New Names", + "Translate the names of new data-blocks (objects, materials...)"); + RNA_def_property_update(prop, 0, "rna_userdef_update"); } static void rna_def_userdef_edit(BlenderRNA *brna) @@ -4011,8 +4082,8 @@ static void rna_def_userdef_edit(BlenderRNA *brna) "When entering numbers while transforming, " "default to advanced mode for full math expression evaluation"); - /* Undo */ + prop = RNA_def_property(srna, "undo_steps", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "undosteps"); RNA_def_property_range(prop, 0, 256); @@ -4030,13 +4101,13 @@ static void rna_def_userdef_edit(BlenderRNA *brna) "Global undo works by keeping a full copy of the file itself in memory, " "so takes extra memory"); + /* auto keyframing */ prop = RNA_def_property(srna, "use_auto_keying", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "autokey_mode", AUTOKEY_ON); RNA_def_property_ui_text(prop, "Auto Keying Enable", "Automatic keyframe insertion for Objects and Bones " "(default setting used for new Scenes)"); - RNA_def_property_ui_icon(prop, ICON_REC, 0); prop = RNA_def_property(srna, "auto_keying_mode", PROP_ENUM, PROP_NONE); RNA_def_property_enum_items(prop, auto_key_modes); @@ -4258,15 +4329,6 @@ static void rna_def_userdef_system(BlenderRNA *brna) {0, NULL, 0, NULL, NULL} }; - static const EnumPropertyItem color_picker_types[] = { - {USER_CP_CIRCLE_HSV, "CIRCLE_HSV", 0, "Circle (HSV)", "A circular Hue/Saturation color wheel, with Value slider"}, - {USER_CP_CIRCLE_HSL, "CIRCLE_HSL", 0, "Circle (HSL)", "A circular Hue/Saturation color wheel, with Lightness slider"}, - {USER_CP_SQUARE_SV, "SQUARE_SV", 0, "Square (SV + H)", "A square showing Saturation/Value, with Hue slider"}, - {USER_CP_SQUARE_HS, "SQUARE_HS", 0, "Square (HS + V)", "A square showing Hue/Saturation, with Value slider"}, - {USER_CP_SQUARE_HV, "SQUARE_HV", 0, "Square (HV + S)", "A square showing Hue/Value, with Saturation slider"}, - {0, NULL, 0, NULL, NULL} - }; - static const EnumPropertyItem multi_sample_levels[] = { {USER_MULTISAMPLE_NONE, "NONE", 0, "No MultiSample", "Do not use OpenGL MultiSample"}, {USER_MULTISAMPLE_2, "2", 0, "MultiSample: 2", "Use 2x OpenGL MultiSample (requires restart)"}, @@ -4290,14 +4352,6 @@ static void rna_def_userdef_system(BlenderRNA *brna) {0, NULL, 0, NULL, NULL} }; - static const EnumPropertyItem text_hinting_items[] = { - {0, "AUTO", 0, "Auto", ""}, - {USER_TEXT_HINTING_NONE, "NONE", 0, "None", ""}, - {USER_TEXT_HINTING_SLIGHT, "SLIGHT", 0, "Slight", ""}, - {USER_TEXT_HINTING_FULL, "FULL", 0, "Full", ""}, - {0, NULL, 0, NULL, NULL} - }; - srna = RNA_def_struct(brna, "PreferencesSystem", NULL); RNA_def_struct_sdna(srna, "UserDef"); RNA_def_struct_nested(brna, srna, "Preferences"); @@ -4328,63 +4382,57 @@ static void rna_def_userdef_system(BlenderRNA *brna) RNA_def_property_clear_flag(prop, PROP_EDITABLE); RNA_def_property_float_sdna(prop, NULL, "pixelsize"); - prop = RNA_def_property(srna, "font_path_ui", PROP_STRING, PROP_FILEPATH); - RNA_def_property_string_sdna(prop, NULL, "font_path_ui"); - RNA_def_property_ui_text(prop, "Interface Font", "Path to interface font"); - RNA_def_property_update(prop, NC_WINDOW, "rna_userdef_language_update"); - prop = RNA_def_property(srna, "font_path_ui_mono", PROP_STRING, PROP_FILEPATH); - RNA_def_property_string_sdna(prop, NULL, "font_path_ui_mono"); - RNA_def_property_ui_text(prop, "Mono-space Font", "Path to interface mono-space Font"); - RNA_def_property_update(prop, NC_WINDOW, "rna_userdef_language_update"); + /* Memory */ + + prop = RNA_def_property(srna, "prefetch_frames", PROP_INT, PROP_NONE); + RNA_def_property_int_sdna(prop, NULL, "prefetchframes"); + RNA_def_property_range(prop, 0, INT_MAX); + RNA_def_property_ui_range(prop, 0, 500, 1, -1); + RNA_def_property_ui_text(prop, "Prefetch Frames", "Number of frames to render ahead during playback (sequencer only)"); + + prop = RNA_def_property(srna, "memory_cache_limit", PROP_INT, PROP_NONE); + RNA_def_property_int_sdna(prop, NULL, "memcachelimit"); + RNA_def_property_range(prop, 0, max_memory_in_megabytes_int()); + RNA_def_property_ui_text(prop, "Memory Cache Limit", "Memory cache limit (in megabytes)"); + RNA_def_property_update(prop, 0, "rna_Userdef_memcache_update"); prop = RNA_def_property(srna, "scrollback", PROP_INT, PROP_UNSIGNED); RNA_def_property_int_sdna(prop, NULL, "scrollback"); RNA_def_property_range(prop, 32, 32768); RNA_def_property_ui_text(prop, "Scrollback", "Maximum number of lines to store for the console buffer"); - prop = RNA_def_property(srna, "author", PROP_STRING, PROP_NONE); - RNA_def_property_string_sdna(prop, NULL, "author"); - RNA_def_property_string_maxlength(prop, 80); - RNA_def_property_ui_text(prop, "Author", - "Name that will be used in exported files when format supports such feature"); - - /* Language. */ + /* OpenGL */ - prop = RNA_def_property(srna, "use_international_fonts", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "transopts", USER_DOTRANSLATE); - RNA_def_property_ui_text(prop, "Translate UI", "Enable UI translation and use international fonts"); - RNA_def_property_update(prop, NC_WINDOW, "rna_userdef_language_update"); - - prop = RNA_def_property(srna, "language", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_items(prop, rna_enum_language_default_items); -#ifdef WITH_INTERNATIONAL - RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_lang_enum_properties_itemf"); -#endif - RNA_def_property_ui_text(prop, "Language", "Language used for translation"); - RNA_def_property_update(prop, NC_WINDOW, "rna_userdef_language_update"); + /* Full scene anti-aliasing */ + prop = RNA_def_property(srna, "multi_sample", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_bitflag_sdna(prop, NULL, "ogl_multisamples"); + RNA_def_property_enum_items(prop, multi_sample_levels); + RNA_def_property_ui_text(prop, "MultiSample", + "Enable OpenGL multi-sampling, only for systems that support it, requires restart"); + RNA_def_property_update(prop, 0, "rna_userdef_dpi_update"); - prop = RNA_def_property(srna, "use_translate_tooltips", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "transopts", USER_TR_TOOLTIPS); - RNA_def_property_ui_text(prop, "Translate Tooltips", - "Translate the descriptions when hovering UI elements (recommended)"); - RNA_def_property_update(prop, 0, "rna_userdef_update"); + /* grease pencil anti-aliasing */ + prop = RNA_def_property(srna, "gpencil_multi_sample", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_bitflag_sdna(prop, NULL, "gpencil_multisamples"); + RNA_def_property_enum_items(prop, multi_sample_levels); + RNA_def_property_ui_text(prop, "Gpencil MultiSample", + "Enable Grease Pencil OpenGL multi-sampling, only for systems that support it"); + RNA_def_property_update(prop, 0, "rna_userdef_dpi_update"); - prop = RNA_def_property(srna, "use_translate_interface", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "transopts", USER_TR_IFACE); - RNA_def_property_ui_text(prop, "Translate Interface", - "Translate all labels in menus, buttons and panels " - "(note that this might make it hard to follow tutorials or the manual)"); - RNA_def_property_update(prop, 0, "rna_userdef_update"); + prop = RNA_def_property(srna, "use_region_overlap", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "uiflag2", USER_REGION_OVERLAP); + RNA_def_property_ui_text(prop, "Region Overlap", + "Draw tool/property regions over the main region, when using Triple Buffer"); + RNA_def_property_update(prop, 0, "rna_userdef_dpi_update"); - prop = RNA_def_property(srna, "use_translate_new_dataname", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "transopts", USER_TR_NEWDATANAME); - RNA_def_property_ui_text(prop, "Translate New Names", - "Translate the names of new data-blocks (objects, materials...)"); + prop = RNA_def_property(srna, "gpu_viewport_quality", PROP_FLOAT, PROP_FACTOR); + RNA_def_property_float_sdna(prop, NULL, "gpu_viewport_quality"); + RNA_def_property_float_default(prop, 0.6f); + RNA_def_property_range(prop, 0.0f, 1.0f); + RNA_def_property_ui_text(prop, "Viewport Quality", "Quality setting for Solid mode rendering in the 3d viewport"); RNA_def_property_update(prop, 0, "rna_userdef_update"); - /* System & OpenGL */ - prop = RNA_def_property(srna, "solid_lights", PROP_COLLECTION, PROP_NONE); RNA_def_property_collection_sdna(prop, NULL, "light_param", ""); RNA_def_property_struct_type(prop, "UserSolidLight"); @@ -4402,56 +4450,14 @@ static void rna_def_userdef_system(BlenderRNA *brna) "View the result of the studio light editor in the viewport"); RNA_def_property_update(prop, 0, "rna_UserDef_viewport_lights_update"); - prop = RNA_def_property(srna, "use_weight_color_range", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "flag", USER_CUSTOM_RANGE); - RNA_def_property_ui_text(prop, "Use Weight Color Range", - "Enable color range used for weight visualization in weight painting mode"); - RNA_def_property_update(prop, 0, "rna_UserDef_weight_color_update"); - - prop = RNA_def_property(srna, "weight_color_range", PROP_POINTER, PROP_NONE); - RNA_def_property_flag(prop, PROP_NEVER_NULL); - RNA_def_property_pointer_sdna(prop, NULL, "coba_weight"); - RNA_def_property_struct_type(prop, "ColorRamp"); - RNA_def_property_ui_text(prop, "Weight Color Range", - "Color range used for weight visualization in weight painting mode"); - RNA_def_property_update(prop, 0, "rna_UserDef_weight_color_update"); - - prop = RNA_def_property(srna, "color_picker_type", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_items(prop, color_picker_types); - RNA_def_property_enum_sdna(prop, NULL, "color_picker_type"); - RNA_def_property_ui_text(prop, "Color Picker Type", "Different styles of displaying the color picker widget"); - RNA_def_property_update(prop, 0, "rna_userdef_update"); - - prop = RNA_def_property(srna, "use_scripts_auto_execute", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", USER_SCRIPT_AUTOEXEC_DISABLE); - RNA_def_property_ui_text(prop, "Auto Run Python Scripts", - "Allow any .blend file to run scripts automatically " - "(unsafe with blend files from an untrusted source)"); - RNA_def_property_update(prop, 0, "rna_userdef_script_autoexec_update"); - - prop = RNA_def_property(srna, "use_tabs_as_spaces", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", USER_TXT_TABSTOSPACES_DISABLE); - RNA_def_property_ui_text(prop, "Tabs as Spaces", - "Automatically convert all new tabs into spaces for new and loaded text files"); - - prop = RNA_def_property(srna, "prefetch_frames", PROP_INT, PROP_NONE); - RNA_def_property_int_sdna(prop, NULL, "prefetchframes"); - RNA_def_property_range(prop, 0, INT_MAX); - RNA_def_property_ui_range(prop, 0, 500, 1, -1); - RNA_def_property_ui_text(prop, "Prefetch Frames", "Number of frames to render ahead during playback (sequencer only)"); - - prop = RNA_def_property(srna, "memory_cache_limit", PROP_INT, PROP_NONE); - RNA_def_property_int_sdna(prop, NULL, "memcachelimit"); - RNA_def_property_range(prop, 0, max_memory_in_megabytes_int()); - RNA_def_property_ui_text(prop, "Memory Cache Limit", "Memory cache limit (in megabytes)"); - RNA_def_property_update(prop, 0, "rna_Userdef_memcache_update"); - prop = RNA_def_property(srna, "gl_clip_alpha", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "glalphaclip"); RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text(prop, "Clip Alpha", "Clip alpha below this threshold in the 3D textured view"); RNA_def_property_update(prop, 0, "rna_userdef_update"); + /* Textures */ + prop = RNA_def_property(srna, "use_16bit_textures", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "use_16bit_textures", 1); RNA_def_property_ui_text(prop, "16 Bit Float Textures", "Use 16 bit per component texture for float images"); @@ -4465,7 +4471,7 @@ static void rna_def_userdef_system(BlenderRNA *brna) prop = RNA_def_property(srna, "image_draw_method", PROP_ENUM, PROP_NONE); RNA_def_property_enum_items(prop, image_draw_methods); RNA_def_property_enum_sdna(prop, NULL, "image_draw_method"); - RNA_def_property_ui_text(prop, "Image Draw Method", "Method used for displaying images on the screen"); + RNA_def_property_ui_text(prop, "Image Display Method", "Method used for displaying images on the screen"); RNA_def_property_update(prop, 0, "rna_userdef_update"); prop = RNA_def_property(srna, "anisotropic_filter", PROP_ENUM, PROP_NONE); @@ -4496,6 +4502,20 @@ static void rna_def_userdef_system(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Texture Collection Rate", "Number of seconds between each run of the GL texture garbage collector"); + /* Select */ + + prop = RNA_def_property(srna, "select_method", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "gpu_select_method"); + RNA_def_property_enum_items(prop, gpu_select_method_items); + RNA_def_property_ui_text(prop, "Selection Method", + "Use OpenGL occlusion queries or selection render mode to accelerate selection"); + + prop = RNA_def_property(srna, "use_select_pick_depth", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "gpu_select_pick_deph", 1); + RNA_def_property_ui_text(prop, "OpenGL Depth Picking", "Use the depth buffer for picking 3D View selection"); + + /* Audio */ + prop = RNA_def_property(srna, "audio_mixing_buffer", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "mixbufsize"); RNA_def_property_enum_items(prop, audio_mixing_samples_items); @@ -4527,56 +4547,6 @@ static void rna_def_userdef_system(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Audio Channels", "Audio channel count"); RNA_def_property_update(prop, 0, "rna_UserDef_audio_update"); - prop = RNA_def_property(srna, "use_text_antialiasing", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_negative_sdna(prop, NULL, "text_render", USER_TEXT_DISABLE_AA); - RNA_def_property_ui_text(prop, "Text Anti-aliasing", "Draw user interface text anti-aliased"); - RNA_def_property_update(prop, 0, "rna_userdef_text_update"); - - prop = RNA_def_property(srna, "text_hinting", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_bitflag_sdna(prop, NULL, "text_render"); - RNA_def_property_enum_items(prop, text_hinting_items); - RNA_def_property_ui_text(prop, "Text Hinting", "Method for making user interface text render sharp"); - RNA_def_property_update(prop, 0, "rna_userdef_text_update"); - - prop = RNA_def_property(srna, "select_method", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_sdna(prop, NULL, "gpu_select_method"); - RNA_def_property_enum_items(prop, gpu_select_method_items); - RNA_def_property_ui_text(prop, "Selection Method", - "Use OpenGL occlusion queries or selection render mode to accelerate selection"); - - prop = RNA_def_property(srna, "use_select_pick_depth", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "gpu_select_pick_deph", 1); - RNA_def_property_ui_text(prop, "OpenGL Depth Picking", "Use the depth buffer for picking 3D View selection"); - - /* Full scene anti-aliasing */ - prop = RNA_def_property(srna, "multi_sample", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_bitflag_sdna(prop, NULL, "ogl_multisamples"); - RNA_def_property_enum_items(prop, multi_sample_levels); - RNA_def_property_ui_text(prop, "MultiSample", - "Enable OpenGL multi-sampling, only for systems that support it, requires restart"); - RNA_def_property_update(prop, 0, "rna_userdef_dpi_update"); - - /* grease pencil anti-aliasing */ - prop = RNA_def_property(srna, "gpencil_multi_sample", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_bitflag_sdna(prop, NULL, "gpencil_multisamples"); - RNA_def_property_enum_items(prop, multi_sample_levels); - RNA_def_property_ui_text(prop, "Gpencil MultiSample", - "Enable Grease Pencil OpenGL multi-sampling, only for systems that support it"); - RNA_def_property_update(prop, 0, "rna_userdef_dpi_update"); - - prop = RNA_def_property(srna, "use_region_overlap", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "uiflag2", USER_REGION_OVERLAP); - RNA_def_property_ui_text(prop, "Region Overlap", - "Draw tool/property regions over the main region, when using Triple Buffer"); - RNA_def_property_update(prop, 0, "rna_userdef_dpi_update"); - - prop = RNA_def_property(srna, "gpu_viewport_quality", PROP_FLOAT, PROP_FACTOR); - RNA_def_property_float_sdna(prop, NULL, "gpu_viewport_quality"); - RNA_def_property_float_default(prop, 0.6f); - RNA_def_property_range(prop, 0.0f, 1.0f); - RNA_def_property_ui_text(prop, "Viewport Quality", "Quality setting for Solid mode rendering in the 3d viewport"); - RNA_def_property_update(prop, 0, "rna_userdef_update"); - #ifdef WITH_OPENSUBDIV prop = RNA_def_property(srna, "opensubdiv_compute_type", PROP_ENUM, PROP_NONE); @@ -4603,8 +4573,8 @@ static void rna_def_userdef_input(BlenderRNA *brna) StructRNA *srna; static const EnumPropertyItem view_rotation_items[] = { - {0, "TURNTABLE", 0, "Turntable", "Use turntable style rotation in the viewport"}, - {USER_TRACKBALL, "TRACKBALL", 0, "Trackball", "Use trackball style rotation in the viewport"}, + {0, "TURNTABLE", 0, "Turntable", "Turntable keeps the Z-axis upright while orbiting"}, + {USER_TRACKBALL, "TRACKBALL", 0, "Trackball", "Trackball allows you to tumble your view at any angle"}, {0, NULL, 0, NULL, NULL} }; @@ -4642,10 +4612,6 @@ static void rna_def_userdef_input(BlenderRNA *brna) RNA_def_struct_clear_flag(srna, STRUCT_UNDO); RNA_def_struct_ui_text(srna, "Input", "Settings for input devices"); - prop = RNA_def_property(srna, "show_ui_keyconfig", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_negative_sdna(prop, NULL, "userpref_flag", USER_SECTION_INPUT_HIDE_UI_KEYCONFIG); - RNA_def_property_ui_text(prop, "Show UI Key-Config", ""); - prop = RNA_def_property(srna, "view_zoom_method", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "viewzoom"); RNA_def_property_enum_items(prop, view_zoom_styles); @@ -4660,10 +4626,49 @@ static void rna_def_userdef_input(BlenderRNA *brna) RNA_def_property_boolean_sdna(prop, NULL, "uiflag", USER_ZOOM_INVERT); RNA_def_property_ui_text(prop, "Invert Zoom Direction", "Invert the axis of mouse movement for zooming"); + prop = RNA_def_property(srna, "use_cursor_lock_adjust", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "uiflag", USER_LOCK_CURSOR_ADJUST); + RNA_def_property_ui_text(prop, "Cursor Lock Adjust", + "Place the cursor without 'jumping' to the new location (when lock-to-cursor is used)"); + + prop = RNA_def_property(srna, "use_mouse_depth_navigate", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "uiflag", USER_DEPTH_NAVIGATE); + RNA_def_property_ui_text(prop, "Auto Depth", + "Use the depth under the mouse to improve view pan/rotate/zoom functionality"); + + prop = RNA_def_property(srna, "use_mouse_depth_cursor", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "uiflag", USER_DEPTH_CURSOR); + RNA_def_property_ui_text(prop, "Cursor Surface Project", + "Use the surface depth for cursor placement"); + + prop = RNA_def_property(srna, "use_camera_lock_parent", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_negative_sdna(prop, NULL, "uiflag", USER_CAM_LOCK_NO_PARENT); + RNA_def_property_ui_text(prop, "Camera Parent Lock", + "When the camera is locked to the view and in fly mode, " + "transform the parent rather than the camera"); + + /* view zoom */ + prop = RNA_def_property(srna, "use_zoom_to_mouse", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "uiflag", USER_ZOOM_TO_MOUSEPOS); + RNA_def_property_ui_text(prop, "Zoom To Mouse Position", + "Zoom in towards the mouse pointer's position in the 3D view, " + "rather than the 2D window center"); + + /* view rotation */ + prop = RNA_def_property(srna, "use_auto_perspective", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "uiflag", USER_AUTOPERSP); + RNA_def_property_ui_text(prop, "Auto Perspective", + "Automatically switch between orthographic and perspective when changing " + "from top/front/side views"); + + prop = RNA_def_property(srna, "use_rotate_around_active", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "uiflag", USER_ORBIT_SELECTION); + RNA_def_property_ui_text(prop, "Orbit Around Selection", "Use selection as the pivot point"); + prop = RNA_def_property(srna, "view_rotate_method", PROP_ENUM, PROP_NONE); RNA_def_property_enum_bitflag_sdna(prop, NULL, "flag"); RNA_def_property_enum_items(prop, view_rotation_items); - RNA_def_property_ui_text(prop, "View Rotation", "Rotation style in the viewport"); + RNA_def_property_ui_text(prop, "Orbit Method", "Orbit method in the viewport"); prop = RNA_def_property(srna, "use_mouse_continuous", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "uiflag", USER_CONTINUOUS_MOUSE); @@ -4807,7 +4812,7 @@ static void rna_def_userdef_input(BlenderRNA *brna) prop = RNA_def_property(srna, "use_mouse_emulate_3_button", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", USER_TWOBUTTONMOUSE); RNA_def_property_ui_text(prop, "Emulate 3 Button Mouse", - "Emulate Middle Mouse with Alt+Left Mouse (doesn't work with Left Mouse Select option)"); + "Emulate Middle Mouse with Alt+Left Mouse"); RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE); RNA_def_property_update(prop, 0, "rna_userdef_keyconfig_reload_update"); @@ -4828,6 +4833,21 @@ static void rna_def_userdef_input(BlenderRNA *brna) RNA_def_property_boolean_sdna(prop, NULL, "uiflag2", USER_TRACKPAD_NATURAL); RNA_def_property_ui_text(prop, "Trackpad Natural", "If your system uses 'natural' scrolling, this option keeps consistent trackpad usage throughout the UI"); +} + +static void rna_def_userdef_keymap(BlenderRNA *brna) +{ + PropertyRNA *prop; + + StructRNA *srna = RNA_def_struct(brna, "PreferencesKeymap", NULL); + RNA_def_struct_sdna(srna, "UserDef"); + RNA_def_struct_nested(brna, srna, "Preferences"); + RNA_def_struct_clear_flag(srna, STRUCT_UNDO); + RNA_def_struct_ui_text(srna, "Keymap", "Shortcut setup for keyboards and other input devices"); + + prop = RNA_def_property(srna, "show_ui_keyconfig", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_negative_sdna(prop, NULL, "userpref_flag", USER_SECTION_INPUT_HIDE_UI_KEYCONFIG); + RNA_def_property_ui_text(prop, "Show UI Key-Config", ""); prop = RNA_def_property(srna, "active_keyconfig", PROP_STRING, PROP_DIRPATH); RNA_def_property_string_sdna(prop, NULL, "keyconfigstr"); @@ -4889,6 +4909,27 @@ static void rna_def_userdef_filepaths(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Load UI", "Load user interface setup when loading .blend files"); RNA_def_property_update(prop, 0, "rna_userdef_load_ui_update"); + + prop = RNA_def_property(srna, "use_scripts_auto_execute", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", USER_SCRIPT_AUTOEXEC_DISABLE); + RNA_def_property_ui_text(prop, "Auto Run Python Scripts", + "Allow any .blend file to run scripts automatically " + "(unsafe with blend files from an untrusted source)"); + RNA_def_property_update(prop, 0, "rna_userdef_script_autoexec_update"); + + prop = RNA_def_property(srna, "author", PROP_STRING, PROP_NONE); + RNA_def_property_string_sdna(prop, NULL, "author"); + RNA_def_property_string_maxlength(prop, 80); + RNA_def_property_ui_text(prop, "Author", + "Name that will be used in exported files when format supports such feature"); + + prop = RNA_def_property(srna, "use_tabs_as_spaces", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", USER_TXT_TABSTOSPACES_DISABLE); + RNA_def_property_ui_text(prop, "Tabs as Spaces", + "Automatically convert all new tabs into spaces for new and loaded text files"); + + /* Directories */ + prop = RNA_def_property(srna, "font_directory", PROP_STRING, PROP_DIRPATH); RNA_def_property_string_sdna(prop, NULL, "fontdir"); RNA_def_property_ui_text(prop, "Fonts Directory", "The default directory to search for loading fonts"); @@ -5035,13 +5076,14 @@ void RNA_def_userdef(BlenderRNA *brna) PropertyRNA *prop; static const EnumPropertyItem preference_section_items[] = { - {0, "", ICON_USER, "User Preferences", ""}, + {0, "", ICON_USER, "User", ""}, {USER_SECTION_INTERFACE, "INTERFACE", 0, "Interface", ""}, + {USER_SECTION_THEME, "THEMES", 0, "Themes", ""}, + {USER_SECTION_LIGHT, "LIGHTS", 0, "Lights", ""}, {USER_SECTION_EDIT, "EDITING", 0, "Editing", ""}, {USER_SECTION_INPUT, "INPUT", 0, "Input", ""}, + {USER_SECTION_KEYMAP, "KEYMAP", 0, "Keymap", ""}, {USER_SECTION_ADDONS, "ADDONS", 0, "Add-ons", ""}, - {USER_SECTION_THEME, "THEMES", 0, "Themes", ""}, - {USER_SECTION_LIGHT, "LIGHTS", 0, "Lights", ""}, #ifdef WITH_USERDEF_WORKSPACES {0, "", ICON_WORKSPACE, "Workspaces", ""}, {USER_SECTION_WORKSPACE_CONFIG, "WORKSPACE_CONFIG", 0, "Configuration File", ""}, @@ -5071,7 +5113,7 @@ void RNA_def_userdef(BlenderRNA *brna) RNA_def_property_enum_sdna(prop, NULL, "userpref"); RNA_def_property_enum_items(prop, preference_section_items); RNA_def_property_ui_text(prop, "Active Section", - "Active section of the user preferences shown in the user interface"); + "Active section of the preferences shown in the user interface"); RNA_def_property_update(prop, 0, "rna_userdef_update"); /* don't expose this directly via the UI, modify via an operator */ @@ -5120,6 +5162,12 @@ void RNA_def_userdef(BlenderRNA *brna) RNA_def_property_pointer_funcs(prop, "rna_UserDef_input_get", NULL, NULL, NULL); RNA_def_property_ui_text(prop, "Inputs", "Settings for input devices"); + prop = RNA_def_property(srna, "keymap", PROP_POINTER, PROP_NONE); + RNA_def_property_flag(prop, PROP_NEVER_NULL); + RNA_def_property_struct_type(prop, "PreferencesKeymap"); + RNA_def_property_pointer_funcs(prop, "rna_UserDef_keymap_get", NULL, NULL, NULL); + RNA_def_property_ui_text(prop, "Keymap", "Shortcut setup for keyboards and other input devices"); + prop = RNA_def_property(srna, "filepaths", PROP_POINTER, PROP_NONE); RNA_def_property_flag(prop, PROP_NEVER_NULL); RNA_def_property_struct_type(prop, "PreferencesFilePaths"); @@ -5151,6 +5199,7 @@ void RNA_def_userdef(BlenderRNA *brna) rna_def_userdef_view(brna); rna_def_userdef_edit(brna); rna_def_userdef_input(brna); + rna_def_userdef_keymap(brna); rna_def_userdef_filepaths(brna); rna_def_userdef_system(brna); rna_def_userdef_addon(brna); diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c index 715ab5166b6..cc3c4ed235d 100644 --- a/source/blender/windowmanager/intern/wm_files.c +++ b/source/blender/windowmanager/intern/wm_files.c @@ -1684,7 +1684,7 @@ void WM_OT_save_userpref(wmOperatorType *ot) { ot->name = "Save Preferences"; ot->idname = "WM_OT_save_userpref"; - ot->description = "Save user preferences separately, overrides startup file preferences"; + ot->description = "Save preferences separately, overrides startup file preferences"; ot->invoke = WM_operator_confirm; ot->exec = wm_userpref_write_exec; @@ -1825,7 +1825,7 @@ void WM_OT_read_factory_settings(wmOperatorType *ot) ot->name = "Load Factory Settings"; ot->idname = "WM_OT_read_factory_settings"; - ot->description = "Load default file and user preferences"; + ot->description = "Load default file and preferences"; ot->invoke = WM_operator_confirm; ot->exec = wm_homefile_read_exec; |