diff --git a/src/MainForm.cs b/src/MainForm.cs index 05412ba..2e9f5cb 100644 --- a/src/MainForm.cs +++ b/src/MainForm.cs @@ -31,7 +31,7 @@ public partial class MainForm : Form private string mSearchResultsKey = null ; private Point? mMouseDragAnchor = null ; private Tuple mScrollDragAnchor ; - private double mCurrZoom, mMinZoom, mMaxZoom ; + private double mCurrZoom, mDefaultZoom, mMinZoom, mMaxZoom ; private DateTime mLastKeyPressTimeStamp = DateTime.Now ; private bool mDisableProcessCmdKey = false ; private bool mSearchQueryTextChangedDisabled = false ; @@ -284,12 +284,47 @@ public partial class MainForm : Form { // FUDGE! These need to be set twice to take effect on Windows :-/ if ( hscrollPos != null ) { - mChartImagePanel.HorizontalScroll.Value = hscrollPos.Value ; - mChartImagePanel.HorizontalScroll.Value = hscrollPos.Value ; + int scrollPos = Math.Min( Math.Max( hscrollPos.Value, 0 ), ChartImagePanel_MaxScrollX() ) ; + mChartImagePanel.HorizontalScroll.Value = scrollPos ; + mChartImagePanel.HorizontalScroll.Value = scrollPos ; } if ( vscrollPos != null ) { - mChartImagePanel.VerticalScroll.Value = vscrollPos.Value ; - mChartImagePanel.VerticalScroll.Value = vscrollPos.Value ; + int scrollPos = Math.Min( Math.Max( vscrollPos.Value, 0 ), ChartImagePanel_MaxScrollY() ) ; + mChartImagePanel.VerticalScroll.Value = scrollPos ; + mChartImagePanel.VerticalScroll.Value = scrollPos ; + } + } + + private void scrollMainForm( int nLines, bool horz ) + { + if ( horz ) { + // scroll the ChartImage left/right + HScrollProperties hscroll = mChartImagePanel.HorizontalScroll ; + int scrollRange = hscroll.Maximum - hscroll.Minimum ; + int scrollX = hscroll.Value + (int)( scrollRange * nLines/100 ) ; + scrollChartImagePanel( scrollX, null ) ; + } else { + // scroll the ChartImage up/down + VScrollProperties vscroll = mChartImagePanel.VerticalScroll ; + int scrollRange = vscroll.Maximum - vscroll.Minimum ; + int scrollY = vscroll.Value + (int)( scrollRange * nLines/100 ) ; + scrollChartImagePanel( null, scrollY ) ; + } + } + + private void adjustZoom( double? delta, Point? clientMousePos ) + { + // adjust the zoom + double newZoom ; + if ( delta != null ) + newZoom = Math.Max( Math.Min( mCurrZoom+delta.Value, mMaxZoom ), mMinZoom ) ; + else + newZoom = mDefaultZoom ; + if ( Math.Abs( newZoom - mCurrZoom) > 0.001 ) { + ILog logger = LogManager.GetLogger( "zoom" ) ; + logger.Info( $"Setting image zoom: {newZoom:0.00}" ) ; + mCurrZoom = newZoom ; + doMainFormResize( clientMousePos ) ; } } diff --git a/src/MainForm.ui.cs b/src/MainForm.ui.cs index 3b9c8c5..cab674c 100644 --- a/src/MainForm.ui.cs +++ b/src/MainForm.ui.cs @@ -118,6 +118,7 @@ public partial class MainForm : Form // FUDGE! On Windows, when we handle Ctrl/Shift-ScrollWheel, Windows still wants to scroll the ChartImage. // To stop this, we disable mouse wheel messages and handle everything ourself :-/ if ( msg.Msg == 0x020A ) { // nb: WM_MOUSEWHEEL + // figure out how much to scroll ulong wParam = (ulong)msg.WParam & 0xFFFFFFFF ; int nLines = (int)( wParam >> 16 ) ; if ( (nLines & 0x8000) != 0 ) @@ -125,8 +126,18 @@ public partial class MainForm : Form nLines = nLines * SystemInformation.MouseWheelScrollLines / 120 ; if ( (wParam & 0xFFFF) == 0 ) nLines = - nLines ; // nb: no virtual keys are down - this.scrollMainForm( nLines ) ; - return true ; + // scroll the main form + Point pos = Cursor.Position ; + pos = mChartImagePanel.PointToClient( pos ) ; + if ( pos.X >= 0 && pos.X < mChartImagePanel.Width && pos.Y >= 0 && pos.Y < mChartImagePanel.Height ) { + if ( (Control.ModifierKeys & Keys.Shift) != 0 ) + scrollMainForm( nLines, true ) ; + else if ( (Control.ModifierKeys & Keys.Control) != 0 ) + adjustZoom( (nLines > 0) ? +0.05 : -0.05, pos ) ; + else + scrollMainForm( nLines, false ) ; + return true ; + } } return false ; } @@ -141,8 +152,8 @@ public partial class MainForm : Form Keys modifierKeys = Control.ModifierKeys & (Keys.Control | Keys.Shift | Keys.Alt) ; Keys keyCode = keyData & ~(Keys.Control | Keys.Shift | Keys.Alt) ; - // check for special keypresses - if ( keyCode == Keys.Left || keyCode == Keys.Right ) { + // handle search result selection + if ( (keyData & Keys.Control) == 0 && (keyCode == Keys.Left || keyCode == Keys.Right) ) { // send the keypress to the search results // NOTE: We could also respond to Up/Down and scroll the ChartImage vertically, // but that would be confusing, given that Left/Right selects a search result. @@ -164,8 +175,44 @@ public partial class MainForm : Form mDisableProcessCmdKey = false ; return true ; } + + // handle ChartImage zoom and panning + if ( (keyData & Keys.Control) == 0 && (keyCode == Keys.Up || keyCode == Keys.Down) ) { + // FUDGE! Windows seems to be mapping Ctrl-Up/Down to PageUp/Down before even preFilterMessage() + // sees the message. It would nice to be able to scroll the ChartImage using Ctrl-Left/Right/Up/Down, + // but since Ctrl-Left/Right will be rarely used, we can live with doing things like this :-/ + if ( keyCode == Keys.Up ) { + scrollMainForm( -3, false ) ; + return true ; + } + if ( keyCode == Keys.Down ) { + scrollMainForm( +3, false ) ; + return true ; + } + } + if ( (keyData & Keys.Control) != 0 ) { + if ( keyCode == Keys.Add || keyCode == Keys.Oemplus ) { + adjustZoom( +0.05, null ) ; + return true ; + } + if ( keyCode == Keys.Subtract || keyCode == Keys.OemMinus ) { + adjustZoom( -0.05, null ) ; + return true ; + } + if ( keyCode == Keys.D0 ) { + adjustZoom( null, null ) ; + return true ; + } + if ( keyCode == Keys.Left ) { + scrollMainForm( -3, true ) ; + return true ; + } + if ( keyCode == Keys.Right ) { + scrollMainForm( +3, true ) ; + return true ; + } + } if ( keyCode == Keys.PageUp || keyCode == Keys.PageDown ) { - // scroll the ChartImage up/down if ( mChartImagePictureBox.Image == null ) return false ; double ratio = (double)mChartImagePanel.Height / (double)mChartImagePictureBox.Height ; @@ -202,15 +249,18 @@ public partial class MainForm : Form setChartImagePanelScrollPos( scrollX, scrollY ) ; return true ; } + + // check if the user wants to clear the search query if ( keyCode == Keys.Escape ) { - // clear the search query loadSearchResults( null, "", true ) ; return true ; } + + // FUDGE! Stop Windows from beeping :-/ if ( keyCode == Keys.Return ) - return true ; // nb: stop Windows from beeping :-/ + return true ; - // NOTE: The following keypress handling is only done after we've finished initialization. + // NOTE: The remaining keypress handling is only done after we've finished initialization. if ( ! mIsReady ) return false ; @@ -246,8 +296,8 @@ 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 int ChartImagePanel_MaxScrollX() { return Math.Max( 0, mChartImagePanel.HorizontalScroll.Maximum-mChartImagePanel.Width) + 17 ; } + private int ChartImagePanel_MaxScrollY() { return Math.Max( 0, mChartImagePanel.VerticalScroll.Maximum-mChartImagePanel.Height) + 17 ; } private void MainForm_Load( object sender, EventArgs e ) { @@ -394,41 +444,6 @@ public partial class MainForm : Form Cursor.Current = Cursors.Default ; } - private void scrollMainForm( int nLines ) - { - // check if the mouse is over the ChartImage Panel - Point pos = Cursor.Position ; - pos = mChartImagePanel.PointToClient( pos ) ; - if ( pos.X < 0 || pos.X >= mChartImagePanel.Width || pos.Y < 0 || pos.Y >= mChartImagePanel.Height ) - return ; - if ( (Control.ModifierKeys & Keys.Shift) != 0 ) { - // scroll the ChartImage left/right - HScrollProperties hscroll = mChartImagePanel.HorizontalScroll ; - int scrollRange = hscroll.Maximum - hscroll.Minimum ; - int scrollX = hscroll.Value + (int)( scrollRange * nLines/100 ) ; - scrollChartImagePanel( scrollX, null ) ; - } else if ( (Control.ModifierKeys & Keys.Control) != 0 ) { - double newZoom ; - if ( nLines > 0 ) { - newZoom = Math.Min( mCurrZoom+0.05, mMaxZoom ) ; - } else { - newZoom = Math.Max( mCurrZoom-0.05, mMinZoom ) ; - } - if ( Math.Abs( newZoom - mCurrZoom) > 0.001 ) { - ILog logger = LogManager.GetLogger( "zoom" ) ; - logger.Info( $"Setting image zoom: {newZoom:0.00}" ) ; - mCurrZoom = newZoom ; - doMainFormResize( pos ) ; - } - } else { - // scroll the ChartImage up/down - VScrollProperties vscroll = mChartImagePanel.VerticalScroll ; - int scrollRange = vscroll.Maximum - vscroll.Minimum ; - int scrollY = vscroll.Value + (int)( scrollRange * nLines/100 ) ; - scrollChartImagePanel( null, scrollY ) ; - } - } - private void scrollChartImagePanel( int? scrollX, int? scrollY ) { // update the scroll position @@ -462,7 +477,7 @@ public partial class MainForm : Form } ILog logger = LogManager.GetLogger( "zoom" ) ; logger.Info( $"Setting initial image zoom: {userZoom:0.00} (min={minZoom:0.00}, max={maxZoom:0.00})" ) ; - mCurrZoom = userZoom ; + mCurrZoom = mDefaultZoom = userZoom ; mMinZoom = minZoom ; mMaxZoom = maxZoom ;