""" Text Texture Generator - Property Groups This module contains all property group definitions for the text texture generator addon. Extracted property definitions include: - TEXT_TEXTURE_ImageOverlay: Single image overlay configuration - TEXT_TEXTURE_Preset: Preset storage metadata - TEXT_TEXTURE_Properties: Main property group with all texture generation settings """ import bpy from bpy.types import PropertyGroup from bpy.props import ( StringProperty, IntProperty, FloatVectorProperty, FloatProperty, BoolProperty, EnumProperty, CollectionProperty, PointerProperty ) import os # Import update functions from the main module (will need to be adjusted during integration) def update_live_preview(self, context): """Update preview when properties change""" if not hasattr(context, 'scene'): return props = context.scene.text_texture_props print(f"DEBUG: update_live_preview called, is_updating: {props.is_updating}") # Always update preview unless already updating if not props.is_updating: print("DEBUG: Triggering preview generation from property update") # Use a timer to debounce rapid property changes for better performance if hasattr(update_live_preview, '_timer'): bpy.app.timers.unregister(update_live_preview._timer) def delayed_preview(): # Import generate_preview function (will need to be adjusted during integration) try: from . import generate_preview generate_preview(context) except ImportError: # Fallback during development print("DEBUG: generate_preview not available during extraction") return None # Stop timer update_live_preview._timer = delayed_preview bpy.app.timers.register(delayed_preview, first_interval=0.1) def get_font_enum_items(self, context): """Dynamic enum items for font selection""" items = [("default", "Default Font", "Use system default font", 0)] if not hasattr(get_font_enum_items, 'cached_fonts'): # Import get_system_fonts function (will need to be adjusted during integration) try: from ..utils.system import get_system_fonts get_font_enum_items.cached_fonts = get_system_fonts() except ImportError: # Fallback during development get_font_enum_items.cached_fonts = {} fonts = get_font_enum_items.cached_fonts for i, (font_name, font_path) in enumerate(sorted(fonts.items())[:50]): items.append((font_path, font_name, f"Font: {font_name}", i + 1)) return items class TEXT_TEXTURE_ImageOverlay(PropertyGroup): """Single image overlay item""" name: StringProperty( name="Image Name", description="Name identifier for this image overlay", default="Overlay", update=update_live_preview ) image_path: StringProperty( name="Image File", description="Path to image file", subtype='FILE_PATH', default="", update=update_live_preview ) x_position: FloatProperty( name="X Position", description="X position (0.0 = left, 1.0 = right)", default=0.5, min=0.0, max=1.0, update=update_live_preview ) y_position: FloatProperty( name="Y Position", description="Y position (0.0 = bottom, 1.0 = top)", default=0.5, min=0.0, max=1.0, update=update_live_preview ) scale: FloatProperty( name="Scale", description="Scale of the image", default=1.0, min=0.1, max=5.0, update=update_live_preview ) rotation: FloatProperty( name="Rotation", description="Rotation in degrees", default=0.0, min=-360.0, max=360.0, update=update_live_preview ) z_index: IntProperty( name="Z-Index", description="Layer order (0=text level, -1=below text, 1+=above text)", default=1, min=-10, max=10, update=update_live_preview ) positioning_mode: EnumProperty( name="Positioning Mode", description="How the image overlay is positioned relative to the text", items=[ ('ABSOLUTE', "Absolute", "Position overlay at absolute coordinates (legacy mode)"), ('APPEND', "Append", "Position overlay after the text content"), ('PREPEND', "Prepend", "Position overlay before the text content") ], default='ABSOLUTE', update=update_live_preview ) text_spacing: FloatProperty( name="Text Spacing (%)", description="Spacing between text and image as percentage of canvas width (0-100%)", default=10.0, min=0.0, max=100.0, subtype='PERCENTAGE', update=update_live_preview ) image_spacing: FloatProperty( name="Image Spacing (%)", description="Spacing between consecutive images as percentage of canvas width (0-100%)", default=5.0, min=0.0, max=100.0, subtype='PERCENTAGE', update=update_live_preview ) enabled: BoolProperty( name="Enabled", description="Enable this image overlay", default=True, update=update_live_preview ) class TEXT_TEXTURE_Preset(PropertyGroup): """Single preset item""" name: StringProperty( name="Preset Name", description="Name of the preset", default="New Preset" ) source: EnumProperty( name="Source", description="Where this preset is stored", items=[ ('BLEND_FILE', 'Blend File', 'Preset stored in the blend file (travels with the file)'), ('PERSISTENT_FILE', 'Persistent File', 'Preset stored in persistent location (survives addon updates)'), ('LOCAL_FILE', 'Local File', 'Preset stored locally (legacy system)') ], default='BLEND_FILE' ) class TEXT_TEXTURE_Properties(PropertyGroup): """Properties for text texture generation""" is_updating: BoolProperty(default=False) preview_image: PointerProperty( type=bpy.types.Image, name="Preview Image" ) # Collapsible section expand/collapse states expand_multiline: BoolProperty( name="Multiline Text", description="Show/hide Multiline Text section", default=False ) expand_image_overlays: BoolProperty( name="Image Overlays", description="Show/hide Image Overlays section", default=False ) expand_positioning: BoolProperty( name="Positioning & Layout", description="Show/hide Positioning & Layout section", default=False ) expand_font_settings: BoolProperty( name="Font Settings", description="Show/hide Font Settings section", default=False ) expand_preview_options: BoolProperty( name="Preview Options", description="Show/hide Preview Options section", default=False ) expand_presets: BoolProperty( name="Presets", description="Show/hide Presets section", default=False ) expand_colors: BoolProperty( name="Colors", description="Show/hide Colors section", default=False ) text: StringProperty( name="Text", description="Text to render as texture", default="", maxlen=1024, update=update_live_preview ) # Prepend/Append Text Properties prepend_text: StringProperty( name="Prepend Text", description="Text to prepend before main text", default="", maxlen=512, update=update_live_preview ) append_text: StringProperty( name="Append Text", description="Text to append after main text", default="", maxlen=512, update=update_live_preview ) prepend_margin: FloatProperty( name="Prepend Margin", description="Margin between prepend text and main text as percentage of font size", default=50.0, min=0.0, max=200.0, precision=1, update=update_live_preview ) append_margin: FloatProperty( name="Append Margin", description="Margin between main text and append text as percentage of font size", default=50.0, min=0.0, max=200.0, precision=1, update=update_live_preview ) prepend_append_layout: EnumProperty( name="Layout", description="Layout arrangement for prepend/main/append text", items=[ ('HORIZONTAL', 'Horizontal', 'Arrange text horizontally: [prepend] [main] [append]'), ('VERTICAL', 'Vertical', 'Arrange text vertically: prepend above, main center, append below'), ], default='HORIZONTAL', update=update_live_preview ) texture_width: IntProperty( name="Width", description="Texture width in pixels", default=1024, min=64, max=4096, update=update_live_preview ) texture_height: IntProperty( name="Height", description="Texture height in pixels", default=1024, min=64, max=4096, update=update_live_preview ) font_size: IntProperty( name="Font Size", description="Font size in pixels", default=96, min=8, max=500, update=update_live_preview ) padding: IntProperty( name="Padding", description="Padding around text in pixels", default=20, min=0, max=200, update=update_live_preview ) text_color: FloatVectorProperty( name="Text Color", description="Color of the text", subtype='COLOR', default=(1.0, 1.0, 1.0, 1.0), size=4, min=0.0, max=1.0, update=update_live_preview ) background_transparent: BoolProperty( name="Transparent Background", description="Use transparent background", default=True, update=update_live_preview ) background_color: FloatVectorProperty( name="Background Color", description="Background color (when not transparent)", subtype='COLOR', default=(0.0, 0.0, 0.0, 1.0), size=4, min=0.0, max=1.0, update=update_live_preview ) font_path: EnumProperty( name="Font", description="Font to use for text rendering", items=get_font_enum_items, update=update_live_preview ) custom_font_path: StringProperty( name="Custom Font File", description="Path to custom font file (.ttf, .otf)", subtype='FILE_PATH', default="", update=update_live_preview ) use_custom_font: BoolProperty( name="Use Custom Font", description="Use custom font file instead of system fonts", default=False, update=update_live_preview ) text_align: EnumProperty( name="Alignment", description="Text alignment", items=[ ('left', 'Left', 'Align text to the left'), ('center', 'Center', 'Center text'), ('right', 'Right', 'Align text to the right'), ], default='center', update=update_live_preview ) # ============================================================================ # ENHANCED POSITIONING & ALIGNMENT PROPERTIES # ============================================================================ # 9-point anchor system anchor_point: EnumProperty( name="Anchor Point", description="Text anchor position on canvas", items=[ ('TOP_LEFT', 'Top Left', 'Position text from top-left corner'), ('TOP_CENTER', 'Top Center', 'Position text from top center'), ('TOP_RIGHT', 'Top Right', 'Position text from top-right corner'), ('MIDDLE_LEFT', 'Middle Left', 'Position text from middle-left'), ('MIDDLE_CENTER', 'Middle Center', 'Position text from center (default)'), ('MIDDLE_RIGHT', 'Middle Right', 'Position text from middle-right'), ('BOTTOM_LEFT', 'Bottom Left', 'Position text from bottom-left corner'), ('BOTTOM_CENTER', 'Bottom Center', 'Position text from bottom center'), ('BOTTOM_RIGHT', 'Bottom Right', 'Position text from bottom-right corner'), ], default='MIDDLE_CENTER', update=update_live_preview ) # Position mode toggle position_mode: EnumProperty( name="Position Mode", description="Choose between preset anchor positions or manual positioning", items=[ ('PRESET', 'Preset', 'Use anchor points with margins and offsets'), ('MANUAL', 'Manual', 'Manually specify X,Y coordinates'), ], default='PRESET', update=update_live_preview ) # Percentage-based margins (0-50%) margin_x: FloatProperty( name="X Margin", description="Horizontal margin from edge as percentage (0-50%)", subtype='PERCENTAGE', default=0.0, min=0.0, max=50.0, precision=1, update=update_live_preview ) margin_y: FloatProperty( name="Y Margin", description="Vertical margin from edge as percentage (0-50%)", subtype='PERCENTAGE', default=0.0, min=0.0, max=50.0, precision=1, update=update_live_preview ) # Link margins option margins_linked: BoolProperty( name="Link Margins", description="Keep X and Y margins synchronized", default=False, update=update_live_preview ) # Pixel offset fine-tuning (-200 to +200px) offset_x: IntProperty( name="X Offset", description="Fine-tune X position in pixels (-200 to +200)", default=0, min=-200, max=200, update=update_live_preview ) offset_y: IntProperty( name="Y Offset", description="Fine-tune Y position in pixels (-200 to +200)", default=0, min=-200, max=200, update=update_live_preview ) # Manual positioning properties manual_position_x: FloatProperty( name="Manual X", description="Manual X position as percentage (0-100%)", subtype='PERCENTAGE', default=50.0, min=0.0, max=100.0, precision=1, update=update_live_preview ) manual_position_y: FloatProperty( name="Manual Y", description="Manual Y position as percentage (0-100%)", subtype='PERCENTAGE', default=50.0, min=0.0, max=100.0, precision=1, update=update_live_preview ) manual_position_unit: EnumProperty( name="Position Unit", description="Units for manual positioning", items=[ ('PERCENTAGE', 'Percentage', 'Position as percentage of canvas'), ('PIXELS', 'Pixels', 'Position in absolute pixels'), ], default='PERCENTAGE', update=update_live_preview ) # Canvas constraint option constrain_to_canvas: BoolProperty( name="Constrain to Canvas", description="Keep text within canvas bounds", default=True, update=update_live_preview ) # Visual feedback options show_position_guides: BoolProperty( name="Show Position Guides", description="Display positioning guide lines in preview", default=False, update=update_live_preview ) show_text_bounds: BoolProperty( name="Show Text Bounds", description="Display text bounding box in preview", default=False, update=update_live_preview ) show_canvas_grid: BoolProperty( name="Show Canvas Grid", description="Display alignment grid overlay in preview", default=False, update=update_live_preview ) grid_density: IntProperty( name="Grid Density", description="Number of grid divisions (4-16)", default=8, min=4, max=16, update=update_live_preview ) # Removed live_preview_enabled - preview is always on preview_size: IntProperty( name="Preview Size", description="Size of the preview image (does not affect final output)", default=512, min=128, max=2048, update=update_live_preview ) preview_zoom_level: FloatProperty( name="Zoom", description="Zoom level for preview", default=1.0, min=0.5, max=4.0, update=update_live_preview ) # Preview background options preview_bg_type: EnumProperty( name="Preview Background", description="Background type for preview display", items=[ ('transparent', 'Transparent', 'Transparent checkerboard pattern'), ('color', 'Solid Color', 'Use a solid color background'), ('gradient', 'Gradient', 'Use a gradient background'), ], default='transparent', update=update_live_preview ) preview_bg_color: FloatVectorProperty( name="Preview BG Color", description="Background color for preview", subtype='COLOR', default=(0.2, 0.2, 0.2, 1.0), size=4, min=0.0, max=1.0, update=update_live_preview ) preview_bg_color2: FloatVectorProperty( name="Preview BG Color 2", description="Second color for gradient background", subtype='COLOR', default=(0.4, 0.4, 0.4, 1.0), size=4, min=0.0, max=1.0, update=update_live_preview ) # Image overlays image_overlays: CollectionProperty(type=TEXT_TEXTURE_ImageOverlay) active_overlay_index: IntProperty(default=0) # Presets presets: CollectionProperty(type=TEXT_TEXTURE_Preset) active_preset_index: IntProperty(default=0) new_preset_name: StringProperty( name="Preset Name", description="Name for new preset (Press Enter to save)", default="New Preset" ) # Property to track when user wants to save with Enter preset_save_requested: BoolProperty( name="Save Requested", description="Internal flag for Enter key save requests", default=False ) # ============================================================================ # SHADER GENERATION PROPERTIES # ============================================================================ expand_shader: BoolProperty( name="Shader Settings", description="Show/hide Shader Settings section", default=False ) shader_type: EnumProperty( name="Shader Type", description="Type of shader to generate", items=[ ('PRINCIPLED', 'Principled BSDF', 'Standard PBR shader with text texture'), ('EMISSION', 'Emission', 'Emissive shader for glowing text effects'), ('TRANSPARENT', 'Transparent', 'Transparent shader with alpha blending'), ], default='PRINCIPLED' ) shader_connection: EnumProperty( name="Texture Connection", description="How to connect the texture to the shader", items=[ ('BASE_COLOR', 'Base Color', 'Connect texture to base color input'), ('EMISSION', 'Emission', 'Connect texture to emission input'), ('ALPHA', 'Alpha', 'Connect texture alpha to transparency'), ], default='BASE_COLOR' ) use_alpha: BoolProperty( name="Use Alpha Channel", description="Use texture alpha channel for transparency", default=True ) emission_strength: FloatProperty( name="Emission Strength", description="Strength of emission shader", default=1.0, min=0.0, max=10.0 ) auto_assign_material: BoolProperty( name="Auto-Assign Material", description="Automatically assign generated material to active object", default=True ) custom_material_name: StringProperty( name="Custom Material Name", description="Custom name for the generated material (leave empty to use text-based naming)", default="", maxlen=128 ) disable_shadows: BoolProperty( name="Disable Shadows", description="Make material not cast shadows using light path", default=False ) disable_reflections: BoolProperty( name="Disable Reflections", description="Make material not appear in reflections using light path", default=False ) disable_backfacing: BoolProperty( name="Disable Backfacing", description="Make material not render on backfacing geometry using light path", default=False ) # ============================================================================ # NORMAL MAP GENERATION PROPERTIES # ============================================================================ expand_normal_maps: BoolProperty( name="Normal Maps", description="Show/hide Normal Maps section", default=False ) generate_normal_map: BoolProperty( name="Generate Normal Map", description="Automatically generate normal map from text alpha channel", default=False, update=update_live_preview ) normal_map_strength: FloatProperty( name="Normal Strength", description="Intensity of the normal map effect (higher = more pronounced)", default=1.0, min=0.1, max=5.0, precision=2, update=update_live_preview ) normal_map_blur_radius: FloatProperty( name="Blur Radius", description="Blur radius for smoothing normal map (0 = no blur)", default=1.0, min=0.0, max=10.0, precision=1, update=update_live_preview ) normal_map_invert: BoolProperty( name="Invert Normal Map", description="Invert the normal map for different height effects (emboss vs deboss)", default=False, update=update_live_preview ) # ============================================================================ # TEXT FITTING PROPERTIES # ============================================================================ expand_text_fitting: BoolProperty( name="Text Fitting", description="Show/hide Text Fitting section", default=False ) enable_text_fitting: BoolProperty( name="Enable Text Fitting", description="Automatically adjust text size to fit within the canvas dimensions", default=False, update=update_live_preview ) text_fitting_mode: EnumProperty( name="Fitting Mode", description="How to fit text within the canvas", items=[ ('FIT_WIDTH', 'Fit Width', 'Scale text to fit canvas width'), ('FIT_HEIGHT', 'Fit Height', 'Scale text to fit canvas height'), ('FIT_BOTH', 'Fit Both', 'Scale text to fit both width and height (may cause distortion)'), ('FIT_CONTAIN', 'Fit Contain', 'Scale text to fit entirely within canvas (preserves aspect ratio)'), ], default='FIT_CONTAIN', update=update_live_preview ) text_fitting_margin: FloatProperty( name="Fitting Margin", description="Margin to leave around text when fitting (as percentage of canvas)", default=10.0, min=0.0, max=50.0, precision=1, subtype='PERCENTAGE', update=update_live_preview ) min_font_size: IntProperty( name="Minimum Font Size", description="Minimum font size when fitting text (prevents text from becoming too small)", default=8, min=4, max=200, update=update_live_preview ) max_font_size: IntProperty( name="Maximum Font Size", description="Maximum font size when fitting text (prevents text from becoming too large)", default=500, min=20, max=1000, update=update_live_preview ) # ============================================================================ # MULTILINE TEXT PROPERTIES # ============================================================================ enable_multiline: BoolProperty( name="Enable Multiline", description="Enable multiline text rendering", default=False, update=update_live_preview ) line_height: FloatProperty( name="Line Height", description="Line height multiplier (1.0 = normal, 1.5 = 150% spacing)", default=1.2, min=0.1, max=5.0, step=0.1, precision=2, update=update_live_preview ) text_alignment: EnumProperty( name="Text Alignment", description="Text alignment for multiline text", items=[ ('LEFT', "Left", "Left align text"), ('CENTER', "Center", "Center align text"), ('RIGHT', "Right", "Right align text") ], default='CENTER', update=update_live_preview ) auto_wrap: BoolProperty( name="Auto Wrap", description="Automatically wrap text to fit texture width", default=True, update=update_live_preview ) wrap_width: IntProperty( name="Wrap Width", description="Maximum width in pixels before text wraps (0 = use texture width)", default=0, min=0, max=10000, update=update_live_preview ) max_lines: IntProperty( name="Max Lines", description="Maximum number of lines (0 = unlimited)", default=0, min=0, max=100, update=update_live_preview ) line_spacing_pixels: IntProperty( name="Line Spacing (px)", description="Additional spacing between lines in pixels", default=0, min=-50, max=200, update=update_live_preview ) # ============================================================================ # STROKE SYSTEM PROPERTIES # ============================================================================ expand_stroke: BoolProperty( name="Stroke & Outlines", description="Show/hide Stroke & Outlines section", default=False ) enable_stroke: BoolProperty( name="Enable Stroke", description="Enable text stroke/outline rendering", default=False, update=update_live_preview ) stroke_width: IntProperty( name="Stroke Width", description="Width of the text stroke in pixels", default=2, min=0, max=20, update=update_live_preview ) stroke_position: EnumProperty( name="Stroke Position", description="How the stroke is positioned relative to the text", items=[ ('OUTER', 'Outer', 'Stroke outside text (expands text bounds)'), ('INNER', 'Inner', 'Stroke inside text (shrinks text)'), ('CENTER', 'Center', 'Stroke centered on text edge'), ], default='OUTER', update=update_live_preview ) stroke_color: FloatVectorProperty( name="Stroke Color", description="Color of the text stroke", subtype='COLOR', default=(0.0, 0.0, 0.0, 1.0), size=4, min=0.0, max=1.0, update=update_live_preview ) # ============================================================================ # SHADOW/GLOW SYSTEM PROPERTIES # ============================================================================ expand_shadow_glow: BoolProperty( name="Shadow & Glow Effects", description="Show/hide Shadow & Glow Effects section", default=False ) enable_shadow: BoolProperty( name="Enable Drop Shadow", description="Enable drop shadow effect", default=False, update=update_live_preview ) shadow_offset_x: FloatProperty( name="Shadow Offset X", description="Horizontal offset for drop shadow", default=8.0, min=-100.0, max=100.0, step=0.1, precision=1, update=update_live_preview ) shadow_offset_y: FloatProperty( name="Shadow Offset Y", description="Vertical offset for drop shadow", default=8.0, min=-100.0, max=100.0, step=0.1, precision=1, update=update_live_preview ) shadow_blur: FloatProperty( name="Shadow Blur", description="Blur radius for drop shadow", default=6.0, min=0.0, max=50.0, step=0.1, precision=1, update=update_live_preview ) shadow_color: FloatVectorProperty( name="Shadow Color", description="Color of drop shadow", subtype='COLOR', default=(0.0, 0.0, 0.0, 1.0), size=4, min=0.0, max=1.0, update=update_live_preview ) shadow_spread: FloatProperty( name="Shadow Spread", description="Controls how far the shadow extends from the text (multiplies shadow offset)", default=1.0, min=0.0, max=3.0, precision=2, step=0.1, update=update_live_preview ) enable_glow: BoolProperty( name="Enable Glow", description="Enable glow effect", default=False, update=update_live_preview ) glow_blur: FloatProperty( name="Glow Blur", description="Blur radius for glow effect", default=10.0, min=0.0, max=50.0, step=0.1, precision=1, update=update_live_preview ) glow_color: FloatVectorProperty( name="Glow Color", description="Color of glow effect", subtype='COLOR', default=(1.0, 1.0, 1.0, 0.8), size=4, min=0.0, max=1.0, update=update_live_preview ) # ============================================================================ # BLUR PROPERTIES # ============================================================================ expand_blur: BoolProperty( name="Blur Effects", description="Show/hide Blur Effects section", default=False ) enable_blur: BoolProperty( name="Enable Blur", description="Enable blur effect on main text content", default=False, update=update_live_preview ) blur_radius: FloatProperty( name="Blur Radius", description="Blur radius for text content (0-50 pixels)", default=2.0, min=0.0, max=50.0, step=0.1, precision=1, update=update_live_preview )