/* 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); Console.WriteLine("{0} bound to {1}", c, eventId ); } 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; } } }