-
-
Notifications
You must be signed in to change notification settings - Fork 62
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Panel Scrollbar Update (clean) #749
base: dev
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -124,6 +124,60 @@ | |
set => SetProperty(ref _autoSizePadding, value); | ||
} | ||
|
||
protected Scrollbar _panelScrollbar; | ||
|
||
protected Vector2 _scrollPadding = new Vector2(4, 0); | ||
/// <summary> | ||
/// Padding on the left side of the <see cref="Scrollbar"/>. | ||
/// </summary> | ||
public Vector2 ScrollPadding { | ||
get => _scrollPadding; | ||
set => SetProperty(ref _scrollPadding, value, true); | ||
} | ||
Comment on lines
+129
to
+136
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What is ScrollPadding for? I don't see it referenced anywhere else except in the ScrollbarWidth (and that appears to only use the X). |
||
|
||
/// <summary> | ||
/// Indicates whether or not there is a <see cref="Scrollbar"/> drawn inside the <see cref="Panel"/>. | ||
/// </summary> | ||
public bool ScrollbarVisible { | ||
//get => _panelScrollbar != null && _panelScrollbar.Drawn; | ||
//get => _panelScrollbar != null; | ||
Comment on lines
+142
to
+143
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Needs cleaned up. |
||
get => _scrollbarVisible; | ||
protected set => SetProperty(ref _scrollbarVisible, value, true); | ||
} | ||
protected bool _scrollbarVisible = false; | ||
|
||
/// <summary> | ||
/// Space which is taken from the <see cref="Scrollbar"/> to be drawn inside the <see cref="Panel"/>. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This isn't a panel. This is a container. |
||
/// </summary> | ||
public int ScrollbarWidth { | ||
get => _panelScrollbar != null ? (_panelScrollbar.ScrollbarWidth + (int) ScrollPadding.X) : 0; | ||
} | ||
|
||
protected Point _maxSize = Point.Zero; | ||
/// <summary> | ||
/// Maximum Size the <see cref="Container"/> can autoresize to. | ||
/// </summary> | ||
public Point MaxSize { | ||
get => _maxSize; | ||
protected set => SetProperty(ref _maxSize, value, true); | ||
} | ||
|
||
/// <summary> | ||
/// Maximum Width the <see cref="Container"/> can autoresize to. | ||
/// </summary> | ||
public int MaxWidth { | ||
get => _maxSize.X; | ||
protected set => SetProperty(ref _maxSize.X, value, true); | ||
} | ||
|
||
/// <summary> | ||
/// Maximum Height the <see cref="Container"/> can autoresize to. | ||
/// </summary> | ||
public int MaxHeight{ | ||
get => _maxSize.Y; | ||
protected set => SetProperty(ref _maxSize.Y, value, true); | ||
} | ||
Comment on lines
+156
to
+179
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
|
||
protected override CaptureType CapturesInput() => CaptureType.Mouse | CaptureType.MouseWheel; | ||
|
||
/// <summary> | ||
|
@@ -162,6 +216,7 @@ | |
/// </summary> | ||
public bool AddChild(Control child) { | ||
if (_children.Contains(child)) return true; | ||
if (_panelScrollbar != null && child == _panelScrollbar) return true; | ||
|
||
var resultingChildren = _children.ToList(); | ||
resultingChildren.Add(child); | ||
|
@@ -253,35 +308,40 @@ | |
} | ||
} | ||
|
||
public sealed override void DoUpdate(GameTime gameTime) { | ||
UpdateContainer(gameTime); | ||
|
||
Control[] children = _children.ToArray(); | ||
var filteredChildren = children.Where(c => c.GetType() != typeof(Scrollbar) && c.Visible).ToArray(); | ||
|
||
_contentBounds = ControlUtil.GetControlBounds(filteredChildren); | ||
|
||
_contentBounds = ControlUtil.GetControlBounds(children); | ||
var limitSize = _maxSize != Point.Zero; | ||
|
||
// Update our size based on the sizing mode | ||
var parent = this.Parent; | ||
if (parent != null) { | ||
if (parent != null) { | ||
this.Size = new Point(GetUpdatedSizing(this.WidthSizingMode, | ||
this.Width, | ||
_contentBounds.X + (this.Width - this.ContentRegion.Width) + _autoSizePadding.X, | ||
parent.ContentRegion.Width - this.Left), | ||
limitSize ? Math.Min(_maxSize.X, this.Width) : this.Width, | ||
limitSize ? Math.Min(_maxSize.X, _contentBounds.X + (this.Width - this.ContentRegion.Width) + _autoSizePadding.X) : _contentBounds.X + (this.Width - this.ContentRegion.Width) + _autoSizePadding.X, | ||
limitSize ? Math.Min(_maxSize.X, parent.ContentRegion.Width - this.Left) : parent.ContentRegion.Width - this.Left), | ||
GetUpdatedSizing(this.HeightSizingMode, | ||
this.Height, | ||
_contentBounds.Y + (this.Height - this.ContentRegion.Height) + _autoSizePadding.Y, | ||
parent.ContentRegion.Height - this.Top)); | ||
limitSize ? Math.Min(_maxSize.Y, this.Height) : this.Height, | ||
limitSize ? Math.Min(_maxSize.Y, _contentBounds.Y + (this.Height - this.ContentRegion.Height) + _autoSizePadding.Y) : _contentBounds.Y + (this.Height - this.ContentRegion.Height) + _autoSizePadding.Y, | ||
limitSize ? Math.Min(_maxSize.Y, parent.ContentRegion.Height - this.Top) : parent.ContentRegion.Height - this.Top)); | ||
|
||
ScrollbarVisible = _contentBounds.Y > this.Height; | ||
} | ||
|
||
// Update our children | ||
foreach (var childControl in children) { | ||
// Update child if it is visible or if it hasn't rendered yet (needs a first time calc) | ||
if (childControl.Visible || childControl.LayoutState != LayoutState.Ready) { | ||
childControl.Update(gameTime); | ||
} | ||
} | ||
} | ||
|
||
protected sealed override void Paint(SpriteBatch spriteBatch, Rectangle bounds) { | ||
var controlScissor = spriteBatch.GraphicsDevice.ScissorRectangle.ScaleBy(1 / Graphics.UIScaleMultiplier); | ||
|
||
|
@@ -303,8 +363,9 @@ | |
public virtual void PaintBeforeChildren(SpriteBatch spriteBatch, Rectangle bounds) { /* NOOP */ } | ||
|
||
protected void PaintChildren(SpriteBatch spriteBatch, Rectangle bounds, Rectangle scissor) { | ||
var contentScissor = Rectangle.Intersect(scissor, ContentRegion.ToBounds(this.AbsoluteBounds)); | ||
|
||
var cR = ContentRegion.ToBounds(this.AbsoluteBounds); | ||
var contentScissor = Rectangle.Intersect(scissor, cR); | ||
Comment on lines
+366
to
+367
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What is this change for? |
||
|
||
var zSortedChildren = _children.ToArray().OrderBy(i => i.ZIndex); | ||
|
||
// Render each visible child | ||
|
@@ -326,6 +387,8 @@ | |
descendant.Dispose(); | ||
} | ||
|
||
_panelScrollbar?.Dispose(); | ||
|
||
base.DisposeControl(); | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -662,6 +662,12 @@ public bool Enabled { | |||||||||||||
set => SetProperty(ref _enabled, value); | ||||||||||||||
} | ||||||||||||||
|
||||||||||||||
/// <summary> | ||||||||||||||
/// The rectangle which will be colored behind the <see cref="Control"/> by BackgroundColor. | ||||||||||||||
/// <br/><br/>Default: <see cref="Rectangle.Empty"/> | ||||||||||||||
/// </summary> | ||||||||||||||
protected Rectangle _backgroundColorBounds; | ||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we perhaps had a misunderstanding about this. Background color should fill the full bounds. We can get rid of this. The tint I was referring to shown here is drawn by the panel control itself and fills the Blish-HUD/Blish HUD/Controls/Panel.cs Lines 313 to 318 in 736ba25
|
||||||||||||||
|
||||||||||||||
protected Color _backgroundColor = Color.Transparent; | ||||||||||||||
/// <summary> | ||||||||||||||
/// The <see cref="Color"/> rendered behind the <see cref="Control"/>. | ||||||||||||||
|
@@ -904,7 +910,7 @@ public virtual void Draw(SpriteBatch spriteBatch, Rectangle drawBounds, Rectangl | |||||||||||||
|
||||||||||||||
// Draw background | ||||||||||||||
if (_backgroundColor != Color.Transparent) | ||||||||||||||
spriteBatch.DrawOnCtrl(this, ContentService.Textures.Pixel, drawBounds, _backgroundColor); | ||||||||||||||
spriteBatch.DrawOnCtrl(this, ContentService.Textures.Pixel, _backgroundColorBounds == Rectangle.Empty ? drawBounds : _backgroundColorBounds, _backgroundColor); | ||||||||||||||
|
||||||||||||||
if (!this.ClipsBounds) { | ||||||||||||||
spriteBatch.GraphicsDevice.ScissorRectangle = Graphics.SpriteScreen.LocalBounds.ScaleBy(Graphics.UIScaleMultiplier); | ||||||||||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -115,7 +115,6 @@ public override SizingMode HeightSizingMode { | |
[JsonIgnore] public float AccentOpacity { get; set; } = 1f; | ||
|
||
private Glide.Tween _collapseAnim; | ||
private Scrollbar _panelScrollbar; | ||
|
||
/// <inheritdoc /> | ||
public bool ToggleAccordionState() { | ||
|
@@ -233,7 +232,7 @@ public override void RecalculateLayout() { | |
int cornerAccentWidth = Math.Min(_size.X, MAX_ACCENT_WIDTH); | ||
_layoutTopLeftAccentBounds = new Rectangle(-2, topOffset - 12, cornerAccentWidth, _textureCornerAccent.Height); | ||
|
||
_layoutBottomRightAccentBounds = new Rectangle(_size.X - cornerAccentWidth + 2, _size.Y - 59, cornerAccentWidth, _textureCornerAccent.Height); | ||
_layoutBottomRightAccentBounds = new Rectangle(_size.X - cornerAccentWidth, _size.Y - 59, cornerAccentWidth, _textureCornerAccent.Height); | ||
|
||
_layoutCornerAccentSrc = new Rectangle(MAX_ACCENT_WIDTH - cornerAccentWidth, 0, cornerAccentWidth, _textureCornerAccent.Height); | ||
|
||
|
@@ -242,34 +241,47 @@ public override void RecalculateLayout() { | |
_layoutLeftAccentSrc = new Rectangle(0, 0, _textureLeftSideAccent.Width, _layoutLeftAccentBounds.Height); | ||
} | ||
|
||
ScrollbarVisible = _contentBounds.Y > (_size.Y - topOffset - bottomOffset); | ||
|
||
this.ContentRegion = new Rectangle(leftOffset, | ||
topOffset, | ||
_size.X - leftOffset - rightOffset, | ||
_size.X - leftOffset - rightOffset - (ScrollbarVisible ? (ScrollbarWidth / 2) + (ScrollbarVisible ? 0 : RIGHT_PADDING) : 0), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think we should be magically updating the boundaries of ContentRegions like this. It's confusing if your ContentRegion is not the size that you have specified as a developer and further it gets us into weird domino behaviors with panels that manage the position of their children based on the content region size. |
||
_size.Y - topOffset - bottomOffset); | ||
|
||
_layoutHeaderBounds = new Rectangle(this.ContentRegion.Left, 0, this.ContentRegion.Width, HEADER_HEIGHT); | ||
_layoutHeaderBounds = new Rectangle(this.ContentRegion.Left, 0, this.ContentRegion.Width, HEADER_HEIGHT); | ||
_layoutHeaderTextBounds = new Rectangle(_layoutHeaderBounds.Left + 10, 0, _layoutHeaderBounds.Width - 10, HEADER_HEIGHT); | ||
|
||
_layoutAccordionArrowOrigin = new Vector2((float)ARROW_SIZE / 2, (float)ARROW_SIZE / 2); | ||
_layoutAccordionArrowBounds = new Rectangle(_layoutHeaderBounds.Right - ARROW_SIZE, | ||
(topOffset - ARROW_SIZE) / 2, | ||
ARROW_SIZE, | ||
ARROW_SIZE).OffsetBy(_layoutAccordionArrowOrigin.ToPoint()); | ||
|
||
_backgroundColorBounds = new Rectangle(leftOffset, | ||
topOffset, | ||
_size.X - leftOffset - rightOffset - 2, | ||
_size.Y - topOffset - bottomOffset); | ||
|
||
if (_panelScrollbar != null) { | ||
_panelScrollbar.Height = this.ContentRegion.Height - 20; | ||
_panelScrollbar.Right = this.Right; | ||
_panelScrollbar.Top = this.Top + this.ContentRegion.Top + 10; | ||
} | ||
} | ||
|
||
private void UpdateScrollbar() { | ||
/* TODO: Fix .CanScroll: currently you have to set it after you set other region changing settings for it | ||
to work correctly */ | ||
if (this.CanScroll) { | ||
if (_panelScrollbar == null) | ||
if (_panelScrollbar == null) | ||
_panelScrollbar = new Scrollbar(this); | ||
|
||
this.PropertyChanged -= UpdatePanelScrollbarOnOwnPropertyChanged; | ||
this.PropertyChanged += UpdatePanelScrollbarOnOwnPropertyChanged; | ||
|
||
_panelScrollbar.Parent = this.Parent; | ||
_panelScrollbar.Height = this.ContentRegion.Height - 20; | ||
_panelScrollbar.Right = this.Right - _panelScrollbar.Width / 2; | ||
_panelScrollbar.Right = this.Right; | ||
_panelScrollbar.Top = this.Top + this.ContentRegion.Top + 10; | ||
_panelScrollbar.Visible = this.Visible; | ||
_panelScrollbar.ZIndex = this.ZIndex + 2; | ||
|
@@ -291,7 +303,7 @@ private void UpdatePanelScrollbarOnOwnPropertyChanged(object? sender, PropertyCh | |
_panelScrollbar.Height = this.ContentRegion.Height - 20; | ||
break; | ||
case "Right": | ||
_panelScrollbar.Right = this.Right - _panelScrollbar.Width / 2; | ||
_panelScrollbar.Right = this.Right; | ||
break; | ||
case "Top": | ||
_panelScrollbar.Top = this.Top + this.ContentRegion.Top + 10; | ||
|
@@ -389,8 +401,6 @@ public override void PaintBeforeChildren(SpriteBatch spriteBatch, Rectangle boun | |
} | ||
|
||
protected override void DisposeControl() { | ||
_panelScrollbar?.Dispose(); | ||
|
||
foreach (var control in this._children) { | ||
control.Resized -= UpdateContentRegionBounds; | ||
control.Moved -= UpdateContentRegionBounds; | ||
|
@@ -400,4 +410,4 @@ protected override void DisposeControl() { | |
} | ||
|
||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -91,6 +91,22 @@ private int ScrollbarHeight { | |
|
||
private double _scrollbarPercent = 1.0; | ||
|
||
/// <summary> | ||
/// See if the <see cref="Scrollbar"/> is beeing drawn. | ||
/// </summary> | ||
public bool Drawn | ||
{ | ||
get => Visible && _scrollbarPercent < 0.99; | ||
} | ||
Comment on lines
+94
to
+100
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since the plan is to move towards not having a scrollbar control at all, I'd like to avoid adding any "short-cut" APIs that can be done by the consumer itself. |
||
|
||
/// <summary> | ||
/// Width of the <see cref="Scrollbar"/>. | ||
/// </summary> | ||
public int ScrollbarWidth | ||
{ | ||
get => _barBounds.Width; | ||
} | ||
|
||
private Container _associatedContainer; | ||
public Container AssociatedContainer { | ||
get => _associatedContainer; | ||
|
@@ -298,4 +314,4 @@ protected override void Paint(SpriteBatch spriteBatch, Rectangle bounds) { | |
} | ||
|
||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Anything for the scrollbar itself should be in the
Panel
control. Panel is the highest level control that has implemented the scrollbar and I don't see a reason to move its implementation up into the Container. Containers are intended to be fairly barebones.If an implementer wishes to share this functionality then they can implement the
Panel
control as they do now.