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));
            }
        }
    }
Пример #3
0
        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());
            };
        }
Пример #5
0
        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);
        }
Пример #6
0
        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);
        }
Пример #7
0
        protected override void SortChildren()
        {
            foreach (var child in Children)
            {
                var childSize = child.CombinedMinimumSize;
                var childPos  = (Size - childSize) / 2;

                FitChildInBox(child, UIBox2.FromDimensions(childPos, childSize));
            }
        }
Пример #8
0
        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);
        }
Пример #9
0
        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);
        }
Пример #10
0
        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());
            };
        }
Пример #11
0
        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);
        }
Пример #12
0
        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));
                }
            }
Пример #14
0
        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);
            }
        }
Пример #15
0
        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)));
        }
Пример #16
0
        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);
        }
Пример #17
0
        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;
        }
Пример #18
0
        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);
        }
Пример #19
0
        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");
        }
Пример #21
0
        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));
            }
        }
Пример #22
0
        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;
                }
            }
        }
Пример #23
0
        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);
        }
Пример #25
0
        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;
        }
Пример #26
0
        public void DrawTexture(Texture texture, Vector2 position, Color?modulate = null)
        {
            CheckDisposed();

            DrawTextureRect(texture, UIBox2.FromDimensions(position, texture.Size), modulate);
        }
Пример #27
0
        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;
            }
        }
Пример #28
0
 /// <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));
 }
Пример #29
0
        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);
        }