Compare commits

...

4 Commits
v0.1 ... master

  1. 1
      .gitignore
  2. 7
      README.md
  3. BIN
      doc/air.png
  4. BIN
      doc/bog.png
  5. BIN
      doc/home.png
  6. 4
      make_release.py
  7. 3
      src/MainForm.cs
  8. 34
      src/MainForm.ui.cs
  9. 24
      src/Shortcut.cs

1
.gitignore vendored

@ -1,6 +1,7 @@
log4net.xml
out/
_work_/
_releases_/
.vscode/
*.swp

@ -2,6 +2,13 @@
This program lets you manage your ASL charts, play-aids, and other documents, and provides quick access to them as you play your game.
[<img src="doc/home.png" height="150">](doc/home.png)
&nbsp;
[<img src="doc/bog.png" height="150">](doc/bog.png)
&nbsp;
[<img src="doc/air.png" height="150">](doc/air.png)
</a>
It's written using .NET, so if you're on a recent version of Windows, it should Just Work<sup><small>&trade;</small></sup>; Linux and Mac users will need to use Mono (but see below). Simply unpack the release ZIP file somewhere, then run `asl-charts.exe`.
For demonstration purposes, the program comes with the tables from Ole B&oslash;e’s Quick Reference Data Card pre-installed. Type something into the search box e.g. _"cc"_ or _"tk"_, and the corresponding tables will be shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 261 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 169 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 85 KiB

@ -2,6 +2,7 @@
import sys
import os
import stat
import subprocess
import zipfile
import getopt
@ -41,6 +42,9 @@ with zipfile.ZipFile( output_fname, "w" ) as zip_file:
# add the binaries
os.chdir( "out" )
for fname in os.listdir( "." ):
if os.path.splitext( fname )[1] == ".exe":
flags = os.stat( fname ).st_mode
os.chmod( fname, flags | stat.S_IEXEC )
zip_file.write( fname )
os.chdir( ".." )
# add the license

@ -210,6 +210,9 @@ public partial class MainForm : Form
// clear the search query
if ( clearSearchQuery )
setSearchQuery( "", false ) ;
// reset the repeated shortkey
Shortcut.resetLastShortcut() ;
}
public void showShortcuts()

@ -157,22 +157,7 @@ public partial class MainForm : Form
// 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.
if ( mSearchResults.Items.Count > 1 && mSearchResults.SelectedItems.Count > 0 ) {
// check for wrap-around
ImageListViewItem selItem = mSearchResults.SelectedItems[0] ;
if ( keyCode == Keys.Left && Object.ReferenceEquals( selItem, mSearchResults.Items[0] ) ) {
mSearchResults.setSelection( mSearchResults.Items.Count-1 ) ;
return true ;
}
if ( keyCode == Keys.Right && Object.ReferenceEquals( selItem, mSearchResults.Items[mSearchResults.Items.Count-1] ) ) {
mSearchResults.setSelection( 0 ) ;
return true ;
}
}
mSearchResults.Focus() ;
mDisableProcessCmdKey = true ;
SendKeys.SendWait( "{" + keyCode.ToString() + "}" ) ;
mDisableProcessCmdKey = false ;
selectSearchResult( keyCode ) ;
return true ;
}
@ -296,6 +281,23 @@ public partial class MainForm : Form
return false ;
}
public void selectSearchResult( Keys keyCode )
{
if ( mSearchResults.Items.Count == 0 )
return ;
int selIndex = 0 ;
if ( mSearchResults.SelectedItems.Count > 0 ) {
ImageListViewItem selItem = mSearchResults.SelectedItems[0] ;
if ( keyCode == Keys.Left )
selIndex = (selItem.Index > 0) ? selItem.Index-1 : mSearchResults.Items.Count-1 ;
else if ( keyCode == Keys.Right )
selIndex = (selItem.Index < mSearchResults.Items.Count-1) ? selItem.Index+1 : 0 ;
else
Debug.Assert( false, $"Unexpected keyCode: {keyCode}" ) ;
}
mSearchResults.setSelection( selIndex ) ;
}
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 ; }

@ -12,6 +12,8 @@ public abstract class Shortcut
{
private static Dictionary<Keys,Shortcut> mRegisteredShortcuts = new Dictionary<Keys,Shortcut>() ;
private static Shortcut mLastShortcut = null ;
private static DateTime mLastShortcutTimestamp = DateTime.Now ;
private Keys mKeys ;
@ -52,13 +54,33 @@ public abstract class Shortcut
if ( shortcut == null )
return false ;
// found one - execute it
// found one - check if it's the same as the last shortcut used
ILog logger = LogManager.GetLogger( "shortcuts" ) ;
if ( mLastShortcut != null && Object.ReferenceEquals( shortcut, mLastShortcut ) ) {
// yup - check how much time has passed since the last shortcut was used
TimeSpan delta = DateTime.Now - mLastShortcutTimestamp ;
double cutoff = Program.appConfig.getDoubleVal( new string[]{"ShortcutRepeatThreshold"}, 5 ) ;
logger.Debug( $"Repeated shortcut: {mLastShortcut} ; delta={delta.TotalSeconds} ; cutoff={cutoff}" ) ;
if ( delta.TotalSeconds <= cutoff ) {
// less than the threshold - select the next search result instead
logger.Debug( "- Selecting next search result instead." ) ;
Program.mainForm.selectSearchResult( Keys.Right ) ;
mLastShortcutTimestamp = DateTime.Now ;
return true ;
}
}
logger.Info( $"Executing shortcut: {shortcut}" ) ;
shortcut.executeShortcut() ;
mLastShortcut = shortcut ;
mLastShortcutTimestamp = DateTime.Now ;
return true ;
}
public static void resetLastShortcut()
{
mLastShortcut = null ;
}
public static void registerShortcut( Shortcut shortcut )
{
// register the shortcut

Loading…
Cancel
Save