/// <summary> /// Calculate the correct position and size of a tab button, based on the /// index it is due to be placed at. /// </summary> /// <param name="index"> /// The index of the tab button /// </param> protected void CalculateTabButtonSizePosition(int index) { var btn = d_tabButtonVector[index]; // relative height is always 1.0 for buttons since they are embedded in a // panel of the correct height already var position = new UVector2(UDim.Absolute(0.0f), UDim.Absolute(0.0f)); var size = new USize(UDim.Absolute(0.0f), UDim.Relative(1.0f)); // x position is based on previous button if (index == 0) { // First button position.d_x = UDim.Absolute(d_firstTabOffset); } else { var prevButton = d_tabButtonVector[index - 1]; // position is prev pos + width position.d_x = prevButton.GetArea().d_max.d_x; } size.d_width = UDim.Absolute(btn.GetRenderedString().GetHorizontalExtent(btn)) + GetTabTextPadding() + GetTabTextPadding(); btn.SetPosition(position); btn.SetSize(size); var leftX = position.d_x.d_offset; btn.SetVisible((leftX < GetPixelSize().Width) && (leftX + btn.GetPixelSize().Width > 0)); btn.Invalidate(false); }
protected override void LayoutItemWidgets() { // get render area var renderRect = GetItemRenderArea(); // get starting position var x0 = CoordConverter.AlignToPixels(renderRect.d_min.X); var y0 = CoordConverter.AlignToPixels(renderRect.d_min.Y); var sz = new UVector2(UDim.Absolute(CoordConverter.AlignToPixels(renderRect.Width)), UDim.Absolute(0)); // set item width // iterate through all items attached to this window foreach (var item in ListItems) { // get the "optimal" height of the item and use that! sz.d_y.d_offset = CoordConverter.AlignToPixels(item.GetItemPixelSize().Height); // rounding errors ? // set destination rect var rect = new URect { Position = new UVector2(UDim.Absolute(x0), UDim.Absolute(y0)), Size = new USize(sz.d_x, sz.d_y) }; // todo: vector vs size item.SetArea(rect); // next position y0 += CoordConverter.AlignToPixels(sz.d_y.d_offset + ItemSpacing); } }
public UDim2 ReadAttribute(Attribute attr) { UDim x = UDimToken.ReadUDim(attr); UDim y = UDimToken.ReadUDim(attr); return(new UDim2(x, y)); }
public override void UpdateThumb() { var w = (Scrollbar)Window; var wlf = GetLookNFeel(); var area = wlf.GetNamedArea("ThumbTrackArea").GetArea().GetPixelRect(w); var theThumb = w.GetThumb(); var posExtent = w.GetDocumentSize() - w.GetPageSize(); float slideExtent; if (_vertical) { slideExtent = area.Height - theThumb.GetPixelSize().Height; theThumb.SetVertRange(area.Top / w.GetPixelSize().Height, (area.Top + slideExtent) / w.GetPixelSize().Height); theThumb.SetPosition( new UVector2(UDim.Absolute(area.Left), UDim.Relative((area.Top + (w.GetScrollPosition() * (slideExtent / posExtent))) / w.GetPixelSize().Height))); } else { slideExtent = area.Width - theThumb.GetPixelSize().Width; theThumb.SetHorzRange(area.Left / w.GetPixelSize().Width, (area.Left + slideExtent) / w.GetPixelSize().Width); theThumb.SetPosition( new UVector2( UDim.Relative((area.Left + (w.GetScrollPosition() * (slideExtent / posExtent))) / w.GetPixelSize().Width), UDim.Absolute(area.Top))); } }
// Overridden from Window protected override void InitialiseComponents() { // get horizontal scrollbar var horzScrollbar = GetHorzScrollbar(); // get vertical scrollbar var vertScrollbar = GetVertScrollbar(); // get scrolled container widget var container = GetScrolledContainer(); // do a bit of initialisation container.BanPropertyFromXML("MouseInputPropagationEnabled"); container.BanPropertyFromXML("ContentArea"); container.BanPropertyFromXML("ContentPaneAutoSized"); horzScrollbar.BanPropertyFromXML("AlwaysOnTop"); vertScrollbar.BanPropertyFromXML("AlwaysOnTop"); horzScrollbar.SetAlwaysOnTop(true); vertScrollbar.SetAlwaysOnTop(true); // container pane is always same size as this parent pane, // scrolling is actually implemented via positioning and clipping tricks. container.SetSize(new USize(UDim.Relative(1.0f), UDim.Relative(1.0f))); // subscribe to events we need to hear about vertScrollbar.ScrollPositionChanged += HandleScrollChange; horzScrollbar.ScrollPositionChanged += HandleScrollChange; container.ContentChanged += HandleContentAreaChange; container.AutoSizeSettingChanged += HandleAutoSizePaneChanged; // finalise setup ConfigureScrollbars(); }
/// <summary> /// set the movement range of the thumb for the vertical axis. /// /// The values specified here are relative to the parent window for the thumb, and are specified in whichever /// metrics mode is active for the widget. /// </summary> /// <param name="min"> /// the minimum setting for the thumb on the vertical axis. /// </param> /// <param name="max"> /// the maximum setting for the thumb on the vertical axis. /// </param> public void SetVertRange(float min, float max) { // ensure min <= max, swap if not. if (min > max) { var tmp = min; max = min; min = tmp; } _vertMax = max; _vertMin = min; // validate current position. var cp = CoordConverter.AsRelative(GetYPosition(), GetParentPixelSize().Height); if (cp < min) { SetYPosition(UDim.Relative(min)); } else if (cp > max) { SetYPosition(UDim.Relative(max)); } }
/// <summary> /// Move the window by the pixel offsets specified in \a offset. /// This is intended for internal system use - it is the method by /// which the title bar moves the frame window. /// </summary> /// <param name="offset"> /// Vector2 object containing the offsets to apply (offsets are in screen pixels). /// </param> public void OffsetPixelPosition(Lunatics.Mathematics.Vector2 offset) { var uOffset = new UVector2(UDim.Absolute(/*PixelAligned(*/ offset.X /*)*/), UDim.Absolute(/*PixelAligned(*/ offset.Y /*)*/)); SetPosition(d_area.Position + uOffset); }
/// <summary> /// set the movement range of the thumb for the horizontal axis. /// /// The values specified here are relative to the parent window for the thumb, and are specified in whichever /// metrics mode is active for the widget. /// </summary> /// <param name="min"> /// the minimum setting for the thumb on the horizontal axis. /// </param> /// <param name="max"> /// the maximum setting for the thumb on the horizontal axis. /// </param> public void SetHorzRange(float min, float max) { var parentSize = GetParentPixelSize(); // ensure min <= max, swap if not. if (min > max) { var tmp = min; max = min; min = tmp; } _horzMax = max; _horzMin = min; // validate current position. var cp = CoordConverter.AsAbsolute(GetXPosition(), parentSize.Width); if (cp < min) { SetXPosition(UDim.Absolute(min)); } else if (cp > max) { SetXPosition(UDim.Absolute(max)); } }
protected bool HandleHScroll(EventArgs e) { var h = (Scrollbar)((WindowEventArgs)e).Window; var newpos = -h.GetScrollPosition(); Pane.SetXPosition(UDim.Absolute(newpos)); return(true); }
/// <summary> /// Constructor for TabControl base class. /// </summary> /// <param name="type"></param> /// <param name="name"></param> public TabControl(string type, string name) : base(type, name) { d_tabHeight = new UDim(0, -1f); // means 'to be initialized later' d_tabPadding = new UDim(0, 5f); d_firstTabOffset = 0; d_tabPanePos = TabPanePosition.Top; AddTabControlProperties(); }
public TestWindow() { Size = new USize(UDim.Relative(0.5f)); Position = new UVector2(UDim.Absolute(200), UDim.Absolute(50)); Title = "MY BEAUTIJFUL TEST WINDOW!?"; CanClose = true; Icon = "Inventory"; }
public override void AutoPositionSize(Lunatics.Mathematics.Vector2 position, Sizef ownerSize) { var view = GetView(); var totalArea = view.GetUnclippedOuterRect().Get(); var contentArea = _itemViewRenderer.GetViewRenderArea(view, false, false); var withScrollContentArea = _itemViewRenderer.GetViewRenderArea(view, true, true); var frameSize = totalArea.Size - contentArea.Size; var withScrollFrameSize = totalArea.Size - withScrollContentArea.Size; var contentSize = new Sizef(view.GetRenderedMaxWidth(), view.GetRenderedTotalHeight()); var parentSize = view.GetParentPixelSize(); var maxSize = new Sizef(ownerSize.Width /*parentSize.Width - CoordConverter.AsAbsolute(view.GetXPosition(), parentSize.Width)*/, 0.8f * parentSize.Height /*CoordConverter.AsAbsolute(view.GetYPosition(), parentSize.Height)*/); var requiredSize = frameSize + contentSize + new Sizef(1, 1); if (requiredSize.Height > maxSize.Height) { requiredSize.Height = maxSize.Height; requiredSize.Width = Math.Min(maxSize.Width, requiredSize.Width - frameSize.Width + withScrollFrameSize.Width); view.SetVertScrollbarDisplayMode(ScrollbarDisplayMode.Shown); } else { view.SetVertScrollbarDisplayMode(ScrollbarDisplayMode.Hidden); } requiredSize.Width = ownerSize.Width; if (requiredSize.Width > maxSize.Width) { requiredSize.Width = maxSize.Width; requiredSize.Height = Math.Min(maxSize.Height, requiredSize.Height - frameSize.Height + withScrollFrameSize.Height); view.SetHorzScrollbarDisplayMode(ScrollbarDisplayMode.Shown); } else { view.SetHorzScrollbarDisplayMode(ScrollbarDisplayMode.Hidden); } var posY = position.Y + (ownerSize.Height - requiredSize.Height) / 2f; posY = posY < 0f ? 0f : posY; posY -= posY + requiredSize.Height > parentSize.Height //? parentSize.Height - (posY + requiredSize.Height + 1f) ? (posY + requiredSize.Height) - parentSize.Height : 0f; view.SetPosition(new UVector2(UDim.Absolute(position.X), UDim.Absolute(posY))); view.SetHeight(new UDim(0, requiredSize.Height)); view.SetWidth(new UDim(0, requiredSize.Width)); }
/// <summary> /// Set the current content pane area for the ScrolledContainer. /// </summary> /// <param name="area"> /// Rect object that details the pixel extents to use for the content /// pane represented by this ScrolledContainer. /// </param> /// <remarks> /// If the ScrolledContainer is configured to auto-size the content pane /// this call will have no effect. /// </remarks> public void SetContentArea(Rectf area) { if (!_autoSizePane) { _contentArea = area; SetSize(new USize(UDim.Absolute(_contentArea.Width), UDim.Absolute(_contentArea.Height))); // Fire event OnContentChanged(new WindowEventArgs(this)); } }
public static void WriteUDim(XmlDocument doc, XmlNode node, UDim value, string prefix = "") { XmlElement scale = doc.CreateElement(prefix + 'S'); scale.InnerText = value.Scale.ToInvariantString(); node.AppendChild(scale); XmlElement offset = doc.CreateElement(prefix + 'O'); offset.InnerText = value.Offset.ToInvariantString(); node.AppendChild(offset); }
/// <summary> /// Constructor for Window base class /// </summary> /// <param name="type"> /// String object holding Window type (usually provided by WindowFactory). /// </param> /// <param name="name"> /// String object holding unique name for the Window. /// </param> protected LayoutContainer(string type, string name) : base(type, name) { _needsLayouting = false; _clientChildContentArea = new CachedRectf(this, (e, v) => ((LayoutContainer)e).GetClientChildContentAreaImpl(v)); // layout should take the whole window by default I think SetSize(new USize(UDim.Relative(1), UDim.Relative(1))); ChildAdded += HandleChildAdded; ChildRemoved += HandleChildRemoved; }
public void WriteProperty(Property prop, XmlDocument doc, XmlNode node) { UDim2 value = prop.CastValue <UDim2>(); UDim xUDim = value.X; UDimToken.WriteUDim(doc, node, xUDim, "X"); UDim yUDim = value.Y; UDimToken.WriteUDim(doc, node, yUDim, "Y"); }
/// <summary> /// Update state for window dragging. /// </summary> /// <param name="localMouse"> /// Mouse position as a pixel offset from the top-left corner of this window. /// </param> protected void DoDragging(Lunatics.Mathematics.Vector2 localMouse) { // calculate amount to move var offset = new UVector2(UDim.Absolute(localMouse.X), UDim.Absolute(localMouse.Y)); offset -= (_usingFixedDragOffset) ? _fixedDragOffset : _dragPoint; // set new position SetPosition(GetPosition() + offset); // Perform event notification OnDragPositionChanged(new WindowEventArgs(this)); }
public override void Draw(DrawingContext ctx) { var spriteCountHorizontal = (int)Math.Ceiling((ActualSize.Width.Absolute() - _leftSprite.Width - _rightSprite.Width) / _leftSprite.Width); // Top row ctx.Draw(_topLeftSprite, ActualPosition); for (int i = 0; i < spriteCountHorizontal; ++i) { ctx.Draw(_topSprite, ActualPosition + new UVector2(_topSprite.Width * i + _topLeftSprite.Width, 0f)); } ctx.Draw(_topRightSprite, ActualPosition + new UVector2(ActualSize.Width - UDim.Absolute(_topRightSprite.Width), UDim.Zero)); // Middle rows and background int rowHeight = _leftSprite.Height; float height = ActualSize.Height.Absolute() - _topSprite.Height - _bottomSprite.Height; int amountOfRows = (int)Math.Ceiling(height / rowHeight); for (int row = 0; row < amountOfRows; row++) { int rowY = row * _leftSprite.Height + _topSprite.Height; ctx.Draw(_leftSprite, ActualPosition + new UVector2(UDim.Zero, UDim.Absolute(rowY))); for (int i = 0; i < spriteCountHorizontal; i++) { int spriteX = _leftSprite.Width + i * _middleSprite.Width; ctx.Draw(_middleSprite, ActualPosition + new UVector2(UDim.Absolute(spriteX), UDim.Absolute(rowY))); } ctx.Draw(_rightSprite, ActualPosition + new UVector2(ActualSize.Width.Absolute() - _rightSprite.Width, rowY)); } // Bottom row ctx.Draw(_bottomLeftSprite, ActualPosition + new UVector2(UDim.Zero, ActualSize.Height - UDim.Absolute(_bottomLeftSprite.Height))); for (int i = 0; i < spriteCountHorizontal; ++i) { ctx.Draw(_bottomSprite, ActualPosition + new UVector2(_bottomSprite.Width * i + _leftSprite.Width, ActualSize.Height.Absolute() - _bottomSprite.Height)); } ctx.Draw(_bottomRightSprite, ActualPosition + new UVector2(ActualSize.Width - UDim.Absolute(_bottomRightSprite.Width), ActualSize.Height - UDim.Absolute(_bottomRightSprite.Height))); if (_drawCorners) { // Corners ctx.Draw(_topLeftCorner, ActualPosition + new UVector2(UDim.Absolute(-1f))); ctx.Draw(_topRightCorner, ActualPosition + new UVector2(ActualSize.Width.Absolute() - _topRightCorner.Width + 1f, -1f)); ctx.Draw(_bottomLeftCorner, ActualPosition + new UVector2(-1f, ActualSize.Height.Absolute() - _bottomLeftCorner.Height + 1f)); ctx.Draw(_bottomRightCorner, ActualPosition + new UVector2(ActualSize.Width.Absolute() - _bottomRightCorner.Width + 1f, ActualSize.Height.Absolute() - _bottomRightCorner.Height + 1f)); } }
public bool ReadProperty(Property property, XmlNode token) { UDim result = ReadUDim(token); bool success = (result != null); if (success) { property.Type = PropertyType.UDim; property.Value = result; } return(success); }
/// <summary> /// Resize the ItemListBase to exactly fit the content that is attached to it. /// Return a Rect object describing, in un-clipped pixels, the window relative area /// that is to be used for rendering items. /// </summary> protected virtual void SizeToContentImpl() { var renderArea = GetItemRenderArea(); var wndArea = CoordConverter.AsAbsolute(GetArea(), GetParentPixelSize()); // get size of content var sz = GetContentSize(); // calculate the full size with the frame accounted for and resize the window to this sz.Width += wndArea.Width - renderArea.Width; sz.Height += wndArea.Height - renderArea.Height; SetSize(new USize(UDim.Absolute(sz.Width), UDim.Absolute(sz.Height))); }
public bool ReadProperty(Property property, XmlNode token) { UDim xUDim = UDimToken.ReadUDim(token, "X"); UDim yUDim = UDimToken.ReadUDim(token, "Y"); if (xUDim != null && yUDim != null) { property.Type = PropertyType.UDim2; property.Value = new UDim2(xUDim, yUDim); return(true); } return(false); }
/// <summary> /// Opens the PopupMenu. /// </summary> /// <param name="notify"> /// true if the parent menu bar or menu popup (if any) is to handle the open. /// </param> public void OpenPopupMenu(bool notify = true) { // no popup? or already open... if (_popup == null || _opened) { return; } _popupOpening = false; _popupClosing = false; // should we notify ? // if so, and we are attached to a menu bar or popup menu, we let it handle the "activation" var p = OwnerList; if (notify && p != null) { var menubar = p as Menubar; if (menubar != null) { // align the popup to the bottom-left of the menuitem var pos = new UVector2(UDim.Absolute(0), UDim.Absolute(d_pixelSize.Height)); _popup.SetPosition(pos + _popupOffset); menubar.ChangePopupMenuItem(this); return; // the rest is handled when the menu bar eventually calls us itself } // or maybe a popup menu? var popupMenu = p as PopupMenu; if (popupMenu != null) { // align the popup to the top-right of the menuitem var pos = new UVector2(UDim.Absolute(d_pixelSize.Width), UDim.Absolute(0)); _popup.SetPosition(pos + _popupOffset); popupMenu.ChangePopupMenuItem(this); return; // the rest is handled when the popup menu eventually calls us itself } } // by now we must handle it ourselves // match up with Menubar::changePopupMenu _popup.OpenPopupMenu(false); _opened = true; Invalidate(false); }
public void AddLabledCheckbox(string labelText, bool checkboxDefaultState, UDim2 position, out GUILabel label, out GUICheckbox checkbox) { label = new GUILabel(position, UDim2.Zero, labelText, TextAlign.Left, Theme); Vector2 textSize = label.Font.MeasureString(labelText); label.Size = new UDim2(0, textSize.X, 0, textSize.Y + (ElementPadding * 2)); UDim labelXPos = position.X + new UDim(0, textSize.X + ElementPadding); checkbox = new GUICheckbox(new UDim2(labelXPos, position.Y), label.Size.Y.Offset, Theme); checkbox.IsChecked = checkboxDefaultState; label.Parent = this; checkbox.Parent = this; }
/// <summary> /// Update the content container position according to the current /// state of the widget (like scrollbar positions, etc). /// </summary> protected void UpdateContainerPosition() { // basePos is the position represented by the scrollbars // (these are negated so pane is scrolled in the correct directions) var basePos = new UVector2(UDim.Absolute(-GetHorzScrollbar().GetScrollPosition()), UDim.Absolute(-GetVertScrollbar().GetScrollPosition())); // this bias is the absolute position that 0 on the scrollbars represent. // Allows the pane to function correctly with negatively positioned content. var bias = new UVector2(UDim.Absolute(_contentRect.d_min.X), UDim.Absolute(_contentRect.d_min.Y)); // set the new container pane position to be what the scrollbars request // minus any bias generated by the location of the content. GetScrolledContainer().SetPosition(basePos - bias); }
/// <summary> /// Causes the tooltip to position itself appropriately. /// </summary> public void PositionSelf() { // no recusion allowed for this function! if (_inPositionSelf) { return; } _inPositionSelf = true; var cursor = GetGUIContext().GetCursor(); var screen = new Rectf(Lunatics.Mathematics.Vector2.Zero, GetRootContainerSize()); var tipRect = GetUnclippedOuterRect().Get(); var mouseImage = cursor.GetImage(); var mousePos = cursor.GetPosition(); var mouseSz = Sizef.Zero; if (mouseImage != null) { mouseSz = mouseImage.GetRenderedSize(); } var tmpPos = new Lunatics.Mathematics.Vector2(mousePos.X + mouseSz.Width, mousePos.Y + mouseSz.Height); tipRect.Position = tmpPos; // if tooltip would be off the right of the screen, // reposition to the other side of the mouse cursor. if (screen.Right < tipRect.Right) { tmpPos.X = mousePos.X - tipRect.Width - 5; } // if tooltip would be off the bottom of the screen, // reposition to the other side of the mouse cursor. if (screen.Bottom < tipRect.Bottom) { tmpPos.Y = mousePos.Y - tipRect.Height - 5; } // set final position of tooltip window. SetPosition(new UVector2(UDim.Absolute(tmpPos.X), UDim.Absolute(tmpPos.Y))); _inPositionSelf = false; }
public HotbarPanel() : base("PanelAlt1", false) { Size = new USize(UDim.Relative(0.2f), UDim.Absolute(41f)); Position = new UVector2(UDim.Relative(0.4f), new UDim(1f, -41f)); InterestedKeys.Add(Keys.D1); InterestedKeys.Add(Keys.D2); InterestedKeys.Add(Keys.D3); InterestedKeys.Add(Keys.D4); InterestedKeys.Add(Keys.D5); InterestedKeys.Add(Keys.D6); InterestedKeys.Add(Keys.D7); InterestedKeys.Add(Keys.D8); InterestedKeys.Add(Keys.D9); InterestedKeys.Add(Keys.D0); SelectedIndex = 1; }
/// <summary> /// Immediately pick up the DragContainer and optionally set the sticky /// mode in order to allow this to happen. Any current interaction /// (i.e. mouse capture) will be interrupted. /// </summary> /// <param name="forceSticky"> /// - true to automatically enable the sticky mode in order to facilitate picking up the DragContainer. /// - false to ignore the pick up request if the sticky mode is not alraedy enabled (default). /// </param> /// <returns> /// - true if the DragContainer was successfully picked up. /// - false if the DragContainer was not picked up. /// </returns> public bool PickUp(bool forceSticky = false) { // check if we're already picked up or if dragging is disabled. if (_pickedUp || !_draggingEnabled) { return(true); } // see if we need to force sticky mode switch if (!_stickyMode && forceSticky) { SetStickyModeEnabled(true); } // can only pick up if sticky if (_stickyMode) { // force immediate release of any current input capture (unless it's us) if (GetCaptureWindow() != null && GetCaptureWindow() != this) { GetCaptureWindow().ReleaseInput(); } // activate ourselves and try to capture input Activate(); if (CaptureInput()) { // set the dragging point to the centre of the container. _dragPoint.d_x = UDim.Absolute(d_pixelSize.Width / 2); _dragPoint.d_y = UDim.Absolute(d_pixelSize.Height / 2); // initialise the dragging state InitialiseDragging(); // get position of mouse as co-ordinates local to this window. var localMousePos = CoordConverter.ScreenToWindow(this, GetGUIContext().GetCursor().GetPosition()); DoDragging(localMousePos); _pickedUp = true; } } return(_pickedUp); }
private void ReinitializeSlots() { var basePosition = new UVector2(UDim.Absolute(3f)); Children.Clear(); for (int i = 0; i < HotbarSlots; i++) { Add(new ImageElement("InventorySlot") { Position = basePosition + new UVector2(UDim.Absolute(i * 38f), UDim.Zero) }); if (i == 0) { Add(new ImageElement("ShovelIcon") { Position = basePosition + new UVector2(UDim.Absolute(i * 38f + 2f), UDim.Absolute(1f)) }); } var text = (i + 1).ToString(); if (i + 1 == 10) { text = "0"; } Add(new TextElement() { Text = text, Position = basePosition + new UVector2(UDim.Absolute(i * 38f + 3f), UDim.Absolute(1f)), Color = (i == 0) ? Color.Yellow : Color.White }); } foreach (var child in Children) { child.LoadContent(_contentManager); } _slotsInitialized = HotbarSlots; }
/// <summary> /// Constructor for MenuItem objects /// </summary> /// <param name="type"></param> /// <param name="name"></param> public MenuItem(string type, string name) : base(type, name) { _pushed = false; _hovering = false; _opened = false; _popupClosing = false; _popupOpening = false; _autoPopupTimeout = 0.0f; _autoPopupTimeElapsed = 0.0f; _popup = null; // menuitems dont want multi-click events SetWantsMultiClickEvents(false); // add the new properties AddMenuItemProperties(); _popupOffset.d_x = UDim.Absolute(0); _popupOffset.d_y = UDim.Absolute(0); }
protected internal override void OnCursorPressHold(CursorInputEventArgs e) { base.OnCursorPressHold(e); if (e.Source == CursorInputSource.Left) { // ensure all inputs come to us for now if (CaptureInput()) { // get position of mouse as co-ordinates local to this window. var localPos = CoordConverter.ScreenToWindow(this, e.Position); // store drag point for possible sizing or moving operation. _dragPoint.d_x = UDim.Absolute(localPos.X); _dragPoint.d_y = UDim.Absolute(localPos.Y); _leftPointerHeld = true; } ++e.handled; } }