diff --git a/SpritePacker-GUI/ListView.cs b/SpritePacker-GUI/ListView.cs
new file mode 100644
index 0000000..21c2442
--- /dev/null
+++ b/SpritePacker-GUI/ListView.cs
@@ -0,0 +1,131 @@
+﻿using System;
+using System.Collections.Generic;
+using Gtk;
+
+namespace SilentorBit
+{
+	/// <summary>
+	/// <para>A single column list, text comes from object.ToString()</para>
+	/// <para>For multicolumns, see ListView&lt;ClassType&gt;</para>
+	/// <para>By SilentorBit from https://silentorbit.com/notes/2011/05/gtk-sharp-listview/</para>
+	/// </summary>
+	public class ListView : ListView<object>
+	{
+		public ListView (string columnTitle) : base(columnTitle)
+		{
+		}
+
+		protected override void RenderCell (CellRendererText render, int index, object item)
+		{
+			render.Text = item.ToString ();
+		}
+	}
+
+	/// <summary>
+	/// The list only contains one type of object.
+	/// To get multiple columns, pass that number of parameters to the constructor
+	/// and implement RenderCell accordingly.
+	/// </summary>
+	public abstract class ListView<T> : TreeView
+	{
+		/// <summary>
+		/// List of all items selected
+		/// </summary>
+		public T[] SelectedItems { get; private set; }
+		public event Action<T[]> ItemSelected;
+		public event Action<T> ItemActivated;
+
+		protected abstract void RenderCell (CellRendererText render, int index, T item);
+
+		ListStore store = new ListStore (typeof(T));
+		Dictionary<T, TreeIter> storeList = new Dictionary<T, TreeIter> ();
+		List<TreeViewColumn> columns = new List<TreeViewColumn> ();
+
+		/// <summary>
+		/// Pass one string parameter for every column
+		/// </summary>
+		/// <param name="columnNames">
+		/// Column Titles, one parameter for each column.
+		/// </param>
+		public ListView (params string[] columnNames)
+		{
+			this.Model = store;
+			foreach (string s in columnNames) {
+				TreeViewColumn c = this.AppendColumn (s, new CellRendererText (), this.ColumnCellData);
+				columns.Add (c);
+			}
+
+			this.SelectedItems = new T[0];
+			this.Selection.Changed += HandleSelectionChanged;
+		}
+
+		private void ColumnCellData (TreeViewColumn column, CellRenderer renderer, ITreeModel model, TreeIter iter)
+		{
+			T item = (T)model.GetValue (iter, 0);
+			CellRendererText textRender = (CellRendererText)renderer;
+			int index = columns.IndexOf (column);
+			RenderCell (textRender, index, item);
+		}
+
+		#region Add, Remove and Clear Items
+
+		public void AddItem (T item)
+		{
+			var iter = store.AppendValues (item);
+			storeList.Add (item, iter);
+		}
+
+		public void ClearItems ()
+		{
+			store.Clear ();
+			storeList.Clear ();
+		}
+
+		public void RemoveItem (T item)
+		{
+			if (! storeList.ContainsKey (item))
+				return;
+
+			TreeIter iter = storeList[item];
+			store.Remove (ref iter);
+			storeList.Remove (item);
+		}
+
+		#endregion
+
+		#region Selection and Aktivation triggers
+
+		void HandleSelectionChanged (object sender, EventArgs e)
+		{
+			TreeSelection selection = (TreeSelection)sender;
+			TreePath[] paths = selection.GetSelectedRows ();
+			T[] items = new T[paths.Length];
+			for (int n = 0; n < paths.Length; n++) {
+				TreeIter iter;
+				Model.GetIter (out iter, paths[n]);
+				items[n] = (T)Model.GetValue (iter, 0);
+			}
+
+			SelectedItems = items;
+
+			var itemEvent = ItemSelected;
+			if (itemEvent != null)
+				itemEvent (items);
+		}
+
+		protected override void OnRowActivated (TreePath path, TreeViewColumn column)
+		{
+			TreeIter iter;
+			Model.GetIter (out iter, path);
+			T item = (T)Model.GetValue (iter, 0);
+
+			var e = ItemActivated;
+			if (e != null)
+				e (item);
+
+			base.OnRowActivated (path, column);
+		}
+
+		#endregion
+	}
+}
diff --git a/SpritePacker-GUI/MainWindow.cs b/SpritePacker-GUI/MainWindow.cs
new file mode 100644
index 0000000..35a4e03
--- /dev/null
+++ b/SpritePacker-GUI/MainWindow.cs
@@ -0,0 +1,68 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Linq;
+
+using Gtk;
+using SilentorBit;
+
+namespace SpritePacker.GUI
+{
+	public class MainWindow : Window
+	{
+		private static bool initialised = false;
+
+		private SpriteListView spriteListDisplay;
+
+		public MainWindow() : base("SpritePacker GUI")
+		{
+			if (!initialised)
+				throw new InvalidOperationException("Error: Gtk hasn't been initialised yet, so you can't create a new window.");
+
+			SetDefaultSize(500, 300);
+			SetPosition(WindowPosition.Center);
+
+			// Quit when the close button is pressed
+			DeleteEvent += (object o, DeleteEventArgs args) => {
+				Application.Quit();
+			};
+
+			setupLayout();
+		}
+
+		/// <summary>
+		/// Initilise GTK# to make it ready for use.
+		/// </summary>
+		public static void Init()
+		{
+			initialised = true;
+			Application.Init();
+		}
+
+		public void Start()
+		{
+			ShowAll();
+			Application.Run();
+		}
+
+		private void setupLayout()
+		{
+			HBox masterContainer = new HBox(true, 10);
+			VBox leftPanel = new VBox(false, 0) { MarginRight = 5 };
+			VBox rightPanel = new VBox(false, 0) { MarginLeft = 5 };
+			Frame leftPanelFrame = new Frame("Sprites") { Child = leftPanel, Margin = 10, MarginRight = 5 };
+			Frame rightPanelFrame = new Frame("Preview") { Child = rightPanel, Margin = 10, MarginLeft = 5 };
+
+			spriteListDisplay = new SpriteListView() { Margin = 10 };
+			spriteListDisplay.AddItem(new Sprite("/home/sbrl/Pictures/Spaghetti.png"));
+
+			leftPanel.OverrideBackgroundColor(StateFlags.Normal, Gdk.RGBA.Zero);
+			leftPanel.PackStart(spriteListDisplay, true, true, 0);
+
+			masterContainer.PackStart(leftPanelFrame, true, true, 0);
+			masterContainer.PackStart(rightPanelFrame, true, true, 0);
+
+			Add(masterContainer);
+		}
+	}
+}
+
diff --git a/SpritePacker-GUI/Program.cs b/SpritePacker-GUI/Program.cs
new file mode 100644
index 0000000..5df8d0a
--- /dev/null
+++ b/SpritePacker-GUI/Program.cs
@@ -0,0 +1,14 @@
+﻿using System;
+
+namespace SpritePacker.GUI
+{
+	class MainClass
+	{
+		public static void Main(string[] args)
+		{
+			MainWindow.Init();
+			MainWindow mainWindow = new MainWindow();
+			mainWindow.Start();
+		}
+	}
+}
diff --git a/SpritePacker-GUI/Properties/AssemblyInfo.cs b/SpritePacker-GUI/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..a9a86e6
--- /dev/null
+++ b/SpritePacker-GUI/Properties/AssemblyInfo.cs
@@ -0,0 +1,27 @@
+﻿using System.Reflection;
+using System.Runtime.CompilerServices;
+
+// Information about this assembly is defined by the following attributes.
+// Change them to the values specific to your project.
+
+[assembly: AssemblyTitle("SpritePacker-GUI")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("")]
+[assembly: AssemblyCopyright("Starbeamrainbowlabs")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}".
+// The form "{Major}.{Minor}.*" will automatically update the build and revision,
+// and "{Major}.{Minor}.{Build}.*" will update just the revision.
+
+[assembly: AssemblyVersion("1.0.*")]
+
+// The following attributes are used to specify the signing key for the assembly,
+// if desired. See the Mono documentation for more information about signing.
+
+//[assembly: AssemblyDelaySign(false)]
+//[assembly: AssemblyKeyFile("")]
+
diff --git a/SpritePacker-GUI/SpriteListView.cs b/SpritePacker-GUI/SpriteListView.cs
new file mode 100644
index 0000000..a4543b3
--- /dev/null
+++ b/SpritePacker-GUI/SpriteListView.cs
@@ -0,0 +1,29 @@
+﻿using System;
+using SilentorBit;
+using System.IO;
+
+namespace SpritePacker.GUI
+{
+	public class SpriteListView : ListView<Sprite>
+	{
+		public SpriteListView() : base("Number", "Filepath")
+		{
+		}
+
+		protected override void RenderCell(Gtk.CellRendererText render, int index, Sprite item)
+		{
+			switch(index)
+			{
+				case 0:
+					render.Text = index.ToString();
+					break;
+				case 1:
+					render.Text = item.Filename;
+					break;
+				default:
+					throw new InvalidDataException($"Invalid column index {index}");
+			}
+		}
+	}
+}
+
diff --git a/SpritePacker-GUI/SpritePacker-GUI.csproj b/SpritePacker-GUI/SpritePacker-GUI.csproj
new file mode 100644
index 0000000..6420771
--- /dev/null
+++ b/SpritePacker-GUI/SpritePacker-GUI.csproj
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">x86</Platform>
+    <ProjectGuid>{ECC09EBE-FE69-4DC2-B553-B92DF4992762}</ProjectGuid>
+    <OutputType>Exe</OutputType>
+    <RootNamespace>SpritePacker.GUI</RootNamespace>
+    <AssemblyName>SpritePacker-GUI</AssemblyName>
+    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug</OutputPath>
+    <DefineConstants>DEBUG;</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <Externalconsole>true</Externalconsole>
+    <PlatformTarget>x86</PlatformTarget>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
+    <DebugType>full</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release</OutputPath>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <Externalconsole>true</Externalconsole>
+    <PlatformTarget>x86</PlatformTarget>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="System" />
+    <Reference Include="atk-sharp">
+      <HintPath>..\packages\GtkSharp.3.1.3\lib\net45\atk-sharp.dll</HintPath>
+    </Reference>
+    <Reference Include="cairo-sharp">
+      <HintPath>..\packages\GtkSharp.3.1.3\lib\net45\cairo-sharp.dll</HintPath>
+    </Reference>
+    <Reference Include="gdk-sharp">
+      <HintPath>..\packages\GtkSharp.3.1.3\lib\net45\gdk-sharp.dll</HintPath>
+    </Reference>
+    <Reference Include="gio-sharp">
+      <HintPath>..\packages\GtkSharp.3.1.3\lib\net45\gio-sharp.dll</HintPath>
+    </Reference>
+    <Reference Include="glib-sharp">
+      <HintPath>..\packages\GtkSharp.3.1.3\lib\net45\glib-sharp.dll</HintPath>
+    </Reference>
+    <Reference Include="gtk-sharp">
+      <HintPath>..\packages\GtkSharp.3.1.3\lib\net45\gtk-sharp.dll</HintPath>
+    </Reference>
+    <Reference Include="pango-sharp">
+      <HintPath>..\packages\GtkSharp.3.1.3\lib\net45\pango-sharp.dll</HintPath>
+    </Reference>
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Program.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="MainWindow.cs" />
+    <Compile Include="ListView.cs" />
+    <Compile Include="SpriteListView.cs" />
+  </ItemGroup>
+  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+  <Import Project="..\packages\GtkSharp.3.1.3\build\net45\GtkSharp.targets" Condition="Exists('..\packages\GtkSharp.3.1.3\build\net45\GtkSharp.targets')" />
+  <ItemGroup>
+    <None Include="packages.config" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\SpritePacker\SpritePacker.csproj">
+      <Project>{2D3C4FAA-6D9C-4644-ABC0-361550A1884A}</Project>
+      <Name>SpritePacker</Name>
+    </ProjectReference>
+  </ItemGroup>
+</Project>
\ No newline at end of file
diff --git a/SpritePacker-GUI/packages.config b/SpritePacker-GUI/packages.config
new file mode 100644
index 0000000..e026545
--- /dev/null
+++ b/SpritePacker-GUI/packages.config
@@ -0,0 +1,4 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<packages>
+  <package id="GtkSharp" version="3.1.3" targetFramework="net45" />
+</packages>
\ No newline at end of file
diff --git a/SpritePacker.sln b/SpritePacker.sln
index 1bd93ee..e96560c 100644
--- a/SpritePacker.sln
+++ b/SpritePacker.sln
@@ -11,6 +11,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SpritePacker", "SpritePacker\SpritePacker.csproj", "{2D3C4FAA-6D9C-4644-ABC0-361550A1884A}"
 EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SpritePacker-GUI", "SpritePacker-GUI\SpritePacker-GUI.csproj", "{ECC09EBE-FE69-4DC2-B553-B92DF4992762}"
+EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug|x86 = Debug|x86
@@ -25,6 +27,10 @@ Global
 		{6EF47B64-1920-4827-BEEF-B262D5A2D214}.Debug|x86.Build.0 = Debug|x86
 		{6EF47B64-1920-4827-BEEF-B262D5A2D214}.Release|x86.ActiveCfg = Release|x86
 		{6EF47B64-1920-4827-BEEF-B262D5A2D214}.Release|x86.Build.0 = Release|x86
+		{ECC09EBE-FE69-4DC2-B553-B92DF4992762}.Debug|x86.ActiveCfg = Debug|x86
+		{ECC09EBE-FE69-4DC2-B553-B92DF4992762}.Debug|x86.Build.0 = Debug|x86
+		{ECC09EBE-FE69-4DC2-B553-B92DF4992762}.Release|x86.ActiveCfg = Release|x86
+		{ECC09EBE-FE69-4DC2-B553-B92DF4992762}.Release|x86.Build.0 = Release|x86
 	EndGlobalSection
 	GlobalSection(NestedProjects) = preSolution
 	EndGlobalSection
