Added the ability to select chart images from preview thumbnails.

master
Pacman Ghost 5 years ago
parent 14d2154568
commit f76f4313c1
  1. 1
      .gitignore
  2. 2
      Makefile
  3. 3
      _archive_/ImageListView.txt
  4. BIN
      _archive_/ImageListViewDemo.zip
  5. BIN
      _archive_/ImageListViewSource.zip
  6. BIN
      lib/ImageListView.dll
  7. 14
      src/AppImageListView.cs
  8. 89
      src/MainForm.cs
  9. 131
      src/MainForm.ui.cs

1
.gitignore vendored

@ -1,5 +1,6 @@
app.config
out/
_work_
.vscode/
*.swp

@ -8,9 +8,11 @@ init:
compile:
csc $(SRC) /nologo /warnaserror \
/r:lib/ImageListView.dll \
/d:TRACE \
/target:winexe /out:$(OUTPUT)/asl-charts.exe
cp app.config $(OUTPUT)/asl-charts.exe.config
cp lib/*.dll $(OUTPUT)
clean:
rm -r $(OUTPUT)

@ -0,0 +1,3 @@
https://www.codeproject.com/Articles/43265/ImageListView
Apache License v2.0

Binary file not shown.

Binary file not shown.

Binary file not shown.

@ -0,0 +1,14 @@
using System.Drawing ;
using Manina.Windows.Forms ;
// --------------------------------------------------------------------
public class AppImageListView
{
public class AppImageListViewRenderer : ImageListView.ImageListViewRenderer
{
// NOTE: This disables the large preview image in Gallery mode.
public override void DrawGalleryImage( Graphics g, ImageListViewItem lvi , Image img, Rectangle rc ) {}
}
}

@ -1,78 +1,53 @@
using System ;
using System.Text ;
using System.Drawing ;
using System.IO ;
using System.Runtime.InteropServices ;
using System.Drawing ;
using System.Collections.Generic ;
using System.Windows.Forms ;
using System.Diagnostics ;
using Manina.Windows.Forms ;
// --------------------------------------------------------------------
public class MainForm : Form
public partial class MainForm : Form
{
private readonly HashSet<string> mValidImageExtensions = new HashSet<string>{ ".png", ".jpg", ".gif" } ;
private Dictionary<string,Image> mImages = new Dictionary<string,Image>() ;
private Dictionary<string,Image>.Enumerator mImagesIter ;
private struct ChartImage {
public string mFullPath ;
public Image mImage ;
}
private Dictionary<string,ChartImage> mChartImages = new Dictionary<string,ChartImage>() ;
private SplitContainer mSplitter = new SplitContainer() ;
private UserControl mSearchUserControl = new UserControl() ;
private Label mSearchLabel = new Label() ;
private TextBox mSearchQuery = new TextBox() ;
private ImageListView mSearchResults = new ImageListView() ;
private PictureBox mImagePictureBox = new PictureBox() ;
public MainForm()
{
// initialize the form
this.Text = Program.APP_NAME ;
this.MinimumSize = new Size( 800, 500 ) ;
// initialize the form
// 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.Controls.Add( mImagePictureBox ) ;
// initialize handlers
this.Load += new EventHandler( this.MainForm_Load ) ;
this.KeyDown += new System.Windows.Forms.KeyEventHandler( this.MainForm_KeyDown ) ;
}
private void MainForm_Load( object sender, EventArgs args )
{
// locate the image files
string dataDir = Path.GetFullPath( Program.dataDir ) ;
IEnumerable<string> files = Directory.EnumerateFiles(
dataDir, "*.*", SearchOption.AllDirectories
) ;
foreach( string fname in files ) {
string extn = Path.GetExtension( fname ).ToLower() ;
if ( ! mValidImageExtensions.Contains( extn ) )
continue ;
string fname2 = Path.GetFullPath( fname ) ;
if ( fname2.StartsWith( dataDir ) ) {
fname2 = fname.Substring( dataDir.Length ) ;
if ( fname2.StartsWith( "/" ) || fname2.StartsWith( "\\" ) )
fname2 = fname2.Substring( 1 ) ;
} else {
// NOTE: I don't think we should ever get here :-/ If we do, the user will have to manage
// their configuration using full paths for the image files, but at least we will still run...
}
Program.logTraceMsg( String.Format( "Loading image: {0}", fname2 ) ) ;
mImages[ fname2 ] = Image.FromFile( fname ) ;
}
mImagesIter = mImages.GetEnumerator() ;
InitializeComponent() ;
}
private void MainForm_KeyDown( object sender, KeyEventArgs args )
private void loadSearchResults( Dictionary<string,ChartImage>.Enumerator iter )
{
// FIXME! For now, we just allow the user to cycle through the loaded images.
if ( args.KeyCode == Keys.Space ) {
// show the next image
KeyValuePair<String,Image> val ;
if ( ! mImagesIter.MoveNext() ) {
mImagesIter = mImages.GetEnumerator() ;
mImagesIter.MoveNext() ;
}
val = mImagesIter.Current ;
mImagePictureBox.Image = val.Value ;
// clear the search results
mSearchResults.SuspendLayout() ;
foreach( var item in mSearchResults.SelectedItems )
mSearchResults.Items.Remove( item ) ;
// load the search results
int nItems = 0 ;
while ( iter.MoveNext() ) {
ChartImage chartImage = iter.Current.Value ;
ImageListViewItem item = new ImageListViewItem( chartImage.mFullPath ) ;
item.Tag = chartImage ;
item.Text = Path.GetFileNameWithoutExtension( chartImage.mFullPath ) ;
mSearchResults.Items.Add( item ) ;
if ( nItems++ == 0 )
item.Selected = true ;
}
mSearchResults.ResumeLayout( true ) ;
}
}

@ -0,0 +1,131 @@
using System ;
using System.Text ;
using System.Drawing ;
using System.IO ;
using System.Runtime.InteropServices ;
using System.Collections.Generic ;
using System.Windows.Forms ;
using System.Diagnostics ;
using Manina.Windows.Forms ;
// --------------------------------------------------------------------
public partial class MainForm : Form
{
private void InitializeComponent()
{
// initialize the form
this.Text = Program.APP_NAME ;
this.MinimumSize = new Size( 800, 500 ) ;
// initialize the main splitter
this.mSplitter.Orientation = Orientation.Horizontal ;
this.mSplitter.Location = new Point( 0, 0 ) ;
this.mSplitter.Size = new Size( this.Width, this.Height ) ;
this.mSplitter.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Bottom | AnchorStyles.Right ;
this.mSplitter.FixedPanel = FixedPanel.Panel1 ;
this.mSplitter.Panel1MinSize = 140 ;
this.mSplitter.Panel2MinSize = 300 ;
this.mSplitter.SplitterDistance = this.mSplitter.Panel1MinSize ;
this.mSplitter.Panel1.BackColor = Color.White ;
this.mSplitter.Panel2.BackColor = Color.White ;
this.mSplitter.BackColor = SystemColors.Control ;
this.mSplitter.SplitterWidth = 2 ;
this.Controls.Add( mSplitter ) ;
// initialize the top pane (search)
int margin = 2 ;
this.mSearchUserControl.Size = new Size( 100, mSplitter.Panel1.Size.Height ) ;
this.mSearchLabel.Location = new Point( margin, margin ) ;
this.mSearchLabel.Size = new Size( mSearchUserControl.Width - 2*margin, 15 ) ;
this.mSearchLabel.Font = new Font( mSearchLabel.Font, FontStyle.Bold ) ;
this.mSearchLabel.Text = "Search for:" ;
this.mSearchUserControl.Controls.Add( mSearchLabel ) ;
this.mSearchQuery.Location = new Point( margin, mSearchLabel.Location.Y + mSearchLabel.Height ) ;
this.mSearchQuery.Width = mSearchLabel.Width ;
this.mSearchQuery.BorderStyle = BorderStyle.FixedSingle ;
this.mSearchUserControl.Controls.Add( mSearchQuery ) ;
this.mSplitter.Panel1.Controls.Add( mSearchUserControl ) ;
this.mSearchResults.View = Manina.Windows.Forms.View.Gallery ;
this.mSearchResults.SetRenderer( new AppImageListView.AppImageListViewRenderer() ) ;
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 ) ;
this.mSearchResults.Size = searchResultsSize ;
this.mSearchResults.BorderStyle = BorderStyle.None ;
this.mSearchResults.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right | AnchorStyles.Bottom ;
this.mSplitter.Panel1.Controls.Add( mSearchResults ) ;
this.mSearchResults.Size = searchResultsSize ; // FUDGE! need to do this again :shrug:
// 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 ) ;
// initialize handlers
this.Load += new EventHandler( this.MainForm_Load ) ;
this.mSearchQuery.KeyDown += new System.Windows.Forms.KeyEventHandler( this.SearchQuery_KeyDown ) ;
this.mSearchResults.KeyPress += new System.Windows.Forms.KeyPressEventHandler( this.SearchResults_KeyPress ) ;
this.mSearchResults.SelectionChanged += new EventHandler( this.SearchResults_SelectionChanged ) ;
}
private void MainForm_Load( object sender, EventArgs e )
{
// locate the image files
string dataDir = Path.GetFullPath( Program.dataDir ) ;
IEnumerable<string> files = Directory.EnumerateFiles(
dataDir, "*.*", SearchOption.AllDirectories
) ;
foreach( string fname in files ) {
string extn = Path.GetExtension( fname ).ToLower() ;
if ( ! mValidImageExtensions.Contains( extn ) )
continue ;
string key ;
string fullPath = Path.GetFullPath( fname ) ;
if ( fullPath.StartsWith( dataDir ) ) {
key = fname.Substring( dataDir.Length ) ;
if ( key.StartsWith( "/" ) || key.StartsWith( "\\" ) )
key = key.Substring( 1 ) ;
} else {
// NOTE: I don't think we should ever get here :-/ If we do, the user will have to manage
// their configuration using full paths for the image files, but at least we will still run...
key = fullPath ;
}
Program.logTraceMsg( String.Format( "Loading image: {0}", key ) ) ;
mChartImages[ key ] = new ChartImage{ mFullPath=fullPath, mImage=Image.FromFile(fname) } ;
}
// load the images into the search results
loadSearchResults( mChartImages.GetEnumerator() ) ;
}
private void SearchResults_SelectionChanged( object sender, EventArgs e )
{
// show the selected chart image
Debug.Assert( mSearchResults.SelectedItems.Count == 1 ) ;
ChartImage chartImage = (ChartImage) mSearchResults.SelectedItems[0].Tag ;
mImagePictureBox.Image = chartImage.mImage ;
}
private void SearchQuery_KeyDown( object sender, KeyEventArgs e )
{
// check if we should apply the keypress to the search results
if ( e.KeyCode == Keys.Left || e.KeyCode == Keys.Right ) {
mSearchResults.Focus() ;
SendKeys.SendWait( "{" + e.KeyCode.ToString() + "}" ) ;
mSearchQuery.Focus() ;
e.Handled = true ;
}
}
private void SearchResults_KeyPress( object sender, KeyPressEventArgs e )
{
// check if we should apply the keypress to the search query
int ch = (int) e.KeyChar ;
if ( ch >= 32 && ch < 127 ) {
mSearchQuery.AppendText( e.KeyChar.ToString() ) ;
mSearchQuery.Focus() ;
}
}
}
Loading…
Cancel
Save