This commit is contained in:
2025-10-13 11:15:21 +02:00
parent 9a6543c530
commit 2519b55f08
24 changed files with 498 additions and 169 deletions

31
src/ui/font_helpers.py Normal file
View File

@@ -0,0 +1,31 @@
"""
Helper utilities for font sizing and text fitting presentation logic.
"""
from ..utils.constants import has_text_fitting
FONT_FITTING_MODE_LABELS = {
'FIT_WIDTH': "Fit Width",
'FIT_HEIGHT': "Fit Height",
'FIT_BOTH': "Fit Width & Height",
'FIT_CONTAIN': "Fit Contain",
}
def font_size_ui_state(props):
"""
Determine whether the manual font size control should be enabled and what
status message to show based on the current text fitting configuration.
Returns:
tuple(bool, str): (is_manual_enabled, status_message)
"""
fitting_available = bool(has_text_fitting())
fitting_enabled = fitting_available and bool(getattr(props, "enable_text_fitting", False))
if not fitting_enabled:
return True, ""
mode = getattr(props, "text_fitting_mode", "")
mode_label = FONT_FITTING_MODE_LABELS.get(mode, mode.replace("_", " ").title() if mode else "Auto")
return False, f"Auto-sized via Text Fitting ({mode_label})"

View File

@@ -14,6 +14,7 @@ from ..utils.constants import (
has_normal_maps, has_batch_processing, has_advanced_utilities,
has_advanced_styling, has_text_fitting
)
from .font_helpers import font_size_ui_state
# ============================================================================
@@ -403,28 +404,63 @@ def draw_positioning_section(layout, props):
def draw_font_settings_section(layout, props):
pass
"""Draw extended font settings"""
# Font size moved here from top level
layout.prop(props, "font_size")
layout.separator()
layout.label(text="Font Selection:")
# Default font dropdown moved here from top level
row = layout.row(align=True)
row.prop(props, "font_path", text="")
row.operator("text_texture.refresh_fonts", text="", icon='FILE_REFRESH')
layout.separator()
# Custom font controls moved here from top level
layout.prop(props, "use_custom_font")
"""Draw unified font sizing and fitting controls."""
content = layout.column(align=True)
content.use_property_split = True
content.use_property_decorate = False
sizing_box = content.box()
sizing_box.use_property_split = True
sizing_box.use_property_decorate = False
sizing_box.label(text="Size & Text Fitting", icon='FULLSCREEN_ENTER')
manual_enabled, status_message = font_size_ui_state(props)
manual_row = sizing_box.row(align=True)
manual_row.enabled = manual_enabled
manual_row.prop(props, "font_size", text="Manual Size")
if status_message:
info_row = sizing_box.row()
info_row.label(text=status_message, icon='INFO')
if has_text_fitting():
toggle_row = sizing_box.row(align=True)
toggle_row.prop(props, "enable_text_fitting", text="Enable Text Fitting", toggle=True)
if props.enable_text_fitting:
sizing_box.separator(factor=0.5)
mode_row = sizing_box.row(align=True)
mode_row.prop(props, "text_fitting_mode", text="Mode")
margin_row = sizing_box.row(align=True)
margin_row.prop(props, "text_fitting_margin", text="Margin", slider=True)
limit_row = sizing_box.row(align=True)
limit_row.prop(props, "min_font_size", text="Min Size")
limit_row.prop(props, "max_font_size", text="Max Size")
else:
sizing_box.separator(factor=0.5)
draw_feature_lock_indicator(sizing_box, 'text_fitting', show_hint=False)
content.separator(factor=0.8)
selection_box = content.box()
selection_box.use_property_split = True
selection_box.use_property_decorate = False
selection_box.label(text="Font Selection", icon='FONT_DATA')
font_row = selection_box.row(align=True)
font_row.prop(props, "font_path", text="")
font_row.operator("text_texture.refresh_fonts", text="", icon='FILE_REFRESH')
selection_box.prop(props, "use_custom_font")
if props.use_custom_font:
pass
layout.prop(props, "custom_font_path", text="")
layout.separator()
row = layout.row(align=True)
row.prop(props, "padding")
row.prop(props, "text_align")
selection_box.prop(props, "custom_font_path", text="")
selection_box.separator(factor=0.5)
selection_box.prop(props, "text_align", text="Alignment")
def draw_colors_section(layout, props):
pass
@@ -654,55 +690,6 @@ def draw_normal_maps_section(layout, props):
info_box.label(text="• Blur smooths sharp edges")
info_box.label(text="• Invert changes raised/recessed effect")
def draw_text_fitting_section(layout, props):
"""Draw text fitting controls"""
# Check if text fitting is available
if not has_text_fitting():
draw_feature_lock_indicator(layout, 'text_fitting')
return
# Main toggle for text fitting
layout.prop(props, "enable_text_fitting", text="Enable Text Fitting", icon='FULLSCREEN_ENTER')
# Show controls only if text fitting is enabled
if props.enable_text_fitting:
pass
layout.separator()
# Fitting mode selection
layout.prop(props, "text_fitting_mode", text="Fitting Mode")
layout.separator()
# Margin setting
layout.prop(props, "text_fitting_margin", text="Margin", slider=True)
layout.separator()
# Font size limits
col = layout.column(align=True)
col.label(text="Font Size Limits:", icon='RESTRICT_SELECT_ON')
row = col.row(align=True)
row.prop(props, "min_font_size", text="Min")
row.prop(props, "max_font_size", text="Max")
# Info box with usage tips
layout.separator()
info_box = layout.box()
info_box.scale_y = 0.8
info_box.label(text="💡 Text fitting automatically sizes text", icon='INFO')
if props.text_fitting_mode == 'FIT_WIDTH':
pass
info_box.label(text="• Fits text width to canvas width")
elif props.text_fitting_mode == 'FIT_HEIGHT':
info_box.label(text="• Fits text height to canvas height")
elif props.text_fitting_mode == 'FIT_BOTH':
info_box.label(text="• Fits both width and height (may distort)")
elif props.text_fitting_mode == 'FIT_CONTAIN':
info_box.label(text="• Fits entirely within canvas (preserves ratio)")
info_box.label(text="• Respects min/max font size limits")
def draw_stroke_section(layout, props):
pass
"""Draw stroke and outline controls"""
@@ -916,12 +903,6 @@ class TEXT_TEXTURE_PT_panel(Panel):
if position_section:
draw_positioning_section(position_section, props)
# Text Fitting Section (collapsed by default)
text_fitting_section = draw_collapsible_header(layout, "expand_text_fitting", "Text Fitting", 'FULLSCREEN_ENTER')
if text_fitting_section:
pass
draw_text_fitting_section(text_fitting_section, props)
# Colors Section (collapsed by default)
colors_section = draw_collapsible_header(layout, "expand_colors", "Colors", 'COLOR')
if colors_section:
@@ -1134,12 +1115,6 @@ class TEXT_TEXTURE_PT_panel_3d(Panel):
if position_section:
draw_positioning_section(position_section, props)
# Text Fitting Section (collapsed by default)
text_fitting_section = draw_collapsible_header(layout, "expand_text_fitting", "Text Fitting", 'FULLSCREEN_ENTER')
if text_fitting_section:
pass
draw_text_fitting_section(text_fitting_section, props)
# Colors Section (collapsed by default)
colors_section = draw_collapsible_header(layout, "expand_colors", "Colors", 'COLOR')
if colors_section:
@@ -1352,12 +1327,6 @@ class TEXT_TEXTURE_PT_panel_properties(Panel):
if position_section:
draw_positioning_section(position_section, props)
# Text Fitting Section (collapsed by default)
text_fitting_section = draw_collapsible_header(layout, "expand_text_fitting", "Text Fitting", 'FULLSCREEN_ENTER')
if text_fitting_section:
pass
draw_text_fitting_section(text_fitting_section, props)
# Colors Section (collapsed by default)
colors_section = draw_collapsible_header(layout, "expand_colors", "Colors", 'COLOR')
if colors_section: