I've been working on a custom grid control whose viewport is exactly of size 1024 pixels which is used to plot signal points. Note that a complete signal also consist of exactly 1024 points. This means that one signal spread to the whole width of the grid.
I can also zoom into the graph which increases the Signal points times ZoomFactor. which is:
...
const int SignalLength = 1024;
int ZoomFactor = 2; //Updated by user
int NewPoints = SignalLength * ZoomFactor;
...
I've been trying to create custom scrubber/scroller which helps in scrolling through a zoomed signal. However, I've been facing issues during maintaining the proportions of scroll and visible content in sync.
A few parameters that I've worked are:
Scroll Buttons : Each of Size 50x50 pixels
Scrollable Area: Which reduces due to Scroll buttons. That is Grid Width - (50*2)
: 924 pixels.
Scrubber Width : Which will always be Scrollable Area / ZoomFactor
Notice the arrows in image which shows the visible section of signal is not in sync with the scrubber. I guess the scrubber is moving too fast than what the grid is actually showing.
private void ZoomFactor_Changed(object sender, EventArgs e)
{
if (ZoomFactor > 1)
{
Scrubber.Width = (ScrubberTrackPanel.Width / ZoomFactor);
ScrubberWidth.Text = Scrubber.Width.ToString();
ScrubberTrackPanel.Visible = true;
}
else
{
ScrubberTrackPanel.Visible = false;
Scrubber.Width = Scrubber.Parent.Width;
}
}
private void SfBtn_GridScrollRight_MouseDown(object sender, MouseEventArgs e)
{
// Both left and right button's tag property have the step value.
// Left has -2
// Right has 2
GlobalVars.GridScrubStepSize = 0 + int.Parse((SfButton)sender).Tag.ToString());
GridScrubberTimer.Start();
}
private void GridScrubberTimer_Tick(object sender, EventArgs e)
{
ScrollGrid(GlobalVars.GridScrubStepSize);
}
private void ScrollGrid(int StepSize)
{
var newStepPos = GlobalVars.ZoomedSignalLeft + StepSize;
//To stop scroll timer if any of the boundry (left/right) of graph is reached.
if (newStepPos <= 0 || newStepPos >= 1024 * ZoomFactor && GridScrubberTimer.Enabled)
{
GridScrubberTimer.Stop();
return;
}
var ZoomedSignalSlice = GlobalVars.ZoomedSignal.Skip(newStepPos).Take(1024).ToList();
if (ZoomedSignalSlice.Count == 1024)
{
GlobalVars.ZoomedSignalLeft += GlobalVars.GridScrubStepSize;
if (ScrubberTrackPanel.Visible)
{
Scrubber.Location = new Point(Scrubber.Location.X + (int)Math.Floor(GlobalVars.GridScrubStepSize/ (float)ZoomFactor), 0);
ScrubberCords.Text = Scrubber.Location.ToString();
}
GraphGrid.Refresh();
}
}
I've tried How to calculate the size of scroll bar thumb and Formula for content step of scrollbar but somehow I'm not able to grasp the proportions correctly.
I'm sure I'm missing something very obvious (&& stupid :p) thing which you will shed light on.
After tinkering a lot with the code for hours I realized the calculation for the location was very wrong. After fixing it, the scroll is working as expected while maintaining the proportions appropriately.
Below is the correct code:
...
GlobalVars.ZoomedSignalLeft += GlobalVars.GridScrollStepSize;
// Mapping the current beginning position of the visible signal on the grid in the range of ScrollerTrackPanel and then dividing
// it with the ZoomFactor To get location of scrubber over the signal image proportional to the visible signal on the grid.
int newx = (int)Math.Floor(GlobalVars.ZoomedSignalLeft / 1024F * ScrollerTrackPanel.Width / ZoomFactor);
Scrubber.Location = new Point(newx, 0);
...