Modifs Midi

This commit is contained in:
tzim 2015-08-26 10:08:42 +00:00
parent 3803a830da
commit 5b810eaa8c
7 changed files with 462 additions and 350 deletions

View file

@ -125,11 +125,11 @@ namespace DMX2
clientId = Invoke.snd_seq_client_id (seq_handle.Handle);
outport = inport = Invoke.snd_seq_create_simple_port (seq_handle.Handle,
"dmx_ctrl",
"midi_in_out",
SND_SEQ_PORT_CAP_WRITE
//+ SND_SEQ_PORT_CAP_SUBS_WRITE
+ SND_SEQ_PORT_CAP_READ
//+ SND_SEQ_PORT_CAP_SUBS_READ
+ SND_SEQ_PORT_CAP_SUBS_READ
,
SND_SEQ_PORT_TYPE_APPLICATION
);

View file

@ -339,6 +339,7 @@ namespace DMX2
#endif
if (bindings.ContainsKey (data.id)) {
foreach (IEventTarget target in bindings[data.id].Targets) {
// TODO : Gestion des targets expirees
target.FireEvent(data);
}
}

View file

@ -16,7 +16,7 @@ namespace DMX2
this.Build ();
lsDetect = new Gtk.ListStore (typeof(string));
lsKnown = new Gtk.ListStore (typeof(MidiEventProvider.MidiDev));
lsKnown = new Gtk.ListStore (typeof(MidiEventProvider.MidiDevice));
var nameCol = new Gtk.TreeViewColumn ();
@ -49,7 +49,7 @@ namespace DMX2
spinNbPage.Value = Conduite.Courante.Midi.Maxpage;
spinPageDown.Value = Conduite.Courante.Midi.PageDownCC;
spinPageUp.Value = Conduite.Courante.Midi.PageUpCC;
chkFourteenBits.Active = Conduite.Courante.Midi.Fourteenbits;
spinMax14b.Sensitive = chkFourteenBits.Active = Conduite.Courante.Midi.Use14bCC;
if (Conduite.Courante.Midi.UnpaginatedChannels.Count == 0) {
spinUPCh.Sensitive = false;
@ -60,7 +60,7 @@ namespace DMX2
chkPg.Active = true;
}
spinMax14b.Value = Conduite.Courante.Midi.Max14bValue;
}
@ -81,7 +81,7 @@ namespace DMX2
void RenderMidiDev (Gtk.TreeViewColumn tree_column, Gtk.CellRenderer cell, Gtk.TreeModel tree_model, Gtk.TreeIter iter)
{
MidiEventProvider.MidiDev dev = tree_model.GetValue (iter, 0) as MidiEventProvider.MidiDev;
MidiEventProvider.MidiDevice dev = tree_model.GetValue (iter, 0) as MidiEventProvider.MidiDevice;
(cell as Gtk.CellRendererText).Text = dev.ConnectedPorts.Count>0
?string.Format("{0} ({1} connectés)",dev.Name,dev.ConnectedPorts.Count)
:string.Format("{0} (Déconnecté)",dev.Name);
@ -124,7 +124,7 @@ namespace DMX2
chkFB.Sensitive = btnDesactiv.Sensitive = (listKnown.Selection.CountSelectedRows() >0);
TreeIter iter;
if(!listKnown.Selection.GetSelected(out iter)) return;
MidiEventProvider.MidiDev dev = lsKnown.GetValue(iter,0) as MidiEventProvider.MidiDev ;
MidiEventProvider.MidiDevice dev = lsKnown.GetValue(iter,0) as MidiEventProvider.MidiDevice ;
chkFB.Active = dev.HasFeedback;
}
@ -144,7 +144,7 @@ namespace DMX2
{
TreeIter iter;
if(!listKnown.Selection.GetSelected(out iter)) return;
MidiEventProvider.MidiDev dev = lsKnown.GetValue(iter,0) as MidiEventProvider.MidiDev ;
MidiEventProvider.MidiDevice dev = lsKnown.GetValue(iter,0) as MidiEventProvider.MidiDevice ;
Conduite.Courante.Midi.DisconnectDevice(dev);
FillLsDetect () ;
FillLsKnown();
@ -156,7 +156,7 @@ namespace DMX2
{
TreeIter iter;
if(!listKnown.Selection.GetSelected(out iter)) return;
MidiEventProvider.MidiDev dev = lsKnown.GetValue(iter,0) as MidiEventProvider.MidiDev ;
MidiEventProvider.MidiDevice dev = lsKnown.GetValue(iter,0) as MidiEventProvider.MidiDevice ;
dev.HasFeedback = chkFB.Active;
Conduite.Courante.Midi.RefreshFeedback(dev.Name);
@ -187,12 +187,9 @@ namespace DMX2
Conduite.Courante.Midi.UnpaginatedChannels.Add((byte)(spinUPCh.ValueAsInt-1));
}
protected void OnChkFourteenBitsToggled (object sender, EventArgs e)
{
Conduite.Courante.Midi.Fourteenbits = chkFourteenBits.Active;
spinMax14b.Sensitive = Conduite.Courante.Midi.Use14bCC = chkFourteenBits.Active;
}
protected void OnSpinPageDownValueChanged (object sender, EventArgs e)
@ -204,6 +201,11 @@ namespace DMX2
{
Conduite.Courante.Midi.PageUpCC = (uint)spinPageUp.ValueAsInt;
}
protected void OnSpinMax14bValueChanged (object sender, EventArgs e)
{
Conduite.Courante.Midi.Max14bValue = spinMax14b.ValueAsInt;
}
}
}

View file

@ -19,178 +19,21 @@ using System;
using System.Runtime.InteropServices;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
namespace DMX2
{
public class MidiEventProvider : IEventProvider, IDisposable
{
class internalEvent
{
readonly string internalName;
bool bound = false;
readonly uint page;
readonly int midiEvCode;
readonly midiEventSender evsender;
public bool Bound {
get {
return bound;
}
set {
bound = value;
}
}
public string InternalName {
get {
return internalName;
}
}
public uint Page {
get {
return page;
}
}
public int MidiEvCode {
get {
return midiEvCode;
}
}
public internalEvent (string _id, uint _page, int _evHCode, midiEventSender _evsender)
{
internalName = _id;
page = _page;
midiEvCode = _evHCode;
evsender = _evsender;
}
int lastknownvalue = -1;
public int LastKnownValue {
get {
return lastknownvalue;
}
set {
lastknownvalue = value;
}
}
public void SendEvent ()
{
if(evsender !=null)
evsender.SendEvent (lastknownvalue);
}
}
abstract class midiEventSender {
public abstract void SendEvent (int value);
}
class midiCCEvSender : midiEventSender {
readonly MidiEventProvider prov;
AlsaSeqLib.snd_seq_event_t ev;
AlsaSeqLib.snd_seq_event_t ev2;
public midiCCEvSender (MidiEventProvider _prov, byte _chan, uint _param){
prov = _prov;
ev = new AlsaSeqLib.snd_seq_event_t();
ev.type = AlsaSeqLib.snd_seq_event_type_t.SND_SEQ_EVENT_CONTROLLER;
ev.data_ev_ctrl.channel = _chan;
ev.data_ev_ctrl.param = _param;
ev2 = ev;
ev2.data_ev_ctrl.param -= 32;
}
public override void SendEvent (int value)
{
if (prov.Fourteenbits && ev2.data_ev_ctrl.param <32 ) {
ev2.data_ev_ctrl.value = value >> 7;
ev.data_ev_ctrl.value = value & 0xFF;
prov.SendEvent (ev2);
prov.SendEvent (ev);
} else {
ev.data_ev_ctrl.value = value * 127 / 255;
prov.SendEvent (ev);
}
}
}
class midiPBEvSender : midiEventSender {
public override void SendEvent (int value)
{
}
}
class feedbackinfo : IFeedbackInfo
{
MidiEventProvider prov;
readonly internalEvent iev;
public feedbackinfo (MidiEventProvider _prov, internalEvent _iev)
{
prov = _prov;
iev = _iev;
}
#region IFeedbackInfo implementation
bool IFeedbackInfo.FeedBack (byte data)
{
iev.LastKnownValue = data;
if (prov.CurrentPage == iev.Page || iev.Page == 0) {
iev.SendEvent();
foreach (int src in prov.feedbacksources) {
int lnvk = CombineHash (src, iev.MidiEvCode);
if (iev.LastKnownValue != -1)
prov.lastValueOfSrc [lnvk] = (byte)iev.LastKnownValue;
}
}
return true;
}
#endregion
}
public class MidiDev
{
string name;
public string Name { get { return name; } }
public bool HasFeedback { get; set; }
readonly List<int> connected = new List<int> ();
public List<int> ConnectedPorts {
get{ return connected;}
}
public MidiDev (string _name)
{
name = _name;
}
}
/// <summary>
/// Etat interne des evenements midi paginés.
/// </summary>
readonly Dictionary<string,internalEvent> eventlist = new Dictionary<string, internalEvent> ();
readonly Dictionary<string,internalEventDesc> eventlist = new Dictionary<string, internalEventDesc> ();
/// <summary>
/// Liste des peripheriques connus (presents ou non)
/// </summary>
readonly Dictionary<string,MidiDev> knowndevices = new Dictionary<string,MidiDev> ();
readonly Dictionary<string,MidiDevice> knowndevices = new Dictionary<string,MidiDevice> ();
/// <summary>
/// Liste des ports connectés avec feedback
@ -206,13 +49,13 @@ namespace DMX2
/// </summary>
readonly Dictionary<int,byte> lastValueOfSrc = new Dictionary<int, byte> ();
// EventData last;
internalEvent levent = null;
bool connected = false;
internalEventDesc levent = null;
bool guirefreshflag = false;
uint page = 1;
uint maxpage = 8;
bool fourteenbits = false;
protected bool use14b = false;
protected int max14bValue = 100;
byte[] fbTmpData = new byte[512];
uint pageUpCC = 127;
uint pageDownCC = 126;
@ -228,7 +71,6 @@ namespace DMX2
Refresh ();
}
}
public uint PageUpCC {
get {
return pageUpCC;
@ -237,7 +79,6 @@ namespace DMX2
pageUpCC = value;
}
}
public uint PageDownCC {
get {
return pageDownCC;
@ -255,19 +96,26 @@ namespace DMX2
maxpage = value;
}
}
public List<byte> UnpaginatedChannels {
get {
return unpaginatedchannels;
}
}
public bool Fourteenbits {
public bool Use14bCC {
get {
return fourteenbits;
return use14b;
}
set {
fourteenbits = value;
use14b = value;
}
}
public int Max14bValue {
get {
return max14bValue;
}
set {
max14bValue = value;
}
}
@ -283,7 +131,7 @@ namespace DMX2
public void ConnectDevice (string name)
{
knowndevices.Add (name, new MidiDev (name));
knowndevices.Add (name, new MidiDevice (name));
AutoConnect ();
}
@ -300,7 +148,7 @@ namespace DMX2
}
}
public void DisconnectDevice (MidiEventProvider.MidiDev dev)
public void DisconnectDevice (MidiEventProvider.MidiDevice dev)
{
if (!knowndevices.ContainsKey (dev.Name))
return;
@ -318,7 +166,7 @@ namespace DMX2
return knowndevices.ContainsKey (name);
}
public IEnumerable<MidiDev> KnownDevices {
public IEnumerable<MidiDevice> KnownDevices {
get {
return knowndevices.Values;
}
@ -326,10 +174,10 @@ namespace DMX2
public MidiEventProvider (EventManager manager)
{
/*MidiDev dev = new MidiDev("VMPK Input:VMPK Input");
/*MidiDevice dev = new MidiDevice("VMPK Input:VMPK Input");
dev.HasFeedback = true;
knowndevices.Add(dev.Name,dev);
dev = new MidiDev("VMPK Output:VMPK Output");
dev = new MidiDevice("VMPK Output:VMPK Output");
dev.HasFeedback = true;
knowndevices.Add(dev.Name,dev);*/
@ -442,9 +290,6 @@ namespace DMX2
#region IEventProvider implementation
static System.Text.RegularExpressions.Regex regexEventID = new System.Text.RegularExpressions.Regex (
@"MIDI-PAGE(?<page>\d+)-(?<id>.+)",
System.Text.RegularExpressions.RegexOptions.Compiled);
bool IEventProvider.Bind (string eventId)
{
@ -453,12 +298,23 @@ namespace DMX2
return false;
if (! eventlist.ContainsKey (eventId)) {
var res = regexEventID.Match (eventId);
Match res = regexEventID.Match (eventId);
if (!res.Success)
return false;
uint _page = uint.Parse (res.Groups ["page"].Value);
int _evHC = res.Groups ["id"].Value.GetHashCode ();
eventlist.Add (eventId, new internalEvent (eventId, _page, _evHC,null));
midiEventSender sender = null;
res = regexCtrlEventID.Match (eventId);
if (res.Success) {
byte chan = byte.Parse (res.Groups ["chan"].Value);
uint param = uint.Parse (res.Groups ["param"].Value);
sender = new midiCCEvSender (this, chan, param);
} else if ((res = regexPbEventID.Match (eventId)).Success){
byte chan = byte.Parse (res.Groups ["chan"].Value);
sender = new midiPBEvSender (this, chan);
}
eventlist.Add (eventId, new internalEventDesc (eventId, _page, _evHC,sender));
}
eventlist [eventId].Bound = true;
@ -475,8 +331,6 @@ namespace DMX2
Gtk.Menu IEventProvider.GetProviderSubMenu (EventManager.EventMenuData state, Gtk.ButtonPressEventHandler handler)
{
if (!connected)
return null; // Si pas encore recu d'evenements => pas de menu
Gtk.Menu retmenu = new Gtk.Menu ();
if (levent != null) { // Creation du sous menu "Dernier"
@ -500,7 +354,7 @@ namespace DMX2
sortedKeys.Sort (); // et on les trie
foreach (string key in sortedKeys) {
internalEvent evt = eventlist [key];
internalEventDesc evt = eventlist [key];
Gtk.MenuItem item = new Gtk.MenuItem (GetDescription (evt.InternalName));
item.Data [EventManager.EventIdKey] = evt.InternalName;
item.Data [EventManager.StateKey] = state;
@ -519,7 +373,7 @@ namespace DMX2
// Tant qu'il y des evenements midi en attente
while (AlsaSeqLib.GetEvent(out evS)) {
Console.WriteLine(string.Format ("event {0}", evS.type) );
string id = null;
int value = 0;
byte channel = 255;
@ -543,23 +397,24 @@ namespace DMX2
continue;
}
channel = evS.data_ev_ctrl.channel;
if (fourteenbits && evS.data_ev_ctrl.param < 64) {
if (use14b && evS.data_ev_ctrl.param < 64) {
long msbAddr;
if (evS.data_ev_ctrl.param < 32) {
msbAddr = evS.data_ev_ctrl.channel * 32 + evS.data_ev_ctrl.param;
fbTmpData [msbAddr] = (byte)evS.data_ev_ctrl.value;
continue;
}
id = string.Format ("CTRL-C{0}P{1}", evS.data_ev_ctrl.channel, evS.data_ev_ctrl.param-32);
msbAddr = evS.data_ev_ctrl.channel * 32 + evS.data_ev_ctrl.param - 32;
evS.data_ev_ctrl.param -= 32;
msbAddr = evS.data_ev_ctrl.channel * 32 + evS.data_ev_ctrl.param;
value = ((fbTmpData [msbAddr] << 7) ^ evS.data_ev_ctrl.value);
value = 255 * value / max14bValue;
if (value > 255) value = 255;
} else {
id = string.Format ("CTRL-C{0}P{1}", evS.data_ev_ctrl.channel, evS.data_ev_ctrl.param);
value = 255 * evS.data_ev_ctrl.value / 127; // Conversion {0,127} => {0,255}
}
id = string.Format ("CTRL-C{0}P{1}", evS.data_ev_ctrl.channel, evS.data_ev_ctrl.param);
break;
case AlsaSeqLib.snd_seq_event_type_t.SND_SEQ_EVENT_NOTEON:
id = string.Format ("NOTE-C{0}N{1}", evS.data_ev_note.channel, evS.data_ev_note.note);
@ -580,9 +435,6 @@ namespace DMX2
if (value > 255)
value = 255;
break;
case AlsaSeqLib.snd_seq_event_type_t.SND_SEQ_EVENT_CLOCK:
case AlsaSeqLib.snd_seq_event_type_t.SND_SEQ_EVENT_SENSING:
continue;
case AlsaSeqLib.snd_seq_event_type_t.SND_SEQ_EVENT_PGMCHANGE:
CurrentPage = (uint)evS.data_ev_ctrl.value;
continue;
@ -593,6 +445,10 @@ namespace DMX2
);
continue;
/*case AlsaSeqLib.snd_seq_event_type_t.SND_SEQ_EVENT_CLOCK:
case AlsaSeqLib.snd_seq_event_type_t.SND_SEQ_EVENT_SENSING:
continue;*/
default:
id = null;
#if DEBUG
@ -602,10 +458,6 @@ namespace DMX2
continue;
}
connected = true;
if (id != null) {
// Hashcode de l'ev Midi, non pagine
int evHC = id.GetHashCode ();
@ -623,21 +475,28 @@ namespace DMX2
// Creation de l'objet interne si innexistant
if (!eventlist.ContainsKey (id)) {
switch (evS.type) {
// TODO : Pitchbend feedback
case AlsaSeqLib.snd_seq_event_type_t.SND_SEQ_EVENT_CONTROLLER:
eventlist.Add (id, new internalEvent (id, page, evHC,
new midiCCEvSender(this,channel,evS.data_ev_ctrl.param))
eventlist.Add (id, new internalEventDesc (id, page, evHC,
new midiCCEvSender(this,channel,evS.data_ev_ctrl.param))
);
break;
case AlsaSeqLib.snd_seq_event_type_t.SND_SEQ_EVENT_PITCHBEND:
eventlist.Add (id, new internalEventDesc (id, page, evHC,
new midiPBEvSender(this,channel))
);
break;
default:
eventlist.Add (id, new internalEvent (id, page, evHC, null));
eventlist.Add (id, new internalEventDesc (id, page, evHC, null));
break;
}
}
levent = eventlist [id]; //Dernier Evenement recu conserve pour menu
if (!lastValueOfSrc.ContainsKey (lnvk))
if (!lastValueOfSrc.ContainsKey (lnvk)) {
lastValueOfSrc [lnvk] = (byte)value;
} else if (lastValueOfSrc [lnvk] == (byte)value)
continue;
EventData evData = new EventData ();
evData.id = id;
@ -664,6 +523,10 @@ namespace DMX2
}
}
static System.Text.RegularExpressions.Regex regexEventID = new System.Text.RegularExpressions.Regex (
@"MIDI-PAGE(?<page>\d+)-(?<id>.+)",
System.Text.RegularExpressions.RegexOptions.Compiled);
static System.Text.RegularExpressions.Regex regexCtrlEventID = new System.Text.RegularExpressions.Regex (
@"MIDI-PAGE(?<page>\d+)-CTRL-C(?<chan>\d+)P(?<param>\d+)",
System.Text.RegularExpressions.RegexOptions.Compiled);
@ -707,20 +570,7 @@ namespace DMX2
if (!eventlist.ContainsKey (eventId))
return null;
return new feedbackinfo (this, eventlist [eventId]);
/*var res = regexCtrlEventID.Match (eventId);
if (res.Success) {
byte chan = byte.Parse (res.Groups ["chan"].Value);
uint param = uint.Parse (res.Groups ["param"].Value);
return new ctrlfeedbackinfo (this, eventlist [eventId], chan, param);
}
res = regexPbEventID.Match (eventId);
if (res.Success) {
byte chan = byte.Parse (res.Groups ["chan"].Value);
return new pitchbendfeedbackinfo (this, eventlist [eventId], chan);
}
return null;*/
return new midifeedbackinfo (this, eventlist [eventId]);
}
@ -752,10 +602,11 @@ namespace DMX2
el.SetAttribute ("maxpage", maxpage.ToString ());
el.SetAttribute ("pageUpCC", pageUpCC.ToString ());
el.SetAttribute ("pageDownCC", pageDownCC.ToString ());
el.SetAttribute ("fourteenbits", fourteenbits?"true":"false");
el.SetAttribute ("fourteenbits", use14b?"true":"false");
el.SetAttribute ("max14b", max14bValue.ToString ());
System.Xml.XmlElement xmlEl;
foreach (MidiDev dev in knowndevices.Values) {
foreach (MidiDevice dev in knowndevices.Values) {
el.AppendChild (xmlEl = parent.OwnerDocument.CreateElement ("MidiDev"));
xmlEl.SetAttribute ("name", dev.Name);
xmlEl.SetAttribute ("feedback", dev.HasFeedback.ToString ());
@ -775,13 +626,14 @@ namespace DMX2
maxpage = uint.Parse (el.TryGetAttribute ("maxpage", "8"));
pageUpCC = uint.Parse (el.TryGetAttribute ("pageUpCC", "127"));
pageDownCC = uint.Parse (el.TryGetAttribute ("pageDownCC", "126"));
fourteenbits = el.TryGetAttribute ("fourteenbits", string.Empty).Equals ("true");
use14b = el.TryGetAttribute ("fourteenbits", string.Empty).Equals ("true");
max14bValue = int.Parse (el.TryGetAttribute ("max14b", "255"));
foreach (var xd in el.GetElementsByTagName("MidiDev")) {
System.Xml.XmlElement xdev = xd as System.Xml.XmlElement;
string name = xdev.GetAttribute ("name");
if (!knowndevices.ContainsKey (name))
knowndevices.Add (name, new MidiDev (name));
knowndevices.Add (name, new MidiDevice (name));
knowndevices [name].HasFeedback = bool.Parse (xdev.TryGetAttribute ("feedback", "false"));
}
unpaginatedchannels.Clear ();
@ -793,5 +645,176 @@ namespace DMX2
AutoConnect ();
}
class internalEventDesc
{
readonly string internalName;
bool bound = false;
readonly uint page;
readonly int midiEvCode;
readonly midiEventSender evsender;
public bool Bound {
get {
return bound;
}
set {
bound = value;
}
}
public string InternalName {
get {
return internalName;
}
}
public uint Page {
get {
return page;
}
}
public int MidiEvCode {
get {
return midiEvCode;
}
}
public internalEventDesc (string _id, uint _page, int _evHCode, midiEventSender _evsender)
{
internalName = _id;
page = _page;
midiEvCode = _evHCode;
evsender = _evsender;
}
int lastknownvalue = -1;
public int LastKnownValue {
get {
return lastknownvalue;
}
set {
lastknownvalue = value;
}
}
public void SendEvent ()
{
if(evsender !=null)
evsender.SendEvent (lastknownvalue);
}
}
abstract class midiEventSender {
public abstract void SendEvent (int value);
}
class midiCCEvSender : midiEventSender {
readonly MidiEventProvider prov;
AlsaSeqLib.snd_seq_event_t ev;
AlsaSeqLib.snd_seq_event_t ev2;
public midiCCEvSender (MidiEventProvider _prov, byte _chan, uint _param){
prov = _prov;
ev = new AlsaSeqLib.snd_seq_event_t();
ev.type = AlsaSeqLib.snd_seq_event_type_t.SND_SEQ_EVENT_CONTROLLER;
ev.data_ev_ctrl.channel = _chan;
ev.data_ev_ctrl.param = _param;
ev2 = ev;
ev2.data_ev_ctrl.param += 32;
}
public override void SendEvent (int value)
{
if (prov.use14b && ev.data_ev_ctrl.param <32 ) {
value = value * prov.max14bValue / 255;
ev.data_ev_ctrl.value = value >> 7;
ev2.data_ev_ctrl.value = value & 0xFF;
prov.SendEvent (ev);
prov.SendEvent (ev2);
} else {
ev.data_ev_ctrl.value = value * 127 / 255;
prov.SendEvent (ev);
}
}
}
class midiPBEvSender : midiEventSender {
readonly MidiEventProvider prov;
AlsaSeqLib.snd_seq_event_t ev;
public midiPBEvSender (MidiEventProvider _prov, byte _chan){
prov = _prov;
ev = new AlsaSeqLib.snd_seq_event_t();
ev.type = AlsaSeqLib.snd_seq_event_type_t.SND_SEQ_EVENT_PITCHBEND;
ev.data_ev_ctrl.channel = _chan;
}
public override void SendEvent (int value)
{ // value = ((evS.data_ev_ctrl.value + 7000) * 255 / 14000);
ev.data_ev_ctrl.value = value * 14000 / 255 - 7000;
prov.SendEvent (ev);
}
}
class midifeedbackinfo : IFeedbackInfo
{
MidiEventProvider prov;
readonly internalEventDesc iev;
public midifeedbackinfo (MidiEventProvider _prov, internalEventDesc _iev)
{
prov = _prov;
iev = _iev;
}
#region IFeedbackInfo implementation
bool IFeedbackInfo.FeedBack (byte data)
{
iev.LastKnownValue = data;
if (prov.CurrentPage == iev.Page || iev.Page == 0) {
iev.SendEvent();
foreach (int src in prov.feedbacksources) {
int lnvk = CombineHash (src, iev.MidiEvCode);
if (iev.LastKnownValue != -1)
prov.lastValueOfSrc [lnvk] = (byte)iev.LastKnownValue;
}
}
return true;
}
#endregion
}
public class MidiDevice
{
string name;
public string Name { get { return name; } }
public bool HasFeedback { get; set; }
readonly List<int> connected = new List<int> ();
public List<int> ConnectedPorts {
get{ return connected;}
}
public MidiDevice (string _name)
{
name = _name;
}
}
}
}

View file

@ -322,7 +322,10 @@ namespace DMX2
circuitsSeq.Remove (c);
valeurscourantes.Remove (c);
valeursinitiales.Remove (c);
targets.Remove(c);
if (targets.ContainsKey (c)) {
Conduite.Courante.EventManager.Unbind (targets [c]);
targets.Remove (c);
}
}
public override int ValeurCircuit (Circuit c)

View file

@ -13,11 +13,13 @@ namespace DMX2
private global::Gtk.Label label3;
private global::Gtk.Label label4;
private global::Gtk.Label label5;
private global::Gtk.Label label6;
private global::Gtk.SpinButton spinMax14b;
private global::Gtk.SpinButton spinNbPage;
private global::Gtk.SpinButton spinPageDown;
private global::Gtk.SpinButton spinPageUp;
private global::Gtk.SpinButton spinUPCh;
private global::Gtk.Label GtkLabel5;
private global::Gtk.Label GtkLabel6;
private global::Gtk.Frame frame3;
private global::Gtk.Alignment GtkAlignment2;
private global::Gtk.VBox vbox5;
@ -61,7 +63,7 @@ namespace DMX2
this.GtkAlignment3.Name = "GtkAlignment3";
this.GtkAlignment3.LeftPadding = ((uint)(12));
// Container child GtkAlignment3.Gtk.Container+ContainerChild
this.table2 = new global::Gtk.Table (((uint)(5)), ((uint)(2)), false);
this.table2 = new global::Gtk.Table (((uint)(6)), ((uint)(2)), false);
this.table2.Name = "table2";
this.table2.RowSpacing = ((uint)(6));
this.table2.ColumnSpacing = ((uint)(6));
@ -123,6 +125,34 @@ namespace DMX2
w6.XOptions = ((global::Gtk.AttachOptions)(4));
w6.YOptions = ((global::Gtk.AttachOptions)(4));
// Container child table2.Gtk.Table+TableChild
this.label6 = new global::Gtk.Label ();
this.label6.Name = "label6";
this.label6.Xpad = 20;
this.label6.Xalign = 0F;
this.label6.LabelProp = "Valeur entrée max :";
this.table2.Add (this.label6);
global::Gtk.Table.TableChild w7 = ((global::Gtk.Table.TableChild)(this.table2 [this.label6]));
w7.TopAttach = ((uint)(5));
w7.BottomAttach = ((uint)(6));
w7.XOptions = ((global::Gtk.AttachOptions)(4));
w7.YOptions = ((global::Gtk.AttachOptions)(4));
// Container child table2.Gtk.Table+TableChild
this.spinMax14b = new global::Gtk.SpinButton (1, 16383, 1);
this.spinMax14b.CanFocus = true;
this.spinMax14b.Name = "spinMax14b";
this.spinMax14b.Adjustment.PageIncrement = 10;
this.spinMax14b.ClimbRate = 1;
this.spinMax14b.Numeric = true;
this.spinMax14b.Value = 127;
this.table2.Add (this.spinMax14b);
global::Gtk.Table.TableChild w8 = ((global::Gtk.Table.TableChild)(this.table2 [this.spinMax14b]));
w8.TopAttach = ((uint)(5));
w8.BottomAttach = ((uint)(6));
w8.LeftAttach = ((uint)(1));
w8.RightAttach = ((uint)(2));
w8.XOptions = ((global::Gtk.AttachOptions)(4));
w8.YOptions = ((global::Gtk.AttachOptions)(4));
// Container child table2.Gtk.Table+TableChild
this.spinNbPage = new global::Gtk.SpinButton (1, 99, 1);
this.spinNbPage.CanFocus = true;
this.spinNbPage.Name = "spinNbPage";
@ -131,11 +161,11 @@ namespace DMX2
this.spinNbPage.Numeric = true;
this.spinNbPage.Value = 8;
this.table2.Add (this.spinNbPage);
global::Gtk.Table.TableChild w7 = ((global::Gtk.Table.TableChild)(this.table2 [this.spinNbPage]));
w7.LeftAttach = ((uint)(1));
w7.RightAttach = ((uint)(2));
w7.XOptions = ((global::Gtk.AttachOptions)(4));
w7.YOptions = ((global::Gtk.AttachOptions)(4));
global::Gtk.Table.TableChild w9 = ((global::Gtk.Table.TableChild)(this.table2 [this.spinNbPage]));
w9.LeftAttach = ((uint)(1));
w9.RightAttach = ((uint)(2));
w9.XOptions = ((global::Gtk.AttachOptions)(4));
w9.YOptions = ((global::Gtk.AttachOptions)(4));
// Container child table2.Gtk.Table+TableChild
this.spinPageDown = new global::Gtk.SpinButton (1, 127, 1);
this.spinPageDown.CanFocus = true;
@ -145,13 +175,13 @@ namespace DMX2
this.spinPageDown.Numeric = true;
this.spinPageDown.Value = 126;
this.table2.Add (this.spinPageDown);
global::Gtk.Table.TableChild w8 = ((global::Gtk.Table.TableChild)(this.table2 [this.spinPageDown]));
w8.TopAttach = ((uint)(3));
w8.BottomAttach = ((uint)(4));
w8.LeftAttach = ((uint)(1));
w8.RightAttach = ((uint)(2));
w8.XOptions = ((global::Gtk.AttachOptions)(4));
w8.YOptions = ((global::Gtk.AttachOptions)(4));
global::Gtk.Table.TableChild w10 = ((global::Gtk.Table.TableChild)(this.table2 [this.spinPageDown]));
w10.TopAttach = ((uint)(3));
w10.BottomAttach = ((uint)(4));
w10.LeftAttach = ((uint)(1));
w10.RightAttach = ((uint)(2));
w10.XOptions = ((global::Gtk.AttachOptions)(4));
w10.YOptions = ((global::Gtk.AttachOptions)(4));
// Container child table2.Gtk.Table+TableChild
this.spinPageUp = new global::Gtk.SpinButton (1, 127, 1);
this.spinPageUp.CanFocus = true;
@ -161,13 +191,13 @@ namespace DMX2
this.spinPageUp.Numeric = true;
this.spinPageUp.Value = 127;
this.table2.Add (this.spinPageUp);
global::Gtk.Table.TableChild w9 = ((global::Gtk.Table.TableChild)(this.table2 [this.spinPageUp]));
w9.TopAttach = ((uint)(2));
w9.BottomAttach = ((uint)(3));
w9.LeftAttach = ((uint)(1));
w9.RightAttach = ((uint)(2));
w9.XOptions = ((global::Gtk.AttachOptions)(4));
w9.YOptions = ((global::Gtk.AttachOptions)(4));
global::Gtk.Table.TableChild w11 = ((global::Gtk.Table.TableChild)(this.table2 [this.spinPageUp]));
w11.TopAttach = ((uint)(2));
w11.BottomAttach = ((uint)(3));
w11.LeftAttach = ((uint)(1));
w11.RightAttach = ((uint)(2));
w11.XOptions = ((global::Gtk.AttachOptions)(4));
w11.YOptions = ((global::Gtk.AttachOptions)(4));
// Container child table2.Gtk.Table+TableChild
this.spinUPCh = new global::Gtk.SpinButton (1, 16, 1);
this.spinUPCh.CanFocus = true;
@ -177,24 +207,24 @@ namespace DMX2
this.spinUPCh.Numeric = true;
this.spinUPCh.Value = 1;
this.table2.Add (this.spinUPCh);
global::Gtk.Table.TableChild w10 = ((global::Gtk.Table.TableChild)(this.table2 [this.spinUPCh]));
w10.TopAttach = ((uint)(1));
w10.BottomAttach = ((uint)(2));
w10.LeftAttach = ((uint)(1));
w10.RightAttach = ((uint)(2));
w10.XOptions = ((global::Gtk.AttachOptions)(4));
w10.YOptions = ((global::Gtk.AttachOptions)(4));
global::Gtk.Table.TableChild w12 = ((global::Gtk.Table.TableChild)(this.table2 [this.spinUPCh]));
w12.TopAttach = ((uint)(1));
w12.BottomAttach = ((uint)(2));
w12.LeftAttach = ((uint)(1));
w12.RightAttach = ((uint)(2));
w12.XOptions = ((global::Gtk.AttachOptions)(4));
w12.YOptions = ((global::Gtk.AttachOptions)(4));
this.GtkAlignment3.Add (this.table2);
this.frame2.Add (this.GtkAlignment3);
this.GtkLabel5 = new global::Gtk.Label ();
this.GtkLabel5.Name = "GtkLabel5";
this.GtkLabel5.LabelProp = "<b>Options Midi</b>";
this.GtkLabel5.UseMarkup = true;
this.frame2.LabelWidget = this.GtkLabel5;
this.GtkLabel6 = new global::Gtk.Label ();
this.GtkLabel6.Name = "GtkLabel6";
this.GtkLabel6.LabelProp = "<b>Options Midi</b>";
this.GtkLabel6.UseMarkup = true;
this.frame2.LabelWidget = this.GtkLabel6;
this.table1.Add (this.frame2);
global::Gtk.Table.TableChild w13 = ((global::Gtk.Table.TableChild)(this.table1 [this.frame2]));
w13.XOptions = ((global::Gtk.AttachOptions)(4));
w13.YOptions = ((global::Gtk.AttachOptions)(4));
global::Gtk.Table.TableChild w15 = ((global::Gtk.Table.TableChild)(this.table1 [this.frame2]));
w15.XOptions = ((global::Gtk.AttachOptions)(4));
w15.YOptions = ((global::Gtk.AttachOptions)(4));
// Container child table1.Gtk.Table+TableChild
this.frame3 = new global::Gtk.Frame ();
this.frame3.Name = "frame3";
@ -216,10 +246,10 @@ namespace DMX2
this.chkFB.DrawIndicator = true;
this.chkFB.UseUnderline = true;
this.vbox5.Add (this.chkFB);
global::Gtk.Box.BoxChild w14 = ((global::Gtk.Box.BoxChild)(this.vbox5 [this.chkFB]));
w14.Position = 0;
w14.Expand = false;
w14.Fill = false;
global::Gtk.Box.BoxChild w16 = ((global::Gtk.Box.BoxChild)(this.vbox5 [this.chkFB]));
w16.Position = 0;
w16.Expand = false;
w16.Fill = false;
this.GtkAlignment2.Add (this.vbox5);
this.frame3.Add (this.GtkAlignment2);
this.GtkLabel3 = new global::Gtk.Label ();
@ -228,11 +258,11 @@ namespace DMX2
this.GtkLabel3.UseMarkup = true;
this.frame3.LabelWidget = this.GtkLabel3;
this.table1.Add (this.frame3);
global::Gtk.Table.TableChild w17 = ((global::Gtk.Table.TableChild)(this.table1 [this.frame3]));
w17.TopAttach = ((uint)(2));
w17.BottomAttach = ((uint)(3));
w17.XOptions = ((global::Gtk.AttachOptions)(4));
w17.YOptions = ((global::Gtk.AttachOptions)(4));
global::Gtk.Table.TableChild w19 = ((global::Gtk.Table.TableChild)(this.table1 [this.frame3]));
w19.TopAttach = ((uint)(2));
w19.BottomAttach = ((uint)(3));
w19.XOptions = ((global::Gtk.AttachOptions)(4));
w19.YOptions = ((global::Gtk.AttachOptions)(4));
// Container child table1.Gtk.Table+TableChild
this.hbuttonbox2 = new global::Gtk.HButtonBox ();
this.hbuttonbox2.Name = "hbuttonbox2";
@ -243,25 +273,25 @@ namespace DMX2
this.btnActiv.Name = "btnActiv";
this.btnActiv.UseUnderline = true;
// Container child btnActiv.Gtk.Container+ContainerChild
global::Gtk.Alignment w18 = new global::Gtk.Alignment (0.5F, 0.5F, 0F, 0F);
global::Gtk.Alignment w20 = new global::Gtk.Alignment (0.5F, 0.5F, 0F, 0F);
// Container child GtkAlignment.Gtk.Container+ContainerChild
global::Gtk.HBox w19 = new global::Gtk.HBox ();
w19.Spacing = 2;
global::Gtk.HBox w21 = new global::Gtk.HBox ();
w21.Spacing = 2;
// Container child GtkHBox.Gtk.Container+ContainerChild
global::Gtk.Image w20 = new global::Gtk.Image ();
w20.Pixbuf = global::Stetic.IconLoader.LoadIcon (this, "gtk-go-down", global::Gtk.IconSize.Menu);
w19.Add (w20);
global::Gtk.Image w22 = new global::Gtk.Image ();
w22.Pixbuf = global::Stetic.IconLoader.LoadIcon (this, "gtk-go-down", global::Gtk.IconSize.Menu);
w21.Add (w22);
// Container child GtkHBox.Gtk.Container+ContainerChild
global::Gtk.Label w22 = new global::Gtk.Label ();
w22.LabelProp = "Activer";
w22.UseUnderline = true;
w19.Add (w22);
w18.Add (w19);
this.btnActiv.Add (w18);
global::Gtk.Label w24 = new global::Gtk.Label ();
w24.LabelProp = "Activer";
w24.UseUnderline = true;
w21.Add (w24);
w20.Add (w21);
this.btnActiv.Add (w20);
this.hbuttonbox2.Add (this.btnActiv);
global::Gtk.ButtonBox.ButtonBoxChild w26 = ((global::Gtk.ButtonBox.ButtonBoxChild)(this.hbuttonbox2 [this.btnActiv]));
w26.Expand = false;
w26.Fill = false;
global::Gtk.ButtonBox.ButtonBoxChild w28 = ((global::Gtk.ButtonBox.ButtonBoxChild)(this.hbuttonbox2 [this.btnActiv]));
w28.Expand = false;
w28.Fill = false;
// Container child hbuttonbox2.Gtk.ButtonBox+ButtonBoxChild
this.btnDesactiv = new global::Gtk.Button ();
this.btnDesactiv.Sensitive = false;
@ -269,48 +299,47 @@ namespace DMX2
this.btnDesactiv.Name = "btnDesactiv";
this.btnDesactiv.UseUnderline = true;
// Container child btnDesactiv.Gtk.Container+ContainerChild
global::Gtk.Alignment w27 = new global::Gtk.Alignment (0.5F, 0.5F, 0F, 0F);
global::Gtk.Alignment w29 = new global::Gtk.Alignment (0.5F, 0.5F, 0F, 0F);
// Container child GtkAlignment.Gtk.Container+ContainerChild
global::Gtk.HBox w28 = new global::Gtk.HBox ();
w28.Spacing = 2;
global::Gtk.HBox w30 = new global::Gtk.HBox ();
w30.Spacing = 2;
// Container child GtkHBox.Gtk.Container+ContainerChild
global::Gtk.Image w29 = new global::Gtk.Image ();
w29.Pixbuf = global::Stetic.IconLoader.LoadIcon (this, "gtk-go-up", global::Gtk.IconSize.Menu);
w28.Add (w29);
global::Gtk.Image w31 = new global::Gtk.Image ();
w31.Pixbuf = global::Stetic.IconLoader.LoadIcon (this, "gtk-go-up", global::Gtk.IconSize.Menu);
w30.Add (w31);
// Container child GtkHBox.Gtk.Container+ContainerChild
global::Gtk.Label w31 = new global::Gtk.Label ();
w31.LabelProp = "Désactiver";
w31.UseUnderline = true;
w28.Add (w31);
w27.Add (w28);
this.btnDesactiv.Add (w27);
global::Gtk.Label w33 = new global::Gtk.Label ();
w33.LabelProp = "Désactiver";
w33.UseUnderline = true;
w30.Add (w33);
w29.Add (w30);
this.btnDesactiv.Add (w29);
this.hbuttonbox2.Add (this.btnDesactiv);
global::Gtk.ButtonBox.ButtonBoxChild w35 = ((global::Gtk.ButtonBox.ButtonBoxChild)(this.hbuttonbox2 [this.btnDesactiv]));
w35.Position = 1;
w35.Expand = false;
w35.Fill = false;
global::Gtk.ButtonBox.ButtonBoxChild w37 = ((global::Gtk.ButtonBox.ButtonBoxChild)(this.hbuttonbox2 [this.btnDesactiv]));
w37.Position = 1;
w37.Expand = false;
w37.Fill = false;
this.table1.Add (this.hbuttonbox2);
global::Gtk.Table.TableChild w36 = ((global::Gtk.Table.TableChild)(this.table1 [this.hbuttonbox2]));
w36.TopAttach = ((uint)(1));
w36.BottomAttach = ((uint)(2));
w36.LeftAttach = ((uint)(1));
w36.RightAttach = ((uint)(2));
w36.XOptions = ((global::Gtk.AttachOptions)(0));
w36.YOptions = ((global::Gtk.AttachOptions)(4));
global::Gtk.Table.TableChild w38 = ((global::Gtk.Table.TableChild)(this.table1 [this.hbuttonbox2]));
w38.TopAttach = ((uint)(1));
w38.BottomAttach = ((uint)(2));
w38.LeftAttach = ((uint)(1));
w38.RightAttach = ((uint)(2));
w38.XOptions = ((global::Gtk.AttachOptions)(0));
w38.YOptions = ((global::Gtk.AttachOptions)(4));
// Container child table1.Gtk.Table+TableChild
this.vbox2 = new global::Gtk.VBox ();
this.vbox2.Name = "vbox2";
this.vbox2.Spacing = 6;
// Container child vbox2.Gtk.Box+BoxChild
this.label1 = new global::Gtk.Label ();
this.label1.Name = "label1";
this.label1.Xalign = 0F;
this.label1.LabelProp = "Interfaces disponibles :";
this.vbox2.Add (this.label1);
global::Gtk.Box.BoxChild w37 = ((global::Gtk.Box.BoxChild)(this.vbox2 [this.label1]));
w37.Position = 0;
w37.Expand = false;
w37.Fill = false;
global::Gtk.Box.BoxChild w39 = ((global::Gtk.Box.BoxChild)(this.vbox2 [this.label1]));
w39.Position = 0;
w39.Expand = false;
w39.Fill = false;
// Container child vbox2.Gtk.Box+BoxChild
this.GtkScrolledWindow = new global::Gtk.ScrolledWindow ();
this.GtkScrolledWindow.Name = "GtkScrolledWindow";
@ -322,12 +351,12 @@ namespace DMX2
this.listDetect.HeadersVisible = false;
this.GtkScrolledWindow.Add (this.listDetect);
this.vbox2.Add (this.GtkScrolledWindow);
global::Gtk.Box.BoxChild w39 = ((global::Gtk.Box.BoxChild)(this.vbox2 [this.GtkScrolledWindow]));
w39.Position = 1;
global::Gtk.Box.BoxChild w41 = ((global::Gtk.Box.BoxChild)(this.vbox2 [this.GtkScrolledWindow]));
w41.Position = 1;
this.table1.Add (this.vbox2);
global::Gtk.Table.TableChild w40 = ((global::Gtk.Table.TableChild)(this.table1 [this.vbox2]));
w40.LeftAttach = ((uint)(1));
w40.RightAttach = ((uint)(2));
global::Gtk.Table.TableChild w42 = ((global::Gtk.Table.TableChild)(this.table1 [this.vbox2]));
w42.LeftAttach = ((uint)(1));
w42.RightAttach = ((uint)(2));
// Container child table1.Gtk.Table+TableChild
this.vbox3 = new global::Gtk.VBox ();
this.vbox3.Name = "vbox3";
@ -338,10 +367,10 @@ namespace DMX2
this.label2.Xalign = 0F;
this.label2.LabelProp = "Interfaces selectionnées : ";
this.vbox3.Add (this.label2);
global::Gtk.Box.BoxChild w41 = ((global::Gtk.Box.BoxChild)(this.vbox3 [this.label2]));
w41.Position = 0;
w41.Expand = false;
w41.Fill = false;
global::Gtk.Box.BoxChild w43 = ((global::Gtk.Box.BoxChild)(this.vbox3 [this.label2]));
w43.Position = 0;
w43.Expand = false;
w43.Fill = false;
// Container child vbox3.Gtk.Box+BoxChild
this.GtkScrolledWindow1 = new global::Gtk.ScrolledWindow ();
this.GtkScrolledWindow1.Name = "GtkScrolledWindow1";
@ -353,23 +382,23 @@ namespace DMX2
this.listKnown.HeadersVisible = false;
this.GtkScrolledWindow1.Add (this.listKnown);
this.vbox3.Add (this.GtkScrolledWindow1);
global::Gtk.Box.BoxChild w43 = ((global::Gtk.Box.BoxChild)(this.vbox3 [this.GtkScrolledWindow1]));
w43.Position = 1;
global::Gtk.Box.BoxChild w45 = ((global::Gtk.Box.BoxChild)(this.vbox3 [this.GtkScrolledWindow1]));
w45.Position = 1;
this.table1.Add (this.vbox3);
global::Gtk.Table.TableChild w44 = ((global::Gtk.Table.TableChild)(this.table1 [this.vbox3]));
w44.TopAttach = ((uint)(2));
w44.BottomAttach = ((uint)(3));
w44.LeftAttach = ((uint)(1));
w44.RightAttach = ((uint)(2));
global::Gtk.Table.TableChild w46 = ((global::Gtk.Table.TableChild)(this.table1 [this.vbox3]));
w46.TopAttach = ((uint)(2));
w46.BottomAttach = ((uint)(3));
w46.LeftAttach = ((uint)(1));
w46.RightAttach = ((uint)(2));
w1.Add (this.table1);
global::Gtk.Box.BoxChild w45 = ((global::Gtk.Box.BoxChild)(w1 [this.table1]));
w45.Position = 0;
global::Gtk.Box.BoxChild w47 = ((global::Gtk.Box.BoxChild)(w1 [this.table1]));
w47.Position = 0;
// Internal child DMX2.GestionMidiUI.ActionArea
global::Gtk.HButtonBox w46 = this.ActionArea;
w46.Name = "dialog1_ActionArea";
w46.Spacing = 10;
w46.BorderWidth = ((uint)(5));
w46.LayoutStyle = ((global::Gtk.ButtonBoxStyle)(4));
global::Gtk.HButtonBox w48 = this.ActionArea;
w48.Name = "dialog1_ActionArea";
w48.Spacing = 10;
w48.BorderWidth = ((uint)(5));
w48.LayoutStyle = ((global::Gtk.ButtonBoxStyle)(4));
// Container child dialog1_ActionArea.Gtk.ButtonBox+ButtonBoxChild
this.buttonClose = new global::Gtk.Button ();
this.buttonClose.CanDefault = true;
@ -379,9 +408,9 @@ namespace DMX2
this.buttonClose.UseUnderline = true;
this.buttonClose.Label = "gtk-close";
this.AddActionWidget (this.buttonClose, -7);
global::Gtk.ButtonBox.ButtonBoxChild w47 = ((global::Gtk.ButtonBox.ButtonBoxChild)(w46 [this.buttonClose]));
w47.Expand = false;
w47.Fill = false;
global::Gtk.ButtonBox.ButtonBoxChild w49 = ((global::Gtk.ButtonBox.ButtonBoxChild)(w48 [this.buttonClose]));
w49.Expand = false;
w49.Fill = false;
if ((this.Child != null)) {
this.Child.ShowAll ();
}
@ -396,6 +425,7 @@ namespace DMX2
this.spinUPCh.ValueChanged += new global::System.EventHandler (this.OnSpinUPChValueChanged);
this.spinPageUp.ValueChanged += new global::System.EventHandler (this.OnSpinPageUpValueChanged);
this.spinPageDown.ValueChanged += new global::System.EventHandler (this.OnSpinPageDownValueChanged);
this.spinMax14b.ValueChanged += new global::System.EventHandler (this.OnSpinMax14bValueChanged);
this.chkPg.Toggled += new global::System.EventHandler (this.OnChkPgToggled);
this.chkFourteenBits.Toggled += new global::System.EventHandler (this.OnChkFourteenBitsToggled);
this.buttonClose.Clicked += new global::System.EventHandler (this.OnButtonCloseClicked);

View file

@ -1820,6 +1820,7 @@ au sequenceur</property>
<child>
<widget class="Gtk.Label" id="actLabel">
<property name="MemberName" />
<property name="LabelProp" translatable="yes" />
<property name="UseMarkup">True</property>
<property name="Wrap">True</property>
</widget>
@ -2116,6 +2117,7 @@ au sequenceur</property>
<child>
<widget class="Gtk.Label" id="GtkLabel2">
<property name="MemberName" />
<property name="LabelProp" translatable="yes" />
<property name="UseMarkup">True</property>
</widget>
<packing>
@ -3217,7 +3219,7 @@ trames DMX (ms)</property>
<child>
<widget class="Gtk.Table" id="table2">
<property name="MemberName" />
<property name="NRows">5</property>
<property name="NRows">6</property>
<property name="NColumns">2</property>
<property name="RowSpacing">6</property>
<property name="ColumnSpacing">6</property>
@ -3330,6 +3332,56 @@ trames DMX (ms)</property>
<property name="YShrink">False</property>
</packing>
</child>
<child>
<widget class="Gtk.Label" id="label6">
<property name="MemberName" />
<property name="Xpad">20</property>
<property name="Xalign">0</property>
<property name="LabelProp" translatable="yes">Valeur entrée max :</property>
</widget>
<packing>
<property name="TopAttach">5</property>
<property name="BottomAttach">6</property>
<property name="AutoSize">True</property>
<property name="XOptions">Fill</property>
<property name="YOptions">Fill</property>
<property name="XExpand">False</property>
<property name="XFill">True</property>
<property name="XShrink">False</property>
<property name="YExpand">False</property>
<property name="YFill">True</property>
<property name="YShrink">False</property>
</packing>
</child>
<child>
<widget class="Gtk.SpinButton" id="spinMax14b">
<property name="MemberName" />
<property name="CanFocus">True</property>
<property name="Lower">1</property>
<property name="Upper">16383</property>
<property name="PageIncrement">10</property>
<property name="StepIncrement">1</property>
<property name="ClimbRate">1</property>
<property name="Numeric">True</property>
<property name="Value">127</property>
<signal name="ValueChanged" handler="OnSpinMax14bValueChanged" />
</widget>
<packing>
<property name="TopAttach">5</property>
<property name="BottomAttach">6</property>
<property name="LeftAttach">1</property>
<property name="RightAttach">2</property>
<property name="AutoSize">True</property>
<property name="XOptions">Fill</property>
<property name="YOptions">Fill</property>
<property name="XExpand">False</property>
<property name="XFill">True</property>
<property name="XShrink">False</property>
<property name="YExpand">False</property>
<property name="YFill">True</property>
<property name="YShrink">False</property>
</packing>
</child>
<child>
<widget class="Gtk.SpinButton" id="spinNbPage">
<property name="MemberName" />
@ -3448,7 +3500,7 @@ trames DMX (ms)</property>
</widget>
</child>
<child>
<widget class="Gtk.Label" id="GtkLabel5">
<widget class="Gtk.Label" id="GtkLabel6">
<property name="MemberName" />
<property name="LabelProp" translatable="yes">&lt;b&gt;Options Midi&lt;/b&gt;</property>
<property name="UseMarkup">True</property>
@ -3848,6 +3900,7 @@ trames DMX (ms)</property>
<child>
<widget class="Gtk.Label" id="titleLabel">
<property name="MemberName" />
<property name="LabelProp" translatable="yes" />
<property name="UseMarkup">True</property>
<property name="Wrap">True</property>
</widget>