public void OpenContextMenu(IEntity entity, ScreenCoordinates screenCoordinates) { if (_currentPopup != null) { _closeContextMenu(); } _currentEntity = entity.Uid; _currentPopup = new Popup(); _currentPopup.UserInterfaceManager.StateRoot.AddChild(_currentPopup); _currentPopup.OnPopupHide += _closeContextMenu; var vBox = new VBoxContainer("ButtonBox"); _currentPopup.AddChild(vBox); vBox.AddChild(new Label { Text = "Waiting on Server..." }); RaiseNetworkEvent(new VerbSystemMessages.RequestVerbsMessage(_currentEntity)); var size = vBox.CombinedMinimumSize; var box = UIBox2.FromDimensions(screenCoordinates.Position, size); _currentPopup.Open(box); }
protected override void Draw(DrawingHandleScreen handle) { foreach (var layer in _parallaxManager.ParallaxLayers) { var tex = layer.Texture; var texSize = tex.Size * layer.Config.Scale.Floored(); var ourSize = PixelSize; if (layer.Config.Tiled) { // Multiply offset by slowness to match normal parallax var scaledOffset = (Offset * layer.Config.Slowness).Floored(); // Then modulo the scaled offset by the size to prevent drawing a bunch of offscreen tiles for really small images. scaledOffset.X %= texSize.X; scaledOffset.Y %= texSize.Y; // Note: scaledOffset must never be below 0 or there will be visual issues. // It could be allowed to be >= texSize on a given axis but that would be wasteful. for (var x = -scaledOffset.X; x < ourSize.X; x += texSize.X) { for (var y = -scaledOffset.Y; y < ourSize.Y; y += texSize.Y) { handle.DrawTextureRect(tex, UIBox2.FromDimensions((x, y), texSize)); } } } else { var origin = ((ourSize - texSize) / 2) + layer.Config.ControlHomePosition; handle.DrawTextureRect(tex, UIBox2.FromDimensions(origin, texSize)); } } }
private void _drawItem( DrawingHandleScreen handle, ref float vOffset, float hOffset, Item item, Font font, StyleBox itemSelected) { var itemHeight = font.GetHeight(UIScale) + itemSelected.MinimumSize.Y; var selected = item.Index == _selectedIndex; if (selected) { itemSelected.Draw(handle, UIBox2.FromDimensions(hOffset, vOffset, PixelWidth - hOffset, itemHeight)); } if (!string.IsNullOrWhiteSpace(item.Text)) { var offset = itemSelected.GetContentOffset(Vector2.Zero); var baseLine = offset + (hOffset, vOffset + font.GetAscent(UIScale)); foreach (var chr in item.Text) { baseLine += (font.DrawChar(handle, chr, baseLine, UIScale, Color.White), 0); } } vOffset += itemHeight; hOffset += 5; foreach (var child in item.Children) { _drawItem(handle, ref vOffset, hOffset, child, font, itemSelected); } }
protected override void Open() { _menu = new UplinkMenu(_prototypeManager); _menu.OpenCentered(); _menu.OnClose += Close; _menu.OnListingButtonPressed += (_, listing) => { if (_menu.CurrentLoggedInAccount?.DataBalance < listing.Price) { _failPopup = new UplinkMenuPopup(Loc.GetString("uplink-bound-user-interface-insufficient-funds-popup")); _userInterfaceManager.ModalRoot.AddChild(_failPopup); _failPopup.Open(UIBox2.FromDimensions(_menu.Position.X + 150, _menu.Position.Y + 60, 156, 24)); _menu.OnClose += () => { _failPopup.Dispose(); }; } SendMessage(new UplinkBuyListingMessage(listing.ItemId)); }; _menu.OnCategoryButtonPressed += (_, category) => { _menu.CurrentFilterCategory = category; SendMessage(new UplinkRequestUpdateInterfaceMessage()); }; }
private void _onPressed(ButtonEventArgs args) { var globalPos = GlobalPosition; var(minX, minY) = _popupVBox.CombinedMinimumSize; var box = UIBox2.FromDimensions(globalPos, (Math.Max(minX, Width), minY)); _popup.Open(box); }
protected override void Draw(DrawingHandleScreen handle) { var dims = Texture != null?GetDrawDimensions(Texture) : UIBox2.FromDimensions(Vector2.Zero, PixelSize); dims.Top = Math.Max(dims.Bottom - dims.Bottom * Progress, 0); handle.DrawRect(dims, DoAfterHelpers.GetProgressColor(Progress)); base.Draw(handle); }
protected override void SortChildren() { foreach (var child in Children) { var childSize = child.CombinedMinimumSize; var childPos = (Size - childSize) / 2; FitChildInBox(child, UIBox2.FromDimensions(childPos, childSize)); } }
protected override Vector2 ArrangeOverride(Vector2 finalSize) { var contentBox = ActualStyleBox.GetContentBox(UIBox2.FromDimensions(Vector2.Zero, finalSize * UIScale)); foreach (var child in Children) { child.ArrangePixel((UIBox2i)contentBox); } return(finalSize); }
protected override Vector2 ArrangeOverride(Vector2 finalSize) { var box = GetMargin().Deflate(UIBox2.FromDimensions(Vector2.Zero, finalSize)); foreach (var child in Children) { child.Arrange(box); } return(finalSize); }
protected override void Open() { base.Open(); SendMessage(new PDARequestUpdateInterfaceMessage()); _menu = new PDAMenu(this, _prototypeManager); _menu.OpenToLeft(); _menu.OnClose += Close; _menu.FlashLightToggleButton.OnToggled += args => { SendMessage(new PDAToggleFlashlightMessage()); }; _menu.EjectIDButton.OnPressed += args => { SendMessage(new PDAEjectIDMessage()); }; _menu.EjectPenButton.OnPressed += args => { SendMessage(new PDAEjectPenMessage()); }; _menu.MasterTabContainer.OnTabChanged += i => { var tab = _menu.MasterTabContainer.GetChild(i); if (tab == _menu.UplinkTabContainer) { SendMessage(new PDARequestUpdateInterfaceMessage()); } }; _menu.OnListingButtonPressed += (args, listing) => { if (_menu.CurrentLoggedInAccount.DataBalance < listing.Price) { _failPopup = new PDAMenuPopup(Loc.GetString("Insufficient funds!")); _userInterfaceManager.ModalRoot.AddChild(_failPopup); _failPopup.Open(UIBox2.FromDimensions(_menu.Position.X + 150, _menu.Position.Y + 60, 156, 24)); _menu.OnClose += () => { _failPopup.Dispose(); }; } SendMessage(new PDAUplinkBuyListingMessage(listing.ItemId)); }; _menu.OnCategoryButtonPressed += (args, category) => { _menu.CurrentFilterCategory = category; SendMessage(new PDARequestUpdateInterfaceMessage()); }; }
protected override Vector2 ArrangeOverride(Vector2 finalSize) { foreach (var child in Children) { var size = child.DesiredSize; var offset = child.GetValue <Vector2>(PopupOriginProperty); var altPos = child.GetValue <Vector2?>(AltOriginProperty); var(r, b) = size + offset; // bottom right corner. var isAltPos = false; // Clamp the right edge. if (r > Width) { // Try to position at alt pos. if (altPos != null && altPos.Value.X - size.X > 0) { // There is horizontal room at the alt pos so there we go. isAltPos = true; offset = (altPos.Value.X - size.X, altPos.Value.Y); (_, b) = size + offset; } else { offset -= (r - Width, 0); } } // Clamp the bottom edge. if (b > Height) { offset -= (0, b - Height); } // Try to clamp the left edge. if (offset.X < 0 && !isAltPos) { offset -= (offset.X, 0); } // Try to clamp the top edge. if (offset.Y < 0) { offset -= (0, offset.Y); } child.Arrange(UIBox2.FromDimensions(offset, size)); } return(finalSize); }
protected override Vector2 ArrangeOverride(Vector2 finalSize) { var pixelSize = finalSize * UIScale; var ourSize = UIBox2.FromDimensions(Vector2.Zero, pixelSize); var contentBox = _getStyleBox()?.GetContentBox(ourSize) ?? ourSize; foreach (var child in Children) { child.ArrangePixel((UIBox2i)contentBox); } return(finalSize); }
protected override void Draw(DrawingHandleBase handle) { var screenHandle = (DrawingHandleScreen)handle; var mousePos = IoCManager.Resolve <IInputManager>().MouseScreenPosition; if (_system.UseOrAttackIsDown && _system._timeHeld > AttackTimeThreshold) { var tex = ResC.GetTexture($"/Textures/Objects/Tools/toolbox_r.png"); screenHandle.DrawTextureRect(tex, UIBox2.FromDimensions(mousePos, tex.Size * 2)); } }
protected override void LayoutUpdateOverride() { var top = MarginTopOverride ?? 0; var bottom = MarginBottomOverride ?? 0; var left = MarginLeftOverride ?? 0; var right = MarginRightOverride ?? 0; var box = UIBox2.FromDimensions(left, top, Width - right - left, Height - bottom - top); foreach (var child in Children) { FitChildInBox(child, box); } }
public void Test() { var container = new CenterContainer(); var child = new Control { MinSize = (50, 50) }; container.AddChild(child); container.Arrange(UIBox2.FromDimensions(0, 0, 100, 100)); Assert.That(container.DesiredSize, Is.EqualTo(new Vector2(50, 50))); Assert.That(child.Position, Is.EqualTo(new Vector2(25, 25))); Assert.That(child.Size, Is.EqualTo(new Vector2(50, 50))); }
protected override Vector2 ArrangeOverride(Vector2 finalSize) { var max = Vector2.Zero; foreach (var child in Children) { var childSize = child.DesiredSize; var childPos = (finalSize - childSize) / 2; child.Arrange(UIBox2.FromDimensions(childPos, childSize)); max = Vector2.ComponentMax(max, childSize); } return(max); }
private void OpenPopupFor(MenuBarTopButton button) { _popupVBox.RemoveAllChildren(); var menu = button.Menu; ConstructMenu(menu, _popupVBox); var globalPos = button.GlobalPosition; globalPos += new Vector2(0, button.Height); _popup.Open(UIBox2.FromDimensions(globalPos, _popupVBox.Size)); // Set this after running open so that if this is called from MouseEntered, // It won't get set to false by Open() closing the popup to move it. _popupOpen = true; }
public void OpenContextMenu(IEntity entity, ScreenCoordinates screenCoordinates) { if (_currentVerbListRoot != null) { CloseVerbMenu(); } _currentEntity = entity.Uid; _currentVerbListRoot = new VerbPopup(); _userInterfaceManager.ModalRoot.AddChild(_currentVerbListRoot); _currentVerbListRoot.OnPopupHide += CloseVerbMenu; _currentVerbListRoot.List.AddChild(new Label {Text = "Waiting on Server..."}); RaiseNetworkEvent(new VerbSystemMessages.RequestVerbsMessage(_currentEntity)); var box = UIBox2.FromDimensions(screenCoordinates.Position, (1, 1)); _currentVerbListRoot.Open(box); }
private static UIBox2 CalcChildRect(Vector2 ourSize, float uiScale, Control child, out UIBox2 anchorSize) { // Calculate where the control "wants" to be by its anchors/margins. var growHorizontal = child.GetValue <GrowDirection>(GrowHorizontalProperty); var growVertical = child.GetValue <GrowDirection>(GrowVerticalProperty); anchorSize = CalcAnchorMargins(ourSize, uiScale, child); // This intentionally results in negatives if the right bound is < the left bound. // Which then causes HandleLayoutOverflow to CORRECTLY work from the right bound instead. var(wSizeX, wSizeY) = (anchorSize.Right - anchorSize.Left, anchorSize.Bottom - anchorSize.Top); var(minSizeX, minSizeY) = child.DesiredPixelSize; HandleLayoutOverflow(growHorizontal, minSizeX, anchorSize.Left, wSizeX, out var posX, out var sizeX); HandleLayoutOverflow(growVertical, minSizeY, anchorSize.Top, wSizeY, out var posY, out var sizeY); return(UIBox2.FromDimensions(posX / uiScale, posY / uiScale, sizeX / uiScale, sizeY / uiScale)); }
private void _genTextureAtlas() { var defList = TileDefs.Where(t => !string.IsNullOrEmpty(t.SpriteName)).ToList(); const int tileSize = EyeManager.PIXELSPERMETER; var dimensionX = (int)Math.Ceiling(Math.Sqrt(defList.Count)); var dimensionY = (int)Math.Ceiling((float)defList.Count / dimensionX); var sheet = new Image <Rgba32>(dimensionX * tileSize, dimensionY * tileSize); for (var i = 0; i < defList.Count; i++) { var def = defList[i]; var column = i % dimensionX; var row = i / dimensionX; Image <Rgba32> image; using (var stream = _resourceCache.ContentFileRead($"/Textures/Tiles/{def.SpriteName}.png")) { image = Image.Load(stream); } if (image.Width != tileSize || image.Height != tileSize) { throw new NotImplementedException("Unable to use tiles with a dimension other than 32x32."); } var point = new Point(column * tileSize, row * tileSize); sheet.Mutate(x => x.DrawImage(image, point, PixelColorBlendingMode.Overlay, 1)); _tileRegions.Add(def.TileId, UIBox2.FromDimensions( point.X / (float)sheet.Width, point.Y / (float)sheet.Height, tileSize / (float)sheet.Width, tileSize / (float)sheet.Height)); } TileTextureAtlas = Texture.LoadFromImage(sheet, "Tile Atlas"); }
protected override void LayoutUpdateOverride() { foreach (var child in Children) { var size = child.CombinedMinimumSize; var offset = child.GetValue <Vector2>(PopupOriginProperty); var(r, b) = size + offset; // bottom right corner. // Clamp the right edge. if (r > Width) { offset -= (r - Width, 0); } // Clamp the bottom edge. if (b > Height) { offset -= (0, b - Height); } // Try to clamp the left edge. if (offset.X < 0) { offset -= (offset.X, 0); } // Try to clamp the top edge. if (offset.Y < 0) { offset -= (0, offset.Y); } FitChildInBox(child, UIBox2.FromDimensions(offset, size)); } }
public async void DoExamine(IEntity entity) { const float minWidth = 300; CloseTooltip(); var popupPos = _userInterfaceManager.MousePositionScaled; // Actually open the tooltip. _examineTooltipOpen = new Popup(); _userInterfaceManager.ModalRoot.AddChild(_examineTooltipOpen); var panel = new PanelContainer(); panel.AddStyleClass(StyleClassEntityTooltip); panel.ModulateSelfOverride = Color.LightGray.WithAlpha(0.90f); _examineTooltipOpen.AddChild(panel); //panel.SetAnchorAndMarginPreset(Control.LayoutPreset.Wide); var vBox = new VBoxContainer(); panel.AddChild(vBox); var hBox = new HBoxContainer { SeparationOverride = 5 }; vBox.AddChild(hBox); if (entity.TryGetComponent(out ISpriteComponent sprite)) { hBox.AddChild(new SpriteView { Sprite = sprite }); } hBox.AddChild(new Label { Text = entity.Name, HorizontalExpand = true, }); panel.Measure(Vector2.Infinity); var size = Vector2.ComponentMax((minWidth, 0), panel.DesiredSize); _examineTooltipOpen.Open(UIBox2.FromDimensions(popupPos, size)); FormattedMessage message; if (entity.Uid.IsClientSide()) { message = GetExamineText(entity, _playerManager.LocalPlayer.ControlledEntity); } else { // Ask server for extra examine info. RaiseNetworkEvent(new ExamineSystemMessages.RequestExamineInfoMessage(entity.Uid)); ExamineSystemMessages.ExamineInfoResponseMessage response; try { _requestCancelTokenSource = new CancellationTokenSource(); response = await AwaitNetworkEvent <ExamineSystemMessages.ExamineInfoResponseMessage>(_requestCancelTokenSource .Token); } catch (TaskCanceledException) { return; } finally { _requestCancelTokenSource = null; } message = response.Message; } foreach (var msg in message.Tags.OfType <FormattedMessage.TagText>()) { if (!string.IsNullOrWhiteSpace(msg.Text)) { var richLabel = new RichTextLabel(); richLabel.SetMessage(message); vBox.AddChild(richLabel); break; } } }
public async void DoExamine(IEntity entity) { CloseTooltip(); var popupPos = _inputManager.MouseScreenPosition; // Actually open the tooltip. _examineTooltipOpen = new Popup(); _userInterfaceManager.StateRoot.AddChild(_examineTooltipOpen); var panel = new PanelContainer(); panel.AddStyleClass(StyleClassEntityTooltip); panel.ModulateSelfOverride = Color.LightGray.WithAlpha(0.90f); _examineTooltipOpen.AddChild(panel); //panel.SetAnchorAndMarginPreset(Control.LayoutPreset.Wide); var vBox = new VBoxContainer(); panel.AddChild(vBox); var hBox = new HBoxContainer { SeparationOverride = 5 }; vBox.AddChild(hBox); if (entity.TryGetComponent(out ISpriteComponent sprite)) { hBox.AddChild(new SpriteView { Sprite = sprite }); } hBox.AddChild(new Label { Text = entity.Name, SizeFlagsHorizontal = Control.SizeFlags.FillExpand, }); const float minWidth = 300; var size = Vector2.ComponentMax((minWidth, 0), panel.CombinedMinimumSize); popupPos += Vector2.ComponentMin(Vector2.Zero, _userInterfaceManager.StateRoot.Size - (size + popupPos)); _examineTooltipOpen.Open(UIBox2.FromDimensions(popupPos, size)); if (entity.Uid.IsClientSide()) { return; } // Ask server for extra examine info. RaiseNetworkEvent(new ExamineSystemMessages.RequestExamineInfoMessage(entity.Uid)); ExamineSystemMessages.ExamineInfoResponseMessage response; try { _requestCancelTokenSource = new CancellationTokenSource(); response = await AwaitNetMessage <ExamineSystemMessages.ExamineInfoResponseMessage>(_requestCancelTokenSource .Token); } catch (TaskCanceledException) { return; } finally { _requestCancelTokenSource = null; } foreach (var msg in response.Message.Tags.OfType <FormattedMessage.TagText>()) { if (!string.IsNullOrWhiteSpace(msg.Text)) { var richLabel = new RichTextLabel(); richLabel.SetMessage(response.Message); vBox.AddChild(richLabel); break; } } //_examineTooltipOpen.Position += Vector2.ComponentMin(Vector2.Zero,_userInterfaceManager.StateRoot.Size - (panel.Size + _examineTooltipOpen.Position)); }
protected override Vector2 ArrangeOverride(Vector2 finalSize) { var separation = (int)(ActualSeparation * UIScale); #region Scroll var cHeight = _totalHeight; var vBarSize = _vScrollBar.DesiredSize.X; var(sWidth, sHeight) = finalSize; try { // Suppress events to avoid weird recursion. _suppressScrollValueChanged = true; if (sHeight < cHeight) { sWidth -= vBarSize; } if (sHeight < cHeight) { _vScrollBar.Visible = true; _vScrollBar.Page = sHeight; _vScrollBar.MaxValue = cHeight; } else { _vScrollBar.Visible = false; } } finally { _suppressScrollValueChanged = false; } if (_vScrollBar.Visible) { _vScrollBar.Arrange(UIBox2.FromDimensions(Vector2.Zero, finalSize)); } #endregion #region Rebuild Children /* * Example: * * var _itemHeight = 32; * var separation = 3; * 32 | 32 | Control.Size.Y 0 * 35 | 3 | Padding * 67 | 32 | Control.Size.Y 1 * 70 | 3 | Padding * 102 | 32 | Control.Size.Y 2 * 105 | 3 | Padding * 137 | 32 | Control.Size.Y 3 * * If viewport height is 60 * visible should be 2 items (start = 0, end = 1) * * scroll.Y = 11 * visible should be 3 items (start = 0, end = 2) * * start expected: 11 (item: 0) * var start = (int) (scroll.Y * * if (scroll == 32) then { start = 1 } * var start = (int) (scroll.Y + separation / (_itemHeight + separation)); * var start = (int) (32 + 3 / (32 + 3)); * var start = (int) (35 / 35); * var start = (int) (1); * * scroll = 0, height = 36 * if (scroll + height == 36) then { end = 2 } * var end = (int) Math.Ceiling(scroll.Y + height / (_itemHeight + separation)); * var end = (int) Math.Ceiling(0 + 36 / (32 + 3)); * var end = (int) Math.Ceiling(36 / 35); * var end = (int) Math.Ceiling(1.02857); * var end = (int) 2; * */ var scroll = GetScrollValue(); var oldTopIndex = _topIndex; _topIndex = (int)((scroll.Y + separation) / (_itemHeight + separation)); if (_topIndex != oldTopIndex) { _updateChildren = true; } var oldBottomIndex = _bottomIndex; _bottomIndex = (int)Math.Ceiling((scroll.Y + Height) / (_itemHeight + separation)); _bottomIndex = Math.Min(_bottomIndex, _count); if (_bottomIndex != oldBottomIndex) { _updateChildren = true; } // When scrolling only rebuild visible list when a new item should be visible if (_updateChildren) { _updateChildren = false; foreach (var child in Children.ToArray()) { if (child == _vScrollBar) { continue; } RemoveChild(child); } if (_entityUids != null) { for (var i = _topIndex; i < _bottomIndex; i++) { var entity = _entityUids[i]; var button = new EntityContainerButton(entity); button.OnPressed += OnItemPressed; GenerateItem?.Invoke(entity, button); AddChild(button); } } _vScrollBar.SetPositionLast(); } #endregion #region Layout Children // Use pixel position var pixelWidth = (int)(sWidth * UIScale); var offset = (int)-((scroll.Y - _topIndex * (_itemHeight + separation)) * UIScale); var first = true; foreach (var child in Children) { if (child == _vScrollBar) { continue; } if (!first) { offset += separation; } first = false; var size = child.DesiredPixelSize.Y; var targetBox = new UIBox2i(0, offset, pixelWidth, offset + size); child.ArrangePixel(targetBox); offset += size; } #endregion return(finalSize); }
public override void Load(IResourceCache cache, ResourcePath path) { var manifestPath = path / "meta.json"; string manifestContents; using (var manifestFile = cache.ContentFileRead(manifestPath)) using (var reader = new StreamReader(manifestFile)) { manifestContents = reader.ReadToEnd(); } #if DEBUG if (RSISchema != null) { var errors = RSISchema.Validate(manifestContents); if (errors.Count != 0) { Logger.Error($"Unable to load RSI from '{path}', {errors.Count} errors:"); foreach (var error in errors) { Logger.Error("{0}", error.ToString()); } throw new RSILoadException($"{errors.Count} errors while loading RSI. See console."); } } #endif // Ok schema validated just fine. var manifestJson = JObject.Parse(manifestContents); var toAtlas = new List <(Image <Rgba32> src, Texture[][] output, int[][] indices, int totalFrameCount)>(); var metaData = ParseMetaData(manifestJson); var frameSize = metaData.Size; var rsi = new RSI(frameSize); // Do every state. foreach (var stateObject in metaData.States) { // Load image from disk. var texPath = path / (stateObject.StateId + ".png"); var image = Image.Load(cache.ContentFileRead(texPath)); var sheetSize = new Vector2i(image.Width, image.Height); if (sheetSize.X % frameSize.X != 0 || sheetSize.Y % frameSize.Y != 0) { throw new RSILoadException("State image size is not a multiple of the icon size."); } // Load all frames into a list so we can operate on it more sanely. var frameCount = stateObject.Delays.Sum(delayList => delayList.Length); var(foldedDelays, foldedIndices) = FoldDelays(stateObject.Delays); var textures = new Texture[foldedIndices.Length][]; for (var i = 0; i < textures.Length; i++) { textures[i] = new Texture[foldedIndices[0].Length]; } var state = new RSI.State(frameSize, stateObject.StateId, stateObject.DirType, foldedDelays, textures); rsi.AddState(state); toAtlas.Add((image, textures, foldedIndices, frameCount)); } // Poorly hacked in texture atlas support here. { var totalFrameCount = toAtlas.Sum(p => p.totalFrameCount); // Generate atlas. var dimensionX = (int)MathF.Ceiling(MathF.Sqrt(totalFrameCount)); var dimensionY = (int)MathF.Ceiling((float)totalFrameCount / dimensionX); using var sheet = new Image <Rgba32>(dimensionX * frameSize.X, dimensionY * frameSize.Y); var sheetIndex = 0; foreach (var(src, _, _, frameCount) in toAtlas) { // Blit all the frames over. for (var i = 0; i < frameCount; i++) { var srcWidth = (src.Width / frameSize.X); var srcColumn = i % srcWidth; var srcRow = i / srcWidth; var srcPos = (srcColumn * frameSize.X, srcRow *frameSize.Y); var sheetColumn = (sheetIndex + i) % dimensionX; var sheetRow = (sheetIndex + i) / dimensionX; var sheetPos = (sheetColumn * frameSize.X, sheetRow *frameSize.Y); var srcBox = UIBox2i.FromDimensions(srcPos, frameSize); src.Blit(srcBox, sheet, sheetPos); } sheetIndex += frameCount; } // Load atlas. var texture = Texture.LoadFromImage(sheet, path.ToString()); var sheetOffset = 0; foreach (var(src, output, indices, frameCount) in toAtlas) { for (var i = 0; i < indices.Length; i++) { var dirIndices = indices[i]; var dirOutput = output[i]; for (var j = 0; j < dirIndices.Length; j++) { var index = sheetOffset + dirIndices[j]; var sheetColumn = index % dimensionX; var sheetRow = index / dimensionX; var sheetPos = (sheetColumn * frameSize.X, sheetRow *frameSize.Y); dirOutput[j] = new AtlasTexture(texture, UIBox2.FromDimensions(sheetPos, frameSize)); } } sheetOffset += frameCount; } } foreach (var(image, _, _, _) in toAtlas) { image.Dispose(); } RSI = rsi; }
public void DrawTexture(Texture texture, Vector2 position, Color?modulate = null) { CheckDisposed(); DrawTextureRect(texture, UIBox2.FromDimensions(position, texture.Size), modulate); }
protected internal override void Draw(DrawingHandleScreen handle) { base.Draw(handle); var font = ActualFont; var listBg = ActualBackground; var iconBg = ActualItemBackground; var iconSelectedBg = ActualSelectedItemBackground; var iconDisabledBg = ActualDisabledItemBackground; var offset = -_scrollBar.Value; listBg.Draw(handle, PixelSizeBox); foreach (var item in _itemList) { var bg = iconBg; if (item.Disabled) { bg = iconDisabledBg; } if (item.Selected) { bg = iconSelectedBg; } var itemHeight = 0f; if (item.Icon != null) { itemHeight = item.IconSize.Y; } itemHeight = Math.Max(itemHeight, ActualFont.GetHeight(UIScale)); itemHeight += ActualItemBackground.MinimumSize.Y; item.Region = UIBox2.FromDimensions(0, offset, PixelWidth, itemHeight); bg.Draw(handle, item.Region.Value); var contentBox = bg.GetContentBox(item.Region.Value); var drawOffset = contentBox.TopLeft; if (item.Icon != null) { if (item.IconRegion.Size == Vector2.Zero) { handle.DrawTextureRect(item.Icon, UIBox2.FromDimensions(drawOffset, item.Icon.Size), false, item.IconModulate, item.IconTranspose); } else { handle.DrawTextureRectRegion(item.Icon, UIBox2.FromDimensions(drawOffset, item.Icon.Size), item.IconRegion, item.IconModulate); } } if (item.Text != null) { var textBox = new UIBox2(contentBox.Left + item.IconSize.X, contentBox.Top, contentBox.Right, contentBox.Bottom); DrawTextInternal(handle, item.Text, textBox); } offset += itemHeight; } }
/// <summary> /// Gets the draw box, positioned at <paramref name="position"/>, /// that envelops a box with the given dimensions perfectly given this box's content margins. /// </summary> /// <remarks> /// It's basically a reverse <see cref="GetContentBox"/>. /// </remarks> /// <param name="position">The position at which the new box should be drawn.</param> /// <param name="dimensions">The dimensions of the content box inside this new box.</param> /// <returns> /// A box that, when ran through <see cref="GetContentBox"/>, /// has a content box of size <paramref name="dimensions"/> /// </returns> public UIBox2 GetEnvelopBox(Vector2 position, Vector2 dimensions) { return(UIBox2.FromDimensions(position, dimensions + MinimumSize)); }
private Item _tryFindItemAtPosition(Vector2 position) { var font = _getFont(); if (font == null || _root == null) { return(null); } var background = _getBackground(); if (background != null) { position -= background.GetContentOffset(Vector2.Zero); } var vOffset = -_scrollBar.Value; Item final = null; bool DoSearch(Item item, float hOffset) { var itemHeight = font.GetHeight(UIScale); var itemBox = UIBox2.FromDimensions(new Vector2(hOffset, vOffset), new Vector2(PixelWidth - hOffset, itemHeight)); if (itemBox.Contains(position)) { final = item; return(true); } vOffset += itemHeight; hOffset += 5; foreach (var child in item.Children) { if (DoSearch(child, hOffset)) { return(true); } } return(false); } if (HideRoot) { foreach (var child in _root.Children) { if (DoSearch(child, 0)) { break; } } } else { DoSearch(_root, 0); } return(final); }