/// <summary> /// Handler invoked on mouse moved event. /// </summary> /// <param name="x">X coordinate.</param> /// <param name="y">Y coordinate.</param> /// <param name="dx">X change.</param> /// <param name="dy">Y change.</param> protected override void OnMouseMoved(int x, int y, int dx, int dy) { if (null == m_Target) { return; } if (!m_Held) { return; } Point p = new Point(x - m_HoldPos.X, y - m_HoldPos.Y); // Translate to parent if (m_Target.Parent != null) { p = m_Target.Parent.CanvasPosToLocal(p); } //m_Target->SetPosition( p.x, p.y ); m_Target.MoveTo(p.X, p.Y); if (Dragged != null) { Dragged.Invoke(this, EventArgs.Empty); } }
public override void dragged(IntVector2 position) { if (Dragged != null) { Dragged.Invoke(this, position); } }
private void Update() { if (Input.GetMouseButtonDown(0)) { touchStartPiece = GetHoveredPiece(); if (touchStartPiece == null) { ClickedEmpty?.Invoke(); } } else if (touchStartPiece != null) { Piece hovered = GetHoveredPiece(); //If is on the same piece if (hovered == touchStartPiece) { if (!Input.GetMouseButton(0)) { //clicked ClickedOnPiece?.Invoke(touchStartPiece); touchStartPiece = null; } } //If Dragged to another piece else if (hovered != null) { Dragged?.Invoke(touchStartPiece, hovered); touchStartPiece = null; } } }
protected void OnAction(InputAction.CallbackContext context) { var control = context.control; var device = control.device; var isMouseInput = device is Mouse; var isPenInput = !isMouseInput && device is Pen; // Read our current pointer values. var drag = context.ReadValue <PointerInput>(); if (isMouseInput) { drag.InputId = PointerInputModule.kMouseLeftId; } else if (isPenInput) { drag.InputId = int.MinValue; } if (drag.Contact && !m_Dragging) { Pressed?.Invoke(drag, context.time); m_Dragging = true; } else if (drag.Contact && m_Dragging) { Dragged?.Invoke(drag, context.time); } else { Released?.Invoke(drag, context.time); m_Dragging = false; } }
void IEndDragHandler.OnEndDrag(PointerEventData _) { if (dragged) { Dragged?.Invoke(); dragged = false; } }
/// <summary> /// Handler invoked on mouse moved event. /// </summary> /// <param name="x">X coordinate.</param> /// <param name="y">Y coordinate.</param> /// <param name="dx">X change.</param> /// <param name="dy">Y change.</param> protected override void onMouseMoved(int x, int y, int dx, int dy) { if (null == target) return; if (!held) return; Point p = new Point(x - holdPos.X, y - holdPos.Y); // Translate to parent if (target.Parent != null) p = target.Parent.CanvasPosToLocal(p); //m_Target->SetPosition( p.x, p.y ); target.MoveTo(p.X, p.Y); if (Dragged != null) Dragged.Invoke(this, EventArgs.Empty); }
private void OnDragged(PointerInput input, double time) { if (!activeGestures.TryGetValue(input.InputId, out var existingGesture)) { // Probably caught by UI, or the input was otherwise lost return; } existingGesture.SubmitPoint(input.Position, time); if (IsValidSwipe(ref existingGesture)) { PotentiallySwiped?.Invoke(new SwipeInput(existingGesture)); } Dragged?.Invoke(new DragInput(existingGesture)); DebugInfo(existingGesture); }
private void HandleMouseButton(ButtonState ButtonState, VoxelHandle underMouse, bool newVoxel, bool altPressed, ref bool ButtonPressed, InputManager.MouseButton Button) { // If the left mouse button is pressed, update the slection buffer. if (ButtonPressed) { // On release, select voxels. if (ButtonState == ButtonState.Released) { ReleaseSound.Play(World.Renderer.CursorLightPos); ButtonPressed = false; if (SelectionBuffer.Count > 0) { var t = new List <VoxelHandle>(SelectionBuffer); SelectionBuffer.Clear(); Selected.Invoke(t, Button); } BoxYOffset = 0; PrevBoxYOffsetInt = 0; } // Otherwise, update the selection buffer else { if (SelectionBuffer.Count == 0) { FirstVoxel = underMouse; SelectionBuffer.Add(underMouse); } else { SelectionBuffer.Clear(); SelectionBuffer.Add(FirstVoxel); SelectionBuffer.Add(underMouse); BoundingBox buffer = GetSelectionBox(); // Update the selection box to account for offsets from mouse wheel. if (BoxYOffset > 0) { buffer.Max.Y = MathFunctions.Clamp(buffer.Max.Y + (int)BoxYOffset, 0, World.WorldSizeInVoxels.Y - 1); } else if (BoxYOffset < 0) { buffer.Min.Y = MathFunctions.Clamp(buffer.Min.Y - (int)BoxYOffset, 0, World.WorldSizeInVoxels.Y - 1); } SelectionBuffer = Select(buffer, FirstVoxel.WorldPosition, underMouse.WorldPosition).ToList(); if (!altPressed && Brush.CullUnseenVoxels && SelectionType == VoxelSelectionType.SelectFilled) { SelectionBuffer.RemoveAll(v => { if (v.Equals(underMouse)) { return(false); } if (World.PersistentData.Designations.IsVoxelDesignation(v, DesignationType.Put)) { return(false); // Treat put designations as solid. } return(!VoxelHelpers.DoesVoxelHaveVisibleSurface(World, v)); }); } if (newVoxel) { DragSound.Play(World.Renderer.CursorLightPos, SelectionBuffer.Count / 20.0f); Dragged.Invoke(SelectionBuffer, Button); } } } } // If the mouse was not previously pressed, but is now pressed, then notify us of that. else if (ButtonState == ButtonState.Pressed) { ClickSound.Play(World.Renderer.CursorLightPos);; ButtonPressed = true; BoxYOffset = 0; PrevBoxYOffsetInt = 0; } }
public void Update() { MouseState mouse = Mouse.GetState(); KeyboardState keyboard = Keyboard.GetState(); Voxel underMouse = GetVoxelUnderMouse(); bool newVoxel = underMouse != null && !underMouse.Equals(VoxelUnderMouse); if (underMouse != null) { VoxelUnderMouse = underMouse; PlayState.CursorLightPos = underMouse.Position + new Vector3(0.5f, 0.5f, 0.5f); if (Enabled && underMouse.TypeName != "empty" && underMouse.IsExplored) { string info = underMouse.TypeName; if (PlayState.PlayerFaction.RoomBuilder.IsInRoom(underMouse)) { Room room = PlayState.PlayerFaction.RoomBuilder.GetMostLikelyRoom(underMouse); if (room != null) { info += " (" + room.ID + ")"; } } PlayState.GUI.ToolTipManager.PopupInfo(info); } } if (!Enabled) { return; } if (keyboard.IsKeyDown(Keys.LeftAlt) || keyboard.IsKeyDown(Keys.RightAlt)) { BoxYOffset += (float)(mouse.ScrollWheelValue - LastMouseWheel) * 0.01f; LastMouseWheel = mouse.ScrollWheelValue; newVoxel = true; } else { LastMouseWheel = mouse.ScrollWheelValue; } if (underMouse != null) { BoundingBox box = underMouse.GetBoundingBox().Expand(0.05f); Drawer3D.DrawBox(box, CurrentColor, CurrentWidth, true); } if (isLeftPressed) { if (mouse.LeftButton == ButtonState.Released) { isLeftPressed = false; LeftReleasedCallback(); BoxYOffset = 0; } else { if (SelectionBuffer.Count == 0) { FirstVoxel = underMouse; SelectionBuffer.Add(underMouse); } else { SelectionBuffer.Clear(); SelectionBuffer.Add(FirstVoxel); SelectionBuffer.Add(underMouse); BoundingBox buffer = GetSelectionBox(); if (BoxYOffset > 0) { buffer.Max.Y += BoxYOffset; } else if (BoxYOffset < 0) { buffer.Min.Y += BoxYOffset; } SelectionBuffer = Chunks.GetVoxelsIntersecting(buffer); if (newVoxel) { Dragged.Invoke(SelectionBuffer, InputManager.MouseButton.Left); } } } } else if (mouse.LeftButton == ButtonState.Pressed) { LeftPressedCallback(); isLeftPressed = true; BoxYOffset = 0; } if (isRightPressed) { if (mouse.RightButton == ButtonState.Released) { isRightPressed = false; RightReleasedCallback(); BoxYOffset = 0; } else { if (SelectionBuffer.Count == 0) { SelectionBuffer.Add(underMouse); FirstVoxel = underMouse; } else { SelectionBuffer.Clear(); SelectionBuffer.Add(FirstVoxel); SelectionBuffer.Add(underMouse); BoundingBox buffer = GetSelectionBox(); if (BoxYOffset > 0) { buffer.Max.Y += BoxYOffset; } else if (BoxYOffset < 0) { buffer.Min.Y += BoxYOffset; } SelectionBuffer = Chunks.GetVoxelsIntersecting(buffer); if (newVoxel) { Dragged.Invoke(SelectionBuffer, InputManager.MouseButton.Right); } } } } else if (mouse.RightButton == ButtonState.Pressed) { RightPressedCallback(); BoxYOffset = 0; isRightPressed = true; } }
public void Update() { MouseState mouse = Mouse.GetState(); KeyboardState keyboard = Keyboard.GetState(); var underMouse = GetVoxelUnderMouse(); // Keep track of whether a new voxel has been selected. bool newVoxel = underMouse.IsValid && underMouse != VoxelUnderMouse; if (!underMouse.IsValid) { return; } VoxelUnderMouse = underMouse; // Update the cursor light. World.CursorLightPos = underMouse.WorldPosition + new Vector3(0.5f, 0.5f, 0.5f); // Get the type of the voxel and display it to the player. if (Enabled && !underMouse.IsEmpty && underMouse.IsExplored) { string info = underMouse.Type.Name; // If it belongs to a room, display that information. if (World.PlayerFaction.RoomBuilder.IsInRoom(underMouse)) { Room room = World.PlayerFaction.RoomBuilder.GetMostLikelyRoom(underMouse); if (room != null) { info += " (" + room.ID + ")"; } } World.ShowInfo(info); } // Do nothing if not enabled. if (!Enabled) { return; } bool altPressed = false; // If the left or right ALT keys are pressed, we can adjust the height of the selection // for building pits and tall walls using the mouse wheel. if (keyboard.IsKeyDown(Keys.LeftAlt) || keyboard.IsKeyDown(Keys.RightAlt)) { var change = mouse.ScrollWheelValue - LastMouseWheel; BoxYOffset += (change) * 0.01f; int offset = (int)BoxYOffset; if (offset != PrevBoxYOffsetInt) { DragSound.Play(World.CursorLightPos); newVoxel = true; } PrevBoxYOffsetInt = offset; altPressed = true; } else { PrevBoxYOffsetInt = 0; } LastMouseWheel = mouse.ScrollWheelValue; // Draw a box around the current voxel under the mouse. if (underMouse.IsValid) { BoundingBox box = underMouse.GetBoundingBox().Expand(0.05f); Drawer3D.DrawBox(box, CurrentColor, CurrentWidth, true); } // If the left mouse button is pressed, update the slection buffer. if (isLeftPressed) { // On release, select voxels. if (mouse.LeftButton == ButtonState.Released) { ReleaseSound.Play(World.CursorLightPos); isLeftPressed = false; LeftReleasedCallback(); BoxYOffset = 0; PrevBoxYOffsetInt = 0; } // Otherwise, update the selection buffer else { if (SelectionBuffer.Count == 0) { FirstVoxel = underMouse; SelectionBuffer.Add(underMouse); } else { SelectionBuffer.Clear(); SelectionBuffer.Add(FirstVoxel); SelectionBuffer.Add(underMouse); BoundingBox buffer = GetSelectionBox(); // Update the selection box to account for offsets from mouse wheel. if (BoxYOffset > 0) { buffer.Max.Y += (int)BoxYOffset; } else if (BoxYOffset < 0) { buffer.Min.Y += (int)BoxYOffset; } SelectionBuffer = Select(buffer, FirstVoxel.WorldPosition, underMouse.WorldPosition).ToList(); if (!altPressed && Brush != VoxelBrush.Stairs) { if (SelectionType == VoxelSelectionType.SelectFilled) { SelectionBuffer.RemoveAll(v => { if (v.Equals(underMouse)) { return(false); } return(v.IsExplored && !VoxelHelpers.DoesVoxelHaveVisibleSurface( Chunks.ChunkData, v)); }); } } if (newVoxel) { DragSound.Play(World.CursorLightPos, SelectionBuffer.Count / 20.0f); Dragged.Invoke(SelectionBuffer, InputManager.MouseButton.Left); } } } } // If the mouse was not previously pressed, but is now pressed, then notify us of that. else if (mouse.LeftButton == ButtonState.Pressed) { ClickSound.Play(World.CursorLightPos);; isLeftPressed = true; BoxYOffset = 0; PrevBoxYOffsetInt = 0; } // Case where the right mouse button is pressed (mirrors left mouse button) // TODO(Break this into a function) if (isRightPressed) { if (mouse.RightButton == ButtonState.Released) { ReleaseSound.Play(World.CursorLightPos); isRightPressed = false; RightReleasedCallback(); BoxYOffset = 0; PrevBoxYOffsetInt = 0; } else { if (SelectionBuffer.Count == 0) { SelectionBuffer.Add(underMouse); FirstVoxel = underMouse; } else { SelectionBuffer.Clear(); SelectionBuffer.Add(FirstVoxel); SelectionBuffer.Add(underMouse); BoundingBox buffer = GetSelectionBox(); if (BoxYOffset > 0) { buffer.Max.Y += (int)BoxYOffset; } else if (BoxYOffset < 0) { buffer.Min.Y += (int)BoxYOffset; } SelectionBuffer = VoxelHelpers.EnumerateCoordinatesInBoundingBox(buffer) .Select(c => new VoxelHandle(Chunks.ChunkData, c)) .Where(v => v.IsValid) .ToList(); if (newVoxel) { DragSound.Play(World.CursorLightPos, SelectionBuffer.Count / 20.0f); Dragged.Invoke(SelectionBuffer, InputManager.MouseButton.Right); } } } } else if (mouse.RightButton == ButtonState.Pressed) { ClickSound.Play(World.CursorLightPos); RightPressedCallback(); BoxYOffset = 0; isRightPressed = true; } }
public void Update() { MouseState mouse = Mouse.GetState(); KeyboardState keyboard = Keyboard.GetState(); Voxel underMouse = GetVoxelUnderMouse(); // Keep track of whether a new voxel has been selected. bool newVoxel = underMouse != null && !underMouse.Equals(VoxelUnderMouse); // If there is a voxel under the mouse... if (underMouse != null) { VoxelUnderMouse = underMouse; // Update the cursor light. PlayState.CursorLightPos = underMouse.Position + new Vector3(0.5f, 0.5f, 0.5f); // Get the type of the voxel and display it to the player. if (Enabled && !underMouse.IsEmpty && underMouse.IsExplored) { string info = underMouse.TypeName; // If it belongs to a room, display that information. if (PlayState.PlayerFaction.RoomBuilder.IsInRoom(underMouse)) { Room room = PlayState.PlayerFaction.RoomBuilder.GetMostLikelyRoom(underMouse); if (room != null) { info += " (" + room.ID + ")"; } } PlayState.GUI.ToolTipManager.PopupInfo(info); } } // Do nothing if not enabled. if (!Enabled) { return; } bool altPressed = false; // If the left or right ALT keys are pressed, we can adjust the height of the selection // for building pits and tall walls using the mouse wheel. if (keyboard.IsKeyDown(Keys.LeftAlt) || keyboard.IsKeyDown(Keys.RightAlt)) { BoxYOffset += (mouse.ScrollWheelValue - LastMouseWheel) * 0.01f; LastMouseWheel = mouse.ScrollWheelValue; newVoxel = true; altPressed = true; } else { LastMouseWheel = mouse.ScrollWheelValue; } // Draw a box around the current voxel under the mouse. if (underMouse != null) { BoundingBox box = underMouse.GetBoundingBox().Expand(0.05f); Drawer3D.DrawBox(box, CurrentColor, CurrentWidth, true); } // If the left mouse button is pressed, update the slection buffer. if (isLeftPressed) { // On release, select voxels. if (mouse.LeftButton == ButtonState.Released) { isLeftPressed = false; LeftReleasedCallback(); BoxYOffset = 0; } // Otherwise, update the selection buffer else { if (SelectionBuffer.Count == 0) { FirstVoxel = underMouse; SelectionBuffer.Add(underMouse); } else { SelectionBuffer.Clear(); SelectionBuffer.Add(FirstVoxel); SelectionBuffer.Add(underMouse); BoundingBox buffer = GetSelectionBox(); // Update the selection box to account for offsets from mouse wheel. if (BoxYOffset > 0) { buffer.Max.Y += BoxYOffset; } else if (BoxYOffset < 0) { buffer.Min.Y += BoxYOffset; } SelectionBuffer = Chunks.GetVoxelsIntersecting(buffer); if (!altPressed) { SelectionBuffer.RemoveAll( voxel => (!voxel.Equals(underMouse) && Chunks.ChunkData.IsVoxelOccluded(voxel))); } if (newVoxel) { Dragged.Invoke(SelectionBuffer, InputManager.MouseButton.Left); } } } } // If the mouse was not previously pressed, but is now pressed, then notify us of that. else if (mouse.LeftButton == ButtonState.Pressed) { LeftPressedCallback(); isLeftPressed = true; BoxYOffset = 0; } // Case where the right mouse button is pressed (mirrors left mouse button) // TODO(Break this into a function) if (isRightPressed) { if (mouse.RightButton == ButtonState.Released) { isRightPressed = false; RightReleasedCallback(); BoxYOffset = 0; } else { if (SelectionBuffer.Count == 0) { SelectionBuffer.Add(underMouse); FirstVoxel = underMouse; } else { SelectionBuffer.Clear(); SelectionBuffer.Add(FirstVoxel); SelectionBuffer.Add(underMouse); BoundingBox buffer = GetSelectionBox(); if (BoxYOffset > 0) { buffer.Max.Y += BoxYOffset; } else if (BoxYOffset < 0) { buffer.Min.Y += BoxYOffset; } SelectionBuffer = Chunks.GetVoxelsIntersecting(buffer); if (!altPressed) { SelectionBuffer.RemoveAll( voxel => (!voxel.Equals(underMouse) && Chunks.ChunkData.IsVoxelOccluded(voxel))); } if (newVoxel) { Dragged.Invoke(SelectionBuffer, InputManager.MouseButton.Right); } } } } else if (mouse.RightButton == ButtonState.Pressed) { RightPressedCallback(); BoxYOffset = 0; isRightPressed = true; } }
void InitializeComponent() { _outterBox.SetLayoutCallback(OnLayout); _surfaceLayout = new ELayout(this); _surfaceLayout.Show(); _surface = new CircleSurface(_surfaceLayout); _naviMenu = new CircleGenList(this, _surface) { Homogeneous = true, BackgroundColor = ElmSharp.Color.Gray }; _naviMenu.Show(); _draggedUpCallback = new SmartEvent(_naviMenu, "drag,start,up"); _draggedUpCallback.On += (s, e) => { if (_footer.TrackObject.IsVisible) { Dragged?.Invoke(this, new DraggedEventArgs(DraggedState.EdgeBottom)); } else { Dragged?.Invoke(this, new DraggedEventArgs(DraggedState.Up)); } }; _draggedDownCallback = new SmartEvent(_naviMenu, "drag,start,down"); _draggedDownCallback.On += (s, e) => { if (_header.TrackObject.IsVisible) { Dragged?.Invoke(this, new DraggedEventArgs(DraggedState.EdgeTop)); } else { Dragged?.Invoke(this, new DraggedEventArgs(DraggedState.Down)); } }; _outterBox.PackEnd(_naviMenu); _outterBox.PackEnd(_surfaceLayout); _surfaceLayout.StackAbove(_naviMenu); _defaultClass = new GenItemClass("1icon_1text") { GetTextHandler = (obj, part) => { if (part == "elm.text") { return((obj as Item).Text); } return(null); }, GetContentHandler = (obj, part) => { if (part == "elm.swallow.icon" && obj is Item menuItem && !string.IsNullOrEmpty(menuItem.Icon)) { var icon = new ElmSharp.Image(Xamarin.Forms.Forms.NativeParent) { AlignmentX = -1, AlignmentY = -1, WeightX = 1.0, WeightY = 1.0, MinimumWidth = _dafaultIconSize, MinimumHeight = _dafaultIconSize, }; icon.Show(); icon.Load(menuItem.Icon); return(icon); } return(null); } }; _naviMenu.ItemSelected += OnItemSelected; } void OnItemSelected(object sender, GenListItemEventArgs e) { ItemSelected?.Invoke(this, new SelectedItemChangedEventArgs((e.Item.Data as Item).Source, -1)); } void OnLayout() { _surfaceLayout.Geometry = Geometry; _naviMenu.Geometry = Geometry; } bool IsUpdated(List <List <Element> > items) { if (_itemCache == null) { return(true); } if (_itemCache.Count != items.Count) { return(true); } for (int i = 0; i < items.Count; i++) { if (_itemCache[i].Count != items[i].Count) { return(true); } for (int j = 0; j < items[i].Count; j++) { if (_itemCache[i][j] != items[i][j]) { return(true); } } } return(false); } }
protected internal override void update(EventLayer eventLayer, bool allowProcessing, Clock clock) { var touches = eventLayer.EventManager.Touches; var fingers = touches.Fingers; if (fingers.Count == fingerCount) { Vector2 primaryFingerVec = new Vector2(fingers[0].PixelDeltaX, fingers[0].PixelDeltaY); float primaryFingerLen = primaryFingerVec.length(); Vector2 longestLengthVec = primaryFingerVec; float longestLength = primaryFingerLen; if (primaryFingerLen > 0) { bool allVectorsSameDirection = true; for (int i = 1; i < fingerCount && allVectorsSameDirection; ++i) { Vector2 testFingerVec = new Vector2(fingers[i].PixelDeltaX, fingers[i].PixelDeltaY); float testFingerLen = testFingerVec.length(); if (testFingerLen > 0) { float cosTheta = primaryFingerVec.dot(ref testFingerVec) / (primaryFingerLen * testFingerLen); if (cosTheta > 0.5f) { if (testFingerLen > longestLength) { longestLengthVec = testFingerVec; longestLength = testFingerLen; } } else { allVectorsSameDirection = false; } } } if (allVectorsSameDirection) { DeltaX = longestLengthVec.x; DeltaY = longestLengthVec.y; AbsoluteX = fingers[0].PixelX; AbsoluteY = fingers[0].PixelY; if (!gestureStarted) { cancelMomentum(); gestureStarted = true; if (GestureStarted != null) { GestureStarted.Invoke(eventLayer, this); } } didGesture = true; averageSpeed[averageSpeedCursor] = longestLengthVec; averageSpeedCursor++; averageSpeedCursor %= averageSpeed.Length; //Make sure to fire event last so momentum can be canceled if needed if (Dragged != null) { Dragged.Invoke(eventLayer, this); } } } else if (gestureStarted) { //If we have done the gesture once and the correct number of fingers are down, keep reporting that we did the gesture didGesture = true; } } if (!didGesture) { if (gestureStarted) { momentumStarted = true; momentum = new IntVector2(0, 0); for (int i = 0; i < averageSpeed.Length; ++i) { momentum += averageSpeed[i]; } momentum /= averageSpeed.Length; momentumDirection = new Vector2(1.0f, 1.0f); if (momentum.x < 0.0f) { momentum.x = -momentum.x; momentumDirection.x = -1.0f; } if (momentum.y < 0.0f) { momentum.y = -momentum.y; momentumDirection.y = -1.0f; } if (momentum.x < minimumMomentum) { momentum.x = 0.0f; } if (momentum.y < minimumMomentum) { momentum.y = 0.0f; } deceleration = momentum / decelerationTime; //Important to fire event last so momentum can be canceled if needed if (MomentumStarted != null) { MomentumStarted(eventLayer, this); } } gestureStarted = false; if (momentum.length2() != 0.0f) { momentum -= deceleration * clock.DeltaSeconds; if (momentum.x < 0.0f) { momentum.x = 0.0f; } if (momentum.y <= 0.0f) { momentum.y = 0.0f; } Vector2 finalMomentum = momentum * momentumDirection; DeltaX = finalMomentum.x; DeltaY = finalMomentum.y; if (Dragged != null) { Dragged.Invoke(eventLayer, this); } } else if (momentumStarted) { momentumStarted = false; if (MomentumEnded != null) { MomentumEnded.Invoke(eventLayer, this); } } } didGesture = false; }
private void OnTouchDragged(InputAction.CallbackContext context) { Dragged?.Invoke(context.ReadValue <Vector2>(), context.time); }
public void OnDrag(PointerEventData eventData) { Dragged?.Invoke(); }