# HG changeset patch # User Tess Snider # Date 2015-09-09 08:29:25 # Node ID b9934660c784f8388a70a23a750d22b7f8b45225 This is the original source migrated over from Google Code, exactly as it appeared in 2010. diff --git a/AssemblyInfo.cs b/AssemblyInfo.cs new file mode 100644 --- /dev/null +++ b/AssemblyInfo.cs @@ -0,0 +1,27 @@ +using System.Reflection; +using System.Runtime.CompilerServices; + +// Information about this assembly is defined by the following attributes. +// Change them to the values specific to your project. + +[assembly: AssemblyTitle("DesertPaintLab")] +[assembly: AssemblyDescription("Program to help record pigment lab reactions in ATITD")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("Tess Snider")] +[assembly: AssemblyProduct("")] +[assembly: AssemblyCopyright("Tess Snider, 2010")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}". +// The form "{Major}.{Minor}.*" will automatically update the build and revision, +// and "{Major}.{Minor}.{Build}.*" will update just the revision. + +[assembly: AssemblyVersion("1.0.*")] + +// The following attributes are used to specify the signing key for the assembly, +// if desired. See the Mono documentation for more information about signing. + +//[assembly: AssemblyDelaySign(false)] +//[assembly: AssemblyKeyFile("")] + diff --git a/DesertPaintLab.csproj b/DesertPaintLab.csproj new file mode 100644 --- /dev/null +++ b/DesertPaintLab.csproj @@ -0,0 +1,78 @@ + + + + Debug + x86 + 8.0.50727 + 2.0 + {1A885212-5FD2-4EBF-A98F-3EB1491A1CBB} + WinExe + DesertPaintLab + DesertPaintLab + + + true + full + false + bin\Debug + DEBUG + prompt + 4 + x86 + false + /unsafe + + + none + false + bin\Release + prompt + 4 + x86 + false + + + + + + + + + + + + + + gui.stetic + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/DesertPaintLab.sln b/DesertPaintLab.sln new file mode 100644 --- /dev/null +++ b/DesertPaintLab.sln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual Studio 2005 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DesertPaintLab", "DesertPaintLab.csproj", "{1A885212-5FD2-4EBF-A98F-3EB1491A1CBB}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x86 = Debug|x86 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {1A885212-5FD2-4EBF-A98F-3EB1491A1CBB}.Debug|x86.ActiveCfg = Debug|x86 + {1A885212-5FD2-4EBF-A98F-3EB1491A1CBB}.Debug|x86.Build.0 = Debug|x86 + {1A885212-5FD2-4EBF-A98F-3EB1491A1CBB}.Release|x86.ActiveCfg = Release|x86 + {1A885212-5FD2-4EBF-A98F-3EB1491A1CBB}.Release|x86.Build.0 = Release|x86 + EndGlobalSection + GlobalSection(MonoDevelopProperties) = preSolution + StartupItem = DesertPaintLab.csproj + EndGlobalSection +EndGlobal diff --git a/FirstRunDialog.cs b/FirstRunDialog.cs new file mode 100644 --- /dev/null +++ b/FirstRunDialog.cs @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2010, Tess Snider + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +using System; +namespace DesertPaintLab +{ + public partial class FirstRunDialog : Gtk.Dialog + { + public FirstRunDialog () + { + this.Build (); + } + } +} + diff --git a/Main.cs b/Main.cs new file mode 100644 --- /dev/null +++ b/Main.cs @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2010, Tess Snider + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +using System; +using Gtk; + +namespace DesertPaintLab +{ + class MainClass + { + public static void Main (string[] args) + { + Application.Init (); + MainWindow win = new MainWindow (); + if (!win.ShouldShutDown) + { + win.Show (); + Application.Run (); + } + } + } +} + diff --git a/MainWindow.cs b/MainWindow.cs new file mode 100644 --- /dev/null +++ b/MainWindow.cs @@ -0,0 +1,798 @@ +/* + * Copyright (c) 2010, Tess Snider + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +using System; +using System.IO; +using System.Collections.Generic; +using Gtk; +using DesertPaintLab; + +public partial class MainWindow : Gtk.Window +{ + const int swatchHeight = 24; + const int colorBarWidth = 260; + const int redBarSpacing = 32; + const int greenBarSpacing = 42; + const int blueBarSpacing = 52; + const int colorTolerance = 2; + + + bool unsavedData = false; + bool shouldShutDown = false; + string appDataPath; + List profileList = new List(); + PlayerProfile profile = null; + PaintColor expectedColor = new PaintColor(); + PaintColor reactedColor = new PaintColor(); + + int screenWidth = 0; + int screenHeight = 0; + + Gdk.Window rootWindow = null; + Gdk.Pixbuf screenBuffer = null; + + Reagent reagent1 = null; + Reagent reagent2 = null; + Reagent reagent3 = null; + + + + public bool ShouldShutDown + { + get + { + return shouldShutDown; + } + } + + + public MainWindow () : base(Gtk.WindowType.Toplevel) + { + appDataPath = System.IO.Path.Combine( + Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), + "DesertPaintLab"); + + if (!System.IO.Directory.Exists(appDataPath)) + { + System.IO.Directory.CreateDirectory(appDataPath); + } + + DirectoryInfo di = new DirectoryInfo(appDataPath); + DirectoryInfo[] dirs = di.GetDirectories(); + foreach (DirectoryInfo dir in dirs) + { + if (dir.Name != "template") + { + profileList.Add(dir.Name); + } + } + + Palette.Load(System.IO.Path.Combine( + System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), + "colors.txt")); + + Build(); + + unmodifiedSwatch.Clear(); + reactionSwatch.Clear(); + + + // get the root window + rootWindow = Gdk.Global.DefaultRootWindow; + + // get its width and height + rootWindow.GetSize(out screenWidth, out screenHeight); + + screenBuffer = new Gdk.Pixbuf(Gdk.Colorspace.Rgb, false, 8, + screenWidth, screenHeight); + + if (!OpenProfile()) + { + shouldShutDown = true; + } + } + + bool ConfirmedExit() + { + if (unsavedData) + { + MessageDialog md = new MessageDialog(this, + DialogFlags.DestroyWithParent, + MessageType.Warning, ButtonsType.OkCancel, + "Your last reaction was unsaved." + + "Are you sure you want to quit?"); + + ResponseType resp = (ResponseType)md.Run(); + md.Destroy(); + return (resp == ResponseType.Ok); + } + return true; + } + + void SetProfileName(string name) + { + profile = new PlayerProfile(name, + System.IO.Path.Combine(appDataPath, name)); + + statusBar.Push(0, name); + } + + bool NewProfile() + { + bool newProfileCreated = false; + bool duplicateName = false; + NewProfileDialog newProfileDialog = new NewProfileDialog(); + ResponseType resp = (ResponseType)newProfileDialog.Run(); + if (resp == ResponseType.Ok) + { + // Make sure profile doesn't already exist. + foreach (string profileName in profileList) + { + if (profileName == newProfileDialog.ProfileName) + { + MessageDialog md = new MessageDialog(this, + DialogFlags.DestroyWithParent, + MessageType.Error, ButtonsType.Ok, + "That profile name already exists."); + resp = (ResponseType)md.Run(); + md.Destroy(); + duplicateName = true; + break; + } + } + + if (!duplicateName) + { + // Set profile name. + SetProfileName(newProfileDialog.ProfileName); + + profile.Initialize(); + + newProfileCreated = true; + } + } + newProfileDialog.Destroy(); + return newProfileCreated; + } + + bool OpenProfile() + { + bool profileSelected = false; + + if (profileList.Count > 0) + { + SelectProfileDialog selectProfileDialog = new SelectProfileDialog(); + selectProfileDialog.ProfileList = profileList; + ResponseType resp = (ResponseType)selectProfileDialog.Run(); + selectProfileDialog.Destroy(); + string selectedProfile = selectProfileDialog.SelectedProfile; + if ((resp == ResponseType.Ok) && (selectedProfile.Length > 0)) + // Selected a profile. + { + SetProfileName(selectedProfile); + profileSelected = true; + } + else if (resp == ResponseType.Accept) // New profile. + { + profileSelected = NewProfile(); + } + } + else + { + FirstRunDialog firstRunDialog = new FirstRunDialog(); + ResponseType resp = (ResponseType)firstRunDialog.Run(); + firstRunDialog.Destroy(); + if (resp == ResponseType.Ok) // New profile + { + profileSelected = NewProfile(); + } + else if (resp == ResponseType.Accept) // Import + { + FileChooserDialog fileDialog = + new FileChooserDialog("Select reactions.txt file.", + this, FileChooserAction.Open, + Gtk.Stock.Cancel, ResponseType.Cancel, + Gtk.Stock.Open, ResponseType.Accept); + resp = (ResponseType)fileDialog.Run(); + if (resp == ResponseType.Accept) + { + string fileName = fileDialog.Filename; + string directory = fileDialog.CurrentFolder; + if (fileName == "reactions.txt") + { + profileSelected = NewProfile(); + if (profileSelected) + { + profile.Import(directory); + } + } + } + } + } + + if (profileSelected) + { + profile.Load(); + PopulateDropDowns(); + } + + return profileSelected; + } + + void PopulateDropDowns() + { + ReagentManager.PopulateReagents(ref ingredient1ComboBox); + ReagentManager.PopulateReagents(ref ingredient2ComboBox); + ReagentManager.PopulateReagents(ref ingredient3ComboBox); + + ingredient2ComboBox.Sensitive = false; + ingredient3ComboBox.Sensitive = false; + + Gtk.TreeIter iter; + ingredient1ComboBox.Model.IterNthChild(out iter, 0); + ingredient1ComboBox.SetActiveIter(iter); + ingredient2ComboBox.Model.IterNthChild(out iter, 0); + ingredient2ComboBox.SetActiveIter(iter); + ingredient3ComboBox.Model.IterNthChild(out iter, 0); + ingredient3ComboBox.SetActiveIter(iter); + } + + protected void SetExpectedColor(byte red, byte green, byte blue) + { + expectedColor.Red = red; + expectedColor.Green = green; + expectedColor.Blue = blue; + unmodifiedSwatch.Color = expectedColor; + } + + protected void SetExpectedColor(PaintColor color) + { + SetExpectedColor(color.Red, color.Green, color.Blue); + } + + protected void UpdateIngredients() + { + Reaction reaction1, reaction2; + TreeIter selectIter; + string reagentName; + reagent1 = null; + reagent2 = null; + reagent3 = null; + + int expRedSum = 0; + int expGreenSum = 0; + int expBlueSum = 0; + + int reactRedSum = 0; + int reactGreenSum = 0; + int reactBlueSum = 0; + + bool reactionKnown = true; + + int pigmentCount = 0; + + saveButton.Sensitive = false; + + if (ingredient1ComboBox.GetActiveIter(out selectIter)) + { + reagentName = (string)ingredient1ComboBox.Model.GetValue(selectIter, 0); + if ((reagentName == null) || (reagentName.Length == 0)) + { + ingredient2ComboBox.Sensitive = false; + ingredient3ComboBox.Sensitive = false; + unmodifiedSwatch.Clear(); + captureButton.Sensitive = false; + } + else + { + reagent1 = ReagentManager.GetReagent(reagentName); + ingredient2ComboBox.Sensitive = true; + if (!reagent1.IsCatalyst) + { + expRedSum = reagent1.Color.Red; + expGreenSum = reagent1.Color.Green; + expBlueSum = reagent1.Color.Blue; + pigmentCount = 1; + } + if (ingredient2ComboBox.GetActiveIter(out selectIter)) + { + reagentName = (string)ingredient2ComboBox.Model.GetValue(selectIter, 0); + if ((reagentName == null) || (reagentName.Length == 0)) + { + ingredient3ComboBox.Sensitive = false; + saveButton.Sensitive = false; + reactionKnown = false; + } + else + { + reagent2 = ReagentManager.GetReagent(reagentName); + ingredient3ComboBox.Sensitive = true; + captureButton.Sensitive = true; + if (!reagent2.IsCatalyst) + { + expRedSum += reagent2.Color.Red; + expGreenSum += reagent2.Color.Green; + expBlueSum += reagent2.Color.Blue; + pigmentCount++; + } + + reaction1 = profile.FindReaction(reagent1, reagent2); + + if (reaction1 != null) + { + ingredient3ComboBox.Sensitive = true; + reactRedSum = reaction1.Red; + reactGreenSum = reaction1.Green; + reactBlueSum = reaction1.Blue;; + } + else + { + reactionKnown = false; + ingredient3ComboBox.Sensitive = false; + } + + if (ingredient3ComboBox.GetActiveIter(out selectIter)) + { + reagentName = (string)ingredient3ComboBox.Model.GetValue(selectIter, 0); + if ((reagentName != null) && (reagentName.Length != 0)) + { + reagent3 = ReagentManager.GetReagent(reagentName); + + if (!reactionKnown) + { + MessageDialog md = new MessageDialog(this, + DialogFlags.DestroyWithParent, + MessageType.Error, ButtonsType.Ok, + "To do a three-ingredient reaction test, " + + "you must first recored the reaction of " + + "the first two ingredients."); + + md.Run(); + md.Destroy(); + captureButton.Sensitive = false; + } + + if (!reagent3.IsCatalyst) + { + expRedSum += reagent3.Color.Red; + expGreenSum += reagent3.Color.Green; + expBlueSum += reagent3.Color.Blue; + pigmentCount++; + } + + reaction1 = profile.FindReaction(reagent1, reagent3); + reaction2 = profile.FindReaction(reagent2, reagent3); + + if (reactionKnown && (reaction1 == null) && (reaction2 == null)) + { + MessageDialog md = new MessageDialog(this, + DialogFlags.DestroyWithParent, + MessageType.Error, ButtonsType.Ok, + "To do a three-ingredient reaction test, " + + "you must first record the reaction of " + + "either the first or second ingredient " + + "with the third ingredient."); + + md.Run(); + md.Destroy(); + captureButton.Sensitive = false; + } + + if (reaction1 != null) + { + reactRedSum += reaction1.Red; + reactGreenSum += reaction1.Green; + reactBlueSum += reaction1.Blue; + } + else + { + reactionKnown = false; + } + + if (reaction2 != null) + { + reactRedSum += reaction2.Red; + reactGreenSum += reaction2.Green; + reactBlueSum += reaction2.Blue; + } + else + { + reactionKnown = false; + } + } + } + } + } + SetExpectedColor((byte)Math.Round((float)expRedSum / (float)pigmentCount), + (byte)Math.Round((float)expGreenSum / (float)pigmentCount), + (byte)Math.Round((float)expBlueSum / (float)pigmentCount)); + + if (reactionKnown) + { + reactedColor.Red = (byte)Math.Min(255, Math.Max(0, expectedColor.Red + reactRedSum)); + reactedColor.Green = (byte)Math.Min(255, Math.Max(0, expectedColor.Green + reactGreenSum)); + reactedColor.Blue = (byte)Math.Min(255, Math.Max(0, expectedColor.Blue + reactBlueSum)); + reactionSwatch.Color = reactedColor; + } + else + { + reactionSwatch.Clear(); + } + } + } + } + + protected void OnDeleteEvent(object sender, DeleteEventArgs a) + { + if (ConfirmedExit()) + { + a.RetVal = true; + Application.Quit(); + } + else + { + a.RetVal = false; + } + } + + bool IsPapyTexture(byte r, byte g, byte b) + { + return ((r > 0xD0) && (g > 0xC8) && (b > 0xA0)) && + ((r < 0xF4) && (g < 0xE0) && (b < 0xC4)); + } + + unsafe bool CaptureReactionColor() + { + // Take a screenshot. + byte r, g, b; + int pixelStart, otherPixelStart; + bool colorMatch; + screenBuffer.GetFromDrawable(rootWindow, + rootWindow.Colormap, 0, 0, 0, 0, screenWidth, screenHeight); + int stride = screenBuffer.Rowstride; + byte* pixBytes = (byte*)screenBuffer.Pixels; + + for (int x = 0; x < screenWidth - colorBarWidth; ++x) + { + for (int y = 0; y < (screenHeight - 53); ++y) + { + // Look for the color swatch. + pixelStart = (y * stride) + (x * 3); + r = pixBytes[pixelStart]; + g = pixBytes[pixelStart + 1]; + b = pixBytes[pixelStart + 2]; + + // 1.) Check if this is a dark pixel. + if ((r < 0x42) && (g < 0x42) && (b <= 0x42)) + { + // 2.) Check the pixel above it, + // to see if it's from the papy texture. + otherPixelStart = pixelStart - stride; + if ((otherPixelStart >= 0) && + IsPapyTexture(pixBytes[otherPixelStart++], + pixBytes[otherPixelStart++], + pixBytes[otherPixelStart])) + { + // 3.) Check the pixel below where the swatch should be, + // to see if it's also from the papy texture. + otherPixelStart = pixelStart + (stride * swatchHeight); + if (IsPapyTexture(pixBytes[otherPixelStart++], + pixBytes[otherPixelStart++], + pixBytes[otherPixelStart])) + { + // pixBytes[pixelStart] = 0xFF; + // pixBytes[pixelStart + 1] = 0x00; + // pixBytes[pixelStart + 2] = 0xFF; + + // 4.) Scan the left border of the potential swatch + // location. + colorMatch = true; + for (int i = 1; i < swatchHeight - 2; ++i) + { + otherPixelStart = pixelStart + (stride * i); + if ((Math.Abs(r - pixBytes[otherPixelStart++]) > colorTolerance) || + (Math.Abs(g - pixBytes[otherPixelStart++]) > colorTolerance) || + (Math.Abs(b - pixBytes[otherPixelStart]) > colorTolerance)) + { + colorMatch = false; + break; + } + } + + if (colorMatch) + { + // WE FOUND THE SWATCH! + // Now we know where the color bars are. + otherPixelStart = pixelStart + (redBarSpacing * stride); + int pixelCount = 0; + while ((Math.Abs(pixBytes[otherPixelStart] - 0xA1) < colorTolerance) && + (Math.Abs(pixBytes[otherPixelStart + 1] - 0x04) < colorTolerance) && + (Math.Abs(pixBytes[otherPixelStart + 2] - 0x03) < colorTolerance)) + { + pixelCount++; + // pixBytes[otherPixelStart] = 0x00; + // pixBytes[otherPixelStart + 1] = 0xFF; + // pixBytes[otherPixelStart + 2] = 0xFF; + otherPixelStart += 3; + } + + reactedColor.Red = (byte)Math.Round((float)pixelCount * 255f / (float)colorBarWidth); + otherPixelStart = pixelStart + (greenBarSpacing * stride); + + pixelCount = 0; + while ((Math.Abs(pixBytes[otherPixelStart] - 0x04) < colorTolerance) && + (Math.Abs(pixBytes[otherPixelStart + 1] - 0xA1) < colorTolerance) && + (Math.Abs(pixBytes[otherPixelStart + 2] - 0x03) < colorTolerance)) + { + pixelCount++; + // pixBytes[otherPixelStart] = 0x00; + // pixBytes[otherPixelStart + 1] = 0xFF; + // pixBytes[otherPixelStart + 2] = 0xFF; + otherPixelStart += 3; + } + + reactedColor.Green = (byte)Math.Round((float)pixelCount * 255f / (float)colorBarWidth); + otherPixelStart = pixelStart + (blueBarSpacing * stride); + + pixelCount = 0; + while ((Math.Abs(pixBytes[otherPixelStart] - 0x04) < colorTolerance) && + (Math.Abs(pixBytes[otherPixelStart + 1] - 0x04) < colorTolerance) && + (Math.Abs(pixBytes[otherPixelStart + 2] - 0xA1) < colorTolerance)) + { + pixelCount++; + // pixBytes[otherPixelStart] = 0x00; + // pixBytes[otherPixelStart + 1] = 0xFF; + // pixBytes[otherPixelStart + 2] = 0xFF; + otherPixelStart += 3; + } + + reactedColor.Blue = (byte)Math.Round((float)pixelCount * 255f / (float)colorBarWidth); + + + // screenBuffer.Save("screenshot.png", "png"); + return true; + } + } + } + } + } + } + // screenBuffer.Save("screenshot.png", "png"); + + return false; + + } + + protected virtual void OnCaptureButton(object sender, System.EventArgs e) + { + if (CaptureReactionColor()) + { + string warning = ""; + if (reactedColor.Red == 0) + { + warning = warning + "\nRed is too low."; + } + if (reactedColor.Green == 0) + { + warning = warning + "\nGreen is too low."; + } + if (reactedColor.Blue == 0) + { + warning = warning + "\nBlue is too low."; + } + if (reactedColor.Red == 255) + { + warning = warning + "\nRed is too low."; + } + if (reactedColor.Green == 255) + { + warning = warning + "\nGreen is too low."; + } + if (reactedColor.Blue == 255) + { + warning = warning + "\nBlue is too low."; + } + + if (warning.Length != 0) + { + MessageDialog md = new MessageDialog(this, + DialogFlags.DestroyWithParent, + MessageType.Error, ButtonsType.Ok, + "Reaction clipped. You will need to do a " + + "3-way reaction to test this pair. Details: " + + warning); + + md.Run(); + md.Destroy(); + } + else + { + this.reactionSwatch.Color = reactedColor; + saveButton.Sensitive = true; + } + } + else + { + MessageDialog md = new MessageDialog(this, + DialogFlags.DestroyWithParent, + MessageType.Error, ButtonsType.Ok, + "Pigment Lab dialog box NOT FOUND. Please ensure " + + "that there is an unobstructed view of the dialog " + + "when you press the Capture button."); + + md.Run(); + md.Destroy(); + } + } + + protected virtual void OnSaveButton(object sender, System.EventArgs e) + { + int r, g, b; + if (reagent3 != null) + { + // A 3-reagent reaction. + Reaction reaction1 = profile.FindReaction(reagent1, reagent2); + Reaction reaction2 = profile.FindReaction(reagent1, reagent3); + Reaction reaction3 = profile.FindReaction(reagent2, reagent3); + + r = reactedColor.Red - expectedColor.Red; + g = reactedColor.Green - expectedColor.Green; + b = reactedColor.Blue - expectedColor.Blue; + + if (reaction2 == null) + { + r = r - reaction1.Red - reaction3.Red; + g = g - reaction1.Green - reaction3.Green; + b = b - reaction1.Blue - reaction3.Blue; + profile.SetReaction(reagent1, reagent3, new Reaction(r, g, b)); + profile.Save(); + saveButton.Sensitive = false; + } + else if (reaction3 == null) + { + r = r - reaction1.Red - reaction2.Red; + g = g - reaction1.Green - reaction2.Green; + b = b - reaction1.Blue - reaction2.Blue; + profile.SetReaction(reagent2, reagent3, new Reaction(r, g, b)); + profile.Save(); + saveButton.Sensitive = false; + } + } + else if ((reagent1 != null) && (reagent2 != null)) + { + // A 2-reagent reaction. + r = reactedColor.Red - expectedColor.Red; + g = reactedColor.Green - expectedColor.Green; + b = reactedColor.Blue - expectedColor.Blue; + profile.SetReaction(reagent1, reagent2, new Reaction(r, g, b)); + profile.Save(); + saveButton.Sensitive = false; + } + } + + protected virtual void OnChangedIngredient1(object sender, System.EventArgs e) + { + UpdateIngredients(); + } + + protected virtual void OnChangedIngredient2(object sender, System.EventArgs e) + { + UpdateIngredients(); + } + + protected virtual void OnChangedIngredient3(object sender, System.EventArgs e) + { + UpdateIngredients(); + + } + + protected virtual void OnNewProfile(object sender, System.EventArgs e) + { + if (unsavedData) + { + MessageDialog md = new MessageDialog(this, + DialogFlags.DestroyWithParent, + MessageType.Warning, ButtonsType.OkCancel, + "Your last reaction was unsaved." + + "Are you sure you want to lose your changes?"); + + ResponseType resp = (ResponseType)md.Run(); + md.Destroy(); + if (resp != ResponseType.Ok) + { + return; + } + } + + if (NewProfile()) + { + profile.Load(); + PopulateDropDowns(); + } + } + + protected virtual void OnOpenProfile(object sender, System.EventArgs e) + { + bool profileSelected = false; + SelectProfileDialog selectProfileDialog = new SelectProfileDialog(); + selectProfileDialog.ProfileList = profileList; + ResponseType resp = (ResponseType)selectProfileDialog.Run(); + selectProfileDialog.Destroy(); + if (resp == ResponseType.Ok) // Selected a profile. + { + SetProfileName(selectProfileDialog.SelectedProfile); + profileSelected = true; + } + else if (resp == ResponseType.Accept) // New profile. + { + profileSelected = NewProfile(); + } + if (profileSelected) + { + profile.Load(); + PopulateDropDowns(); + } + } + + protected virtual void OnAbout(object sender, System.EventArgs e) + { + AboutDialog aboutDialog = new AboutDialog(); + aboutDialog.Run(); + aboutDialog.Destroy(); + } + + protected virtual void OnMenuExit (object sender, System.EventArgs e) + { + if (ConfirmedExit()) + { + Application.Quit(); + } + } + + protected virtual void OnExport(object sender, System.EventArgs e) + { + FileChooserDialog fileDialog = + new FileChooserDialog("Select destination file.", + this, FileChooserAction.Save, + Gtk.Stock.Cancel, ResponseType.Cancel, + Gtk.Stock.Save, ResponseType.Accept); + ResponseType resp = (ResponseType)fileDialog.Run(); + if (resp == ResponseType.Accept) + { + string fileName = fileDialog.Filename; + string directory = fileDialog.CurrentFolder; + profile.Export(System.IO.Path.Combine(directory, fileName)); + } + fileDialog.Destroy(); + } + + protected virtual void RunSimulator(object sender, System.EventArgs e) + { + SimulatorWindow win = new SimulatorWindow(profile); + win.Show(); + } + + + + +} + diff --git a/NewProfileDialog.cs b/NewProfileDialog.cs new file mode 100644 --- /dev/null +++ b/NewProfileDialog.cs @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2010, Tess Snider + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +using System; +namespace DesertPaintLab +{ + public partial class NewProfileDialog : Gtk.Dialog + { + public string ProfileName + { + get + { + return profileNameEntry.Text; + } + } + + public NewProfileDialog () + { + this.Build (); + } + + + } +} + diff --git a/PaintColor.cs b/PaintColor.cs new file mode 100644 --- /dev/null +++ b/PaintColor.cs @@ -0,0 +1,108 @@ +using System; +namespace DesertPaintLab +{ + public class PaintColor + { + byte red; + byte green; + byte blue; + + string name; + + public byte Red + { + get + { + return red; + } + set + { + red = value; + } + } + + public byte Blue + { + get + { + return blue; + } + set + { + blue = value; + } + } + + public byte Green + { + get + { + return green; + } + set + { + green = value; + } + } + + public string Name + { + get + { + return name; + } + set + { + name = value; + } + } + + public PaintColor() + { + name = "Undefined"; + red = 0; + green = 0; + blue = 0; + } + + public PaintColor(string name, string hexRed, string hexGreen, string hexBlue) + { + this.name = name; + red = (byte)System.Int32.Parse(hexRed, + System.Globalization.NumberStyles.AllowHexSpecifier); + green = (byte)System.Int32.Parse(hexGreen, + System.Globalization.NumberStyles.AllowHexSpecifier); + blue = (byte)System.Int32.Parse(hexBlue, + System.Globalization.NumberStyles.AllowHexSpecifier); + } + + public PaintColor(byte red, byte green, byte blue) + { + name = "Undefined"; + this.red = red; + this.green = green; + this.blue = blue; + } + + public int GetDistanceSquared(PaintColor otherColor) + { + return (int)(Math.Pow(this.red - otherColor.red, 2) + + Math.Pow(this.green - otherColor.green, 2) + + Math.Pow(this.blue - otherColor.blue, 2)); + } + + public void Clear() + { + red = 0; + green = 0; + blue = 0; + } + + public override string ToString() + { + return "[" + name + ", " + red + ", " + green + ", " + blue + "]"; + } + + } +} + diff --git a/PaintSwatch.cs b/PaintSwatch.cs new file mode 100644 --- /dev/null +++ b/PaintSwatch.cs @@ -0,0 +1,47 @@ +using System; + +namespace DesertPaintLab +{ + [System.ComponentModel.ToolboxItem(true)] + public partial class PaintSwatch : Gtk.Bin + { + PaintColor color; + + public PaintColor Color + { + get + { + return color; + } + + set + { + color.Red = value.Red; + color.Green = value.Green; + color.Blue = value.Blue; + colorBox.ModifyBg(Gtk.StateType.Normal, new Gdk.Color(color.Red, color.Green, color.Blue)); + rgbLabel.Text = color.Red.ToString() + ", " + + color.Green.ToString() + ", " + + color.Blue.ToString(); + colorNameLabel.Text = Palette.FindNearest(color); + } + + } + + public PaintSwatch () + { + color = new PaintColor(); + this.Build (); + } + + public void Clear() + { + color.Clear(); + colorBox.ModifyBg(Gtk.StateType.Normal, new Gdk.Color(color.Red, color.Green, color.Blue)); + rgbLabel.Text = "???, ???, ???"; + colorNameLabel.Text = "Unknown"; + } + + } +} + diff --git a/Palette.cs b/Palette.cs new file mode 100644 --- /dev/null +++ b/Palette.cs @@ -0,0 +1,56 @@ +using System; +using System.IO; +using System.Collections.Generic; +using System.Text.RegularExpressions; + +namespace DesertPaintLab +{ + public class Palette + { + static List colors = new List(); + static Regex colorEntry = new Regex(@"\#(?\w\w)(?\w\w)(?\w\w)\s*(?\w+)"); + + + public Palette () + { + + } + + public static void Load(string file) + { + string line; + Match match; + using (StreamReader reader = new StreamReader(file)) + { + while ((line = reader.ReadLine()) != null) + { + match = colorEntry.Match(line); + if (match.Success) + { + colors.Add(new PaintColor(match.Groups["name"].Value, + match.Groups["red"].Value, + match.Groups["green"].Value, + match.Groups["blue"].Value)); + } + } + } + } + + public static string FindNearest(PaintColor color) + { + int bestDistSq = int.MaxValue; + PaintColor bestColor = null; + foreach (PaintColor paintColor in colors) + { + int distSq = paintColor.GetDistanceSquared(color); + if (distSq < bestDistSq) + { + bestDistSq = distSq; + bestColor = paintColor; + } + } + return bestColor.Name; + } + } +} + diff --git a/PlayerProfile.cs b/PlayerProfile.cs new file mode 100644 --- /dev/null +++ b/PlayerProfile.cs @@ -0,0 +1,268 @@ +/* + * Copyright (c) 2010, Tess Snider + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +using System; +using System.IO; +using System.Collections.Generic; + +namespace DesertPaintLab +{ + public class PlayerProfile + { + string name; + string directory; + string reactFile; + + SortedDictionary> reactions = + new SortedDictionary>(); + + public PlayerProfile(string name, string directory) + { + this.name = name; + this.directory = directory; + this.reactFile = System.IO.Path.Combine(directory, "dp_reactions.txt"); + } + + public void Initialize() + { + // Create new directory. + System.IO.Directory.CreateDirectory(directory); + + // Copy template files into new directory. + string templatePath = System.IO.Path.Combine( + System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), + "template"); + + DirectoryInfo di = new DirectoryInfo(templatePath); + FileInfo[] templateFiles = di.GetFiles(); + + foreach (FileInfo file in templateFiles) + { + System.IO.File.Copy(file.FullName, + System.IO.Path.Combine(directory, file.Name), true); + } + } + + public void ConvertFromPP(string ppFile, string dpFile) + { + string line; + using (StreamReader reader = new StreamReader(ppFile)) + { + using (StreamWriter writer = new StreamWriter(dpFile)) + { + while ((line = reader.ReadLine()) != null) + { + string[] tokens = line.Split(null); + if ((tokens.Length > 0) && (tokens[0] != "//")) + { + // Write reaction. + writer.Write(tokens[0] + " " + tokens[2] + " "); + switch (tokens[4]) + { + case "W": + writer.WriteLine(tokens[6] + " " + tokens[6] + " " + tokens[6]); + break; + case "R": + writer.WriteLine(tokens[6] + " 0 0"); + break; + case "G": + writer.WriteLine("0 " + tokens[6] + " 0"); + break; + case "B": + writer.WriteLine("0 0 " + tokens[6]); + break; + } + + // Write reverse reaction. + writer.Write(tokens[2] + " " + tokens[0] + " "); + switch (tokens[4]) + { + case "W": + writer.WriteLine(tokens[8] + " " + tokens[8] + " " + tokens[8]); + break; + case "R": + writer.WriteLine(tokens[8] + " 0 0"); + break; + case "G": + writer.WriteLine("0 " + tokens[8] + " 0"); + break; + case "B": + writer.WriteLine("0 0 " + tokens[8]); + break; + } + } + } + } + } + } + + public bool SaveToPP(string ppFile) + { + Reaction reaction1, reaction2; + SortedDictionary secondReagentDict; + using (StreamWriter writer = new StreamWriter(ppFile)) + { + foreach (KeyValuePair> firstPair in reactions) + { + foreach (KeyValuePair secondPair in firstPair.Value) + { + reaction1 = secondPair.Value; + if ((reaction1 != null) && !reaction1.Exported) + { + reaction2 = null; + reactions.TryGetValue(secondPair.Key, out secondReagentDict); + if (secondReagentDict != null) + { + secondReagentDict.TryGetValue(firstPair.Key, out reaction2); + } + if (reaction2 != null) + { + writer.Write(firstPair.Key + " | " + secondPair.Key + " | "); + if ((Math.Abs(reaction1.Red) > Math.Abs(reaction1.Green)) || + (Math.Abs(reaction2.Red) > Math.Abs(reaction2.Green))) + { + writer.WriteLine("R | " + reaction1.Red + " | " + reaction2.Red); + } + else if ((Math.Abs(reaction1.Green) > Math.Abs(reaction1.Red)) || + (Math.Abs(reaction2.Green) > Math.Abs(reaction2.Red))) + { + writer.WriteLine("G | " + reaction1.Green + " | " + reaction2.Green); + } + else if ((Math.Abs(reaction1.Blue) > Math.Abs(reaction1.Red)) || + (Math.Abs(reaction2.Blue) > Math.Abs(reaction2.Red))) + { + writer.WriteLine("B | " + reaction1.Blue + " | " + reaction2.Blue); + } + else + { + writer.WriteLine("W | " + reaction1.Red + " | " + reaction2.Red); + } + reaction1.Exported = true; + reaction2.Exported = true; + } + } + } + } + } + + // Clear Exported flags. + foreach (KeyValuePair> firstPair in reactions) + { + foreach (KeyValuePair secondPair in firstPair.Value) + { + if (secondPair.Value != null) + { + secondPair.Value.Exported = false; + } + } + } + return true; + } + + public void Import(string importDir) + { + // Convert old file. + ConvertFromPP( + System.IO.Path.Combine(importDir, "reactions.txt"), + reactFile); + try + { + // If there is an ingredients file, move it in. + System.IO.File.Copy( + System.IO.Path.Combine(importDir, "ingredients.txt"), + System.IO.Path.Combine(directory, "ingredients.txt"), + true); + } + catch (Exception) + { + // If there is no ingredients file, we don't really care. + } + } + + public void Export(string file) + { + SaveToPP(file); + } + + public void Load() + { + string line; + SortedDictionary dict; + reactions.Clear(); + ReagentManager.Load(System.IO.Path.Combine(directory, "ingredients.txt")); + ReagentManager.InitializeReactions(ref reactions); + using (StreamReader reader = new StreamReader(reactFile)) + { + while ((line = reader.ReadLine()) != null) + { + string[] tokens = line.Split(null); + reactions.TryGetValue(tokens[0], out dict); + dict[tokens[1]] = new Reaction(int.Parse(tokens[2]), int.Parse(tokens[3]), int.Parse(tokens[4])); + } + } + } + + public void Save() + { + Reaction reaction; + using (StreamWriter writer = new StreamWriter(reactFile, false)) + { + foreach (KeyValuePair> firstPair in reactions) + { + foreach (KeyValuePair secondPair in firstPair.Value) + { + reaction = secondPair.Value; + + if (reaction != null) + { + writer.WriteLine(firstPair.Key + " " + secondPair.Key + " " + + reaction.Red + " " + reaction.Green + " " + reaction.Blue); + } + } + } + } + } + + public Reaction FindReaction(Reagent reagent1, Reagent reagent2) + { + SortedDictionary secondReagentDict = null; + Reaction reaction = null; + reactions.TryGetValue(reagent1.Name, out secondReagentDict); + if (secondReagentDict != null) + { + secondReagentDict.TryGetValue(reagent2.Name, out reaction); + } + return reaction; + } + + public void SetReaction(Reagent reagent1, Reagent reagent2, Reaction reaction) + { + SortedDictionary secondReagentDict = null; + reactions.TryGetValue(reagent1.Name, out secondReagentDict); + if (secondReagentDict != null) + { + secondReagentDict[reagent2.Name] = reaction; + } + } + } +} + diff --git a/Reaction.cs b/Reaction.cs new file mode 100644 --- /dev/null +++ b/Reaction.cs @@ -0,0 +1,61 @@ +using System; +namespace DesertPaintLab +{ + public class Reaction + { + int red = 0; + int green = 0; + int blue = 0; + bool exported = false; + + public int Red + { + get + { + return red; + } + } + + public int Green + { + get + { + return green; + } + } + + public int Blue + { + get + { + return blue; + } + } + + public bool Exported + { + get + { + return exported; + } + set + { + exported = value; + } + } + + public Reaction(int r, int g, int b) + { + red = r; + green = g; + blue = b; + } + + public override string ToString() + { + return "[" + red + ", " + green + ", " + blue + "]"; + } + + } +} + diff --git a/Reagent.cs b/Reagent.cs new file mode 100644 --- /dev/null +++ b/Reagent.cs @@ -0,0 +1,62 @@ +using System; + +namespace DesertPaintLab +{ + public class Reagent + { + string name; + bool isCatalyst = false; + PaintColor color; + + public bool IsCatalyst + { + get + { + return isCatalyst; + } + } + + public PaintColor Color + { + get + { + return color; + } + } + + public string Name + { + get + { + return name; + } + } + + public Reagent(string name) + { + this.name = name; + isCatalyst = true; + } + + public Reagent(string name, byte red, byte green, byte blue) + { + color = new PaintColor(red, green, blue); + this.name = name; + } + + public override string ToString() + { + if (isCatalyst) + { + return "[" + name + ", catalyst]"; + } + else + { + return "[" + name + ", " + color.ToString() + "]"; + } + } + + + } +} + diff --git a/ReagentManager.cs b/ReagentManager.cs new file mode 100644 --- /dev/null +++ b/ReagentManager.cs @@ -0,0 +1,128 @@ +using System; +using System.IO; +using System.Collections.Generic; +using System.Text.RegularExpressions; + +namespace DesertPaintLab +{ + public class ReagentManager + { + static Regex reagentRegex = new Regex(@"(?\w+)\s*\|\s*(?\d+),\s*(?\d+),\s*(?\d+).*"); + static Regex catalystRegex = new Regex(@"(?\w+)\s*\|\s*catalyst"); + + static SortedDictionary reagents = new SortedDictionary(); + + static Gtk.ListStore nameStore = new Gtk.ListStore(typeof(string)); + + static public Gtk.ListStore NameListModel + { + get + { + return nameStore; + } + } + + public ReagentManager () + { + + } + + public static void Load(string file) + { + Match match; + string line; + reagents.Clear(); + using (StreamReader reader = new StreamReader(file)) + { + while ((line = reader.ReadLine()) != null) + { + match = reagentRegex.Match(line); + if (match.Success) + { + string name = match.Groups["name"].Value; + reagents.Add(name, + new Reagent(name, + byte.Parse(match.Groups["red"].Value), + byte.Parse(match.Groups["green"].Value), + byte.Parse(match.Groups["blue"].Value))); + nameStore.AppendValues(name); + } + else + { + match = catalystRegex.Match(line); + if (match.Success) + { + string name = match.Groups["name"].Value; + reagents.Add(name, new Reagent(name)); + nameStore.AppendValues(name); + } + } + } + } + } + + public static void InitializeReactions(ref SortedDictionary> reactions) + { + foreach (KeyValuePair pair1 in reagents) + { + SortedDictionary dict = new SortedDictionary(); + foreach (KeyValuePair pair2 in reagents) + { + if (pair1.Key != pair2.Key) + { + dict.Add(pair2.Key, null); + } + } + reactions.Add(pair1.Key, dict); + } + } + + public static void PopulateReagents(ref Gtk.ComboBox comboBox) + { + comboBox.Clear(); + + Gtk.CellRendererText cell = new Gtk.CellRendererText(); + comboBox.PackStart(cell, false); + comboBox.AddAttribute(cell, "text", 0); + Gtk.ListStore store = new Gtk.ListStore(typeof(string)); + comboBox.Model = store; + + store.AppendValues(""); + foreach (KeyValuePair pair in reagents) + { + store.AppendValues(pair.Key); + } + } + + /* + public static void PopulatePigments(ref Gtk.ComboBox comboBox) + { + comboBox.Clear(); + + Gtk.CellRendererText cell = new Gtk.CellRendererText(); + comboBox.PackStart(cell, false); + comboBox.AddAttribute(cell, "text", 0); + Gtk.ListStore store = new Gtk.ListStore(typeof(string)); + comboBox.Model = store; + + store.AppendValues(""); + foreach (KeyValuePair pair in reagents) + { + if (!pair.Value.IsCatalyst) + { + store.AppendValues(pair.Key); + } + } + } + */ + + public static Reagent GetReagent(string reagentName) + { + Reagent returnVal; + reagents.TryGetValue(reagentName, out returnVal); + return returnVal; + } + } + +} + diff --git a/SelectProfileDialog.cs b/SelectProfileDialog.cs new file mode 100644 --- /dev/null +++ b/SelectProfileDialog.cs @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2010, Tess Snider + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +using System; +using System.Collections.Generic; + +namespace DesertPaintLab +{ + public partial class SelectProfileDialog : Gtk.Dialog + { + List profileList = null; + Gtk.ListStore profileStore = new Gtk.ListStore(typeof(string)); + string selectedProfile; + + public int ProfileCount + { + get + { + return profileList.Count; + } + } + + public List ProfileList + { + get + { + return profileList; + } + set + { + profileList = value; + profileStore.Clear(); + foreach (string name in profileList) + { + profileStore.AppendValues(name); + } + } + } + + public string SelectedProfile + { + get + { + return selectedProfile; + } + } + + public SelectProfileDialog() + { + this.Build(); + + Gtk.TreeViewColumn nameColumn = new Gtk.TreeViewColumn(); + Gtk.CellRendererText nameColumnCell = new Gtk.CellRendererText(); + nameColumn.PackStart(nameColumnCell, true); + nameColumn.Title = "Name"; + profileListView.AppendColumn(nameColumn); + nameColumn.AddAttribute(nameColumnCell, "text", 0); + + profileListView.Model = profileStore; + } + + protected virtual void OnCursorChanged(object sender, System.EventArgs e) + { + Gtk.TreeModel model; + Gtk.TreeIter iter; + + Gtk.TreeSelection selection = profileListView.Selection; + if ((selection != null) && selection.GetSelected(out model, out iter)) + { + selectedProfile = model.GetValue(iter, 0).ToString(); + } + else + { + selectedProfile = ""; + } + } + + } +} + diff --git a/SimWindow.cs b/SimWindow.cs new file mode 100644 --- /dev/null +++ b/SimWindow.cs @@ -0,0 +1,12 @@ +using System; +namespace DesertPaintLab +{ + public partial class SimWindow : Gtk.Window + { + public SimWindow () : base(Gtk.WindowType.Toplevel) + { + this.Build (); + } + } +} + diff --git a/SimulatorWindow.cs b/SimulatorWindow.cs new file mode 100644 --- /dev/null +++ b/SimulatorWindow.cs @@ -0,0 +1,230 @@ +/* + * Copyright (c) 2010, Tess Snider + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +using System; +using System.Collections.Generic; + +namespace DesertPaintLab +{ + public partial class SimulatorWindow : Gtk.Window + { + PlayerProfile profile; + Gtk.ListStore recipeData = new Gtk.ListStore(typeof(string), typeof(int)); + + public SimulatorWindow(PlayerProfile profile) : base(Gtk.WindowType.Toplevel) + { + this.profile = profile; + this.Build (); + + Gtk.TreeViewColumn reagentColumn = new Gtk.TreeViewColumn(); + Gtk.CellRendererText reagentColumnCell = new Gtk.CellRendererText(); + reagentColumn.PackStart(reagentColumnCell, true); + reagentColumn.Title = "Ingredient"; + + reagentListView.AppendColumn(reagentColumn); + reagentColumn.AddAttribute(reagentColumnCell, "text", 0); + + reagentListView.Model = ReagentManager.NameListModel; + + Gtk.TreeViewColumn additiveColumn = new Gtk.TreeViewColumn(); + Gtk.CellRendererText additiveColumnCell = new Gtk.CellRendererText(); + additiveColumn.PackStart(additiveColumnCell, true); + additiveColumn.Title = "Ingredient"; + + recipeView.AppendColumn(additiveColumn); + additiveColumn.AddAttribute(additiveColumnCell, "text", 0); + + Gtk.TreeViewColumn qtyColumn = new Gtk.TreeViewColumn(); + Gtk.CellRendererText qtyColumnCell = new Gtk.CellRendererText(); + qtyColumnCell.Editable = true; + qtyColumnCell.Edited += OnQtyEdited; + qtyColumn.PackStart(qtyColumnCell, true); + qtyColumn.Title = "Qty"; + + recipeView.AppendColumn(qtyColumn); + qtyColumn.AddAttribute(qtyColumnCell, "text", 1); + + recipeView.Model = recipeData; + + recipeData.RowChanged += OnRecipeChanged; + recipeData.RowDeleted += OnRecipeChanged; + recipeData.RowInserted += OnRecipeChanged; + recipeData.RowsReordered += OnRecipeChanged; + + } + + protected virtual void OnAddReagent(object sender, System.EventArgs e) + { + Gtk.TreeModel model; + Gtk.TreeIter iter; + + Gtk.TreeSelection selection = reagentListView.Selection; + if ((selection != null) && selection.GetSelected(out model, out iter)) + { + recipeData.AppendValues(model.GetValue(iter, 0).ToString(), 1); + + recipeData.IterNthChild(out iter, recipeView.Children.Length - 1); + + selection = recipeView.Selection; + selection.SelectIter(iter); + } + } + + protected void OnQtyEdited(object sender, Gtk.EditedArgs args) + { + Gtk.TreeIter iter; + recipeData.GetIter(out iter, new Gtk.TreePath(args.Path)); + + int oldValue = (int)recipeData.GetValue(iter, 1); + + try + { + recipeData.SetValue(iter, 1, int.Parse(args.NewText)); + UpdateRecipeColor(); + } + catch (Exception) + { + recipeData.SetValue(iter, 1, oldValue); + } + } + + protected void OnRecipeChanged(object sender, GLib.SignalArgs args) + { + UpdateRecipeColor(); + } + + void UpdateRecipeColor() + { + if (recipeView.Children.Length == 0) + { + paintSwatch.Clear(); + } + + Reaction reaction; + Gtk.TreeIter iter; + string reagentName; + int qty; + PaintColor color = null; + Reagent reagent = null; + + int baseRedSum = 0; + int baseGreenSum = 0; + int baseBlueSum = 0; + + int reactRedSum = 0; + int reactGreenSum = 0; + int reactBlueSum = 0; + + int pigmentCount = 0; + + SortedDictionary reagentSet = new SortedDictionary(); + List reagents = new List(); + + recipeData.GetIterFirst(out iter); + + do + { + reagentName = (string) recipeData.GetValue(iter, 0); + + if (reagentName == null) + { + continue; + } + + qty = (int)recipeData.GetValue(iter, 1); + reagent = ReagentManager.GetReagent(reagentName); + if (!reagent.IsCatalyst) + { + color = reagent.Color; + baseRedSum += qty * color.Red; + baseGreenSum += qty * color.Green; + baseBlueSum += qty * color.Blue; + pigmentCount += qty; + } + if (!reagentSet.ContainsKey(reagentName) && reagentSet.Count <= 4) + { + reagentSet[reagentName] = true; + // Run reactions. + foreach (Reagent otherReagent in reagents) + { + reaction = profile.FindReaction(otherReagent, reagent); + if (reaction != null) + { + reactRedSum += reaction.Red; + reactGreenSum += reaction.Green; + reactBlueSum += reaction.Blue; + } + } + reagents.Add(reagent); + } + + } + while (recipeData.IterNext(ref iter)); + + paintSwatch.Color = new PaintColor( + CalculateColor(baseRedSum, pigmentCount, reactRedSum), + CalculateColor(baseGreenSum, pigmentCount, reactGreenSum), + CalculateColor(baseBlueSum, pigmentCount, reactBlueSum)); + } + + byte CalculateColor(int baseSum, int pigmentCount, int reactSum) + { + return (byte)Math.Max(Math.Min(Math.Round((((float)baseSum / (float)pigmentCount) + (float)reactSum)), 255), 0); + } + + protected virtual void OnIncrementReagent (object sender, System.EventArgs e) + { + Gtk.TreeModel model; + Gtk.TreeIter iter; + + Gtk.TreeSelection selection = recipeView.Selection; + if ((selection != null) && selection.GetSelected(out model, out iter)) + { + int oldValue = (int)recipeData.GetValue(iter, 1); + recipeData.SetValue(iter, 1, oldValue + 1); + } + + } + + protected virtual void OnDecrementReagent (object sender, System.EventArgs e) + { + Gtk.TreeModel model; + Gtk.TreeIter iter; + + Gtk.TreeSelection selection = recipeView.Selection; + if ((selection != null) && selection.GetSelected(out model, out iter)) + { + int oldValue = (int)recipeData.GetValue(iter, 1); + if (oldValue == 1) + { + recipeData.Remove(ref iter); + } + else + { + recipeData.SetValue(iter, 1, oldValue - 1); + } + } + + } + + } +} \ No newline at end of file diff --git a/bin/Debug/DesertPaintLab/colors.txt b/bin/Debug/DesertPaintLab/colors.txt new file mode 100644 --- /dev/null +++ b/bin/Debug/DesertPaintLab/colors.txt @@ -0,0 +1,142 @@ +#F0F8FF AliceBlue +#FAEBD7 AntiqueWhite +#00FFFF Aqua +#7FFFD4 Aquamarine +#F0FFFF Azure +#F5F5DC Beige +#FFE4C4 Bisque +#010101 Black +#FFEBCD BlanchedAlmond +#0000FF Blue +#8A2BE2 BlueViolet +#A52A2A Brown +#DEB887 Burlywood +#5F9EA0 CadetBlue +#E07020 Carrot +#7FFF00 Chartreuse +#D2691E Chocolate +#FF7F50 Coral +#6495ED CornflowerBlue +#FFF8DC Cornsilk +#DC143C Crimson +#00008B DarkBlue +#008B8B DarkCyan +#B8860B DarkGoldenrod +#A9A9A9 DarkGray +#006400 DarkGreen +#BDB76B DarkKhaki +#8B008B DarkMagenta +#556B2F DarkOliveGreen +#FF8C00 DarkOrange +#9932CC DarkOrchid +#8B0000 DarkRed +#E9967A DarkSalmon +#8FBC8F DarkSeaGreen +#483D8B DarkSlateBlue +#2F4F4F DarkSlateGray +#00CED1 DarkTurquoise +#9400D3 DarkViolet +#FF1493 DeepPink +#00BFFF DeepSkyBlue +#696969 DimGray +#1E90FF DodgerBlue +#D19275 Feldspar +#B22222 FireBrick +#FFFAF0 FloralWhite +#228B22 ForestGreen +#FF00FF Fuchsia +#DCDCDC Gainsboro +#F8F8FF GhostWhite +#FFD700 Gold +#DAA520 Goldenrod +#808080 Gray +#008000 Green +#ADFF2F GreenYellow +#F0FFF0 Honeydew +#FF69B4 HotPink +#CD5C5C IndianRed +#4B0082 Indigo +#FFFFF0 Ivory +#F0E68C Khaki +#E6E6FA Lavender +#FFF0F5 LavenderBlush +#7CFC00 LawnGreen +#FFFACD LemonChiffon +#ADD8E6 LightBlue +#F08080 LightCoral +#E0FFFF LightCyan +#FAFAD2 LightGoldenrodYellow +#90EE90 LightGreen +#D3D3D3 LightGrey +#FFB6C1 LightPink +#FFA07A LightSalmon +#20B2AA LightSeaGreen +#87CEFA LightSkyBlue +#8470FF LightSlateBlue +#778899 LightSlateGray +#B0C4DE LightSteelBlue +#FFFFE0 LightYellow +#00FF00 Lime +#32CD32 LimeGreen +#FAF0E6 Linen +#800000 Maroon +#66CDAA MediumAquamarine +#0000CD MediumBlue +#BA55D3 MediumOrchid +#9370DB MediumPurple +#3CB371 MediumSeaGreen +#7B68EE MediumSlateBlue +#00FA9A MediumSpringGreen +#48D1CC MediumTurquoise +#C71585 MediumVioletRed +#191970 MidnightBlue +#F5FFFA MintCream +#FFE4E1 MistyRose +#FFE4B5 Moccasin +#FFDEAD NavajoWhite +#000080 Navy +#FDF5E6 OldLace +#808000 Olive +#6B8E23 OliveDrab +#FFA500 Orange +#FF4500 OrangeRed +#DA70D6 Orchid +#EEE8AA PaleGoldenrod +#98FB98 PaleGreen +#AFEEEE PaleTurquoise +#DB7093 PaleVioletRed +#FFEFD5 PapayaWhip +#FFDAB9 PeachPuff +#CD853F Peru +#FFC0CB Pink +#DDA0DD Plum +#B0E0E6 PowderBlue +#800080 Purple +#FF0000 Red +#BC8F8F RosyBrown +#4169E1 RoyalBlue +#8B4513 SaddleBrown +#FA8072 Salmon +#F4A460 SandyBrown +#2E8B57 SeaGreen +#FFF5EE Seashell +#A0522D Sienna +#C0C0C0 Silver +#87CEEB SkyBlue +#6A5ACD SlateBlue +#708090 SlateGray +#FFFAFA Snow +#00FF7F SpringGreen +#4682B4 SteelBlue +#D2B48C Tan +#008080 Teal +#D8BFD8 Thistle +#FF6347 Tomato +#40E0D0 Turquoise +#EE82EE Violet +#D02090 VioletRed +#F5DEB3 Wheat +#FFFFFF White +#F5F5F5 WhiteSmoke +#FFFF00 Yellow +#9ACD32 YellowGreen \ No newline at end of file diff --git a/bin/Debug/DesertPaintLab/template/dp_reactions.txt b/bin/Debug/DesertPaintLab/template/dp_reactions.txt new file mode 100644 --- /dev/null +++ b/bin/Debug/DesertPaintLab/template/dp_reactions.txt @@ -0,0 +1,1 @@ + \ No newline at end of file diff --git a/bin/Debug/DesertPaintLab/template/ingredients.txt b/bin/Debug/DesertPaintLab/template/ingredients.txt new file mode 100644 --- /dev/null +++ b/bin/Debug/DesertPaintLab/template/ingredients.txt @@ -0,0 +1,21 @@ +// Ingredients are in the form: +// Name | RGB values | cost | enabled (Y/N) | bulk/normal | max items per paint (1-20) +// +// It is recommended to only change the cost value +// It is not recommended to set many of the ingredients above 10 per paint + +Cabbage | 128, 64, 144 | 8 | Y | bulk | 10 +Clay | 128, 96, 32 | 4 | Y | bulk | 20 +Carrot | 224, 112, 32 | 10 | Y | bulk | 10 +Copper | 64, 192, 192 | 30 | Y | normal | 8 +Iron | 96, 48, 32 | 30 | Y | normal | 8 +Lead | 80, 80, 96 | 50 | Y | normal | 6 +RedSand | 144, 16, 24 | 10 | Y | bulk | 20 +Silver | 16, 16, 32 | 50 | N | normal | 6 +ToadSkin | 48, 96, 48 | 500 | N | normal | 4 +DeadTongue | 112, 64, 64 | 500 | N | normal | 4 +EarthLight | 128, 240, 224 | 10000 | N | normal | 4 +Lime | catalyst | 20 | Y | normal | 1 +Sulfur | catalyst | 10 | Y | normal | 1 +Potash | catalyst | 50 | Y | normal | 1 +Saltpeter | catalyst | 10 | Y | normal | 1 \ No newline at end of file diff --git a/bin/Debug/colors.txt b/bin/Debug/colors.txt new file mode 100644 --- /dev/null +++ b/bin/Debug/colors.txt @@ -0,0 +1,142 @@ +#F0F8FF AliceBlue +#FAEBD7 AntiqueWhite +#00FFFF Aqua +#7FFFD4 Aquamarine +#F0FFFF Azure +#F5F5DC Beige +#FFE4C4 Bisque +#010101 Black +#FFEBCD BlanchedAlmond +#0000FF Blue +#8A2BE2 BlueViolet +#A52A2A Brown +#DEB887 Burlywood +#5F9EA0 CadetBlue +#E07020 Carrot +#7FFF00 Chartreuse +#D2691E Chocolate +#FF7F50 Coral +#6495ED CornflowerBlue +#FFF8DC Cornsilk +#DC143C Crimson +#00008B DarkBlue +#008B8B DarkCyan +#B8860B DarkGoldenrod +#A9A9A9 DarkGray +#006400 DarkGreen +#BDB76B DarkKhaki +#8B008B DarkMagenta +#556B2F DarkOliveGreen +#FF8C00 DarkOrange +#9932CC DarkOrchid +#8B0000 DarkRed +#E9967A DarkSalmon +#8FBC8F DarkSeaGreen +#483D8B DarkSlateBlue +#2F4F4F DarkSlateGray +#00CED1 DarkTurquoise +#9400D3 DarkViolet +#FF1493 DeepPink +#00BFFF DeepSkyBlue +#696969 DimGray +#1E90FF DodgerBlue +#D19275 Feldspar +#B22222 FireBrick +#FFFAF0 FloralWhite +#228B22 ForestGreen +#FF00FF Fuchsia +#DCDCDC Gainsboro +#F8F8FF GhostWhite +#FFD700 Gold +#DAA520 Goldenrod +#808080 Gray +#008000 Green +#ADFF2F GreenYellow +#F0FFF0 Honeydew +#FF69B4 HotPink +#CD5C5C IndianRed +#4B0082 Indigo +#FFFFF0 Ivory +#F0E68C Khaki +#E6E6FA Lavender +#FFF0F5 LavenderBlush +#7CFC00 LawnGreen +#FFFACD LemonChiffon +#ADD8E6 LightBlue +#F08080 LightCoral +#E0FFFF LightCyan +#FAFAD2 LightGoldenrodYellow +#90EE90 LightGreen +#D3D3D3 LightGrey +#FFB6C1 LightPink +#FFA07A LightSalmon +#20B2AA LightSeaGreen +#87CEFA LightSkyBlue +#8470FF LightSlateBlue +#778899 LightSlateGray +#B0C4DE LightSteelBlue +#FFFFE0 LightYellow +#00FF00 Lime +#32CD32 LimeGreen +#FAF0E6 Linen +#800000 Maroon +#66CDAA MediumAquamarine +#0000CD MediumBlue +#BA55D3 MediumOrchid +#9370DB MediumPurple +#3CB371 MediumSeaGreen +#7B68EE MediumSlateBlue +#00FA9A MediumSpringGreen +#48D1CC MediumTurquoise +#C71585 MediumVioletRed +#191970 MidnightBlue +#F5FFFA MintCream +#FFE4E1 MistyRose +#FFE4B5 Moccasin +#FFDEAD NavajoWhite +#000080 Navy +#FDF5E6 OldLace +#808000 Olive +#6B8E23 OliveDrab +#FFA500 Orange +#FF4500 OrangeRed +#DA70D6 Orchid +#EEE8AA PaleGoldenrod +#98FB98 PaleGreen +#AFEEEE PaleTurquoise +#DB7093 PaleVioletRed +#FFEFD5 PapayaWhip +#FFDAB9 PeachPuff +#CD853F Peru +#FFC0CB Pink +#DDA0DD Plum +#B0E0E6 PowderBlue +#800080 Purple +#FF0000 Red +#BC8F8F RosyBrown +#4169E1 RoyalBlue +#8B4513 SaddleBrown +#FA8072 Salmon +#F4A460 SandyBrown +#2E8B57 SeaGreen +#FFF5EE Seashell +#A0522D Sienna +#C0C0C0 Silver +#87CEEB SkyBlue +#6A5ACD SlateBlue +#708090 SlateGray +#FFFAFA Snow +#00FF7F SpringGreen +#4682B4 SteelBlue +#D2B48C Tan +#008080 Teal +#D8BFD8 Thistle +#FF6347 Tomato +#40E0D0 Turquoise +#EE82EE Violet +#D02090 VioletRed +#F5DEB3 Wheat +#FFFFFF White +#F5F5F5 WhiteSmoke +#FFFF00 Yellow +#9ACD32 YellowGreen \ No newline at end of file diff --git a/bin/Debug/template/dp_reactions.txt b/bin/Debug/template/dp_reactions.txt new file mode 100644 --- /dev/null +++ b/bin/Debug/template/dp_reactions.txt @@ -0,0 +1,1 @@ + \ No newline at end of file diff --git a/bin/Debug/template/ingredients.txt b/bin/Debug/template/ingredients.txt new file mode 100644 --- /dev/null +++ b/bin/Debug/template/ingredients.txt @@ -0,0 +1,21 @@ +// Ingredients are in the form: +// Name | RGB values | cost | enabled (Y/N) | bulk/normal | max items per paint (1-20) +// +// It is recommended to only change the cost value +// It is not recommended to set many of the ingredients above 10 per paint + +Cabbage | 128, 64, 144 | 8 | Y | bulk | 10 +Clay | 128, 96, 32 | 4 | Y | bulk | 20 +Carrot | 224, 112, 32 | 10 | Y | bulk | 10 +Copper | 64, 192, 192 | 30 | Y | normal | 8 +Iron | 96, 48, 32 | 30 | Y | normal | 8 +Lead | 80, 80, 96 | 50 | Y | normal | 6 +RedSand | 144, 16, 24 | 10 | Y | bulk | 20 +Silver | 16, 16, 32 | 50 | N | normal | 6 +ToadSkin | 48, 96, 48 | 500 | N | normal | 4 +DeadTongue | 112, 64, 64 | 500 | N | normal | 4 +EarthLight | 128, 240, 224 | 10000 | N | normal | 4 +Lime | catalyst | 20 | Y | normal | 1 +Sulfur | catalyst | 10 | Y | normal | 1 +Potash | catalyst | 50 | Y | normal | 1 +Saltpeter | catalyst | 10 | Y | normal | 1 \ No newline at end of file diff --git a/gtk-gui/DesertPaintLab.FirstRunDialog.cs b/gtk-gui/DesertPaintLab.FirstRunDialog.cs new file mode 100644 --- /dev/null +++ b/gtk-gui/DesertPaintLab.FirstRunDialog.cs @@ -0,0 +1,86 @@ + +// This file has been generated by the GUI designer. Do not modify. +namespace DesertPaintLab +{ + public partial class FirstRunDialog + { + private global::Gtk.Label label2; + + private global::Gtk.Button buttonCancel; + + private global::Gtk.Button buttonImport; + + private global::Gtk.Button buttonNew; + + protected virtual void Build () + { + global::Stetic.Gui.Initialize (this); + // Widget DesertPaintLab.FirstRunDialog + this.Name = "DesertPaintLab.FirstRunDialog"; + this.Title = global::Mono.Unix.Catalog.GetString ("Set Up Profile"); + this.WindowPosition = ((global::Gtk.WindowPosition)(4)); + this.Modal = true; + this.AllowShrink = true; + // Internal child DesertPaintLab.FirstRunDialog.VBox + global::Gtk.VBox w1 = this.VBox; + w1.Name = "dialog1_VBox"; + w1.BorderWidth = ((uint)(2)); + // Container child dialog1_VBox.Gtk.Box+BoxChild + this.label2 = new global::Gtk.Label (); + this.label2.Name = "label2"; + this.label2.LabelProp = global::Mono.Unix.Catalog.GetString ("Since this is your first time using this program, you need a new profile.\n\nYou ca" + "n either import an existing PracticalPaint reactions.txt file, or you can start " + "a new profile from scratch."); + this.label2.Wrap = true; + w1.Add (this.label2); + global::Gtk.Box.BoxChild w2 = ((global::Gtk.Box.BoxChild)(w1[this.label2])); + w2.Position = 0; + w2.Padding = ((uint)(5)); + // Internal child DesertPaintLab.FirstRunDialog.ActionArea + global::Gtk.HButtonBox w3 = this.ActionArea; + w3.Name = "dialog1_ActionArea"; + w3.Spacing = 10; + w3.BorderWidth = ((uint)(5)); + w3.LayoutStyle = ((global::Gtk.ButtonBoxStyle)(4)); + // Container child dialog1_ActionArea.Gtk.ButtonBox+ButtonBoxChild + this.buttonCancel = new global::Gtk.Button (); + this.buttonCancel.CanDefault = true; + this.buttonCancel.CanFocus = true; + this.buttonCancel.Name = "buttonCancel"; + this.buttonCancel.UseStock = true; + this.buttonCancel.UseUnderline = true; + this.buttonCancel.Label = "gtk-cancel"; + this.AddActionWidget (this.buttonCancel, -6); + global::Gtk.ButtonBox.ButtonBoxChild w4 = ((global::Gtk.ButtonBox.ButtonBoxChild)(w3[this.buttonCancel])); + w4.Expand = false; + w4.Fill = false; + // Container child dialog1_ActionArea.Gtk.ButtonBox+ButtonBoxChild + this.buttonImport = new global::Gtk.Button (); + this.buttonImport.CanDefault = true; + this.buttonImport.CanFocus = true; + this.buttonImport.Name = "buttonImport"; + this.buttonImport.UseUnderline = true; + this.buttonImport.Label = global::Mono.Unix.Catalog.GetString ("Import reactions.txt"); + this.AddActionWidget (this.buttonImport, -3); + global::Gtk.ButtonBox.ButtonBoxChild w5 = ((global::Gtk.ButtonBox.ButtonBoxChild)(w3[this.buttonImport])); + w5.Position = 1; + w5.Expand = false; + w5.Fill = false; + // Container child dialog1_ActionArea.Gtk.ButtonBox+ButtonBoxChild + this.buttonNew = new global::Gtk.Button (); + this.buttonNew.CanFocus = true; + this.buttonNew.Name = "buttonNew"; + this.buttonNew.UseUnderline = true; + this.buttonNew.Label = global::Mono.Unix.Catalog.GetString ("New Profile"); + this.AddActionWidget (this.buttonNew, -5); + global::Gtk.ButtonBox.ButtonBoxChild w6 = ((global::Gtk.ButtonBox.ButtonBoxChild)(w3[this.buttonNew])); + w6.Position = 2; + w6.Expand = false; + w6.Fill = false; + if ((this.Child != null)) { + this.Child.ShowAll (); + } + this.DefaultWidth = 416; + this.DefaultHeight = 189; + this.Show (); + } + } +} diff --git a/gtk-gui/DesertPaintLab.NewProfileDialog.cs b/gtk-gui/DesertPaintLab.NewProfileDialog.cs new file mode 100644 --- /dev/null +++ b/gtk-gui/DesertPaintLab.NewProfileDialog.cs @@ -0,0 +1,86 @@ + +// This file has been generated by the GUI designer. Do not modify. +namespace DesertPaintLab +{ + public partial class NewProfileDialog + { + private global::Gtk.Label label1; + + private global::Gtk.Entry profileNameEntry; + + private global::Gtk.Button buttonCancel; + + private global::Gtk.Button buttonOk; + + protected virtual void Build () + { + global::Stetic.Gui.Initialize (this); + // Widget DesertPaintLab.NewProfileDialog + this.Name = "DesertPaintLab.NewProfileDialog"; + this.Title = global::Mono.Unix.Catalog.GetString ("New Profile"); + this.WindowPosition = ((global::Gtk.WindowPosition)(4)); + this.BorderWidth = ((uint)(5)); + // Internal child DesertPaintLab.NewProfileDialog.VBox + global::Gtk.VBox w1 = this.VBox; + w1.Name = "dialog1_VBox"; + w1.Spacing = 10; + w1.BorderWidth = ((uint)(9)); + // Container child dialog1_VBox.Gtk.Box+BoxChild + this.label1 = new global::Gtk.Label (); + this.label1.Name = "label1"; + this.label1.LabelProp = global::Mono.Unix.Catalog.GetString ("Name your new profile:"); + w1.Add (this.label1); + global::Gtk.Box.BoxChild w2 = ((global::Gtk.Box.BoxChild)(w1[this.label1])); + w2.Position = 0; + w2.Expand = false; + w2.Fill = false; + // Container child dialog1_VBox.Gtk.Box+BoxChild + this.profileNameEntry = new global::Gtk.Entry (); + this.profileNameEntry.CanFocus = true; + this.profileNameEntry.Name = "profileNameEntry"; + this.profileNameEntry.IsEditable = true; + w1.Add (this.profileNameEntry); + global::Gtk.Box.BoxChild w3 = ((global::Gtk.Box.BoxChild)(w1[this.profileNameEntry])); + w3.Position = 1; + w3.Expand = false; + w3.Fill = false; + // Internal child DesertPaintLab.NewProfileDialog.ActionArea + global::Gtk.HButtonBox w4 = this.ActionArea; + w4.Name = "dialog1_ActionArea"; + w4.Spacing = 10; + w4.BorderWidth = ((uint)(5)); + w4.LayoutStyle = ((global::Gtk.ButtonBoxStyle)(4)); + // Container child dialog1_ActionArea.Gtk.ButtonBox+ButtonBoxChild + this.buttonCancel = new global::Gtk.Button (); + this.buttonCancel.CanDefault = true; + this.buttonCancel.CanFocus = true; + this.buttonCancel.Name = "buttonCancel"; + this.buttonCancel.UseStock = true; + this.buttonCancel.UseUnderline = true; + this.buttonCancel.Label = "gtk-cancel"; + this.AddActionWidget (this.buttonCancel, -6); + global::Gtk.ButtonBox.ButtonBoxChild w5 = ((global::Gtk.ButtonBox.ButtonBoxChild)(w4[this.buttonCancel])); + w5.Expand = false; + w5.Fill = false; + // Container child dialog1_ActionArea.Gtk.ButtonBox+ButtonBoxChild + this.buttonOk = new global::Gtk.Button (); + this.buttonOk.CanDefault = true; + this.buttonOk.CanFocus = true; + this.buttonOk.Name = "buttonOk"; + this.buttonOk.UseStock = true; + this.buttonOk.UseUnderline = true; + this.buttonOk.Label = "gtk-ok"; + this.AddActionWidget (this.buttonOk, -5); + global::Gtk.ButtonBox.ButtonBoxChild w6 = ((global::Gtk.ButtonBox.ButtonBoxChild)(w4[this.buttonOk])); + w6.Position = 1; + w6.Expand = false; + w6.Fill = false; + if ((this.Child != null)) { + this.Child.ShowAll (); + } + this.DefaultWidth = 318; + this.DefaultHeight = 177; + this.Show (); + } + } +} diff --git a/gtk-gui/DesertPaintLab.PaintSwatch.cs b/gtk-gui/DesertPaintLab.PaintSwatch.cs new file mode 100644 --- /dev/null +++ b/gtk-gui/DesertPaintLab.PaintSwatch.cs @@ -0,0 +1,56 @@ + +// This file has been generated by the GUI designer. Do not modify. +namespace DesertPaintLab +{ + public partial class PaintSwatch + { + private global::Gtk.VBox vbox1; + + private global::Gtk.Label colorNameLabel; + + private global::Gtk.DrawingArea colorBox; + + private global::Gtk.Label rgbLabel; + + protected virtual void Build () + { + global::Stetic.Gui.Initialize (this); + // Widget DesertPaintLab.PaintSwatch + global::Stetic.BinContainer.Attach (this); + this.Name = "DesertPaintLab.PaintSwatch"; + // Container child DesertPaintLab.PaintSwatch.Gtk.Container+ContainerChild + this.vbox1 = new global::Gtk.VBox (); + this.vbox1.Name = "vbox1"; + this.vbox1.Spacing = 6; + // Container child vbox1.Gtk.Box+BoxChild + this.colorNameLabel = new global::Gtk.Label (); + this.colorNameLabel.Name = "colorNameLabel"; + this.colorNameLabel.LabelProp = global::Mono.Unix.Catalog.GetString ("Unknown"); + this.vbox1.Add (this.colorNameLabel); + global::Gtk.Box.BoxChild w1 = ((global::Gtk.Box.BoxChild)(this.vbox1[this.colorNameLabel])); + w1.Position = 0; + w1.Expand = false; + w1.Fill = false; + // Container child vbox1.Gtk.Box+BoxChild + this.colorBox = new global::Gtk.DrawingArea (); + this.colorBox.Name = "colorBox"; + this.vbox1.Add (this.colorBox); + global::Gtk.Box.BoxChild w2 = ((global::Gtk.Box.BoxChild)(this.vbox1[this.colorBox])); + w2.Position = 1; + // Container child vbox1.Gtk.Box+BoxChild + this.rgbLabel = new global::Gtk.Label (); + this.rgbLabel.Name = "rgbLabel"; + this.rgbLabel.LabelProp = global::Mono.Unix.Catalog.GetString ("???, ???, ???"); + this.vbox1.Add (this.rgbLabel); + global::Gtk.Box.BoxChild w3 = ((global::Gtk.Box.BoxChild)(this.vbox1[this.rgbLabel])); + w3.Position = 2; + w3.Expand = false; + w3.Fill = false; + this.Add (this.vbox1); + if ((this.Child != null)) { + this.Child.ShowAll (); + } + this.Hide (); + } + } +} diff --git a/gtk-gui/DesertPaintLab.SelectProfileDialog.cs b/gtk-gui/DesertPaintLab.SelectProfileDialog.cs new file mode 100644 --- /dev/null +++ b/gtk-gui/DesertPaintLab.SelectProfileDialog.cs @@ -0,0 +1,99 @@ + +// This file has been generated by the GUI designer. Do not modify. +namespace DesertPaintLab +{ + public partial class SelectProfileDialog + { + private global::Gtk.Label label3; + + private global::Gtk.TreeView profileListView; + + private global::Gtk.Button buttonCancel; + + private global::Gtk.Button button56; + + private global::Gtk.Button buttonOk; + + protected virtual void Build () + { + global::Stetic.Gui.Initialize (this); + // Widget DesertPaintLab.SelectProfileDialog + this.Name = "DesertPaintLab.SelectProfileDialog"; + this.Title = global::Mono.Unix.Catalog.GetString ("Open Profile"); + this.WindowPosition = ((global::Gtk.WindowPosition)(4)); + this.Modal = true; + this.BorderWidth = ((uint)(5)); + // Internal child DesertPaintLab.SelectProfileDialog.VBox + global::Gtk.VBox w1 = this.VBox; + w1.Name = "dialog1_VBox"; + w1.Spacing = 10; + w1.BorderWidth = ((uint)(2)); + // Container child dialog1_VBox.Gtk.Box+BoxChild + this.label3 = new global::Gtk.Label (); + this.label3.Name = "label3"; + this.label3.LabelProp = global::Mono.Unix.Catalog.GetString ("Select the profile you would like to open:"); + w1.Add (this.label3); + global::Gtk.Box.BoxChild w2 = ((global::Gtk.Box.BoxChild)(w1[this.label3])); + w2.Position = 0; + w2.Expand = false; + w2.Fill = false; + // Container child dialog1_VBox.Gtk.Box+BoxChild + this.profileListView = new global::Gtk.TreeView (); + this.profileListView.CanFocus = true; + this.profileListView.Name = "profileListView"; + this.profileListView.EnableSearch = false; + w1.Add (this.profileListView); + global::Gtk.Box.BoxChild w3 = ((global::Gtk.Box.BoxChild)(w1[this.profileListView])); + w3.Position = 1; + // Internal child DesertPaintLab.SelectProfileDialog.ActionArea + global::Gtk.HButtonBox w4 = this.ActionArea; + w4.Name = "dialog1_ActionArea"; + w4.Spacing = 10; + w4.BorderWidth = ((uint)(5)); + w4.LayoutStyle = ((global::Gtk.ButtonBoxStyle)(4)); + // Container child dialog1_ActionArea.Gtk.ButtonBox+ButtonBoxChild + this.buttonCancel = new global::Gtk.Button (); + this.buttonCancel.CanDefault = true; + this.buttonCancel.CanFocus = true; + this.buttonCancel.Name = "buttonCancel"; + this.buttonCancel.UseStock = true; + this.buttonCancel.UseUnderline = true; + this.buttonCancel.Label = "gtk-cancel"; + this.AddActionWidget (this.buttonCancel, -6); + global::Gtk.ButtonBox.ButtonBoxChild w5 = ((global::Gtk.ButtonBox.ButtonBoxChild)(w4[this.buttonCancel])); + w5.Expand = false; + w5.Fill = false; + // Container child dialog1_ActionArea.Gtk.ButtonBox+ButtonBoxChild + this.button56 = new global::Gtk.Button (); + this.button56.CanFocus = true; + this.button56.Name = "button56"; + this.button56.UseUnderline = true; + this.button56.Label = global::Mono.Unix.Catalog.GetString ("New Profile"); + this.AddActionWidget (this.button56, -3); + global::Gtk.ButtonBox.ButtonBoxChild w6 = ((global::Gtk.ButtonBox.ButtonBoxChild)(w4[this.button56])); + w6.Position = 1; + w6.Expand = false; + w6.Fill = false; + // Container child dialog1_ActionArea.Gtk.ButtonBox+ButtonBoxChild + this.buttonOk = new global::Gtk.Button (); + this.buttonOk.CanDefault = true; + this.buttonOk.CanFocus = true; + this.buttonOk.Name = "buttonOk"; + this.buttonOk.UseStock = true; + this.buttonOk.UseUnderline = true; + this.buttonOk.Label = "gtk-ok"; + this.AddActionWidget (this.buttonOk, -5); + global::Gtk.ButtonBox.ButtonBoxChild w7 = ((global::Gtk.ButtonBox.ButtonBoxChild)(w4[this.buttonOk])); + w7.Position = 2; + w7.Expand = false; + w7.Fill = false; + if ((this.Child != null)) { + this.Child.ShowAll (); + } + this.DefaultWidth = 400; + this.DefaultHeight = 288; + this.Show (); + this.profileListView.CursorChanged += new global::System.EventHandler (this.OnCursorChanged); + } + } +} diff --git a/gtk-gui/DesertPaintLab.SimulatorWindow.cs b/gtk-gui/DesertPaintLab.SimulatorWindow.cs new file mode 100644 --- /dev/null +++ b/gtk-gui/DesertPaintLab.SimulatorWindow.cs @@ -0,0 +1,189 @@ + +// This file has been generated by the GUI designer. Do not modify. +namespace DesertPaintLab +{ + public partial class SimulatorWindow + { + private global::Gtk.HBox hbox1; + + private global::Gtk.ScrolledWindow GtkScrolledWindow; + + private global::Gtk.TreeView reagentListView; + + private global::Gtk.VBox vbox162; + + private global::Gtk.Alignment alignment1; + + private global::Gtk.Button addReagentButton; + + private global::Gtk.Image addReagentButtonImage; + + private global::Gtk.Alignment alignment3; + + private global::Gtk.ScrolledWindow GtkScrolledWindow1; + + private global::Gtk.TreeView recipeView; + + private global::Gtk.VBox vbox3; + + private global::Gtk.Alignment alignment2; + + private global::Gtk.Button button65; + + private global::Gtk.Image image1; + + private global::Gtk.Button button66; + + private global::Gtk.Image image2; + + private global::Gtk.Alignment alignment4; + + private global::DesertPaintLab.PaintSwatch paintSwatch; + + protected virtual void Build () + { + global::Stetic.Gui.Initialize (this); + // Widget DesertPaintLab.SimulatorWindow + this.Name = "DesertPaintLab.SimulatorWindow"; + this.Title = global::Mono.Unix.Catalog.GetString ("Simulator"); + this.WindowPosition = ((global::Gtk.WindowPosition)(4)); + // Container child DesertPaintLab.SimulatorWindow.Gtk.Container+ContainerChild + this.hbox1 = new global::Gtk.HBox (); + this.hbox1.Name = "hbox1"; + this.hbox1.Spacing = 6; + this.hbox1.BorderWidth = ((uint)(12)); + // Container child hbox1.Gtk.Box+BoxChild + this.GtkScrolledWindow = new global::Gtk.ScrolledWindow (); + this.GtkScrolledWindow.Name = "GtkScrolledWindow"; + this.GtkScrolledWindow.ShadowType = ((global::Gtk.ShadowType)(1)); + // Container child GtkScrolledWindow.Gtk.Container+ContainerChild + this.reagentListView = new global::Gtk.TreeView (); + this.reagentListView.CanFocus = true; + this.reagentListView.Name = "reagentListView"; + this.GtkScrolledWindow.Add (this.reagentListView); + this.hbox1.Add (this.GtkScrolledWindow); + global::Gtk.Box.BoxChild w2 = ((global::Gtk.Box.BoxChild)(this.hbox1[this.GtkScrolledWindow])); + w2.Position = 0; + // Container child hbox1.Gtk.Box+BoxChild + this.vbox162 = new global::Gtk.VBox (); + this.vbox162.Name = "vbox162"; + this.vbox162.Spacing = 6; + // Container child vbox162.Gtk.Box+BoxChild + this.alignment1 = new global::Gtk.Alignment (0.5f, 0.5f, 1f, 1f); + this.alignment1.Name = "alignment1"; + this.vbox162.Add (this.alignment1); + global::Gtk.Box.BoxChild w3 = ((global::Gtk.Box.BoxChild)(this.vbox162[this.alignment1])); + w3.Position = 0; + // Container child vbox162.Gtk.Box+BoxChild + this.addReagentButton = new global::Gtk.Button (); + this.addReagentButton.CanFocus = true; + this.addReagentButton.Name = "addReagentButton"; + // Container child addReagentButton.Gtk.Container+ContainerChild + this.addReagentButtonImage = new global::Gtk.Image (); + this.addReagentButtonImage.Name = "addReagentButtonImage"; + this.addReagentButtonImage.Pixbuf = global::Stetic.IconLoader.LoadIcon (this, "gtk-go-forward", global::Gtk.IconSize.Menu); + this.addReagentButton.Add (this.addReagentButtonImage); + this.addReagentButton.Label = null; + this.vbox162.Add (this.addReagentButton); + global::Gtk.Box.BoxChild w5 = ((global::Gtk.Box.BoxChild)(this.vbox162[this.addReagentButton])); + w5.Position = 1; + w5.Expand = false; + w5.Fill = false; + // Container child vbox162.Gtk.Box+BoxChild + this.alignment3 = new global::Gtk.Alignment (0.5f, 0.5f, 1f, 1f); + this.alignment3.Name = "alignment3"; + this.vbox162.Add (this.alignment3); + global::Gtk.Box.BoxChild w6 = ((global::Gtk.Box.BoxChild)(this.vbox162[this.alignment3])); + w6.Position = 2; + this.hbox1.Add (this.vbox162); + global::Gtk.Box.BoxChild w7 = ((global::Gtk.Box.BoxChild)(this.hbox1[this.vbox162])); + w7.Position = 1; + w7.Expand = false; + w7.Fill = false; + // Container child hbox1.Gtk.Box+BoxChild + this.GtkScrolledWindow1 = new global::Gtk.ScrolledWindow (); + this.GtkScrolledWindow1.WidthRequest = 0; + this.GtkScrolledWindow1.Name = "GtkScrolledWindow1"; + this.GtkScrolledWindow1.ShadowType = ((global::Gtk.ShadowType)(1)); + // Container child GtkScrolledWindow1.Gtk.Container+ContainerChild + this.recipeView = new global::Gtk.TreeView (); + this.recipeView.CanFocus = true; + this.recipeView.Name = "recipeView"; + this.recipeView.EnableSearch = false; + this.recipeView.Reorderable = true; + this.GtkScrolledWindow1.Add (this.recipeView); + this.hbox1.Add (this.GtkScrolledWindow1); + global::Gtk.Box.BoxChild w9 = ((global::Gtk.Box.BoxChild)(this.hbox1[this.GtkScrolledWindow1])); + w9.Position = 2; + // Container child hbox1.Gtk.Box+BoxChild + this.vbox3 = new global::Gtk.VBox (); + this.vbox3.Name = "vbox3"; + this.vbox3.Spacing = 6; + // Container child vbox3.Gtk.Box+BoxChild + this.alignment2 = new global::Gtk.Alignment (0.5f, 0.5f, 1f, 1f); + this.alignment2.Name = "alignment2"; + this.vbox3.Add (this.alignment2); + global::Gtk.Box.BoxChild w10 = ((global::Gtk.Box.BoxChild)(this.vbox3[this.alignment2])); + w10.Position = 0; + // Container child vbox3.Gtk.Box+BoxChild + this.button65 = new global::Gtk.Button (); + this.button65.CanFocus = true; + this.button65.Name = "button65"; + // Container child button65.Gtk.Container+ContainerChild + this.image1 = new global::Gtk.Image (); + this.image1.Name = "image1"; + this.image1.Pixbuf = global::Stetic.IconLoader.LoadIcon (this, "gtk-add", global::Gtk.IconSize.Menu); + this.button65.Add (this.image1); + this.button65.Label = null; + this.vbox3.Add (this.button65); + global::Gtk.Box.BoxChild w12 = ((global::Gtk.Box.BoxChild)(this.vbox3[this.button65])); + w12.Position = 1; + w12.Expand = false; + w12.Fill = false; + // Container child vbox3.Gtk.Box+BoxChild + this.button66 = new global::Gtk.Button (); + this.button66.CanFocus = true; + this.button66.Name = "button66"; + // Container child button66.Gtk.Container+ContainerChild + this.image2 = new global::Gtk.Image (); + this.image2.Name = "image2"; + this.image2.Pixbuf = global::Stetic.IconLoader.LoadIcon (this, "gtk-remove", global::Gtk.IconSize.Menu); + this.button66.Add (this.image2); + this.button66.Label = null; + this.vbox3.Add (this.button66); + global::Gtk.Box.BoxChild w14 = ((global::Gtk.Box.BoxChild)(this.vbox3[this.button66])); + w14.Position = 2; + w14.Expand = false; + w14.Fill = false; + // Container child vbox3.Gtk.Box+BoxChild + this.alignment4 = new global::Gtk.Alignment (0.5f, 0.5f, 1f, 1f); + this.alignment4.Name = "alignment4"; + this.vbox3.Add (this.alignment4); + global::Gtk.Box.BoxChild w15 = ((global::Gtk.Box.BoxChild)(this.vbox3[this.alignment4])); + w15.Position = 3; + this.hbox1.Add (this.vbox3); + global::Gtk.Box.BoxChild w16 = ((global::Gtk.Box.BoxChild)(this.hbox1[this.vbox3])); + w16.Position = 3; + w16.Expand = false; + w16.Fill = false; + // Container child hbox1.Gtk.Box+BoxChild + this.paintSwatch = new global::DesertPaintLab.PaintSwatch (); + this.paintSwatch.WidthRequest = 200; + this.paintSwatch.Events = ((global::Gdk.EventMask)(256)); + this.paintSwatch.Name = "paintSwatch"; + this.hbox1.Add (this.paintSwatch); + global::Gtk.Box.BoxChild w17 = ((global::Gtk.Box.BoxChild)(this.hbox1[this.paintSwatch])); + w17.Position = 4; + this.Add (this.hbox1); + if ((this.Child != null)) { + this.Child.ShowAll (); + } + this.DefaultWidth = 804; + this.DefaultHeight = 390; + this.Show (); + this.addReagentButton.Clicked += new global::System.EventHandler (this.OnAddReagent); + this.button65.Clicked += new global::System.EventHandler (this.OnIncrementReagent); + this.button66.Clicked += new global::System.EventHandler (this.OnDecrementReagent); + } + } +} diff --git a/gtk-gui/MainWindow.cs b/gtk-gui/MainWindow.cs new file mode 100644 --- /dev/null +++ b/gtk-gui/MainWindow.cs @@ -0,0 +1,362 @@ + +// This file has been generated by the GUI designer. Do not modify. + +public partial class MainWindow +{ + private global::Gtk.UIManager UIManager; + + private global::Gtk.Action FileAction; + + private global::Gtk.Action HelpAction; + + private global::Gtk.Action AboutAction; + + private global::Gtk.Action NewProfileAction; + + private global::Gtk.Action OpenProfileAction; + + private global::Gtk.Action ExitAction; + + private global::Gtk.Action ExportForPracticalPaintAction; + + private global::Gtk.Action WindowAction; + + private global::Gtk.Action RunSimulatorAction; + + private global::Gtk.VBox vbox1; + + private global::Gtk.MenuBar menubar1; + + private global::Gtk.HBox hbox1; + + private global::Gtk.Frame frame2; + + private global::Gtk.Alignment GtkAlignment; + + private global::Gtk.VBox vbox3; + + private global::Gtk.HBox hbox6; + + private global::Gtk.Label label4; + + private global::Gtk.ComboBox ingredient1ComboBox; + + private global::Gtk.HBox hbox7; + + private global::Gtk.Label label5; + + private global::Gtk.ComboBox ingredient2ComboBox; + + private global::Gtk.HBox hbox8; + + private global::Gtk.Label label6; + + private global::Gtk.ComboBox ingredient3ComboBox; + + private global::Gtk.Label GtkLabel2; + + private global::Gtk.Frame frame3; + + private global::Gtk.Alignment GtkAlignment1; + + private global::Gtk.VBox vbox4; + + private global::DesertPaintLab.PaintSwatch unmodifiedSwatch; + + private global::Gtk.Button captureButton; + + private global::Gtk.Label GtkLabel25; + + private global::Gtk.Frame frame4; + + private global::Gtk.Alignment GtkAlignment2; + + private global::Gtk.VBox vbox5; + + private global::DesertPaintLab.PaintSwatch reactionSwatch; + + private global::Gtk.Button saveButton; + + private global::Gtk.Label GtkLabel26; + + private global::Gtk.Statusbar statusBar; + + protected virtual void Build () + { + global::Stetic.Gui.Initialize (this); + // Widget MainWindow + this.UIManager = new global::Gtk.UIManager (); + global::Gtk.ActionGroup w1 = new global::Gtk.ActionGroup ("Default"); + this.FileAction = new global::Gtk.Action ("FileAction", global::Mono.Unix.Catalog.GetString ("_File"), null, null); + this.FileAction.ShortLabel = global::Mono.Unix.Catalog.GetString ("_File"); + w1.Add (this.FileAction, "f"); + this.HelpAction = new global::Gtk.Action ("HelpAction", global::Mono.Unix.Catalog.GetString ("_Help"), null, null); + this.HelpAction.ShortLabel = global::Mono.Unix.Catalog.GetString ("_Help"); + w1.Add (this.HelpAction, "a"); + this.AboutAction = new global::Gtk.Action ("AboutAction", global::Mono.Unix.Catalog.GetString ("_About..."), null, null); + this.AboutAction.ShortLabel = global::Mono.Unix.Catalog.GetString ("_About..."); + w1.Add (this.AboutAction, "a"); + this.NewProfileAction = new global::Gtk.Action ("NewProfileAction", global::Mono.Unix.Catalog.GetString ("_New Profile..."), null, null); + this.NewProfileAction.ShortLabel = global::Mono.Unix.Catalog.GetString ("_New Profile..."); + w1.Add (this.NewProfileAction, "n"); + this.OpenProfileAction = new global::Gtk.Action ("OpenProfileAction", global::Mono.Unix.Catalog.GetString ("_Open Profile..."), null, null); + this.OpenProfileAction.ShortLabel = global::Mono.Unix.Catalog.GetString ("_Open Profile..."); + w1.Add (this.OpenProfileAction, "o"); + this.ExitAction = new global::Gtk.Action ("ExitAction", global::Mono.Unix.Catalog.GetString ("E_xit"), null, null); + this.ExitAction.ShortLabel = global::Mono.Unix.Catalog.GetString ("E_xit"); + w1.Add (this.ExitAction, "x"); + this.ExportForPracticalPaintAction = new global::Gtk.Action ("ExportForPracticalPaintAction", global::Mono.Unix.Catalog.GetString ("Export for _PracticalPaint..."), null, null); + this.ExportForPracticalPaintAction.ShortLabel = global::Mono.Unix.Catalog.GetString ("Export for _PracticalPaint..."); + w1.Add (this.ExportForPracticalPaintAction, null); + this.WindowAction = new global::Gtk.Action ("WindowAction", global::Mono.Unix.Catalog.GetString ("_Window"), null, null); + this.WindowAction.ShortLabel = global::Mono.Unix.Catalog.GetString ("_Window"); + w1.Add (this.WindowAction, null); + this.RunSimulatorAction = new global::Gtk.Action ("RunSimulatorAction", global::Mono.Unix.Catalog.GetString ("_Run Simulator"), null, null); + this.RunSimulatorAction.ShortLabel = global::Mono.Unix.Catalog.GetString ("_Run Simulator"); + w1.Add (this.RunSimulatorAction, null); + this.UIManager.InsertActionGroup (w1, 0); + this.AddAccelGroup (this.UIManager.AccelGroup); + this.Name = "MainWindow"; + this.Title = global::Mono.Unix.Catalog.GetString ("Desert Paint Lab"); + this.WindowPosition = ((global::Gtk.WindowPosition)(4)); + // Container child MainWindow.Gtk.Container+ContainerChild + this.vbox1 = new global::Gtk.VBox (); + this.vbox1.Name = "vbox1"; + // Container child vbox1.Gtk.Box+BoxChild + this.UIManager.AddUiFromString (@""); + this.menubar1 = ((global::Gtk.MenuBar)(this.UIManager.GetWidget ("/menubar1"))); + this.menubar1.Name = "menubar1"; + this.vbox1.Add (this.menubar1); + global::Gtk.Box.BoxChild w2 = ((global::Gtk.Box.BoxChild)(this.vbox1[this.menubar1])); + w2.Position = 0; + w2.Expand = false; + w2.Fill = false; + // Container child vbox1.Gtk.Box+BoxChild + this.hbox1 = new global::Gtk.HBox (); + this.hbox1.Name = "hbox1"; + this.hbox1.Spacing = 6; + this.hbox1.BorderWidth = ((uint)(4)); + // Container child hbox1.Gtk.Box+BoxChild + this.frame2 = new global::Gtk.Frame (); + this.frame2.Name = "frame2"; + this.frame2.BorderWidth = ((uint)(4)); + // Container child frame2.Gtk.Container+ContainerChild + this.GtkAlignment = new global::Gtk.Alignment (0f, 0f, 1f, 1f); + this.GtkAlignment.Name = "GtkAlignment"; + this.GtkAlignment.LeftPadding = ((uint)(6)); + this.GtkAlignment.RightPadding = ((uint)(6)); + // Container child GtkAlignment.Gtk.Container+ContainerChild + this.vbox3 = new global::Gtk.VBox (); + this.vbox3.Name = "vbox3"; + this.vbox3.Homogeneous = true; + this.vbox3.Spacing = 6; + // Container child vbox3.Gtk.Box+BoxChild + this.hbox6 = new global::Gtk.HBox (); + this.hbox6.Name = "hbox6"; + this.hbox6.Spacing = 6; + // Container child hbox6.Gtk.Box+BoxChild + this.label4 = new global::Gtk.Label (); + this.label4.Name = "label4"; + this.label4.LabelProp = global::Mono.Unix.Catalog.GetString ("Ingredient 1:"); + this.hbox6.Add (this.label4); + global::Gtk.Box.BoxChild w3 = ((global::Gtk.Box.BoxChild)(this.hbox6[this.label4])); + w3.Position = 0; + w3.Expand = false; + w3.Fill = false; + // Container child hbox6.Gtk.Box+BoxChild + this.ingredient1ComboBox = global::Gtk.ComboBox.NewText (); + this.ingredient1ComboBox.Name = "ingredient1ComboBox"; + this.hbox6.Add (this.ingredient1ComboBox); + global::Gtk.Box.BoxChild w4 = ((global::Gtk.Box.BoxChild)(this.hbox6[this.ingredient1ComboBox])); + w4.Position = 1; + this.vbox3.Add (this.hbox6); + global::Gtk.Box.BoxChild w5 = ((global::Gtk.Box.BoxChild)(this.vbox3[this.hbox6])); + w5.Position = 0; + w5.Expand = false; + w5.Fill = false; + // Container child vbox3.Gtk.Box+BoxChild + this.hbox7 = new global::Gtk.HBox (); + this.hbox7.Name = "hbox7"; + this.hbox7.Spacing = 6; + // Container child hbox7.Gtk.Box+BoxChild + this.label5 = new global::Gtk.Label (); + this.label5.Name = "label5"; + this.label5.LabelProp = global::Mono.Unix.Catalog.GetString ("Ingredient 2:"); + this.hbox7.Add (this.label5); + global::Gtk.Box.BoxChild w6 = ((global::Gtk.Box.BoxChild)(this.hbox7[this.label5])); + w6.Position = 0; + w6.Expand = false; + w6.Fill = false; + // Container child hbox7.Gtk.Box+BoxChild + this.ingredient2ComboBox = global::Gtk.ComboBox.NewText (); + this.ingredient2ComboBox.Name = "ingredient2ComboBox"; + this.hbox7.Add (this.ingredient2ComboBox); + global::Gtk.Box.BoxChild w7 = ((global::Gtk.Box.BoxChild)(this.hbox7[this.ingredient2ComboBox])); + w7.Position = 1; + this.vbox3.Add (this.hbox7); + global::Gtk.Box.BoxChild w8 = ((global::Gtk.Box.BoxChild)(this.vbox3[this.hbox7])); + w8.Position = 1; + w8.Expand = false; + w8.Fill = false; + // Container child vbox3.Gtk.Box+BoxChild + this.hbox8 = new global::Gtk.HBox (); + this.hbox8.Name = "hbox8"; + this.hbox8.Spacing = 6; + // Container child hbox8.Gtk.Box+BoxChild + this.label6 = new global::Gtk.Label (); + this.label6.Name = "label6"; + this.label6.LabelProp = global::Mono.Unix.Catalog.GetString ("Ingredient 3:"); + this.hbox8.Add (this.label6); + global::Gtk.Box.BoxChild w9 = ((global::Gtk.Box.BoxChild)(this.hbox8[this.label6])); + w9.Position = 0; + w9.Expand = false; + w9.Fill = false; + // Container child hbox8.Gtk.Box+BoxChild + this.ingredient3ComboBox = global::Gtk.ComboBox.NewText (); + this.ingredient3ComboBox.Name = "ingredient3ComboBox"; + this.hbox8.Add (this.ingredient3ComboBox); + global::Gtk.Box.BoxChild w10 = ((global::Gtk.Box.BoxChild)(this.hbox8[this.ingredient3ComboBox])); + w10.Position = 1; + this.vbox3.Add (this.hbox8); + global::Gtk.Box.BoxChild w11 = ((global::Gtk.Box.BoxChild)(this.vbox3[this.hbox8])); + w11.Position = 2; + w11.Expand = false; + w11.Fill = false; + this.GtkAlignment.Add (this.vbox3); + this.frame2.Add (this.GtkAlignment); + this.GtkLabel2 = new global::Gtk.Label (); + this.GtkLabel2.Name = "GtkLabel2"; + this.GtkLabel2.LabelProp = global::Mono.Unix.Catalog.GetString ("Select Ingredients"); + this.GtkLabel2.UseMarkup = true; + this.frame2.LabelWidget = this.GtkLabel2; + this.hbox1.Add (this.frame2); + global::Gtk.Box.BoxChild w14 = ((global::Gtk.Box.BoxChild)(this.hbox1[this.frame2])); + w14.Position = 0; + // Container child hbox1.Gtk.Box+BoxChild + this.frame3 = new global::Gtk.Frame (); + this.frame3.Name = "frame3"; + this.frame3.BorderWidth = ((uint)(4)); + // Container child frame3.Gtk.Container+ContainerChild + this.GtkAlignment1 = new global::Gtk.Alignment (0f, 0f, 1f, 1f); + this.GtkAlignment1.Name = "GtkAlignment1"; + this.GtkAlignment1.LeftPadding = ((uint)(5)); + this.GtkAlignment1.TopPadding = ((uint)(5)); + this.GtkAlignment1.RightPadding = ((uint)(5)); + this.GtkAlignment1.BottomPadding = ((uint)(6)); + // Container child GtkAlignment1.Gtk.Container+ContainerChild + this.vbox4 = new global::Gtk.VBox (); + this.vbox4.WidthRequest = 120; + this.vbox4.Name = "vbox4"; + this.vbox4.Spacing = 6; + // Container child vbox4.Gtk.Box+BoxChild + this.unmodifiedSwatch = new global::DesertPaintLab.PaintSwatch (); + this.unmodifiedSwatch.Events = ((global::Gdk.EventMask)(256)); + this.unmodifiedSwatch.Name = "unmodifiedSwatch"; + this.vbox4.Add (this.unmodifiedSwatch); + global::Gtk.Box.BoxChild w15 = ((global::Gtk.Box.BoxChild)(this.vbox4[this.unmodifiedSwatch])); + w15.Position = 0; + // Container child vbox4.Gtk.Box+BoxChild + this.captureButton = new global::Gtk.Button (); + this.captureButton.WidthRequest = 100; + this.captureButton.CanFocus = true; + this.captureButton.Name = "captureButton"; + this.captureButton.UseUnderline = true; + this.captureButton.Label = global::Mono.Unix.Catalog.GetString ("Capture"); + this.vbox4.Add (this.captureButton); + global::Gtk.Box.BoxChild w16 = ((global::Gtk.Box.BoxChild)(this.vbox4[this.captureButton])); + w16.Position = 1; + w16.Expand = false; + w16.Fill = false; + this.GtkAlignment1.Add (this.vbox4); + this.frame3.Add (this.GtkAlignment1); + this.GtkLabel25 = new global::Gtk.Label (); + this.GtkLabel25.Name = "GtkLabel25"; + this.GtkLabel25.LabelProp = global::Mono.Unix.Catalog.GetString ("Unmodified"); + this.GtkLabel25.UseMarkup = true; + this.frame3.LabelWidget = this.GtkLabel25; + this.hbox1.Add (this.frame3); + global::Gtk.Box.BoxChild w19 = ((global::Gtk.Box.BoxChild)(this.hbox1[this.frame3])); + w19.Position = 1; + w19.Expand = false; + w19.Fill = false; + // Container child hbox1.Gtk.Box+BoxChild + this.frame4 = new global::Gtk.Frame (); + this.frame4.Name = "frame4"; + this.frame4.BorderWidth = ((uint)(4)); + // Container child frame4.Gtk.Container+ContainerChild + this.GtkAlignment2 = new global::Gtk.Alignment (0f, 0f, 1f, 1f); + this.GtkAlignment2.WidthRequest = 130; + this.GtkAlignment2.Name = "GtkAlignment2"; + this.GtkAlignment2.LeftPadding = ((uint)(5)); + this.GtkAlignment2.TopPadding = ((uint)(5)); + this.GtkAlignment2.RightPadding = ((uint)(5)); + this.GtkAlignment2.BottomPadding = ((uint)(6)); + // Container child GtkAlignment2.Gtk.Container+ContainerChild + this.vbox5 = new global::Gtk.VBox (); + this.vbox5.WidthRequest = 120; + this.vbox5.Name = "vbox5"; + this.vbox5.Spacing = 6; + // Container child vbox5.Gtk.Box+BoxChild + this.reactionSwatch = new global::DesertPaintLab.PaintSwatch (); + this.reactionSwatch.Events = ((global::Gdk.EventMask)(256)); + this.reactionSwatch.Name = "reactionSwatch"; + this.vbox5.Add (this.reactionSwatch); + global::Gtk.Box.BoxChild w20 = ((global::Gtk.Box.BoxChild)(this.vbox5[this.reactionSwatch])); + w20.Position = 0; + // Container child vbox5.Gtk.Box+BoxChild + this.saveButton = new global::Gtk.Button (); + this.saveButton.WidthRequest = 100; + this.saveButton.CanFocus = true; + this.saveButton.Name = "saveButton"; + this.saveButton.UseUnderline = true; + this.saveButton.Label = global::Mono.Unix.Catalog.GetString ("Record"); + this.vbox5.Add (this.saveButton); + global::Gtk.Box.BoxChild w21 = ((global::Gtk.Box.BoxChild)(this.vbox5[this.saveButton])); + w21.Position = 1; + w21.Expand = false; + w21.Fill = false; + this.GtkAlignment2.Add (this.vbox5); + this.frame4.Add (this.GtkAlignment2); + this.GtkLabel26 = new global::Gtk.Label (); + this.GtkLabel26.Name = "GtkLabel26"; + this.GtkLabel26.LabelProp = global::Mono.Unix.Catalog.GetString ("Reaction"); + this.GtkLabel26.UseMarkup = true; + this.frame4.LabelWidget = this.GtkLabel26; + this.hbox1.Add (this.frame4); + global::Gtk.Box.BoxChild w24 = ((global::Gtk.Box.BoxChild)(this.hbox1[this.frame4])); + w24.Position = 2; + w24.Expand = false; + w24.Fill = false; + this.vbox1.Add (this.hbox1); + global::Gtk.Box.BoxChild w25 = ((global::Gtk.Box.BoxChild)(this.vbox1[this.hbox1])); + w25.Position = 1; + // Container child vbox1.Gtk.Box+BoxChild + this.statusBar = new global::Gtk.Statusbar (); + this.statusBar.Name = "statusBar"; + this.statusBar.Spacing = 6; + this.vbox1.Add (this.statusBar); + global::Gtk.Box.BoxChild w26 = ((global::Gtk.Box.BoxChild)(this.vbox1[this.statusBar])); + w26.Position = 2; + w26.Expand = false; + w26.Fill = false; + this.Add (this.vbox1); + if ((this.Child != null)) { + this.Child.ShowAll (); + } + this.DefaultWidth = 629; + this.DefaultHeight = 265; + this.Show (); + this.DeleteEvent += new global::Gtk.DeleteEventHandler (this.OnDeleteEvent); + this.AboutAction.Activated += new global::System.EventHandler (this.OnAbout); + this.NewProfileAction.Activated += new global::System.EventHandler (this.OnNewProfile); + this.OpenProfileAction.Activated += new global::System.EventHandler (this.OnOpenProfile); + this.ExitAction.Activated += new global::System.EventHandler (this.OnMenuExit); + this.ExportForPracticalPaintAction.Activated += new global::System.EventHandler (this.OnExport); + this.RunSimulatorAction.Activated += new global::System.EventHandler (this.RunSimulator); + this.ingredient1ComboBox.Changed += new global::System.EventHandler (this.OnChangedIngredient1); + this.ingredient2ComboBox.Changed += new global::System.EventHandler (this.OnChangedIngredient2); + this.ingredient3ComboBox.Changed += new global::System.EventHandler (this.OnChangedIngredient3); + this.captureButton.Clicked += new global::System.EventHandler (this.OnCaptureButton); + this.saveButton.Clicked += new global::System.EventHandler (this.OnSaveButton); + } +} diff --git a/gtk-gui/generated.cs b/gtk-gui/generated.cs new file mode 100644 --- /dev/null +++ b/gtk-gui/generated.cs @@ -0,0 +1,116 @@ + +// This file has been generated by the GUI designer. Do not modify. +namespace Stetic +{ + internal class Gui + { + private static bool initialized; + + static internal void Initialize (Gtk.Widget iconRenderer) + { + if ((Stetic.Gui.initialized == false)) { + Stetic.Gui.initialized = true; + } + } + } + + internal class BinContainer + { + private Gtk.Widget child; + + private Gtk.UIManager uimanager; + + public static BinContainer Attach (Gtk.Bin bin) + { + BinContainer bc = new BinContainer (); + bin.SizeRequested += new Gtk.SizeRequestedHandler (bc.OnSizeRequested); + bin.SizeAllocated += new Gtk.SizeAllocatedHandler (bc.OnSizeAllocated); + bin.Added += new Gtk.AddedHandler (bc.OnAdded); + return bc; + } + + private void OnSizeRequested (object sender, Gtk.SizeRequestedArgs args) + { + if ((this.child != null)) { + args.Requisition = this.child.SizeRequest (); + } + } + + private void OnSizeAllocated (object sender, Gtk.SizeAllocatedArgs args) + { + if ((this.child != null)) { + this.child.Allocation = args.Allocation; + } + } + + private void OnAdded (object sender, Gtk.AddedArgs args) + { + this.child = args.Widget; + } + + public void SetUiManager (Gtk.UIManager uim) + { + this.uimanager = uim; + this.child.Realized += new System.EventHandler (this.OnRealized); + } + + private void OnRealized (object sender, System.EventArgs args) + { + if ((this.uimanager != null)) { + Gtk.Widget w; + w = this.child.Toplevel; + if (((w != null) && typeof(Gtk.Window).IsInstanceOfType (w))) { + ((Gtk.Window)(w)).AddAccelGroup (this.uimanager.AccelGroup); + this.uimanager = null; + } + } + } + } + + internal class IconLoader + { + public static Gdk.Pixbuf LoadIcon (Gtk.Widget widget, string name, Gtk.IconSize size) + { + Gdk.Pixbuf res = widget.RenderIcon (name, size, null); + if ((res != null)) { + return res; + } else { + int sz; + int sy; + global::Gtk.Icon.SizeLookup (size, out sz, out sy); + try { + return Gtk.IconTheme.Default.LoadIcon (name, sz, 0); + } catch (System.Exception) { + if ((name != "gtk-missing-image")) { + return Stetic.IconLoader.LoadIcon (widget, "gtk-missing-image", size); + } else { + Gdk.Pixmap pmap = new Gdk.Pixmap (Gdk.Screen.Default.RootWindow, sz, sz); + Gdk.GC gc = new Gdk.GC (pmap); + gc.RgbFgColor = new Gdk.Color (255, 255, 255); + pmap.DrawRectangle (gc, true, 0, 0, sz, sz); + gc.RgbFgColor = new Gdk.Color (0, 0, 0); + pmap.DrawRectangle (gc, false, 0, 0, (sz - 1), (sz - 1)); + gc.SetLineAttributes (3, Gdk.LineStyle.Solid, Gdk.CapStyle.Round, Gdk.JoinStyle.Round); + gc.RgbFgColor = new Gdk.Color (255, 0, 0); + pmap.DrawLine (gc, (sz / 4), (sz / 4), ((sz - 1) - (sz / 4)), ((sz - 1) - (sz / 4))); + pmap.DrawLine (gc, ((sz - 1) - (sz / 4)), (sz / 4), (sz / 4), ((sz - 1) - (sz / 4))); + return Gdk.Pixbuf.FromDrawable (pmap, pmap.Colormap, 0, 0, 0, 0, sz, sz); + } + } + } + } + } + + internal class ActionGroups + { + public static Gtk.ActionGroup GetActionGroup (System.Type type) + { + return Stetic.ActionGroups.GetActionGroup (type.FullName); + } + + public static Gtk.ActionGroup GetActionGroup (string name) + { + return null; + } + } +} diff --git a/gtk-gui/gui.stetic b/gtk-gui/gui.stetic new file mode 100644 --- /dev/null +++ b/gtk-gui/gui.stetic @@ -0,0 +1,908 @@ + + + + .. + 2.12 + + + + + + + + + Action + <Alt>f + _File + _File + + + Action + <Alt>a + _Help + _Help + + + Action + <Alt>a + _About... + _About... + + + + Action + <Alt>n + _New Profile... + _New Profile... + + + + Action + <Alt>o + _Open Profile... + _Open Profile... + + + + Action + <Alt>x + E_xit + E_xit + + + + Action + Export for _PracticalPaint... + Export for _PracticalPaint... + + + + Action + _Window + _Window + + + Action + _Run Simulator + _Run Simulator + + + + + Desert Paint Lab + CenterOnParent + + + + + + + + + + + + + + + + + + + + + + + + + 0 + True + False + False + + + + + + 6 + 4 + + + + 4 + + + + 0 + 0 + 6 + 6 + + + + True + 6 + + + + 6 + + + + Ingredient 1: + + + 0 + True + False + False + + + + + + True + + + + + 1 + False + + + + + 0 + True + False + False + + + + + + 6 + + + + Ingredient 2: + + + 0 + True + False + False + + + + + + True + + + + + 1 + False + + + + + 1 + True + False + False + + + + + + 6 + + + + Ingredient 3: + + + 0 + True + False + False + + + + + + True + + + + + 1 + False + + + + + 2 + True + False + False + + + + + + + + + + <b>Select Ingredients</b> + True + + + label_item + + + + + 0 + False + + + + + + 4 + + + + 0 + 0 + 5 + 5 + 5 + 6 + + + + 120 + 6 + + + + ButtonPressMask + + + 0 + True + + + + + + 100 + True + TextOnly + Capture + True + + + + 1 + True + False + False + + + + + + + + + + <b>Unmodified</b> + True + + + label_item + + + + + 1 + True + False + False + + + + + + 4 + + + + 130 + 0 + 0 + 5 + 5 + 5 + 6 + + + + 120 + 6 + + + + ButtonPressMask + + + 0 + True + + + + + + 100 + True + TextOnly + Record + True + + + + 1 + True + False + False + + + + + + + + + + <b>Reaction</b> + True + + + label_item + + + + + 2 + True + False + False + + + + + 1 + False + + + + + + 6 + + + 2 + True + False + False + + + + + + + + Set Up Profile + CenterOnParent + True + True + 3 + False + + + + 2 + + + + Since this is your first time using this program, you need a new profile. + +You can either import an existing PracticalPaint reactions.txt file, or you can start a new profile from scratch. + True + + + 0 + False + 5 + + + + + + + + 10 + 5 + 3 + End + + + + True + True + True + StockItem + gtk-cancel + -6 + gtk-cancel + + + False + False + + + + + + True + True + TextOnly + Import reactions.txt + True + -3 + + + 1 + False + False + + + + + + True + TextOnly + New Profile + True + -5 + + + 2 + False + False + + + + + + + + Open Profile + CenterOnParent + True + 5 + 3 + False + + + + 10 + 2 + + + + Select the profile you would like to open: + + + 0 + True + False + False + + + + + + True + False + + + + 1 + True + + + + + + + + 10 + 5 + 3 + End + + + + True + True + True + StockItem + gtk-cancel + -6 + gtk-cancel + + + False + False + + + + + + True + TextOnly + New Profile + True + -3 + + + 1 + False + False + + + + + + True + True + True + StockItem + gtk-ok + -5 + gtk-ok + + + 2 + False + False + + + + + + + + New Profile + CenterOnParent + 5 + 2 + False + + + + 10 + 9 + + + + Name your new profile: + + + 0 + True + False + False + + + + + + True + True + + + 1 + True + False + False + + + + + + + + 10 + 5 + 2 + End + + + + True + True + True + StockItem + gtk-cancel + -6 + gtk-cancel + + + False + False + + + + + + True + True + True + StockItem + gtk-ok + -5 + gtk-ok + + + 1 + False + False + + + + + + + + False + + + + 6 + + + + Unknown + + + 0 + True + False + False + + + + + + + + 1 + True + + + + + + ???, ???, ??? + + + 2 + True + False + False + + + + + + + + Simulator + CenterOnParent + + + + 6 + 12 + + + + In + + + + True + True + + + + + 0 + True + + + + + + 6 + + + + + + + + + 0 + True + + + + + + True + Custom + + + + + stock:gtk-go-forward Menu + + + + + 1 + True + False + False + + + + + + + + + + + 2 + True + + + + + 1 + True + False + False + + + + + + 0 + In + + + + True + True + False + True + + + + + 2 + True + + + + + + 6 + + + + + + + + + 0 + True + + + + + + True + Custom + + + + + stock:gtk-add Menu + + + + + 1 + True + False + False + + + + + + True + Custom + + + + + stock:gtk-remove Menu + + + + + 2 + True + False + False + + + + + + + + + + + 3 + True + + + + + 3 + True + False + False + + + + + + 200 + ButtonPressMask + + + 4 + False + + + + + + \ No newline at end of file