diff --git a/src/MainForm.cs b/src/MainForm.cs index 9a9e037..a0efe06 100644 --- a/src/MainForm.cs +++ b/src/MainForm.cs @@ -25,6 +25,7 @@ public partial class MainForm : Form private Point? mMouseDragAnchor = null ; private Tuple mScrollDragAnchor ; + private double mUserZoom = 1.0 ; public MainForm() { diff --git a/src/MainForm.ui.cs b/src/MainForm.ui.cs index 6d7d0be..631bdff 100644 --- a/src/MainForm.ui.cs +++ b/src/MainForm.ui.cs @@ -104,17 +104,22 @@ public partial class MainForm : Form return false ; } + private int ChartImagePanel_MaxScrollX() { return mChartImagePanel.HorizontalScroll.Maximum - mChartImagePanel.Width + 17 ; } + private int ChartImagePanel_MaxScrollY() { return mChartImagePanel.VerticalScroll.Maximum - mChartImagePanel.Height + 17 ; } + private void MainForm_Load( object sender, EventArgs e ) { // initialize - MainForm_Resize( this, null ) ; + doMainFormResize( null ) ; // load the chart images loadChartImages() ; loadSearchResults( mChartImages.Values ) ; } - private void MainForm_Resize( object sender, EventArgs e ) + private void MainForm_Resize( object sender, EventArgs e ) { doMainFormResize( null ) ; } + + private void doMainFormResize( Point? clientMousePos ) { // check if we are showing a ChartImage Image img = mChartImagePictureBox.Image ; @@ -149,6 +154,10 @@ public partial class MainForm : Form height = (int) (img.Height * maxZoom) ; } + // incorporate the user-controlled manual zoom + width = (int)( width * mUserZoom + 0.5 ) ; + height = (int)( height * mUserZoom + 0.5 ) ; + // check if the v-scrollbar is showing if ( height >= mChartImagePanel.Height ) { // yup - adjust the width @@ -157,16 +166,44 @@ public partial class MainForm : Form width -= sbWidth ; } + // remember the current scroll positions + HScrollProperties hscroll = mChartImagePanel.HorizontalScroll ; + int prevScrollPosX = hscroll.Value ; + int prevMaxScrollX = ChartImagePanel_MaxScrollX() ; + double prevRelScrollPosX = (double)prevScrollPosX / (double)prevMaxScrollX ; + VScrollProperties vscroll = mChartImagePanel.VerticalScroll ; + int prevScrollPosY = vscroll.Value ; + int prevMaxScrollY = ChartImagePanel_MaxScrollY() ; + double prevRelScrollPosY = (double)prevScrollPosY / (double)prevMaxScrollY ; + // resize and position the ChartImage - // TODO: It would be nice to maintain the scroll position of the current image, - // but how .NET sets the scroll range/position is weird :-/ + mChartImagePanel.HorizontalScroll.Value = 0 ; + mChartImagePanel.VerticalScroll.Value = 0 ; + Size prevChartImagePictureBoxSize = new Size( mChartImagePictureBox.Size.Width, mChartImagePictureBox.Size.Height ) ; mChartImagePictureBox.Size = new Size( width, height ) ; if ( width < availableWidth ) mChartImagePictureBox.Location = new Point( margin + (availableWidth - width)/2, margin ) ; else mChartImagePictureBox.Location = new Point( margin, margin ) ; - mChartImagePanel.HorizontalScroll.Value = 0 ; - mChartImagePanel.VerticalScroll.Value = 0 ; + + // restore the scroll positions + int newScrollPosX, newScrollPosY ; + int newMaxScrollX = ChartImagePanel_MaxScrollX() ; + int newMaxScrollY = ChartImagePanel_MaxScrollY() ; + if ( clientMousePos == null ) { + // maintain the relative scroll positions + newScrollPosX = (int)( prevRelScrollPosX * newMaxScrollX + 0.5 ) ; + newScrollPosY = (int)( prevRelScrollPosY * newMaxScrollY + 0.5 ) ; + } else { + // keep whatever's under the mouse in the same place + int absX = prevScrollPosX + clientMousePos.Value.X ; + double scaling = (double)mChartImagePictureBox.Size.Width / (double)prevChartImagePictureBoxSize.Width ; + newScrollPosX = (int)( absX * scaling + 0.5) - clientMousePos.Value.X ; + int absY = prevScrollPosY + clientMousePos.Value.Y ; + scaling = (double)mChartImagePictureBox.Size.Height / (double)prevChartImagePictureBoxSize.Height ; + newScrollPosY = (int)( absY * scaling + 0.5) - clientMousePos.Value.Y ; + } + scrollChartImagePanel( newScrollPosX, newScrollPosY ) ; } private void ChartImagePictureBox_MouseDown( object sender, MouseEventArgs e ) @@ -213,6 +250,15 @@ public partial class MainForm : Form int scrollRange = hscroll.Maximum - hscroll.Minimum ; int scrollX = hscroll.Value + (int)( scrollRange * nLines/100 ) ; scrollChartImagePanel( scrollX, null ) ; + } else if ( (Control.ModifierKeys & Keys.Control) != 0 ) { + if ( nLines > 0 ) { + float maxUserZoom = Program.appConfig.getFloatVal( new string[]{"MaxUserZoom"}, 2.0f ) ; + mUserZoom = Math.Min( mUserZoom+0.1, maxUserZoom ) ; + } else { + float minUserZoom = Program.appConfig.getFloatVal( new string[]{"MinUserZoom"}, 0.5f ) ; + mUserZoom = Math.Max( mUserZoom-0.1, minUserZoom ) ; + } + doMainFormResize( pos ) ; } else { // scroll the ChartImage up/down VScrollProperties vscroll = mChartImagePanel.VerticalScroll ; @@ -227,14 +273,14 @@ public partial class MainForm : Form // update the scroll position if ( scrollX != null ) { HScrollProperties hscroll = mChartImagePanel.HorizontalScroll ; - int maxScrollX = hscroll.Maximum - mChartImagePanel.Width + 17 ; + int maxScrollX = ChartImagePanel_MaxScrollX() ; int scrollPos = Math.Max( 0, Math.Min( maxScrollX, scrollX.Value ) ) ; hscroll.Value = scrollPos ; hscroll.Value = scrollPos ; // nb: for Windows :shrug: } if ( scrollY != null ) { VScrollProperties vscroll = mChartImagePanel.VerticalScroll ; - int maxScrollY = vscroll.Maximum - mChartImagePanel.Height + 17 ; + int maxScrollY = ChartImagePanel_MaxScrollY() ; int scrollPos = Math.Max( 0, Math.Min( maxScrollY, scrollY.Value ) ) ; vscroll.Value = scrollPos ; vscroll.Value = scrollPos ; // nb: for Windows :shrug: @@ -253,7 +299,8 @@ public partial class MainForm : Form mChartImagePictureBox.Image = null ; mChartImagePanel.HorizontalScroll.Value = 0 ; mChartImagePanel.VerticalScroll.Value = 0 ; - MainForm_Resize( this, null ) ; + mUserZoom = 1.0 ; + doMainFormResize( null ) ; } private void SearchQuery_TextChanged( object sender, EventArgs e )