diff --git a/Samples/Genetec.Dap.CodeSamples.sln b/Samples/Genetec.Dap.CodeSamples.sln index 0f809f96..015b0d44 100644 --- a/Samples/Genetec.Dap.CodeSamples.sln +++ b/Samples/Genetec.Dap.CodeSamples.sln @@ -1601,6 +1601,7 @@ Global Shared\Shared.projitems*{5a217bbf-eafa-4f52-b81a-02c4232da68e}*SharedItemsImports = 5 Shared\Shared.projitems*{5a3ca774-e381-4e87-b8d9-091644b52222}*SharedItemsImports = 5 Shared\Shared.projitems*{5d7b3be5-9b6a-4723-a316-78918ade866a}*SharedItemsImports = 5 + Shared\Shared.projitems*{5e1abc70-44e0-437c-a9ea-90bfd7bb7449}*SharedItemsImports = 5 Shared\Shared.projitems*{62ff8f2f-fe3a-4c9e-ab42-fc58184971e0}*SharedItemsImports = 5 Shared\Shared.projitems*{63c46961-ccb1-4dd1-a292-8cf1de362f94}*SharedItemsImports = 5 Shared\Shared.projitems*{691fb77e-e114-49bf-8fcf-c0957696e305}*SharedItemsImports = 5 diff --git a/Samples/Shared/Shared.projitems b/Samples/Shared/Shared.projitems index 9ebcf321..279bcfae 100644 --- a/Samples/Shared/Shared.projitems +++ b/Samples/Shared/Shared.projitems @@ -16,5 +16,7 @@ + + \ No newline at end of file diff --git a/Samples/Workspace SDK/CardholderFieldsExtractorSample/VCard.cs b/Samples/Shared/VCard.cs similarity index 100% rename from Samples/Workspace SDK/CardholderFieldsExtractorSample/VCard.cs rename to Samples/Shared/VCard.cs diff --git a/Samples/Workspace SDK/CardholderFieldsExtractorSample/VCardReader.cs b/Samples/Shared/VCardReader.cs similarity index 100% rename from Samples/Workspace SDK/CardholderFieldsExtractorSample/VCardReader.cs rename to Samples/Shared/VCardReader.cs diff --git a/Samples/Workspace SDK/CardholderFieldsExtractorSample/CardholderFieldsExtractorSample.csproj b/Samples/Workspace SDK/CardholderFieldsExtractorSample/CardholderFieldsExtractorSample.csproj index 82c10b39..236bdf87 100644 --- a/Samples/Workspace SDK/CardholderFieldsExtractorSample/CardholderFieldsExtractorSample.csproj +++ b/Samples/Workspace SDK/CardholderFieldsExtractorSample/CardholderFieldsExtractorSample.csproj @@ -77,4 +77,6 @@ + + diff --git a/Samples/Workspace SDK/CardholderFieldsExtractorSample/SampleCardholderFieldsExtractor.cs b/Samples/Workspace SDK/CardholderFieldsExtractorSample/SampleCardholderFieldsExtractor.cs index a5ab9d4e..86fce71d 100644 --- a/Samples/Workspace SDK/CardholderFieldsExtractorSample/SampleCardholderFieldsExtractor.cs +++ b/Samples/Workspace SDK/CardholderFieldsExtractorSample/SampleCardholderFieldsExtractor.cs @@ -12,30 +12,30 @@ public class SampleCardholderFieldsExtractor : CardholderFieldsExtractor { public override string Name => "Read vCard..."; - public override Guid UniqueId { get; } = new("88F33E43-1E51-4504-95BF-ADD2FBCBA8AD"); // TODO: Replace with your own GUID + public override Guid UniqueId { get; } = new("88F33E43-1E51-4504-95BF-ADD2FBCBA8AD"); public override CardholderFields GetFields(CardholderFieldsExtractorData data) { - var openFileDialog = new OpenFileDialog + var dialog = new OpenFileDialog { Filter = "vCard files (*.vcf)|*.vcf|All files (*.*)|*.*", Title = "Open vCard File" }; - if (openFileDialog.ShowDialog() == true) + if (dialog.ShowDialog() != true) + return null; + + VCard vCardInfo = VCardReader.ReadVCard(dialog.FileName); + if (vCardInfo != null) { - VCard vCardInfo = VCardReader.ReadVCard(openFileDialog.FileName); - if (vCardInfo != null) + return new CardholderFields { - return new CardholderFields - { - FirstName = vCardInfo.FirstName, - LastName = vCardInfo.LastName, - Email = vCardInfo.Emails.FirstOrDefault(), - Picture = vCardInfo.Picture, - Description = vCardInfo.Note - }; - } + FirstName = vCardInfo.FirstName, + LastName = vCardInfo.LastName, + Email = vCardInfo.Emails.FirstOrDefault(), + Picture = vCardInfo.Picture, + Description = vCardInfo.Note + }; } return null; diff --git a/Samples/Workspace SDK/CardholderFieldsExtractorSample/SampleModule.cs b/Samples/Workspace SDK/CardholderFieldsExtractorSample/SampleModule.cs index 726bb2e7..b38a195c 100644 --- a/Samples/Workspace SDK/CardholderFieldsExtractorSample/SampleModule.cs +++ b/Samples/Workspace SDK/CardholderFieldsExtractorSample/SampleModule.cs @@ -3,18 +3,29 @@ namespace Genetec.Dap.CodeSamples; +using Genetec.Sdk; using Sdk.Workspace.Modules; public class SampleModule : Module { + private SampleCardholderFieldsExtractor m_extractor; + public override void Load() { - var component = new SampleCardholderFieldsExtractor(); - component.Initialize(Workspace); - Workspace.Components.Register(component); + if (Workspace.ApplicationType is ApplicationType.SecurityDesk or ApplicationType.ConfigTool) + { + m_extractor = new SampleCardholderFieldsExtractor(); + m_extractor.Initialize(Workspace); + Workspace.Components.Register(m_extractor); + } } public override void Unload() { + if (m_extractor != null) + { + Workspace.Components.Unregister(m_extractor); + m_extractor = null; + } } } \ No newline at end of file diff --git a/Samples/Workspace SDK/ImageExtractorSample/SampleImageExtractor.cs b/Samples/Workspace SDK/ImageExtractorSample/SampleImageExtractor.cs index 9f053b13..809f5dad 100644 --- a/Samples/Workspace SDK/ImageExtractorSample/SampleImageExtractor.cs +++ b/Samples/Workspace SDK/ImageExtractorSample/SampleImageExtractor.cs @@ -3,11 +3,11 @@ namespace Genetec.Dap.CodeSamples; +using Microsoft.Win32; +using Sdk.Workspace.Components.ImageExtractor; using System; using System.Windows.Media; using System.Windows.Media.Imaging; -using Microsoft.Win32; -using Sdk.Workspace.Components.ImageExtractor; public sealed class SampleImageExtractor : ImageExtractor { @@ -17,16 +17,18 @@ public sealed class SampleImageExtractor : ImageExtractor public override Guid UniqueId { get; } = new Guid("5EDBB0B6-8253-433E-99A1-9021E498437A"); - public override ImageSource GetImage() { - var openFileDialog = new OpenFileDialog + var dialog = new OpenFileDialog { Filter = "vCard files (*.vcf)|*.vcf|All files (*.*)|*.*", - Title = "Open vCard File" + Title = "Select vCard File" }; - return openFileDialog.ShowDialog() == true ? VCardReader.ReadVCard(openFileDialog.FileName)?.Picture : null; + if (dialog.ShowDialog() != true) + return null; + + return VCardReader.ReadVCard(dialog.FileName)?.Picture; } public override bool SupportsContext(ImageExtractorContext context) diff --git a/Samples/Workspace SDK/ImageExtractorSample/SampleModule.cs b/Samples/Workspace SDK/ImageExtractorSample/SampleModule.cs index f1f48d88..9401602d 100644 --- a/Samples/Workspace SDK/ImageExtractorSample/SampleModule.cs +++ b/Samples/Workspace SDK/ImageExtractorSample/SampleModule.cs @@ -3,20 +3,29 @@ namespace Genetec.Dap.CodeSamples; +using Genetec.Sdk; using Sdk.Workspace.Modules; public class SampleModule : Module { - static SampleModule() => AssemblyResolver.Initialize(); + private SampleImageExtractor m_imageExtractor; public override void Load() { - var component = new SampleImageExtractor(); - component.Initialize(Workspace); - Workspace.Components.Register(component); + if (Workspace.ApplicationType is ApplicationType.SecurityDesk or ApplicationType.ConfigTool) + { + m_imageExtractor = new SampleImageExtractor(); + m_imageExtractor.Initialize(Workspace); + Workspace.Components.Register(m_imageExtractor); + } } public override void Unload() { + if (m_imageExtractor != null) + { + Workspace.Components.Unregister(m_imageExtractor); + m_imageExtractor = null; + } } } \ No newline at end of file diff --git a/Samples/Workspace SDK/ImageExtractorSample/VCard.cs b/Samples/Workspace SDK/ImageExtractorSample/VCard.cs deleted file mode 100644 index 44c893e1..00000000 --- a/Samples/Workspace SDK/ImageExtractorSample/VCard.cs +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright 2025 Genetec Inc. -// Licensed under the Apache License, Version 2.0 - -namespace Genetec.Dap.CodeSamples; - -using System.Collections.Generic; -using System.Windows.Media; - -public class VCard -{ - public string FirstName { get; set; } - - public string LastName { get; set; } - - public List Emails { get; } = new List(); - - public string Note { get; set; } - - public ImageSource Picture { get; set; } -} \ No newline at end of file diff --git a/Samples/Workspace SDK/ImageExtractorSample/VCardReader.cs b/Samples/Workspace SDK/ImageExtractorSample/VCardReader.cs deleted file mode 100644 index 8209c34f..00000000 --- a/Samples/Workspace SDK/ImageExtractorSample/VCardReader.cs +++ /dev/null @@ -1,62 +0,0 @@ -// Copyright 2025 Genetec Inc. -// Licensed under the Apache License, Version 2.0 - -namespace Genetec.Dap.CodeSamples; - -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Text.RegularExpressions; -using System.Windows.Media; -using System.Windows.Media.Imaging; - -public class VCardReader -{ - public static VCard ReadVCard(string filePath) - { - string vCardText = File.ReadAllText(filePath); - var vcard = new VCard - { - FirstName = ExtractField(vCardText, "FN:"), - LastName = ExtractField(vCardText, "N:").Split(';')[0], // Assuming last name is the first component in the N: field - Note = ExtractField(vCardText, "NOTE:"), - Picture = ExtractPhoto(vCardText) - }; - - vcard.Emails.AddRange(ExtractEmails(vCardText)); - return vcard; - } - - private static string ExtractField(string vCardText, string fieldName) - { - Match match = Regex.Match(vCardText, $"{fieldName}(.*?)(\n(?![ \t])|\r\n(?![ \t])|$)", RegexOptions.Singleline); - return match.Success ? match.Groups[1].Value.Trim() : string.Empty; - } - - private static List ExtractEmails(string vCardText) - { - MatchCollection matches = Regex.Matches(vCardText, "EMAIL;[^:]+:(.*?)\r?\n"); - return matches.Cast().Select(match => match.Groups[1].Value.Trim()).ToList(); - } - - private static ImageSource ExtractPhoto(string vCardText) - { - Match photoMatch = Regex.Match(vCardText, @"PHOTO;ENCODING=b;TYPE=image/jpeg:(.*?)(\n(?![ \t])|\r\n(?![ \t])|$)", RegexOptions.Singleline); - if (photoMatch.Success) - { - string base64Data = photoMatch.Groups[1].Value.Trim().Replace("\n", "").Replace("\r", ""); - - using var stream = new MemoryStream(Convert.FromBase64String(base64Data)); - var bitmap = new BitmapImage(); - bitmap.BeginInit(); - bitmap.StreamSource = stream; - bitmap.CacheOption = BitmapCacheOption.OnLoad; - bitmap.EndInit(); - bitmap.Freeze(); - return bitmap; - } - - return null; - } -} \ No newline at end of file diff --git a/Samples/Workspace SDK/PageTaskSample/PageTaskSample.csproj b/Samples/Workspace SDK/PageTaskSample/PageTaskSample.csproj index b1696977..8e352581 100644 --- a/Samples/Workspace SDK/PageTaskSample/PageTaskSample.csproj +++ b/Samples/Workspace SDK/PageTaskSample/PageTaskSample.csproj @@ -34,6 +34,10 @@ 12 + + + + $(GSC_SDK)\Genetec.Sdk.dll diff --git a/Samples/Workspace SDK/PageTaskSample/SampleTilePage.cs b/Samples/Workspace SDK/PageTaskSample/SampleTilePage.cs index b4bfd646..5341f00c 100644 --- a/Samples/Workspace SDK/PageTaskSample/SampleTilePage.cs +++ b/Samples/Workspace SDK/PageTaskSample/SampleTilePage.cs @@ -3,46 +3,243 @@ namespace Genetec.Dap.CodeSamples; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; using Genetec.Sdk; +using Genetec.Sdk.Entities; +using Genetec.Sdk.Queries; +using Genetec.Sdk.Workspace.Commands; +using Genetec.Sdk.Workspace.Pages; using Genetec.Sdk.Workspace.Pages.Contents; using Genetec.Sdk.Workspace.Pages.Tiles; +using Genetec.Sdk.Workspace.Services; using Genetec.Sdk.Workspace.SharedComponents; -using Genetec.Sdk.Workspace.Pages; -using Genetec.Sdk.Queries; -using Genetec.Sdk.Entities; +using Prism.Commands; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using System.Windows.Controls; using Monitor = Sdk.Workspace.Monitors.Monitor; -using Genetec.Sdk.Workspace.Services; // This attribute associates the page with its descriptor [Page(typeof(SampleTilePageDescriptor))] public class SampleTilePage : TilePage { - // The view associated with this page - private readonly SampleTilePageView m_view = new(); - - public SampleTilePage() => View = m_view; + private SampleTilePageView m_view; // Shared component for the tile canvas private SharedComponent m_tileCanvas; + private bool m_isActivated; + private bool m_hasPattern; + + // Pattern commands + public DelegateCommand ModifyPatternCommand { get; private set; } + public DelegateCommand CyclePatternNextCommand { get; private set; } + public DelegateCommand CyclePatternPreviousCommand { get; private set; } + + // Tile selection commands + public DelegateCommand SelectNextTileCommand { get; private set; } + public DelegateCommand SelectPreviousTileCommand { get; private set; } + + // Tile display commands + public DelegateCommand ToggleExpandTileCommand { get; private set; } + public DelegateCommand ToggleFullscreenTileCommand { get; private set; } + + // Content cycling commands + public DelegateCommand ToggleStartStopCyclingCommand { get; private set; } + + // Video commands + public DelegateCommand SynchronizeVideoCommand { get; private set; } + public DelegateCommand SaveSnapshotCommand { get; private set; } + public DelegateCommand ExportVideoCommand { get; private set; } + public DelegateCommand ExportVideoAllTilesCommand { get; private set; } + public DelegateCommand BrowseVaultCommand { get; private set; } + public DelegateCommand ToggleDigitalZoomCommand { get; private set; } + + // Entity browser command + public DelegateCommand DisplayEntityCommand { get; private set; } + + // Clear commands + public DelegateCommand ClearTileCommand { get; private set; } + + public DelegateCommand ClearAllTilesCommand { get; private set; } + + public bool IsActivated + { + get => m_isActivated; + private set + { + if (m_isActivated != value) + { + m_isActivated = value; + OnPropertyChanged(); + RefreshCommands(); + } + } + } + + public bool HasPattern + { + get => m_hasPattern; + private set + { + if (m_hasPattern != value) + { + m_hasPattern = value; + OnPropertyChanged(); + RefreshCommands(); + } + } + } + + protected override void Initialize() + { + InitializeCommands(); + + m_view = new SampleTilePageView(); + m_view.DataContext = this; + View = m_view; + + LoadCameras(); + } + protected override void OnActivated(Monitor monitor) { // Get the tile canvas from the monitor's shared components m_tileCanvas = monitor?.SharedComponents[SharedComponents.TileCanvas].FirstOrDefault(); if (m_tileCanvas != null) { - m_view.m_tilesHost.Content = m_tileCanvas; // Set the tile canvas as the content of the tiles host in the view - m_tileCanvas?.Connect(); // Connect the tile canvas - LoadTiles(); // Load the tiles with camera content + m_view.m_tilesHost.Content = m_tileCanvas; + m_tileCanvas?.Connect(); + LoadTiles(); } + + IsActivated = true; } - protected override void Initialize() + protected override void OnDeactivated(Monitor monitor) { - LoadCameras(); + IsActivated = false; + HasPattern = false; + + // Disconnect the tile canvas and clear the content + m_tileCanvas?.Disconnect(); + m_view.m_tilesHost.Content = null; + } + + private void InitializeCommands() + { + // Pattern commands + ModifyPatternCommand = new DelegateCommand( + () => Workspace.Commands.Execute(WorkspaceCommands.ModifyPattern, null), + () => m_isActivated && m_hasPattern); + + CyclePatternNextCommand = new DelegateCommand( + () => Workspace.Commands.Execute(WorkspaceCommands.CyclePatternNext, 0), + () => m_isActivated && m_hasPattern); + + CyclePatternPreviousCommand = new DelegateCommand( + () => Workspace.Commands.Execute(WorkspaceCommands.CyclePatternPrevious, null), + () => m_isActivated && m_hasPattern); + + // Tile selection commands + SelectNextTileCommand = new DelegateCommand( + () => Workspace.Commands.Execute(WorkspaceCommands.SelectNextTile, null), + () => m_isActivated && m_hasPattern); + + SelectPreviousTileCommand = new DelegateCommand( + () => Workspace.Commands.Execute(WorkspaceCommands.SelectPreviousTile, null), + () => m_isActivated && m_hasPattern); + + // Tile display commands + ToggleExpandTileCommand = new DelegateCommand( + () => Workspace.Commands.Execute(WorkspaceCommands.ToggleExpandTile, null), + () => m_isActivated && m_hasPattern); + + ToggleFullscreenTileCommand = new DelegateCommand( + () => Workspace.Commands.Execute(WorkspaceCommands.ToggleFullscreenTile, null), + () => m_isActivated && m_hasPattern); + + // Content cycling commands + ToggleStartStopCyclingCommand = new DelegateCommand( + () => Workspace.Commands.Execute(WorkspaceCommands.ToggleStartStopCycling, null), + () => m_isActivated && m_hasPattern); + + // Video commands + SynchronizeVideoCommand = new DelegateCommand( + () => Workspace.Commands.Execute(WorkspaceCommands.SynchronizeVideo, null), + () => m_isActivated && m_hasPattern); + + SaveSnapshotCommand = new DelegateCommand( + () => Workspace.Commands.Execute(WorkspaceCommands.SaveSnapshot, null), + () => m_isActivated && m_hasPattern); + + ExportVideoCommand = new DelegateCommand( + () => Workspace.Commands.Execute(WorkspaceCommands.ExportVideo, null), + () => m_isActivated && m_hasPattern); + + ExportVideoAllTilesCommand = new DelegateCommand( + () => Workspace.Commands.Execute(WorkspaceCommands.ExportVideoAllTiles, null), + () => m_isActivated && m_hasPattern); + + BrowseVaultCommand = new DelegateCommand( + () => Workspace.Commands.Execute(WorkspaceCommands.BrowseVault, null), + () => m_isActivated); + + ToggleDigitalZoomCommand = new DelegateCommand( + () => Workspace.Commands.Execute(WorkspaceCommands.ToggleDigitalZoom, null), + () => m_isActivated && m_hasPattern); + + // Entity browser command + DisplayEntityCommand = new DelegateCommand( + DisplayEntityInSelectedTile, + () => m_isActivated && m_hasPattern); + + // Clear commands + ClearTileCommand = new DelegateCommand( + () => Workspace.Commands.Execute(WorkspaceCommands.ClearTile, null), + () => m_isActivated && m_hasPattern); + + ClearAllTilesCommand = new DelegateCommand( + () => Workspace.Commands.Execute(WorkspaceCommands.ClearAllTiles, null), + () => m_isActivated && m_hasPattern); + } + + private void RefreshCommands() + { + ModifyPatternCommand.RaiseCanExecuteChanged(); + CyclePatternNextCommand.RaiseCanExecuteChanged(); + CyclePatternPreviousCommand.RaiseCanExecuteChanged(); + SelectNextTileCommand.RaiseCanExecuteChanged(); + SelectPreviousTileCommand.RaiseCanExecuteChanged(); + ToggleExpandTileCommand.RaiseCanExecuteChanged(); + ToggleFullscreenTileCommand.RaiseCanExecuteChanged(); + ToggleStartStopCyclingCommand.RaiseCanExecuteChanged(); + SynchronizeVideoCommand.RaiseCanExecuteChanged(); + SaveSnapshotCommand.RaiseCanExecuteChanged(); + ExportVideoCommand.RaiseCanExecuteChanged(); + ExportVideoAllTilesCommand.RaiseCanExecuteChanged(); + BrowseVaultCommand.RaiseCanExecuteChanged(); + ToggleDigitalZoomCommand.RaiseCanExecuteChanged(); + DisplayEntityCommand.RaiseCanExecuteChanged(); + ClearTileCommand.RaiseCanExecuteChanged(); + ClearAllTilesCommand.RaiseCanExecuteChanged(); + } + + private void DisplayEntityInSelectedTile() + { + // Show the entity browser dialog allowing the user to select a single entity + List selectedEntities = Workspace.Services.Get().ShowEntityBrowserDialog(new EntityTypeCollection([EntityType.Camera]), null, false, SelectionMode.Single); + + if (selectedEntities.Count > 0) + { + // Build content for the selected entity and display it in the active tile + ContentGroup content = Workspace.Services.Get().Build(selectedEntities[0]); + if (content != null) + { + Workspace.Commands.Execute(WorkspaceCommands.DisplayEntity, selectedEntities[0]); + } + } } private void LoadCameras() @@ -56,13 +253,6 @@ private void LoadCameras() Task.Factory.FromAsync(query.BeginQuery, query.EndQuery, null); } - protected override void OnDeactivated(Monitor monitor) - { - // Disconnect the tile canvas and clear the content - m_tileCanvas?.Disconnect(); - m_view.m_tilesHost.Content = null; - } - // Loads camera tiles into the page private void LoadTiles() { @@ -81,5 +271,7 @@ private void LoadTiles() ContentGroup context = builderService.Build(cameras[index].Guid); States[index].Content = context; } + + HasPattern = true; } -} \ No newline at end of file +} diff --git a/Samples/Workspace SDK/PageTaskSample/SampleTilePageView.xaml b/Samples/Workspace SDK/PageTaskSample/SampleTilePageView.xaml index d34debb0..25aebed1 100644 --- a/Samples/Workspace SDK/PageTaskSample/SampleTilePageView.xaml +++ b/Samples/Workspace SDK/PageTaskSample/SampleTilePageView.xaml @@ -8,6 +8,83 @@ d:DesignWidth="800" mc:Ignorable="d"> - + + + + + + + + +