loupiottes/DMX-2.0/MainWindow.cs

621 lines
No EOL
16 KiB
C#

using System;
using Gtk;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
namespace DMX2
{
public partial class MainWindow: Gtk.Window
{
static MainWindow win;
static object circuitKey = new object();
ListStore lsMatrice = null;
FileInfo conduiteFile=null;
public static MainWindow Win {
get { return win; }
}
public MainWindow (): base (Gtk.WindowType.Toplevel)
{
win=this;
Build ();
MajWidgets();
defStyle= this.Style;
}
#region Sequenceur Maitre
protected void ConstruitMatrice ()
{
this.MatriceUI.EnableGridLines = TreeViewGridLines.Both;
var idCol = new Gtk.TreeViewColumn ();
var idCell = new Gtk.CellRendererText ();
idCol.Title = "Num";
idCol.PackStart (idCell, true);
idCol.SetCellDataFunc (idCell, new Gtk.TreeCellDataFunc (RenderMatriceNum));
this.MatriceUI.AppendColumn (idCol);
var nomCol = new Gtk.TreeViewColumn ();
var nomCell = new Gtk.CellRendererText ();
nomCol.Title = "Nom";
nomCol.PackStart (nomCell, true);
nomCol.SetCellDataFunc (nomCell, new Gtk.TreeCellDataFunc (RenderMatriceNom));
nomCell.Editable = true;
nomCell.Edited += OnNomCellEdited;
this.MatriceUI.AppendColumn (nomCol);
var dureeCol = new Gtk.TreeViewColumn ();
var dureeCell = new Gtk.CellRendererText ();
dureeCol.Title = "Durée";
dureeCol.PackStart (dureeCell, true);
dureeCol.SetCellDataFunc (dureeCell, new Gtk.TreeCellDataFunc (RenderMatriceDuree));
dureeCell.Editable = true;
dureeCell.Edited += OnDureeCellEdited;
this.MatriceUI.AppendColumn (dureeCol);
lsMatrice = new Gtk.ListStore(typeof (SequenceurMaitre.Ligne));
this.MatriceUI.Model = lsMatrice;
FillMatrice();
}
void DetruitMatrice ()
{
this.MatriceUI.Model = null;
if (lsMatrice != null) lsMatrice.Dispose();
foreach (var col in MatriceUI.Columns)
MatriceUI.RemoveColumn (col);
}
static object seqkey = new object();
void ConstruitMatriceSeqColumns ()
{
foreach(var c in MatriceUI.Columns)
if(c.CellRenderers[0].Data.ContainsKey(seqkey))
MatriceUI.RemoveColumn(c);
Gtk.TreeViewColumn seqCol;
Gtk.CellRendererText seqCell;
foreach (Sequenceur seq in Conduite.Courante.Sequenceurs) {
seqCol = new TreeViewColumn();
seqCell = new CellRendererText();
seqCol.Title = seq.Name;
seqCol.PackStart(seqCell, true);
seqCol.SetCellDataFunc ( seqCell, new Gtk.TreeCellDataFunc(RenderMatriceSeqVal));
seqCell.Editable = true;
seqCell.Edited += OnSeqValCellEdited;
seqCell.Data[seqkey] = seq;
this.MatriceUI.AppendColumn(seqCol);
}
}
void RenderMatriceNum (TreeViewColumn tree_column, CellRenderer cell, TreeModel tree_model, TreeIter iter)
{
if (Conduite.Courante==null) return;
string num=string.Empty;
SequenceurMaitre.Ligne l = tree_model.GetValue (iter, 0) as SequenceurMaitre.Ligne;
if( Conduite.Courante.SequenceurMaitre.IndexLigneEnCours == Conduite.Courante.SequenceurMaitre.Lignes.IndexOf(l) )
num+= "->";
if( Conduite.Courante.SequenceurMaitre.IndexLigneaSuivre == Conduite.Courante.SequenceurMaitre.Lignes.IndexOf(l) )
num+= "* ";
(cell as Gtk.CellRendererText).Text = num + (Conduite.Courante.SequenceurMaitre.Lignes.IndexOf(l)+1).ToString();
}
void RenderMatriceNom (TreeViewColumn tree_column, CellRenderer cell, TreeModel tree_model, TreeIter iter)
{
if (Conduite.Courante==null) return;
SequenceurMaitre.Ligne l = tree_model.GetValue (iter, 0) as SequenceurMaitre.Ligne;
(cell as Gtk.CellRendererText).Text = l.Nom;
}
void RenderMatriceDuree (TreeViewColumn tree_column, CellRenderer cell, TreeModel tree_model, TreeIter iter)
{
if (Conduite.Courante==null) return;
SequenceurMaitre.Ligne l = tree_model.GetValue (iter, 0) as SequenceurMaitre.Ligne;
if (l.Duree== TimeSpan.Zero) (cell as Gtk.CellRendererText).Text = string.Empty;
else (cell as Gtk.CellRendererText).Text = (l.Duree.TotalMilliseconds /100).ToString();
}
void RenderMatriceSeqVal (TreeViewColumn tree_column, CellRenderer cell, TreeModel tree_model, TreeIter iter)
{
if (Conduite.Courante==null) return;
SequenceurMaitre.Ligne l = tree_model.GetValue (iter, 0) as SequenceurMaitre.Ligne;
Sequenceur seq = cell.Data[seqkey] as Sequenceur;
(cell as Gtk.CellRendererText).Text = l[seq];
}
void FillMatrice ()
{
lsMatrice.Clear ();
foreach (SequenceurMaitre.Ligne l in Conduite.Courante.SequenceurMaitre.Lignes) {
lsMatrice.AppendValues(l);
}
}
void OnNomCellEdited (object o, EditedArgs args)
{
Gtk.TreeIter iter;
lsMatrice.GetIter (out iter, new Gtk.TreePath (args.Path));
SequenceurMaitre.Ligne l = lsMatrice.GetValue(iter,0) as SequenceurMaitre.Ligne;
l.Nom = args.NewText;
}
void OnDureeCellEdited (object o, EditedArgs args)
{
Gtk.TreeIter iter;
lsMatrice.GetIter (out iter, new Gtk.TreePath (args.Path));
SequenceurMaitre.Ligne l = lsMatrice.GetValue (iter, 0) as SequenceurMaitre.Ligne;
if (args.NewText.Length == 0)
l.Duree = TimeSpan.Zero;
else {
int val;
if(int.TryParse(args.NewText, out val))
l.Duree = TimeSpan.FromMilliseconds(val *100);
}
}
void OnSeqValCellEdited (object o, EditedArgs args)
{
Gtk.CellRendererText cell = o as CellRendererText;
Sequenceur seq = cell.Data[seqkey] as Sequenceur;
Gtk.TreeIter iter;
lsMatrice.GetIter (out iter, new Gtk.TreePath (args.Path));
SequenceurMaitre.Ligne l = lsMatrice.GetValue(iter,0) as SequenceurMaitre.Ligne;
l[seq] = args.NewText;
}
int IndexEffetSelectionne()
{
var sel = MatriceUI.Selection.GetSelectedRows();
if(sel.Length ==0) return -1;
return MatriceUI.Selection.GetSelectedRows()[0].Indices[0];
}
void SelectionneEffet (int index)
{
if(index <0 ) return;
MatriceUI.SetCursor( new TreePath( new int[1] {index }) ,null,false);
}
protected void OnBtnAjoutLigneClicked (object sender, EventArgs e)
{
int pos=IndexEffetSelectionne() + 1;
Conduite.Courante.SequenceurMaitre.AjoutLigne(pos);
FillMatrice();
MatriceUI.SetCursor( new TreePath( new int[1] {pos }) , MatriceUI.Columns[1] ,true);
}
protected void OnBtnRetireLigneClicked (object sender, EventArgs e)
{
if(IndexEffetSelectionne()==-1) return;
Conduite.Courante.SequenceurMaitre.RetireLigne(IndexEffetSelectionne());
FillMatrice();
}
protected void OnBtnGoBackClicked (object sender, EventArgs e)
{
Conduite.Courante.SequenceurMaitre.EffetPrecedent();
//FillMatrice();
}
protected void OnBtnGoClicked (object sender, EventArgs e)
{
Conduite.Courante.SequenceurMaitre.EffetSuivant();
//FillMatrice();
}
protected void OnMatriceUICursorChanged (object sender, EventArgs e)
{
if (Conduite.Courante==null) return;
TreeViewColumn col;
TreePath path;
MatriceUI.GetCursor (out path, out col);
if (MatriceUI.Columns [0] == col) {
Conduite.Courante.SequenceurMaitre.IndexLigneaSuivre = IndexEffetSelectionne();
}
}
#endregion
#region Application
protected void OnDeleteEvent (object sender, DeleteEventArgs a)
{
Application.Quit ();
a.RetVal = true;
}
protected void OnQuitActionActivated (object sender, EventArgs e)
{
Application.Quit ();
}
#endregion
#region Gestion de la Conduite
protected void OnNewActionActivated (object sender, EventArgs e)
{
var dlg = new Dialog ("Nom ?", this, DialogFlags.Modal); var entry = new Entry ("Conduite sans Nom");
dlg.AddButton (Stock.Ok, ResponseType.Ok).GrabDefault(); dlg.AddButton (Stock.Cancel, ResponseType.Cancel);
dlg.VBox.Add (new Label("Nom de la nouvelle Conduite :")); dlg.VBox.Add (entry); dlg.VBox.ShowAll ();
entry.ActivatesDefault=true;
if ((ResponseType)dlg.Run () == ResponseType.Ok) {
Conduite.Courante = new Conduite ();
Conduite.Courante.Name = entry.Text;
}
MajWidgets();
dlg.Destroy();
}
protected void OnCloseActionActivated (object sender, EventArgs e)
{
Conduite.Courante.Dispose();
Conduite.Courante= null;
MajWidgets();
}
protected void OnSaveActionActivated (object sender, EventArgs e)
{
if(conduiteFile==null)
SaveFileAs();
else
SaveFile();
}
protected void OnSaveAsActionActivated (object sender, EventArgs e)
{
SaveFileAs();
}
void SaveFileAs ()
{
FileChooserDialog fcd = new FileChooserDialog ("Sauver sous ...", this, FileChooserAction.Save,
"Annuler", ResponseType.Cancel,
"Enregistrer", ResponseType.Accept);
fcd.Filter = new FileFilter ();
fcd.Filter.AddPattern ("*.dmx2");
bool ok = false;
while (!ok) {
if ((ResponseType)fcd.Run () == ResponseType.Cancel) {
fcd.Destroy ();
return;
}
string file = fcd.Filename;
if (!file.EndsWith (".dmx2"))
file += ".dmx2";
conduiteFile = new FileInfo(file);
if(conduiteFile.Exists)
{
MessageDialog msg = new MessageDialog(fcd,DialogFlags.Modal,
MessageType.Warning,
ButtonsType.YesNo,
"Le fichier existe déja. \nVoulez vous écraser le fichier existant ?");
if ((ResponseType)msg.Run () == ResponseType.Yes)ok=true;
msg.Destroy();
}
else ok=true;
}
fcd.Destroy();
SaveFile();
}
void SaveFile ()
{
if (conduiteFile == null)
return;
using (FileStream stream = conduiteFile.Open(FileMode.Create,FileAccess.Write)) {
System.Xml.XmlDocument doc = Conduite.Courante.Save ();
doc.Save (stream);
stream.Close ();
}
}
protected void OnOpenActionActivated (object sender, EventArgs e)
{
FileChooserDialog fcd = new FileChooserDialog ("Sauver sous ...", this, FileChooserAction.Open,
"Annuler", ResponseType.Cancel,
"Ouvrir", ResponseType.Accept);
fcd.Filter = new FileFilter ();
fcd.Filter.AddPattern ("*.dmx2");
if ((ResponseType)fcd.Run () == ResponseType.Cancel) {
fcd.Destroy ();
return;
}
FileInfo openFile = new FileInfo (fcd.Filename);
fcd.Destroy ();
if (!openFile.Exists)
return;
System.Xml.XmlDocument doc;
try {
using(FileStream stream = openFile.OpenRead())
{
doc = new System.Xml.XmlDocument();
doc.Load(stream);
stream.Close();
}
Conduite cond = Conduite.Load(doc);
if (cond==null)
{
// TODO Message erreur au chargement
return;
}
Conduite.Courante = cond;
conduiteFile = openFile;
} catch (IOException) {
}
foreach (Sequenceur s in Conduite.Courante.Sequenceurs)
AddSeqUI (s);
MajWidgets();
NextUpdateFull();
}
#endregion
#region Gestion des Circuits
protected void OnCircuitsActionActivated (object sender, EventArgs e)
{
GestionCircuits gc= new GestionCircuits(this);
gc.Run();
gc.Destroy();
NextUpdateFull();
}
#endregion
#region Gestion des Sequenceurs
// bonton ajout de sequenceur linéraire
protected void OnSeqLinActionActivated (object sender, EventArgs e)
{
Sequenceur s = new SequenceurLineaire();
Conduite.Courante.AjoutSequenceur(s);
AddSeqUI(s);
NextUpdateFull();
}
void AddSeqUI (Sequenceur s)
{
onglets.AppendPage(s.GetUI(),new Gtk.Label(s.Name));
onglets.ShowAll();
}
protected void OnShowAllActionActivated (object sender, EventArgs e)
{
foreach (var notebookchild in onglets.Children)
notebookchild.Destroy();
foreach (Sequenceur s in Conduite.Courante.Sequenceurs)
AddSeqUI(s);
}
protected void OnSeqMacroActionActivated (object sender, EventArgs e)
{
Sequenceur s = new SequenceurMacro();
Conduite.Courante.AjoutSequenceur(s);
AddSeqUI(s);
NextUpdateFull();
}
#endregion
#region Gestion de l'affichage
bool updScheduled=false;
bool fullUpdateFlag=false;
public void NextUpdateFull ()
{
fullUpdateFlag=true;
}
public void ScheduleUpdate ()
{
if (updScheduled) {
//Console.WriteLine("{0} Skip !",DateTime.Now);
return;
}
updScheduled=true;
Gtk.Application.Invoke(new EventHandler(Update));
}
void Update (object sender, EventArgs e)
{
if(Conduite.Courante==null)return;
foreach (var notebookchild in onglets.Children) {
SequenceurUI sequi = notebookchild as SequenceurUI;
if(sequi != null) sequi.Update(fullUpdateFlag);
}
MajCircuits(fullUpdateFlag);
timeLabel.LabelProp = string.Format (@"<big>{0:0\.0}</big>", Conduite.Courante.SequenceurMaitre.TimeStamp.TotalMilliseconds / 100);
if(fullUpdateFlag) ConstruitMatriceSeqColumns();
if( Conduite.Courante.SequenceurMaitre.EffetChange() )MatriceUI.QueueDraw();
fullUpdateFlag=false;
updScheduled=false;
}
protected void MajWidgets ()
{
if (Conduite.Courante != null) {
//Activation / Désactivation des boutons en fonction de l'état de la counduite courante
btnAjoutLigne.Sensitive = btnRetireLigne.Sensitive = btnGo.Sensitive = btnGoBack.Sensitive =
showAllAction.Sensitive = universAction.Sensitive = masterScale.Sensitive =
seqLinAction.Sensitive = seqMacroAction.Sensitive = circAction.Sensitive = saveAction.Sensitive =
btnPause.Sensitive = btnBlackOut.Sensitive =
saveAsAction.Sensitive = closeAction.Sensitive = true;
openAction.Sensitive = newAction.Sensitive = false;
this.Title = "DMX 2.0 - " + Conduite.Courante.Name;
ConstruitMatrice();
} else {
btnAjoutLigne.Sensitive = btnRetireLigne.Sensitive = btnGo.Sensitive = btnGoBack.Sensitive =
showAllAction.Sensitive = universAction.Sensitive = masterScale.Sensitive =
seqLinAction.Sensitive = seqMacroAction.Sensitive = circAction.Sensitive = saveAction.Sensitive =
btnPause.Sensitive = btnBlackOut.Sensitive =
saveAsAction.Sensitive = closeAction.Sensitive = false;
openAction.Sensitive = newAction.Sensitive = true;
this.Title = "DMX 2.0";
DetruitMatrice();
foreach (var widget in vboxCircuits.Children)
vboxCircuits.Remove (widget);
foreach (var notebookvbox in onglets.Children)
notebookvbox.Destroy();
}
}
protected void MajCircuits (bool full)
{
// Ajoute une ProgressBar par circuit, met a jour le texte si necessaire
ProgressBar pb;int i = 0;
if (full) {
foreach (var widget in vboxCircuits.Children)
vboxCircuits.Remove (widget);
foreach (var circuit in Conduite.Courante.Circuits) {
vboxCircuits.PackStart (pb=new ProgressBar (),false,false,0);
pb.Text = (++i).ToString() + " - " + circuit.Name;
pb.HeightRequest = 12;
pb.Data[circuitKey] = circuit;
pb.Name ="pb";
}
vboxCircuits.ShowAll ();
}
foreach (var widget in vboxCircuits.Children) {
pb = (ProgressBar)widget;
pb.Fraction = (double) (pb.Data[circuitKey] as Circuit).ValeurCourante / 255;
}
}
#endregion
protected void OnMasterScaleValueChanged (object sender, EventArgs e)
{
Conduite.Courante.Master = (int)(masterScale.Value);
ChangeMatriceCouleur();
}
bool isfullscreen=false;
protected void OnFullscreenAction1Activated (object sender, EventArgs e)
{
if (!isfullscreen) {
Fullscreen ();
isfullscreen = true;
} else {
Unfullscreen();
isfullscreen = false;
}
}
#region Boite dialogue Univers
EditionUnivers uDlg = null;
protected void OnUniversActionActivated (object sender, EventArgs e)
{
if (uDlg != null) {
uDlg.Show();
return;
}
uDlg = new EditionUnivers(this);
uDlg.ShowAll();
uDlg.Destroyed += udlgDestroyed;
}
void udlgDestroyed (object sender, EventArgs e)
{
uDlg=null;
}
#endregion
protected void OnConnectActionActivated (object sender, EventArgs e)
{
Conduite.Courante.Drivers.Add( new DriverBoitierV1());
}
protected void OnBtnPauseToggled (object sender, EventArgs e)
{
Conduite.Courante.Pause = btnPause.Active;
ChangeMatriceCouleur();
}
protected void OnBtnBlackOutToggled (object sender, EventArgs e)
{
Conduite.Courante.BlackOut = btnBlackOut.Active;
ChangeMatriceCouleur();
}
Style defStyle;
void ChangeMatriceCouleur ()
{
if (Conduite.Courante.BlackOut) {
evInfo.ModifyBg (Gtk.StateType.Normal,new Gdk.Color (255, 100, 100));
return;
}
if (Conduite.Courante.Pause) {
evInfo.ModifyBg (Gtk.StateType.Normal,new Gdk.Color (255, 255, 100));
return;
}
if (Conduite.Courante.Master != 100) {
evInfo.ModifyBg (Gtk.StateType.Normal,new Gdk.Color (205, 205, 255));
return;
}
evInfo.ModifyBg (Gtk.StateType.Normal, defStyle.Background(StateType.Normal) );
}
}
}