Click here to Skip to main content
15,881,381 members
Please Sign up or sign in to vote.
1.00/5 (2 votes)
Hello!

I'm implementing a vertical scrollbar for a small game project and i'm having some issues with calculating local positions of the scrollbar Thumb and Content when the Viewport rectangle moves.

At the moment, when i move the viewport, the track, thumb and content flyes all over the place.

- What i'm trying to achieve:

. Calculate the Thumb and Content "local positions".

. When the Viewport is moved, the Thumb and Content should keep their local positions in relation to the new viewport position.

I'm using C#, Windows Forms and the System.Drawing Rectangle.
I'm not using the Windows Forms controls, they are all custom.

Here is a snippet of the code:

C#
var track = new Rectangle(0, 0, 50, 100);
var thumb = new Rectangle(0, 0, 50, 100);
var content = new Rectangle(0, 0, 100, 100);

// Called when the viewport rectangle position is changed:
public void OnViewportPositionChanged(Point position)
{
	viewport.X = position.X;
	viewport.Y = position.Y;
	
	thumb.X = viewport.X;
	thumb.Y = thumb_local_position;
	
	content.X = viewport.X;
	content.Y = content_local_position;
}

public void CalculateLocalPositions()
{
	content_local_position = ???;
	thumb_local_position   = ???;
}


Thanks in advance!

What I have tried:

I'm trying to solve these two problems since yesterday but could not find the right calculations on the web.
Posted
Updated 25-Aug-21 7:12am
v23
Comments
strangerick 24-Aug-21 14:23pm    
Someone could provide a direct answer with the math to solve this problem?
BillWoodruff 24-Aug-21 20:29pm    
repost of; https://www.codeproject.com/Questions/5310526/How-to-implement-a-simple-scrollbar
strangerick 25-Aug-21 6:44am    
Hi, i posted this question but these problems was already solved, could you help with this new question?
Richard MacCutchan 25-Aug-21 4:04am    
I assume you mean when the parent control is resized, rather than moved. In which case you just need to calculate the ratio of the original scrollbars to the window. You can then calculate the new scrollbar sizes from those values when the parent has been resized.
strangerick 25-Aug-21 6:43am    
Hi, what i need is the math to move the thumb and content so they keep their last Y positions and move to the new position relative to it.
Also, i'm not using the Winform controls, they are all custom.

The problem is probably caused because control coordinates are recalculated internally and have different values than you expect (depending on Windows scale and Font settings).
See: Control.PointToScreen(Point) Method[^]
And: Automatic Scaling - Windows Forms .NET Framework | Microsoft Docs[^]

Quote:
Custom Controls: Another way to create a control is to create one substantially from the beginning by inheriting from Control.
See: Varieties of Custom Controls - Windows Forms .NET Framework | Microsoft Docs[^]
 
Share this answer
 
v3
Comments
strangerick 24-Aug-21 14:41pm    
Hello, thanks for the answer, but i'm not using Windows Forms controls, they are all custom controls made for a game project.

Could you provide a answer with the math to update the positions of the thumb and content rectangles so they can move to the new Y position relative to their last Y position?
RickZeeland 24-Aug-21 14:50pm    
It's been long ago that I struggled with a similar problem, and being an old fart I can't remember how I solved it sadly ... maybe after a good night's rest :)
Oh, and custom controls are controls too !
strangerick 24-Aug-21 14:56pm    
Ok, that's fine. Maybe later you can provide a answer :)
Also, i'm using only the PictureBox from Winforms, the rest are all custom controls that does not inherit from Control.
C++
// When the parent is resized, the scrollbar should be resized
// to fit the new size of the viewport (excluding borders etc).
// It is then just a matter of calculating the ratio of visible
// data to the size the relevant dimension of the viewport.
//
ratio = data.dimension / viewport.dimension; // the percentage of data being displayed
thumb.dimension = scrollbar.dimension / ratio;
//
// So if the viewed data is one twentieth of the total available
// the thumb control should be one twentieth of the scrollbar.
// i.e it can move to view each twentieth section of the data.
// this applies in the horizontal and vertical planes.
 
Share this answer
 
Comments
strangerick 25-Aug-21 13:10pm    
Hello, thanks for the answer but the thumb size has nothing to do with the question in hand, I also tried applying it to the positions but it did not worked.

As I wrote in the original post:

. Calculate the Thumb and Content "LOCAL POSITIONS".
. Then, when the Viewport is MOVED: the Thumb and Content should always KEEP THEIR LOCAL POSITIONS IN RELATION TO THE NEW VIEWPORT POSITION.

Could you please edit your answer?
Richard MacCutchan 26-Aug-21 4:07am    
If the viewport is of size 100 and the data is size 1000 then you can only view one tenth of the data at any time. So your thumb position can be in one of ten places depending on which 'page' is being viewed*. If the viewport size increases to 150 then the data that can be viewed increases to one sixth of the total. So you recalculate the positions and sizes with those values. You need to do this calculation every time you refresh the view, as it may be changing all the time.

In reality you may be moving the view in smaller increments.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900