void ITextBoxViewHost.DetachView()
        {
            TextBoxView view = _view;

            _view = null;
            _host.Children.Remove(view);
        }
        void ITextBoxViewHost.DetachView()
        {
            TextBoxView view = _view;

            _view = null;
            _host.Items.Remove(view);
        }
示例#3
0
        public HashVMClass()
        {
            GetTextHash = new DelegateCommand(() =>
            {
                try
                {
                    Validate();
                    IsStarted     = true;
                    Thread thread = new Thread(() =>
                    {
                        Result           = String.Empty;
                        byte[] inputText = Encoding.Default.GetBytes(Text);
                        string result    = Hash.GetHash(inputText);
                        Result           = result;
                        IsStarted        = false;
                    });
                    thread.Start();
                }
                catch (ValidateException e)
                {
                    IsStarted = false;
                    _textBox  = new TextBoxView(e.Message);
                    _textBox.ShowDialog();
                }
            });

            GetFileHash = new DelegateCommand(() =>
            {
                try
                {
                    Text = String.Empty;
                    OpenFileDialog ofd = new OpenFileDialog();
                    IsStarted          = true;
                    if (ofd.ShowDialog() == true)
                    {
                        string path = ofd.FileName;
                        if (Hash.Name == "GOST")
                        {
                            Validate(isFileWork: true, path: path);
                        }
                        Thread thread = new Thread(() =>
                        {
                            string result = Hash.GetHash(path);
                            Result        = result;
                            IsStarted     = false;
                        });
                        thread.Start();
                    }
                }
                catch (ValidateException e)
                {
                    IsStarted = false;
                    _textBox  = new TextBoxView(e.Message);
                    _textBox.ShowDialog();
                }
            });
        }
示例#4
0
        /// <summary>
        /// Assert that the native overlay layer for Skia targets is initialized in time for UI to appear.
        /// </summary>
        public void AssertIssue8641NativeOverlayInitialized()
        {
#if __SKIA__
            var textBox     = new TextBox();
            var textBoxView = new TextBoxView(textBox);
            ApiExtensibility.CreateInstance <ITextBoxViewExtension>(textBoxView, out var textBoxViewExtension);
            Assert.IsTrue(textBoxViewExtension.IsNativeOverlayLayerInitialized);
#endif
        }
示例#5
0
        private void OnItemListPreviewMouseUp(object sender, MouseButtonEventArgs e)
        {
            if (e.LeftButton == MouseButtonState.Released)
            {
                TextBoxView.Focus();
                UpdateItems();

                e.Handled = true;
            }
        }
示例#6
0
        private void NieuwTextBox()
        {
            Vet    = false;
            Schuin = false;
            TextBoxView test = new TextBoxView();

            test.DataContext = this;
            test.Show();
            Inhoud = string.Empty;
        }
        void ITextBoxViewHost.AttachView(TextBoxView view)
        {
            if (_host.HasItems)
            {
                throw new InvalidOperationException();
            }

            _view = view;
            _host.Items.Add(view);
        }
示例#8
0
        private void InitializeContentElement()
        {
            _textViewHost = GetContentHost(_contentElement);

            if (_textViewHost != null)
            {
                TextBoxView view = CreateView();
                _textViewHost.AttachView(view);
            }
        }
        void ITextBoxViewHost.DetachView()
        {
            EnsureInitialized();

            _view = null;
            if (_setMethod != null)
            {
                _setMethod.Invoke(_host, new object[1] {
                    null
                });
            }
        }
        void ITextBoxViewHost.AttachView(TextBoxView view)
        {
            EnsureInitialized();

            _view = view;
            if (_setMethod != null)
            {
                _setMethod.Invoke(_host, new object[1] {
                    view
                });
            }
        }
示例#11
0
        public static IView View()
        {
            var bodySelector = new ListSelectView<CelestialBody>("Planet", () => FlightGlobals.fetch == null ? null : FlightGlobals.fetch.bodies, null, Extensions.CbToString);
            bodySelector.CurrentlySelected = FlightGlobals.fetch == null ? null : FlightGlobals.ActiveVessel == null ? Planetarium.fetch.Home : FlightGlobals.ActiveVessel.mainBody;
            var lat = new TextBoxView<double>("Lat", "Latitude of landing coordinates", 0.001d, myTryParse);
            var lon = new TextBoxView<double>("Lon", "Longitude of landing coordinates", 0.001d, myTryParse);
            var alt = new TextBoxView<double>("Alt", "Altitude of landing coordinates", 20, Model.SiSuffix.TryParse);
            var setRot = new ToggleView("Set rotation",
                "If set, rotates the vessel such that up on the vessel is up when landing. Otherwise, the same orientation is kept as before teleporting, relative to the planet",
                false);
            Func<bool> isValid = () => lat.Valid && lon.Valid && alt.Valid;
            Action<double, double, CelestialBody> load = (latVal, lonVal, body) =>
            {
                lat.Object = latVal;
                lon.Object = lonVal;
                bodySelector.CurrentlySelected = body;
            };

            return new VerticalView(new IView[]
                {
                    lat,
                    lon,
                    alt,
                    bodySelector,
                    setRot,
                    new ConditionalView(() => FlightGlobals.fetch != null && FlightGlobals.ActiveVessel != null && FlightGlobals.ActiveVessel.mainBody != bodySelector.CurrentlySelected,
                        new LabelView("Landing on a body other than the current one is not recommended.",
                            "This causes lots of explosions, it's advisable to teleport to an orbit above the planet, then land on it directly")),
                    new ConditionalView(() => lat.Valid && (lat.Object < -89.9 || lat.Object > 89.9),
                        new LabelView("Setting latitude to -90 or 90 degrees (or near it) is dangerous, try 89.9 degrees",
                            "(This warning also appears when latitude is past 90 degrees)")),
                    new DynamicToggleView("Landing", "Land the ship (or stop landing)", Model.DoLander.IsLanding,
                        isValid, b => Model.DoLander.ToggleLanding(lat.Object, lon.Object, alt.Object, bodySelector.CurrentlySelected, setRot.Value, load)),
                    new ConditionalView(() => Model.DoLander.IsLanding(), new LabelView(HelpString(), "Moves the landing vessel's coordinates slightly")),
                    new ConditionalView(() => !Model.DoLander.IsLanding(), new ButtonView("Land here", "Stops the vessel and slowly lowers it to the ground (without teleporting)", () => Model.DoLander.LandHere(load))),
                    new ConditionalView(isValid, new ButtonView("Save", "Save the entered location", () => Model.DoLander.AddSavedCoords(lat.Object, lon.Object, bodySelector.CurrentlySelected))),
                    new ButtonView("Load", "Load a previously-saved location", () => Model.DoLander.Load(load)),
                    new ButtonView("Delete", "Delete a previously-saved location", Model.DoLander.Delete),
                    new ButtonView("Set to current", "Set lat/lon to the current position", () => Model.DoLander.SetToCurrent(load)),
                    new ListSelectView<Vessel>("Set lat/lon to", Model.DoLander.LandedVessels, select => Model.DoLander.SetToLanded(load, select), Extensions.VesselToString),
                });
        }
示例#12
0
        protected override void Init()
        {
            //background white 800 x 600 square
            content = new AbsoluteLayout()
            {
                BackgroundColor   = Color.White,
                WidthRequest      = 800,
                HeightRequest     = 800,
                VerticalOptions   = LayoutOptions.CenterAndExpand,
                HorizontalOptions = LayoutOptions.CenterAndExpand
            };

            //test TextBoxView 400 x 400, color gray, should have a red ellipse and a red "hello world"

            var test = new TextBoxView()
            {
                WidthRequest = 300, HeightRequest = 300, BackgroundColor = Color.Blue
            };

            content.Children.Add(test, new Point((content.WidthRequest - test.WidthRequest) / 2f, (content.HeightRequest - test.HeightRequest) / 2f));

            Content = content;
        }
 void ITextBoxViewHost.DetachView()
 {
     _view       = null;
     _host.Child = null;
 }
        /// <summary>
        /// Called when node gets loaded and should be added to the surface. Creates node elements from the archetype.
        /// </summary>
        /// <param name="node">The node.</param>
        public virtual void OnNodeLoaded(SurfaceNode node)
        {
            // Create child elements of the node based on it's archetype
            int elementsCount = node.Archetype.Elements?.Length ?? 0;

            for (int i = 0; i < elementsCount; i++)
            {
                // ReSharper disable once PossibleNullReferenceException
                var arch = node.Archetype.Elements[i];
                ISurfaceNodeElement element = null;
                switch (arch.Type)
                {
                case NodeElementType.Input:
                    element = new InputBox(node, arch);
                    break;

                case NodeElementType.Output:
                    element = new OutputBox(node, arch);
                    break;

                case NodeElementType.BoolValue:
                    element = new BoolValue(node, arch);
                    break;

                case NodeElementType.FloatValue:
                    element = new FloatValue(node, arch);
                    break;

                case NodeElementType.IntegerValue:
                    element = new IntegerValue(node, arch);
                    break;

                case NodeElementType.ColorValue:
                    element = new ColorValue(node, arch);
                    break;

                case NodeElementType.ComboBox:
                    element = new ComboBoxElement(node, arch);
                    break;

                case NodeElementType.Asset:
                    element = new AssetSelect(node, arch);
                    break;

                case NodeElementType.Text:
                    element = new TextView(node, arch);
                    break;

                case NodeElementType.TextBox:
                    element = new TextBoxView(node, arch);
                    break;

                case NodeElementType.SkeletonNodeSelect:
                    element = new SkeletonNodeSelectElement(node, arch);
                    break;
                }
                if (element != null)
                {
                    // Link element
                    node.AddElement(element);
                }
            }

            // Load metadata
            var meta = node.Meta.GetEntry(11);

            if (meta.Data != null)
            {
                var meta11 = Utils.ByteArrayToStructure <VisjectSurface.Meta11>(meta.Data);
                node.Location = meta11.Position;
                //node.IsSelected = meta11.Selected;
            }
        }
示例#15
0
        /// <summary>
        /// Creates an element from the archetype and adds the element to the node.
        /// </summary>
        /// <param name="arch">The element archetype.</param>
        /// <returns>The created element. Null if the archetype is invalid.</returns>
        public ISurfaceNodeElement AddElement(NodeElementArchetype arch)
        {
            ISurfaceNodeElement element = null;

            switch (arch.Type)
            {
            case NodeElementType.Input:
                element = new InputBox(this, arch);
                break;

            case NodeElementType.Output:
                element = new OutputBox(this, arch);
                break;

            case NodeElementType.BoolValue:
                element = new BoolValue(this, arch);
                break;

            case NodeElementType.FloatValue:
                element = new FloatValue(this, arch);
                break;

            case NodeElementType.IntegerValue:
                element = new IntegerValue(this, arch);
                break;

            case NodeElementType.ColorValue:
                element = new ColorValue(this, arch);
                break;

            case NodeElementType.ComboBox:
                element = new ComboBoxElement(this, arch);
                break;

            case NodeElementType.Asset:
                element = new AssetSelect(this, arch);
                break;

            case NodeElementType.Text:
                element = new TextView(this, arch);
                break;

            case NodeElementType.TextBox:
                element = new TextBoxView(this, arch);
                break;

            case NodeElementType.SkeletonBoneIndexSelect:
                element = new SkeletonBoneIndexSelectElement(this, arch);
                break;

            case NodeElementType.BoxValue:
                element = new BoxValue(this, arch);
                break;

            case NodeElementType.EnumValue:
                element = new EnumValue(this, arch);
                break;

            case NodeElementType.SkeletonNodeNameSelect:
                element = new SkeletonNodeNameSelectElement(this, arch);
                break;
                //default: throw new NotImplementedException("Unknown node element type: " + arch.Type);
            }
            if (element != null)
            {
                AddElement(element);
            }

            return(element);
        }
示例#16
0
 public TextBoxViewExtension(TextBoxView owner, GtkWindow window)
 {
     _owner  = owner ?? throw new ArgumentNullException(nameof(owner));
     _window = window ?? throw new ArgumentNullException(nameof(window));
 }
 void ITextBoxViewHost.AttachView(TextBoxView view)
 {
     _view = view;
     _host.Children.Add(view);
 }
示例#18
0
 public void SetView(TextBoxView t)
 {
     TextBoxView = t;
 }
示例#19
0
 public TextBoxViewExtension(TextBoxView owner)
 {
     _owner = owner ?? throw new ArgumentNullException(nameof(owner));
 }
 void ITextBoxViewHost.DetachView()
 {
     _view         = null;
     _host.Content = null;
 }
 void ITextBoxViewHost.AttachView(TextBoxView view)
 {
     _view       = view;
     _host.Child = view;
 }
示例#22
0
        /// <summary>
        /// Creates an element from the archetype and adds the element to the node.
        /// </summary>
        /// <param name="arch">The element archetype.</param>
        /// <returns>The created element. Null if the archetype is invalid.</returns>
        public ISurfaceNodeElement AddElement(NodeElementArchetype arch)
        {
            ISurfaceNodeElement element = null;

            switch (arch.Type)
            {
            case NodeElementType.Input:
                element = new InputBox(this, arch);
                break;

            case NodeElementType.Output:
                element = new OutputBox(this, arch);
                break;

            case NodeElementType.BoolValue:
                element = new BoolValue(this, arch);
                break;

            case NodeElementType.FloatValue:
                element = new FloatValue(this, arch);
                break;

            case NodeElementType.IntegerValue:
                element = new IntegerValue(this, arch);
                break;

            case NodeElementType.ColorValue:
                element = new ColorValue(this, arch);
                break;

            case NodeElementType.ComboBox:
                element = new ComboBoxElement(this, arch);
                break;

            case NodeElementType.Asset:
                element = new AssetSelect(this, arch);
                break;

            case NodeElementType.Text:
                element = new TextView(this, arch);
                break;

            case NodeElementType.TextBox:
                element = new TextBoxView(this, arch);
                break;

            case NodeElementType.SkeletonNodeSelect:
                element = new SkeletonNodeSelectElement(this, arch);
                break;

            case NodeElementType.BoxValue:
                element = new BoxValue(this, arch);
                break;

            case NodeElementType.EnumValue:
                element = new EnumValue(this, arch);
                break;
            }
            if (element != null)
            {
                AddElement(element);
            }

            return(element);
        }
示例#23
0
 public void SetupPrefab(GameObject textBoxPrefab)
 {
     this.view = textBoxPrefab.GetComponent <TextBoxView>();
     SetupHelper(textBoxPrefab);
     view.IsSkip = isSkip;
 }
 void ITextBoxViewHost.AttachView(TextBoxView view)
 {
     _view         = view;
     _host.Content = view;
 }
        public static IView View()
        {
            CelestialBody body = null;

            var geeAsl = new TextBoxView<double>("Gravity multiplier", "1.0 is kerbin, 0.5 is half of kerbin's gravity, etc.", 1, Model.SiSuffix.TryParse);
            var ocean = new ToggleView("Has ocean", "Does weird things to the ocean if off", false);
            var atmosphere = new ToggleView("Has atmosphere", "Toggles if the planet has atmosphere or not", false);
            var atmosphereContainsOxygen = new ToggleView("Atmosphere contains oxygen", "Whether jet engines work or not", false);
            var atmosphereDepth = new TextBoxView<double>("Atmosphere depth", "Theoretically atmosphere height. In reality, doesn't work too well.", 1, Model.SiSuffix.TryParse);
            var atmosphereTemperatureSeaLevel = new TextBoxView<double>("atmosphereTemperatureSeaLevel", "New 1.0 field. Unknown what this does.", 1, Model.SiSuffix.TryParse);
            var atmospherePressureSeaLevel = new TextBoxView<double>("atmospherePressureSeaLevel", "New 1.0 field. Unknown what this does.", 1, Model.SiSuffix.TryParse);
            var atmosphereMolarMass = new TextBoxView<double>("atmosphereMolarMass", "New 1.0 field. Unknown what this does.", 1, Model.SiSuffix.TryParse);
            var atmosphereAdiabaticIndex = new TextBoxView<double>("atmosphereAdiabaticIndex", "New 1.0 field. Unknown what this does.", 1, Model.SiSuffix.TryParse);
            var rotates = new ToggleView("Rotates", "If the planet rotates.", false);
            var rotationPeriod = new TextBoxView<double>("Rotation period", "Rotation period of the planet, in seconds.", 1, Model.SiSuffix.TryParse);
            var initialRotation = new TextBoxView<double>("Initial rotation", "Absolute rotation in degrees of the planet at time=0", 1, Model.SiSuffix.TryParse);
            var tidallyLocked = new ToggleView("Tidally locked", "If the planet is tidally locked. Overrides Rotation Period.", false);

            Action<CelestialBody> onSelect = cb =>
            {
                body = cb;
                geeAsl.Object = body.GeeASL;
                ocean.Value = body.ocean;
                atmosphere.Value = body.atmosphere;
                atmosphereContainsOxygen.Value = body.atmosphereContainsOxygen;
                atmosphereDepth.Object = body.atmosphereDepth;
                atmosphereTemperatureSeaLevel.Object = body.atmosphereTemperatureSeaLevel;
                atmospherePressureSeaLevel.Object = body.atmospherePressureSeaLevel;
                atmosphereMolarMass.Object = body.atmosphereMolarMass;
                atmosphereAdiabaticIndex.Object = body.atmosphereAdiabaticIndex;
                rotates.Value = body.rotates;
                rotationPeriod.Object = body.rotationPeriod;
                initialRotation.Object = body.initialRotation;
                tidallyLocked.Value = body.tidallyLocked;
            };

            var selectBody = new ConditionalView(() => FlightGlobals.fetch != null && FlightGlobals.Bodies != null,
                                 new ListSelectView<CelestialBody>("Selected body", () => FlightGlobals.Bodies, onSelect, Extensions.CbToString));

            var apply = new ConditionalView(() =>
                            geeAsl.Valid &&
                            atmosphereDepth.Valid &&
                            atmosphereTemperatureSeaLevel.Valid &&
                            atmospherePressureSeaLevel.Valid &&
                            atmosphereMolarMass.Valid &&
                            atmosphereAdiabaticIndex.Valid &&
                            rotationPeriod.Valid &&
                            initialRotation.Valid,
                            new ButtonView("Apply", "Applies the changes to the body", () =>
                    {
                        new Model.PlanetEditor.PlanetSettings(
                            geeAsl.Object,
                            ocean.Value,
                            atmosphere.Value,
                            atmosphereContainsOxygen.Value,
                            atmosphereDepth.Object,
                            atmosphereTemperatureSeaLevel.Object,
                            atmospherePressureSeaLevel.Object,
                            atmosphereMolarMass.Object,
                            atmosphereAdiabaticIndex.Object,
                            rotates.Value,
                            rotationPeriod.Object,
                            initialRotation.Object,
                            tidallyLocked.Value,
                            body.orbit).CopyTo(body, false);
                    }));

            var editFields = new ConditionalView(() => body != null, new VerticalView(new IView[]
                    {
                        geeAsl,
                        ocean,
                        atmosphere,
                        atmosphereContainsOxygen,
                        atmosphereDepth,
                        atmosphereTemperatureSeaLevel,
                        atmospherePressureSeaLevel,
                        atmosphereMolarMass,
                        atmosphereAdiabaticIndex,
                        rotates,
                        rotationPeriod,
                        initialRotation,
                        tidallyLocked,
                        apply,
                    }));

            var resetToDefault = new ConditionalView(() => body != null,
                                     new ButtonView("Reset to defaults", "Reset the selected planet to defaults",
                                         () => { Model.PlanetEditor.ResetToDefault(body); onSelect(body); }));

            var copyToKerbin = new ConditionalView(() => body != null && body != Model.PlanetEditor.Kerbin,
                                   new ButtonView("Copy to kerbin", "Copies the selected planet's settings to kerbin",
                                       () => new Model.PlanetEditor.PlanetSettings(body).CopyTo(Model.PlanetEditor.Kerbin, false)));

            var savePlanet = new ConditionalView(() => body != null,
                                 new ButtonView("Save planet to config file", "Saves the current configuration of the planet to a file, so it stays edited even after a restart. Delete the file named the planet's name in " + IoExt.GetPath(null) + " to undo.",
                                     () => Model.PlanetEditor.SavePlanet(body)));

            var reloadDefaults = new ConditionalView(() => FlightGlobals.fetch != null && FlightGlobals.Bodies != null,
                                     new ButtonView("Reload config files", "Reloads the planet .cfg files in " + IoExt.GetPath(null),
                                         Model.PlanetEditor.ApplyFileDefaults));

            return new VerticalView(new IView[]
                {
                    selectBody,
                    editFields,
                    resetToDefault,
                    copyToKerbin,
                    savePlanet,
                    reloadDefaults
                });
        }
        // Also known as "closure hell"
        public static IView View()
        {
            ListSelectView<OrbitDriver> currentlyEditing = null;
            Action<OrbitDriver> onCurrentlyEditingChange = null;

            var setToCurrentOrbit = new ButtonView("Set to current orbit", "Sets all the fields of the editor to reflect the orbit of the currently selected vessel",
                () => onCurrentlyEditingChange(currentlyEditing.CurrentlySelected));

            var referenceSelector = new ListSelectView<CelestialBody>("Reference body", () => FlightGlobals.fetch == null ? null : FlightGlobals.fetch.bodies, null, Extensions.CbToString);

            #region Simple
            var simpleAltitude = new TextBoxView<double>("Altitude", "Altitude of circular orbit", 110000, Model.SiSuffix.TryParse);
            var simpleApply = new ConditionalView(() => simpleAltitude.Valid && referenceSelector.CurrentlySelected != null,
                                  new ButtonView("Apply", "Sets the orbit", () =>
                    {
                        Model.OrbitEditor.Simple(currentlyEditing.CurrentlySelected, simpleAltitude.Object, referenceSelector.CurrentlySelected);

                        currentlyEditing.ReInvokeOnSelect();
                    }));
            var simple = new VerticalView(new IView[]
                {
                    simpleAltitude,
                    referenceSelector,
                    simpleApply,
                    setToCurrentOrbit
                });
            #endregion

            #region Complex
            var complexInclination = new TextBoxView<double>("Inclination", "How close to the equator the orbit plane is", 0, double.TryParse);
            var complexEccentricity = new TextBoxView<double>("Eccentricity", "How circular the orbit is (0=circular, 0.5=elliptical, 1=parabolic)", 0, double.TryParse);
            var complexSemiMajorAxis = new TextBoxView<double>("Semi-major axis", "Mean radius of the orbit (ish)", 10000000, Model.SiSuffix.TryParse);
            var complexLongitudeAscendingNode = new TextBoxView<double>("Lon. of asc. node", "Longitude of the place where you cross the equator northwards", 0, double.TryParse);
            var complexArgumentOfPeriapsis = new TextBoxView<double>("Argument of periapsis", "Rotation of the orbit around the normal", 0, double.TryParse);
            var complexMeanAnomalyAtEpoch = new TextBoxView<double>("Mean anomaly at epoch", "Position along the orbit at the epoch", 0, double.TryParse);
            var complexEpoch = new TextBoxView<double>("Epoch", "Epoch at which mEp is measured", 0, Model.SiSuffix.TryParse);
            var complexEpochNow = new ButtonView("Set epoch to now", "Sets the Epoch field to the current time", () => complexEpoch.Object = Planetarium.GetUniversalTime());
            var complexApply = new ConditionalView(() => complexInclination.Valid &&
                                   complexEccentricity.Valid &&
                                   complexSemiMajorAxis.Valid &&
                                   complexLongitudeAscendingNode.Valid &&
                                   complexArgumentOfPeriapsis.Valid &&
                                   complexMeanAnomalyAtEpoch.Valid &&
                                   complexEpoch.Valid &&
                                   referenceSelector.CurrentlySelected != null,
                                   new ButtonView("Apply", "Sets the orbit", () =>
                    {
                        Model.OrbitEditor.Complex(currentlyEditing.CurrentlySelected,
                            complexInclination.Object,
                            complexEccentricity.Object,
                            complexSemiMajorAxis.Object,
                            complexLongitudeAscendingNode.Object,
                            complexArgumentOfPeriapsis.Object,
                            complexMeanAnomalyAtEpoch.Object,
                            complexEpoch.Object,
                            referenceSelector.CurrentlySelected);

                        currentlyEditing.ReInvokeOnSelect();
                    }));
            var complex = new VerticalView(new IView[]
                {
                    complexInclination,
                    complexEccentricity,
                    complexSemiMajorAxis,
                    complexLongitudeAscendingNode,
                    complexArgumentOfPeriapsis,
                    complexMeanAnomalyAtEpoch,
                    complexEpoch,
                    complexEpochNow,
                    referenceSelector,
                    complexApply,
                    setToCurrentOrbit
                });
            #endregion

            #region Graphical
            SliderView graphicalInclination = null;
            SliderView graphicalEccentricity = null;
            SliderView graphicalPeriapsis = null;
            SliderView graphicalLongitudeAscendingNode = null;
            SliderView graphicalArgumentOfPeriapsis = null;
            SliderView graphicalMeanAnomaly = null;
            double graphicalEpoch = 0;

            Action<double> graphicalOnChange = ignored =>
            {
                Model.OrbitEditor.Graphical(currentlyEditing.CurrentlySelected,
                    graphicalInclination.Value,
                    graphicalEccentricity.Value,
                    graphicalPeriapsis.Value,
                    graphicalLongitudeAscendingNode.Value,
                    graphicalArgumentOfPeriapsis.Value,
                    graphicalMeanAnomaly.Value,
                    graphicalEpoch);

                currentlyEditing.ReInvokeOnSelect();
            };

            graphicalInclination = new SliderView("Inclination", "How close to the equator the orbit plane is", graphicalOnChange);
            graphicalEccentricity = new SliderView("Eccentricity", "How circular the orbit is", graphicalOnChange);
            graphicalPeriapsis = new SliderView("Periapsis", "Lowest point in the orbit", graphicalOnChange);
            graphicalLongitudeAscendingNode = new SliderView("Lon. of asc. node", "Longitude of the place where you cross the equator northwards", graphicalOnChange);
            graphicalArgumentOfPeriapsis = new SliderView("Argument of periapsis", "Rotation of the orbit around the normal", graphicalOnChange);
            graphicalMeanAnomaly = new SliderView("Mean anomaly", "Position along the orbit", graphicalOnChange);

            var graphical = new VerticalView(new IView[]
                {
                    graphicalInclination,
                    graphicalEccentricity,
                    graphicalPeriapsis,
                    graphicalLongitudeAscendingNode,
                    graphicalArgumentOfPeriapsis,
                    graphicalMeanAnomaly,
                    setToCurrentOrbit
                });
            #endregion

            #region Velocity
            var velocitySpeed = new TextBoxView<double>("Speed", "dV to apply", 0, Model.SiSuffix.TryParse);
            var velocityDirection = new ListSelectView<Model.OrbitEditor.VelocityChangeDirection>("Direction", () => Model.OrbitEditor.AllVelocityChanges);
            var velocityApply = new ConditionalView(() => velocitySpeed.Valid,
                                    new ButtonView("Apply", "Adds the selected velocity to the orbit", () =>
                    {
                        Model.OrbitEditor.Velocity(currentlyEditing.CurrentlySelected, velocityDirection.CurrentlySelected, velocitySpeed.Object);
                    }));
            var velocity = new VerticalView(new IView[]
                {
                    velocitySpeed,
                    velocityDirection,
                    velocityApply
                });
            #endregion

            #region Rendezvous
            var rendezvousLeadTime = new TextBoxView<double>("Lead time", "How many seconds off to rendezvous at (zero = on top of each other, bad)", 1, Model.SiSuffix.TryParse);
            var rendezvousVessel = new ListSelectView<Vessel>("Target vessel", () => FlightGlobals.fetch == null ? null : FlightGlobals.fetch.vessels, null, Extensions.VesselToString);
            var rendezvousApply = new ConditionalView(() => rendezvousLeadTime.Valid && rendezvousVessel.CurrentlySelected != null,
                                      new ButtonView("Apply", "Rendezvous", () =>
                    {
                        Model.OrbitEditor.Rendezvous(currentlyEditing.CurrentlySelected, rendezvousLeadTime.Object, rendezvousVessel.CurrentlySelected);
                    }));
            // rendezvous gets special ConditionalView to force only editing of planets
            var rendezvous = new ConditionalView(() => currentlyEditing.CurrentlySelected != null && currentlyEditing.CurrentlySelected.vessel != null,
                                 new VerticalView(new IView[]
                    {
                        rendezvousLeadTime,
                        rendezvousVessel,
                        rendezvousApply
                    }));
            #endregion

            #region CurrentlyEditing
            onCurrentlyEditingChange = newEditing =>
            {
                if (newEditing == null)
                {
                    return;
                }
                {
                    double altitude;
                    CelestialBody body;
                    Model.OrbitEditor.GetSimple(newEditing, out altitude, out body);
                    simpleAltitude.Object = altitude;
                    referenceSelector.CurrentlySelected = body;
                }
                {
                    double inclination;
                    double eccentricity;
                    double semiMajorAxis;
                    double longitudeAscendingNode;
                    double argumentOfPeriapsis;
                    double meanAnomalyAtEpoch;
                    double epoch;
                    CelestialBody body;
                    Model.OrbitEditor.GetComplex(newEditing,
                        out inclination,
                        out eccentricity,
                        out semiMajorAxis,
                        out longitudeAscendingNode,
                        out argumentOfPeriapsis,
                        out meanAnomalyAtEpoch,
                        out epoch,
                        out body);
                    complexInclination.Object = inclination;
                    complexEccentricity.Object = eccentricity;
                    complexSemiMajorAxis.Object = semiMajorAxis;
                    complexLongitudeAscendingNode.Object = longitudeAscendingNode;
                    complexArgumentOfPeriapsis.Object = argumentOfPeriapsis;
                    complexMeanAnomalyAtEpoch.Object = meanAnomalyAtEpoch;
                    complexEpoch.Object = epoch;
                    referenceSelector.CurrentlySelected = body;
                }
                {
                    double inclination;
                    double eccentricity;
                    double periapsis;
                    double longitudeAscendingNode;
                    double argumentOfPeriapsis;
                    double meanAnomaly;
                    Model.OrbitEditor.GetGraphical(newEditing,
                        out inclination,
                        out eccentricity,
                        out periapsis,
                        out longitudeAscendingNode,
                        out argumentOfPeriapsis,
                        out meanAnomaly,
                        out graphicalEpoch);
                    graphicalInclination.Value = inclination;
                    graphicalEccentricity.Value = eccentricity;
                    graphicalPeriapsis.Value = periapsis;
                    graphicalLongitudeAscendingNode.Value = longitudeAscendingNode;
                    graphicalArgumentOfPeriapsis.Value = argumentOfPeriapsis;
                    graphicalMeanAnomaly.Value = meanAnomaly;
                }
                {
                    Model.OrbitEditor.VelocityChangeDirection direction;
                    double speed;
                    Model.OrbitEditor.GetVelocity(newEditing, out direction, out speed);
                    velocityDirection.CurrentlySelected = direction;
                    velocitySpeed.Object = speed;
                }
            };

            currentlyEditing = new ListSelectView<OrbitDriver>("Currently editing", Model.OrbitEditor.OrderedOrbits, onCurrentlyEditingChange, Extensions.OrbitDriverToString);

            if (FlightGlobals.fetch != null && FlightGlobals.fetch.activeVessel != null && FlightGlobals.fetch.activeVessel.orbitDriver != null)
            {
                currentlyEditing.CurrentlySelected = FlightGlobals.fetch.activeVessel.orbitDriver;
            }
            #endregion

            var savePlanet = new ButtonView("Save planet", "Saves the current orbit of the planet to a file, so it stays edited even after a restart. Delete the file named the planet's name in " + IoExt.GetPath(null) + " to undo.",
                                 () => Model.PlanetEditor.SavePlanet(currentlyEditing.CurrentlySelected.celestialBody));
            var resetPlanet = new ButtonView("Reset to defaults", "Reset the selected planet to defaults",
                                  () => Model.PlanetEditor.ResetToDefault(currentlyEditing.CurrentlySelected.celestialBody));

            var planetButtons = new ConditionalView(() => currentlyEditing.CurrentlySelected?.celestialBody != null,
                                    new VerticalView(new IView[]
                    {
                        savePlanet,
                        resetPlanet
                    }));

            var tabs = new TabView(new List<KeyValuePair<string, IView>>()
                {
                    new KeyValuePair<string, IView>("Simple", simple),
                    new KeyValuePair<string, IView>("Complex", complex),
                    new KeyValuePair<string, IView>("Graphical", graphical),
                    new KeyValuePair<string, IView>("Velocity", velocity),
                    new KeyValuePair<string, IView>("Rendezvous", rendezvous),
                });

            return new VerticalView(new IView[]
                {
                    currentlyEditing,
                    planetButtons,
                    new ConditionalView(() => currentlyEditing.CurrentlySelected != null, tabs)
                });
        }