diff --git a/Build/Projects/Pipeline.definition b/Build/Projects/Pipeline.definition index 2add3b531bb..8ea07d1d201 100644 --- a/Build/Projects/Pipeline.definition +++ b/Build/Projects/Pipeline.definition @@ -272,6 +272,12 @@ MacOS,Linux + + MacOS,Linux + + + MacOS,Linux + MacOS,Linux @@ -309,6 +315,12 @@ Toolbar.Save.png + + Toolbar.Undo.png + + + Toolbar.Redo.png + Toolbar.NewItem.png @@ -330,6 +342,9 @@ Toolbar.Clean.png + + Toolbar.CancelBuild.png + Toolbar.FilterOutput.png diff --git a/Tools/Pipeline/Common/IController.cs b/Tools/Pipeline/Common/IController.cs index b300548ace0..7d362903b0a 100644 --- a/Tools/Pipeline/Common/IController.cs +++ b/Tools/Pipeline/Common/IController.cs @@ -106,7 +106,7 @@ interface IController : IContentItemObserver void IncludeFolder(string initialDirectory); - void Exclude(IEnumerable items, IEnumerable folders); + void Exclude(IEnumerable items, IEnumerable folders, bool delete); void NewItem(string name, string location, ContentItemTemplate template); diff --git a/Tools/Pipeline/Common/IView.cs b/Tools/Pipeline/Common/IView.cs index 72a68dd265c..4b64f7c317c 100644 --- a/Tools/Pipeline/Common/IView.cs +++ b/Tools/Pipeline/Common/IView.cs @@ -37,6 +37,8 @@ interface IView void ShowMessage(string message); + bool ShowDeleteDialog(string[] items); + void BeginTreeUpdate(); void SetTreeRoot(IProjectItem item); diff --git a/Tools/Pipeline/Common/PipelineController.ExcludeAction.cs b/Tools/Pipeline/Common/PipelineController.ExcludeAction.cs index 197a243569e..3c676029f4c 100644 --- a/Tools/Pipeline/Common/PipelineController.ExcludeAction.cs +++ b/Tools/Pipeline/Common/PipelineController.ExcludeAction.cs @@ -2,6 +2,7 @@ // This file is subject to the terms and conditions defined in // file 'LICENSE.txt', which is part of this source code package. +using System; using System.Collections.Generic; using System.IO; using System.Linq; @@ -15,11 +16,13 @@ private class ExcludeAction : IProjectAction private readonly PipelineController _con; private readonly ContentItemState[] _state; private readonly string[] _folder; + private readonly bool _delete; - public ExcludeAction(PipelineController controller, IEnumerable items, IEnumerable folders) + public ExcludeAction(PipelineController controller, IEnumerable items, IEnumerable folders, bool delete) { _con = controller; _folder = (folders == null) ? new string[0] : folders.ToArray(); + _delete = delete; if(items == null) _state = new ContentItemState[0]; @@ -44,18 +47,42 @@ public bool Do() for (var i = 0; i < _con._project.ContentItems.Count; i++) { var item = _con._project.ContentItems[i]; + if (item.OriginalPath == obj.SourceFile) { _con._project.ContentItems.Remove(item); _con.View.RemoveTreeItem(item); + + try + { + if (_delete && File.Exists(item.OriginalPath)) + File.Delete(item.OriginalPath); + } + catch(Exception ex) + { + _con.View.ShowError("File could not be deleted", "File '" + item.OriginalPath + "' could not be deleted due to the following reasons: " + ex.Message); + } + break; } } } - foreach(string f in _folder) + foreach (string f in _folder) + { _con.View.RemoveTreeFolder(f); + try + { + if (_delete && Directory.Exists(f)) + Directory.Delete(f); + } + catch(Exception ex) + { + _con.View.ShowError("Folder could not be deleted", "Folder '" + f + "' could not be deleted due to the following reasons: " + ex.Message); + } + } + _con.View.EndTreeUpdate(); _con.ProjectDirty = true; @@ -64,6 +91,9 @@ public bool Do() public bool Undo() { + if (_delete) + return false; + _con.View.BeginTreeUpdate(); foreach(string f in _folder) diff --git a/Tools/Pipeline/Common/PipelineController.cs b/Tools/Pipeline/Common/PipelineController.cs index ba99b4a2f81..0982eed3cbd 100644 --- a/Tools/Pipeline/Common/PipelineController.cs +++ b/Tools/Pipeline/Common/PipelineController.cs @@ -540,7 +540,7 @@ public void CancelBuild() /// private bool AskSaveProject() { - // If the project is not dirty + // If the project is not dirty or open // then we can simply skip it. if (!ProjectDirty) return true; @@ -838,9 +838,23 @@ private List GetDirectories(string folder) return ret; } - public void Exclude(IEnumerable items, IEnumerable folders) + public void Exclude(IEnumerable items, IEnumerable folders, bool delete) { - var action = new ExcludeAction(this, items, folders); + if (delete) + { + var delitems = new List(); + + foreach (var f in folders) + delitems.Add(f.TrimEnd(Path.DirectorySeparatorChar) + Path.DirectorySeparatorChar); + + foreach (var i in items) + delitems.Add(i.OriginalPath); + + if (!View.ShowDeleteDialog(delitems.ToArray())) + return; + } + + var action = new ExcludeAction(this, items, folders, delete); if(action.Do()) _actionStack.Add(action); } diff --git a/Tools/Pipeline/Gtk/Dialogs/CollectionEditorDialog.GUI.cs b/Tools/Pipeline/Gtk/Dialogs/CollectionEditorDialog.GUI.cs index dcd398d9611..498aa046cd5 100644 --- a/Tools/Pipeline/Gtk/Dialogs/CollectionEditorDialog.GUI.cs +++ b/Tools/Pipeline/Gtk/Dialogs/CollectionEditorDialog.GUI.cs @@ -1,163 +1,66 @@ +using Gtk; -// This file has been generated by the GUI designer. Do not modify. namespace MonoGame.Tools.Pipeline { - public partial class CollectionEditorDialog - { - private global::Gtk.HPaned hpaned1; - - private global::Gtk.VBox vbox2; - - private global::Gtk.FileChooserWidget filechooserwidget1; - - private global::Gtk.HBox hbox2; - - private global::Gtk.Alignment alignment1; - - private global::Gtk.Button button9; - - private global::Gtk.VBox vbox3; - - private global::Gtk.HBox hbox1; - - private global::Gtk.Alignment alignment2; - - private global::Gtk.Button button10; - - private global::Gtk.ScrolledWindow GtkScrolledWindow2; - - private global::Gtk.TreeView treeview1; + public partial class CollectionEditorDialog + { + private VBox vbox1; + private HBox hbox1; + private Button buttonAdd, buttonRemove; + private ScrolledWindow scrollView1; + private TreeView treeView1; - protected virtual void Build () - { - global::Stetic.Gui.Initialize (this); - // Widget MonoGame.Tools.Pipeline.CollectionEditorDialog - this.Name = "MonoGame.Tools.Pipeline.CollectionEditorDialog"; - this.Title = global::Mono.Unix.Catalog.GetString ("Reference Editor"); - this.WindowPosition = ((global::Gtk.WindowPosition)(4)); - // Internal child MonoGame.Tools.Pipeline.CollectionEditorDialog.VBox - #if GTK2 - global::Gtk.VBox w1 = this.VBox; - #elif GTK3 - global::Gtk.Box w1 = this.ContentArea; - #endif - w1.Name = "dialog1_VBox"; - w1.BorderWidth = ((uint)(2)); - // Container child dialog1_VBox.Gtk.Box+BoxChild - this.hpaned1 = new global::Gtk.HPaned (); - this.hpaned1.CanFocus = true; - this.hpaned1.Name = "hpaned1"; - this.hpaned1.Position = 573; - // Container child hpaned1.Gtk.Paned+PanedChild - this.vbox2 = new global::Gtk.VBox (); - this.vbox2.Name = "vbox2"; - this.vbox2.Spacing = 6; - // Container child vbox2.Gtk.Box+BoxChild - this.filechooserwidget1 = new global::Gtk.FileChooserWidget (((global::Gtk.FileChooserAction)(0))); - #if GTK3 - this.filechooserwidget1.Expand = true; - #endif - this.filechooserwidget1.Name = "filechooserwidget1"; - this.vbox2.Add (this.filechooserwidget1); - global::Gtk.Box.BoxChild w2 = ((global::Gtk.Box.BoxChild)(this.vbox2 [this.filechooserwidget1])); - w2.Position = 0; - // Container child vbox2.Gtk.Box+BoxChild - this.hbox2 = new global::Gtk.HBox (); - this.hbox2.Name = "hbox2"; - this.hbox2.Spacing = 6; - // Container child hbox2.Gtk.Box+BoxChild - this.alignment1 = new global::Gtk.Alignment (0.5F, 0.5F, 1F, 1F); - this.alignment1.Name = "alignment1"; - this.hbox2.Add (this.alignment1); - global::Gtk.Box.BoxChild w3 = ((global::Gtk.Box.BoxChild)(this.hbox2 [this.alignment1])); - w3.Position = 0; - // Container child hbox2.Gtk.Box+BoxChild - this.button9 = new global::Gtk.Button (); - this.button9.CanFocus = true; - this.button9.Name = "button9"; - this.button9.UseStock = true; - this.button9.UseUnderline = true; - this.button9.Label = "gtk-add"; - this.hbox2.Add (this.button9); - global::Gtk.Box.BoxChild w4 = ((global::Gtk.Box.BoxChild)(this.hbox2 [this.button9])); - w4.Position = 1; - w4.Expand = false; - w4.Fill = false; - this.vbox2.Add (this.hbox2); - global::Gtk.Box.BoxChild w5 = ((global::Gtk.Box.BoxChild)(this.vbox2 [this.hbox2])); - w5.Position = 1; - w5.Expand = false; - w5.Fill = false; - this.hpaned1.Add (this.vbox2); - global::Gtk.Paned.PanedChild w6 = ((global::Gtk.Paned.PanedChild)(this.hpaned1 [this.vbox2])); - w6.Resize = false; - // Container child hpaned1.Gtk.Paned+PanedChild - this.vbox3 = new global::Gtk.VBox (); - this.vbox3.Name = "vbox3"; - this.vbox3.Spacing = 6; - // Container child vbox3.Gtk.Box+BoxChild - this.hbox1 = new global::Gtk.HBox (); - this.hbox1.Name = "hbox1"; - this.hbox1.Spacing = 6; - // Container child hbox1.Gtk.Box+BoxChild - this.alignment2 = new global::Gtk.Alignment (0.5F, 0.5F, 1F, 1F); - this.alignment2.Name = "alignment2"; - this.hbox1.Add (this.alignment2); - global::Gtk.Box.BoxChild w7 = ((global::Gtk.Box.BoxChild)(this.hbox1 [this.alignment2])); - w7.Position = 0; - // Container child hbox1.Gtk.Box+BoxChild - this.button10 = new global::Gtk.Button (); - this.button10.CanFocus = true; - this.button10.Name = "button10"; - this.button10.UseStock = true; - this.button10.UseUnderline = true; - this.button10.Label = "gtk-remove"; - this.hbox1.Add (this.button10); - global::Gtk.Box.BoxChild w8 = ((global::Gtk.Box.BoxChild)(this.hbox1 [this.button10])); - w8.Position = 1; - w8.Expand = false; - w8.Fill = false; - this.vbox3.Add (this.hbox1); - global::Gtk.Box.BoxChild w9 = ((global::Gtk.Box.BoxChild)(this.vbox3 [this.hbox1])); - w9.Position = 0; - w9.Expand = false; - w9.Fill = false; - // Container child vbox3.Gtk.Box+BoxChild - this.GtkScrolledWindow2 = new global::Gtk.ScrolledWindow (); - this.GtkScrolledWindow2.Name = "GtkScrolledWindow2"; - this.GtkScrolledWindow2.ShadowType = ((global::Gtk.ShadowType)(1)); - // Container child GtkScrolledWindow2.Gtk.Container+ContainerChild - this.treeview1 = new global::Gtk.TreeView (); - this.treeview1.CanFocus = true; - this.treeview1.Name = "treeview1"; - this.treeview1.EnableSearch = false; - this.treeview1.HeadersVisible = false; - this.GtkScrolledWindow2.Add (this.treeview1); - this.vbox3.Add (this.GtkScrolledWindow2); - global::Gtk.Box.BoxChild w11 = ((global::Gtk.Box.BoxChild)(this.vbox3 [this.GtkScrolledWindow2])); - w11.Position = 1; - this.hpaned1.Add (this.vbox3); - w1.Add (this.hpaned1); - global::Gtk.Box.BoxChild w13 = ((global::Gtk.Box.BoxChild)(w1 [this.hpaned1])); - w13.Position = 0; - if ((this.Child != null)) { - this.Child.ShowAll (); - } - this.DefaultWidth = 800; - this.DefaultHeight = 397; + protected virtual void Build () + { + this.Title = "Reference Editor"; + this.WindowPosition = WindowPosition.CenterOnParent; + this.DefaultWidth = 400; + this.DefaultHeight = 350; - #if GTK3 - Gdk.Geometry geom = new Gdk.Geometry(); +#if GTK3 + var geom = new Gdk.Geometry(); geom.MinWidth = this.DefaultWidth; geom.MinHeight = 200; this.SetGeometryHints(this, geom, Gdk.WindowHints.MinSize); - #endif +#endif - this.Show (); - this.Response += new global::Gtk.ResponseHandler (this.OnResponse); - this.filechooserwidget1.FileActivated += new global::System.EventHandler (this.AddFileEvent); - this.button9.Clicked += new global::System.EventHandler (this.AddFileEvent); - this.button10.Clicked += new global::System.EventHandler (this.RemoveFileEvent); - } - } + hbox1 = new HBox(); + + scrollView1 = new ScrolledWindow(); + + treeView1 = new TreeView(); + treeView1.HeadersVisible = false; + treeView1.Selection.Changed += SelectionChanged; + scrollView1.Add(treeView1); + + hbox1.PackStart(scrollView1, true, true, 0); + + vbox1 = new VBox(); + + buttonAdd = new Button("Add"); + buttonAdd.Clicked += AddFileEvent; + vbox1.PackStart(buttonAdd, false, true, 0); + + buttonRemove = new Button("Remove"); + buttonRemove.Sensitive = false; + buttonRemove.Clicked += RemoveFileEvent; + vbox1.PackStart(buttonRemove, false, true, 0); + + hbox1.PackStart(vbox1, false, true, 1); + +#if GTK3 + this.ContentArea.PackStart(hbox1, true, true, 0); +#else + this.VBox.PackStart(hbox1, true, true, 0); +#endif + + this.AddButton("Ok", ResponseType.Ok); + this.AddButton("Cancel", ResponseType.Cancel); + this.DefaultResponse = ResponseType.Ok; + + this.ShowAll (); + + this.Response += this.OnResponse; + } + } } diff --git a/Tools/Pipeline/Gtk/Dialogs/CollectionEditorDialog.cs b/Tools/Pipeline/Gtk/Dialogs/CollectionEditorDialog.cs index 455b76cda24..f75d283802d 100644 --- a/Tools/Pipeline/Gtk/Dialogs/CollectionEditorDialog.cs +++ b/Tools/Pipeline/Gtk/Dialogs/CollectionEditorDialog.cs @@ -1,13 +1,16 @@ -using System.Collections.Generic; -using System; +using System; +using System.Collections.Generic; + using Gtk; namespace MonoGame.Tools.Pipeline { - public partial class CollectionEditorDialog : Gtk.Dialog + public partial class CollectionEditorDialog : Dialog { - TreeStore listStore; - PipelineController controller; + private string startLocation; + private FileFilter dllFilter; + private TreeStore listStore; + private PipelineController controller; public string text = ""; @@ -15,20 +18,13 @@ public CollectionEditorDialog (Window parrent, string text) : base(Global.GetNew { Build(); - this.Title = Mono.Unix.Catalog.GetString ("Reference Editor"); - - this.AddButton("Ok", ResponseType.Ok); - this.AddButton("Cancel", ResponseType.Cancel); - this.DefaultResponse = ResponseType.Ok; - this.controller = ((PipelineController)((MainWindow)parrent)._controller); - FileFilter filter = new FileFilter (); - filter.AddPattern ("*.dll"); + dllFilter = new FileFilter (); + dllFilter.Name = "Dll Files (*.dll)"; + dllFilter.AddPattern ("*.dll"); - filechooserwidget1.Filter = filter; - filechooserwidget1.SetCurrentFolder(controller.ProjectLocation); - filechooserwidget1.SelectMultiple = true; + startLocation = controller.ProjectLocation; var column = new TreeViewColumn (); @@ -40,20 +36,20 @@ public CollectionEditorDialog (Window parrent, string text) : base(Global.GetNew column.PackStart (textCell, false); column.PackStart (dataCell, false); - treeview1.AppendColumn (column); + treeView1.AppendColumn (column); column.AddAttribute (textCell, "markup", 0); column.AddAttribute (dataCell, "text", 1); listStore = new TreeStore (typeof (string), typeof (string)); - treeview1.Model = listStore; - treeview1.Selection.Mode = SelectionMode.Multiple; + treeView1.Model = listStore; + treeView1.Selection.Mode = SelectionMode.Multiple; - string[] refs = text.Replace("\r\n", "~").Split('~'); + var refs = text.Split(Environment.NewLine[0]); foreach (string reff in refs) - if (reff != "") + if (!string.IsNullOrWhiteSpace(reff)) AddValue(reff); } @@ -78,36 +74,57 @@ protected void OnResponse(object sender, EventArgs e) private List GetFileNames() { - List ret = new List(); + var ret = new List(); TreeIter iter; if (listStore.GetIterFirst(out iter)) { - ret.Add(treeview1.Model.GetValue(iter, 1).ToString()); + ret.Add(treeView1.Model.GetValue(iter, 1).ToString()); while (listStore.IterNext(ref iter)) - ret.Add(treeview1.Model.GetValue(iter, 1).ToString()); + ret.Add(treeView1.Model.GetValue(iter, 1).ToString()); } return ret; } - protected void AddFileEvent(object sender, EventArgs e) + private void SelectionChanged (object sender, EventArgs e) { - List files = GetFileNames(); + buttonRemove.Sensitive = (treeView1.Selection.GetSelectedRows().Length > 0); + } - string pl = controller.ProjectLocation; + private void AddFileEvent(object sender, EventArgs e) + { + var fileNames = new string[0]; + var files = GetFileNames(); + + var pl = controller.ProjectLocation; if (!pl.EndsWith(System.IO.Path.DirectorySeparatorChar.ToString())) pl += System.IO.Path.DirectorySeparatorChar; - Uri folderUri = new Uri(pl); + var folderUri = new Uri(pl); + + var fileChooser = + new FileChooserDialog("Select Reference File", + this, + FileChooserAction.Open, + "Cancel", ResponseType.Cancel, + "Open", ResponseType.Ok); + + fileChooser.AddFilter (dllFilter); + fileChooser.SetCurrentFolder(startLocation); + + if(fileChooser.Run() == (int)ResponseType.Ok) + fileNames = fileChooser.Filenames; + + fileChooser.Destroy(); - if (filechooserwidget1.Filenames.Length > 0) + if (fileNames.Length > 0) { - foreach (string floc in filechooserwidget1.Filenames) + foreach (string floc in fileNames) { if (System.IO.File.Exists(floc)) { - Uri pathUri = new Uri(floc); + var pathUri = new Uri(floc); string fl = Uri.UnescapeDataString(folderUri.MakeRelativeUri(pathUri).ToString().Replace('/', System.IO.Path.DirectorySeparatorChar)); if (!files.Contains(fl)) @@ -117,14 +134,14 @@ protected void AddFileEvent(object sender, EventArgs e) } } - protected void RemoveFileEvent(object sender, EventArgs e) + private void RemoveFileEvent(object sender, EventArgs e) { - TreePath[] paths = treeview1.Selection.GetSelectedRows (); + var paths = treeView1.Selection.GetSelectedRows (); for (int i = paths.Length - 1; i >= 0; i--) { TreeIter iter; - if (treeview1.Model.GetIter(out iter, paths[i])) + if (treeView1.Model.GetIter(out iter, paths[i])) listStore.Remove(ref iter); } } diff --git a/Tools/Pipeline/Gtk/Dialogs/DeleteDialog.GUI.cs b/Tools/Pipeline/Gtk/Dialogs/DeleteDialog.GUI.cs new file mode 100644 index 00000000000..d6604b7503d --- /dev/null +++ b/Tools/Pipeline/Gtk/Dialogs/DeleteDialog.GUI.cs @@ -0,0 +1,54 @@ +// MonoGame - Copyright (C) The MonoGame Team +// This file is subject to the terms and conditions defined in +// file 'LICENSE.txt', which is part of this source code package. + +using Gtk; +using Gdk; + +namespace MonoGame.Tools.Pipeline +{ + public partial class DeleteDialog : Dialog + { + Label label1; + TextView textView1; + ScrolledWindow scroll1; + + private void Build() + { + this.Title = "Delete Items"; + this.DefaultWidth = 370; + this.DefaultHeight = 250; + +#if GTK3 + var vbox1 = this.ContentArea; + vbox1.Margin = 4; +#else + var vbox1 = this.VBox; +#endif + vbox1.Spacing = 4; + + label1 = new Label("The following items that will be deleted:"); + label1.SetAlignment(0f, 0.5f); + vbox1.PackStart(label1, false, true, 0); + + scroll1 = new ScrolledWindow(); + + textView1 = new TextView(); + textView1.Editable = false; + textView1.CursorVisible = false; + scroll1.Add(textView1); + + vbox1.PackStart(scroll1, true, true, 1); + +#if GTK3 + var geom = new Geometry(); + geom.MinWidth = this.DefaultWidth; + geom.MinHeight = this.DefaultHeight; + this.SetGeometryHints(this, geom, WindowHints.MinSize); +#endif + + this.ShowAll(); + } + } +} + diff --git a/Tools/Pipeline/Gtk/Dialogs/DeleteDialog.cs b/Tools/Pipeline/Gtk/Dialogs/DeleteDialog.cs new file mode 100644 index 00000000000..43bcfa150ba --- /dev/null +++ b/Tools/Pipeline/Gtk/Dialogs/DeleteDialog.cs @@ -0,0 +1,26 @@ +// MonoGame - Copyright (C) The MonoGame Team +// This file is subject to the terms and conditions defined in +// file 'LICENSE.txt', which is part of this source code package. + +using System; + +using Gtk; + +namespace MonoGame.Tools.Pipeline +{ + public partial class DeleteDialog : Dialog + { + public DeleteDialog(Window parrent, string[] items) : base(Global.GetNewDialog(parrent.Handle)) + { + Build(); + + this.AddButton("Ok", ResponseType.Ok); + this.AddButton("Cancel", ResponseType.Cancel); + this.DefaultResponse = ResponseType.Ok; + + foreach (var item in items) + textView1.Buffer.Text += item + Environment.NewLine; + } + } +} + diff --git a/Tools/Pipeline/Gtk/Global.cs b/Tools/Pipeline/Gtk/Global.cs index 65436c3cca4..afd7559a457 100644 --- a/Tools/Pipeline/Gtk/Global.cs +++ b/Tools/Pipeline/Gtk/Global.cs @@ -7,9 +7,11 @@ namespace MonoGame.Tools.Pipeline { public static class Global { + public static Application App; + //by default this should be set to whatever Gtk libs we provide with Mac - public static double GtkMajorVersion = 2; - public static double GtkMinorVersion = 24; + public static uint GtkMajorVersion = 2; + public static uint GtkMinorVersion = 24; //indicates which desktop enviorment is currenlly in use public static string DesktopEnvironment = "OSX"; @@ -18,11 +20,11 @@ public static class Global public static void Initalize() { - #if LINUX - GtkMajorVersion = Gtk3Wrapper.gtk_get_major_version(); - GtkMinorVersion = Gtk3Wrapper.gtk_get_minor_version(); +#if GTK3 + GtkMajorVersion = Gtk.Global.MajorVersion; + GtkMinorVersion = Gtk.Global.MinorVersion; - Process proc = new Process (); + var proc = new Process (); proc.StartInfo.FileName = "/bin/bash"; proc.StartInfo.Arguments = "-c \"echo $XDG_CURRENT_DESKTOP\""; proc.StartInfo.UseShellExecute = false; @@ -33,20 +35,51 @@ public static void Initalize() string line = proc.StandardOutput.ReadLine (); DesktopEnvironment = line; } - #endif - UseHeaderBar = Global.GtkMajorVersion >= 3 && Global.GtkMinorVersion >= 12 && Global.DesktopEnvironment == "GNOME"; + UseHeaderBar = Gtk.Global.MajorVersion >= 3 && Gtk.Global.MinorVersion >= 16 && Global.DesktopEnvironment == "GNOME"; + + if(UseHeaderBar) + { + /* Load Global Menu, I have no idea how to connect events to it so it's disabled for now. + * + * App = new Application("MonoGame.Pipeline", GLib.ApplicationFlags.None); + * App.Register(GLib.Cancellable.Current); + * + * var builder = new Builder(null, "MonoGame.Tools.Pipeline.Gtk.MainWindow.HeaderBar.glade", null); + * Gtk3Wrapper.gtk_application_set_app_menu(Global.App.Handle, builder.GetObject("appmenu").Handle); + */ + } +#endif } public static IntPtr GetNewDialog(IntPtr parrent) { - #if GTK3 +#if GTK3 if(UseHeaderBar) return Gtk3Wrapper.gtk_dialog_new_with_buttons("", parrent, 4 + (int)DialogFlags.Modal); - #endif +#endif return (new Dialog("", new Gtk.Window(parrent), DialogFlags.Modal)).Handle; } + + public static ToolButton GetToolButton(Gtk.Action action, string resource) + { + var ret = (ToolButton)action.CreateToolItem(); + ret.IconWidget = new Gtk.Image(null, resource); + ret.Label = ret.Label.TrimEnd(new [] { '.' }); + ret.TooltipText = ret.Label; + + return ret; + } + + public static ToggleToolButton GetToggleToolButton(Gtk.Action action, string resource) + { + var ret = (ToggleToolButton)action.CreateToolItem(); + ret.IconWidget = new Gtk.Image(null, resource); + ret.Label = ret.TooltipText = ret.Label; + + return ret; + } } public static class IconCache @@ -55,16 +88,17 @@ public static class IconCache public static Pixbuf GetFolderIcon() { - #if GTK3 +#if GTK3 return theme.LoadIcon("folder", 16, (IconLookupFlags)0); - #endif +#else return new Pixbuf(null, "MonoGame.Tools.Pipeline.Icons.folder_open.png"); +#endif } public static Pixbuf GetIcon(string fileName) { - #if GTK3 - GLib.FileInfo info = new GLib.FileInfo(Gtk3Wrapper.g_file_query_info(Gtk3Wrapper.g_file_new_for_path(fileName), "standard::*", 0, new IntPtr(), new IntPtr())); +#if GTK3 + var info = new GLib.FileInfo(Gtk3Wrapper.g_file_query_info(Gtk3Wrapper.g_file_new_for_path(fileName), "standard::*", 0, new IntPtr(), new IntPtr())); try { @@ -83,10 +117,11 @@ public static Pixbuf GetIcon(string fileName) } } catch { } - return theme.LoadIcon("text-x-generic", 16, (IconLookupFlags)0); - #endif + return theme.LoadIcon("text-x-generic", 16, (IconLookupFlags)0); +#else return new Pixbuf(null, "MonoGame.Tools.Pipeline.Icons.blueprint.png"); +#endif } } } diff --git a/Tools/Pipeline/Gtk/Gtk3Integration.cs b/Tools/Pipeline/Gtk/Gtk3Integration.cs index 176a39de103..2c583812e4a 100644 --- a/Tools/Pipeline/Gtk/Gtk3Integration.cs +++ b/Tools/Pipeline/Gtk/Gtk3Integration.cs @@ -58,6 +58,9 @@ public class Gtk3Wrapper [DllImport (gtklibpath, CallingConvention = CallingConvention.Cdecl)] public static extern IntPtr gtk_popover_new (IntPtr relative_to_widget); + [DllImport (gtklibpath, CallingConvention = CallingConvention.Cdecl)] + public static extern IntPtr gtk_popover_menu_new (); + [DllImport (gtklibpath, CallingConvention = CallingConvention.Cdecl)] public static extern IntPtr gtk_menu_button_new (); @@ -69,6 +72,15 @@ public class Gtk3Wrapper [DllImport (gtklibpath, CallingConvention = CallingConvention.Cdecl)] public static extern void gtk_tree_view_set_activate_on_single_click (IntPtr treeview, bool value); + + [DllImport (gtklibpath, CallingConvention = CallingConvention.Cdecl)] + public static extern IntPtr gtk_app_chooser_dialog_new (IntPtr parrent, int flags, IntPtr file); + + [DllImport (gtklibpath, CallingConvention = CallingConvention.Cdecl)] + public static extern void gtk_application_set_app_menu (IntPtr application, IntPtr app_menu); + + [DllImport (gtklibpath, CallingConvention = CallingConvention.Cdecl)] + public static extern IntPtr gtk_application_get_app_menu (IntPtr application); } public class ColorChooserDialog : Dialog @@ -143,9 +155,30 @@ public class Popover : Bin public Popover(IntPtr handle) : base(handle) { } } + public class PopoverMenu : Popover + { + public PopoverMenu() : base(Gtk3Wrapper.gtk_popover_menu_new()) { } + + public PopoverMenu(IntPtr handle) : base(handle) { } + } + + public class ModalButton : Button + { + [Property("active")] + public bool Active + { + set + { + this.SetProperty("active", new Value(value)); + } + } + + public ModalButton(IntPtr handle) : base(handle) { } + } + public class MenuButton : ToggleButton { - public Popover Popup + public Popover Popover { get { diff --git a/Tools/Pipeline/Gtk/MainWindow.GUI.cs b/Tools/Pipeline/Gtk/MainWindow.GUI.cs index ca89ec93d81..fb491ecb122 100644 --- a/Tools/Pipeline/Gtk/MainWindow.GUI.cs +++ b/Tools/Pipeline/Gtk/MainWindow.GUI.cs @@ -1,4 +1,5 @@ using Gtk; +using GLib; namespace MonoGame.Tools.Pipeline { @@ -8,16 +9,20 @@ internal partial class MainWindow HeaderBar hbar; [Builder.ObjectAttribute] Button new_button; - [Builder.ObjectAttribute] Button open_button; [Builder.ObjectAttribute] Button save_button; [Builder.ObjectAttribute] Button build_button; [Builder.ObjectAttribute] Button rebuild_button; [Builder.ObjectAttribute] Button cancel_button; + [Builder.ObjectAttribute] Separator separator1; [Builder.ObjectAttribute] ToggleButton filteroutput_button; - - MenuButton open_menubutton; - - [Builder.ObjectAttribute] Menu menu2; + [Builder.ObjectAttribute] Button saveas_button; + [Builder.ObjectAttribute] Button undo_button; + [Builder.ObjectAttribute] Button redo_button; + [Builder.ObjectAttribute] Button close_button; + [Builder.ObjectAttribute] Button clean_button; + + MenuButton open_button, gear_button; + ModalButton debugmode_button; #endif private global::Gtk.UIManager UIManager; @@ -46,7 +51,9 @@ internal partial class MainWindow private global::Gtk.Action RedoAction; - Action RenameAction; + Action RenameAction; + + private global::Gtk.Action ExcludeAction; private global::Gtk.Action DeleteAction; @@ -94,7 +101,7 @@ internal partial class MainWindow TreeView treeview1; Toolbar toolBar1; - ToolButton toolNew, toolOpen, toolSave, toolNewItem, toolNewFolder, toolAddItem, toolAddFolder, toolBuild, toolRebuild, toolClean; + ToolButton toolNew, toolOpen, toolSave, toolUndo, toolRedo, toolNewItem, toolNewFolder, toolAddItem, toolAddFolder, toolBuild, toolRebuild, toolClean, toolCancelBuild; ToggleToolButton toolFilterOutput; protected virtual void Build () @@ -142,7 +149,10 @@ protected virtual void Build () w1.Add (this.RedoAction, "y"); RenameAction = new Action ("RenameAction", global::Mono.Unix.Catalog.GetString ("Rename"), null, null); RenameAction.ShortLabel = global::Mono.Unix.Catalog.GetString ("Rename"); - w1.Add (RenameAction, null); + w1.Add (RenameAction, null); + this.ExcludeAction = new global::Gtk.Action ("ExcludeAction", global::Mono.Unix.Catalog.GetString ("Exclude from Project"), null, null); + this.ExcludeAction.ShortLabel = global::Mono.Unix.Catalog.GetString ("Exclude"); + w1.Add (this.ExcludeAction, null); this.DeleteAction = new global::Gtk.Action ("DeleteAction", global::Mono.Unix.Catalog.GetString ("Delete"), null, "gtk-delete"); this.DeleteAction.ShortLabel = global::Mono.Unix.Catalog.GetString ("Delete"); w1.Add (this.DeleteAction, null); @@ -201,62 +211,61 @@ protected virtual void Build () this.vbox2 = new global::Gtk.VBox (); this.vbox2.Name = "vbox2"; // Container child vbox2.Gtk.Box+BoxChild - this.UIManager.AddUiFromString (""); + this.UIManager.AddUiFromString (""); this.menubar1 = ((global::Gtk.MenuBar)(this.UIManager.GetWidget ("/menubar1"))); this.menubar1.Name = "menubar1"; this.vbox2.Add (this.menubar1); toolBar1 = new Toolbar(); - toolNew = new ToolButton(new Image(null, "Toolbar.New.png"), "New"); - toolNew.TooltipText = toolNew.Label; + toolNew = Global.GetToolButton(NewAction, "Toolbar.New.png"); toolBar1.Add(toolNew); - toolOpen = new ToolButton(new Image(null, "Toolbar.Open.png"), "Open"); - toolOpen.TooltipText = toolOpen.Label; + toolOpen = Global.GetToolButton(OpenAction, "Toolbar.Open.png"); toolBar1.Add(toolOpen); - toolSave = new ToolButton(new Image(null, "Toolbar.Save.png"), "Save"); - toolSave.TooltipText = toolSave.Label; + toolSave = Global.GetToolButton(SaveAction, "Toolbar.Save.png"); toolBar1.Add(toolSave); toolBar1.Add(new SeparatorToolItem()); - toolNewItem = new ToolButton(new Image(null, "Toolbar.NewItem.png"), "Add New Item"); - toolNewItem.TooltipText = toolNewItem.Label; + toolUndo = Global.GetToolButton(UndoAction, "Toolbar.Undo.png"); + toolBar1.Add(toolUndo); + + toolRedo = Global.GetToolButton(RedoAction, "Toolbar.Redo.png"); + toolBar1.Add(toolRedo); + + toolBar1.Add(new SeparatorToolItem()); + + toolNewItem = Global.GetToolButton(NewItemAction, "Toolbar.NewItem.png"); toolBar1.Add(toolNewItem); - toolAddItem = new ToolButton(new Image(null, "Toolbar.ExistingItem.png"), "Add Existing Item"); - toolAddItem.TooltipText = toolAddItem.Label; + toolAddItem = Global.GetToolButton(ExistingItemAction, "Toolbar.ExistingItem.png"); toolBar1.Add(toolAddItem); - toolNewFolder = new ToolButton(new Image(null, "Toolbar.NewFolder.png"), "Add New Folder"); - toolNewFolder.TooltipText = toolNewFolder.Label; + toolNewFolder = Global.GetToolButton(NewFolderAction, "Toolbar.NewFolder.png"); toolBar1.Add(toolNewFolder); - toolAddFolder = new ToolButton(new Image(null, "Toolbar.ExistingFolder.png"), "Add Existing Folder"); - toolAddFolder.TooltipText = toolAddFolder.Label; + toolAddFolder = Global.GetToolButton(ExistingFolderAction, "Toolbar.ExistingFolder.png"); toolBar1.Add(toolAddFolder); toolBar1.Add(new SeparatorToolItem()); - toolBuild = new ToolButton(new Image(null, "Toolbar.Build.png"), "Build"); - toolBuild.TooltipText = toolBuild.Label; + toolBuild = Global.GetToolButton(BuildAction1, "Toolbar.Build.png"); toolBar1.Add(toolBuild); - toolRebuild = new ToolButton(new Image(null, "Toolbar.Rebuild.png"), "Rebuild"); - toolRebuild.TooltipText = toolRebuild.Label; + toolRebuild = Global.GetToolButton(RebuildAction, "Toolbar.Rebuild.png"); toolBar1.Add(toolRebuild); - toolClean = new ToolButton(new Image(null, "Toolbar.Clean.png"), "Clean"); - toolClean.TooltipText = toolClean.Label; + toolClean = Global.GetToolButton(CleanAction, "Toolbar.Clean.png"); toolBar1.Add(toolClean); + toolCancelBuild = Global.GetToolButton(CancelBuildAction, "Toolbar.CancelBuild.png"); + toolBar1.Add(toolCancelBuild); + toolBar1.Add(new SeparatorToolItem()); - toolFilterOutput = new ToggleToolButton(); - toolFilterOutput.Label = toolFilterOutput.TooltipText = "Filter Output"; - toolFilterOutput.IconWidget = new Image(null, "Toolbar.FilterOutput.png"); + toolFilterOutput = Global.GetToggleToolButton(FilterOutputAction, "Toolbar.FilterOutput.png"); toolBar1.Add(toolFilterOutput); if (!Global.UseHeaderBar) @@ -303,36 +312,48 @@ protected virtual void Build () treeview1 = new TreeView(); - #if GTK3 +#if GTK3 if(Global.UseHeaderBar) { - Builder builder = new Builder(null, "MonoGame.Tools.Pipeline.Gtk.MainWindow.HeaderBar.glade", null); + vbox2.Remove (menubar1); + + var builder = new Builder(null, "MonoGame.Tools.Pipeline.Gtk.MainWindow.HeaderBar.glade", null); + hbar = new HeaderBar(builder.GetObject("headerbar").Handle); + open_button = new MenuButton(builder.GetObject("open_button").Handle); + gear_button = new MenuButton(builder.GetObject("gear_button").Handle); + debugmode_button = new ModalButton(builder.GetObject("debugmode_button").Handle); builder.Autoconnect(this); hbar.AttachToWindow(this); hbar.ShowCloseButton = true; hbar.Show(); - foreach(var o in menubar1.Children) - { - menubar1.Remove(o); - menu2.Insert(o, 4); - } - - new_button.Clicked += OnNewActionActivated; - save_button.Clicked += OnSaveActionActivated; - build_button.Clicked += OnBuildAction1Activated; - rebuild_button.Clicked += OnRebuildActionActivated; - cancel_button.Clicked += OnCancelBuildActionActivated; - - filteroutput_button.ButtonReleaseEvent += ToggleFilterOutput; - filteroutput_button.Sensitive = true; - - vbox2.Remove (menubar1); - - open_menubutton = new MenuButton(open_button.Handle); - var popover = new Popover(open_menubutton); + var gearpopover = new PopoverMenu(builder.GetObject("popovermenu1").Handle); + gearpopover.WidthRequest = 200; + + gear_button.Popover = gearpopover; + + new_button.UseActionAppearance = false; + new_button.RelatedAction = NewAction; + save_button.UseActionAppearance = false; + save_button.RelatedAction = SaveAction; + build_button.UseActionAppearance = false; + build_button.RelatedAction = BuildAction1; + rebuild_button.UseActionAppearance = false; + rebuild_button.RelatedAction = RebuildAction; + cancel_button.UseActionAppearance = false; + cancel_button.RelatedAction = CancelBuildAction; + saveas_button.RelatedAction = SaveAsAction; + undo_button.RelatedAction = UndoAction; + redo_button.RelatedAction = RedoAction; + close_button.RelatedAction = CloseAction; + clean_button.RelatedAction = CleanAction; + debugmode_button.RelatedAction = DebugModeAction; + filteroutput_button.UseActionAppearance = false; + filteroutput_button.RelatedAction = FilterOutputAction; + + var popover = new Popover(open_button); var vbox = new VBox(); vbox.WidthRequest = 350; @@ -352,27 +373,37 @@ protected virtual void Build () OpenProject(recentListStore.GetValue(iter, 1).ToString()); }; - ScrolledWindow scroll1 = new ScrolledWindow(); + var scroll1 = new ScrolledWindow(); scroll1.WidthRequest = 350; scroll1.HeightRequest = 300; scroll1.Add(treeview1); vbox.PackStart(scroll1, true, true, 0); + var hbox = new HBox(); + var openButton = new Button("Open Other..."); openButton.Clicked += delegate(object sender, System.EventArgs e) { popover.Hide(); OnOpenActionActivated(sender, e); }; - vbox.PackStart(openButton, false, true, 0); + hbox.PackStart(openButton, true, true, 0); + + var importButton = new Button("Import"); + importButton.Clicked += delegate(object sender, System.EventArgs e) { + popover.Hide(); + OnImportActionActivated(sender, e); + }; + hbox.PackStart(importButton, false, true, 1); + + vbox.PackStart(hbox, false, true, 1); vbox.ShowAll(); popover.Add(vbox); - open_menubutton.Popup = popover; - + open_button.Popover = popover; } - #endif +#endif this.Title = basetitle; @@ -389,41 +420,30 @@ protected virtual void Build () this.SetGeometryHints(this, geom, Gdk.WindowHints.MinSize); #endif - this.Show (); this.DeleteEvent += new global::Gtk.DeleteEventHandler (this.OnDeleteEvent); this.NewAction.Activated += new global::System.EventHandler (this.OnNewActionActivated); - this.toolNew.Clicked += OnNewActionActivated; this.OpenAction.Activated += new global::System.EventHandler (this.OnOpenActionActivated); - this.toolOpen.Clicked += OnOpenActionActivated; this.CloseAction.Activated += new global::System.EventHandler (this.OnCloseActionActivated); this.ImportAction.Activated += new global::System.EventHandler (this.OnImportActionActivated); this.SaveAction.Activated += new global::System.EventHandler (this.OnSaveActionActivated); - this.toolSave.Clicked += OnSaveActionActivated; this.SaveAsAction.Activated += new global::System.EventHandler (this.OnSaveAsActionActivated); this.ExitAction.Activated += new global::System.EventHandler (this.OnExitActionActivated); this.UndoAction.Activated += new global::System.EventHandler (this.OnUndoActionActivated); - this.RedoAction.Activated += new global::System.EventHandler (this.OnRedoActionActivated); - RenameAction.Activated += this.OnRenameActionActivated; + this.RedoAction.Activated += new global::System.EventHandler (this.OnRedoActionActivated); + ExcludeAction.Activated += this.OnExcludeActionActivated; + RenameAction.Activated += this.OnRenameActionActivated; this.DeleteAction.Activated += new global::System.EventHandler (this.OnDeleteActionActivated); this.BuildAction1.Activated += new global::System.EventHandler (this.OnBuildAction1Activated); - toolBuild.Clicked += OnBuildAction1Activated; this.RebuildAction.Activated += new global::System.EventHandler (this.OnRebuildActionActivated); - toolRebuild.Clicked += OnRebuildActionActivated; this.CleanAction.Activated += new global::System.EventHandler (this.OnCleanActionActivated); - toolClean.Clicked += OnCleanActionActivated; this.ViewHelpAction.Activated += new global::System.EventHandler (this.OnViewHelpActionActivated); this.AboutAction.Activated += new global::System.EventHandler (this.OnAboutActionActivated); this.NewItemAction.Activated += new global::System.EventHandler (this.OnNewItemActionActivated); - this.toolNewItem.Clicked += OnNewItemActionActivated; this.NewFolderAction.Activated += new global::System.EventHandler (this.OnNewFolderActionActivated); - this.toolNewFolder.Clicked += OnNewFolderActionActivated; this.ExistingItemAction.Activated += new global::System.EventHandler (this.OnAddItemActionActivated); - this.toolAddItem.Clicked += OnAddItemActionActivated; this.ExistingFolderAction.Activated += new global::System.EventHandler (this.OnAddFolderActionActivated); - this.toolAddFolder.Clicked += OnAddFolderActionActivated; this.DebugModeAction.Activated += new global::System.EventHandler (this.OnDebugModeActionActivated); this.FilterOutputAction.Activated += OnFilterOutputActionActivated; - this.toolFilterOutput.ButtonReleaseEvent += ToggleFilterOutput; this.CancelBuildAction.Activated += new global::System.EventHandler (this.OnCancelBuildActionActivated); this.SizeAllocated += MainWindow_SizeAllocated; } diff --git a/Tools/Pipeline/Gtk/MainWindow.HeaderBar.glade b/Tools/Pipeline/Gtk/MainWindow.HeaderBar.glade index 8bbf3c2e8e6..edf5a78f92a 100644 --- a/Tools/Pipeline/Gtk/MainWindow.HeaderBar.glade +++ b/Tools/Pipeline/Gtk/MainWindow.HeaderBar.glade @@ -1,7 +1,20 @@ - + + +
+ + _Help + + + _About + + + _Quit + +
+
True False @@ -32,14 +45,6 @@ False open-menu-symbolic - - True - False - - - True - False - True False @@ -102,7 +107,6 @@ True False Open - center @@ -114,7 +118,6 @@ Menu center menu_image - menu2 False @@ -153,4 +156,96 @@ + + + + True + 10 + vertical + + + True + Save As + + + + + True + False + vertical + 3 + 3 + + + + + True + Undo + + + + + True + Redo + + + + + True + False + vertical + 3 + 3 + + + + + True + build + Build + + + + + True + Close + + + + + main + + + + + True + 10 + vertical + + + True + main + True + Build + + + + + True + Clean + + + + + True + Debug Mode + 1 + + + + + build + + +
diff --git a/Tools/Pipeline/Gtk/MainWindow.cs b/Tools/Pipeline/Gtk/MainWindow.cs index daf491887e2..0506a424aec 100644 --- a/Tools/Pipeline/Gtk/MainWindow.cs +++ b/Tools/Pipeline/Gtk/MainWindow.cs @@ -65,6 +65,7 @@ public void ReloadTitle() this.Title = System.IO.Path.GetFileName(projectview1.openedProject); hbar.Subtitle = System.IO.Path.GetDirectoryName(projectview1.openedProject); } + return; } #endif @@ -92,11 +93,7 @@ public void ReloadTitle() AllFilesFilter.Name = "All Files (*.*)"; AllFilesFilter.AddPattern ("*.*"); - #if GTK3 - Widget[] widgets = Global.UseHeaderBar ? menu2.Children : menubar1.Children; - #else - Widget[] widgets = menubar1.Children; - #endif + var widgets = Global.UseHeaderBar ? new Widget[0] : menubar1.Children; var column = new TreeViewColumn (); @@ -207,20 +204,21 @@ public void OnShowEvent() this.hpaned1.Position = PipelineSettings.Default.HSeparator; _controller.LaunchDebugger = DebugModeAction.Active = PipelineSettings.Default.DebugMode; - FilterOutputAction.Active = toolFilterOutput.Active = PipelineSettings.Default.FilterOutput; - -#if GTK3 - if(Global.UseHeaderBar) - filteroutput_button.Active = FilterOutputAction.Active; -#endif + FilterOutputAction.Active = PipelineSettings.Default.FilterOutput; } } private bool Maximized() { #if GTK2 + if (this.GdkWindow == null) + return false; + return this.GdkWindow.State.HasFlag(Gdk.WindowState.Maximized); #elif GTK3 + if (this.Window == null) + return false; + return this.Window.State.HasFlag(Gdk.WindowState.Maximized); #endif } @@ -529,6 +527,15 @@ public bool CopyOrLinkFolder(string folder, bool exists, out CopyAction action, return false; } + public bool ShowDeleteDialog(string[] items) + { + var dialog = new DeleteDialog(this, items); + var result = dialog.Run(); + dialog.Destroy(); + + return result == (int)ResponseType.Ok; + } + public void OnTemplateDefined(ContentItemTemplate item) { @@ -735,6 +742,12 @@ public void OnAddFolderActionActivated(object sender, EventArgs e) expand = false; } + public void OnExcludeActionActivated (object sender, EventArgs e) + { + projectview1.Remove (false); + UpdateMenus(); + } + public void OnRenameActionActivated (object sender, EventArgs e) { expand = true; @@ -742,10 +755,10 @@ public void OnRenameActionActivated (object sender, EventArgs e) UpdateMenus(); expand = false; } - + public void OnDeleteActionActivated (object sender, EventArgs e) { - projectview1.Remove (); + projectview1.Remove (true); UpdateMenus(); } @@ -786,23 +799,17 @@ protected void OnAboutActionActivated (object sender, EventArgs e) protected void OnDebugModeActionActivated (object sender, EventArgs e) { - _controller.LaunchDebugger = this.DebugModeAction.Active; - } - - protected void OnFilterOutputActionActivated (object sender, EventArgs e) - { - buildOutput1.CurrentPage = FilterOutputAction.Active ? 0 : 1; - toolFilterOutput.Active = FilterOutputAction.Active; + _controller.LaunchDebugger = DebugModeAction.Active; #if GTK3 if(Global.UseHeaderBar) - filteroutput_button.Active = FilterOutputAction.Active; + debugmode_button.Active = DebugModeAction.Active; #endif } - protected void ToggleFilterOutput (object sender, EventArgs e) + protected void OnFilterOutputActionActivated (object sender, EventArgs e) { - FilterOutputAction.Active = !FilterOutputAction.Active; + buildOutput1.CurrentPage = FilterOutputAction.Active ? 0 : 1; } protected void OnCancelBuildActionActivated (object sender, EventArgs e) @@ -822,15 +829,13 @@ public void UpdateMenus() var somethingSelected = paths.Length > 0; // Update the state of all menu items. - - Application.Invoke(delegate { - NewAction.Sensitive = toolNew.Sensitive = notBuilding; - OpenAction.Sensitive = toolOpen.Sensitive = notBuilding; + NewAction.Sensitive = notBuilding; + OpenAction.Sensitive = notBuilding; ImportAction.Sensitive = notBuilding; - SaveAction.Sensitive = toolSave.Sensitive = projectOpenAndNotBuilding && _controller.ProjectDirty; + SaveAction.Sensitive = projectOpenAndNotBuilding && _controller.ProjectDirty; SaveAsAction.Sensitive = projectOpenAndNotBuilding; CloseAction.Sensitive = projectOpenAndNotBuilding; @@ -838,29 +843,34 @@ public void UpdateMenus() AddAction.Sensitive = toolAddItem.Sensitive = toolAddFolder.Sensitive = toolNewItem.Sensitive = toolNewFolder.Sensitive = projectOpen; - + + ExcludeAction.Sensitive = somethingSelected; + RenameAction.Sensitive = paths.Length == 1; - DeleteAction.Sensitive = projectOpen && somethingSelected; + DeleteAction.Sensitive = somethingSelected; BuildAction.Sensitive = projectOpen; - BuildAction1.Sensitive = toolBuild.Sensitive = projectOpenAndNotBuilding; + BuildAction1.Sensitive = projectOpenAndNotBuilding; - treerebuild.Sensitive = RebuildAction.Sensitive = toolRebuild.Sensitive = projectOpenAndNotBuilding; + treerebuild.Sensitive = RebuildAction.Sensitive = projectOpenAndNotBuilding; RebuildAction.Sensitive = treerebuild.Sensitive; CleanAction.Sensitive = toolClean.Sensitive = projectOpenAndNotBuilding; CancelBuildAction.Sensitive = !notBuilding; - CancelBuildAction.Visible = !notBuilding; + + toolBuild.Visible = notBuilding; + toolRebuild.Visible = notBuilding; + toolClean.Visible = notBuilding; + toolCancelBuild.Visible = !notBuilding; #if GTK3 if (Global.UseHeaderBar) { - new_button.Sensitive = NewAction.Sensitive; open_button.Sensitive = OpenAction.Sensitive; - save_button.Sensitive = SaveAction.Sensitive; build_button.Visible = BuildAction1.Sensitive; rebuild_button.Visible = RebuildAction.Sensitive; cancel_button.Visible = CancelBuildAction.Sensitive; + separator1.Visible = build_button.Visible || cancel_button.Visible; } #endif @@ -880,10 +890,11 @@ public void OpenProject(string path) public void UpdateRecentProjectList() { var m = new Menu (); - recentMenu.Submenu = null; if (Global.UseHeaderBar) recentListStore.Clear(); + else + recentMenu.Submenu = null; var projectList = PipelineSettings.Default.ProjectHistory.ToList(); @@ -891,13 +902,15 @@ public void UpdateRecentProjectList() { if (Global.UseHeaderBar) recentListStore.InsertWithValues(0, "" + System.IO.Path.GetFileName(project) + "" + Environment.NewLine + System.IO.Path.GetDirectoryName(project), project); - - var recentItem = new MenuItem(project); - recentItem.Activated += (sender, e) => OpenProject(project); - m.Insert (recentItem, 0); + else + { + var recentItem = new MenuItem(project); + recentItem.Activated += (sender, e) => OpenProject(project); + m.Insert(recentItem, 0); + } } - if (projectList.Count > 0) + if (!Global.UseHeaderBar && projectList.Count > 0) { m.Add(new SeparatorMenuItem()); var item = new MenuItem("Clear"); diff --git a/Tools/Pipeline/Gtk/Widgets/BuildOutput.GUI.cs b/Tools/Pipeline/Gtk/Widgets/BuildOutput.GUI.cs index b0cc94db47c..622c027bc0a 100644 --- a/Tools/Pipeline/Gtk/Widgets/BuildOutput.GUI.cs +++ b/Tools/Pipeline/Gtk/Widgets/BuildOutput.GUI.cs @@ -18,6 +18,8 @@ public void Build() treeview1 = new TreeView(); treeview1.HeadersVisible = false; treeview1.CanFocus = true; + treeview1.ScrollEvent += Treeview1_ScrollEvent; + treeview1.SizeAllocated += Treeview1_SizeAllocated; scrollView1.Add(treeview1); this.AppendPage(scrollView1, new Label("Output")); @@ -25,7 +27,11 @@ public void Build() scrollView2 = new ScrolledWindow(); textView1 = new TextView(); + textView1.CursorVisible = false; + textView1.DoubleBuffered = false; textView1.Editable = false; + textView1.ScrollEvent += TextView1_ScrollEvent; + textView1.SizeAllocated += TextView1_SizeAllocated; scrollView2.Add(textView1); this.AppendPage(scrollView2, new Label("Output Log")); diff --git a/Tools/Pipeline/Gtk/Widgets/BuildOutput.cs b/Tools/Pipeline/Gtk/Widgets/BuildOutput.cs index 21d6455af1f..f615d1c9e2f 100644 --- a/Tools/Pipeline/Gtk/Widgets/BuildOutput.cs +++ b/Tools/Pipeline/Gtk/Widgets/BuildOutput.cs @@ -19,6 +19,7 @@ public partial class BuildOutput : Notebook OutputParser outputParser; Uri folderUri; + bool textScroll, treeScroll; public BuildOutput() { @@ -47,8 +48,6 @@ public BuildOutput() listStore = new TreeStore (typeof (Gdk.Pixbuf), typeof (string), typeof (string)); treeview1.Model = listStore; - - textView1.SizeAllocated += TextView1_SizeAllocated; } internal void SetBaseFolder(IController controller) @@ -61,16 +60,37 @@ internal void SetBaseFolder(IController controller) outputParser.Reset(); } + private void Treeview1_SizeAllocated (object o, SizeAllocatedArgs args) + { + if (treeScroll) + { + var path = new TreePath((treeview1.Model.IterNChildren() - 1).ToString()); + treeview1.ScrollToCell(path, null, false, 0, 0); + } + } + private void TextView1_SizeAllocated (object o, SizeAllocatedArgs args) { - textView1.ScrollToIter(textView1.Buffer.EndIter, 0, false, 0, 0); + if (textScroll) + textView1.ScrollToIter(textView1.Buffer.EndIter, 0, false, 0, 0); + } + + private void Treeview1_ScrollEvent (object o, ScrollEventArgs args) + { + treeScroll = false; + } + + private void TextView1_ScrollEvent (object o, ScrollEventArgs args) + { + textScroll = false; } public void OutputAppend(string text) { lock (textView1.Buffer) { - textView1.Buffer.Text += text + "\r\n"; + var iter = textView1.Buffer.EndIter; + textView1.Buffer.Insert(ref iter, text + Environment.NewLine); } if (string.IsNullOrWhiteSpace(text)) @@ -141,6 +161,8 @@ public void ClearOutput() textView1.Buffer.Text = ""; } + textScroll = true; + treeScroll = true; listStore.Clear(); } } diff --git a/Tools/Pipeline/Gtk/Widgets/ProjectView.cs b/Tools/Pipeline/Gtk/Widgets/ProjectView.cs index a4d78b6af8c..3096d6d789a 100644 --- a/Tools/Pipeline/Gtk/Widgets/ProjectView.cs +++ b/Tools/Pipeline/Gtk/Widgets/ProjectView.cs @@ -29,7 +29,7 @@ partial class ProjectView : VBox MainWindow window; PropertiesView propertiesView; - MenuItem treeadd, treeaddseperator, treenewitem, treeadditem, treenewfolder, treeaddfolder, treeopenfile, treerename, treedelete, treeopenfilelocation; + MenuItem treeadd, treeaddseperator, treenewitem, treeadditem, treenewfolder, treeaddfolder, treeopenfile, treeopenwith, treeexclude, treerename, treedelete, treeopenfilelocation; public ProjectView () { @@ -108,6 +108,9 @@ public void Initalize(MainWindow window, MenuItem treerebuild, PropertiesView pr treeaddfolder = new MenuItem ("Existing Folder..."); treeaddfolder.ButtonPressEvent += window.OnAddFolderActionActivated; + + treeexclude = new MenuItem("Exclude from Project"); + treeexclude.Activated += window.OnExcludeActionActivated; treerename = new MenuItem ("Rename"); treerename.Activated += window.OnRenameActionActivated; @@ -117,23 +120,23 @@ public void Initalize(MainWindow window, MenuItem treerebuild, PropertiesView pr treeopenfile = new MenuItem ("Open"); treeopenfile.Activated += delegate { - List iters; - List ids; - GetSelectedTreePath(out iters, out ids); + Process.Start(GetSelectedPath()); + }; - if (ids.Count != 1) - return; + treeopenwith = new MenuItem("Open With"); + treeopenwith.Activated += delegate + { +#if GTK3 + var filePath = GetSelectedPath(); + var adialoghandle = Gtk3Wrapper.gtk_app_chooser_dialog_new(window.Handle, 4 + (int)DialogFlags.Modal, Gtk3Wrapper.g_file_new_for_path(filePath)); - string start = openedProject; + var adialog = new AppChooserDialog(adialoghandle); - if(ids[0] != ID_BASE) - start = window._controller.GetFullPath(GetPathFromIter(iters[0])); + if(adialog.Run() == (int)ResponseType.Ok) + Process.Start(adialog.AppInfo.Executable, "\"" + filePath + "\""); - #if LINUX - Process.Start("xdg-open", start); - #else - Process.Start(start); - #endif + adialog.Destroy(); +#endif }; treeopenfilelocation = new MenuItem ("Open Item Directory"); @@ -155,15 +158,32 @@ public void Initalize(MainWindow window, MenuItem treerebuild, PropertiesView pr addmenu.Add (treeaddfolder); menu.Add (treeopenfile); + menu.Add (treeopenwith); menu.Add (treeadd); menu.Add (treeaddseperator); menu.Add (treeopenfilelocation); menu.Add (treerebuild); menu.Add (new SeparatorMenuItem ()); + menu.Add (treeexclude); + menu.Add (new SeparatorMenuItem ()); menu.Add (treerename); menu.Add (treedelete); } + public string GetSelectedPath() + { + List iters; + List ids; + GetSelectedTreePath(out iters, out ids); + + var path = openedProject; + + if(ids[0] != ID_BASE) + path = window._controller.GetFullPath(GetPathFromIter(iters[0])); + + return path; + } + public void SetBaseIter(string name) { basename = name; @@ -175,7 +195,7 @@ public void SetBaseIter(string name) public TreeIter GetBaseIter() { TreeIter iter; - + if(!treeview1.Model.GetIterFromString (out iter, "0")) iter = listStore.AppendValues (ICON_BASE, basename, ID_BASE); @@ -184,7 +204,8 @@ public TreeIter GetBaseIter() public void ExpandBase() { - treeview1.ExpandRow(treeview1.Model.GetPath(GetBaseIter()), false); + if (window._controller.ProjectOpen) + treeview1.ExpandRow(treeview1.Model.GetPath(GetBaseIter()), false); } public void Close() @@ -420,7 +441,7 @@ public void Rename() } } - public void Remove() + public void Remove(bool delete) { List iter; List ids; @@ -449,8 +470,8 @@ public void Remove() } } - if(items.Count > 0 || directories.Count > 0) - window._controller.Exclude (items, directories); + if (items.Count > 0 || directories.Count > 0) + window._controller.Exclude(items, directories, delete); } public void Rebuild() @@ -508,15 +529,7 @@ protected void OnTreeview1ButtonPressEvent (object o, ButtonPressEventArgs args) return; if (ids[0] == ID_FILE) - { - string start = window._controller.GetFullPath(GetPathFromIter(iters[0])); - - #if LINUX - Process.Start("xdg-open", start); - #else - Process.Start(start); - #endif - } + Process.Start(window._controller.GetFullPath(GetPathFromIter(iters[0]))); else { bool expanded = treeview1.GetRowExpanded(treeview1.Model.GetPath(iters[0])); @@ -816,17 +829,24 @@ void ShowMenu() menu.ShowAll (); if (ids[0] == ID_BASE) { treeadd.Visible = true; - treeopenfile.Visible = true; + treeopenfile.Visible = false; + treeopenwith.Visible = true; } else if (ids[0] == ID_FOLDER) { treeadd.Visible = true; treeopenfile.Visible = false; + treeopenwith.Visible = false; } else { treeadd.Visible = false; treeopenfile.Visible = true; + treeopenwith.Visible = true; } treerename.Visible = true; treeaddseperator.Visible = treeadd.Visible || treeopenfile.Visible; +#if !GTK3 + treeopenwith.Visible = false; +#endif + menu.Popup (); } } else { @@ -834,6 +854,7 @@ void ShowMenu() treeadd.Visible = false; treeopenfile.Visible = false; + treeopenwith.Visible = false; treeaddseperator.Visible = false; treeopenfile.Visible = false; treeopenfilelocation.Visible = false; diff --git a/Tools/Pipeline/Gtk/Widgets/PropertiesView.cs b/Tools/Pipeline/Gtk/Widgets/PropertiesView.cs index 909cd6d8f66..d9665b4444e 100644 --- a/Tools/Pipeline/Gtk/Widgets/PropertiesView.cs +++ b/Tools/Pipeline/Gtk/Widgets/PropertiesView.cs @@ -99,7 +99,7 @@ object CompareVariables(object a, object b) PropertyGridTable.EntryType.List ,(s,e) => { var lines = new List(); - lines.AddRange(((string)((FalseWidget)s).newvalue).Replace("\r\n", "~").Split('~')); + lines.AddRange(((string)((FalseWidget)s).newvalue).Split(System.IO.Path.PathSeparator)); foreach (object o in currentObjects) p.SetValue(o, lines, null); diff --git a/Tools/Pipeline/Gtk/Widgets/PropertyGridTable.cs b/Tools/Pipeline/Gtk/Widgets/PropertyGridTable.cs index cf193d9548e..918c96eb0a0 100644 --- a/Tools/Pipeline/Gtk/Widgets/PropertyGridTable.cs +++ b/Tools/Pipeline/Gtk/Widgets/PropertyGridTable.cs @@ -160,6 +160,7 @@ public PropertyGridTable () var fwidget = new FalseWidget(dialog.text); eitems[i].eventHandler(fwidget, EventArgs.Empty); model.SetValue(iter, 14, dialog.text); + model.SetValue(iter, 12, GetCollectionText(dialog.text)); break; } } @@ -216,7 +217,7 @@ public PropertyGridTable () } else { - #if LINUX + #if GTK3 Gdk.RGBA rgba = new Gdk.RGBA(); try @@ -370,6 +371,16 @@ public PropertyGridTable () treeview1.Model = listStore; } + private string GetCollectionText(string data) + { + var ret = data.Split(Environment.NewLine[0]); + + for (int i = 0; i < ret.Length; i++) + ret[i] = System.IO.Path.GetFileName(ret[i]); + + return string.Join(Environment.NewLine, ret); + } + TreeIter AddGroup(string name) { return listStore.AppendValues (name, true, "", false, "", false, false, null, "", false, false, "", "", false, "", "", false, "", false); @@ -385,8 +396,8 @@ TreeIter AddPropertyTextBox(TreeIter iter, string id, string name, string text, TreeIter AddPropertyCollectionBox(TreeIter iter, string id, string name, string data) { return !iter.Equals(nulliter) ? - listStore.AppendValues(iter, "", false, name, true, "", false, false, null, "", false, false, id, "Collection", true, data, "", false, "", false) : - listStore.AppendValues("", false, name, true, "", false, false, null, "", false, false, id, "Collection", true, data, "", false, "", false); + listStore.AppendValues(iter, "", false, name, true, "", false, false, null, "", false, false, id, GetCollectionText(data), true, data, "", false, "", false) : + listStore.AppendValues("", false, name, true, "", false, false, null, "", false, false, id, GetCollectionText(data), true, data, "", false, "", false); } TreeIter AddPropertyColorBox(TreeIter iter, string id, string name, string color) @@ -556,7 +567,7 @@ public TreeIter AddTreeItem(TreeItem item, TreeIter iter) { text = values[0]; for (int i = 1; i < values.Count; i++) - text += "\r\n" + values[i]; + text += Environment.NewLine + values[i]; } return AddPropertyCollectionBox(iter, eitem.id.ToString(), item.label, text); diff --git a/Tools/Pipeline/Icons/Toolbar/CancelBuild.png b/Tools/Pipeline/Icons/Toolbar/CancelBuild.png new file mode 100644 index 00000000000..8e3468e236c Binary files /dev/null and b/Tools/Pipeline/Icons/Toolbar/CancelBuild.png differ diff --git a/Tools/Pipeline/Icons/Toolbar/Redo.png b/Tools/Pipeline/Icons/Toolbar/Redo.png new file mode 100644 index 00000000000..ebed94483ae Binary files /dev/null and b/Tools/Pipeline/Icons/Toolbar/Redo.png differ diff --git a/Tools/Pipeline/Icons/Toolbar/Undo.png b/Tools/Pipeline/Icons/Toolbar/Undo.png new file mode 100644 index 00000000000..c941481297a Binary files /dev/null and b/Tools/Pipeline/Icons/Toolbar/Undo.png differ diff --git a/Tools/Pipeline/Program.cs b/Tools/Pipeline/Program.cs index be1f96d4878..f51a66661e6 100644 --- a/Tools/Pipeline/Program.cs +++ b/Tools/Pipeline/Program.cs @@ -3,11 +3,10 @@ // file 'LICENSE.txt', which is part of this source code package. using System; -using System.Diagnostics; #if WINDOWS +using System.Diagnostics; using System.Windows.Forms; -#endif -#if MONOMAC +#else using Gtk; #endif @@ -36,28 +35,35 @@ static void Main(string [] args) var controller = new PipelineController(view); Application.Run(view); +#else + Global.Initalize (); + Application.Init (); + + var win = new MainWindow (); + new PipelineController(win); + +#if GTK3 + if(Global.UseHeaderBar && Global.App != null) + Global.App.AddWindow(win); #endif -#if LINUX || MONOMAC - Gtk.Application.Init (); - Global.Initalize (); - MainWindow win = new MainWindow (); - win.Show (); - new PipelineController(win); - #if LINUX - if (args != null && args.Length > 0) - { - var projectFilePath = string.Join(" ", args); - win.OpenProjectPath = projectFilePath; - } - #elif MONOMAC - var project = Environment.GetEnvironmentVariable("MONOGAME_PIPELINE_PROJECT"); - if (!string.IsNullOrEmpty (project)) { - win.OpenProjectPath = project; - } - #endif - win.OnShowEvent (); - Gtk.Application.Run (); +#if LINUX + if (args != null && args.Length > 0) + { + var projectFilePath = string.Join(" ", args); + win.OpenProjectPath = projectFilePath; + } +#elif MONOMAC + var project = Environment.GetEnvironmentVariable("MONOGAME_PIPELINE_PROJECT"); + if (!string.IsNullOrEmpty (project)) { + win.OpenProjectPath = project; + } +#endif + + win.Show (); + win.OnShowEvent (); + + Application.Run (); #endif } } diff --git a/Tools/Pipeline/Windows/MainView.cs b/Tools/Pipeline/Windows/MainView.cs index 434a71a2376..4784352e5d3 100644 --- a/Tools/Pipeline/Windows/MainView.cs +++ b/Tools/Pipeline/Windows/MainView.cs @@ -342,6 +342,11 @@ public void ShowMessage(string message) MessageBox.Show(this, message, this.Text, MessageBoxButtons.OK, MessageBoxIcon.Information); } + public bool ShowDeleteDialog(string[] items) + { + throw new NotImplementedException(); + } + public void BeginTreeUpdate() { Debug.Assert(_treeUpdating == false, "Must finish previous tree update!"); @@ -824,7 +829,7 @@ private void OnDeleteItemClick(object sender, EventArgs e) dirs.Add(node.FullPath.Substring(_treeView.Nodes[0].Text.Length + 1)); } - _controller.Exclude(items, dirs); + _controller.Exclude(items, dirs, false); } private void ViewHelpMenuItemClick(object sender, EventArgs e)