KSPEditor Example Source and PreCompiled Application - Uses .NET 4.0. Runs on WindowsXP SP3, Vista, 7 and 8.

The KSPEditor is an evolving example and starting point template for developers desiring to make a WPF based application using KerbalData. The API usage examples contained in this application are relevant to any desired use of the API, not just WPF.

KSPEditor uses the default Visual Studio 2012 template for a WPF4 project with no real modification to the base setup. The project includes the DelegateCommand package from Nuget for handling events from the UI.

The WPF application is developed using the http://msdn.microsoft.com/en-us/magazine/dd419663.aspx pattern. This means there is no code behind for the XAML file.

The project consists of the following files:
  • MainWindow.xaml - UI
  • MainWindowViewModel.cs - Wireup of UI to KerbalData
  • VisibilityConverter.cs - Simple class to assist in UI operations

The file of most interest is the MainWindowViewModel.cs. This file is setup like most view models with a number of exposed public properties that the UI binds to.

KerbalData is being designed to be developer friendly, while attempting to give plenty of control and options. In the KSPEditor example the Consumer API is used. This top level API is the easiest to use, requires the least code and provides features needed in most applications.

NOTE: For full code download the example with source.
public class MainWindowViewModel : INotifyPropertyChanged
{
        // Internal reference to KerbalData API
        private KerbalData kerbalData;

        // Internal references for public properties (not shown)
        private SaveFile save;
        private SaveFile scenario;
        private SaveFile trainingScenario;
        private CraftFile vabCraft;
        private CraftFile sphCraft;
        private PartFile part;
        private ConfigFile setting;

        // This method is called when the UI updates
        private void UpdateInstallPath()
        {
            // Clear out current KerbalData instance
            KerbalData = null;

            // Create new instance. Only an install location is required.
            KerbalData = new KerbalData(installPath);
        }
      
        // This method handles selecting a file and loading it. Values are 
        // provided by the drop downs in the UI. No other code to expose 
        // KSP data is used in the ViewModel. 
        private void OnPropertyChanged(string name, object value = null)
        {
            switch (name)
            {
                case PropNameSelectedSave:
                    Save = 
                         kerbalData.Saves[SelectedSave];
                    break;
                case PropNameSelectedScenario:
                    Scenario = 
                         kerbalData.Scenarios[SelectedScenario];
                    break;
                case PropNameSelectedTrainingScenario:
                    TrainingScenario = 
                         kerbalData.TrainingScenarios[SelectedTrainingScenario];
                    break;
                case PropNameSelectedVabCraft:
                    VabCraft = 
                         kerbalData.CraftInVab[SelectedVabCraft];
                    break;
                case PropNameSelectedSphCraft:
                    SphCraft = 
                         kerbalData.CraftInSph[SelectedSphCraft];
                    break;
                case PropNameSelectedPart:
                    Part = 
                         kerbalData.Parts[SelectedPart];
                    break;
                case PropNameSelectedSetting:
                    Setting = 
                          kerbalData.KspSettings[SelectedSetting];
                    break;
            }   
        }
}

The view itself handles all the mapping of data fields in KerbalData objects to the UI objects. The XAML file is broken into 2 sections. The top portion (not shown here) handles the UI controls that the end user will interact with. The general workflow of the application is:
  1. Application Launch
  2. User Enters Install path (by hand, or by using Open button to select a folder)
  3. KerbalData is loaded and install path is scanned for files
  4. Files are listed in drop downs for user
  5. User selects a file
  6. File loads and associated grid exposed

Each major type has a UI grid of it's own, tailored to the data for that object.

NOTE: Attributes/Tags not relevant to surfacing data omitted, Download example for full source.

Save
<Grid>
  <Label Content="{Binding Path=SelectedSave}" />
  <Label Content="{Binding Path=Save.Game.Title}"/>
  <Label Content="{Binding Path=Save.Game.Description}"/>
  <Label Content="{Binding Path=Save.Game.Version}"/>
  <Label Content="Game Time Elapsed" />
  <Label Content="{Binding Path=Save.Game.FlightState.UniverseTime}"/>
  <Grid>
    <DataGrid ItemsSource="{Binding Save.Game.FlightState.Crew}">
      <DataGrid.Columns>
	<DataGridTextColumn  Header="Name" Binding="{Binding Path=Name}"/>
	<DataGridTextColumn Header="Brave" Binding="{Binding Path=Brave}"/>
        <DataGridTextColumn Header="Dumb" Binding="{Binding Path=Dumb}"/>
      </DataGrid.Columns>
    </DataGrid>
  </Grid>            	
  <Grid>
    <DataGrid 
        Name="saveCrew" ItemsSource="{Binding Save.Game.FlightState.Vessels}">
      <DataGrid.Columns>
	<DataGridTextColumn 
          Header="Name" Binding="{Binding Path=Name}"/>
	<DataGridTextColumn 
          Header="Type" Binding="{Binding Path=Type}"/>
	<DataGridTextColumn 
          Header="Status" Binding="{Binding Path=Situation}"/>
	<DataGridTextColumn 
          Header="Body" Binding="{Binding Path=Orbit.Body}"/>
	<DataGridTextColumn 
          Header="MET" Binding="{Binding Path=MissionElapsedTime}"/>
        <DataGridTextColumn
          Header="# Parts" Binding="{Binding Path=Parts.Count}"/>
      </DataGrid.Columns>
    </DataGrid>
  </Grid>
</Grid>

The scenario and training scenario XAML entries are nearly identical to the save file XAML. The only difference is binding to Scenario or TrainingScenario instead of Save.

Craft in VAB
<Grid>
  <Label Style="{StaticResource TitleText}"/>
  <Label Content="{Binding Path=VabCraft.Ship}"/>
  <Label Content="{Binding Path=VabCraft.Type}"/>
  <Label Content="{Binding Path=VabCraft.Version}"/>
  <Grid>
    <DataGrid ItemsSource="{Binding VabCraft.Parts}">
      <DataGrid.Columns>
        <DataGridTextColumn 
          Header="Name" Binding="{Binding Path=Part}"/>                        
        <DataGridTextColumn 
          Header="Type" Binding="{Binding Path=Name}"/>
        <DataGridTextColumn 
          Header="Module Count" Binding="{Binding Path=Modules.Count}"/>
        <DataGridTextColumn 
          Header="Resource Count" Binding="{Binding Path=Resources.Count}"/>
        <DataGridTextColumn 
          Header="Action Count" Binding="{Binding Path=Actions.Count}"/>
        <DataGridTextColumn 
          Header="Event Count" Binding="{Binding Path=Events.Count}"/>
      </DataGrid.Columns>
    </DataGrid>
</Grid>

Parts
<Grid>
  <Label Content="{Binding Path=Part.Name}"/>
  <Label Content="{Binding Path=Part.Description}"/>
  <Label Content="{Binding Path=Part.Author}"/>
  <Label Content="{Binding Path=Part.Category}"/>
  <Label Content="{Binding Path=Part.Mesh}"/>
  <Label Content="{Binding Path=Part.Cost}" />
  <Label Content="{Binding Path=Part.Mass}"/>
  <Label Content="{Binding Path=Part.Manufacturer}"/>
  <Label Content="{Binding Path=Part.CrashTolerance}"/>
</Grid>

Last edited Jan 24, 2013 at 5:58 AM by Manitcor, version 10

Comments

No comments yet.