-
Notifications
You must be signed in to change notification settings - Fork 733
Fixes #2489. Create new ScrollBar based on a new Scroll and remove ScrollBarView/ScrollView #3498
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
Closed
Closed
Changes from 3 commits
Commits
Show all changes
105 commits
Select commit
Hold shift + click to select a range
478c93d
Create a Scroll class with unit tests and use case.
BDisp 84c69f0
Remove unnecessary _sliderContainer view.
BDisp 4cb27fc
Rename to Scroll_ prefix on the Scroll event methods.
BDisp 46d1749
Tweaks and suggestions
tig 57d4f0d
More autosize related tweaks
tig d6a183c
Merge pull request #180 from tig/BDisp-v2_2489-tig-1
BDisp 24e4f65
Remove unnecessary ClearOnVisibleFalse property.
BDisp de6d276
Remove unneeded comments.
BDisp 86e0db2
Add mouse wheel.
BDisp 30be052
Ensure the Position is valid if the slider is at end.
BDisp 8c617f3
Fixes NumericUpDown resize when number of characters grows.
BDisp 365f889
Added more tweaks.
BDisp d5b98a1
Suggestions and questions
tig dc9d384
Merge pull request #181 from tig/BDisp-v2_2489-tig-2
BDisp ee47e75
Change Parent to SuperView.
BDisp d4e6ae6
Resolving merge conflicts.
BDisp 4e57840
Fix merge errors.
BDisp 057e89c
Merge branch 'v2_develop' into v2_2489_scroll-scrollbar-new
BDisp 7489d6c
Replace local var with private getter field.
BDisp 1e9e27a
Only raises PositionChanging and PositionChanged if position has chan…
BDisp becad1d
Add slider highlight effect.
BDisp 5d2120e
Replace private _barSize with local variables barSize and improving p…
BDisp 5c6b39b
Removed unnecessary methods and now unit test pass.
BDisp d44efe3
Setting entire ColorScheme attributes.
BDisp 5cc3afb
Merge branch 'v2_2489_scroll-scrollbar-new' of github.com:BDisp/Termi…
tig 9ed6cf7
Merge branch 'v2_develop' into v2_2489_scroll-scrollbar-new
BDisp f9aa619
Fix merge errors.
BDisp e5f1476
Merge branch 'v2_develop' into v2_2489_scroll-scrollbar-new
tig 4a68fc0
Resolving merge conflicts.
BDisp 9b4269e
Fix merge errors.
BDisp 91e4abf
Ensures Position set before call AdjustSlider and
BDisp c20b733
Merge branch 'v2_develop' into v2_2489_scroll-scrollbar-new
BDisp b488796
Move Scroll.cs to the Scroll folder.
BDisp fa6fb11
Add internal ScrollSlider class.
BDisp 4e22706
Using overridden methods instead of events.
BDisp 3317c50
Moving slider code to his class.
BDisp b025beb
Rename id to scrollSlider to avoid conflict with the Slider view.
BDisp 9b89657
Fix scroll slider when moving mouse outside the host.
BDisp 3386d06
Ensure correct Width/Height when orientation is changed.
BDisp e59c02a
Rename to AdjustScroll method.
BDisp ffa08b8
Merge branch 'v2_develop' into v2_2489_scroll-scrollbar-new
BDisp 7e3a3b2
Fixes #3679. WantContinuousButtonPressed mustn't force calling GrabMo…
BDisp 6add7a1
Merge branch 'v2_develop' into v2_2489_scroll-scrollbar-new
BDisp c587cb9
Merge branch 'v2_3679_want-continuous-pressed-fix' into v2_2489_scrol…
BDisp 8188822
Ensures slider to have a length proportional to the bar size.
BDisp 92e067e
Prevents continuous mouse button pressed from processing mouse event …
BDisp 5e7bb7b
Starting implementing ScrollBar.
BDisp 479ff3d
Merge branch 'v2_develop' into v2_2489_scroll-scrollbar-new
BDisp ecc44fc
Merge branch 'v2_develop' into v2_2489_scroll-scrollbar-new
BDisp 14ed92e
Restore color scheme on mouse leave no matter the button.
BDisp cb7bc94
Ensures accurate calculation if is hosted by a ScrollBar before initi…
BDisp d47188f
Consolidating GetPositionFromSliderLocation and GetSliderLocationDime…
BDisp 7a1eb98
Code cleanup.
BDisp 71d558f
Remove _wasSliderLayoutComplete field.
BDisp d3ab81e
Add ScrollBar unit tests and code cleanup.
BDisp a343fd0
Add ScrollButton unit test and code cleanup.
BDisp ae3fcef
Remove host parameter from scroll classes.
BDisp 1ccd548
Merge branch 'v2_develop' into v2_2489_scroll-scrollbar-new
BDisp a83b8f1
Merge branch 'v2_develop' into v2_2489_scroll-scrollbar-new
BDisp e489146
Replaces VariationMode with NavigationDirection enum.
BDisp 27aa591
Remove Virtual.
BDisp 7343832
Replace with SuperViewAsScrollBar.
BDisp b16b463
Doc changes addressed by @tig.
BDisp 3e7d950
Merge branch 'v2_develop' into v2_2489_scroll-scrollbar-new
BDisp 11fc893
Remove commented code.
BDisp f0d2bbe
Rename to SuperViewAsScroll.
BDisp 1804d08
Add private BarSize method.
BDisp bf4b7bd
Merge branch 'v2_develop' into v2_2489_scroll-scrollbar-new
BDisp c43de60
BarSize should use Viewport.
BDisp 70b3be2
The barSize should use the Scroll Viewport.
BDisp 6c972c6
Add AutoHideScrollBar and ShowScrollIndicator properties.
BDisp 5279af1
Merge branch 'v2_2489_scroll-scrollbar-new' of tig:BDisp/Terminal.Gui…
tig e2a2aa1
Upgraded CharMap to use new ScrollBar
tig 68b0352
Merge pull request #194 from tig/BDisp-v2_2489_scroll-scrollbar-new
BDisp cb1c793
Code cleanup and API doc improvements
tig c48f6d9
Merge branch 'v2_2489_scroll-scrollbar-new' into BDisp-v2_2489_scroll…
BDisp 7983500
Fix @tig branch errors.
BDisp 9075aca
Using Visible instead of ShowScrollIndicator.
BDisp 3bd4638
I think this was already done before.
BDisp da85d58
Rename to start and end.
BDisp 20370c4
Remove comment.
BDisp f54ded3
Add KeepContentInAllViewport to Scroll.
BDisp 07d7162
Prevent Size being negative.
BDisp 14e2e3c
Fix some KeepContentInAllViewport bugs.
BDisp dbbde3e
Using GetContentSize.
BDisp bf3e9b2
Fixes #3729. ProcessContinuousButtonPressedAsync is using a stale Mou…
BDisp 06e9910
Merge branch 'v2_3729_windowsdriver-continuous-mouse-pressed-fix' int…
BDisp 6b39670
Merge branch 'v2_develop' into v2_2489_scroll-scrollbar-new
BDisp cccbbc2
Typo.
BDisp 8d346a8
Implement @tig scroll bars and fix some bugs.
BDisp 84225fc
Fix unit test.
BDisp bd51356
Add unit test for KeepContentInAllViewport as false.
BDisp 66ec2de
Fix more unit tests that were used with KeepContentInAllViewport as t…
BDisp 630638e
Fix nullable warnings.
BDisp ae7a86f
Fix ScrollBar that was returning more 2 position at end.
BDisp c5e886f
Manipulate ViewportSettings with ScrollBars.
BDisp 03dac3e
Merged bdisp latest.
tig b19437d
Merge pull request #197 from tig/BDisp-v2_2489_scroll-tig-builtin
BDisp 060f915
Merge branch 'v2_2489_scroll-scrollbar-new' of tig:BDisp/Terminal.Gui…
tig 38c604e
More CharMap tweaks
tig 0f3c1ee
Merge pull request #198 from tig/BDisp-v2_2489_scroll-tig-builtin
BDisp 0c55203
Merge branch 'v2_2489_scroll-scrollbar-new' of tig:BDisp/Terminal.Gui…
tig f4931c2
API doc and overview improvements
tig f8b2d02
Doc'd samples
tig 0bafe6e
Merge pull request #199 from tig/BDisp-v2_2489_scroll-tig-builtin
BDisp File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,355 @@ | ||
| // | ||
| // Scroll.cs: Vertical or horizontal scroll | ||
| // | ||
| // Author: BDisp | ||
| // | ||
| // Licensed under the MIT license | ||
| // | ||
|
|
||
| namespace Terminal.Gui; | ||
|
|
||
| /// <summary> | ||
| /// Represents the "inside part" of a scroll bar, minus the arrows. | ||
| /// </summary> | ||
| public class Scroll : View | ||
| { | ||
| /// <inheritdoc/> | ||
| public Scroll () | ||
| { | ||
| WantContinuousButtonPressed = true; | ||
| ClearOnVisibleFalse = false; | ||
BDisp marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| CanFocus = false; | ||
| Orientation = Orientation.Vertical; | ||
| Width = 1; | ||
BDisp marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| _slider = new () { Id = "slider" }; | ||
| Add (_slider); | ||
|
|
||
| Added += Scroll_Added; | ||
| Removed += Scroll_Removed; | ||
| Initialized += Scroll_Initialized; | ||
| DrawContent += Scroll_DrawContent; | ||
| MouseEvent += Scroll_MouseEvent; | ||
| _slider.DrawContent += Scroll_DrawContent; | ||
| _slider.MouseEvent += Slider_MouseEvent; | ||
| } | ||
|
|
||
| private readonly View _slider; | ||
| private int _lastLocation = -1; | ||
tig marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| private Orientation _orientation; | ||
| private int _size; | ||
| private int _position; | ||
|
|
||
| private bool _wasSliderMouse; | ||
tig marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| /// <summary> | ||
| /// Determines the Orientation of the scroll. | ||
| /// </summary> | ||
| public Orientation Orientation | ||
| { | ||
| get => _orientation; | ||
| set | ||
| { | ||
| _orientation = value; | ||
| SetWidthHeight (); | ||
| } | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// The position, relative to <see cref="Size"/>, to set the scrollbar at. | ||
| /// </summary> | ||
| public int Position | ||
| { | ||
| get => _position; | ||
| set | ||
| { | ||
| int barSize = Orientation == Orientation.Vertical ? Frame.Height : Frame.Width; | ||
|
|
||
| if (value < 0 || (value > 0 && value + barSize > Size)) | ||
| { | ||
| return; | ||
| } | ||
|
|
||
| StateEventArgs<int> args = OnPositionChanging (_position, value); | ||
|
|
||
| if (args.Cancel) | ||
| { | ||
| return; | ||
| } | ||
|
|
||
| int oldPos = _position; | ||
| _position = value; | ||
| OnPositionChanged (oldPos); | ||
|
|
||
| if (!_wasSliderMouse) | ||
| { | ||
| SetWidthHeight (); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| /// <summary>This event is raised when the position on the scrollbar has changed.</summary> | ||
| public event EventHandler<StateEventArgs<int>> PositionChanged; | ||
|
|
||
| /// <summary>This event is raised when the position on the scrollbar is changing.</summary> | ||
| public event EventHandler<StateEventArgs<int>> PositionChanging; | ||
|
|
||
| /// <summary> | ||
| /// The size of content the scroll represents. | ||
| /// </summary> | ||
| public int Size | ||
| { | ||
| get => _size; | ||
| set | ||
| { | ||
| int oldSize = _size; | ||
| _size = value; | ||
| OnSizeChanged (oldSize); | ||
| SetWidthHeight (); | ||
| } | ||
| } | ||
|
|
||
| /// <summary>This event is raised when the size of the scroll has changed.</summary> | ||
| public event EventHandler<StateEventArgs<int>> SizeChanged; | ||
|
|
||
| /// <inheritdoc/> | ||
| protected override void Dispose (bool disposing) | ||
| { | ||
| Added -= Scroll_Added; | ||
| Initialized -= Scroll_Initialized; | ||
| DrawContent -= Scroll_DrawContent; | ||
| MouseEvent -= Scroll_MouseEvent; | ||
| _slider.DrawContent -= Scroll_DrawContent; | ||
| _slider.MouseEvent -= Slider_MouseEvent; | ||
|
|
||
| base.Dispose (disposing); | ||
| } | ||
|
|
||
| /// <summary>Virtual method to invoke the <see cref="PositionChanged"/> event handler.</summary> | ||
| protected virtual void OnPositionChanged (int oldPos) { PositionChanged?.Invoke (this, new (oldPos, Position)); } | ||
|
|
||
| /// <summary>Virtual method to invoke the cancelable <see cref="PositionChanging"/> event handler.</summary> | ||
| protected virtual StateEventArgs<int> OnPositionChanging (int oldPos, int newPos) | ||
| { | ||
| StateEventArgs<int> args = new (oldPos, newPos); | ||
| PositionChanging?.Invoke (this, args); | ||
|
|
||
| return args; | ||
| } | ||
|
|
||
| /// <summary>Virtual method to invoke the <see cref="SizeChanged"/> event handler.</summary> | ||
| protected void OnSizeChanged (int oldSize) { SizeChanged?.Invoke (this, new (oldSize, Size)); } | ||
|
|
||
| private int GetPositionFromSliderLocation (int location) | ||
| { | ||
| if (Frame.Height == 0 || Frame.Width == 0) | ||
| { | ||
| return 0; | ||
| } | ||
|
|
||
| int barSize = Orientation == Orientation.Vertical ? Frame.Height : Frame.Width; | ||
|
|
||
| return Math.Min (location * Size / barSize, Size - barSize); | ||
| } | ||
|
|
||
| private (int Location, int Dimension) GetSliderLocationDimensionFromPosition () | ||
| { | ||
| if (Frame.Height == 0 || Frame.Width == 0) | ||
| { | ||
| return new (0, 0); | ||
| } | ||
|
|
||
| int barSize = Orientation == Orientation.Vertical ? Frame.Height : Frame.Width; | ||
| int location; | ||
| int dimension; | ||
|
|
||
| if (Size > 0) | ||
| { | ||
| dimension = Math.Min (Math.Max (barSize * barSize / Size, 1), barSize); | ||
|
|
||
| // Ensure the Position is valid | ||
| if (Position > 0 && Position + barSize > Size) | ||
| { | ||
| Position = Size - barSize; | ||
| } | ||
|
|
||
| location = Math.Min (Position * barSize / Size, barSize - dimension); | ||
|
|
||
| if (Position == Size - barSize && location + dimension < barSize) | ||
| { | ||
| location = barSize - dimension; | ||
| } | ||
| } | ||
| else | ||
| { | ||
| location = 0; | ||
| dimension = barSize; | ||
| } | ||
|
|
||
| return new (location, dimension); | ||
| } | ||
|
|
||
| private void Parent_LayoutComplete (object sender, LayoutEventArgs e) | ||
| { | ||
| if (!_wasSliderMouse) | ||
| { | ||
| SetWidthHeight (); | ||
| } | ||
| else | ||
| { | ||
| _wasSliderMouse = false; | ||
| } | ||
| } | ||
|
|
||
| private void Parent_MouseEnter (object sender, MouseEventEventArgs e) { OnMouseEnter (e.MouseEvent); } | ||
|
|
||
| private void Parent_MouseLeave (object sender, MouseEventEventArgs e) { OnMouseLeave (e.MouseEvent); } | ||
|
|
||
| private void Scroll_Added (object sender, SuperViewChangedEventArgs e) | ||
| { | ||
| View parent = e.Parent is Adornment adornment ? adornment.Parent : e.Parent; | ||
|
|
||
| parent.LayoutComplete += Parent_LayoutComplete; | ||
| parent.MouseEnter += Parent_MouseEnter; | ||
| parent.MouseLeave += Parent_MouseLeave; | ||
| } | ||
|
|
||
| private void Scroll_DrawContent (object sender, DrawEventArgs e) { SetColorSchemeWithSuperview (sender as View); } | ||
|
|
||
| private void Scroll_Initialized (object sender, EventArgs e) { SetWidthHeight (); } | ||
|
|
||
| private void Scroll_MouseEvent (object sender, MouseEventEventArgs e) | ||
| { | ||
| MouseEvent me = e.MouseEvent; | ||
| int location = Orientation == Orientation.Vertical ? me.Position.Y : me.Position.X; | ||
| int barSize = Orientation == Orientation.Vertical ? Frame.Height : Frame.Width; | ||
|
|
||
| (int topLeft, int bottomRight) sliderPos = _orientation == Orientation.Vertical | ||
| ? new (_slider.Frame.Y, _slider.Frame.Bottom - 1) | ||
| : new (_slider.Frame.X, _slider.Frame.Right - 1); | ||
|
|
||
| if (me.Flags == MouseFlags.Button1Pressed && location < sliderPos.topLeft) | ||
| { | ||
| Position = Math.Max (Position - barSize, 0); | ||
| } | ||
| else if (me.Flags == MouseFlags.Button1Pressed && location > sliderPos.bottomRight) | ||
| { | ||
| Position = Math.Min (Position + barSize, Size - barSize); | ||
| } | ||
| } | ||
|
|
||
| private void Scroll_Removed (object sender, SuperViewChangedEventArgs e) | ||
| { | ||
| if (e.Parent is { }) | ||
| { | ||
| View parent = e.Parent is Adornment adornment ? adornment.Parent : e.Parent; | ||
|
|
||
| parent.LayoutComplete -= Parent_LayoutComplete; | ||
| parent.MouseEnter -= Parent_MouseEnter; | ||
| parent.MouseLeave -= Parent_MouseLeave; | ||
| } | ||
| } | ||
|
|
||
| private static void SetColorSchemeWithSuperview (View view) | ||
| { | ||
| if (view.SuperView is { }) | ||
| { | ||
| View parent = view.SuperView is Adornment adornment ? adornment.Parent : view.SuperView; | ||
|
|
||
| if (view.Id == "slider") | ||
| { | ||
| view.ColorScheme = new () { Normal = new (parent.ColorScheme.Normal.Foreground, parent.ColorScheme.Normal.Foreground) }; | ||
| } | ||
| else | ||
| { | ||
| view.ColorScheme = parent.ColorScheme; | ||
| } | ||
| } | ||
| } | ||
|
|
||
| private void SetSliderText () | ||
| { | ||
| TextDirection = Orientation == Orientation.Vertical ? TextDirection.TopBottom_LeftRight : TextDirection.LeftRight_TopBottom; | ||
|
|
||
| Text = string.Concat ( | ||
| Enumerable.Repeat ( | ||
| Glyphs.Stipple.ToString (), | ||
| Frame.Width * Frame.Height)); | ||
| _slider.TextDirection = Orientation == Orientation.Vertical ? TextDirection.TopBottom_LeftRight : TextDirection.LeftRight_TopBottom; | ||
|
|
||
| _slider.Text = string.Concat ( | ||
| Enumerable.Repeat ( | ||
| Glyphs.ContinuousMeterSegment.ToString (), | ||
| _slider.Frame.Width * _slider.Frame.Height)); | ||
| } | ||
|
|
||
| private void SetWidthHeight () | ||
| { | ||
| if (!IsInitialized) | ||
| { | ||
| return; | ||
| } | ||
|
|
||
| (int Location, int Dimension) slider = GetSliderLocationDimensionFromPosition (); | ||
| _slider.X = Orientation == Orientation.Vertical ? 0 : slider.Location; | ||
| _slider.Y = Orientation == Orientation.Vertical ? slider.Location : 0; | ||
| _slider.Width = Orientation == Orientation.Vertical ? Dim.Fill () : slider.Dimension; | ||
| _slider.Height = Orientation == Orientation.Vertical ? slider.Dimension : Dim.Fill (); | ||
|
|
||
| SetSliderText (); | ||
| } | ||
|
|
||
| private void Slider_MouseEvent (object sender, MouseEventEventArgs e) | ||
| { | ||
| MouseEvent me = e.MouseEvent; | ||
| int location = Orientation == Orientation.Vertical ? me.Position.Y : me.Position.X; | ||
| int barSize = Orientation == Orientation.Vertical ? Frame.Height : Frame.Width; | ||
| int offset = _lastLocation > -1 ? location - _lastLocation : 0; | ||
|
|
||
| if (me.Flags == MouseFlags.Button1Pressed) | ||
| { | ||
| if (Application.MouseGrabView != sender as View) | ||
| { | ||
| Application.GrabMouse (sender as View); | ||
| _lastLocation = location; | ||
| } | ||
| } | ||
| else if (me.Flags == (MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition)) | ||
| { | ||
| if (Orientation == Orientation.Vertical) | ||
| { | ||
| if (_slider.Frame.Y + offset >= 0 && _slider.Frame.Y + offset + _slider.Frame.Height <= barSize) | ||
| { | ||
| _wasSliderMouse = true; | ||
| _slider.Y = _slider.Frame.Y + offset; | ||
| Position = GetPositionFromSliderLocation (_slider.Frame.Y); | ||
| } | ||
| } | ||
| else | ||
| { | ||
| if (_slider.Frame.X + offset >= 0 && _slider.Frame.X + offset + _slider.Frame.Width <= barSize) | ||
| { | ||
| _wasSliderMouse = true; | ||
| _slider.X = _slider.Frame.X + offset; | ||
| Position = GetPositionFromSliderLocation (_slider.Frame.X); | ||
| } | ||
| } | ||
| } | ||
| else if (me.Flags == MouseFlags.Button1Released) | ||
| { | ||
| _lastLocation = -1; | ||
|
|
||
| if (Application.MouseGrabView == sender as View) | ||
| { | ||
| Application.UngrabMouse (); | ||
| } | ||
| } | ||
| else | ||
| { | ||
| return; | ||
| } | ||
|
|
||
| e.Handled = true; | ||
| } | ||
| } | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.