Added the ability to pan chart images.

master
Pacman Ghost 5 years ago
parent c87b7fcf9e
commit 8e79563419
  1. 7
      src/MainForm.cs
  2. 176
      src/MainForm.ui.cs
  3. 20
      src/Program.cs

@ -1,5 +1,6 @@
using System ;
using System.IO ;
using System.Drawing ;
using System.Collections.Generic ;
using System.Windows.Forms ;
@ -19,7 +20,11 @@ public partial class MainForm : Form
private Label mSearchLabel = new Label() ;
private TextBox mSearchQuery = new TextBox() ;
private ImageListView mSearchResults = new ImageListView() ;
private PictureBox mImagePictureBox = new PictureBox() ;
private Panel mChartImagePanel = new Panel() ;
private PictureBox mChartImagePictureBox = new PictureBox() ;
private Point? mMouseDragAnchor = null ;
private Tuple<int,int> mScrollDragAnchor ;
public MainForm()
{

@ -52,7 +52,7 @@ public partial class MainForm : Form
this.mSearchResults.SetRenderer( new AppImageListView.AppImageListViewRenderer() ) ;
this.mSearchResults.CacheMode = CacheMode.Continuous ;
this.mSearchResults.Location = new Point( mSearchUserControl.Location.X + mSearchUserControl.Width, margin ) ;
Size searchResultsSize = new Size( mSplitter.Width - (mSearchQuery.Location.X + mSearchQuery.Width) - margin, mSplitter.Panel1MinSize ) ;
Size searchResultsSize = new Size( mSplitter.Width - (mSearchQuery.Location.X + mSearchQuery.Width) - margin - 7, mSplitter.Panel1MinSize ) ;
this.mSearchResults.Size = searchResultsSize ;
this.mSearchResults.BorderStyle = BorderStyle.None ;
this.mSearchResults.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right | AnchorStyles.Bottom ;
@ -61,25 +61,186 @@ public partial class MainForm : Form
// initialize the bottom pane (image viewer)
// FIXME! We will probably need something better to render the images, but this will do, for now...
this.mImagePictureBox.Dock = DockStyle.Fill ;
this.mImagePictureBox.SizeMode = PictureBoxSizeMode.Zoom ;
this.mSplitter.Panel2.Controls.Add( mImagePictureBox ) ;
this.mChartImagePictureBox.SizeMode = PictureBoxSizeMode.Zoom ;
// FUDGE! We need to put the PictureBox inside a Panel in order to get the h-scrollbar to appear :-/
mChartImagePanel.Anchor = AnchorStyles.Top | AnchorStyles.Left ;
mChartImagePanel.AutoScroll = true ;
mChartImagePanel.Controls.Add( mChartImagePictureBox ) ;
mSplitter.Panel2.Controls.Add( mChartImagePanel ) ;
// initialize handlers
this.Load += new EventHandler( this.MainForm_Load ) ;
this.Resize += new EventHandler( this.MainForm_Resize ) ;
this.mSearchQuery.TextChanged += new EventHandler( this.SearchQuery_TextChanged ) ;
this.mSearchQuery.KeyDown += new KeyEventHandler( this.SearchQuery_KeyDown ) ;
this.mSearchResults.KeyPress += new KeyPressEventHandler( this.SearchResults_KeyPress ) ;
this.mSearchResults.SelectionChanged += new EventHandler( this.SearchResults_SelectionChanged ) ;
mChartImagePictureBox.MouseDown += new MouseEventHandler( this.ChartImagePictureBox_MouseDown ) ;
mChartImagePictureBox.MouseMove += new MouseEventHandler( this.ChartImagePictureBox_MouseMove ) ;
mChartImagePictureBox.MouseUp += new MouseEventHandler( this.ChartImagePictureBox_MouseUp ) ;
// NOTE: We also register mouse event handlers for the panel, so that dragging will work if the user clicks
// inside the image panel, but not on the image itself (i.e. when the image is smaller than the panel).
mChartImagePanel.MouseDown += new MouseEventHandler( this.ChartImagePictureBox_MouseDown ) ;
mChartImagePanel.MouseMove += new MouseEventHandler( this.ChartImagePictureBox_MouseMove ) ;
mChartImagePanel.MouseUp += new MouseEventHandler( this.ChartImagePictureBox_MouseUp ) ;
}
public bool preFilterMessage( ref Message msg )
{
// 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
ulong wParam = (ulong)msg.WParam & 0xFFFFFFFF ;
int nLines = (int)( wParam >> 16 ) ;
if ( (nLines & 0x8000) != 0 )
nLines = nLines - 0x10000 ; // nb: negate the 32-bit value
nLines = nLines * SystemInformation.MouseWheelScrollLines / 120 ;
if ( (wParam & 0xFFFF) == 0 )
nLines = - nLines ; // nb: no virtual keys are down
this.scrollMainForm( nLines ) ;
return true ;
}
return false ;
}
private void MainForm_Load( object sender, EventArgs e )
{
// initialize
MainForm_Resize( this, null ) ;
// load the chart images
loadChartImages() ;
loadSearchResults( mChartImages.Values ) ;
}
private void MainForm_Resize( object sender, EventArgs e )
{
// check if we are showing a ChartImage
Image img = mChartImagePictureBox.Image ;
if ( img == null ) {
mChartImagePanel.Visible = false ;
return ;
}
mChartImagePanel.Visible = true ;
// resize the ChartImage panel to fill the available space
mChartImagePanel.Size = new Size(
mSplitter.Panel2.Width - (Program.isMono?8:17),
mSplitter.Panel2.Height - (Program.isMono?28:40)
) ;
// try to size the image to fill the available width
int margin = 5 ;
float aspectRatio = (float)img.Width / (float)img.Height ;
int availableWidth = mChartImagePanel.Width - 2*margin ;
int width = availableWidth ;
int height = (int) (availableWidth / aspectRatio) ;
// check that we're not zooming in/out too much
float zoom = (float)width / (float)img.Width ;
float minZoom = Program.appConfig.getFloatVal( new string[]{"MinZoom"}, 0.5f ) ;
float maxZoom = Program.appConfig.getFloatVal( new string[]{"MaxZoom"}, 2f ) ;
if ( minZoom > 0 && zoom < minZoom ) {
width = (int) (img.Width * minZoom) ;
height = (int) (img.Height * minZoom) ;
} else if ( maxZoom > 0 && zoom > maxZoom ) {
width = (int) (img.Width * maxZoom) ;
height = (int) (img.Height * maxZoom) ;
}
// check if the v-scrollbar is showing
if ( height >= mChartImagePanel.Height ) {
// yup - adjust the width
int sbWidth = SystemInformation.VerticalScrollBarWidth ;
availableWidth -= sbWidth ;
width -= sbWidth ;
}
// 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 :-/
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 ;
}
private void ChartImagePictureBox_MouseDown( object sender, MouseEventArgs e )
{
// flag that the user has started to drag the ChartImage
// FUDGE! The mouse position as reported by the MouseEventArgs bounces around weirdly during mouse move,
// so we read the mouse position directly :shrug:
mMouseDragAnchor = Cursor.Position ;
mScrollDragAnchor = new Tuple<int,int>( mChartImagePanel.HorizontalScroll.Value, mChartImagePanel.VerticalScroll.Value ) ;
Cursor.Current = Cursors.Hand ;
}
private void ChartImagePictureBox_MouseMove( object sender, MouseEventArgs e )
{
// check if a drag is in progress
if ( mMouseDragAnchor == null )
return ;
Point pos = Cursor.Position ;
int deltaX = pos.X - mMouseDragAnchor.Value.X ;
int deltaY = pos.Y - mMouseDragAnchor.Value.Y ;
int scrollX = mScrollDragAnchor.Item1 - deltaX ;
int scrollY = mScrollDragAnchor.Item2 - deltaY ;
scrollChartImagePanel( scrollX, scrollY ) ;
}
private void ChartImagePictureBox_MouseUp( object sender, MouseEventArgs e )
{
// end the drag
mMouseDragAnchor = null ;
mScrollDragAnchor = null ;
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 {
// 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
if ( scrollX != null ) {
HScrollProperties hscroll = mChartImagePanel.HorizontalScroll ;
int maxScrollX = hscroll.Maximum - mChartImagePanel.Width + 17 ;
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 scrollPos = Math.Max( 0, Math.Min( maxScrollY, scrollY.Value ) ) ;
vscroll.Value = scrollPos ;
vscroll.Value = scrollPos ; // nb: for Windows :shrug:
}
}
private void SearchResults_SelectionChanged( object sender, EventArgs e )
{
// show the selected chart image
@ -87,9 +248,12 @@ public partial class MainForm : Form
ChartImage chartImage ;
if ( mSearchResults.SelectedItems.Count > 0 ) {
chartImage = (ChartImage) mSearchResults.SelectedItems[0].Tag ;
mImagePictureBox.Image = chartImage.image ;
mChartImagePictureBox.Image = chartImage.image ;
} else
mImagePictureBox.Image = null ;
mChartImagePictureBox.Image = null ;
mChartImagePanel.HorizontalScroll.Value = 0 ;
mChartImagePanel.VerticalScroll.Value = 0 ;
MainForm_Resize( this, null ) ;
}
private void SearchQuery_TextChanged( object sender, EventArgs e )

@ -9,7 +9,12 @@ using log4net.Config ;
public static class Program
{
private class MyMessageFilter : IMessageFilter {
public bool PreFilterMessage( ref Message msg ) { return Program.preFilterMessage( ref msg ) ; }
}
public const string APP_NAME = "ASL Charts" ;
private static bool mIsMono ;
private static string mBaseDir ;
private static string mDataDir ;
@ -23,6 +28,7 @@ public static class Program
{
// initialize
mBaseDir = Application.StartupPath ;
mIsMono = Type.GetType( "Mono.Runtime" ) != null ;
// configure logging
string fname = Path.Combine( mBaseDir, "log4net.xml" ) ;
@ -62,6 +68,9 @@ public static class Program
return ;
}
// install our message filter
Application.AddMessageFilter( new MyMessageFilter() ) ;
// run the application
Application.EnableVisualStyles() ;
Application.SetCompatibleTextRenderingDefault( false ) ;
@ -69,10 +78,21 @@ public static class Program
Application.Run( mMainForm ) ;
}
public static bool preFilterMessage( ref Message msg )
{
// check if we should filter this message
if ( Program.mainForm.preFilterMessage( ref msg ) )
return true ;
return false ;
}
public static void showInfoMsg( string msg ) { MessageBox.Show(msg,APP_NAME,MessageBoxButtons.OK,MessageBoxIcon.Information) ; }
public static void showWarningMsg( string msg ) { MessageBox.Show(msg,APP_NAME,MessageBoxButtons.OK,MessageBoxIcon.Warning) ; }
public static void showErrorMsg( string msg ) { MessageBox.Show(msg,APP_NAME,MessageBoxButtons.OK,MessageBoxIcon.Error) ; }
public static bool isMono { get { return mIsMono ; } }
public static MainForm mainForm { get { return mMainForm ; } }
public static JsonConfig appConfig { get { return mAppConfig ; } }
public static JsonConfig dataConfig { get { return mDataConfig ; } }
public static JsonConfig debugConfig { get { return mDebugConfig ; } }

Loading…
Cancel
Save