Added the ability to search captions.

master
Pacman Ghost 5 years ago
parent f76f4313c1
commit 7483504e6d
  1. 1
      Makefile
  2. BIN
      _archive_/Json120r2.zip
  3. 44
      data/config.json
  4. BIN
      lib/Newtonsoft.Json.dll
  5. 38
      src/ChartImage.cs
  6. 34
      src/JsonConfig.cs
  7. 59
      src/MainForm.cs
  8. 57
      src/MainForm.ui.cs
  9. 6
      src/Program.cs

@ -8,6 +8,7 @@ init:
compile:
csc $(SRC) /nologo /warnaserror \
/r:lib/Newtonsoft.Json.dll \
/r:lib/ImageListView.dll \
/d:TRACE \
/target:winexe /out:$(OUTPUT)/asl-charts.exe

Binary file not shown.

@ -1 +1,43 @@
{}
{
"IIFTMQRDCc/leader-creation.png": {
"caption": "Leader Creation"
},
"IIFTMQRDCc/close-combat.png": {
"caption": "Close Combat"
},
"IIFTMQRDCc/heat-to-kill.png": {
"caption": "HEAT To Kill"
},
"IIFTMQRDCc/iift.png": {
"caption": "Incremental IFT"
},
"IIFTMQRDCc/ap-to-kill.png": {
"caption": "AP To Kill"
},
"IIFTMQRDCc/afv-destruction.png": {
"caption": "AFV Destruction"
},
"IIFTMQRDCc/ambush.png": {
"caption": "Ambush"
},
"IIFTMQRDCc/heat-of-battle.png": {
"caption": "Heat Of Battle"
},
"IIFTMQRDCc/apcr-apds-to-kill.png": {
"caption": "APCR/APDS To Kill"
},
"IIFTMQRDCc/to-hit.png": {
"caption": "To Hit"
}
}

Binary file not shown.

@ -0,0 +1,38 @@
using System.IO ;
using System.Drawing ;
using Manina.Windows.Forms ;
// --------------------------------------------------------------------
public class ChartImage
{
private string mFullPath ;
private dynamic mConfig ;
private Image mImage ;
private ImageListViewItem mImageListViewItem ;
public ChartImage( string key, string fullPath )
{
mFullPath = fullPath ;
mConfig = Program.dataConfig.data[ key ] ;
mImage = Image.FromFile( fullPath ) ;
// NOTE: Thumbnails are cached by ImageListViewItem GUID, so we reuse these objects,
// instead of creating new ones every time we reload the search results.
mImageListViewItem = new ImageListViewItem( fullPath ) ;
mImageListViewItem.Tag = this ;
mImageListViewItem.Text = caption() ;
}
public string caption()
{
string caption = (mConfig != null) ? mConfig["caption"] : null ;
if ( caption == null )
caption = Path.GetFileNameWithoutExtension( mFullPath ) ;
return caption ;
}
public Image image { get { return mImage ; } }
public ImageListViewItem imageListViewItem { get { return mImageListViewItem ; } }
}

@ -1,16 +1,13 @@
using System ;
using System.Text ;
using System.IO ;
using System.Runtime.Serialization.Json ;
using System.Xml ;
using System.Xml.Linq ;
using System.Xml.XPath ;
using Newtonsoft.Json ;
// --------------------------------------------------------------------
public class JsonConfig
{
private XElement mRootElem ;
private dynamic mData ;
public JsonConfig( string caption, string fname )
{
@ -21,29 +18,8 @@ public class JsonConfig
data = File.ReadAllText( fname ) ;
} else
data ="{}" ;
var jsonReader = JsonReaderWriterFactory.CreateJsonReader(
Encoding.UTF8.GetBytes( data ),
new XmlDictionaryReaderQuotas()
) ;
mRootElem = XElement.Load( jsonReader ) ;
}
public string getStringVal( string xpath, string defaultVal="" )
{
// return the specified value
var elem = mRootElem.XPathSelectElement( xpath ) ;
if ( elem == null )
return defaultVal ;
return elem.Value ;
mData = JsonConvert.DeserializeObject( data ) ;
}
public int getIntVal( string xpath, int defaultVal=0 )
{
// return the specified value
try {
return Int32.Parse( getStringVal( xpath ) ) ;
} catch( System.FormatException ) {
return defaultVal ;
}
}
public dynamic data { get { return mData ; } }
}

@ -1,5 +1,5 @@
using System ;
using System.IO ;
using System.Drawing ;
using System.Collections.Generic ;
using System.Windows.Forms ;
@ -11,10 +11,6 @@ public partial class MainForm : Form
{
private readonly HashSet<string> mValidImageExtensions = new HashSet<string>{ ".png", ".jpg", ".gif" } ;
private struct ChartImage {
public string mFullPath ;
public Image mImage ;
}
private Dictionary<string,ChartImage> mChartImages = new Dictionary<string,ChartImage>() ;
private SplitContainer mSplitter = new SplitContainer() ;
@ -30,20 +26,57 @@ public partial class MainForm : Form
InitializeComponent() ;
}
private void loadSearchResults( Dictionary<string,ChartImage>.Enumerator iter )
private void loadChartImages()
{
// locate the chart images
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( key, fullPath ) ;
}
}
private void updateSearchResults( string searchQuery )
{
// search for matching chart images
List<ChartImage> results = new List<ChartImage>() ;
searchQuery = searchQuery.ToLower() ;
foreach ( ChartImage chartImage in mChartImages.Values ) {
if ( chartImage.caption().ToLower().IndexOf( searchQuery ) >= 0 )
results.Add( chartImage ) ;
}
loadSearchResults( results ) ;
}
private void loadSearchResults( IEnumerable<ChartImage> chartImages )
{
// clear the search results
mSearchResults.SuspendLayout() ;
foreach( var item in mSearchResults.SelectedItems )
mSearchResults.Items.Remove( item ) ;
mSearchResults.Items.Clear() ;
mSearchResults.ResumeLayout( true ) ;
// load the search results
mSearchResults.SuspendLayout() ;
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 ) ;
foreach( ChartImage chartImage in chartImages ) {
ImageListViewItem item = chartImage.imageListViewItem ;
mSearchResults.Items.Add( item ) ;
if ( nItems++ == 0 )
item.Selected = true ;

@ -49,6 +49,7 @@ public partial class MainForm : Form
this.mSplitter.Panel1.Controls.Add( mSearchUserControl ) ;
this.mSearchResults.View = Manina.Windows.Forms.View.Gallery ;
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 ) ;
this.mSearchResults.Size = searchResultsSize ;
@ -65,53 +66,43 @@ public partial class MainForm : Form
// 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.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 ) ;
}
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() ) ;
// load the chart images
loadChartImages() ;
loadSearchResults( mChartImages.Values ) ;
}
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 ;
ChartImage chartImage ;
if ( mSearchResults.SelectedItems.Count > 0 ) {
chartImage = (ChartImage) mSearchResults.SelectedItems[0].Tag ;
mImagePictureBox.Image = chartImage.image ;
} else
mImagePictureBox.Image = null ;
}
private void SearchQuery_TextChanged( object sender, EventArgs e )
{
// update the search results
updateSearchResults( mSearchQuery.Text.Trim() ) ;
}
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 ) {
if ( e.KeyCode == Keys.Escape )
mSearchQuery.Text = "" ;
else if ( e.KeyCode == Keys.Left || e.KeyCode == Keys.Right ) {
mSearchResults.Focus() ;
SendKeys.SendWait( "{" + e.KeyCode.ToString() + "}" ) ;
mSearchQuery.Focus() ;
@ -123,7 +114,9 @@ public partial class MainForm : Form
{
// check if we should apply the keypress to the search query
int ch = (int) e.KeyChar ;
if ( ch >= 32 && ch < 127 ) {
if ( ch == 27 )
mSearchQuery.Text = "" ;
else if ( ch >= 32 && ch < 127 ) {
mSearchQuery.AppendText( e.KeyChar.ToString() ) ;
mSearchQuery.Focus() ;
}

@ -11,7 +11,7 @@ public static class Program
private static string mBaseDir ;
private static string mDataDir ;
private static JsonConfig mAppConfig = null ;
private static JsonConfig mDataConfig = null ;
private static JsonConfig mDebugConfig = null ;
private static MainForm mMainForm = null ;
@ -34,7 +34,7 @@ public static class Program
// load the app config
// NOTE: It would be nice to be able to load the app config from another location, but it seems
// we need to create a new AppDomain to do this, and it doesn't work with Mono :-/
mAppConfig = new JsonConfig( "app config", Path.Combine( mDataDir, "config.json" ) ) ;
mDataConfig = new JsonConfig( "data config", Path.Combine( mDataDir, "config.json" ) ) ;
// load the debug config
mDebugConfig = new JsonConfig( "debug config", Path.Combine( mBaseDir, "debug.json" ) ) ;
@ -61,7 +61,7 @@ public static class Program
Trace.WriteLine( DateTime.Now.ToString("HH:mm:ss") + " | " + msg ) ;
}
public static JsonConfig appConfig { get { return mAppConfig ; } }
public static JsonConfig dataConfig { get { return mDataConfig ; } }
public static JsonConfig debugConfig { get { return mDebugConfig ; } }
public static string dataDir { get { return mDataDir ; } }
}

Loading…
Cancel
Save