private void AddChar(char c) { AddCharOperation addCharOperation = new AddCharOperation(_textBuffer, c); _undoBuffer.Add(addCharOperation); addCharOperation.Do(); }
private async void MakeCopyOfGroup() { if (MeshGroups.Count > 0 && SelectedMeshGroupIndex != -1) { string makingCopyLabel = "Making Copy".Localize(); string makingCopyLabelFull = string.Format("{0}:", makingCopyLabel); processingProgressControl.ProcessType = makingCopyLabelFull; processingProgressControl.Visible = true; processingProgressControl.PercentComplete = 0; LockEditControls(); await Task.Run((System.Action) CopyGroup); if (HasBeenClosed) { return; } UnlockEditControls(); PullMeshGroupDataFromAsynchLists(); PartHasBeenChanged(); // now set the selection to the new copy SelectedMeshGroupIndex = MeshGroups.Count - 1; UndoBuffer.Add(new CopyUndoCommand(this, SelectedMeshGroupIndex)); } }
public void replaceAllItems(string replaceWhat, string replaceWith, bool direction) { if (Movie == null) { return; } int start = 0; int end = FrameData.Input.Length; bool search = !(lvInput.SelectedIndices.Count > 1); UndoBuffer.Add(ref UndoHistory, ref FrameData.Input); int totalReplacements = 0; if (!search) { for (int i = 0; i < lvInput.SelectedIndices.Count; i++) { for (int j = 0; j < FrameData.Input[i].Controller.Length; j++) { if (FrameData.Input[lvInput.SelectedIndices[i]].Controller[j] != replaceWhat) { continue; } FrameData.Input[lvInput.SelectedIndices[i]].Controller[j] = replaceWith; ++totalReplacements; } } } else { for (int i = start; i < end; i++) { for (int j = 0; i < FrameData.Input[i].Controller.Length; i++) { if (FrameData.Input[i].Controller[j] != replaceWhat) { continue; } FrameData.Input[i].Controller[j] = replaceWith; ++totalReplacements; } } } updateControlsAfterEdit(); MessageBox.Show(this, "" + totalReplacements + " cases replaced.", "Replace", MessageBoxButtons.OK, MessageBoxIcon.None, MessageBoxDefaultButton.Button1); Msg.AddMsg("Replaced frame(s) on position with " + lvInput.SelectedIndices[0]); }
/// <summary> /// Insert the buffered frame input at/after the selected position. /// </summary> private void pasteFrames(bool after) { bool notEmpty = (lvInput.Items.Count > 0); if (notEmpty) { // check for a valid paste position if (lvInput.SelectedIndices.Count == 0) { return; } } int framePos = notEmpty ? (after ? lvInput.SelectedIndices[lvInput.SelectedIndices.Count - 1] + 1: lvInput.SelectedIndices[0]) : 0; // confirm whether to paste frames if (mnuEditingPrompt.Checked) { DialogResult confirmPaste = MessageBox.Show(this, "Paste " + FrameBuffer.Input.Length + " frame(s) " + (notEmpty && after ? "after frame " + (framePos - 1) : "at frame " + framePos) + " ?", "Confirm Paste", MessageBoxButtons.OKCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1); if (confirmPaste != DialogResult.OK) { return; } } UndoBuffer.Add(ref UndoHistory, ref FrameData.Input); TASMovieInput.Insert(ref FrameData.Input, ref FrameBuffer.Input, framePos); updateControlsAfterEdit(); lvInput.SelectedIndices.Clear(); for (int i = 0; i < FrameBuffer.Input.Length; i++) { lvInput.Items[framePos + i].Selected = true; } int focusPos = lvInput.SelectedIndices[lvInput.SelectedIndices.Count - 1]; lvInput.Items[focusPos].Focused = true; lvInput.Focus(); lvInput.EnsureVisible(focusPos); lvInput.Refresh(); Msg.AddMsg("Pasted " + FrameBuffer.Input.Length + " frame(s)"); }
void InsertLine(Point pos, Point cursor) { CharacterHandler handler = this.Handler as CharacterHandler; Canvas canvas = handler.CurrentPage.Canvas; var rect = new Rectangle(cursor.X, cursor.Y, canvas.Width - cursor.X, 1); var undo = new UndoBuffer() { CursorLocation = handler.CursorPosition }; undo.Add(new UndoRect(handler, rect)); undo.Add(new UndoInsertLine(handler, pos.Y)); handler.Undo.Save(undo); var buffer = canvas.Copy(rect); canvas.Fill(rect, CanvasElement.Default); canvas.InsertRow(pos.Y); canvas.Set(pos, buffer); handler.InvalidateCharacterRegion(rect, true); handler.InvalidateCharacterRegion(new Rectangle(0, pos.Y, canvas.Width, canvas.Height - pos.Y), true); }
public void storeDo(string option, Element e) { Element olde = null; if (e.UndoElement != null) { olde = e.UndoElement.Copy(); } Element newe = e.Copy(); var buff = new BuffElement(e, newe, olde, option); undoB.Add(buff); e.UndoElement = e.Copy(); }
/// <summary> /// Remove the row from the listview at the selectedIndex point and /// update the inputArray, or if multiple rows have been selected, prompt for deletion /// </summary> private void removeFrames() { // make sure something is selected if (lvInput.SelectedIndices.Count == 0) { return; } int[] selectedIndices = new int[lvInput.SelectedIndices.Count]; lvInput.SelectedIndices.CopyTo(selectedIndices, 0); //int framePosition = Convert.ToInt32(lvInput.Items[frameIndex].Text); // prompt for multiple frame insertion if (lvInput.SelectedIndices.Count > 1 && mnuEditingPrompt.Checked) { DialogResult confirmDelete = MessageBox.Show(this, "Are you sure you want to remove the selected " + lvInput.SelectedIndices.Count + " frames", "Confirm Multiple Frame Removal", MessageBoxButtons.OKCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1); if (confirmDelete != DialogResult.OK) { return; } } UndoBuffer.Add(ref UndoHistory, ref FrameData.Input); TASMovieInput.Remove(ref FrameData.Input, selectedIndices); //* // HACK::ensures that the virtual list doesn't try to access an element that // no longer exists after a block of frames is deleted int focusPos = selectedIndices[selectedIndices.Length - 1] - selectedIndices.Length; if (FrameData.Input.Length > 0) { // if we haven't removed all frames... lvInput.Items[focusPos].Focused = true; lvInput.Focus(); lvInput.EnsureVisible(focusPos); } lvInput.SelectedIndices.Clear(); //*/ updateControlsAfterEdit(); Msg.AddMsg("Removed " + lvInput.SelectedIndices.Count + " frame(s)"); }
private async void AutoArrangePartsInBackground() { if (MeshGroups.Count > 0) { string progressArrangeParts = LocalizedString.Get("Arranging Parts"); string progressArrangePartsFull = string.Format("{0}:", progressArrangeParts); processingProgressControl.ProcessType = progressArrangePartsFull; processingProgressControl.Visible = true; processingProgressControl.PercentComplete = 0; LockEditControls(); List <Matrix4X4> preArrangeTarnsforms = new List <Matrix4X4>(MeshGroupTransforms); await Task.Run(() => { Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture; PushMeshGroupDataToAsynchLists(TraceInfoOpperation.DONT_COPY); PlatingHelper.ArrangeMeshGroups(asyncMeshGroups, asyncMeshGroupTransforms, asyncPlatingDatas, ReportProgressChanged); }); if (HasBeenClosed) { return; } // offset them to the center of the bed for (int i = 0; i < asyncMeshGroups.Count; i++) { asyncMeshGroupTransforms[i] *= Matrix4X4.CreateTranslation(new Vector3(ActiveSliceSettings.Instance.GetValue <Vector2>(SettingsKey.print_center), 0)); } PartHasBeenChanged(); PullMeshGroupDataFromAsynchLists(); List <Matrix4X4> postArrangeTarnsforms = new List <Matrix4X4>(MeshGroupTransforms); UndoBuffer.Add(new ArangeUndoCommand(this, preArrangeTarnsforms, postArrangeTarnsforms)); UnlockEditControls(); } }
public void replaceCurrentSelection(string replaceWith) { if (Movie == null) { return; } if (lvInput.SelectedIndices.Count < 1) { return; } UndoBuffer.Add(ref UndoHistory, ref FrameData.Input); for (int i = 0; i < lvInput.SelectedIndices.Count; i++) { FrameData.Input[lvInput.SelectedIndices[i]].Controller[0] = replaceWith; } updateControlsAfterEdit(); Msg.AddMsg("Replaced frame(s) on position with " + lvInput.SelectedIndices[0]); }
/// <summary> /// Append a blank row into the listview after the selectedIndex point and /// update the inputArray, or prompt for insertion of multiple frames based /// on how many frames were selected. /// </summary> private void appendFrames() { int framePosition = FrameData.Input.Length; int totalFrames = 1; // make sure something is selected if (lvInput.SelectedIndices.Count > 0) { framePosition = lvInput.SelectedIndices[lvInput.SelectedIndices.Count - 1] + 1; totalFrames = lvInput.SelectedIndices.Count; } if (FrameData.Input.Length == 0) { framePosition = 0; } // prompt for multiple frame insertion if (lvInput.SelectedIndices.Count > 1 && mnuEditingPrompt.Checked) { DialogResult confirmAdd = MessageBox.Show(this, "Are you sure you want to append " + totalFrames + " frames after frame " + framePosition, "Confirm Multiple Frame Insertion", MessageBoxButtons.OKCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1); if (confirmAdd != DialogResult.OK) { return; } } UndoBuffer.Add(ref UndoHistory, ref FrameData.Input); TASMovieInput.Insert(ref FrameData.Input, new TASMovieInput(), framePosition, totalFrames); updateControlsAfterEdit(); Msg.AddMsg("Appended " + totalFrames + " frame(s) after position " + framePosition); }
public bool DoPhysicsBlockchange(int b, BlockID block, bool overRide = false, PhysicsArgs data = default(PhysicsArgs), bool addUndo = true) { if (blocks == null || b < 0 || b >= blocks.Length) { return(false); } BlockID old = blocks[b]; #if TEN_BIT_BLOCKS BlockID extended = Block.ExtendedBase[old]; if (extended > 0) { old = (BlockID)(extended | GetExtTile(b)); } #else if (old == Block.custom_block) { old = (BlockID)(Block.Extended | GetExtTile(b)); } #endif try { if (!overRide) { if (Props[old].OPBlock || (Props[block].OPBlock && data.Raw != 0)) { return(false); } } if (old == Block.Sponge && physics > 0 && block != Block.Sponge) { OtherPhysics.DoSpongeRemoved(this, b, false); } if (old == Block.LavaSponge && physics > 0 && block != Block.LavaSponge) { OtherPhysics.DoSpongeRemoved(this, b, true); } if (addUndo) { UndoPos uP = default(UndoPos); uP.Index = b; uP.SetData(old, block); if (UndoBuffer.Count < Server.Config.PhysicsUndo) { UndoBuffer.Add(uP); } else { if (currentUndo >= Server.Config.PhysicsUndo) { currentUndo = 0; } UndoBuffer[currentUndo] = uP; } currentUndo++; } Changed = true; if (block >= Block.Extended) { #if TEN_BIT_BLOCKS blocks[b] = Block.ExtendedClass[block >> Block.ExtendedShift]; #else blocks[b] = Block.custom_block; #endif ushort x, y, z; IntToPos(b, out x, out y, out z); FastSetExtTile(x, y, z, (BlockRaw)block); } else { blocks[b] = (BlockRaw)block; if (old >= Block.Extended) { ushort x, y, z; IntToPos(b, out x, out y, out z); FastRevertExtTile(x, y, z); } } if (physics > 0 && (ActivatesPhysics(block) || data.Raw != 0)) { AddCheck(b, false, data); } // Save bandwidth not sending identical looking blocks, like air/op_air changes. return(!Block.VisuallyEquals(old, block)); } catch { return(false); } }
/// <summary> /// Insert the buffered frame input at/after each selected position. /// </summary> private void pasteFramesMultiple(bool after) { // check for a valid paste position if (lvInput.SelectedIndices.Count <= 1) { return; } int[] selectedIndices = new int[lvInput.SelectedIndices.Count]; if (after) { for (int i = 0; i < selectedIndices.Length; i++) { selectedIndices[i] = lvInput.SelectedIndices[i] + 1; } } else { lvInput.SelectedIndices.CopyTo(selectedIndices, 0); } bool multiplePaste = false; // ask whether to paste multiple times if (mnuEditingPrompt.Checked) { DialogResult confirmPaste = MessageBox.Show(this, "Paste " + selectedIndices.Length + " chunks of " + FrameBuffer.Input.Length + " frame(s) " + (after ? "after" : "before") + " each selected frame?\nWarning: this might be extremely slow!", "Confirm Paste", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1); if (confirmPaste == DialogResult.Yes) { multiplePaste = true; } else if (confirmPaste == DialogResult.No) { multiplePaste = false; } else { return; } } UndoBuffer.Add(ref UndoHistory, ref FrameData.Input); if (multiplePaste) { TASMovieInput.InsertMultiple(ref FrameData.Input, ref FrameBuffer.Input, selectedIndices); } else { TASMovieInput.Insert(ref FrameData.Input, ref FrameBuffer.Input, (after ? selectedIndices[selectedIndices.Length - 1] : selectedIndices[0])); } lvInput.ClearVirtualCache(); lvInput.VirtualListSource = FrameData.Input; lvInput.VirtualListSize = FrameData.Input.Length; lvInput.SelectedIndices.Clear(); lvInput.Refresh(); if (multiplePaste) { for (int i = 0; i < selectedIndices.Length; i++) { for (int j = 0; j < FrameBuffer.Input.Length; j++) { lvInput.Items[selectedIndices[i] + i * FrameBuffer.Input.Length + j].Selected = true; } } } else { int startPos = (after ? selectedIndices[selectedIndices.Length - 1] : selectedIndices[0]); for (int i = 0; i < FrameBuffer.Input.Length; i++) { lvInput.Items[startPos + i].Selected = true; } } int focusPos = lvInput.SelectedIndices[lvInput.SelectedIndices.Count - 1]; lvInput.Items[focusPos].Focused = true; lvInput.Focus(); lvInput.EnsureVisible(focusPos); updateControlsAfterEdit(); if (multiplePaste) { Msg.AddMsg("Pasted " + lvInput.SelectedIndices.Count + " chunks of " + FrameBuffer.Input.Length + " frame(s)"); } else { Msg.AddMsg("Pasted " + FrameBuffer.Input.Length + " frame(s)"); } }
/// <summary> /// Update the input array with the changed frame data /// </summary> private void btnUpdate_Click(object sender, EventArgs e) { if (lvInput.SelectedIndices.Count == 0) { return; } bool[] updateFlag = { false, false, false, false, false }; TASMovieInput updated = new TASMovieInput(); if (sender == button1) { updated.Controller[0] = txtFrameDataC1.Text; updateFlag[0] = true; } else if (sender == button2) { updated.Controller[1] = txtFrameDataC2.Text; updateFlag[1] = true; } else if (sender == button3) { updated.Controller[2] = txtFrameDataC3.Text; updateFlag[2] = true; } else if (sender == button4) { updated.Controller[3] = txtFrameDataC4.Text; updateFlag[3] = true; } else if (sender == button5) { updated.Controller[4] = txtFrameDataC5.Text; updateFlag[4] = true; } else { if (chkFrameDataC1.Checked) { updated.Controller[0] = txtFrameData.Text; updateFlag[0] = true; } if (chkFrameDataC2.Checked) { updated.Controller[1] = txtFrameData.Text; updateFlag[1] = true; } if (chkFrameDataC3.Checked) { updated.Controller[2] = txtFrameData.Text; updateFlag[2] = true; } if (chkFrameDataC4.Checked) { updated.Controller[3] = txtFrameData.Text; updateFlag[3] = true; } if (chkFrameDataC5.Checked) { updated.Controller[4] = txtFrameData.Text; updateFlag[4] = true; } } // if no controllers were set, return if (!updateFlag[0] && !updateFlag[1] && !updateFlag[2] && !updateFlag[3] && !updateFlag[4]) { return; } // prompt for multiple frame insertion if (lvInput.SelectedIndices.Count > 1 && EditingPrompts) { DialogResult confirmUpdate = MessageBox.Show(MovieSplicer.UI.frmMain.frm, "Are you sure you want to update the " + lvInput.SelectedIndices.Count + " frames with the same input?", "Confirm Multiple Frame Update", MessageBoxButtons.OKCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1); if (confirmUpdate != DialogResult.OK) { return; } } UndoBuffer.Add(ref UndoHistory, ref FrameData); int[] selectedIndices = new int[lvInput.SelectedIndices.Count]; lvInput.SelectedIndices.CopyTo(selectedIndices, 0); // append or overwrite check if (chkAppendInput.Checked) { TASMovieInput.UpdatePlus(ref FrameData, updated, updateFlag, AutoFire, selectedIndices); } else { TASMovieInput.Update(ref FrameData, updated, updateFlag, AutoFire, selectedIndices); } lvInput.ClearVirtualCache(); lvInput.Refresh(); Msg.AddMsg("Updated " + lvInput.SelectedIndices.Count + " frame(s)"); }
internal bool DoPhysicsBlockchange(int b, ExtBlock block, bool overRide = false, PhysicsArgs data = default(PhysicsArgs), bool addUndo = true) { if (blocks == null || b < 0 || b >= blocks.Length) { return(false); } ExtBlock old; old.BlockID = blocks[b]; old.ExtID = old.BlockID == Block.custom_block ? GetExtTile(b) : Block.Air; try { if (!overRide) { if (Props[old.Index].OPBlock || (Props[block.Index].OPBlock && data.Raw != 0)) { return(false); } } if (old.BlockID == Block.Sponge && physics > 0 && block.BlockID != Block.Sponge) { OtherPhysics.DoSpongeRemoved(this, b, false); } if (old.BlockID == Block.LavaSponge && physics > 0 && block.BlockID != Block.LavaSponge) { OtherPhysics.DoSpongeRemoved(this, b, true); } if (addUndo) { UndoPos uP = default(UndoPos); uP.index = b; uP.SetData(old, block); if (UndoBuffer.Count < ServerConfig.PhysicsUndo) { UndoBuffer.Add(uP); } else { if (currentUndo >= ServerConfig.PhysicsUndo) { currentUndo = 0; } UndoBuffer[currentUndo] = uP; } currentUndo++; } blocks[b] = block.BlockID; Changed = true; if (block.BlockID == Block.custom_block) { ushort x, y, z; IntToPos(b, out x, out y, out z); SetExtTileNoCheck(x, y, z, block.ExtID); } else if (old.BlockID == Block.custom_block) { ushort x, y, z; IntToPos(b, out x, out y, out z); RevertExtTileNoCheck(x, y, z); } if (physics > 0 && (ActivatesPhysics(block) || data.Raw != 0)) { AddCheck(b, false, data); } // Save bandwidth sending identical looking blocks, like air/op_air changes. return(!old.VisuallyEquals(block)); } catch { blocks[b] = block.BlockID; return(false); } }
internal bool DoPhysicsBlockchange(int b, byte block, bool overRide = false, PhysicsArgs data = default(PhysicsArgs), byte extBlock = 0, bool addUndo = true) { if (b < 0 || b >= blocks.Length || blocks == null) { return(false); } byte old = blocks[b]; byte oldExt = old == Block.custom_block ? GetExtTile(b) : (byte)0; try { if (!overRide) { if (Block.Props[old].OPBlock || (Block.Props[block].OPBlock && data.Raw != 0)) { return(false); } } if (b == Block.sponge && physics > 0 && block != Block.sponge) { OtherPhysics.DoSpongeRemoved(this, b); } if (b == Block.lava_sponge && physics > 0 && block != Block.lava_sponge) { OtherPhysics.DoSpongeRemoved(this, b, true); } if (addUndo) { UndoPos uP = default(UndoPos); uP.index = b; uP.SetData(old, oldExt, block, extBlock); if (UndoBuffer.Count < Server.physUndo) { UndoBuffer.Add(uP); } else { if (currentUndo >= Server.physUndo) { currentUndo = 0; } UndoBuffer[currentUndo] = uP; } currentUndo++; } blocks[b] = block; changed = true; if (block == Block.custom_block) { ushort x, y, z; IntToPos(b, out x, out y, out z); SetExtTileNoCheck(x, y, z, extBlock); } else if (old == Block.custom_block) { ushort x, y, z; IntToPos(b, out x, out y, out z); RevertExtTileNoCheck(x, y, z); } if (physics > 0 && (ActivatesPhysics(block, extBlock) || data.Raw != 0)) { AddCheck(b, false, data); } // Save bandwidth sending identical looking blocks, like air/op_air changes. bool diffBlock = Block.Convert(old) != Block.Convert(block); if (!diffBlock && old == Block.custom_block) { diffBlock = oldExt != extBlock; } return(diffBlock); } catch { blocks[b] = block; return(false); } }
public static GuiWidget GetFieldContentWithSlider(EditableProperty property, PPEContext context, UIField field, UndoBuffer undoBuffer, Func <string, object> valueFromString, ThemeConfig theme) { var sliderAttribute = property.PropertyInfo.GetCustomAttributes(true).OfType <SliderAttribute>().FirstOrDefault(); if (sliderAttribute != null) { var min = sliderAttribute.Min; var max = sliderAttribute.Max; var delta = max - min; // the slider values go from 0 to 1 and are then mapped during translation to the field var slider = new Slider(new Vector2(0, 0), 80 * GuiWidget.DeviceScale, 0, 1) { VAnchor = VAnchor.Center, }; slider.View.TrackColor = theme.TextColor; slider.View.ThumbColor = theme.PrimaryAccentColor; slider.View.TrackHeight = 1 * GuiWidget.DeviceScale; Func <double> getFieldValue = null; double GetSlider0To1FromField() { return(GetSlider0To1FromValue(getFieldValue())); } double GetSlider0To1FromValue(double value) { var mapped0To1 = Math.Max(0, Math.Min(1, (value - min) / delta)); return(Easing.CalculateInverse(sliderAttribute.EasingType, sliderAttribute.EaseOption, mapped0To1)); } double GetFieldFromSlider0To1() { var fieldValue = Easing.Calculate(sliderAttribute.EasingType, sliderAttribute.EaseOption, slider.Value) * delta + min; var snapGridDistance = sliderAttribute.SnapDistance; if (sliderAttribute.UseSnappingGrid) { snapGridDistance = SnapGridDistance(); } if (snapGridDistance > 0) { // snap this position to the grid // snap this position to the grid fieldValue = ((int)((fieldValue / snapGridDistance) + .5)) * snapGridDistance; } return(fieldValue); } double SnapGridDistance() { var view3DWidget = slider.Parents <View3DWidget>().FirstOrDefault(); if (view3DWidget != null) { var object3DControlLayer = view3DWidget.Descendants <Object3DControlsLayer>().FirstOrDefault(); if (object3DControlLayer != null) { return(object3DControlLayer.SnapGridDistance); } } return(0); } var changeDueToSlider = false; var changeDueToField = false; slider.ValueChanged += (s, e) => { if (!changeDueToField) { changeDueToSlider = true; SetValue(property, context, valueFromString, GetFieldFromSlider0To1()); changeDueToSlider = false; } }; double sliderDownValue = 0; slider.SliderGrabed += (s, e) => { sliderDownValue = getFieldValue(); }; slider.SliderReleased += (s, e) => { var currentValue = GetFieldFromSlider0To1(); changeDueToSlider = true; SetValue(property, context, valueFromString, currentValue); changeDueToSlider = false; // save the undo information undoBuffer.Add(new UndoRedoActions(() => { SetValue(property, context, valueFromString, sliderDownValue); }, () => { SetValue(property, context, valueFromString, currentValue); })); }; GuiWidget content = null; var sliderRightMargin = 11; if (field is DoubleField doubleField) { getFieldValue = () => doubleField.DoubleValue; doubleField.ValueChanged += (s, e) => { changeDueToField = true; slider.Value = GetSlider0To1FromField(); changeDueToField = false; }; content = new FlowLayoutWidget(); content.AddChild(slider); content.AddChild(new GuiWidget() { Width = sliderRightMargin * GuiWidget.DeviceScale, Height = 3 }); content.AddChild(field.Content); } else if (field is ExpressionField expressionField) { getFieldValue = () => { if (double.TryParse(expressionField.Value, out double value)) { return(value); } return(0); }; expressionField.ValueChanged += (s, e) => { if (!changeDueToSlider) { changeDueToField = true; slider.Value = GetSlider0To1FromField(); changeDueToField = false; } }; expressionField.Content.Descendants <TextWidget>().First().TextChanged += (s, e) => { if (!changeDueToSlider) { changeDueToField = true; var textWidget = expressionField.Content.Descendants <TextWidget>().First(); double.TryParse(textWidget.Text, out double textWidgetValue); slider.Value = GetSlider0To1FromValue(textWidgetValue); changeDueToField = false; } }; var leftHold = new FlowLayoutWidget() { HAnchor = HAnchor.Stretch, Margin = new BorderDouble(0, 0, 66 / GuiWidget.DeviceScale + sliderRightMargin, 0) }; leftHold.AddChild(new HorizontalSpacer()); leftHold.AddChild(slider); field.Content.AddChild(leftHold, 0); content = field.Content; } // set the initial value of the slider changeDueToField = true; slider.Value = GetSlider0To1FromField(); changeDueToField = false; return(content); } return(field.Content); }