diff --git a/MobiFlight/MaximumDeviceNumberReachedMobiFlightException.cs b/MobiFlight/MaximumDeviceNumberReachedMobiFlightException.cs new file mode 100644 index 000000000..1712076af --- /dev/null +++ b/MobiFlight/MaximumDeviceNumberReachedMobiFlightException.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace MobiFlight +{ + class MaximumDeviceNumberReachedMobiFlightException : Exception + { + public String DeviceType; + public int MaxNumber; + public MaximumDeviceNumberReachedMobiFlightException(String DeviceType, int MaxNumber) + : base(String.Format("Max number of {0} is {1}", DeviceType, MaxNumber)) + { + this.DeviceType = DeviceType; + this.MaxNumber = MaxNumber; + } + } +} diff --git a/MobiFlight/MobiFlightButton.cs b/MobiFlight/MobiFlightButton.cs index e70eac4a0..e98dff8ef 100644 --- a/MobiFlight/MobiFlightButton.cs +++ b/MobiFlight/MobiFlightButton.cs @@ -8,6 +8,7 @@ namespace MobiFlight { class MobiFlightButton : IConnectedDevice { + public const string TYPE = "Button"; public enum InputEvent { PRESS, diff --git a/MobiFlight/MobiFlightEncoder.cs b/MobiFlight/MobiFlightEncoder.cs index 0d2f4d661..94114bfc5 100644 --- a/MobiFlight/MobiFlightEncoder.cs +++ b/MobiFlight/MobiFlightEncoder.cs @@ -8,6 +8,7 @@ namespace MobiFlight { class MobiFlightEncoder : IConnectedDevice { + public const string TYPE = "Encoder"; public enum InputEvent { LEFT, diff --git a/MobiFlight/MobiFlightModule.cs b/MobiFlight/MobiFlightModule.cs index b89997e97..da85c3450 100644 --- a/MobiFlight/MobiFlightModule.cs +++ b/MobiFlight/MobiFlightModule.cs @@ -151,6 +151,8 @@ public Config.Config Config { Dictionary servoModules = new Dictionary(); Dictionary outputs = new Dictionary(); Dictionary lcdDisplays = new Dictionary(); + Dictionary buttons = new Dictionary(); + Dictionary encoders = new Dictionary(); Dictionary buttonValues = new Dictionary(); @@ -285,6 +287,8 @@ public void LoadConfig() servoModules.Clear(); outputs.Clear(); lcdDisplays.Clear(); + buttons.Clear(); + encoders.Clear(); foreach (Config.BaseDevice device in Config.Items) { @@ -319,6 +323,14 @@ public void LoadConfig() device.Name = GenerateUniqueDeviceName(outputs.Keys.ToArray(), device.Name); lcdDisplays.Add(device.Name, new MobiFlightLcdDisplay() { CmdMessenger = _cmdMessenger, Name = device.Name, Address = lcdDisplays.Count, Cols = (device as Config.LcdDisplay).Cols, Lines = (device as Config.LcdDisplay).Lines }); break; + case DeviceType.Button: + device.Name = GenerateUniqueDeviceName(outputs.Keys.ToArray(), device.Name); + buttons.Add(device.Name, new MobiFlightButton() { Name = device.Name }); + break; + case DeviceType.Encoder: + device.Name = GenerateUniqueDeviceName(outputs.Keys.ToArray(), device.Name); + encoders.Add(device.Name, new MobiFlightEncoder() { Name = device.Name }); + break; } } } @@ -771,6 +783,20 @@ public List GetConnectedDevices() return result; } + public Dictionary GetConnectedDevicesStatistics() + { + Dictionary result = new Dictionary(); + result[MobiFlightOutput.TYPE] = outputs.Count; + result[MobiFlightLedModule.TYPE] = ledModules.Count; + result[MobiFlightStepper.TYPE] = stepperModules.Count; + result[MobiFlightServo.TYPE] = servoModules.Count; + result[MobiFlightLcdDisplay.TYPE] = lcdDisplays.Count; + result[MobiFlightButton.TYPE] = buttons.Count; + result[MobiFlightEncoder.TYPE] = encoders.Count; + + return result; + } + public List GetConnectedDevices(String name) { List result = new List(); diff --git a/MobiFlight/MobiFlightModuleInfo.cs b/MobiFlight/MobiFlightModuleInfo.cs index 0bc5d3c63..ecd0ceb4b 100644 --- a/MobiFlight/MobiFlightModuleInfo.cs +++ b/MobiFlight/MobiFlightModuleInfo.cs @@ -5,6 +5,59 @@ namespace MobiFlight { + public abstract class MobiFlightCapabilities + { + public int MaxOutputs = 0; + public int MaxButtons = 0; + public int MaxLedSegments = 0; + public int MaxEncoders = 0; + public int MaxSteppers = 0; + public int MaxServos = 0; + public int MaxLcdI2C = 0; + } + + public class MegaCapabilities : MobiFlightCapabilities + { + public MegaCapabilities() + { + MaxOutputs = 40; + MaxButtons = 68; + MaxLedSegments = 4; + MaxEncoders = 20; + MaxSteppers = 10; + MaxServos = 10; + MaxLcdI2C = 2; + } + } + + public class MicroCapabilities : MobiFlightCapabilities + { + public MicroCapabilities() + { + MaxOutputs = 10; + MaxButtons = 16; + MaxLedSegments = 1; + MaxEncoders = 4; + MaxSteppers = 2; + MaxServos = 2; + MaxLcdI2C = 2; + } + } + + public class UnoCapabilities : MobiFlightCapabilities + { + public UnoCapabilities() + { + MaxOutputs = 8; + MaxButtons = 8; + MaxLedSegments =1; + MaxEncoders = 2; + MaxSteppers = 2; + MaxServos = 2; + MaxLcdI2C = 2; + } + } + public class MobiFlightPin { public byte Pin { get; set; } @@ -284,5 +337,27 @@ public void SetTypeByVidPid(String VidPid) Type = TYPE_ARDUINO_UNO; } } + + public MobiFlightCapabilities GetCapabilities() + { + MobiFlightCapabilities result = null; + + switch(Type) + { + case TYPE_MEGA: + result = new MegaCapabilities(); + break; + + case TYPE_MICRO: + result = new MicroCapabilities(); + break; + + case TYPE_UNO: + result = new UnoCapabilities(); + break; + } + + return result; + } } } diff --git a/MobiFlightConnector.csproj b/MobiFlightConnector.csproj index b4a27ae8d..9f75e826f 100644 --- a/MobiFlightConnector.csproj +++ b/MobiFlightConnector.csproj @@ -167,6 +167,7 @@ + diff --git a/ProjectMessages/ProjectMessages.Designer.cs b/ProjectMessages/ProjectMessages.Designer.cs index 67508a245..d670b1a35 100644 --- a/ProjectMessages/ProjectMessages.Designer.cs +++ b/ProjectMessages/ProjectMessages.Designer.cs @@ -623,6 +623,15 @@ internal static string uiMessageInvalidValueHexOnly { } } + /// + /// Looks up a localized string similar to You cannot add another {1}. The maximum is {0} on a {2}.. + /// + internal static string uiMessageMaxNumberOfDevicesReached { + get { + return ResourceManager.GetString("uiMessageMaxNumberOfDevicesReached", resourceCulture); + } + } + /// /// Looks up a localized string similar to MFConnector still active. /// diff --git a/ProjectMessages/ProjectMessages.de.resx b/ProjectMessages/ProjectMessages.de.resx index 94197dcfa..554ccd0d1 100644 --- a/ProjectMessages/ProjectMessages.de.resx +++ b/ProjectMessages/ProjectMessages.de.resx @@ -444,4 +444,7 @@ Du kannst es jederzeit wieder in den Einstellungen aktivieren Die Verbindung zu SimConnect wurde unterbrochen. + + Du kannst kein weiteres {0} hinzufügen. Die maximale Anzahl sind {1} bei einem {2}. + \ No newline at end of file diff --git a/ProjectMessages/ProjectMessages.resx b/ProjectMessages/ProjectMessages.resx index 3320c11a2..310fb9ccf 100644 --- a/ProjectMessages/ProjectMessages.resx +++ b/ProjectMessages/ProjectMessages.resx @@ -454,4 +454,7 @@ You can always enable it later again in the settings menu. The connection to SimConnect got lost. + + You cannot add another {1}. The maximum is {0} on a {2}. + \ No newline at end of file diff --git a/UI/Panels/Settings/MobiFlightPanel.cs b/UI/Panels/Settings/MobiFlightPanel.cs index d35a1fc0e..73a49d0b4 100644 --- a/UI/Panels/Settings/MobiFlightPanel.cs +++ b/UI/Panels/Settings/MobiFlightPanel.cs @@ -347,18 +347,34 @@ private void syncPanelWithSelectedDevice(TreeNode selectedNode) /// private void addDeviceTypeToolStripMenuItem_Click(object sender, EventArgs e) { + MobiFlight.Config.BaseDevice cfgItem = null; + MobiFlightModule tempModule = null; try { - MobiFlight.Config.BaseDevice cfgItem = null; + cfgItem = null; + tempModule = getVirtualModuleFromTree(); + tempModule.LoadConfig(); + Dictionary statistics = tempModule.GetConnectedDevicesStatistics(); + switch ((sender as ToolStripMenuItem).Name) { case "servoToolStripMenuItem": case "addServoToolStripMenuItem": + if (statistics[MobiFlightServo.TYPE] == tempModule.ToMobiFlightModuleInfo().GetCapabilities().MaxServos) + { + throw new MaximumDeviceNumberReachedMobiFlightException(MobiFlightServo.TYPE, tempModule.ToMobiFlightModuleInfo().GetCapabilities().MaxServos); + } + cfgItem = new MobiFlight.Config.Servo(); (cfgItem as MobiFlight.Config.Servo).DataPin = getVirtualModuleFromTree().GetFreePins().ElementAt(0).Pin.ToString(); break; case "stepperToolStripMenuItem": case "addStepperToolStripMenuItem": + if (statistics[MobiFlightStepper.TYPE] == tempModule.ToMobiFlightModuleInfo().GetCapabilities().MaxSteppers) + { + throw new MaximumDeviceNumberReachedMobiFlightException(MobiFlightStepper.TYPE, tempModule.ToMobiFlightModuleInfo().GetCapabilities().MaxSteppers); + } + cfgItem = new MobiFlight.Config.Stepper(); (cfgItem as MobiFlight.Config.Stepper).Pin1 = getVirtualModuleFromTree().GetFreePins().ElementAt(0).Pin.ToString(); (cfgItem as MobiFlight.Config.Stepper).Pin2 = getVirtualModuleFromTree().GetFreePins().ElementAt(1).Pin.ToString(); @@ -368,11 +384,21 @@ private void addDeviceTypeToolStripMenuItem_Click(object sender, EventArgs e) break; case "ledOutputToolStripMenuItem": case "addOutputToolStripMenuItem": + if (statistics[MobiFlightOutput.TYPE] == tempModule.ToMobiFlightModuleInfo().GetCapabilities().MaxOutputs) + { + throw new MaximumDeviceNumberReachedMobiFlightException(MobiFlightOutput.TYPE, tempModule.ToMobiFlightModuleInfo().GetCapabilities().MaxOutputs); + } + cfgItem = new MobiFlight.Config.Output(); (cfgItem as MobiFlight.Config.Output).Pin = getVirtualModuleFromTree().GetFreePins().ElementAt(0).Pin.ToString(); break; case "ledSegmentToolStripMenuItem": case "addLedModuleToolStripMenuItem": + if (statistics[MobiFlightLedModule.TYPE] == tempModule.ToMobiFlightModuleInfo().GetCapabilities().MaxLedSegments) + { + throw new MaximumDeviceNumberReachedMobiFlightException(MobiFlightLedModule.TYPE, tempModule.ToMobiFlightModuleInfo().GetCapabilities().MaxLedSegments); + } + cfgItem = new MobiFlight.Config.LedModule(); (cfgItem as MobiFlight.Config.LedModule).DinPin = getVirtualModuleFromTree().GetFreePins().ElementAt(0).Pin.ToString(); (cfgItem as MobiFlight.Config.LedModule).ClkPin = getVirtualModuleFromTree().GetFreePins().ElementAt(1).Pin.ToString(); @@ -380,17 +406,32 @@ private void addDeviceTypeToolStripMenuItem_Click(object sender, EventArgs e) break; case "buttonToolStripMenuItem": case "addButtonToolStripMenuItem": + if (statistics[MobiFlightButton.TYPE] == tempModule.ToMobiFlightModuleInfo().GetCapabilities().MaxButtons) + { + throw new MaximumDeviceNumberReachedMobiFlightException(MobiFlightButton.TYPE, tempModule.ToMobiFlightModuleInfo().GetCapabilities().MaxButtons); + } + cfgItem = new MobiFlight.Config.Button(); (cfgItem as MobiFlight.Config.Button).Pin = getVirtualModuleFromTree().GetFreePins().ElementAt(0).Pin.ToString(); break; case "encoderToolStripMenuItem": case "addEncoderToolStripMenuItem": + if (statistics[MobiFlightEncoder.TYPE] == tempModule.ToMobiFlightModuleInfo().GetCapabilities().MaxEncoders) + { + throw new MaximumDeviceNumberReachedMobiFlightException(MobiFlightEncoder.TYPE, tempModule.ToMobiFlightModuleInfo().GetCapabilities().MaxEncoders); + } + cfgItem = new MobiFlight.Config.Encoder(); (cfgItem as MobiFlight.Config.Encoder).PinLeft = getVirtualModuleFromTree().GetFreePins().ElementAt(0).Pin.ToString(); (cfgItem as MobiFlight.Config.Encoder).PinRight = getVirtualModuleFromTree().GetFreePins().ElementAt(1).Pin.ToString(); break; case "LcdDisplayToolStripMenuItem": case "addLcdDisplayToolStripMenuItem": + if (statistics[MobiFlightLcdDisplay.TYPE] == tempModule.ToMobiFlightModuleInfo().GetCapabilities().MaxLcdI2C) + { + throw new MaximumDeviceNumberReachedMobiFlightException(MobiFlightLcdDisplay.TYPE, tempModule.ToMobiFlightModuleInfo().GetCapabilities().MaxLcdI2C); + } + cfgItem = new MobiFlight.Config.LcdDisplay(); // does not deal yet with these kind of pins because we use I2C break; @@ -422,6 +463,12 @@ private void addDeviceTypeToolStripMenuItem_Click(object sender, EventArgs e) mfModulesTreeView.SelectedNode = newNode; syncPanelWithSelectedDevice(newNode); } + catch (MaximumDeviceNumberReachedMobiFlightException ex) + { + MessageBox.Show(String.Format(i18n._tr("uiMessageMaxNumberOfDevicesReached"), ex.MaxNumber, ex.DeviceType, tempModule.Type), + i18n._tr("uiMessageNotEnoughPinsHint"), + MessageBoxButtons.OK, MessageBoxIcon.Error); + } catch (ArgumentOutOfRangeException ex) { MessageBox.Show(i18n._tr("uiMessageNotEnoughPinsMessage"),