Changeset - 867b2b613117
[Not reviewed]
default
0 3 0
Jason Maltzen - 3 years ago 2021-08-16 07:53:33
jason@hiddenachievement.com
Add an export to paintmix option
3 files changed with 62 insertions and 2 deletions:
0 comments (0 inline, 0 general)
Models/PlayerProfile.cs
Show inline comments
...
 
@@ -524,147 +524,193 @@ namespace DesertPaintCodex.Models
 
            SaveRecipes(RibbonRecipes, RibbonRecipeFile);
 
        }
 

	
 
        public void ClearRecipes()
 
        {
 
            DeleteRecipes(Recipes, PaintRecipeFile);
 
            DeleteRecipes(RibbonRecipes, RibbonRecipeFile);
 
        }
 

	
 
        public void ClearPaintRecipes()
 
        {
 
            DeleteRecipes(Recipes, PaintRecipeFile);
 
        }
 

	
 
        public void ClearRibbonRecipes()
 
        {
 
            DeleteRecipes(RibbonRecipes, RibbonRecipeFile);
 
        }
 

	
 
        public void ExportWikiRecipes(string file)
 
        {
 
            StreamWriter writer = new(file);
 
            ExportWikiFormat(writer, Recipes);
 
        }
 

	
 
        public void ExportWikiRibbons(string file)
 
        {
 
            StreamWriter writer = new StreamWriter(file);
 
            ExportWikiFormat(writer, this.RibbonRecipes);
 
        }
 

	
 
        public void ExportWikiRecipes(TextWriter writer)
 
        {
 
            ExportWikiFormat(writer, this.Recipes);
 
        }
 

	
 
        public void ExportWikiRibbons(TextWriter writer)
 
        {
 
            ExportWikiFormat(writer, this.RibbonRecipes);
 
        }
 
        
 
        public static void ExportWikiFormat(TextWriter writer, Dictionary<string, PaintRecipe> recipeDict)
 
        {
 
            using (writer)
 
            {
 
                writer.WriteLine("{| class='wikitable sortable' border=\"1\" style=\"background-color:#DEB887;\"");
 
                writer.WriteLine("! Color !! Recipe !! Missing Reactions? || Verified");
 
                foreach (PaintColor color in PaletteService.Colors)
 
                {
 
                    writer.WriteLine("|-");
 
                    string colorLine = "| ";
 
                    colorLine += "style=\"font-weight: bold; background-color: #" + color.Red.ToString("X2") + color.Green.ToString("X2") + color.Blue.ToString("X2") + ";";
 
                    
 
                    if (color.UseWhiteText)
 
                    {
 
                        // dark color gets light text
 
                        colorLine += " color: #FFFFFF;";
 
                    }
 
                    else
 
                    {
 
                        colorLine += "color: #000000;";
 
                    }
 
                    colorLine += "\" | " + color.Name + " || ";
 
                    if (recipeDict.TryGetValue(color.Name, out PaintRecipe? recipe))
 
                    {
 
                        foreach (PaintRecipe.ReagentQuantity ingredient in recipe.Reagents)
 
                        {
 
                            colorLine += " " + ingredient;
 
                        }
 
                    }
 
                    else
 
                    {
 
                        // no recipe
 
                    }
 
                    colorLine += " || ";
 

	
 
                    if (recipe == null)
 
                    {
 
                        colorLine += "?";
 
                    }
 
                    else if (recipe.HasMissingReactions())
 
                    {
 
                        colorLine += "Y";
 
                    }
 
                    else
 
                    {
 
                        colorLine += "N";
 
                    }
 

	
 
                    colorLine += " || N";
 
                    writer.WriteLine(colorLine);
 
                }
 
                writer.WriteLine("|}");
 
            }
 
        }
 

	
 
        public void ExportPaintMixRecipes(string file)
 
        {
 
            StreamWriter writer = new(file);
 
            ExportPaintMixFormat(writer, Recipes);
 
        }
 

	
 
        public void ExportPaintMixRibbons(string file)
 
        {
 
            StreamWriter writer = new StreamWriter(file);
 
            ExportPaintMixFormat(writer, this.RibbonRecipes);
 
        }
 

	
 
        public void ExportPaintMixRecipes(TextWriter writer)
 
        {
 
            ExportPaintMixFormat(writer, this.Recipes);
 
        }
 

	
 
        public void ExportPaintMixRibbons(TextWriter writer)
 
        {
 
            ExportWikiFormat(writer, this.RibbonRecipes);
 
        }
 

	
 
        public static void ExportPaintMixFormat(TextWriter writer, Dictionary<string, PaintRecipe> recipeDict)
 
        {
 
            using (writer)
 
            {
 
                foreach (PaintColor color in PaletteService.Colors)
 
                {
 
                    if (recipeDict.TryGetValue(color.Name, out PaintRecipe? recipe))
 
                    {
 
                        string colorLine = $"{color.Name} : ";
 
                        foreach (PaintRecipe.ReagentQuantity ingredient in recipe.Reagents)
 
                        {
 
                            colorLine += $" {ingredient.Name} {ingredient.Quantity}";
 
                        }
 
                        colorLine += $"  - #{color.Red:X2}{color.Green:X2}{color.Blue:X2}";
 
                        writer.WriteLine(colorLine);
 
                    }
 
                    else
 
                    {
 
                        // no recipe
 
                    }
 
                }
 
            }
 
        }
 

	
 
        public Reaction? FindReaction(Reagent? reagent1, Reagent? reagent2)
 
        {
 
            if ((reagent1 == null) || (reagent2 == null)) return null;
 
            return Reactions.Find(reagent1, reagent2);
 
        }
 

	
 
        public void SetReaction(Reagent reagent1, Reagent reagent2, Reaction reaction)
 
        {
 
            Reactions.Set(reagent1, reagent2, reaction);
 
        }
 

	
 
        public void ClearReaction(Reagent reagent1, Reagent reagent2)
 
        {
 
            Reactions.Remove(reagent1, reagent2);
 
        }
 

	
 
        public void SetRecipe(PaintRecipe recipe)
 
        {
 
            SetRecipe(PaletteService.FindNearest(recipe.ReactedColor), recipe);
 
        }
 

	
 
        public void SetRecipe(string colorName, PaintRecipe recipe)
 
        {
 
            if (Recipes.TryGetValue(colorName, out PaintRecipe? profileRecipe))
 
            {
 
                profileRecipe.CopyFrom(recipe);
 
            }
 
            else
 
            {
 
                Recipes.Add(colorName, new PaintRecipe(recipe));
 
            }
 
        }
 

	
 
        public void SetRibbonRecipe(PaintRecipe recipe)
 
        {
 
            SetRibbonRecipe(PaletteService.FindNearest(recipe.ReactedColor), recipe);
 
        }
 

	
 
        public void SetRibbonRecipe(string colorName, PaintRecipe recipe)
 
        {
 
            if (RibbonRecipes.TryGetValue(colorName, out PaintRecipe? profileRecipe))
 
            {
 
                profileRecipe.CopyFrom(recipe);
 
            }
 
            else
 
            {
 
                RibbonRecipes.Add(colorName, new PaintRecipe(recipe));
 
            }
 
        }
 
    }
 
}
ViewModels/MainWindowViewModel.cs
Show inline comments
...
 
@@ -73,175 +73,184 @@ namespace DesertPaintCodex.ViewModels
 
            try
 
            {
 
                ProfileManager.CurrentProfile?.Import(fileName);
 
            }
 
            catch (Exception e)
 
            {
 
                Debug.WriteLine("ImportProfile threw exception " + e);
 
                await ShowMessageBox("Import Failed",
 
                    "Your file could not be imported. It must be a zip file containing a Desert Paint Codex profile.", "OK");
 
            }
 

	
 
            ProfileManager.ReloadProfile();
 
            
 
            if (Application.Current is not App app) return;
 
            
 
            app.RefreshMainWindow();
 
        }
 

	
 
        public async void ExportProfile()
 
        {
 
            string? fileName = await GetSaveFileName("Save Zipped Profile", ZipFileFilters);
 
            
 
            if (string.IsNullOrEmpty(fileName)) return;
 
            
 
            try
 
            {
 
                ProfileManager.CurrentProfile?.Export(fileName);
 
            }
 
            catch (Exception e)
 
            {
 
                Debug.WriteLine("ExportProfile threw exception " + e);
 
                await ShowMessageBox("Export Failed",
 
                    "Your profile could not be exported. Please ensure that you are providing a valid filename for the zip file that we are creating.", "OK");
 
            }
 
        }
 

	
 
        public async void ExportForPP(object f)
 
        {
 
            string? fileName = await GetSaveFileName("Save Practical Paint File", TxtFileFilters, "reactions.txt");
 
            
 
            if (string.IsNullOrEmpty(fileName)) return;
 
            
 
            try
 
            {
 
                ProfileManager.CurrentProfile?.SaveToPP(fileName);
 
            }
 
            catch (Exception e)
 
            {
 
                Debug.WriteLine("ExportForPP threw exception " + e);
 
                await ShowMessageBox("Export Failed",
 
                    "Please ensure that you have provided a valid file path for your reactions file.", "OK");
 
            }
 
        }
 

	
 
        public async void ImportFromPP()
 
        {
 
            string? fileName = await GetLoadFileName("Import Reactions File", TxtFileFilters, "reactions.txt");
 
            
 
            if (string.IsNullOrEmpty(fileName)) return;
 

	
 
            try
 
            {
 
                ProfileManager.CurrentProfile?.ImportFromPP(fileName);
 
            }
 
            catch (Exception e)
 
            {
 
                Debug.WriteLine("ImportFromPP threw exception " + e);
 
                await ShowMessageBox("Import Failed",
 
                    "Your file could not be imported. It must be a valid Practical Paint reactions.txt file.", "OK");
 
            }
 

	
 
            ProfileManager.ReloadProfile();
 
            
 
            if (Application.Current is not App app) return;
 
            
 
            app.RefreshMainWindow();
 
        }
 

	
 
        public static async void ExportPaintRecipes()
 
        {
 
            string? fileName = await GetSaveFileName("Export Paint Recipes", NoFileFilters);
 
            if (!string.IsNullOrEmpty(fileName))
 
            {
 
                ProfileManager.CurrentProfile?.ExportWikiRecipes(fileName);
 
            }
 
        }
 
        
 
        public static async void ExportRibbonRecipes()
 
        {
 
            string? fileName = await GetSaveFileName("Export Ribbon Recipes", NoFileFilters);
 
            if (!string.IsNullOrEmpty(fileName))
 
            {
 
                ProfileManager.CurrentProfile?.ExportWikiRibbons(fileName);
 
            }
 
        }
 

	
 
        public static async void ExportPaintMixRecipes()
 
        {
 
            string? fileName = await GetSaveFileName("Export paint_mix recipes", NoFileFilters, "paint_recipes.txt");
 
            if (!string.IsNullOrEmpty(fileName))
 
            {
 
                ProfileManager.CurrentProfile?.ExportPaintMixRecipes(fileName);
 
            }
 
        }
 

	
 
        public static async void CopyPaintRecipes()
 
        {
 
            StringWriter writer = new();
 
            ProfileManager.CurrentProfile?.ExportWikiRecipes(writer);
 
            IClipboard clipboard = Application.Current.Clipboard;
 
            await writer.FlushAsync();
 
            await clipboard.SetTextAsync(writer.ToString());
 
            writer.Close();
 
        }
 
        
 
        public static async void CopyRibbonRecipes()
 
        {
 
            StringWriter writer = new();
 
            ProfileManager.CurrentProfile?.ExportWikiRibbons(writer);
 
            IClipboard clipboard = Application.Current.Clipboard;
 
            await writer.FlushAsync();
 
            await clipboard.SetTextAsync(writer.ToString());
 
            writer.Close();
 
        }
 

	
 
        public async Task ShowScreenSettings()
 
        {
 
            await ShowScreenSettingsDialog.Handle(new ScreenSettingsViewModel());
 
        }
 

	
 
        public async Task ShowAbout()
 
        {
 
            await ShowAboutDialog.Handle(new AboutViewModel());
 
        }
 

	
 
        public async Task<bool> ValidateSafeExit()
 
        {
 
            // TODO: Determine if there's unsaved stuff we need to deal with.
 
            // return await ShowYesNoBox("Leaving so Soon?", "[A potential reason not to quit goes here]");
 
            await Task.Delay(1); // Stub to prevent warnings.
 
            return true;
 
        }
 

	
 
        private static async Task<string?> GetLoadFileName(string title, List<FileDialogFilter> filters, string? fileName = null)
 
        {
 
            if (Application.Current.ApplicationLifetime is not IClassicDesktopStyleApplicationLifetime desktop) return null;
 
            
 
            // TODO: Figure out why the file filters aren't working.
 
            
 
            OpenFileDialog dialog = new()
 
            {
 
                Title           = title,
 
                Filters         = filters,
 
                InitialFileName = fileName,
 
                AllowMultiple   = false
 
            };
 

	
 
            string[] files = await dialog.ShowAsync(desktop.MainWindow);
 
            return files.Length > 0 ? files[0] : null;
 
        }
 
        
 
        
 
        private static async Task<string?> GetSaveFileName(string title, List<FileDialogFilter> filters, string? fileName = null)
 
        {
 
            if (Application.Current.ApplicationLifetime is not IClassicDesktopStyleApplicationLifetime desktop) return null;
 
            
 
            // TODO: Figure out why the file filters aren't working.
 
            
 
            SaveFileDialog dialog = new()
 
            {
 
                Title           = title,
 
                Filters         = filters,
 
                InitialFileName = fileName
 
            };
 

	
 
            return await dialog.ShowAsync(desktop.MainWindow);
 
        }
 
        
 
        public Interaction<AboutViewModel, Unit> ShowAboutDialog { get; }
 
        public Interaction<ScreenSettingsViewModel, Unit> ShowScreenSettingsDialog { get; }
 

	
 
        public ReactiveCommand<Unit, Unit> Exit { get; }
 
    }
 
}
Views/MainWindow.axaml
Show inline comments
 
<Window xmlns="https://github.com/avaloniaui"
 
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 
        xmlns:vm="using:DesertPaintCodex.ViewModels"
 
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
 
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
 
        xmlns:views="clr-namespace:DesertPaintCodex.Views"
 
        mc:Ignorable="d" d:DesignWidth="640" d:DesignHeight="800"
 
        Width="640" Height="800" MinWidth="600" MinHeight="500" Topmost="True"
 
        x:Class="DesertPaintCodex.Views.MainWindow"
 
        Icon="/Assets/desert_paint_codex_icon.ico"
 
        Title="Desert Paint Codex">
 

	
 
    <Design.DataContext>
 
        <vm:MainWindowViewModel/>
 
    </Design.DataContext>
 
    
 
    <Window.DataContext>
 
        <vm:MainWindowViewModel/>
 
    </Window.DataContext>
 
    
 
    <Window.Styles>
 
        <!--
 
        <Style Selector="Menu">
 
            <Setter Property="Background" Value="#282828"/>
 
        </Style>
 
        -->
 
        <Style Selector="ContentControl">
 
            <Setter Property="Margin" Value="0 5 0 0"/>
 
        </Style>
 
        <Style Selector="TextBlock.StatusBar">
 
            <Setter Property="Margin" Value="5"/>
 
        </Style>
 
        <Style Selector="TabControl.ActivityPicker WrapPanel">
 
            <Setter Property="Background" Value="{DynamicResource GutterBackgroundBrush}"/>
 
        </Style>
 
    
 
        <Style Selector="TabControl.ActivityPicker">
 
            <Setter Property="Background" Value="{DynamicResource FlatBackgroundBrush}"/>
 
        </Style>
 
    
 
        <Style Selector="TabControl.ActivityPicker > TabItem">
 
            <Setter Property="Padding" Value="15 5"/>
 
        </Style>
 
    
 
        <Style Selector="TabControl.ActivityPicker > TabItem:pointerover">
 
            <Setter Property="Foreground" Value="#000000"/>
 
        </Style>
 

	
 
        <Style Selector="TabControl.ActivityPicker > TabItem:selected">
 
            <Setter Property="Background" Value="{DynamicResource FlatBackgroundBrush}"/>
 
            <Setter Property="Foreground" Value="#FFFFFF"/>
 
        </Style>
 

	
 
        <Style Selector="TabControl.ActivityPicker > TabItem:selected /template/ ContentPresenter#PART_ContentPresenter">
 
            <Setter Property="Background" Value="{DynamicResource FlagBackgroundBrush}"/>
 
        </Style>
 
    </Window.Styles>
 
    <Grid ColumnDefinitions="*" RowDefinitions="*">
 
        <DockPanel Name="Main" Grid.Row="0" Grid.Column="0">
 
            <Menu DockPanel.Dock="Top" Margin="0, 5">
 
                <MenuItem Header="_File">
 
                    <MenuItem Header="Profile">
 
                        <MenuItem Header="Manage Profiles..." Command="{Binding ManageProfiles}"></MenuItem>
 
                        <Separator/>
 
                        <MenuItem Header="Import Profile..." Command="{Binding ImportProfile}">
 
                            <ToolTip.Tip>
 
                                Will overwrite the current profile with a profile from a zipped folder.
 
                            </ToolTip.Tip>
 
                        </MenuItem>
 
                        <MenuItem Header="Export Profile..." Command="{Binding ExportProfile}">
 
                            <ToolTip.Tip>
 
                                Will export the current profile to a zipped folder.
 
                            </ToolTip.Tip>
 
                        </MenuItem>
 
                        <Separator/>
 
                        <MenuItem Header="Import PracticalPaint Reactions..." Command="{Binding ImportFromPP}">
 
                            <ToolTip.Tip>
 
                                Will import a Practical Paint reactions file, replacing this profile's reactions.
 
                            </ToolTip.Tip>
 
                        </MenuItem>
 
                        <MenuItem Header="Export PracticalPaint Reactions..." Command="{Binding ExportForPP}">
 
                            <ToolTip.Tip>
 
                                Will generate a Practical Paint reactions file from the current profile.
 
                            </ToolTip.Tip>
 
                        </MenuItem>
 
                    </MenuItem>
 
                    <Separator/>
 
                    <MenuItem Header="Recipes">
 
                        <MenuItem Header="Export Paint Recipes..." Command="{Binding ExportPaintRecipes}">
 
                        <MenuItem Header="Export Paint Recipes (Wiki format)..." Command="{Binding ExportPaintRecipes}">
 
                            <ToolTip.Tip>
 
                                Exports recipes in Wiki table format.
 
                            </ToolTip.Tip>
 
                        </MenuItem>
 
                        <MenuItem Header="Export Ribbon Recipes..." Command="{Binding ExportRibbonRecipes}">
 
                        <MenuItem Header="Export Ribbon Recipes (Wiki format)..." Command="{Binding ExportRibbonRecipes}">
 
                            <ToolTip.Tip>
 
                                Exports recipes in Wiki table format.
 
                            </ToolTip.Tip>
 
                        </MenuItem>
 
                        <Separator/>
 
                        <MenuItem Header="Copy Paint Recipes to Clipboard" Command="{Binding CopyPaintRecipes}">
 
                            <ToolTip.Tip>
 
                                Copies recipes in Wiki table format.
 
                            </ToolTip.Tip>
 
                        </MenuItem>
 
                        <MenuItem Header="Copy Ribbon Recipes to Clipboard" Command="{Binding CopyRibbonRecipes}">
 
                            <ToolTip.Tip>
 
                                Copies recipes in Wiki table format.
 
                            </ToolTip.Tip>
 
                        </MenuItem>
 
                      <MenuItem Header="Export Paint Recipes (paint_mix format)..." Command="{Binding ExportPaintMixRecipes}">
 
                        <ToolTip.Tip>
 
                          Exports recipes in Wiki table format.
 
                        </ToolTip.Tip>
 
                      </MenuItem>
 
                    </MenuItem>
 

	
 
                    <Separator/>
 

	
 
                    <MenuItem Header="Screen Settings..." Command="{Binding ShowScreenSettings}"></MenuItem>
 
                    <Separator/>
 

	
 
                    <MenuItem Header="Exit" Command="{Binding Exit}"></MenuItem>
 
                </MenuItem>
 

	
 
                <MenuItem Header="_Help">
 
                     <MenuItem Header="Documentation" Command="{Binding OpenBrowser}" CommandParameter="https://repos.malkyne.org/ATITD-Tools/Desert-Paint-Codex"></MenuItem>
 
                     <MenuItem Header="About..." Command="{Binding ShowAbout}"></MenuItem>
 
                </MenuItem>
 
            </Menu>
 
            
 
            <Border DockPanel.Dock="Top" BorderThickness="2" Background="{DynamicResource GutterBackgroundBrush}"></Border>
 

	
 

	
 
            <TextBlock DockPanel.Dock="Bottom" Classes="StatusBar"
 
                       Text="{Binding StatusText}"
 
                       HorizontalAlignment="Left" VerticalAlignment="Center" Height="18"/>
 
            
 
            <Border DockPanel.Dock="Bottom" BorderThickness="2" Background="{DynamicResource GutterBackgroundBrush}"></Border>
 
            
 
            <TabControl Classes="ActivityPicker">
 
                <TabItem Header="EXPERIMENT LOG" VerticalContentAlignment="Center">
 
                    <views:ExperimentLogView />
 
                </TabItem>
 
                <TabItem Header="SIMULATOR" VerticalContentAlignment="Center">
 
                    <views:SimulatorView />
 
                </TabItem>
 
                <TabItem Header="RECIPE GENERATOR" VerticalContentAlignment="Center">
 
                    <views:RecipeGeneratorView />
 
                </TabItem>
 
            </TabControl>
 
        </DockPanel>
 
    </Grid>
 
    
 

	
 
</Window>
0 comments (0 inline, 0 general)