/*
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;
namespace DMX2
{
[System.ComponentModel.ToolboxItem(true)]
public partial class SeqLinUI : SequenceurUI
{
bool fullUpdFlag = true;
SequenceurLineaire sequenceur;
ListStore lsEffets=null;
TreeViewColumn nomCol;
bool effetChange = false;
public void EffetChange ()
{
effetChange = true;
}
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();
}
public SeqLinUI (SequenceurLineaire s ) : base (s)
{
this.Build ();
titreLabel.Text = s.Name;
sequenceur = s;
tirettesContextHelper.ContextMenu += TirettePopup;
new ContextMenuHelper(seqMasterScale,MasterPopup);
new ContextMenuHelper(evBBox,CompteurPopup);
new ContextMenuHelper(frame1,RenamePopup);
#region Construction listeEffets
// Construction de la liste d'effets
var numCol = new TreeViewColumn();
nomCol = new TreeViewColumn();
var dureeCol = new TreeViewColumn();
var transCol = new TreeViewColumn();
var numCell = new CellRendererText();
var nomCell = new CellRendererText();
var dureeCell = new CellRendererText();
var transCell = new CellRendererText();
numCol.Title = "N°";
nomCol.Title = "Effet";
dureeCol.Title = "Duree";
transCol.Title = "Transition";
numCol.PackEnd(numCell,true);
nomCol.PackStart(nomCell,true);
dureeCol.PackEnd(dureeCell,true);
transCol.PackEnd(transCell,true);
numCol.SetCellDataFunc(numCell, new TreeCellDataFunc(RenderNum));
nomCol.SetCellDataFunc(nomCell, new TreeCellDataFunc(RenderNom));
dureeCol.SetCellDataFunc(dureeCell, new TreeCellDataFunc(RenderDuree));
transCol.SetCellDataFunc(transCell, new TreeCellDataFunc(RenderTrans));
nomCol.MinWidth = 150;
nomCol.Expand=true;
dureeCol.MaxWidth=50;
transCol.MaxWidth=50;
effetsListe.AppendColumn(numCol);
effetsListe.AppendColumn(nomCol);
effetsListe.AppendColumn(transCol);
effetsListe.AppendColumn(dureeCol);
lsEffets = new ListStore(typeof(SequenceurLineaire.Effet));
effetsListe.Model = lsEffets;
nomCell.Editable = true;
dureeCell.Editable = true;
transCell.Editable = true;
nomCell.Edited += EditNom;
dureeCell.Edited += EditDuree;
transCell.Edited += EditTrans;
//Update(true);
UpdListeEffets();
#endregion
}
void EditNom (object o, EditedArgs args)
{
Gtk.TreeIter iter;
lsEffets.GetIter (out iter, new Gtk.TreePath (args.Path));
SequenceurLineaire.Effet e = lsEffets.GetValue(iter,0) as SequenceurLineaire.Effet;
e.Nom = args.NewText;
}
void EditDuree (object o, EditedArgs args)
{
Gtk.TreeIter iter;int d;
lsEffets.GetIter (out iter, new Gtk.TreePath (args.Path));
SequenceurLineaire.Effet e = lsEffets.GetValue(iter,0) as SequenceurLineaire.Effet;
if(int.TryParse(args.NewText , out d))
e.Duree = TimeSpan.FromMilliseconds(d * 100);
}
void EditTrans (object o, EditedArgs args)
{
Gtk.TreeIter iter; int t;
lsEffets.GetIter (out iter, new Gtk.TreePath (args.Path));
SequenceurLineaire.Effet e = lsEffets.GetValue(iter,0) as SequenceurLineaire.Effet;
if(int.TryParse(args.NewText , out t))
e.Transition = TimeSpan.FromMilliseconds(t * 100);
}
#region Affichage Liste d'Effets
void RenderNum (TreeViewColumn tree_column, CellRenderer cell, TreeModel tree_model, TreeIter iter)
{
SequenceurLineaire.Effet e = tree_model.GetValue (iter, 0) as SequenceurLineaire.Effet;
(cell as Gtk.CellRendererText).Text = (sequenceur.Effets.IndexOf(e)+1).ToString() ;
}
void RenderNom (TreeViewColumn tree_column, CellRenderer cell, TreeModel tree_model, TreeIter iter)
{
SequenceurLineaire.Effet e = tree_model.GetValue (iter, 0) as SequenceurLineaire.Effet;
(cell as Gtk.CellRendererText).Text = e.Nom;
}
void RenderDuree (TreeViewColumn tree_column, CellRenderer cell, TreeModel tree_model, TreeIter iter)
{
SequenceurLineaire.Effet e = tree_model.GetValue (iter, 0) as SequenceurLineaire.Effet;
(cell as Gtk.CellRendererText).Text = (e.Duree.TotalMilliseconds/100).ToString();
}
void RenderTrans (TreeViewColumn tree_column, CellRenderer cell, TreeModel tree_model, TreeIter iter)
{
SequenceurLineaire.Effet e = tree_model.GetValue (iter, 0) as SequenceurLineaire.Effet;
(cell as Gtk.CellRendererText).Text = (e.Transition.TotalMilliseconds/100).ToString();
}
void UpdListeEffets ()
{
lsEffets.Clear();
foreach (var effet in sequenceur.Effets) {
lsEffets.AppendValues(effet);
}
}
#endregion
public override void Update (bool full)
{
if (fullUpdFlag || full)
FullUpdate ();
UpdateValues ();
timeLabel.LabelProp = string.Format (@"{0:0\.0}", sequenceur.TimeStamp.TotalMilliseconds / 100);
if (sequenceur.EffetCourrant.Duree != TimeSpan.Zero)
pbDuree.Fraction = Math.Min (1.0d, sequenceur.TimeStamp.TotalMilliseconds / sequenceur.EffetCourrant.Duree.TotalMilliseconds);
else
pbDuree.Fraction = 0.0d;
if (sequenceur.TempsTransition != TimeSpan.Zero)
pbTrans.Fraction = Math.Min (1.0d, sequenceur.TimeStamp.TotalMilliseconds / sequenceur.TempsTransition.TotalMilliseconds);
else
pbTrans.Fraction = 0.0d;
if (effetChange) {
SelectionneEffet (sequenceur.IndexEffetCourrant);
posLabel.Text = string.Format("n°{0}",sequenceur.IndexEffetCourrant +1 );
}
}
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();
}
Dictionary tirettes = new Dictionary();
Dictionary tirettesNames = new Dictionary();
static VScale NouvelleTirette ()
{
VScale tirette = new VScale (null);
tirette.WidthRequest = 25;
tirette.HeightRequest = 130;
tirette.CanFocus = true;
tirette.Inverted = true;
tirette.Adjustment.Upper = 255;
tirette.Adjustment.PageIncrement = 10;
tirette.Adjustment.StepIncrement = 1;
tirette.DrawValue = true;
tirette.Digits = 0;
tirette.Name = "sclTirette";
return tirette;
}
void TirettePopup (object sender, ContextMenuEventArgs e)
{
Circuit c = e.Widget.Data[circuitKey] as Circuit;
Menu m = Conduite.Courante.EventManager.GetMenu(c,TirettePopupEnd);
m.ShowAll();
m.Popup();
}
void TirettePopupEnd (object state, string eventId)
{
Circuit c = state as Circuit;
sequenceur.BindCircuitEvent(c,eventId);
#if DEBUG
Console.WriteLine("{0} bound to {1}", c, eventId );
#endif
}
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();
}
static Label NouveauLabel ()
{
Label l = new Label();
l.WidthRequest = 50;
l.HeightRequest = 66;
l.Xalign = 1F;
l.Yalign = 0F;
l.UseMarkup = true;
l.Angle = 65;
l.Name = "lblTirette";
return l;
}
int lastKnownWidth =0;
object circuitKey = new object();
object labKey = new object();
ContextMenuHelper tirettesContextHelper = new ContextMenuHelper();
protected void FullUpdate ()
{
fullUpdFlag = true;
lastKnownWidth = zoneWid.Allocation.Width;
if (lastKnownWidth < 50) {
fullUpdFlag=false;
return;
}
foreach (Widget wid in new List(zoneWid.Children))
zoneWid.Remove (wid);
tirettes.Clear();
int xpos=10, ypos=0;
VScale tirette; Fixed.FixedChild fx;
Label label;
foreach (Circuit c in sequenceur.Circuits) {
label = new Label();
if(pourcentBtn.Active)
label.LabelProp = "00";
else
label.LabelProp = "00,0";
label.WidthRequest = 25;
label.HeightRequest = 25;
zoneWid.Add(label);
fx = ( zoneWid[label] as Fixed.FixedChild);
fx.X = xpos;
fx.Y = ypos;
label.Name = "sclTirette";
label.Show();
label.Justify = Justification.Left;
tirettes[c] = tirette = NouvelleTirette();
tirettesNames[c] = "sclTirette";
zoneWid.Add(tirette);
fx = ( zoneWid[tirette] as Fixed.FixedChild);
fx.X = xpos;
fx.Y = ypos + 20;
tirette.Show();
tirette.ValueChanged += TiretteActionee;
tirette.Data.Add(circuitKey,c);
tirette.Data.Add(labKey,label);
tirettesContextHelper.AttachToWidget(tirette);
tirette.TooltipText = c.Name;
tirette.DrawValue = false;
label = NouveauLabel();
zoneWid.Add(label);
fx = ( zoneWid[label] as Fixed.FixedChild);
fx.X = xpos-30;
fx.Y = ypos+150;
label.LabelProp = string.Format( "{0}-{1}", c.ID, c.ShortName);
label.Show();
xpos+=30;
if(lastKnownWidth < xpos +30)
{
xpos = 10;
ypos += 215;
}
}
posLabel.Text = string.Format("n°{0}",sequenceur.IndexEffetCourrant +1);
fullUpdFlag=false;
}
bool updating=false;
void TiretteActionee (object sender, EventArgs e)
{
VScale t = sender as VScale;
Label lab = t.Data[labKey] as Label;
if(pourcentBtn.Active)
lab.LabelProp = string.Format(@"{0:00}", t.Value );
else
lab.LabelProp = string.Format(@"{0:00.0}",100 * t.Value / 255 );
if (updating) return;
Circuit c = t.Data[circuitKey] as Circuit;
sequenceur.ChangeValeur(c,(int)(t.Value));
}
protected void UpdateValues()
{
updating = true;
foreach (Circuit c in tirettes.Keys) {
tirettes[c].Value = sequenceur.ValeurBruteCircuit(c);
string tname;
if(sequenceur.EstChange(c)){
if (sequenceur.EstCapture(c))
tname="sclTiretteM";
else
tname="sclTiretteC";
}
else if (sequenceur.EnTransition(c))
tname="sclTiretteT";
else
tname="sclTirette";
if (tirettesNames[c] != tname) tirettesNames[c] = (tirettes[c].Data[labKey] as Label).Name = tirettes[c].Name = tname;
}
seqMasterScale.Value = sequenceur.Master;
updating=false;
}
protected void OnZoneWidSizeAllocated (object o, SizeAllocatedArgs args)
{
if (!fullUpdFlag) {
if(lastKnownWidth != args.Allocation.Width)
FullUpdate ();
}
}
int IndexEffetSelectionne()
{
var sel = effetsListe.Selection.GetSelectedRows();
if(sel.Length ==0) return -1;
return effetsListe.Selection.GetSelectedRows()[0].Indices[0];
}
protected void OnSaveActionActivated (object sender, EventArgs e)
{
int pos = sequenceur.SauveEffet("Nouvel Effet", TimeSpan.Zero,TimeSpan.FromSeconds(5));
UpdListeEffets();
effetChange = true; Update(false);
effetsListe.SetCursor(new TreePath( new int[1] {pos}) ,nomCol,true);
}
protected void OnGoForwardActionActivated (object sender, EventArgs e)
{
// Si l'effet courant est selectioné, on passe au suivant, sinon, on passe a celui selectionné.
if(sequenceur.IndexEffetCourrant == IndexEffetSelectionne())
sequenceur.IndexEffetCourrant++;
else
sequenceur.IndexEffetCourrant = IndexEffetSelectionne();
}
protected void OnGoBackActionActivated (object sender, EventArgs e)
{
sequenceur.IndexEffetCourrant--;
}
protected void OnMediaPauseActionActivated (object sender, EventArgs e)
{
sequenceur.Paused = ! sequenceur.Paused;
}
protected void OnMediaNextActionActivated (object sender, EventArgs e)
{
sequenceur.FinDeTransition();
}
protected void OnApplyActionActivated (object sender, EventArgs e)
{
int pos = IndexEffetSelectionne();
if(pos==-1) return;
sequenceur.RemplaceEffet(pos);
UpdListeEffets();
effetChange = true; Update(false);
}
protected void OnSaveAfterActionActivated (object sender, EventArgs e)
{
int pos = sequenceur.InsereEffetApres(IndexEffetSelectionne(),"Nouvel Effet",TimeSpan.Zero,TimeSpan.FromSeconds(5));
UpdListeEffets();
effetChange = true; Update(false);
effetsListe.SetCursor(new TreePath( new int[1] {pos}) ,nomCol,true);
}
protected void OnDeleteActionActivated (object sender, EventArgs e)
{
int pos = IndexEffetSelectionne();
if(pos==-1) return;
sequenceur.SupprimeEffet(pos);
UpdListeEffets();
effetChange = true; Update(false);
}
protected void OnMoveUpActionActivated (object sender, EventArgs e)
{
int pos = IndexEffetSelectionne();
if(pos==-1) return;
pos = sequenceur.MonteEffet(pos);
UpdListeEffets();
effetChange = true; Update(false);
}
protected void OnMoveDownActionActivated (object sender, EventArgs e)
{
int pos = IndexEffetSelectionne();
if(pos==-1) return;
pos = sequenceur.BaisseEffet(pos);
UpdListeEffets();
effetChange = true; Update(false);
}
protected void OnSeqMasterScaleValueChanged (object sender, EventArgs e)
{
if (updating)return;
sequenceur.Master = (int)(seqMasterScale.Value);
}
protected void OnPourcentBtnToggled (object sender, EventArgs e)
{
fullUpdFlag = true;
}
}
}