UI: Add UILayout::property_split_factor static value

This adds the `UILayout::property_split_factor` property which contains
the split factor used in the layout system, and avoids to use the this
as raw value all over the place.

Pull Request: https://projects.blender.org/blender/blender/pulls/163393
This commit is contained in:
Guillermo Venegas 2026-09-09 00:27:44 +02:00 • committed by Guillermo Venegas
parent 6294beebb7
commit bad8871dc5
23 changed files with 71 additions and 53 deletions

View file

@ -894,7 +894,7 @@ class CYCLES_RENDER_PT_performance_texture_cache(CyclesButtonsPanel, Panel):
col.prop(rd, "use_auto_generate_texture_cache", text="Auto Generate")
row = col.split(factor=0.4)
row = col.split(factor=col.property_split_factor)
row.label()
sub = row.row(align=True)
sub.operator("render.generate_texture_cache", text="Generate")

View file

@ -513,7 +513,7 @@ class DATA_PT_rigify_actions(Panel):
row.prop_search(active_slot, trigger_prop, metarig.data, 'rigify_action_slots', icon=icon)
if not trigger:
row = layout.split(factor=0.4)
row = layout.split(factor=layout.property_split_factor)
row.separator()
row.alert = True
row.label(text="Action not in list", icon='STATUS_ERROR')
@ -552,7 +552,7 @@ class DATA_PT_rigify_actions(Panel):
row.alert = not subtarget_exists
if slot.subtarget and not subtarget_exists:
row = layout.split(factor=0.4)
row = layout.split(factor=layout.property_split_factor)
row.column()
row.alert = True
text = rpt_("Bone not found: {:s}").format(slot.subtarget)
@ -573,7 +573,7 @@ class DATA_PT_rigify_actions(Panel):
if slot.symmetrical and not flipped_subtarget_exists:
row.alert = True
row = layout.split(factor=0.4)
row = layout.split(factor=layout.property_split_factor)
row.column()
row.alert = True
text = rpt_("Bone not found: {:s}").format(flipped_subtarget)
@ -595,7 +595,7 @@ class DATA_PT_rigify_actions(Panel):
"""
layout = self.layout
split = layout.split(factor=0.4)
split = layout.split(factor=layout.property_split_factor)
heading = split.row()
heading.alignment = 'RIGHT'
heading.label(text="Status:")

View file

@ -343,7 +343,7 @@ class DATA_PT_rigify_collection_list(bpy.types.Panel):
col.operator("armature.collection_move", icon='TRIA_DOWN', text="").direction = 'DOWN'
row = layout.row()
split = row.split(factor=0.4)
split = row.split(factor=row.property_split_factor)
split.label(text="")
split.operator(operator='armature.rigify_validate_layers')
@ -871,7 +871,7 @@ class DATA_PT_rigify_color_sets(bpy.types.Panel):
col.menu("DATA_MT_rigify_color_sets_context_menu", icon='DOWNARROW_HLT', text="")
row = layout.row()
split = row.split(factor=0.4)
split = row.split(factor=row.property_split_factor)
split.label(text="Bone Theme:")
split.prop(armature, 'rigify_theme_to_add', text="")
op = row.operator("armature.rigify_color_set_add_theme", text="Add From Theme")

View file

@ -195,7 +195,7 @@ def draw_kmi(display_keymaps, kc, km, kmi, layout, level):
box = col.box()
split = box.split(factor=0.4)
split = box.split(factor=box.property_split_factor)
sub = split.row()
if km.is_modal:
@ -567,7 +567,7 @@ def draw_keymaps(context, layout):
# layout.context_pointer_set("keyconfig", wm.keyconfigs.active)
# row.operator("preferences.keyconfig_remove", text="", icon='X')
rowsub = row.split(factor=0.4, align=True)
rowsub = row.split(factor=row.property_split_factor, align=True)
# postpone drawing into rowsub, so we can set alert!
layout.separator()

View file

@ -206,7 +206,7 @@ def draw(layout, context, context_member, property_type, *, use_edit=True):
elif to_list:
value = to_list()
split = layout.split(factor=0.4, align=True)
split = layout.split(factor=layout.property_split_factor, align=True)
label_row = split.row()
label_row.alignment = 'RIGHT'
label_row.label(text=key, translate=False)

View file

@ -177,7 +177,7 @@ class BONE_PT_curved(BoneButtonsPanel, Panel):
row = col.row(align=True)
row.use_property_split = False
split = row.split(factor=0.4)
split = row.split(factor=row.property_split_factor)
split.alignment = 'RIGHT'
split.label(text="Scale")
split2 = split.split(factor=0.7)
@ -197,7 +197,7 @@ class BONE_PT_curved(BoneButtonsPanel, Panel):
row = col.row(align=True)
row.use_property_split = False
split = row.split(factor=0.4)
split = row.split(factor=row.property_split_factor)
split.alignment = 'RIGHT'
split.label(text="Scale")
split2 = split.split(factor=0.7)

View file

@ -350,7 +350,7 @@ class DATA_PT_shape_keys(MeshButtonsPanel, Panel):
sub.operator("object.shape_key_move", icon='TRIA_UP', text="").type = 'UP'
sub.operator("object.shape_key_move", icon='TRIA_DOWN', text="").type = 'DOWN'
split = layout.split(factor=0.4)
split = layout.split(factor=layout.property_split_factor)
row = split.row()
row.enabled = enable_edit
row.prop(key, "use_relative")

View file

@ -450,7 +450,7 @@ class RENDER_PT_output_pixel_density(RenderOutputButtonsPanel, Panel):
layout.prop(rd, "ppm_factor", text="Pixels")
layout.active = rd.save_output
row = layout.split(factor=0.4)
row = layout.split(factor=layout.property_split_factor)
row.alignment = 'RIGHT'
row.label(text="Unit")
row.menu("RENDER_MT_pixeldensity_presets", text=pixeldensity_label_text)
@ -564,7 +564,7 @@ class RENDER_PT_encoding_video(RenderOutputButtonsPanel, Panel):
layout.label(text="HDR needs 10 or 12 bits", icon='STATUS_ERROR')
# Color space
split = layout.split(factor=0.4)
split = layout.split(factor=layout.property_split_factor)
col = split.column()
col.alignment = 'RIGHT'
col.label(text="Color Space")

View file

@ -1598,7 +1598,7 @@ def draw_mesh_automasking_settings(layout, settings, *, topbar=False, use_face_s
else:
col = parent.column()
col.use_property_split = False
split = col.split(factor=0.4)
split = col.split(factor=col.property_split_factor)
col = split.column()
split.prop(settings, "boundary_edges_propagation_steps")

View file

@ -79,7 +79,7 @@ class RENDER_PT_color_management(RenderButtonsPanel, Panel):
col.prop(view, "look")
if view.is_hdr and not context.window.support_hdr_color:
row = col.split(factor=0.4)
row = col.split(factor=col.property_split_factor)
row.label()
if gpu.platform.backend_type_get() == 'OPENGL':
@ -114,7 +114,7 @@ class RENDER_PT_color_management_working_space(RenderButtonsPanel, Panel):
col = flow.column()
split = col.split(factor=0.4)
split = col.split(factor=col.property_split_factor)
row = split.row()
row.label(text="File")
row.alignment = 'RIGHT'

View file

@ -702,7 +702,7 @@ class STRIP_PT_scene_sound(StripButtonsPanel, Panel):
col = layout.column()
col.use_property_decorate = True
split = col.split(factor=0.4)
split = col.split(factor=col.property_split_factor)
split.alignment = 'RIGHT'
split.label(text="Strip Volume", text_ctxt=i18n_contexts.id_sound)
split.prop(strip, "volume", text="")
@ -922,7 +922,7 @@ class STRIP_PT_adjust_sound(StripButtonsPanel, Panel):
layout.use_property_split = True
col = layout.column()
split = col.split(factor=0.4)
split = col.split(factor=col.property_split_factor)
split.alignment = 'RIGHT'
split.label(text="Volume", text_ctxt=i18n_contexts.id_sound)
split.prop(strip, "volume", text="")
@ -931,7 +931,7 @@ class STRIP_PT_adjust_sound(StripButtonsPanel, Panel):
layout.use_property_split = False
col = layout.column()
split = col.split(factor=0.4)
split = col.split(factor=col.property_split_factor)
split.label(text="")
split.prop(sound, "use_mono")
@ -942,14 +942,14 @@ class STRIP_PT_adjust_sound(StripButtonsPanel, Panel):
pan_enabled = sound.use_mono and audio_channels != 'MONO'
pan_text = "{:.2f}°".format(strip.pan * 90.0)
split = col.split(factor=0.4)
split = col.split(factor=col.property_split_factor)
split.alignment = 'RIGHT'
split.label(text="Pan", text_ctxt=i18n_contexts.id_sound)
split.prop(strip, "pan", text="")
split.enabled = pan_enabled
if audio_channels not in {'MONO', 'STEREO'}:
split = col.split(factor=0.4)
split = col.split(factor=col.property_split_factor)
split.alignment = 'RIGHT'
split.label(text="Pan Angle")
split.enabled = pan_enabled
@ -962,11 +962,11 @@ class STRIP_PT_adjust_sound(StripButtonsPanel, Panel):
layout.use_property_split = False
col = layout.column()
split = col.split(factor=0.4)
split = col.split(factor=col.property_split_factor)
split.label(text="")
split.prop(strip, "pitch_correction")
split = col.split(factor=0.4)
split = col.split(factor=col.property_split_factor)
split.label(text="")
split.prop(strip, "show_waveform")

View file

@ -786,7 +786,7 @@ class DOPESHEET_PT_action_slot(Panel):
except (KeyError, IndexError, AttributeError) as ex:
idtype_label = str(ex)
split = layout.split(factor=0.4)
split = layout.split(factor=layout.property_split_factor)
split.alignment = 'RIGHT'
split.label(text="Type")
split.alignment = 'LEFT'

View file

@ -787,7 +787,7 @@ class ASSETBROWSER_PT_metadata(asset_utils.AssetBrowserPanel, Panel):
asset is in the current file). Empty, non-editable fields are not really useful.
"""
if getattr(asset_metadata, propname) or not asset_metadata.is_property_readonly(propname):
split = layout.split(factor=0.4)
split = layout.split(factor=layout.property_split_factor)
ui_name = asset_metadata.rna_type.properties[propname].name
sub = split.row()
sub.alignment = 'RIGHT'
@ -808,7 +808,7 @@ class ASSETBROWSER_PT_metadata(asset_utils.AssetBrowserPanel, Panel):
if getattr(asset_metadata, "webpage") or not asset_metadata.is_property_readonly("webpage"):
ui_name = asset_metadata.rna_type.properties["webpage"].name
if asset_metadata.is_property_readonly("webpage"):
split = layout.split(factor=0.4)
split = layout.split(factor=layout.property_split_factor)
sub = split.row()
sub.alignment = 'RIGHT'
sub.label(text=ui_name)

View file

@ -1670,19 +1670,19 @@ class SEQUENCER_PT_cache_view_settings(SequencerButtonsPanel, Panel):
col = layout.box()
col = col.column(align=True)
split = col.split(factor=0.4, align=True)
split = col.split(factor=col.property_split_factor, align=True)
split.alignment = 'RIGHT'
split.label(text="Current Cache Size")
split.alignment = 'LEFT'
split.label(text=iface_("{:d} MB").format(cache_raw_size + cache_final_size), translate=False)
split = col.split(factor=0.4, align=True)
split = col.split(factor=col.property_split_factor, align=True)
split.alignment = 'RIGHT'
split.label(text="Raw")
split.alignment = 'LEFT'
split.label(text=iface_("{:d} MB").format(cache_raw_size), translate=False)
split = col.split(factor=0.4, align=True)
split = col.split(factor=col.property_split_factor, align=True)
split.alignment = 'RIGHT'
split.label(text="Final")
split.alignment = 'LEFT'

View file

@ -693,7 +693,7 @@ class USERPREF_PT_animation_timeline_advanced(AnimationPanel, CenterAlignMixIn,
edit = prefs.edit
layout.prop(edit, "use_negative_frames")
split = layout.split(factor=0.4)
split = layout.split(factor=layout.property_split_factor)
split.active = edit.use_negative_frames
split.separator()
split.label_multiline(
@ -837,7 +837,7 @@ class USERPREF_PT_system_network(SystemPanel, CenterAlignMixIn, Panel):
# Show when the preference has been overridden and doesn't match the current preference.
runtime_online_access = bpy.app.online_access
if system.use_online_access != runtime_online_access:
row = layout.split(factor=0.4)
row = layout.split(factor=layout.property_split_factor)
row.label(text="")
if runtime_online_access:
text = iface_("Enabled on startup, overriding the preference.")

View file

@ -529,7 +529,7 @@ class _draw_tool_settings_context_mode:
BrushAssetShelf.draw_popup_selector(layout, context, brush)
if brush.gpencil_vertex_brush_type not in {'BLUR', 'AVERAGE', 'SMEAR'}:
layout.separator(factor=0.4)
layout.separator(factor=layout.property_split_factor)
ups = paint.unified_paint_settings
prop_owner = ups if brush.use_unified_color else brush
layout.prop_with_popover(prop_owner, "color", text="", panel="TOPBAR_PT_grease_pencil_vertex_color")
@ -705,7 +705,7 @@ class _draw_tool_settings_context_mode:
brush_basic__draw_color_selector(context, layout, brush, brush.gpencil_settings)
if grease_pencil_tool == 'TINT':
row.separator(factor=0.4)
row.separator(factor=layout.property_split_factor)
row.prop_with_popover(brush, "color", text="", panel="TOPBAR_PT_grease_pencil_vertex_color")
from bl_ui.properties_paint_common import (

View file

@ -117,6 +117,9 @@ enum class EnumTabExpand {
};
struct Layout : public Item, NonCopyable, NonMovable {
static constexpr float PROPERTY_SPLIT_FACTOR = 0.4f;
protected:
LayoutRoot *root_ = nullptr;
bContextStore *context_ = nullptr;

View file

@ -77,8 +77,6 @@ struct ButtonItem;
} \
(void)0
#define UI_ITEM_PROP_SEP_DIVIDE 0.4f
/* uiLayoutRoot */
struct LayoutRoot {
@ -2158,7 +2156,7 @@ void Layout::prop(PointerRNA *ptr,
}
else {
Layout *layout_split =
&(layout_row ? layout_row : layout)->split(UI_ITEM_PROP_SEP_DIVIDE, true);
&(layout_row ? layout_row : layout)->split(Layout::PROPERTY_SPLIT_FACTOR, true);
bool label_added = false;
Layout *layout_sub = &layout_split->column(true);
layout_sub->space_ = 0;
@ -3482,7 +3480,7 @@ PropertySplitWrapper uiItemPropertySplitWrapperCreate(Layout *parent_layout)
PropertySplitWrapper split_wrapper = {nullptr};
Layout *layout_row = &parent_layout->row(true);
Layout *layout_split = &layout_row->split(UI_ITEM_PROP_SEP_DIVIDE, true);
Layout *layout_split = &layout_row->split(Layout::PROPERTY_SPLIT_FACTOR, true);
split_wrapper.label_column = &layout_split->column(true);
split_wrapper.label_column->alignment_set(LayoutAlign::Right);

View file

@ -1312,7 +1312,7 @@ static void std_node_socket_draw(
layout->prop(ptr, "default_value", DEFAULT_FLAGS, "", ICON_NONE);
}
else {
ui::Layout *row = &layout->split(0.4f, false);
ui::Layout *row = &layout->split(ui::Layout::PROPERTY_SPLIT_FACTOR, false);
ui::Layout *label_layout = &row->column(true);
label_layout->label(label, ICON_NONE);
ui::Layout *color_layout = &row->column(true);
@ -1332,7 +1332,7 @@ static void std_node_socket_draw(
node_geometry_add_attribute_search_button(*C, *node, *ptr, *layout, label);
}
else {
ui::Layout *row = &layout->split(0.4f, false);
ui::Layout *row = &layout->split(ui::Layout::PROPERTY_SPLIT_FACTOR, false);
row->label(label, ICON_NONE);
node_geometry_add_attribute_search_button(*C, *node, *ptr, *row);
}
@ -1342,7 +1342,7 @@ static void std_node_socket_draw(
node_geometry_add_layer_search_button(*C, *node, *ptr, *layout, label);
}
else {
ui::Layout *row = &layout->split(0.4f, false);
ui::Layout *row = &layout->split(ui::Layout::PROPERTY_SPLIT_FACTOR, false);
row->label(label, ICON_NONE);
node_geometry_add_layer_search_button(*C, *node, *ptr, *row);
}
@ -1352,7 +1352,7 @@ static void std_node_socket_draw(
node_geometry_add_volume_grid_search_button(*C, *node, *ptr, *layout, label);
}
else {
ui::Layout *row = &layout->split(0.4f, false);
ui::Layout *row = &layout->split(ui::Layout::PROPERTY_SPLIT_FACTOR, false);
row->label(label, ICON_NONE);
node_geometry_add_volume_grid_search_button(*C, *node, *ptr, *row);
}
@ -1362,7 +1362,7 @@ static void std_node_socket_draw(
node_bundle_type_add_string_search_button(*C, *node, *ptr, *layout, label);
}
else {
ui::Layout *row = &layout->split(0.4f, false);
ui::Layout *row = &layout->split(ui::Layout::PROPERTY_SPLIT_FACTOR, false);
row->label(label, ICON_NONE);
node_bundle_type_add_string_search_button(*C, *node, *ptr, *row);
}
@ -1379,7 +1379,7 @@ static void std_node_socket_draw(
label);
}
else {
ui::Layout *row = &layout->split(0.4f, false);
ui::Layout *row = &layout->split(ui::Layout::PROPERTY_SPLIT_FACTOR, false);
row->label(label, ICON_NONE);
row->prop(ptr, "default_value", DEFAULT_FLAGS, "", ICON_NONE);
}
@ -1391,7 +1391,7 @@ static void std_node_socket_draw(
sock->default_value_typed<bNodeSocketValueMenu>();
if (default_value->enum_items) {
if (default_value->enum_items->items.is_empty()) {
ui::Layout *row = &layout->split(0.4f, false);
ui::Layout *row = &layout->split(ui::Layout::PROPERTY_SPLIT_FACTOR, false);
row->label(label, ICON_NONE);
row->label(IFACE_("No Items"), ICON_NONE);
}
@ -1411,7 +1411,7 @@ static void std_node_socket_draw(
}
}
else {
ui::Layout &row = layout->split(0.4f, false);
ui::Layout &row = layout->split(ui::Layout::PROPERTY_SPLIT_FACTOR, false);
row.label(label, ICON_NONE);
if (expanded) {
/* Use a single space for the name to work around a bug. Also see

View file

@ -2826,7 +2826,7 @@ static void view3d_panel_curve_data(const bContext *C, Panel *panel)
auto add_labeled_field =
[&](const StringRef label, const bool active, FunctionRef<ui::Button *()> add_button) {
ui::Layout &row = bcol.row(true);
ui::Layout &split = row.split(0.4, true);
ui::Layout &split = row.split(ui::Layout::PROPERTY_SPLIT_FACTOR, true);
ui::Layout &col = split.column(true);
col.alignment_set(ui::LayoutAlign::Right);
col.label(label, ICON_NONE);

View file

@ -1524,6 +1524,11 @@ static float rna_UILayout_units_y_get(PointerRNA *ptr)
return ptr->data_as<const Layout>()->ui_units_y();
}
static float rna_UIlayout_property_split_factor_get(PointerRNA * /*ptr*/)
{
return Layout::PROPERTY_SPLIT_FACTOR;
}
static void rna_UILayout_units_y_set(PointerRNA *ptr, float value)
{
ptr->data_as<Layout>()->ui_units_y_set(value);
@ -1809,6 +1814,18 @@ static void rna_def_ui_layout(BlenderRNA *brna)
RNA_def_property_boolean_funcs(
prop, "rna_UILayout_property_split_get", "rna_UILayout_property_split_set");
prop = RNA_def_float(srna,
"property_split_factor",
ui::Layout::PROPERTY_SPLIT_FACTOR,
ui::Layout::PROPERTY_SPLIT_FACTOR,
ui::Layout::PROPERTY_SPLIT_FACTOR,
"Property Split Factor",
"Factor used by the layout system when property split is enabled",
ui::Layout::PROPERTY_SPLIT_FACTOR,
ui::Layout::PROPERTY_SPLIT_FACTOR);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_float_funcs(prop, "rna_UIlayout_property_split_factor_get", nullptr, nullptr);
prop = RNA_def_property(srna, "use_property_decorate", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_funcs(
prop, "rna_UILayout_property_decorate_get", "rna_UILayout_property_decorate_set");

View file

@ -246,7 +246,7 @@ static void add_layer_name_search_button(DrawGroupInputsContext &ctx,
layout.use_property_decorate_set(false);
ui::Layout &split = layout.split(0.4f, false);
ui::Layout &split = layout.split(ui::Layout::PROPERTY_SPLIT_FACTOR, false);
ui::Layout &name_row = split.row(false);
name_row.alignment_set(ui::LayoutAlign::Right);
@ -425,7 +425,7 @@ static void add_attribute_search_or_value_buttons(
/* We're handling this manually in this case. */
layout.use_property_decorate_set(false);
ui::Layout &split = layout.split(0.4f, false);
ui::Layout &split = layout.split(ui::Layout::PROPERTY_SPLIT_FACTOR, false);
ui::Layout &name_row = split.row(false);
name_row.alignment_set(ui::LayoutAlign::Right);
@ -744,7 +744,7 @@ static void draw_property_for_output_socket(DrawGroupInputsContext &ctx,
ui::Layout &layout,
const bNodeTreeInterfaceSocket &socket)
{
ui::Layout &split = layout.split(0.4f, false);
ui::Layout &split = layout.split(ui::Layout::PROPERTY_SPLIT_FACTOR, false);
ui::Layout &name_row = split.row(false);
name_row.alignment_set(ui::LayoutAlign::Right);
name_row.label(socket.name(), ICON_NONE);
@ -823,7 +823,7 @@ static void draw_named_attributes_panel(ui::Layout &layout, Object &object, Node
const eval_log::NamedAttributeUsage usage = attribute.usage;
/* #uiLayoutRowWithHeading doesn't seem to work in this case. */
ui::Layout &split = layout.split(0.4f, false);
ui::Layout &split = layout.split(ui::Layout::PROPERTY_SPLIT_FACTOR, false);
std::stringstream ss;
Vector<std::string> usages;

View file

@ -41,7 +41,7 @@ static void sound_equalizermodifier_draw(const bContext * /*C*/, Panel *panel)
const float clip_max_x = RNA_float_get(&curve_mapping, "clip_max_x");
ui::Layout &col = flow.column(false);
ui::Layout &split = col.split(0.4f, false);
ui::Layout &split = col.split(ui::Layout::PROPERTY_SPLIT_FACTOR, false);
split.label(fmt::format("{:.2f}", clip_min_x), ICON_NONE);
split.label("Hz", ICON_NONE);
split.alignment_set(ui::LayoutAlign::Right);