private StackPanel InitGeneticSettings()
        {
            // Population
            var populationValidity  = StringExtensions.IsInt().And(StringExtensions.InRange(2, 10000));
            var updatePopulation    = new Action <string>(str => GeneticSettings = GeneticSettings.WithPopulation(int.Parse(str)));
            var populationContainer = HorizontalContainerStrecherd.Create()
                                      .AddLeft(TextBlockCreator.RegularTextBlock("Population").WithBullet())
                                      .AsDock(InteractiveTextBox.Create(GeneticSettings.Population.ToString(), populationValidity, updatePopulation, Dispatcher));

            // Mutation Rate
            var mutationRateValidity  = StringExtensions.IsDouble().And(StringExtensions.InRange(0, 1));
            var updateMutationRate    = new Action <string>(str => GeneticSettings = GeneticSettings.WithMutationRate(double.Parse(str)));
            var mutationRateContainer = HorizontalContainerStrecherd.Create()
                                        .AddLeft(TextBlockCreator.RegularTextBlock("Mutation Rate").WithBullet())
                                        .AsDock(InteractiveTextBox.Create(this.GeneticSettings.MutationRate.ToString(), mutationRateValidity, updateMutationRate, Dispatcher));

            // Elitism Rate
            var elitismRateValidity  = StringExtensions.IsDouble().And(StringExtensions.InRange(0, 1));
            var updateElitismRate    = new Action <string>(str => GeneticSettings = GeneticSettings.WithMutationRate(double.Parse(str)));
            var elitismRateContainer = HorizontalContainerStrecherd.Create()
                                       .AddLeft(TextBlockCreator.RegularTextBlock("Elitism Rate").WithBullet())
                                       .AsDock(InteractiveTextBox.Create(this.GeneticSettings.ElitismRate.ToString(), elitismRateValidity, updateElitismRate, Dispatcher));


            // New Genes Rate
            var newGenesRateValidity  = StringExtensions.IsDouble().And(StringExtensions.InRange(0, 1));
            var updateNewGenesRate    = new Action <string>(str => GeneticSettings = GeneticSettings.WithMutationRate(double.Parse(str)));
            var newGenesRateContainer = HorizontalContainerStrecherd.Create()
                                        .AddLeft(TextBlockCreator.RegularTextBlock("New Genes Rate").WithBullet())
                                        .AsDock(InteractiveTextBox.Create(this.GeneticSettings.NewGenesRate.ToString(), newGenesRateValidity, updateNewGenesRate, Dispatcher));

            var title = TextBlockCreator.TitleTextBlock("Genetic Settings");

            return(GuiExtensions.CreateStackPanel(title, populationContainer, mutationRateContainer, elitismRateContainer, newGenesRateContainer));
        }
        private UIElement OutputPathBullet()
        {
            Predicate <string> validityCheck = path => Directory.Exists(path);
            Action <string>    onPathChanged = path => OutputResultPath = path;
            var textBox = InteractiveTextBox.Create(OutputResultPath, validityCheck, onPathChanged, Dispatcher);

            return(HorizontalContainerStrecherd.Create()
                   .AddLeft(TextBlockCreator.RegularTextBlock("Result Output Folder").WithBullet())
                   .AddRight(ButtonCreator.Create("...", () => DialogCreator.ChooseFolder(path => textBox.Text = path)))
                   .AsDock(textBox));
        }
        private UIElement InputGraphBullet()
        {
            Predicate <string> validityCheck = path => File.Exists(path) && GraphEmbedding.CanParse(path);
            Action <string>    onPathChanged = path =>
            {
                InputGraphPath = path;
                SetGraph(GraphEmbedding.FromText(File.ReadLines(path)));
            };
            var textBox = InteractiveTextBox.Create(InputGraphPath, validityCheck, onPathChanged, Dispatcher);

            InputGraphTextBox = textBox;
            return(HorizontalContainerStrecherd.Create()
                   .AddLeft(TextBlockCreator.RegularTextBlock("Input Graph").WithBullet())
                   .AddRight(ButtonCreator.Create("...", () => DialogCreator.ChooseFile(path => textBox.Text = path)))
                   .AsDock(textBox));
        }
        public void AddEdge(Edge edge, bool active = true)
        {
            void WeightChanged(string newWeight) => UpdateWeight.ForEach(a => a.Invoke(edge.WithWeight(double.Parse(newWeight))));

            UIElement textPart =
                !active
                    ? TextBlockCreator.RegularTextBlock(edge.Weight.ToString()).WithVerticalAlignment(VerticalAlignment.Center)
                    : (UIElement)InteractiveTextBox.Create(edge.Weight.ToString(), StringExtensions.IsDouble(), WeightChanged,
                                                           Dispatcher.CurrentDispatcher);


            var dockPanel = HorizontalContainerStrecherd.Create()
                            .AddLeft(TextBlockCreator.RegularTextBlock(edge + ": ").WithBullet())
                            .AsDock(textPart);

            this.StackPanel.Children.Add(dockPanel);
            this.Edges[edge] = dockPanel;
        }