public DeviceDialogViewModel(ArtemisDevice device,
                                     ICoreService coreService,
                                     IDeviceService deviceService,
                                     IRgbService rgbService,
                                     IDialogService dialogService,
                                     IDeviceDebugVmFactory factory)
        {
            _coreService   = coreService;
            _deviceService = deviceService;
            _rgbService    = rgbService;
            _dialogService = dialogService;

            Device           = device;
            PanZoomViewModel = new PanZoomViewModel();
            SelectedLeds     = new BindableCollection <ArtemisLed>();

            Items.Add(factory.DevicePropertiesTabViewModel(device));
            if (device.RgbDevice.DeviceInfo.DeviceType == RGBDeviceType.Keyboard)
            {
                Items.Add(factory.InputMappingsTabViewModel(device));
            }
            Items.Add(factory.DeviceInfoTabViewModel(device));
            Items.Add(factory.DeviceLedsTabViewModel(device));

            ActiveItem  = Items.First();
            DisplayName = $"{device.RgbDevice.DeviceInfo.Model} | Artemis";
        }
Exemple #2
0
        public ProfileDeviceViewModel(ArtemisDevice device)
        {
            Device = device;
            Leds   = new ObservableCollection <ProfileLedViewModel>();

            Task.Run(AddLedsAsync);
        }
Exemple #3
0
        private void BlinkDevice(ArtemisDevice device, int blinkCount)
        {
            // Draw a white overlay over the device
            void DrawOverlay(object sender, FrameRenderingEventArgs args)
            {
                args.Canvas.DrawPath(device.RenderPath, new SKPaint {
                    Color = new SKColor(255, 255, 255)
                });
            }

            _coreService.FrameRendering += DrawOverlay;

            // After 200ms, stop drawing the overlay
            Task.Run(async() =>
            {
                await Task.Delay(200);
                _coreService.FrameRendering -= DrawOverlay;

                if (blinkCount < 5)
                {
                    // After another 200ms, draw the overlay again, repeat six times
                    await Task.Delay(200);
                    BlinkDevice(device, blinkCount + 1);
                }
            });
        }
        private void AddDeviceIfMissing(IRGBDevice rgbDevice, ArtemisSurface surface)
        {
            string        deviceIdentifier = rgbDevice.GetDeviceIdentifier();
            ArtemisDevice device           = surface.Devices.FirstOrDefault(d => d.DeviceEntity.DeviceIdentifier == deviceIdentifier);

            if (device != null)
            {
                return;
            }

            // Find an existing device config and use that
            DeviceEntity existingDeviceConfig = surface.SurfaceEntity.DeviceEntities.FirstOrDefault(d => d.DeviceIdentifier == deviceIdentifier);

            if (existingDeviceConfig != null)
            {
                Plugin plugin = _pluginService.GetPluginByDevice(rgbDevice);
                device = new ArtemisDevice(rgbDevice, plugin, surface, existingDeviceConfig);
            }
            // Fall back on creating a new device
            else
            {
                _logger.Information(
                    "No device config found for {deviceInfo}, device hash: {deviceHashCode}. Adding a new entry.",
                    rgbDevice.DeviceInfo,
                    deviceIdentifier
                    );
                Plugin plugin = _pluginService.GetPluginByDevice(rgbDevice);
                device = new ArtemisDevice(rgbDevice, plugin, surface);
            }

            surface.Devices.Add(device);
        }
Exemple #5
0
        public DeviceSettingsViewModel(ArtemisDevice device, IDeviceService deviceService)
        {
            _deviceService = deviceService;
            Device         = device;

            Type            = Device.RgbDevice.DeviceInfo.DeviceType.ToString().Humanize();
            Name            = Device.RgbDevice.DeviceInfo.Model;
            Manufacturer    = Device.RgbDevice.DeviceInfo.Manufacturer;
            IsDeviceEnabled = true;
        }
        public override string GetDeviceLayoutName(ArtemisDevice device)
        {
            // Pumps can have different amounts of LEDs but share the model name "PUMP", by including the LED count in the layout name
            // we can still have different layouts of each type of pump
            if (device.RgbDevice.DeviceInfo.Model.Equals("pump", StringComparison.InvariantCultureIgnoreCase))
            {
                return($"PUMP-{device.RgbDevice.Count()}-ZONE.xml");
            }

            return(base.GetDeviceLayoutName(device));
        }
Exemple #7
0
        /// <summary>
        ///     Loads a layout for the specified device and wraps it in an <see cref="ArtemisLayout" />
        /// </summary>
        /// <param name="device">The device to load the layout for</param>
        /// <returns>The resulting Artemis layout</returns>
        public virtual ArtemisLayout LoadLayout(ArtemisDevice device)
        {
            string layoutDir = Path.Combine(Plugin.Directory.FullName, "Layouts");
            string filePath  = Path.Combine(
                layoutDir,
                device.RgbDevice.DeviceInfo.Manufacturer,
                device.RgbDevice.DeviceInfo.DeviceType.ToString(),
                device.GetLayoutFileName()
                );

            return(new ArtemisLayout(filePath, LayoutSource.Plugin));
        }
Exemple #8
0
        /// <summary>
        ///     Loads a layout from the user layout folder for the specified device and wraps it in an <see cref="ArtemisLayout" />
        /// </summary>
        /// <param name="device">The device to load the layout for</param>
        /// <returns>The resulting Artemis layout</returns>
        public virtual ArtemisLayout LoadUserLayout(ArtemisDevice device)
        {
            string layoutDir = Path.Combine(Constants.DataFolder, "user layouts");
            string filePath  = Path.Combine(
                layoutDir,
                device.RgbDevice.DeviceInfo.Manufacturer,
                device.RgbDevice.DeviceInfo.DeviceType.ToString(),
                device.GetLayoutFileName()
                );

            return(new ArtemisLayout(filePath, LayoutSource.User));
        }
Exemple #9
0
        public InputMappingsTabViewModel(ArtemisDevice device, IRgbService rgbService, IInputService inputService)
        {
            if (device.RgbDevice.DeviceInfo.DeviceType != RGBDeviceType.Keyboard)
            {
                throw new ArtemisUIException("The input mappings tab only supports keyboards");
            }
            _rgbService   = rgbService;
            _inputService = inputService;

            Device        = device;
            DisplayName   = "INPUT MAPPINGS";
            InputMappings = new BindableCollection <Tuple <ArtemisLed, ArtemisLed> >();
        }
Exemple #10
0
        public SurfaceDeviceViewModel(ArtemisDevice device)
        {
            Device = device;
            _leds  = new List <SurfaceLedViewModel>();

            if (Device.RgbDevice != null)
            {
                foreach (var led in Device.RgbDevice)
                {
                    _leds.Add(new SurfaceLedViewModel(led));
                }
            }
        }
Exemple #11
0
        public DevicePropertiesTabViewModel(ArtemisDevice device,
                                            ICoreService coreService,
                                            IRgbService rgbService,
                                            IDialogService dialogService,
                                            IModelValidator <DevicePropertiesTabViewModel> validator) : base(validator)
        {
            _coreService   = coreService;
            _rgbService    = rgbService;
            _dialogService = dialogService;

            Device      = device;
            DisplayName = "PROPERTIES";
        }
Exemple #12
0
        public DeviceLayoutDialogViewModel(ArtemisDevice device, IRgbService rgbService)
        {
            _rgbService          = rgbService;
            Device               = device;
            SelectPhysicalLayout = !device.DeviceProvider.CanDetectPhysicalLayout;

            Task.Run(() =>
            {
                AutocompleteSource = new RegionInfoAutocompleteSource();
                SelectedRegion     = AutocompleteSource.Regions.FirstOrDefault(r => r.TwoLetterISORegionName == Device.LogicalLayout ||
                                                                               r.TwoLetterISORegionName == "US" && Device.LogicalLayout == "NA");
            });
        }
        public DeviceDialogViewModel(ArtemisDevice device, IDeviceService deviceService, IRgbService rgbService, IDialogService dialogService, IDeviceDebugVmFactory factory)
        {
            _deviceService = deviceService;
            _rgbService    = rgbService;
            _dialogService = dialogService;

            Device           = device;
            PanZoomViewModel = new PanZoomViewModel();

            Items.Add(factory.DevicePropertiesTabViewModel(device));
            Items.Add(factory.DeviceInfoTabViewModel(device));
            Items.Add(factory.DeviceLedsTabViewModel(device));
            ActiveItem  = Items.First();
            DisplayName = $"{device.RgbDevice.DeviceInfo.Model} | Artemis";
        }
        public DeviceLayoutDialogViewModel(ArtemisDevice device, IRgbService rgbService, IDialogService dialogService)
        {
            _rgbService          = rgbService;
            Device               = device;
            SelectPhysicalLayout = !device.DeviceProvider.CanDetectPhysicalLayout;

            try
            {
                AutocompleteSource = new RegionInfoAutocompleteSource();
            }
            catch (Exception e)
            {
                dialogService.ShowExceptionDialog("Failed to get region information for keyboard layout selection", e);
                Session?.Close(false);
            }
        }
        public DeviceSettingsViewModel(ArtemisDevice device, IDeviceService deviceService, IDialogService dialogService,
                                       IWindowManager windowManager, IDeviceDebugVmFactory deviceDebugVmFactory)
        {
            _deviceService        = deviceService;
            _dialogService        = dialogService;
            _windowManager        = windowManager;
            _deviceDebugVmFactory = deviceDebugVmFactory;
            Device = device;

            Type         = Device.RgbDevice.DeviceInfo.DeviceType.ToString().Humanize();
            Name         = Device.RgbDevice.DeviceInfo.Model;
            Manufacturer = Device.RgbDevice.DeviceInfo.Manufacturer;

            // TODO: Implement this bad boy
            IsDeviceEnabled = true;
        }
Exemple #16
0
        public DeviceSettingsViewModel(ArtemisDevice device,
                                       IDeviceService deviceService,
                                       IDialogService dialogService,
                                       IWindowManager windowManager,
                                       IDeviceDebugVmFactory deviceDebugVmFactory,
                                       IRgbService rgbService)
        {
            _deviceService        = deviceService;
            _dialogService        = dialogService;
            _windowManager        = windowManager;
            _deviceDebugVmFactory = deviceDebugVmFactory;
            _rgbService           = rgbService;
            Device = device;

            Type         = Device.RgbDevice.DeviceInfo.DeviceType.ToString().Humanize();
            Name         = Device.RgbDevice.DeviceInfo.Model;
            Manufacturer = Device.RgbDevice.DeviceInfo.Manufacturer;
        }
        public SurfaceDeviceDetectInputViewModel(ArtemisDevice device, IInputService inputService, IMessageService messageService, IRgbService rgbService)
        {
            Device  = device;
            Title   = $"{Device.RgbDevice.DeviceInfo.DeviceName} - Detect input";
            IsMouse = Device.RgbDevice.DeviceInfo.DeviceType == RGBDeviceType.Mouse;

            _inputService   = inputService;
            _messageService = messageService;
            _rgbService     = rgbService;
            _inputService.IdentifyDevice(Device);
            _inputService.DeviceIdentified += InputServiceOnDeviceIdentified;

            // Create a LED group way at the top
            _ledGroup = new ListLedGroup(_rgbService.Surface, Device.Leds.Select(l => l.RgbLed))
            {
                Brush  = new SolidColorBrush(new Color(255, 255, 0)),
                ZIndex = 999
            };
        }
        private async Task RequestLayoutInput(ArtemisDevice artemisDevice)
        {
            bool configure = await _dialogService.ShowConfirmDialog(
                "Device requires layout info",
                $"Artemis could not detect the layout of your {artemisDevice.RgbDevice.DeviceInfo.DeviceName}. Please configure out manually",
                "Configure",
                "Ignore for now"
                );

            if (!configure)
            {
                _ignoredDevices.Add(artemisDevice);
                return;
            }

            await _dialogService.ShowDialog <DeviceLayoutDialogViewModel>(new Dictionary <string, object> {
                { "device", artemisDevice }
            });
        }
Exemple #19
0
        private void BlinkDevice(ArtemisDevice device, int blinkCount)
        {
            // Create a LED group way at the top
            ListLedGroup ledGroup = new ListLedGroup(device.Leds.Select(l => l.RgbLed))
            {
                Brush  = new SolidColorBrush(new Color(255, 255, 255)),
                ZIndex = 999
            };

            // After 200ms, detach the LED group
            Task.Run(async() =>
            {
                await Task.Delay(200);
                ledGroup.Detach();

                if (blinkCount < 5)
                {
                    // After another 200ms, start over, repeat six times
                    await Task.Delay(200);
                    BlinkDevice(device, blinkCount + 1);
                }
            });
        }
Exemple #20
0
 public ListDeviceViewModel(ArtemisDevice device, SurfaceEditorViewModel surfaceEditorViewModel)
 {
     Device = device;
     Parent = surfaceEditorViewModel;
 }
Exemple #21
0
 public void IdentifyDevice(ArtemisDevice device)
 {
     BlinkDevice(device, 0);
 }
 internal LedClickedEventArgs(ArtemisDevice device, ArtemisLed led)
 {
     Device = device;
     Led    = led;
 }
 public DeviceDebugViewModel(ArtemisDevice device, IDeviceService deviceService, IDialogService dialogService)
 {
     _deviceService = deviceService;
     _dialogService = dialogService;
     Device         = device;
 }
Exemple #24
0
 public SurfaceDeviceViewModel(ArtemisDevice device)
 {
     Device = device;
 }
Exemple #25
0
 public DeviceLedsTabViewModel(ArtemisDevice device)
 {
     Device        = device;
     DisplayName   = "LEDS";
     LedViewModels = new BindableCollection <DeviceLedsTabLedViewModel>();
 }
 public DeviceInfoTabViewModel(ArtemisDevice device)
 {
     Device      = device;
     DisplayName = "INFO";
 }
        private void HandleKeyboardData(RawInputData data, RawInputKeyboardData keyboardData)
        {
            KeyboardKey key = (KeyboardKey)KeyInterop.KeyFromVirtualKey(keyboardData.Keyboard.VirutalKey);

            // Debug.WriteLine($"VK: {key} ({keyboardData.Keyboard.VirutalKey}), Flags: {keyboardData.Keyboard.Flags}, Scan code: {keyboardData.Keyboard.ScanCode}");

            // Sometimes we get double hits and they resolve to None, ignore those
            if (key == KeyboardKey.None)
            {
                return;
            }

            // Right alt triggers LeftCtrl with a different scan code for some reason, ignore those
            if (key == KeyboardKey.LeftCtrl && keyboardData.Keyboard.ScanCode == 56)
            {
                return;
            }

            string identifier = data.Device?.DevicePath;

            // Let the core know there is an identifier so it can store new identifications if applicable
            if (identifier != null)
            {
                OnIdentifierReceived(identifier, InputDeviceType.Keyboard);
            }

            ArtemisDevice device = null;

            if (identifier != null)
            {
                try
                {
                    device = _inputService.GetDeviceByIdentifier(this, identifier, InputDeviceType.Keyboard);
                }
                catch (Exception e)
                {
                    _logger.Warning(e, "Failed to retrieve input device by its identifier");
                }
            }

            // Duplicate keys with different positions can be identified by the LeftKey flag (even though its set of the key that's physically on the right)
            if (keyboardData.Keyboard.Flags == RawKeyboardFlags.LeftKey || keyboardData.Keyboard.Flags == (RawKeyboardFlags.LeftKey | RawKeyboardFlags.Up))
            {
                if (key == KeyboardKey.Enter)
                {
                    key = KeyboardKey.NumPadEnter;
                }
                if (key == KeyboardKey.LeftCtrl)
                {
                    key = KeyboardKey.RightCtrl;
                }
                if (key == KeyboardKey.LeftAlt)
                {
                    key = KeyboardKey.RightAlt;
                }
            }

            if (key == KeyboardKey.LeftShift && keyboardData.Keyboard.ScanCode == 54)
            {
                key = KeyboardKey.RightShift;
            }

            bool isDown = keyboardData.Keyboard.Flags != RawKeyboardFlags.Up &&
                          keyboardData.Keyboard.Flags != (RawKeyboardFlags.Up | RawKeyboardFlags.LeftKey) &&
                          keyboardData.Keyboard.Flags != (RawKeyboardFlags.Up | RawKeyboardFlags.RightKey);

            OnKeyboardDataReceived(device, key, isDown);
            UpdateToggleStatus();
        }
        private void HandleMouseData(RawInputData data, RawInputMouseData mouseData)
        {
            // Only submit mouse movement 25 times per second but increment the delta
            // This can create a small inaccuracy of course, but Artemis is not a shooter :')
            if (mouseData.Mouse.Buttons == RawMouseButtonFlags.None)
            {
                _mouseDeltaX += mouseData.Mouse.LastX;
                _mouseDeltaY += mouseData.Mouse.LastY;
                if (DateTime.Now - _lastMouseUpdate < TimeSpan.FromMilliseconds(40))
                {
                    return;
                }
            }

            ArtemisDevice device     = null;
            string        identifier = data.Device?.DevicePath;

            if (identifier != null)
            {
                try
                {
                    device = _inputService.GetDeviceByIdentifier(this, identifier, InputDeviceType.Keyboard);
                }
                catch (Exception e)
                {
                    _logger.Warning(e, "Failed to retrieve input device by its identifier");
                }
            }

            // Debug.WriteLine($"Buttons: {data.Mouse.Buttons}, Data: {data.Mouse.ButtonData}, Flags: {data.Mouse.Flags}, XY: {data.Mouse.LastX},{data.Mouse.LastY}");

            // Movement
            if (mouseData.Mouse.Buttons == RawMouseButtonFlags.None)
            {
                Win32Point cursorPosition = GetCursorPosition();
                OnMouseMoveDataReceived(device, cursorPosition.X, cursorPosition.Y, _mouseDeltaX, _mouseDeltaY);
                _mouseDeltaX     = 0;
                _mouseDeltaY     = 0;
                _lastMouseUpdate = DateTime.Now;
                return;
            }

            // Now we know its not movement, let the core know there is an identifier so it can store new identifications if applicable
            if (identifier != null)
            {
                OnIdentifierReceived(identifier, InputDeviceType.Mouse);
            }

            // Scrolling
            if (mouseData.Mouse.ButtonData != 0)
            {
                if (mouseData.Mouse.Buttons == RawMouseButtonFlags.MouseWheel)
                {
                    OnMouseScrollDataReceived(device, MouseScrollDirection.Vertical, mouseData.Mouse.ButtonData);
                }
                else if (mouseData.Mouse.Buttons == RawMouseButtonFlags.MouseHorizontalWheel)
                {
                    OnMouseScrollDataReceived(device, MouseScrollDirection.Horizontal, mouseData.Mouse.ButtonData);
                }
                return;
            }

            // Button presses
            MouseButton button = MouseButton.Left;
            bool        isDown = false;

            // Left
            if (DetermineMouseButton(mouseData, RawMouseButtonFlags.LeftButtonDown, RawMouseButtonFlags.LeftButtonUp, ref isDown))
            {
                button = MouseButton.Left;
            }
            // Middle
            else if (DetermineMouseButton(mouseData, RawMouseButtonFlags.MiddleButtonDown, RawMouseButtonFlags.MiddleButtonUp, ref isDown))
            {
                button = MouseButton.Middle;
            }
            // Right
            else if (DetermineMouseButton(mouseData, RawMouseButtonFlags.RightButtonDown, RawMouseButtonFlags.RightButtonUp, ref isDown))
            {
                button = MouseButton.Right;
            }
            // Button 4
            else if (DetermineMouseButton(mouseData, RawMouseButtonFlags.Button4Down, RawMouseButtonFlags.Button4Up, ref isDown))
            {
                button = MouseButton.Button4;
            }
            else if (DetermineMouseButton(mouseData, RawMouseButtonFlags.Button5Down, RawMouseButtonFlags.Button5Up, ref isDown))
            {
                button = MouseButton.Button5;
            }

            OnMouseButtonDataReceived(device, button, isDown);
        }
 private bool DeviceNeedsLayout(ArtemisDevice d)
 {
     return(d.RgbDevice.DeviceInfo.DeviceType == RGBDeviceType.Keyboard &&
            (d.LogicalLayout == null || d.PhysicalLayout == KeyboardLayoutType.Unknown) &&
            (!d.DeviceProvider.CanDetectLogicalLayout || !d.DeviceProvider.CanDetectPhysicalLayout));
 }
 public SurfaceDeviceViewModel(ArtemisDevice device, IRgbService rgbService)
 {
     Device      = device;
     _rgbService = rgbService;
 }