/*
Copyright (C) Arnaud Houdelette 2012-2014
Copyright (C) Emmanuel Langlois 2012-2014
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
using System;
using System.Collections.Generic;
using Gtk;
using System.Text;
namespace DMX2
{
[System.ComponentModel.ToolboxItem(true)]
public partial class SeqMacroUI : SequenceurUI
{
bool fullUpdFlag = true;
bool updating;
SequenceurMacro sequenceur; /* pointe sur les données */
ListStore lsEffets=null; /* liste des effets */
//TreeViewColumn nomCol; /* inutile dans le contexte macro */
bool effetChange = false;
public void EffetChange ()
{
effetChange = true;
}
DateTime nextMaj = DateTime.Now;
void RenamePopup (object sender, ContextMenuEventArgs e)
{
Menu m = new Menu();
MenuItem renameItem = new MenuItem("Renommer le Sequenceur");
renameItem.ButtonPressEvent += new ButtonPressEventHandler(OnRenameItemButtonPressed);
m.Add(renameItem);
m.ShowAll();
m.Popup();
}
void OnRenameItemButtonPressed (object o, ButtonPressEventArgs args)
{
var dlg = new Dialog ("Nouveau Nom ?", GetAncestor(Gtk.Window.GType) as Gtk.Window , DialogFlags.Modal); var entry = new Entry (sequenceur.Name);
dlg.AddButton (Stock.Ok, ResponseType.Ok).GrabDefault(); dlg.AddButton (Stock.Cancel, ResponseType.Cancel);
dlg.VBox.Add (entry); dlg.VBox.ShowAll ();
entry.ActivatesDefault=true;
if ((ResponseType)dlg.Run () == ResponseType.Ok) {
sequenceur.Name = entry.Text;
titreLabel.Text = sequenceur.Name;
}
dlg.Destroy();
}
#region construction et gestion de la matrice d'affichage
protected void ConstruitMatrice () /* Matrice d'affichage des effets de la macro */
{
effetsListe.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));
effetsListe.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;
effetsListe.AppendColumn (nomCol);
var topCol = new Gtk.TreeViewColumn ();
var topCell = new Gtk.CellRendererText ();
topCol.Title = "Top";
topCol.PackStart (topCell, true);
topCol.SetCellDataFunc (topCell, new Gtk.TreeCellDataFunc (RenderMatriceTop));
topCell.Editable = true;
topCell.Edited += OnTopCellEdited;
effetsListe.AppendColumn (topCol);
var circuitsCol = new Gtk.TreeViewColumn ();
var circuitsCell = new Gtk.CellRendererText ();
circuitsCol.Title = "Circuits";
circuitsCol.PackStart (circuitsCell, true);
circuitsCol.SetCellDataFunc (circuitsCell, new Gtk.TreeCellDataFunc (RenderMatriceCircuits));
circuitsCell.Editable = true;
circuitsCell.Edited += OnCircuitsCellEdited;
effetsListe.AppendColumn (circuitsCol);
var valeurCol = new Gtk.TreeViewColumn ();
var valeurCell = new Gtk.CellRendererText ();
valeurCol.Title = "Valeur";
valeurCol.PackStart (valeurCell, true);
valeurCol.SetCellDataFunc (valeurCell, new Gtk.TreeCellDataFunc (RenderMatriceValeur));
valeurCell.Editable = true;
valeurCell.Edited += OnValeurCellEdited;
effetsListe.AppendColumn (valeurCol);
var tempsCol = new Gtk.TreeViewColumn ();
var tempsCell = new Gtk.CellRendererText ();
tempsCol.Title = "Temps";
tempsCol.PackStart (tempsCell, true);
tempsCol.SetCellDataFunc (tempsCell, new Gtk.TreeCellDataFunc (RenderMatriceTemps));
tempsCell.Editable = true;
tempsCell.Edited += OnTempsCellEdited;
effetsListe.AppendColumn (tempsCol);
lsEffets = new Gtk.ListStore(typeof (SequenceurMacro.Ligne));
this.effetsListe.Model = lsEffets;
UpdListeEffets();
}
void RenderMatriceNum (TreeViewColumn tree_column, CellRenderer cell, TreeModel tree_model, TreeIter iter)
{
if (Conduite.Courante==null) return;
string num=string.Empty;
SequenceurMacro.Ligne l = tree_model.GetValue (iter, 0) as SequenceurMacro.Ligne;
if( sequenceur.IndexLigneEnCours == sequenceur.Lignes.IndexOf(l) )
num+= "->";
if( sequenceur.IndexLigneaSuivre == sequenceur.Lignes.IndexOf(l) )
num+= "* ";
(cell as Gtk.CellRendererText).Text = num + (sequenceur.Lignes.IndexOf(l)+1).ToString();
}
void RenderMatriceNom (TreeViewColumn tree_column, CellRenderer cell, TreeModel tree_model, TreeIter iter)
{
if (Conduite.Courante==null) return;
SequenceurMacro.Ligne l = tree_model.GetValue (iter, 0) as SequenceurMacro.Ligne;
(cell as Gtk.CellRendererText).Text = l.Nom;
}
void RenderMatriceTop (TreeViewColumn tree_column, CellRenderer cell, TreeModel tree_model, TreeIter iter)
{
if (Conduite.Courante==null) return;
SequenceurMacro.Ligne l = tree_model.GetValue (iter, 0) as SequenceurMacro.Ligne;
if (l.Top< TimeSpan.Zero) (cell as Gtk.CellRendererText).Text = string.Empty;
else (cell as Gtk.CellRendererText).Text = (l.Top.TotalMilliseconds /100).ToString();
}
void RenderMatriceCircuits (TreeViewColumn tree_column, CellRenderer cell, TreeModel tree_model, TreeIter iter)
{
if (Conduite.Courante==null) return;
SequenceurMacro.Ligne l = tree_model.GetValue (iter, 0) as SequenceurMacro.Ligne;
(cell as Gtk.CellRendererText).Text = l.Circuits;
}
void RenderMatriceValeur (TreeViewColumn tree_column, CellRenderer cell, TreeModel tree_model, TreeIter iter)
{
if (Conduite.Courante==null) return;
SequenceurMacro.Ligne l = tree_model.GetValue (iter, 0) as SequenceurMacro.Ligne;
(cell as Gtk.CellRendererText).Text = (l.Valeur).ToString();
}
void RenderMatriceTemps (TreeViewColumn tree_column, CellRenderer cell, TreeModel tree_model, TreeIter iter)
{
if (Conduite.Courante==null) return;
SequenceurMacro.Ligne l = tree_model.GetValue (iter, 0) as SequenceurMacro.Ligne;
(cell as Gtk.CellRendererText).Text = (l.Temps.TotalMilliseconds /100).ToString();
}
void OnNomCellEdited (object o, EditedArgs args)
{
Gtk.TreeIter iter;
lsEffets.GetIter (out iter, new Gtk.TreePath (args.Path));
SequenceurMacro.Ligne l = lsEffets.GetValue(iter,0) as SequenceurMacro.Ligne;
l.Nom = args.NewText;
}
void OnTopCellEdited (object o, EditedArgs args)
{
Gtk.TreeIter iter;
lsEffets.GetIter (out iter, new Gtk.TreePath (args.Path));
SequenceurMacro.Ligne l = lsEffets.GetValue (iter, 0) as SequenceurMacro.Ligne;
if (args.NewText.Length == 0)
l.Top = TimeSpan.MinValue;
else {
int val;
if(int.TryParse(args.NewText, out val))
l.Top = TimeSpan.FromMilliseconds(val *100);
}
}
void OnCircuitsCellEdited (object o, EditedArgs args)
{
Gtk.TreeIter iter;
lsEffets.GetIter (out iter, new Gtk.TreePath (args.Path));
SequenceurMacro.Ligne l = lsEffets.GetValue(iter,0) as SequenceurMacro.Ligne;
l.Circuits = args.NewText;
}
void OnValeurCellEdited (object o, EditedArgs args)
{
Gtk.TreeIter iter;
lsEffets.GetIter (out iter, new Gtk.TreePath (args.Path));
SequenceurMacro.Ligne l = lsEffets.GetValue(iter,0) as SequenceurMacro.Ligne;
int val;
if(int.TryParse(args.NewText,out val)) l.Valeur = val;
}
void OnTempsCellEdited (object o, EditedArgs args)
{
Gtk.TreeIter iter;
lsEffets.GetIter (out iter, new Gtk.TreePath (args.Path));
SequenceurMacro.Ligne l = lsEffets.GetValue (iter, 0) as SequenceurMacro.Ligne;
if (args.NewText.Length == 0)
l.Temps = TimeSpan.Zero;
else {
int val;
if(int.TryParse(args.NewText, out val))
l.Temps = TimeSpan.FromMilliseconds(val *100);
}
}
void UpdListeEffets ()
{
lsEffets.Clear();
foreach (var ligne in sequenceur.Lignes) {
lsEffets.AppendValues(ligne);
}
}
#endregion
public SeqMacroUI (SequenceurMacro s ) : base (s)
{
this.Build ();
titreLabel.Text = s.Name;
sequenceur = s;
ConstruitMatrice ();
new ContextMenuHelper(seqMasterScale,MasterPopup);
new ContextMenuHelper(frame1,RenamePopup);
new ContextMenuHelper(evBBox,CompteurPopup);
}
void MasterPopup (object sender, ContextMenuEventArgs e)
{
Menu m = Conduite.Courante.EventManager.GetMenu(null,
delegate(object o,string eventId){
sequenceur.BindMasterEvent(eventId);
}
);
m.ShowAll();
m.Popup();
}
void CompteurPopup (object sender, ContextMenuEventArgs e)
{
Menu m = new Menu();
MenuItem item = new MenuItem("Effet Suivant");
m.Add(item);
item.Submenu = Conduite.Courante.EventManager.GetMenu(null,
delegate(object o,string eventId){
sequenceur.BindEffetSuivantEvent(eventId);
}
);
item = new MenuItem("Effet Precedent");
m.Add(item);
item.Submenu = Conduite.Courante.EventManager.GetMenu(null,
delegate(object o,string eventId){
sequenceur.BindEffetPrecedentEvent(eventId);
}
);
m.ShowAll();
m.Popup();
}
public override void Update (bool full)
{
if (fullUpdFlag || full)
FullUpdate ();
// UpdateValues (); inutil dans le contexte
timeLabel.LabelProp = string.Format (@"{0:0\.0}", sequenceur.TimeStamp.TotalMilliseconds / 100);
if (effetChange) {
//UpdListeEffets();
effetsListe.QueueDraw();
SelectionneEffet (sequenceur.IndexLigneEnCours);
posLabel.Text = string.Format("n°{0}",sequenceur.IndexLigneEnCours +1 );
}
updating = true;
seqMasterScale.Value = sequenceur.Master;
updating = false;
if (DateTime.Now > nextMaj ) {
nextMaj = DateTime.Now.AddMilliseconds(500);
StringBuilder str = new StringBuilder ();
bool a = false;
foreach (Circuit c in sequenceur.Circuits) {
if (sequenceur.ValeurBruteCircuit (c) > 0) {
if (sequenceur.EstActif (c) != a) {
if(!a){
str.Append ("");
a = true;
} else {
str.Append ("");
a = false;
}
}
str.Append (c.ID); str.Append (' ');
}
}
if (a) {
str.Append ("");
a = false;
}
actLabel.LabelProp = str.ToString ();
}
}
void SelectionneEffet (int index)
{
if(index <0 ) return;
effetsListe.SetCursor( new TreePath( new int[1] {index }) ,null,false);
effetChange = false;
}
protected void OnCircuitsActionActivated (object sender, EventArgs e)
{
// récupère la fenètre principale
Window win = this.GetAncestor(Gtk.Window.GType) as Window;
var dlg = new SelSeqCircuits (sequenceur.Circuits,win);
if ((ResponseType)dlg.Run () == ResponseType.Ok) {
sequenceur.ChangeCircuits(dlg.GetResultList());
}
dlg.Destroy();
fullUpdFlag = true;
}
protected void OnCloseActionActivated (object sender, EventArgs e)
{
this.Destroy();
}
protected void FullUpdate ()
{
fullUpdFlag = true;
posLabel.Text = string.Format("n°{0}",sequenceur.IndexLigneEnCours +1);
fullUpdFlag=false;
}
int IndexEffetSelectionne()
{
var sel = effetsListe.Selection.GetSelectedRows();
if(sel.Length ==0) return -1;
return effetsListe.Selection.GetSelectedRows()[0].Indices[0];
}
protected void OnGoForwardActionActivated (object sender, EventArgs e)
{
sequenceur.LigneSuivante();
}
protected void OnGoBackActionActivated (object sender, EventArgs e)
{
if (sequenceur.IndexLigneEnCours > 0) {
sequenceur.IndexLigneaSuivre = sequenceur.IndexLigneEnCours - 1;
sequenceur.LigneSuivante ();
}
}
protected void OnMediaPauseActionActivated (object sender, EventArgs e)
{
sequenceur.Paused = ! sequenceur.Paused;
}
protected void OnSeqMasterScaleValueChanged (object sender, EventArgs e)
{
if (updating)return;
sequenceur.Master = (int)(seqMasterScale.Value);
}
protected void OnBtnAjoutLigneActivated (object sender, EventArgs e)
{
int pos=IndexEffetSelectionne() + 1;
sequenceur.AjoutLigne(pos);
UpdListeEffets();
effetsListe.SetCursor( new TreePath( new int[1] {pos }) , effetsListe.Columns[1] ,true);
}
protected void OnRemoveLigneActivated (object sender, EventArgs e)
{
int pos = IndexEffetSelectionne();
if (pos==-1) return;
sequenceur.RetireLigne(pos);
UpdListeEffets();
}
protected void OnEffetsListeCursorChanged (object sender, EventArgs e)
{
if(effetChange) return;
TreeViewColumn col;
TreePath path;
effetsListe.GetCursor (out path, out col);
if (effetsListe.Columns [0] == col) {
sequenceur.IndexLigneaSuivre = IndexEffetSelectionne();
}
}
protected void OnBtnCommandClicked (object sender, EventArgs e)
{
sequenceur.CommandDirecte(txtCommand.Text );
}
protected void OnHbox2SizeAllocated (object o, SizeAllocatedArgs args)
{
actLabel.SetSizeRequest ( Math.Max(50, args.Allocation.Width - posLabel.Allocation.Width - timeLabel.Allocation.Width - 50),-1);
}
}
}