From ce98638e5541c3a3bd0cb6831f16b3e1f1b79735 Mon Sep 17 00:00:00 2001 From: Leonid Pershin Date: Mon, 27 Oct 2025 00:19:31 +0300 Subject: [PATCH] Refactor AIImages mod to replace ArtStyle enum with ArtStyleDef name for improved flexibility in prompt generation. Update UI components to reflect changes in art style selection and enhance scrolling functionality in the right column. Update AIImages.dll to incorporate the latest modifications. --- Assemblies/AIImages.dll | Bin 87552 -> 87040 bytes Defs/ArtStyleDefs.xml | 111 ++++++++++++++++ Defs/ImageSizePresetDefs.xml | 78 +++++++++++ Defs/README.md | 124 ++++++++++++++++++ Source/AIImages/Defs/ArtStyleDef.cs | 46 +++++++ Source/AIImages/Defs/ImageSizePresetDef.cs | 36 +++++ .../Models/StableDiffusionSettings.cs | 22 +--- .../Services/AdvancedPromptGenerator.cs | 106 +++++++-------- .../AIImages/Settings/AIImagesModSettings.cs | 10 +- Source/AIImages/UI/AIImagesSettingsUI.cs | 89 ++++++++----- Source/AIImages/Window_AIImage.cs | 110 ++++++++++++---- 11 files changed, 594 insertions(+), 138 deletions(-) create mode 100644 Defs/ArtStyleDefs.xml create mode 100644 Defs/ImageSizePresetDefs.xml create mode 100644 Defs/README.md create mode 100644 Source/AIImages/Defs/ArtStyleDef.cs create mode 100644 Source/AIImages/Defs/ImageSizePresetDef.cs diff --git a/Assemblies/AIImages.dll b/Assemblies/AIImages.dll index daa0bbbc27f385fa7dfb1cf677e27bfc59290eb4..569545abf8b814e21f81d7a5befa15f2e9de7c3f 100644 GIT binary patch literal 87040 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 literal 87552 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 z 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 V^9j=p)cz-amFEBd{l7 + + + + ArtStyle_None + + No predefined style - use only your custom prompts + + + + false + false + 0 + + + + ArtStyle_Realistic + + Photorealistic style with high detail + photorealistic, hyperrealistic, realistic photo, photography + cartoon, anime, painting, drawing, illustration + professional photography, 8k uhd, dslr, high quality, sharp focus + true + true + 10 + + + + ArtStyle_SemiRealistic + + Detailed illustration with realistic elements + semi-realistic, detailed illustration, realistic art + cartoon, anime, painting, drawing, illustration + professional photography, 8k uhd, dslr, high quality, sharp focus + true + true + 20 + + + + ArtStyle_Anime + + Japanese anime/manga style + anime style, manga style, anime character + realistic, photo, photography, 3d + anime masterpiece, high resolution, vibrant colors + true + true + 30 + + + + ArtStyle_ConceptArt + + Professional digital concept art + concept art, digital art, artstation, professional concept design + + trending on artstation, professional digital art + true + true + 40 + + + + ArtStyle_DigitalPainting + + Digital painting with brush strokes + digital painting, painterly, brush strokes, artistic + + + true + true + 50 + + + + ArtStyle_OilPainting + + Traditional oil painting style + oil painting, traditional painting, canvas, fine art + + + true + true + 60 + + + + ArtStyle_Sketch + + Pencil sketch or line art + pencil sketch, hand drawn, sketch art, line art + + + true + true + 70 + + + + ArtStyle_CellShaded + + Flat colors with toon shading + cell shaded, flat colors, toon shading, stylized + + + true + true + 80 + + diff --git a/Defs/ImageSizePresetDefs.xml b/Defs/ImageSizePresetDefs.xml new file mode 100644 index 0000000..1db4801 --- /dev/null +++ b/Defs/ImageSizePresetDefs.xml @@ -0,0 +1,78 @@ + + + + + Size_512x512 + + 512 + 512 + Square + 10 + + + Size_768x768 + + 768 + 768 + Square + 20 + + + Size_1024x1024 + + 1024 + 1024 + Square + 30 + + + + Size_512x768 + + 512 + 768 + Portrait + 40 + + + Size_768x1024 + + 768 + 1024 + Portrait + 50 + + + Size_896x1152 + + 896 + 1152 + Portrait + 60 + + + + Size_768x512 + + 768 + 512 + Landscape + 70 + + + Size_1024x768 + + 1024 + 768 + Landscape + 80 + + + Size_1152x896 + + 1152 + 896 + Landscape + 90 + + diff --git a/Defs/README.md b/Defs/README.md new file mode 100644 index 0000000..8567385 --- /dev/null +++ b/Defs/README.md @@ -0,0 +1,124 @@ +# AI Images - Defs Documentation + +This folder contains XML definition files that allow you to easily customize art styles and image size presets without recompiling the mod. + +## Art Style Definitions (ArtStyleDefs.xml) + +Art styles define how images should be generated, including prompts, quality tags, and negative prompts. + +### Structure + +```xml + + ArtStyle_MyStyle + + Description of the style + style keywords here + things to avoid + additional quality tags + true + true + 100 + +``` + +### Fields + +- **defName**: Unique identifier (must start with `ArtStyle_`) +- **label**: Display name shown in the UI +- **description**: Tooltip text explaining the style +- **positivePrompt**: Keywords added to the positive prompt (e.g., "photorealistic, 8k uhd") +- **negativePrompt**: Keywords added to the negative prompt (e.g., "cartoon, anime") +- **qualityTags**: Style-specific quality tags +- **addBaseQualityTags**: If true, adds "highly detailed, professional, masterpiece, best quality" +- **addBaseNegativePrompts**: If true, adds base negative prompts like "ugly, deformed, low quality" +- **sortOrder**: Determines order in the UI (lower numbers appear first) + +### Example: Custom Watercolor Style + +```xml + + ArtStyle_Watercolor + + Soft watercolor painting style + watercolor painting, soft colors, flowing paint, artistic + photograph, digital art, sharp edges + traditional art, paper texture + true + true + 65 + +``` + +## Image Size Presets (ImageSizePresetDefs.xml) + +Image size presets provide quick buttons for common image dimensions. + +### Structure + +```xml + + Size_1024x1024 + + 1024 + 1024 + Square + 30 + +``` + +### Fields + +- **defName**: Unique identifier (should start with `Size_`) +- **label**: Display text on the button +- **width**: Image width in pixels +- **height**: Image height in pixels +- **category**: Grouping category (Square, Portrait, Landscape, or custom) +- **sortOrder**: Determines button order (lower numbers appear first) + +### Example: Ultra-wide Size + +```xml + + Size_2048x1024 + + 2048 + 1024 + Ultrawide + 95 + +``` + +## Adding Custom Definitions + +1. **Create a new XML file** in the `Defs` folder +2. **Start with the XML header**: + ```xml + + + + + ``` +3. **Add your definitions** using the structures above +4. **Restart RimWorld** to load the new definitions + +## Tips + +- Keep `defName` unique to avoid conflicts +- Use descriptive `label` values for the UI +- Adjust `sortOrder` to organize items logically +- Test your prompts with different characters to ensure good results +- For art styles, experiment with different combinations of tags +- Consider using existing styles as templates + +## Compatibility + +These definitions are compatible with other mods. If another mod adds art styles or size presets, they will all appear together in the UI. + +## Troubleshooting + +- **Style doesn't appear**: Check that `defName` is unique and starts with `ArtStyle_` +- **Size preset missing**: Verify the XML syntax and that `defName` starts with `Size_` +- **Prompts not working**: Make sure prompts are in English and follow Stable Diffusion prompt syntax +- **XML errors**: Use an XML validator to check your file for syntax errors + diff --git a/Source/AIImages/Defs/ArtStyleDef.cs b/Source/AIImages/Defs/ArtStyleDef.cs new file mode 100644 index 0000000..5ec1c41 --- /dev/null +++ b/Source/AIImages/Defs/ArtStyleDef.cs @@ -0,0 +1,46 @@ +using System.Diagnostics.CodeAnalysis; +using Verse; + +namespace AIImages +{ + ///

+ /// Определение художественного стиля для генерации изображений + /// + [SuppressMessage( + "Major Code Smell", + "S1104:Fields should not have public accessibility", + Justification = "Required for RimWorld's Def system XML serialization" + )] + public class ArtStyleDef : Def + { + /// + /// Промпт для позитивного описания стиля + /// + public string positivePrompt = ""; + + /// + /// Промпт для негативного описания (что исключить) + /// + public string negativePrompt = ""; + + /// + /// Теги качества специфичные для этого стиля + /// + public string qualityTags = ""; + + /// + /// Добавлять ли базовые теги качества (highly detailed, professional, masterpiece, best quality) + /// + public bool addBaseQualityTags = true; + + /// + /// Добавлять ли базовые негативные промпты (ugly, deformed, low quality, etc.) + /// + public bool addBaseNegativePrompts = true; + + /// + /// Порядок сортировки в UI + /// + public int sortOrder = 100; + } +} diff --git a/Source/AIImages/Defs/ImageSizePresetDef.cs b/Source/AIImages/Defs/ImageSizePresetDef.cs new file mode 100644 index 0000000..c067c33 --- /dev/null +++ b/Source/AIImages/Defs/ImageSizePresetDef.cs @@ -0,0 +1,36 @@ +using System.Diagnostics.CodeAnalysis; +using Verse; + +namespace AIImages +{ + /// + /// Предустановка размера изображения + /// + [SuppressMessage( + "Major Code Smell", + "S1104:Fields should not have public accessibility", + Justification = "Required for RimWorld's Def system XML serialization" + )] + public class ImageSizePresetDef : Def + { + /// + /// Ширина изображения в пикселях + /// + public int width = 512; + + /// + /// Высота изображения в пикселях + /// + public int height = 512; + + /// + /// Категория размера (Square, Portrait, Landscape) + /// + public string category = "Square"; + + /// + /// Порядок сортировки в UI + /// + public int sortOrder = 100; + } +} diff --git a/Source/AIImages/Models/StableDiffusionSettings.cs b/Source/AIImages/Models/StableDiffusionSettings.cs index 90ffef8..f472b29 100644 --- a/Source/AIImages/Models/StableDiffusionSettings.cs +++ b/Source/AIImages/Models/StableDiffusionSettings.cs @@ -15,7 +15,7 @@ namespace AIImages.Models public string Scheduler { get; set; } public int Seed { get; set; } public string Model { get; set; } - public ArtStyle ArtStyle { get; set; } + public string ArtStyleDefName { get; set; } public StableDiffusionSettings() { @@ -25,27 +25,11 @@ namespace AIImages.Models Width = 512; Height = 768; Sampler = "Euler a"; - Scheduler = "Automatic"; + Scheduler = "Automatic"; // С большой буквы для API Seed = -1; // Случайный seed - ArtStyle = ArtStyle.Realistic; + ArtStyleDefName = "ArtStyle_Realistic"; PositivePrompt = ""; NegativePrompt = "ugly, deformed, low quality, blurry, bad anatomy, worst quality"; } } - - /// - /// Художественный стиль изображения - /// - public enum ArtStyle - { - None, // Без стиля - Realistic, - SemiRealistic, - Anime, - ConceptArt, - DigitalPainting, - OilPainting, - Sketch, - CellShaded, - } } diff --git a/Source/AIImages/Services/AdvancedPromptGenerator.cs b/Source/AIImages/Services/AdvancedPromptGenerator.cs index 8e3d90a..e2a717a 100644 --- a/Source/AIImages/Services/AdvancedPromptGenerator.cs +++ b/Source/AIImages/Services/AdvancedPromptGenerator.cs @@ -34,25 +34,6 @@ namespace AIImages.Services { "Pretty", "attractive features, pleasant appearance, charming" }, }; - private static readonly Dictionary ArtStylePrompts = new Dictionary< - ArtStyle, - string - > - { - { ArtStyle.None, "" }, - { ArtStyle.Realistic, "photorealistic, hyperrealistic, realistic photo, photography" }, - { ArtStyle.SemiRealistic, "semi-realistic, detailed illustration, realistic art" }, - { ArtStyle.Anime, "anime style, manga style, anime character" }, - { - ArtStyle.ConceptArt, - "concept art, digital art, artstation, professional concept design" - }, - { ArtStyle.DigitalPainting, "digital painting, painterly, brush strokes, artistic" }, - { ArtStyle.OilPainting, "oil painting, traditional painting, canvas, fine art" }, - { ArtStyle.Sketch, "pencil sketch, hand drawn, sketch art, line art" }, - { ArtStyle.CellShaded, "cell shaded, flat colors, toon shading, stylized" }, - }; - public string GeneratePositivePrompt( PawnAppearanceData appearanceData, StableDiffusionSettings settings @@ -66,17 +47,15 @@ namespace AIImages.Services // 1. Базовый пользовательский промпт (если указан) - идет первым if (!string.IsNullOrEmpty(settings.PositivePrompt)) { - prompt.Append(settings.PositivePrompt); + prompt.Append(settings.PositivePrompt.TrimEnd(',', ' ')); prompt.Append(", "); } // 2. Художественный стиль - if ( - ArtStylePrompts.TryGetValue(settings.ArtStyle, out string stylePrompt) - && !string.IsNullOrEmpty(stylePrompt) - ) + var styleDef = DefDatabase.GetNamedSilentFail(settings.ArtStyleDefName); + if (styleDef != null && !string.IsNullOrEmpty(styleDef.positivePrompt)) { - prompt.Append(stylePrompt); + prompt.Append(styleDef.positivePrompt); prompt.Append(", "); } @@ -127,7 +106,7 @@ namespace AIImages.Services } // 10. Качественные теги - prompt.Append(GetQualityTags(settings.ArtStyle)); + prompt.Append(GetQualityTags(settings.ArtStyleDefName)); return prompt.ToString().Trim().TrimEnd(','); } @@ -139,34 +118,38 @@ namespace AIImages.Services // 1. Пользовательский негативный промпт (если указан) - идет первым if (!string.IsNullOrEmpty(settings.NegativePrompt)) { - negativePrompt.Append(settings.NegativePrompt); - negativePrompt.Append(", "); + negativePrompt.Append(settings.NegativePrompt.TrimEnd(',', ' ')); + } + + // Получаем стиль из Def + var styleDef = DefDatabase.GetNamedSilentFail(settings.ArtStyleDefName); + if (styleDef == null || !styleDef.addBaseNegativePrompts) + { + // Для стилей без базовых негативов - используем только пользовательский промпт + return negativePrompt.ToString().Trim(); } // 2. Базовые негативные промпты + if (negativePrompt.Length > 0) + { + negativePrompt.Append(", "); + } + negativePrompt.Append( "ugly, deformed, low quality, blurry, bad anatomy, worst quality, " ); negativePrompt.Append( - "mutated, disfigured, bad proportions, extra limbs, missing limbs, " + "mutated, disfigured, bad proportions, extra limbs, missing limbs" ); - // 3. Специфичные для стиля негативы - switch (settings.ArtStyle) + // 3. Специфичные для стиля негативы из Def + if (!string.IsNullOrEmpty(styleDef.negativePrompt)) { - case ArtStyle.Realistic: - case ArtStyle.SemiRealistic: - negativePrompt.Append("cartoon, anime, painting, drawing, illustration, "); - break; - case ArtStyle.Anime: - negativePrompt.Append("realistic, photo, photography, 3d, "); - break; - case ArtStyle.None: - // Без дополнительных негативных промптов для стиля None - break; + negativePrompt.Append(", "); + negativePrompt.Append(styleDef.negativePrompt); } - return negativePrompt.ToString().Trim().TrimEnd(','); + return negativePrompt.ToString().Trim(); } public string GetFullPromptDescription( @@ -317,24 +300,33 @@ namespace AIImages.Services return apparelDesc.ToString(); } - private string GetQualityTags(ArtStyle style) + private string GetQualityTags(string styleDefName) { - var baseTags = "highly detailed, professional, masterpiece, best quality"; - - switch (style) + var styleDef = DefDatabase.GetNamedSilentFail(styleDefName); + if (styleDef == null) { - case ArtStyle.None: - return baseTags; - case ArtStyle.Realistic: - case ArtStyle.SemiRealistic: - return $"{baseTags}, professional photography, 8k uhd, dslr, high quality, sharp focus"; - case ArtStyle.Anime: - return $"{baseTags}, anime masterpiece, high resolution, vibrant colors"; - case ArtStyle.ConceptArt: - return $"{baseTags}, trending on artstation, professional digital art"; - default: - return baseTags; + return ""; } + + StringBuilder tags = new StringBuilder(); + + // Базовые теги качества + if (styleDef.addBaseQualityTags) + { + tags.Append("highly detailed, professional, masterpiece, best quality"); + } + + // Специфичные для стиля теги качества + if (!string.IsNullOrEmpty(styleDef.qualityTags)) + { + if (tags.Length > 0) + { + tags.Append(", "); + } + tags.Append(styleDef.qualityTags); + } + + return tags.ToString(); } /// diff --git a/Source/AIImages/Settings/AIImagesModSettings.cs b/Source/AIImages/Settings/AIImagesModSettings.cs index b9600e6..6c66461 100644 --- a/Source/AIImages/Settings/AIImagesModSettings.cs +++ b/Source/AIImages/Settings/AIImagesModSettings.cs @@ -14,7 +14,7 @@ namespace AIImages.Settings public string apiEndpoint = "http://127.0.0.1:7860"; public string selectedModel = ""; public string selectedSampler = "Euler a"; - public string selectedScheduler = "Automatic"; + public string selectedScheduler = "Automatic"; // С большой буквы для API // Кэшированные списки из API (не сохраняются) [Unsaved] @@ -38,8 +38,8 @@ namespace AIImages.Settings public string baseNegativePrompt = "ugly, deformed, low quality, blurry, bad anatomy, worst quality"; - // Художественный стиль - public ArtStyle artStyle = ArtStyle.Realistic; + // Художественный стиль (defName) + public string artStyleDefName = "ArtStyle_Realistic"; // Путь для сохранения public string savePath = "AIImages/Generated"; @@ -70,7 +70,7 @@ namespace AIImages.Settings "ugly, deformed, low quality, blurry, bad anatomy, worst quality" ); - Scribe_Values.Look(ref artStyle, "artStyle", ArtStyle.Realistic); + Scribe_Values.Look(ref artStyleDefName, "artStyleDefName", "ArtStyle_Realistic"); Scribe_Values.Look(ref savePath, "savePath", "AIImages/Generated"); @@ -97,7 +97,7 @@ namespace AIImages.Settings Scheduler = selectedScheduler, Seed = seed, Model = selectedModel, - ArtStyle = artStyle, + ArtStyleDefName = artStyleDefName, PositivePrompt = basePositivePrompt, NegativePrompt = baseNegativePrompt, }; diff --git a/Source/AIImages/UI/AIImagesSettingsUI.cs b/Source/AIImages/UI/AIImagesSettingsUI.cs index 1d4be27..0bf5e18 100644 --- a/Source/AIImages/UI/AIImagesSettingsUI.cs +++ b/Source/AIImages/UI/AIImagesSettingsUI.cs @@ -174,21 +174,37 @@ namespace AIImages AIImagesModSettings settings ) { + // Получаем текущий стиль + var currentStyleDef = DefDatabase.GetNamedSilentFail( + settings.artStyleDefName + ); + string currentStyleLabel = currentStyleDef?.label ?? settings.artStyleDefName; + if ( listingStandard.ButtonTextLabeled( "AIImages.Settings.ArtStyle".Translate(), - settings.artStyle.ToString() + currentStyleLabel ) ) { List styleOptions = new List(); - foreach (ArtStyle style in Enum.GetValues(typeof(ArtStyle))) + + // Получаем все стили из DefDatabase и сортируем по sortOrder + var allStyles = DefDatabase.AllDefs.OrderBy(s => s.sortOrder); + + foreach (var styleDef in allStyles) { - ArtStyle localStyle = style; + string localDefName = styleDef.defName; + string localLabel = styleDef.label; + styleOptions.Add( - new FloatMenuOption(style.ToString(), () => settings.artStyle = localStyle) + new FloatMenuOption( + localLabel, + () => settings.artStyleDefName = localDefName + ) ); } + Find.WindowStack.Add(new FloatMenu(styleOptions)); } } @@ -220,34 +236,47 @@ namespace AIImages AIImagesModSettings settings ) { - listingStandard.Gap(4f); - Rect presetRect1 = listingStandard.GetRect(30f); - DrawPresetButton(presetRect1, 0f, "512x512", 512, 512, settings); - DrawPresetButton(presetRect1, 85f, "512x768", 512, 768, settings); - DrawPresetButton(presetRect1, 170f, "768x768", 768, 768, settings); + // Получаем все предустановки размеров из DefDatabase + var allPresets = DefDatabase + .AllDefs.OrderBy(p => p.sortOrder) + .ToList(); - listingStandard.Gap(4f); - Rect presetRect2 = listingStandard.GetRect(30f); - DrawPresetButton(presetRect2, 0f, "896x1152", 896, 1152, settings, 90f); - DrawPresetButton(presetRect2, 95f, "1024x1024", 1024, 1024, settings, 90f); - } - - private static void DrawPresetButton( - Rect rect, - float xOffset, - string label, - int width, - int height, - AIImagesModSettings settings, - float buttonWidth = 80f - ) - { - if (Widgets.ButtonText(new Rect(rect.x + xOffset, rect.y, buttonWidth, 30f), label)) + if (!allPresets.Any()) { - settings.width = width; - settings.height = height; - widthBuffer = width.ToString(); - heightBuffer = height.ToString(); + return; + } + + listingStandard.Gap(4f); + + // Разбиваем на строки по 3 кнопки + int buttonsPerRow = 3; + float buttonWidth = 80f; + float spacing = 5f; + + for (int i = 0; i < allPresets.Count; i += buttonsPerRow) + { + Rect rowRect = listingStandard.GetRect(30f); + + for (int j = 0; j < buttonsPerRow && (i + j) < allPresets.Count; j++) + { + var preset = allPresets[i + j]; + float xOffset = j * (buttonWidth + spacing); + + if ( + Widgets.ButtonText( + new Rect(rowRect.x + xOffset, rowRect.y, buttonWidth, 30f), + preset.label + ) + ) + { + settings.width = preset.width; + settings.height = preset.height; + widthBuffer = preset.width.ToString(); + heightBuffer = preset.height.ToString(); + } + } + + listingStandard.Gap(4f); } } diff --git a/Source/AIImages/Window_AIImage.cs b/Source/AIImages/Window_AIImage.cs index 011a3ac..af067fa 100644 --- a/Source/AIImages/Window_AIImage.cs +++ b/Source/AIImages/Window_AIImage.cs @@ -70,6 +70,7 @@ namespace AIImages public override Vector2 InitialSize => new Vector2(900f, 800f); private Vector2 scrollPosition = Vector2.zero; + private Vector2 rightColumnScrollPosition = Vector2.zero; private Vector2 promptScrollPosition = Vector2.zero; private Vector2 negativePromptScrollPosition = Vector2.zero; private float copiedMessageTime = 0f; @@ -440,17 +441,23 @@ namespace AIImages private void DrawRightColumn(Rect rect) { + // Рассчитываем высоту контента для скролла + float contentHeight = CalculateRightColumnHeight(rect); + Rect scrollViewRect = new Rect(0f, 0f, rect.width - 20f, contentHeight); + + Widgets.BeginScrollView(rect, ref rightColumnScrollPosition, scrollViewRect); + float curY = 0f; - curY = DrawImagePreview(rect, curY); - curY = DrawGenerationStatus(rect, curY); - curY = DrawProgressBar(rect, curY); - curY = DrawGenerationButton(rect, curY); + curY = DrawImagePreview(scrollViewRect, curY); + curY = DrawGenerationStatus(scrollViewRect, curY); + curY = DrawProgressBar(scrollViewRect, curY); + curY = DrawGenerationButton(scrollViewRect, curY); // Позитивный промпт секция Text.Font = GameFont.Medium; Widgets.Label( - new Rect(rect.x, rect.y + curY, rect.width, 30f), + new Rect(0f, curY, scrollViewRect.width, 30f), "AIImages.Prompt.PositiveTitle".Translate() ); curY += 35f; @@ -464,10 +471,18 @@ namespace AIImages // Фиксированная высота для области промпта float promptBoxHeight = 100f; - float actualPositiveHeight = Text.CalcHeight(positivePrompt, rect.width - 20f); + float actualPositiveHeight = Text.CalcHeight( + positivePrompt, + scrollViewRect.width - 20f + ); - Rect positiveOuterRect = new Rect(rect.x, rect.y + curY, rect.width, promptBoxHeight); - Rect positiveViewRect = new Rect(0f, 0f, rect.width - 20f, actualPositiveHeight); + Rect positiveOuterRect = new Rect(0f, curY, scrollViewRect.width, promptBoxHeight); + Rect positiveViewRect = new Rect( + 0f, + 0f, + scrollViewRect.width - 20f, + actualPositiveHeight + ); // Рисуем фон Widgets.DrawBoxSolid(positiveOuterRect, new Color(0.1f, 0.3f, 0.1f, 0.5f)); @@ -489,7 +504,7 @@ namespace AIImages // Негативный промпт секция Text.Font = GameFont.Medium; Widgets.Label( - new Rect(rect.x, rect.y + curY, rect.width, 30f), + new Rect(0f, curY, scrollViewRect.width, 30f), "AIImages.Prompt.NegativeTitle".Translate() ); curY += 35f; @@ -500,10 +515,18 @@ namespace AIImages generationSettings ); - float actualNegativeHeight = Text.CalcHeight(negativePrompt, rect.width - 20f); + float actualNegativeHeight = Text.CalcHeight( + negativePrompt, + scrollViewRect.width - 20f + ); - Rect negativeOuterRect = new Rect(rect.x, rect.y + curY, rect.width, promptBoxHeight); - Rect negativeViewRect = new Rect(0f, 0f, rect.width - 20f, actualNegativeHeight); + Rect negativeOuterRect = new Rect(0f, curY, scrollViewRect.width, promptBoxHeight); + Rect negativeViewRect = new Rect( + 0f, + 0f, + scrollViewRect.width - 20f, + actualNegativeHeight + ); // Рисуем фон (красноватый для негативного) Widgets.DrawBoxSolid(negativeOuterRect, new Color(0.3f, 0.1f, 0.1f, 0.5f)); @@ -525,7 +548,7 @@ namespace AIImages // Кнопки копирования промптов if ( Widgets.ButtonText( - new Rect(rect.x, rect.y + curY, rect.width / 2f - 5f, 30f), + new Rect(0f, curY, scrollViewRect.width / 2f - 5f, 30f), "AIImages.Prompt.CopyPositive".Translate() ) ) @@ -541,9 +564,9 @@ namespace AIImages if ( Widgets.ButtonText( new Rect( - rect.x + rect.width / 2f + 5f, - rect.y + curY, - rect.width / 2f - 5f, + scrollViewRect.width / 2f + 5f, + curY, + scrollViewRect.width / 2f - 5f, 30f ), "AIImages.Prompt.CopyNegative".Translate() @@ -561,7 +584,7 @@ namespace AIImages // Кнопка обновления данных if ( Widgets.ButtonText( - new Rect(rect.x, rect.y + curY, rect.width, 30f), + new Rect(0f, curY, scrollViewRect.width, 30f), "AIImages.Window.Refresh".Translate() ) ) @@ -575,11 +598,13 @@ namespace AIImages curY += 35f; GUI.color = new Color(0f, 1f, 0f, copiedMessageTime / 2f); Widgets.Label( - new Rect(rect.x, rect.y + curY, rect.width, 25f), + new Rect(0f, curY, scrollViewRect.width, 25f), "AIImages.Prompt.Copied".Translate() ); GUI.color = Color.white; } + + Widgets.EndScrollView(); } private float CalculateContentHeight() @@ -613,15 +638,46 @@ namespace AIImages // Дополнительный отступ height += 50f; - // Позитивный промпт заголовок - height += 35f; - // Позитивный промпт контент - height += 100f + 10f; + return height; + } - // Негативный промпт заголовок - height += 35f; - // Негативный промпт контент - height += 100f + 10f; + private float CalculateRightColumnHeight(Rect rect) + { + float height = 0f; + float contentWidth = rect.width - 20f; + + // Превью изображения + if (generatedImage != null) + { + height += 200f + 10f; + } + else if (!isGenerating) + { + height += 100f + 10f; + } + + // Статус генерации + if (!string.IsNullOrEmpty(generationStatus)) + { + height += 30f; + } + + // Прогресс бар + if (isGenerating && generationProgress > 0.0) + { + height += 30f; + } + + // Кнопка генерации + height += 40f; + + // Позитивный промпт + height += 35f; // Заголовок + height += 100f + 10f; // Бокс + + // Негативный промпт + height += 35f; // Заголовок + height += 100f + 10f; // Бокс // Кнопки копирования height += 35f; @@ -635,7 +691,7 @@ namespace AIImages height += 30f; } - return height; + return height + 50f; // Дополнительный отступ } private float DrawImagePreview(Rect rect, float curY)